From fc124714c3901df07d324e5d7bce02db92f9bb64 Mon Sep 17 00:00:00 2001 From: aa-g Date: Wed, 19 May 2021 18:54:41 +0200 Subject: [PATCH 01/68] [WIP] Add CDeformationDriver --- .../include/drivers/CDeformationDriver.hpp | 63 +++ SU2_DEF/src/drivers/CDeformationDriver.cpp | 501 ++++++++++++++++++ SU2_PY/pySU2/Makefile.am | 21 +- SU2_PY/pySU2/pySU2.i | 10 +- SU2_PY/pySU2/pySU2ad.i | 8 +- 5 files changed, 585 insertions(+), 18 deletions(-) create mode 100644 SU2_DEF/include/drivers/CDeformationDriver.hpp create mode 100644 SU2_DEF/src/drivers/CDeformationDriver.cpp diff --git a/SU2_DEF/include/drivers/CDeformationDriver.hpp b/SU2_DEF/include/drivers/CDeformationDriver.hpp new file mode 100644 index 00000000000..afd9a5abb8d --- /dev/null +++ b/SU2_DEF/include/drivers/CDeformationDriver.hpp @@ -0,0 +1,63 @@ +/*! + * \file CDeformationDriver.hpp + * \brief Headers of the main subroutines for driving single or multi-zone problems. + * The subroutines and functions are in the driver_structure.cpp file. + * \author T. Economon, H. Kline, R. Sanchez + * \version 7.1.1 "Blackbird" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2021, SU2 Contributors (cf. AUTHORS.md) + * + * SU2 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * SU2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SU2. If not, see . + */ + +#pragma once +#include "../../../SU2_CFD/include/drivers/CDriver.hpp" + +/*! + * \class CDeformationDriver + * \brief Class for driving single-zone solvers. + * \author R. Sanchez + * \version 7.1.1 "Blackbird" + */ +class CDeformationDriver : public CDriver { +protected: + + unsigned long TimeIter; + +public: + + /*! + * \brief Constructor of the class. + * \param[in] confFile - Configuration file name. + * \param[in] MPICommunicator - MPI communicator for SU2. + */ + CDeformationDriver(char* confFile, + SU2_Comm MPICommunicator); + + /*! + * \brief Destructor of the class. + */ + ~CDeformationDriver(void) override; + + /*! + * \brief [Overload] Launch the computation for single-zone problems. + */ + void RunSolver(); + +}; diff --git a/SU2_DEF/src/drivers/CDeformationDriver.cpp b/SU2_DEF/src/drivers/CDeformationDriver.cpp new file mode 100644 index 00000000000..0aa20dff8a8 --- /dev/null +++ b/SU2_DEF/src/drivers/CDeformationDriver.cpp @@ -0,0 +1,501 @@ +/*! + * \file SU2_DEF.cpp + * \brief Main file of Mesh Deformation Code (SU2_DEF). + * \author F. Palacios, T. Economon + * \version 7.1.1 "Blackbird" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2021, SU2 Contributors (cf. AUTHORS.md) + * + * SU2 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * SU2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SU2. If not, see . + */ + + +#include "../../include/drivers/CDeformationDriver.hpp" +#include "../../../Common/include/geometry/CPhysicalGeometry.hpp" +#include "../../../SU2_CFD/include/output/COutput.hpp" +#include "../../../SU2_CFD/include/output/CMeshOutput.hpp" +using namespace std; + +CDeformationDriver::CDeformationDriver(char* confFile, + SU2_Comm MPICommunicator) : CDriver(confFile, + 1, + MPICommunicator, + false) { + + /*--- Initialize the counter for TimeIter ---*/ + TimeIter = 0; +} + +CDeformationDriver::~CDeformationDriver(void) { + +} + +void CDeformationDriver::RunSolver() { + + + unsigned short iZone, nZone = SINGLE_ZONE; + su2double StartTime = 0.0, StopTime = 0.0, UsedTime = 0.0; + char config_file_name[MAX_STRING_SIZE]; + int rank, size; + string str; + + rank = SU2_MPI::GetRank(); + size = SU2_MPI::GetSize(); + + /*--- Pointer to different structures that will be used throughout + the entire code ---*/ + + CConfig **config_container = nullptr; + CGeometry **geometry_container = nullptr; + CSurfaceMovement **surface_movement = nullptr; + CVolumetricMovement **grid_movement = nullptr; + COutput **output = nullptr; + CConfig *driver_config = nullptr; + + /*--- 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 = nullptr; + config = new CConfig(config_file_name, SU2_COMPONENT::SU2_DEF); + + nZone = config->GetnZone(); + + /*--- Definition of the containers per zones ---*/ + + config_container = new CConfig*[nZone]; + geometry_container = new CGeometry*[nZone]; + surface_movement = new CSurfaceMovement*[nZone]; + grid_movement = new CVolumetricMovement*[nZone]; + output = new COutput*[nZone]; + + driver_config = nullptr; + + for (iZone = 0; iZone < nZone; iZone++) { + config_container[iZone] = nullptr; + geometry_container[iZone] = nullptr; + surface_movement[iZone] = nullptr; + grid_movement[iZone] = nullptr; + output[iZone] = nullptr; + } + + /*--- Initialize the configuration of the driver ---*/ + driver_config = new CConfig(config_file_name, SU2_COMPONENT::SU2_DEF, false); + + /*--- Initialize a char to store the zone filename ---*/ + char zone_file_name[MAX_STRING_SIZE]; + + /*--- 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. ---*/ + + if (driver_config->GetnConfigFiles() > 0){ + strcpy(zone_file_name, driver_config->GetConfigFilename(iZone).c_str()); + config_container[iZone] = new CConfig(driver_config, zone_file_name, SU2_COMPONENT::SU2_DEF, iZone, nZone, true); + } + else{ + config_container[iZone] = new CConfig(driver_config, config_file_name, SU2_COMPONENT::SU2_DEF, iZone, nZone, true); + } + config_container[iZone]->SetMPICommunicator(SU2_MPI::GetComm()); + } + + /*--- Set the multizone part of the problem. ---*/ + if (driver_config->GetMultizone_Problem()){ + for (iZone = 0; iZone < nZone; iZone++) { + /*--- Set the interface markers for multizone ---*/ + config_container[iZone]->SetMultizone(driver_config, config_container); + } + } + + for (iZone = 0; iZone < nZone; iZone++) { + + /*--- Definition of the geometry class to store the primal grid in the partitioning process. ---*/ + + CGeometry *geometry_aux = nullptr; + + /*--- 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]); + + /*--- Build the grid data structures using the ParMETIS coloring. ---*/ + + geometry_container[iZone] = new CPhysicalGeometry(geometry_aux, config_container[iZone]); + + /*--- 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) ---*/ + + StartTime = SU2_MPI::Wtime(); + + for (iZone = 0; iZone < nZone; iZone++) { + + /*--- Computational grid preprocesing ---*/ + + if (rank == MASTER_NODE) cout << endl << "----------------------- Preprocessing computations ----------------------" << endl; + + /*--- Compute elements surrounding points, points surrounding points ---*/ + + if (rank == MASTER_NODE) cout << "Setting local point connectivity." <SetPoint_Connectivity(); + + /*--- Check the orientation before computing geometrical quantities ---*/ + + geometry_container[iZone]->SetBoundVolume(); + if (config_container[iZone]->GetReorientElements()) { + if (rank == MASTER_NODE) cout << "Checking the numerical grid orientation of the interior elements." <Check_IntElem_Orientation(config_container[iZone]); + geometry_container[iZone]->Check_BoundElem_Orientation(config_container[iZone]); + } + + /*--- Create the edge structure ---*/ + + if (rank == MASTER_NODE) cout << "Identify edges and vertices." <SetEdges(); + geometry_container[iZone]->SetVertex(config_container[iZone]); + + if (config_container[iZone]->GetDesign_Variable(0) != NO_DEFORMATION) { + + /*--- Create the dual control volume structures ---*/ + + if (rank == MASTER_NODE) cout << "Setting the bound control volume structure." << endl; + geometry_container[iZone]->SetControlVolume(config_container[iZone], ALLOCATE); + geometry_container[iZone]->SetBoundControlVolume(config_container[iZone], ALLOCATE); + + } + /*--- Create the point-to-point MPI communication structures. ---*/ + + geometry_container[iZone]->PreprocessP2PComms(geometry_container[iZone], config_container[iZone]); + + /*--- Allocate the mesh output ---*/ + + output[iZone] = new CMeshOutput(config_container[iZone], geometry_container[iZone]->GetnDim()); + + /*--- Preprocess the volume output ---*/ + + output[iZone]->PreprocessVolumeOutput(config_container[iZone]); + + /*--- Preprocess history --- */ + + output[iZone]->PreprocessHistoryOutput(config_container[iZone], false); + + } + + + /*--- Surface grid deformation using design variables ---*/ + + for (iZone = 0; iZone < nZone; iZone++){ + + if (config_container[iZone]->GetDesign_Variable(0) != NO_DEFORMATION) { + + /*--- Definition of the Class for grid movement ---*/ + grid_movement[iZone] = new CVolumetricMovement(geometry_container[iZone], config_container[iZone]); + + /*--- Save original coordinates to be reused in convexity checking procedure ---*/ + auto OriginalCoordinates = geometry_container[iZone]->nodes->GetCoord(); + + /*--- First check for volumetric grid deformation/transformations ---*/ + + if (config_container[iZone]->GetDesign_Variable(0) == SCALE_GRID) { + + if (rank == MASTER_NODE) + cout << endl << "--------------------- Volumetric grid scaling (ZONE " << iZone <<") ------------------" << endl; + grid_movement[iZone]->SetVolume_Scaling(geometry_container[iZone], config_container[iZone], false); + + } else if (config_container[iZone]->GetDesign_Variable(0) == TRANSLATE_GRID) { + + if (rank == MASTER_NODE) + cout << endl << "------------------- Volumetric grid translation (ZONE " << iZone <<") ----------------" << endl; + grid_movement[iZone]->SetVolume_Translation(geometry_container[iZone], config_container[iZone], false); + + } else if (config_container[iZone]->GetDesign_Variable(0) == ROTATE_GRID) { + + if (rank == MASTER_NODE) + cout << endl << "--------------------- Volumetric grid rotation (ZONE " << iZone <<") -----------------" << endl; + grid_movement[iZone]->SetVolume_Rotation(geometry_container[iZone], config_container[iZone], false); + + } else { + + /*--- If no volume-type deformations are requested, then this is a + surface-based deformation or FFD set up. ---*/ + + if (rank == MASTER_NODE) + cout << endl << "--------------------- Surface grid deformation (ZONE " << iZone <<") -----------------" << endl; + + /*--- Definition and initialization of the surface deformation class ---*/ + + surface_movement[iZone] = new CSurfaceMovement(); + + /*--- Copy coordinates to the surface structure ---*/ + + surface_movement[iZone]->CopyBoundary(geometry_container[iZone], config_container[iZone]); + + /*--- Surface grid deformation ---*/ + + if (rank == MASTER_NODE) cout << "Performing the deformation of the surface grid." << endl; + auto TotalDeformation = surface_movement[iZone]->SetSurface_Deformation(geometry_container[iZone], config_container[iZone]); + + if (config_container[iZone]->GetDesign_Variable(0) != FFD_SETTING) { + + if (rank == MASTER_NODE) + cout << endl << "------------------- Volumetric grid deformation (ZONE " << iZone <<") ----------------" << endl; + + if (rank == MASTER_NODE) + cout << "Performing the deformation of the volumetric grid." << endl; + grid_movement[iZone]->SetVolume_Deformation(geometry_container[iZone], config_container[iZone], false); + + /*--- Get parameters for convexity check ---*/ + bool ConvexityCheck; + unsigned short ConvexityCheck_MaxIter, ConvexityCheck_MaxDepth; + + tie(ConvexityCheck, ConvexityCheck_MaxIter, ConvexityCheck_MaxDepth) = config_container[iZone]->GetConvexityCheck(); + + /*--- Recursively change deformations if there are nonconvex elements. ---*/ + + if (ConvexityCheck && geometry_container[iZone]->GetnNonconvexElements() > 0) { + if (rank == MASTER_NODE) { + cout << "Nonconvex elements present after deformation. " << endl; + cout << "Recursively lowering deformation magnitude." << endl; + } + + /*--- Load initial deformation values ---*/ + auto InitialDeformation = TotalDeformation; + + unsigned short ConvexityCheckIter, RecursionDepth = 0; + su2double DeformationFactor = 1.0, DeformationDifference = 1.0; + for (ConvexityCheckIter = 1; ConvexityCheckIter <= ConvexityCheck_MaxIter; ConvexityCheckIter++) { + + /*--- Recursively change deformation magnitude: + decrease if there are nonconvex elements, increase otherwise ---*/ + DeformationDifference /= 2.0; + + if (geometry_container[iZone]->GetnNonconvexElements() > 0) { + DeformationFactor -= DeformationDifference; + } else { + RecursionDepth += 1; + + if (RecursionDepth == ConvexityCheck_MaxDepth) { + if (rank == MASTER_NODE) { + cout << "Maximum recursion depth reached." << endl; + cout << "Remaining amount of original deformation: "; + cout << DeformationFactor*100.0 << " percent. " << endl; + } + break; + } + + DeformationFactor += DeformationDifference; + } + + /*--- Load mesh to start every iteration with an undeformed grid ---*/ + for (auto iPoint = 0ul; iPoint < OriginalCoordinates.rows(); iPoint++) { + for (auto iDim = 0ul; iDim < OriginalCoordinates.cols(); iDim++) { + geometry_container[iZone]->nodes->SetCoord(iPoint, iDim, OriginalCoordinates(iPoint,iDim)); + } + } + + /*--- Set deformation magnitude as percentage of initial deformation ---*/ + for (auto iDV = 0u; iDV < config->GetnDV(); iDV++) { + for (auto iDV_Value = 0u; iDV_Value < config->GetnDV_Value(iDV); iDV_Value++) { + config_container[iZone]->SetDV_Value(iDV, iDV_Value, InitialDeformation[iDV][iDV_Value]*DeformationFactor); + } + } + + /*--- Surface grid deformation ---*/ + if (rank == MASTER_NODE) cout << "Performing the deformation of the surface grid." << endl; + + TotalDeformation = surface_movement[iZone]->SetSurface_Deformation(geometry_container[iZone], config_container[iZone]); + + if (rank == MASTER_NODE) + cout << endl << "------------------- Volumetric grid deformation (ZONE " << iZone <<") ----------------" << endl; + + if (rank == MASTER_NODE) + cout << "Performing the deformation of the volumetric grid." << endl; + grid_movement[iZone]->SetVolume_Deformation(geometry_container[iZone], config_container[iZone], false); + + if (rank == MASTER_NODE) { + cout << "Number of nonconvex elements for iteration " << ConvexityCheckIter << ": "; + cout << geometry_container[iZone]->GetnNonconvexElements() << endl; + cout << "Remaining amount of original deformation: "; + cout << DeformationFactor*100.0 << " percent. " << endl; + } + + } + + } + + } + + } + + } + + } + + /*--- Computational grid preprocesing ---*/ + + if (rank == MASTER_NODE) cout << endl << "----------------------- Write deformed grid files -----------------------" << endl; + + /*--- Output deformed grid for visualization, if requested (surface and volumetric), in parallel + requires to move all the data to the master node---*/ + + for (iZone = 0; iZone < nZone; iZone++){ + + /*--- Compute Mesh Quality if requested. Necessary geometry preprocessing re-done beforehand. ---*/ + + if (config_container[iZone]->GetWrt_MeshQuality() && !config->GetStructuralProblem()) { + + if (rank == MASTER_NODE) cout << "Recompute geometry properties necessary to evaluate mesh quality statistics.\n"; + + geometry_container[iZone]->SetPoint_Connectivity(); + geometry_container[iZone]->SetBoundVolume(); + geometry_container[iZone]->SetEdges(); + geometry_container[iZone]->SetVertex(config_container[iZone]); + geometry_container[iZone]->SetControlVolume(config_container[iZone], ALLOCATE); + geometry_container[iZone]->SetBoundControlVolume(config_container[iZone], ALLOCATE); + + if (rank == MASTER_NODE) cout << "Computing mesh quality statistics for the dual control volumes.\n"; + geometry_container[iZone]->ComputeMeshQualityStatistics(config_container[iZone]); + }// Mesh Quality Output + + /*--- Load the data --- */ + + output[iZone]->Load_Data(geometry_container[iZone], config_container[iZone], nullptr); + + output[iZone]->WriteToFile(config_container[iZone], geometry_container[iZone], MESH, config->GetMesh_Out_FileName()); + + /*--- Set the file names for the visualization files ---*/ + + output[iZone]->SetVolume_Filename("volume_deformed"); + output[iZone]->SetSurface_Filename("surface_deformed"); + + for (unsigned short iFile = 0; iFile < config_container[iZone]->GetnVolumeOutputFiles(); iFile++){ + auto FileFormat = config_container[iZone]->GetVolumeOutputFiles(); + if (FileFormat[iFile] != RESTART_ASCII && FileFormat[iFile] != RESTART_BINARY) + output[iZone]->WriteToFile(config_container[iZone], geometry_container[iZone], FileFormat[iFile]); + } + } + + + if ((config_container[ZONE_0]->GetDesign_Variable(0) != NO_DEFORMATION) && + (config_container[ZONE_0]->GetDesign_Variable(0) != SCALE_GRID) && + (config_container[ZONE_0]->GetDesign_Variable(0) != TRANSLATE_GRID) && + (config_container[ZONE_0]->GetDesign_Variable(0) != ROTATE_GRID)) { + + /*--- Write the the free-form deformation boxes after deformation. ---*/ + + if (rank == MASTER_NODE) cout << "Adding any FFD information to the SU2 file." << endl; + + surface_movement[ZONE_0]->WriteFFDInfo(surface_movement, geometry_container, config_container); + + } + + delete config; + config = nullptr; + if (rank == MASTER_NODE) + cout << endl <<"------------------------- Solver Postprocessing -------------------------" << endl; + + if (geometry_container != nullptr) { + for (iZone = 0; iZone < nZone; iZone++) { + if (geometry_container[iZone] != nullptr) { + delete geometry_container[iZone]; + } + } + delete [] geometry_container; + } + if (rank == MASTER_NODE) cout << "Deleted CGeometry container." << endl; + + if (surface_movement != nullptr) { + for (iZone = 0; iZone < nZone; iZone++) { + if (surface_movement[iZone] != nullptr) { + delete surface_movement[iZone]; + } + } + delete [] surface_movement; + } + if (rank == MASTER_NODE) cout << "Deleted CSurfaceMovement class." << endl; + + if (grid_movement != nullptr) { + for (iZone = 0; iZone < nZone; iZone++) { + if (grid_movement[iZone] != nullptr) { + delete grid_movement[iZone]; + } + } + delete [] grid_movement; + } + if (rank == MASTER_NODE) cout << "Deleted CVolumetricMovement class." << endl; + + if (config_container != nullptr) { + for (iZone = 0; iZone < nZone; iZone++) { + if (config_container[iZone] != nullptr) { + delete config_container[iZone]; + } + } + delete [] config_container; + } + if (output != nullptr) { + for (iZone = 0; iZone < nZone; iZone++) { + if (output[iZone] != nullptr) { + delete output[iZone]; + } + } + delete [] output; + } + if (rank == MASTER_NODE) cout << "Deleted CConfig container." << endl; + + if (rank == MASTER_NODE) cout << "Deleted COutput class." << endl; + + /*--- Synchronization point after a single solver iteration. Compute the + wall clock time required. ---*/ + + StopTime = SU2_MPI::Wtime(); + + /*--- 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 ---*/ + + if (rank == MASTER_NODE) + cout << endl << "------------------------- Exit Success (SU2_DEF) ------------------------" << endl << endl; + } diff --git a/SU2_PY/pySU2/Makefile.am b/SU2_PY/pySU2/Makefile.am index 29c7ef1833b..631400db6bd 100644 --- a/SU2_PY/pySU2/Makefile.am +++ b/SU2_PY/pySU2/Makefile.am @@ -6,8 +6,8 @@ # \version 7.1.1 "Blackbird" # # SU2 Project Website: https://su2code.github.io -# -# The SU2 Project is maintained by the SU2 Foundation +# +# The SU2 Project is maintained by the SU2 Foundation # (http://su2foundation.org) # # Copyright 2012-2021, SU2 Contributors (cf. AUTHORS.md) @@ -16,7 +16,7 @@ # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. -# +# # SU2 is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -61,15 +61,15 @@ PY_LIB = ${PYTHON_LIBS} \ -L${PYTHON_EXEC_PREFIX}/lib \ -L/usr/lib \ -L/usr/lib/x86_64-linux-gnu - + SWIG_INCLUDE = ${PY_INCLUDE} SUBDIR_EXEC = ${bindir} -all: - ${MAKE} real; - +all: + ${MAKE} real; + # List the dependencies real: ${SWIG_SO_REAL} @@ -104,11 +104,11 @@ pySU2_LD_FLAGS = ${SU2SOLVER_LIB} @su2_externals_LIBS@ ${PY_LIB} # Set the command line flags to use for compilation pySU2_CC_FLAGS = ${CPPFLAGS} ${EXTRA_CC_FLAGS} @su2_externals_INCLUDES@ ${pySU2_INCLUDE} -SO_LINK_FLAGS= -fPIC -shared +SO_LINK_FLAGS= -fPIC -shared # Default rule for creating the _wrap.cxx file from the .i file ${SWIG_WRAP_REAL}.cxx: ${SU2SOLVER_LIB} ${SWIG_SRC} - ${SWIG} ${CPPFLAGS} -Wall ${SWIG_INCLUDE} -outdir ./ -o ${SWIG_WRAP_REAL}.cxx -c++ -python ${SWIG_SRC} + ${SWIG} ${CPPFLAGS} -Wall ${SWIG_INCLUDE} -outdir ./ -o ${SWIG_WRAP_REAL}.cxx -c++ -python ${SWIG_SRC} #Default rule for compiling the .o files ${SWIG_WRAP_REAL}.o: ${SWIG_WRAP_REAL}.cxx @@ -122,7 +122,7 @@ ${SWIG_SO_REAL}: ${SWIG_WRAP_REAL}.o .SECONDARY: -clean: +clean: rm -f ${CURRENT_DIR}/*.cxx rm -f ${CURRENT_DIR}/*.${SO_EXT} rm -f ${CURRENT_DIR}/*.o @@ -132,4 +132,3 @@ clean: install: all ${INSTALL} ${PYLIB} ${bindir} ${INSTALL} ${SOLIB} ${bindir} - diff --git a/SU2_PY/pySU2/pySU2.i b/SU2_PY/pySU2/pySU2.i index e783ac8b48b..c042919a506 100644 --- a/SU2_PY/pySU2/pySU2.i +++ b/SU2_PY/pySU2/pySU2.i @@ -7,8 +7,8 @@ # \version 7.1.1 "Blackbird" # # SU2 Project Website: https://su2code.github.io -# -# The SU2 Project is maintained by the SU2 Foundation +# +# The SU2 Project is maintained by the SU2 Foundation # (http://su2foundation.org) # # Copyright 2012-2021, SU2 Contributors (cf. AUTHORS.md) @@ -17,7 +17,7 @@ # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. -# +# # SU2 is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -42,7 +42,8 @@ threads="1" #include "../../SU2_CFD/include/drivers/CSinglezoneDriver.hpp" #include "../../SU2_CFD/include/drivers/CMultizoneDriver.hpp" #include "../../SU2_CFD/include/drivers/CDiscAdjSinglezoneDriver.hpp" - +#include "../../SU2_DEF/include/drivers/CDeformationDriver.hpp" + %} // ----------- USED MODULES ------------ @@ -91,3 +92,4 @@ const unsigned int ZONE_1 = 1; /*!< \brief Definition of the first grid domain. %include "../../SU2_CFD/include/drivers/CSinglezoneDriver.hpp" %include "../../SU2_CFD/include/drivers/CMultizoneDriver.hpp" %include "../../SU2_CFD/include/drivers/CDiscAdjSinglezoneDriver.hpp" +%include "../../SU2_DEF/include/drivers/CDeformationDriver.hpp" diff --git a/SU2_PY/pySU2/pySU2ad.i b/SU2_PY/pySU2/pySU2ad.i index aaf37844c90..910202a138e 100644 --- a/SU2_PY/pySU2/pySU2ad.i +++ b/SU2_PY/pySU2/pySU2ad.i @@ -7,8 +7,8 @@ # \version 7.1.1 "Blackbird" # # SU2 Project Website: https://su2code.github.io -# -# The SU2 Project is maintained by the SU2 Foundation +# +# The SU2 Project is maintained by the SU2 Foundation # (http://su2foundation.org) # # Copyright 2012-2021, SU2 Contributors (cf. AUTHORS.md) @@ -17,7 +17,7 @@ # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. -# +# # SU2 is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -42,6 +42,7 @@ threads="1" #include "../../SU2_CFD/include/drivers/CSinglezoneDriver.hpp" #include "../../SU2_CFD/include/drivers/CMultizoneDriver.hpp" #include "../../SU2_CFD/include/drivers/CDiscAdjSinglezoneDriver.hpp" +#include "../../SU2_DEF/include/drivers/CDeformationDriver.hpp" %} @@ -91,3 +92,4 @@ const unsigned int ZONE_1 = 1; /*!< \brief Definition of the first grid domain. %include "../../SU2_CFD/include/drivers/CSinglezoneDriver.hpp" %include "../../SU2_CFD/include/drivers/CMultizoneDriver.hpp" %include "../../SU2_CFD/include/drivers/CDiscAdjSinglezoneDriver.hpp" +%include "../../SU2_DEF/include/drivers/CDeformationDriver.hpp" From 2643405946420bf47459c7961fafa2c4c80eb08b Mon Sep 17 00:00:00 2001 From: aa-g Date: Fri, 21 May 2021 18:48:51 +0200 Subject: [PATCH 02/68] Implement RunSolver() --- .../include/drivers/CDeformationDriver.hpp | 22 ++++-- SU2_DEF/src/drivers/CDeformationDriver.cpp | 36 ++++----- SU2_DEF/src/meson.build | 73 +++++++++++-------- SU2_PY/pySU2/meson.build | 2 +- SU2_PY/pySU2/pySU2ad.i | 2 - 5 files changed, 79 insertions(+), 56 deletions(-) diff --git a/SU2_DEF/include/drivers/CDeformationDriver.hpp b/SU2_DEF/include/drivers/CDeformationDriver.hpp index afd9a5abb8d..e2fd22f748f 100644 --- a/SU2_DEF/include/drivers/CDeformationDriver.hpp +++ b/SU2_DEF/include/drivers/CDeformationDriver.hpp @@ -27,7 +27,8 @@ */ #pragma once -#include "../../../SU2_CFD/include/drivers/CDriver.hpp" +#include "../../../Common/include/parallelization/mpi_structure.hpp" +#include "../../../Common/include/geometry/CGeometry.hpp" /*! * \class CDeformationDriver @@ -35,13 +36,11 @@ * \author R. Sanchez * \version 7.1.1 "Blackbird" */ -class CDeformationDriver : public CDriver { +class CDeformationDriver { protected: - - unsigned long TimeIter; + char config_file_name[MAX_STRING_SIZE]; public: - /*! * \brief Constructor of the class. * \param[in] confFile - Configuration file name. @@ -53,11 +52,22 @@ class CDeformationDriver : public CDriver { /*! * \brief Destructor of the class. */ - ~CDeformationDriver(void) override; + ~CDeformationDriver(void); /*! * \brief [Overload] Launch the computation for single-zone problems. */ void RunSolver(); +protected: + /*! + * \brief Init_Containers + */ + void SetContainers_Null(); + + /*! + * \brief Read in the config and mesh files. + */ + void Input_Preprocessing(CConfig **&config, CConfig *&driver_config); + }; diff --git a/SU2_DEF/src/drivers/CDeformationDriver.cpp b/SU2_DEF/src/drivers/CDeformationDriver.cpp index 0aa20dff8a8..529085f87e6 100644 --- a/SU2_DEF/src/drivers/CDeformationDriver.cpp +++ b/SU2_DEF/src/drivers/CDeformationDriver.cpp @@ -12,7 +12,7 @@ * Copyright 2012-2021, SU2 Contributors (cf. AUTHORS.md) * * SU2 is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public + * modify it under the terms of the GNU Lesser/ General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * @@ -28,18 +28,25 @@ #include "../../include/drivers/CDeformationDriver.hpp" #include "../../../Common/include/geometry/CPhysicalGeometry.hpp" +#include "../../../Common/include/grid_movement/CSurfaceMovement.hpp" +#include "../../../Common/include/grid_movement/CVolumetricMovement.hpp" #include "../../../SU2_CFD/include/output/COutput.hpp" #include "../../../SU2_CFD/include/output/CMeshOutput.hpp" using namespace std; -CDeformationDriver::CDeformationDriver(char* confFile, - SU2_Comm MPICommunicator) : CDriver(confFile, - 1, - MPICommunicator, - false) { +CDeformationDriver::CDeformationDriver(char* confFile, SU2_Comm MPICommunicator) { - /*--- Initialize the counter for TimeIter ---*/ - TimeIter = 0; + /*--- Initialize Medipack (must also be here so it is initialized from python) ---*/ + #ifdef HAVE_MPI + #if defined(CODI_REVERSE_TYPE) || defined(CODI_FORWARD_TYPE) + SU2_MPI::Init_AMPI(); + #endif + #endif + + SU2_MPI::SetComm(MPICommunicator); + + /*--- Copy the config filename ---*/ + strcpy(config_file_name, confFile); } CDeformationDriver::~CDeformationDriver(void) { @@ -48,15 +55,12 @@ CDeformationDriver::~CDeformationDriver(void) { void CDeformationDriver::RunSolver() { - - unsigned short iZone, nZone = SINGLE_ZONE; + unsigned short iZone, nZone = SINGLE_ZONE; su2double StartTime = 0.0, StopTime = 0.0, UsedTime = 0.0; - char config_file_name[MAX_STRING_SIZE]; - int rank, size; string str; - rank = SU2_MPI::GetRank(); - size = SU2_MPI::GetSize(); + int rank = SU2_MPI::GetRank(); + int size = SU2_MPI::GetSize(); /*--- Pointer to different structures that will be used throughout the entire code ---*/ @@ -79,7 +83,7 @@ void CDeformationDriver::RunSolver() { /*--- Definition of the containers per zones ---*/ - config_container = new CConfig*[nZone]; + config_container = new CConfig*[nZone]; geometry_container = new CGeometry*[nZone]; surface_movement = new CSurfaceMovement*[nZone]; grid_movement = new CVolumetricMovement*[nZone]; @@ -215,10 +219,8 @@ void CDeformationDriver::RunSolver() { /*--- Preprocess history --- */ output[iZone]->PreprocessHistoryOutput(config_container[iZone], false); - } - /*--- Surface grid deformation using design variables ---*/ for (iZone = 0; iZone < nZone; iZone++){ diff --git a/SU2_DEF/src/meson.build b/SU2_DEF/src/meson.build index d18ed7a46b0..a6681c5c88d 100644 --- a/SU2_DEF/src/meson.build +++ b/SU2_DEF/src/meson.build @@ -1,38 +1,51 @@ -su2_def_src = ['SU2_DEF.cpp'] +su2_def_include = include_directories('./') +su2_def_src = files([ + 'SU2_DEF.cpp', + 'drivers/CDeformationDriver.cpp' +]) if get_option('enable-normal') - su2_cfd_obj = su2_cfd_lib.extract_objects(['solvers/CSolver.cpp', - 'solvers/CBaselineSolver.cpp', - 'CMarkerProfileReaderFVM.cpp', - 'output/COutput.cpp', - 'output/tools/CWindowingTools.cpp', - 'output/CMeshOutput.cpp', - 'output/output_structure_legacy.cpp', - 'variables/CBaselineVariable.cpp', - 'variables/CVariable.cpp', - 'output/filewriter/CParallelDataSorter.cpp', - 'output/filewriter/CFVMDataSorter.cpp', - 'output/filewriter/CFEMDataSorter.cpp', - 'output/filewriter/CSurfaceFEMDataSorter.cpp', - 'output/filewriter/CSurfaceFVMDataSorter.cpp', - 'output/filewriter/CParallelFileWriter.cpp', - 'output/filewriter/CParaviewFileWriter.cpp', - 'output/filewriter/CParaviewBinaryFileWriter.cpp', - 'output/filewriter/CTecplotFileWriter.cpp', - 'output/filewriter/CTecplotBinaryFileWriter.cpp', - 'output/filewriter/CCSVFileWriter.cpp', - 'output/filewriter/CSTLFileWriter.cpp', - 'output/filewriter/CSU2FileWriter.cpp', - 'output/filewriter/CSU2BinaryFileWriter.cpp', - 'output/filewriter/CParaviewXMLFileWriter.cpp', - 'output/filewriter/CParaviewVTMFileWriter.cpp', - 'output/filewriter/CSU2MeshFileWriter.cpp', - 'limiters/CLimiterDetails.cpp']) +su2_cfd_obj = su2_cfd_lib.extract_objects(['solvers/CSolver.cpp', + 'solvers/CBaselineSolver.cpp', + 'CMarkerProfileReaderFVM.cpp', + 'output/COutput.cpp', + 'output/tools/CWindowingTools.cpp', + 'output/CMeshOutput.cpp', + 'output/output_structure_legacy.cpp', + 'variables/CBaselineVariable.cpp', + 'variables/CVariable.cpp', + 'output/filewriter/CParallelDataSorter.cpp', + 'output/filewriter/CFVMDataSorter.cpp', + 'output/filewriter/CFEMDataSorter.cpp', + 'output/filewriter/CSurfaceFEMDataSorter.cpp', + 'output/filewriter/CSurfaceFVMDataSorter.cpp', + 'output/filewriter/CParallelFileWriter.cpp', + 'output/filewriter/CParaviewFileWriter.cpp', + 'output/filewriter/CParaviewBinaryFileWriter.cpp', + 'output/filewriter/CTecplotFileWriter.cpp', + 'output/filewriter/CTecplotBinaryFileWriter.cpp', + 'output/filewriter/CCSVFileWriter.cpp', + 'output/filewriter/CSTLFileWriter.cpp', + 'output/filewriter/CSU2FileWriter.cpp', + 'output/filewriter/CSU2BinaryFileWriter.cpp', + 'output/filewriter/CParaviewXMLFileWriter.cpp', + 'output/filewriter/CParaviewVTMFileWriter.cpp', + 'output/filewriter/CSU2MeshFileWriter.cpp', + 'limiters/CLimiterDetails.cpp']) + + su2_def_lib = static_library('SU2core_DEF', + su2_def_src, + install : false, + dependencies : [su2_deps, common_dep], + cpp_args: [default_warning_flags, su2_cpp_args]) + + su2_def_dep = declare_dependency(link_with: su2_def_lib, + include_directories: su2_def_include) su2_def = executable('SU2_DEF', - su2_def_src, + su2_def_src, install: true, - dependencies: [su2_deps, common_dep], + dependencies: [su2_deps, common_dep], objects : su2_cfd_obj, cpp_args :[default_warning_flags, su2_cpp_args]) endif diff --git a/SU2_PY/pySU2/meson.build b/SU2_PY/pySU2/meson.build index 1404f7fe10a..1aab2e53b50 100644 --- a/SU2_PY/pySU2/meson.build +++ b/SU2_PY/pySU2/meson.build @@ -28,7 +28,7 @@ if get_option('enable-normal') '_pysu2', cpp_source, dependencies: [wrapper_deps, common_dep, su2_deps], - objects: su2_cfd_lib.extract_all_objects(), + objects: [su2_cfd_lib.extract_all_objects(), su2_def_lib.extract_objects('drivers/CDeformationDriver.cpp')], install: true, include_directories : mpi4py_include, cpp_args : [default_warning_flags,su2_cpp_args], diff --git a/SU2_PY/pySU2/pySU2ad.i b/SU2_PY/pySU2/pySU2ad.i index 910202a138e..4409fd93fcb 100644 --- a/SU2_PY/pySU2/pySU2ad.i +++ b/SU2_PY/pySU2/pySU2ad.i @@ -42,7 +42,6 @@ threads="1" #include "../../SU2_CFD/include/drivers/CSinglezoneDriver.hpp" #include "../../SU2_CFD/include/drivers/CMultizoneDriver.hpp" #include "../../SU2_CFD/include/drivers/CDiscAdjSinglezoneDriver.hpp" -#include "../../SU2_DEF/include/drivers/CDeformationDriver.hpp" %} @@ -92,4 +91,3 @@ const unsigned int ZONE_1 = 1; /*!< \brief Definition of the first grid domain. %include "../../SU2_CFD/include/drivers/CSinglezoneDriver.hpp" %include "../../SU2_CFD/include/drivers/CMultizoneDriver.hpp" %include "../../SU2_CFD/include/drivers/CDiscAdjSinglezoneDriver.hpp" -%include "../../SU2_DEF/include/drivers/CDeformationDriver.hpp" From 907b5bfd4fae3f6db7ec141f9de9c3f002bd220f Mon Sep 17 00:00:00 2001 From: aa-g Date: Tue, 25 May 2021 19:06:39 +0200 Subject: [PATCH 03/68] Clean up CDeformationDriver implementation. Refactor some pre-processing operations in constructor to Geometrical_Preprocessing() and Output_Preprocessing(). Refactor SU2_DEF main function to use the new CDeformationDriver class. --- SU2_DEF/include/SU2_DEF.hpp | 7 +- .../include/drivers/CDeformationDriver.hpp | 53 +- SU2_DEF/src/SU2_DEF.cpp | 456 +----------------- SU2_DEF/src/drivers/CDeformationDriver.cpp | 265 +++++----- 4 files changed, 200 insertions(+), 581 deletions(-) diff --git a/SU2_DEF/include/SU2_DEF.hpp b/SU2_DEF/include/SU2_DEF.hpp index 462599f36df..505e72a73d0 100644 --- a/SU2_DEF/include/SU2_DEF.hpp +++ b/SU2_DEF/include/SU2_DEF.hpp @@ -32,14 +32,11 @@ #include "../../Common/include/parallelization/mpi_structure.hpp" #include "../../Common/include/parallelization/omp_structure.hpp" +#include "drivers/CDeformationDriver.hpp" + #include #include #include #include -#include "../../SU2_CFD/include/solvers/CSolver.hpp" -#include "../../SU2_CFD/include/output/CMeshOutput.hpp" -#include "../../Common/include/geometry/CPhysicalGeometry.hpp" -#include "../../Common/include/CConfig.hpp" - using namespace std; diff --git a/SU2_DEF/include/drivers/CDeformationDriver.hpp b/SU2_DEF/include/drivers/CDeformationDriver.hpp index e2fd22f748f..b76a2919976 100644 --- a/SU2_DEF/include/drivers/CDeformationDriver.hpp +++ b/SU2_DEF/include/drivers/CDeformationDriver.hpp @@ -27,7 +27,12 @@ */ #pragma once + #include "../../../Common/include/parallelization/mpi_structure.hpp" + +#include "../../../Common/include/grid_movement/CSurfaceMovement.hpp" +#include "../../../Common/include/grid_movement/CVolumetricMovement.hpp" +#include "../../../SU2_CFD/include/output/COutput.hpp" #include "../../../Common/include/geometry/CGeometry.hpp" /*! @@ -39,6 +44,21 @@ class CDeformationDriver { protected: char config_file_name[MAX_STRING_SIZE]; + int rank, + size; + su2double StartTime, /*!< \brief Start point of the timer for performance benchmarking.*/ + StopTime, /*!< \brief Stop point of the timer for performance benchmarking.*/ + UsedTimePreproc, /*!< \brief Elapsed time between Start and Stop point of the timer for tracking preprocessing phase.*/ + UsedTimeCompute, /*!< \brief Elapsed time between Start and Stop point of the timer for tracking compute phase.*/ + UsedTime; /*!< \brief Elapsed time between Start and Stop point of the timer.*/ + unsigned short iZone, nZone = SINGLE_ZONE; + CConfig *driver_config; /*!< \brief Definition of the driver configuration. */ + CConfig **config_container; /*!< \brief Definition of the particular problem. */ + CGeometry **geometry_container; /*!< \brief Geometrical definition of the problem. */ + CSurfaceMovement **surface_movement; /*!< \brief Surface movement classes of the problem. */ + CVolumetricMovement **grid_movement; /*!< \brief Volume grid movement classes of the problem. */ + COutput **output_container; /*!< \brief Pointer to the COutput class. */ + /*!< \brief FFD FFDBoxes of the problem. */ public: /*! @@ -57,17 +77,32 @@ class CDeformationDriver { /*! * \brief [Overload] Launch the computation for single-zone problems. */ - void RunSolver(); + void Run(); + + /*! + * \brief Deallocation routine + */ + void Postprocessing(); protected: - /*! - * \brief Init_Containers - */ - void SetContainers_Null(); + /*! + * \brief Init_Containers + */ + void SetContainers_Null(); - /*! - * \brief Read in the config and mesh files. - */ - void Input_Preprocessing(CConfig **&config, CConfig *&driver_config); + /*! + * \brief Read in the config and mesh files. + */ + void Input_Preprocessing(); + + /*! + * \brief Construction of the edge-based data structure. + */ + void Geometrical_Preprocessing(CConfig *config, CGeometry *&geometry); + + /*! + * \brief Preprocess the output container. + */ + void Output_Preprocessing(CConfig *config, CGeometry *geometry, COutput *&output); }; diff --git a/SU2_DEF/src/SU2_DEF.cpp b/SU2_DEF/src/SU2_DEF.cpp index adb078ae4a1..ea0ce32bcb2 100644 --- a/SU2_DEF/src/SU2_DEF.cpp +++ b/SU2_DEF/src/SU2_DEF.cpp @@ -27,15 +27,16 @@ #include "../include/SU2_DEF.hpp" + using namespace std; int main(int argc, char *argv[]) { - unsigned short iZone, nZone = SINGLE_ZONE; - su2double StartTime = 0.0, StopTime = 0.0, UsedTime = 0.0; char config_file_name[MAX_STRING_SIZE]; - int rank, size; - string str; + + /*--- Create a pointer to the main SU2_DEF Driver ---*/ + + CDeformationDriver* driver = nullptr; /*--- MPI initialization ---*/ @@ -45,20 +46,7 @@ int main(int argc, char *argv[]) { #else SU2_MPI::Init(&argc, &argv); #endif - SU2_MPI::Comm MPICommunicator = SU2_MPI::GetComm(); - - rank = SU2_MPI::GetRank(); - size = SU2_MPI::GetSize(); - - /*--- Pointer to different structures that will be used throughout - the entire code ---*/ - - CConfig **config_container = nullptr; - CGeometry **geometry_container = nullptr; - CSurfaceMovement **surface_movement = nullptr; - CVolumetricMovement **grid_movement = nullptr; - COutput **output = nullptr; - CConfig *driver_config = nullptr; + SU2_MPI::Comm comm = SU2_MPI::GetComm(); /*--- Load in the number of zones and spatial dimensions in the mesh file (if no config file is specified, default.cfg is used) ---*/ @@ -66,436 +54,18 @@ int main(int argc, char *argv[]) { 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 = nullptr; - config = new CConfig(config_file_name, SU2_COMPONENT::SU2_DEF); - - nZone = config->GetnZone(); - - /*--- Definition of the containers per zones ---*/ - - config_container = new CConfig*[nZone]; - geometry_container = new CGeometry*[nZone]; - surface_movement = new CSurfaceMovement*[nZone]; - grid_movement = new CVolumetricMovement*[nZone]; - output = new COutput*[nZone]; - - driver_config = nullptr; - - for (iZone = 0; iZone < nZone; iZone++) { - config_container[iZone] = nullptr; - geometry_container[iZone] = nullptr; - surface_movement[iZone] = nullptr; - grid_movement[iZone] = nullptr; - output[iZone] = nullptr; - } - - /*--- Initialize the configuration of the driver ---*/ - driver_config = new CConfig(config_file_name, SU2_COMPONENT::SU2_DEF, false); - - /*--- Initialize a char to store the zone filename ---*/ - char zone_file_name[MAX_STRING_SIZE]; - - /*--- 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. ---*/ - - if (driver_config->GetnConfigFiles() > 0){ - strcpy(zone_file_name, driver_config->GetConfigFilename(iZone).c_str()); - config_container[iZone] = new CConfig(driver_config, zone_file_name, SU2_COMPONENT::SU2_DEF, iZone, nZone, true); - } - else{ - config_container[iZone] = new CConfig(driver_config, config_file_name, SU2_COMPONENT::SU2_DEF, iZone, nZone, true); - } - config_container[iZone]->SetMPICommunicator(MPICommunicator); - } - - /*--- Set the multizone part of the problem. ---*/ - if (driver_config->GetMultizone_Problem()){ - for (iZone = 0; iZone < nZone; iZone++) { - /*--- Set the interface markers for multizone ---*/ - config_container[iZone]->SetMultizone(driver_config, config_container); - } - } - - for (iZone = 0; iZone < nZone; iZone++) { - - /*--- Definition of the geometry class to store the primal grid in the partitioning process. ---*/ - - CGeometry *geometry_aux = nullptr; - - /*--- 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]); - - /*--- Build the grid data structures using the ParMETIS coloring. ---*/ - - geometry_container[iZone] = new CPhysicalGeometry(geometry_aux, config_container[iZone]); - - /*--- 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) ---*/ - - StartTime = SU2_MPI::Wtime(); - - for (iZone = 0; iZone < nZone; iZone++) { - - /*--- Computational grid preprocesing ---*/ - - if (rank == MASTER_NODE) cout << endl << "----------------------- Preprocessing computations ----------------------" << endl; - - /*--- Compute elements surrounding points, points surrounding points ---*/ - - if (rank == MASTER_NODE) cout << "Setting local point connectivity." <SetPoint_Connectivity(); - - /*--- Check the orientation before computing geometrical quantities ---*/ - - geometry_container[iZone]->SetBoundVolume(); - if (config_container[iZone]->GetReorientElements()) { - if (rank == MASTER_NODE) cout << "Checking the numerical grid orientation of the interior elements." <Check_IntElem_Orientation(config_container[iZone]); - geometry_container[iZone]->Check_BoundElem_Orientation(config_container[iZone]); - } - - /*--- Create the edge structure ---*/ - - if (rank == MASTER_NODE) cout << "Identify edges and vertices." <SetEdges(); - geometry_container[iZone]->SetVertex(config_container[iZone]); - - if (config_container[iZone]->GetDesign_Variable(0) != NO_DEFORMATION) { - - /*--- Create the dual control volume structures ---*/ - - if (rank == MASTER_NODE) cout << "Setting the bound control volume structure." << endl; - geometry_container[iZone]->SetControlVolume(config_container[iZone], ALLOCATE); - geometry_container[iZone]->SetBoundControlVolume(config_container[iZone], ALLOCATE); - - } - /*--- Create the point-to-point MPI communication structures. ---*/ - - geometry_container[iZone]->PreprocessP2PComms(geometry_container[iZone], config_container[iZone]); - - /*--- Allocate the mesh output ---*/ - - output[iZone] = new CMeshOutput(config_container[iZone], geometry_container[iZone]->GetnDim()); - - /*--- Preprocess the volume output ---*/ - - output[iZone]->PreprocessVolumeOutput(config_container[iZone]); - - /*--- Preprocess history --- */ - - output[iZone]->PreprocessHistoryOutput(config_container[iZone], false); - - } - - - /*--- Surface grid deformation using design variables ---*/ - - for (iZone = 0; iZone < nZone; iZone++){ - - if (config_container[iZone]->GetDesign_Variable(0) != NO_DEFORMATION) { - - /*--- Definition of the Class for grid movement ---*/ - grid_movement[iZone] = new CVolumetricMovement(geometry_container[iZone], config_container[iZone]); - - /*--- Save original coordinates to be reused in convexity checking procedure ---*/ - auto OriginalCoordinates = geometry_container[iZone]->nodes->GetCoord(); - - /*--- First check for volumetric grid deformation/transformations ---*/ - - if (config_container[iZone]->GetDesign_Variable(0) == SCALE_GRID) { - - if (rank == MASTER_NODE) - cout << endl << "--------------------- Volumetric grid scaling (ZONE " << iZone <<") ------------------" << endl; - grid_movement[iZone]->SetVolume_Scaling(geometry_container[iZone], config_container[iZone], false); - - } else if (config_container[iZone]->GetDesign_Variable(0) == TRANSLATE_GRID) { - - if (rank == MASTER_NODE) - cout << endl << "------------------- Volumetric grid translation (ZONE " << iZone <<") ----------------" << endl; - grid_movement[iZone]->SetVolume_Translation(geometry_container[iZone], config_container[iZone], false); - - } else if (config_container[iZone]->GetDesign_Variable(0) == ROTATE_GRID) { - - if (rank == MASTER_NODE) - cout << endl << "--------------------- Volumetric grid rotation (ZONE " << iZone <<") -----------------" << endl; - grid_movement[iZone]->SetVolume_Rotation(geometry_container[iZone], config_container[iZone], false); - - } else { - - /*--- If no volume-type deformations are requested, then this is a - surface-based deformation or FFD set up. ---*/ - - if (rank == MASTER_NODE) - cout << endl << "--------------------- Surface grid deformation (ZONE " << iZone <<") -----------------" << endl; - - /*--- Definition and initialization of the surface deformation class ---*/ - - surface_movement[iZone] = new CSurfaceMovement(); - - /*--- Copy coordinates to the surface structure ---*/ - - surface_movement[iZone]->CopyBoundary(geometry_container[iZone], config_container[iZone]); - - /*--- Surface grid deformation ---*/ - - if (rank == MASTER_NODE) cout << "Performing the deformation of the surface grid." << endl; - auto TotalDeformation = surface_movement[iZone]->SetSurface_Deformation(geometry_container[iZone], config_container[iZone]); - - if (config_container[iZone]->GetDesign_Variable(0) != FFD_SETTING) { - - if (rank == MASTER_NODE) - cout << endl << "------------------- Volumetric grid deformation (ZONE " << iZone <<") ----------------" << endl; - - if (rank == MASTER_NODE) - cout << "Performing the deformation of the volumetric grid." << endl; - grid_movement[iZone]->SetVolume_Deformation(geometry_container[iZone], config_container[iZone], false); - - /*--- Get parameters for convexity check ---*/ - bool ConvexityCheck; - unsigned short ConvexityCheck_MaxIter, ConvexityCheck_MaxDepth; - - tie(ConvexityCheck, ConvexityCheck_MaxIter, ConvexityCheck_MaxDepth) = config_container[iZone]->GetConvexityCheck(); - - /*--- Recursively change deformations if there are nonconvex elements. ---*/ - - if (ConvexityCheck && geometry_container[iZone]->GetnNonconvexElements() > 0) { - if (rank == MASTER_NODE) { - cout << "Nonconvex elements present after deformation. " << endl; - cout << "Recursively lowering deformation magnitude." << endl; - } - - /*--- Load initial deformation values ---*/ - auto InitialDeformation = TotalDeformation; - - unsigned short ConvexityCheckIter, RecursionDepth = 0; - su2double DeformationFactor = 1.0, DeformationDifference = 1.0; - for (ConvexityCheckIter = 1; ConvexityCheckIter <= ConvexityCheck_MaxIter; ConvexityCheckIter++) { - - /*--- Recursively change deformation magnitude: - decrease if there are nonconvex elements, increase otherwise ---*/ - DeformationDifference /= 2.0; - - if (geometry_container[iZone]->GetnNonconvexElements() > 0) { - DeformationFactor -= DeformationDifference; - } else { - RecursionDepth += 1; - - if (RecursionDepth == ConvexityCheck_MaxDepth) { - if (rank == MASTER_NODE) { - cout << "Maximum recursion depth reached." << endl; - cout << "Remaining amount of original deformation: "; - cout << DeformationFactor*100.0 << " percent. " << endl; - } - break; - } - - DeformationFactor += DeformationDifference; - } - - /*--- Load mesh to start every iteration with an undeformed grid ---*/ - for (auto iPoint = 0ul; iPoint < OriginalCoordinates.rows(); iPoint++) { - for (auto iDim = 0ul; iDim < OriginalCoordinates.cols(); iDim++) { - geometry_container[iZone]->nodes->SetCoord(iPoint, iDim, OriginalCoordinates(iPoint,iDim)); - } - } - - /*--- Set deformation magnitude as percentage of initial deformation ---*/ - for (auto iDV = 0u; iDV < config->GetnDV(); iDV++) { - for (auto iDV_Value = 0u; iDV_Value < config->GetnDV_Value(iDV); iDV_Value++) { - config_container[iZone]->SetDV_Value(iDV, iDV_Value, InitialDeformation[iDV][iDV_Value]*DeformationFactor); - } - } - - /*--- Surface grid deformation ---*/ - if (rank == MASTER_NODE) cout << "Performing the deformation of the surface grid." << endl; - - TotalDeformation = surface_movement[iZone]->SetSurface_Deformation(geometry_container[iZone], config_container[iZone]); - - if (rank == MASTER_NODE) - cout << endl << "------------------- Volumetric grid deformation (ZONE " << iZone <<") ----------------" << endl; - - if (rank == MASTER_NODE) - cout << "Performing the deformation of the volumetric grid." << endl; - grid_movement[iZone]->SetVolume_Deformation(geometry_container[iZone], config_container[iZone], false); - - if (rank == MASTER_NODE) { - cout << "Number of nonconvex elements for iteration " << ConvexityCheckIter << ": "; - cout << geometry_container[iZone]->GetnNonconvexElements() << endl; - cout << "Remaining amount of original deformation: "; - cout << DeformationFactor*100.0 << " percent. " << endl; - } - - } - - } - - } - - } - - } - - } - - /*--- Computational grid preprocesing ---*/ - - if (rank == MASTER_NODE) cout << endl << "----------------------- Write deformed grid files -----------------------" << endl; - - /*--- Output deformed grid for visualization, if requested (surface and volumetric), in parallel - requires to move all the data to the master node---*/ - - for (iZone = 0; iZone < nZone; iZone++){ - - /*--- Compute Mesh Quality if requested. Necessary geometry preprocessing re-done beforehand. ---*/ - - if (config_container[iZone]->GetWrt_MeshQuality() && !config->GetStructuralProblem()) { - - if (rank == MASTER_NODE) cout << "Recompute geometry properties necessary to evaluate mesh quality statistics.\n"; - - geometry_container[iZone]->SetPoint_Connectivity(); - geometry_container[iZone]->SetBoundVolume(); - geometry_container[iZone]->SetEdges(); - geometry_container[iZone]->SetVertex(config_container[iZone]); - geometry_container[iZone]->SetControlVolume(config_container[iZone], ALLOCATE); - geometry_container[iZone]->SetBoundControlVolume(config_container[iZone], ALLOCATE); - - if (rank == MASTER_NODE) cout << "Computing mesh quality statistics for the dual control volumes.\n"; - geometry_container[iZone]->ComputeMeshQualityStatistics(config_container[iZone]); - }// Mesh Quality Output - - /*--- Load the data --- */ - - output[iZone]->Load_Data(geometry_container[iZone], config_container[iZone], nullptr); - - output[iZone]->WriteToFile(config_container[iZone], geometry_container[iZone], MESH, config->GetMesh_Out_FileName()); - - /*--- Set the file names for the visualization files ---*/ - - output[iZone]->SetVolume_Filename("volume_deformed"); - output[iZone]->SetSurface_Filename("surface_deformed"); - - for (unsigned short iFile = 0; iFile < config_container[iZone]->GetnVolumeOutputFiles(); iFile++){ - auto FileFormat = config_container[iZone]->GetVolumeOutputFiles(); - if (FileFormat[iFile] != RESTART_ASCII && FileFormat[iFile] != RESTART_BINARY) - output[iZone]->WriteToFile(config_container[iZone], geometry_container[iZone], FileFormat[iFile]); - } - } - - - if ((config_container[ZONE_0]->GetDesign_Variable(0) != NO_DEFORMATION) && - (config_container[ZONE_0]->GetDesign_Variable(0) != SCALE_GRID) && - (config_container[ZONE_0]->GetDesign_Variable(0) != TRANSLATE_GRID) && - (config_container[ZONE_0]->GetDesign_Variable(0) != ROTATE_GRID)) { - - /*--- Write the the free-form deformation boxes after deformation. ---*/ - - if (rank == MASTER_NODE) cout << "Adding any FFD information to the SU2 file." << endl; - - surface_movement[ZONE_0]->WriteFFDInfo(surface_movement, geometry_container, config_container); - - } - - delete config; - config = nullptr; - if (rank == MASTER_NODE) - cout << endl <<"------------------------- Solver Postprocessing -------------------------" << endl; - - if (geometry_container != nullptr) { - for (iZone = 0; iZone < nZone; iZone++) { - if (geometry_container[iZone] != nullptr) { - delete geometry_container[iZone]; - } - } - delete [] geometry_container; - } - if (rank == MASTER_NODE) cout << "Deleted CGeometry container." << endl; - - if (surface_movement != nullptr) { - for (iZone = 0; iZone < nZone; iZone++) { - if (surface_movement[iZone] != nullptr) { - delete surface_movement[iZone]; - } - } - delete [] surface_movement; - } - if (rank == MASTER_NODE) cout << "Deleted CSurfaceMovement class." << endl; - - if (grid_movement != nullptr) { - for (iZone = 0; iZone < nZone; iZone++) { - if (grid_movement[iZone] != nullptr) { - delete grid_movement[iZone]; - } - } - delete [] grid_movement; - } - if (rank == MASTER_NODE) cout << "Deleted CVolumetricMovement class." << endl; - - if (config_container != nullptr) { - for (iZone = 0; iZone < nZone; iZone++) { - if (config_container[iZone] != nullptr) { - delete config_container[iZone]; - } - } - delete [] config_container; - } - if (output != nullptr) { - for (iZone = 0; iZone < nZone; iZone++) { - if (output[iZone] != nullptr) { - delete output[iZone]; - } - } - delete [] output; - } - if (rank == MASTER_NODE) cout << "Deleted CConfig container." << endl; - - if (rank == MASTER_NODE) cout << "Deleted COutput class." << endl; - - /*--- Synchronization point after a single solver iteration. Compute the - wall clock time required. ---*/ + /*--- Initialize the mesh deformation driver ---*/ + driver = new CDeformationDriver(config_file_name, comm); - StopTime = SU2_MPI::Wtime(); + /*--- Launch the main external loop of the solver. ---*/ - /*--- Compute/print the total time for performance benchmarking. ---*/ + driver->Run(); - 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; - } + /*--- Postprocess all the containers, close history file, exit SU2. ---*/ - /*--- Exit the solver cleanly ---*/ + driver->Postprocessing(); - if (rank == MASTER_NODE) - cout << endl << "------------------------- Exit Success (SU2_DEF) ------------------------" << endl << endl; + delete driver; /*--- Finalize MPI parallelization ---*/ SU2_MPI::Finalize(); diff --git a/SU2_DEF/src/drivers/CDeformationDriver.cpp b/SU2_DEF/src/drivers/CDeformationDriver.cpp index 529085f87e6..9ceb6b65fc5 100644 --- a/SU2_DEF/src/drivers/CDeformationDriver.cpp +++ b/SU2_DEF/src/drivers/CDeformationDriver.cpp @@ -28,9 +28,6 @@ #include "../../include/drivers/CDeformationDriver.hpp" #include "../../../Common/include/geometry/CPhysicalGeometry.hpp" -#include "../../../Common/include/grid_movement/CSurfaceMovement.hpp" -#include "../../../Common/include/grid_movement/CVolumetricMovement.hpp" -#include "../../../SU2_CFD/include/output/COutput.hpp" #include "../../../SU2_CFD/include/output/CMeshOutput.hpp" using namespace std; @@ -43,183 +40,202 @@ CDeformationDriver::CDeformationDriver(char* confFile, SU2_Comm MPICommunicator) #endif #endif - SU2_MPI::SetComm(MPICommunicator); + SU2_MPI::SetComm(MPICommunicator); + + rank = SU2_MPI::GetRank(); + size = SU2_MPI::GetSize(); /*--- Copy the config filename ---*/ strcpy(config_file_name, confFile); -} -CDeformationDriver::~CDeformationDriver(void) { + /*--- Initialize the configuration of the driver ---*/ + driver_config = new CConfig(config_file_name, SU2_COMPONENT::SU2_DEF, false); -} + nZone = driver_config->GetnZone(); + + /*--- Initialize containers --- */ + + SetContainers_Null(); + + /*--- Preprocessing of the config files. ---*/ -void CDeformationDriver::RunSolver() { + Input_Preprocessing(); - unsigned short iZone, nZone = SINGLE_ZONE; - su2double StartTime = 0.0, StopTime = 0.0, UsedTime = 0.0; - string str; + /*--- Set up a timer for performance benchmarking ---*/ - int rank = SU2_MPI::GetRank(); - int size = SU2_MPI::GetSize(); + StartTime = SU2_MPI::Wtime(); - /*--- Pointer to different structures that will be used throughout - the entire code ---*/ + for (iZone = 0; iZone < nZone; iZone++) { - CConfig **config_container = nullptr; - CGeometry **geometry_container = nullptr; - CSurfaceMovement **surface_movement = nullptr; - CVolumetricMovement **grid_movement = nullptr; - COutput **output = nullptr; - CConfig *driver_config = nullptr; + /*--- Preprocessing of the geometry for all zones. ---*/ - /*--- 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) ---*/ + Geometrical_Preprocessing(config_container[iZone], geometry_container[iZone]); - CConfig *config = nullptr; - config = new CConfig(config_file_name, SU2_COMPONENT::SU2_DEF); + /*--- Preprocessing of the output for all zones. ---*/ - nZone = config->GetnZone(); + Output_Preprocessing(config_container[iZone], geometry_container[iZone], output_container[iZone]); - /*--- Definition of the containers per zones ---*/ + } + + /*--- Preprocessing time is reported now, but not included in the next compute portion. ---*/ + + StopTime = SU2_MPI::Wtime(); + + /*--- Compute/print the total time for performance benchmarking. ---*/ + + UsedTime = StopTime-StartTime; + UsedTimePreproc = UsedTime; + UsedTimeCompute = 0.0; + +} +CDeformationDriver::~CDeformationDriver(void) { + +} + +void CDeformationDriver::SetContainers_Null() { + + /*--- Create pointers to all of the classes that may be used throughout + the SU2_DEF code. In general, the pointers are instantiated down a + hierarchy over all zones as described in the comments below. ---*/ config_container = new CConfig*[nZone]; geometry_container = new CGeometry*[nZone]; surface_movement = new CSurfaceMovement*[nZone]; grid_movement = new CVolumetricMovement*[nZone]; - output = new COutput*[nZone]; - - driver_config = nullptr; + output_container = new COutput*[nZone]; for (iZone = 0; iZone < nZone; iZone++) { - config_container[iZone] = nullptr; - geometry_container[iZone] = nullptr; - surface_movement[iZone] = nullptr; - grid_movement[iZone] = nullptr; - output[iZone] = nullptr; + config_container[iZone] = nullptr; + geometry_container[iZone] = nullptr; + surface_movement[iZone] = nullptr; + grid_movement[iZone] = nullptr; + output_container[iZone] = nullptr; } +} - /*--- Initialize the configuration of the driver ---*/ - driver_config = new CConfig(config_file_name, SU2_COMPONENT::SU2_DEF, false); +void CDeformationDriver::Input_Preprocessing() { /*--- Initialize a char to store the zone filename ---*/ char zone_file_name[MAX_STRING_SIZE]; /*--- 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. ---*/ + 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. ---*/ + /*--- 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. ---*/ - if (driver_config->GetnConfigFiles() > 0){ - strcpy(zone_file_name, driver_config->GetConfigFilename(iZone).c_str()); - config_container[iZone] = new CConfig(driver_config, zone_file_name, SU2_COMPONENT::SU2_DEF, iZone, nZone, true); - } - else{ - config_container[iZone] = new CConfig(driver_config, config_file_name, SU2_COMPONENT::SU2_DEF, iZone, nZone, true); - } - config_container[iZone]->SetMPICommunicator(SU2_MPI::GetComm()); + if (driver_config->GetnConfigFiles() > 0){ + strcpy(zone_file_name, driver_config->GetConfigFilename(iZone).c_str()); + config_container[iZone] = new CConfig(driver_config, zone_file_name, SU2_COMPONENT::SU2_DEF, iZone, nZone, true); + } else { + config_container[iZone] = new CConfig(driver_config, config_file_name, SU2_COMPONENT::SU2_DEF, iZone, nZone, true); + } + + config_container[iZone]->SetMPICommunicator(SU2_MPI::GetComm()); } - /*--- Set the multizone part of the problem. ---*/ + /*--- Set the multizone part of the problem. ---*/ if (driver_config->GetMultizone_Problem()){ - for (iZone = 0; iZone < nZone; iZone++) { - /*--- Set the interface markers for multizone ---*/ - config_container[iZone]->SetMultizone(driver_config, config_container); - } + for (iZone = 0; iZone < nZone; iZone++) { + /*--- Set the interface markers for multizone ---*/ + config_container[iZone]->SetMultizone(driver_config, config_container); + } } +} - for (iZone = 0; iZone < nZone; iZone++) { +void CDeformationDriver::Geometrical_Preprocessing(CConfig *config, CGeometry *&geometry) { - /*--- Definition of the geometry class to store the primal grid in the partitioning process. ---*/ + /*--- Definition of the geometry class to store the primal grid in the partitioning process. ---*/ - CGeometry *geometry_aux = nullptr; + CGeometry *geometry_aux = nullptr; - /*--- All ranks process the grid and call ParMETIS for partitioning ---*/ + /*--- All ranks process the grid and call ParMETIS for partitioning ---*/ - geometry_aux = new CPhysicalGeometry(config_container[iZone], iZone, nZone); + geometry_aux = new CPhysicalGeometry(config, iZone, nZone); - /*--- Color the initial grid and set the send-receive domains (ParMETIS) ---*/ + /*--- Color the initial grid and set the send-receive domains (ParMETIS) ---*/ - geometry_aux->SetColorGrid_Parallel(config_container[iZone]); + geometry_aux->SetColorGrid_Parallel(config); - /*--- Build the grid data structures using the ParMETIS coloring. ---*/ + /*--- Build the grid data structures using the ParMETIS coloring. ---*/ - geometry_container[iZone] = new CPhysicalGeometry(geometry_aux, config_container[iZone]); + geometry = new CPhysicalGeometry(geometry_aux, config); - /*--- Deallocate the memory of geometry_aux ---*/ + /*--- Deallocate the memory of geometry_aux ---*/ - delete geometry_aux; + delete geometry_aux; - /*--- Add the Send/Receive boundaries ---*/ + /*--- Add the Send/Receive boundaries ---*/ - geometry_container[iZone]->SetSendReceive(config_container[iZone]); + geometry->SetSendReceive(config); - /*--- Add the Send/Receive boundaries ---*/ + /*--- Add the Send/Receive boundaries ---*/ - geometry_container[iZone]->SetBoundaries(config_container[iZone]); + geometry->SetBoundaries(config); - } + /*--- Computational grid preprocesing ---*/ - /*--- Set up a timer for performance benchmarking (preprocessing time is included) ---*/ + if (rank == MASTER_NODE) cout << endl << "----------------------- Preprocessing computations ----------------------" << endl; - StartTime = SU2_MPI::Wtime(); + /*--- Compute elements surrounding points, points surrounding points ---*/ - for (iZone = 0; iZone < nZone; iZone++) { + if (rank == MASTER_NODE) cout << "Setting local point connectivity." <SetPoint_Connectivity(); - /*--- Computational grid preprocesing ---*/ + /*--- Check the orientation before computing geometrical quantities ---*/ - if (rank == MASTER_NODE) cout << endl << "----------------------- Preprocessing computations ----------------------" << endl; + geometry->SetBoundVolume(); + if (config->GetReorientElements()) { + if (rank == MASTER_NODE) cout << "Checking the numerical grid orientation of the interior elements." <Check_IntElem_Orientation(config); + geometry->Check_BoundElem_Orientation(config); + } - /*--- Compute elements surrounding points, points surrounding points ---*/ + /*--- Create the edge structure ---*/ - if (rank == MASTER_NODE) cout << "Setting local point connectivity." <SetPoint_Connectivity(); + if (rank == MASTER_NODE) cout << "Identify edges and vertices." <SetEdges(); + geometry->SetVertex(config); - /*--- Check the orientation before computing geometrical quantities ---*/ + if (config->GetDesign_Variable(0) != NO_DEFORMATION) { - geometry_container[iZone]->SetBoundVolume(); - if (config_container[iZone]->GetReorientElements()) { - if (rank == MASTER_NODE) cout << "Checking the numerical grid orientation of the interior elements." <Check_IntElem_Orientation(config_container[iZone]); - geometry_container[iZone]->Check_BoundElem_Orientation(config_container[iZone]); - } + /*--- Create the dual control volume structures ---*/ - /*--- Create the edge structure ---*/ + if (rank == MASTER_NODE) cout << "Setting the bound control volume structure." << endl; + geometry->SetControlVolume(config, ALLOCATE); + geometry->SetBoundControlVolume(config, ALLOCATE); + } - if (rank == MASTER_NODE) cout << "Identify edges and vertices." <SetEdges(); - geometry_container[iZone]->SetVertex(config_container[iZone]); + /*--- Create the point-to-point MPI communication structures. ---*/ - if (config_container[iZone]->GetDesign_Variable(0) != NO_DEFORMATION) { + geometry->PreprocessP2PComms(geometry, config); - /*--- Create the dual control volume structures ---*/ +} - if (rank == MASTER_NODE) cout << "Setting the bound control volume structure." << endl; - geometry_container[iZone]->SetControlVolume(config_container[iZone], ALLOCATE); - geometry_container[iZone]->SetBoundControlVolume(config_container[iZone], ALLOCATE); +void CDeformationDriver::Output_Preprocessing(CConfig *config, CGeometry *geometry, COutput *&output) { - } - /*--- Create the point-to-point MPI communication structures. ---*/ + /*--- Allocate the mesh output ---*/ - geometry_container[iZone]->PreprocessP2PComms(geometry_container[iZone], config_container[iZone]); + output = new CMeshOutput(config, geometry->GetnDim()); - /*--- Allocate the mesh output ---*/ + /*--- Preprocess the volume output ---*/ - output[iZone] = new CMeshOutput(config_container[iZone], geometry_container[iZone]->GetnDim()); + output->PreprocessVolumeOutput(config); - /*--- Preprocess the volume output ---*/ + /*--- Preprocess history --- */ - output[iZone]->PreprocessVolumeOutput(config_container[iZone]); + output->PreprocessHistoryOutput(config, false); +} - /*--- Preprocess history --- */ +void CDeformationDriver::Run() { - output[iZone]->PreprocessHistoryOutput(config_container[iZone], false); - } + /* --- Start measuring computation time ---*/ + + StartTime = SU2_MPI::Wtime(); /*--- Surface grid deformation using design variables ---*/ @@ -333,8 +349,8 @@ void CDeformationDriver::RunSolver() { } /*--- Set deformation magnitude as percentage of initial deformation ---*/ - for (auto iDV = 0u; iDV < config->GetnDV(); iDV++) { - for (auto iDV_Value = 0u; iDV_Value < config->GetnDV_Value(iDV); iDV_Value++) { + for (auto iDV = 0u; iDV < driver_config->GetnDV(); iDV++) { + for (auto iDV_Value = 0u; iDV_Value < driver_config->GetnDV_Value(iDV); iDV_Value++) { config_container[iZone]->SetDV_Value(iDV, iDV_Value, InitialDeformation[iDV][iDV_Value]*DeformationFactor); } } @@ -381,7 +397,7 @@ void CDeformationDriver::RunSolver() { /*--- Compute Mesh Quality if requested. Necessary geometry preprocessing re-done beforehand. ---*/ - if (config_container[iZone]->GetWrt_MeshQuality() && !config->GetStructuralProblem()) { + if (config_container[iZone]->GetWrt_MeshQuality() && !driver_config->GetStructuralProblem()) { if (rank == MASTER_NODE) cout << "Recompute geometry properties necessary to evaluate mesh quality statistics.\n"; @@ -398,19 +414,19 @@ void CDeformationDriver::RunSolver() { /*--- Load the data --- */ - output[iZone]->Load_Data(geometry_container[iZone], config_container[iZone], nullptr); + output_container[iZone]->Load_Data(geometry_container[iZone], config_container[iZone], nullptr); - output[iZone]->WriteToFile(config_container[iZone], geometry_container[iZone], MESH, config->GetMesh_Out_FileName()); + output_container[iZone]->WriteToFile(config_container[iZone], geometry_container[iZone], MESH, driver_config->GetMesh_Out_FileName()); /*--- Set the file names for the visualization files ---*/ - output[iZone]->SetVolume_Filename("volume_deformed"); - output[iZone]->SetSurface_Filename("surface_deformed"); + output_container[iZone]->SetVolume_Filename("volume_deformed"); + output_container[iZone]->SetSurface_Filename("surface_deformed"); for (unsigned short iFile = 0; iFile < config_container[iZone]->GetnVolumeOutputFiles(); iFile++){ auto FileFormat = config_container[iZone]->GetVolumeOutputFiles(); if (FileFormat[iFile] != RESTART_ASCII && FileFormat[iFile] != RESTART_BINARY) - output[iZone]->WriteToFile(config_container[iZone], geometry_container[iZone], FileFormat[iFile]); + output_container[iZone]->WriteToFile(config_container[iZone], geometry_container[iZone], FileFormat[iFile]); } } @@ -427,12 +443,15 @@ void CDeformationDriver::RunSolver() { surface_movement[ZONE_0]->WriteFFDInfo(surface_movement, geometry_container, config_container); } +} - delete config; - config = nullptr; +void CDeformationDriver::Postprocessing() { if (rank == MASTER_NODE) cout << endl <<"------------------------- Solver Postprocessing -------------------------" << endl; + delete driver_config; + driver_config = nullptr; + if (geometry_container != nullptr) { for (iZone = 0; iZone < nZone; iZone++) { if (geometry_container[iZone] != nullptr) { @@ -471,13 +490,13 @@ void CDeformationDriver::RunSolver() { } delete [] config_container; } - if (output != nullptr) { + if (output_container != nullptr) { for (iZone = 0; iZone < nZone; iZone++) { - if (output[iZone] != nullptr) { - delete output[iZone]; + if (output_container[iZone] != nullptr) { + delete output_container[iZone]; } } - delete [] output; + delete [] output_container; } if (rank == MASTER_NODE) cout << "Deleted CConfig container." << endl; @@ -488,11 +507,9 @@ void CDeformationDriver::RunSolver() { StopTime = SU2_MPI::Wtime(); - /*--- Compute/print the total time for performance benchmarking. ---*/ - - UsedTime = StopTime-StartTime; + UsedTimeCompute = StopTime-StartTime; if (rank == MASTER_NODE) { - cout << "\nCompleted in " << fixed << UsedTime << " seconds on "<< size; + cout << "\nCompleted in " << fixed << UsedTimeCompute << " seconds on "<< size; if (size == 1) cout << " core." << endl; else cout << " cores." << endl; } From b9838977be491aa8b529b69b6d7839f5db980a83 Mon Sep 17 00:00:00 2001 From: aa-g Date: Wed, 26 May 2021 01:17:28 +0200 Subject: [PATCH 04/68] Minor fixes in CDeformationDriver --- .../include/drivers/CDeformationDriver.hpp | 11 ++---- SU2_DEF/src/drivers/CDeformationDriver.cpp | 38 ++++++++++--------- 2 files changed, 24 insertions(+), 25 deletions(-) diff --git a/SU2_DEF/include/drivers/CDeformationDriver.hpp b/SU2_DEF/include/drivers/CDeformationDriver.hpp index b76a2919976..905cdf106c6 100644 --- a/SU2_DEF/include/drivers/CDeformationDriver.hpp +++ b/SU2_DEF/include/drivers/CDeformationDriver.hpp @@ -1,7 +1,6 @@ /*! * \file CDeformationDriver.hpp - * \brief Headers of the main subroutines for driving single or multi-zone problems. - * The subroutines and functions are in the driver_structure.cpp file. + * \brief Headers of the main subroutines for driving the mesh deformation. * \author T. Economon, H. Kline, R. Sanchez * \version 7.1.1 "Blackbird" * @@ -37,8 +36,8 @@ /*! * \class CDeformationDriver - * \brief Class for driving single-zone solvers. - * \author R. Sanchez + * \brief Class for driving mesh deformation solvers. + * \author A. Gastaldi, H. Patel * \version 7.1.1 "Blackbird" */ class CDeformationDriver { @@ -58,7 +57,6 @@ class CDeformationDriver { CSurfaceMovement **surface_movement; /*!< \brief Surface movement classes of the problem. */ CVolumetricMovement **grid_movement; /*!< \brief Volume grid movement classes of the problem. */ COutput **output_container; /*!< \brief Pointer to the COutput class. */ - /*!< \brief FFD FFDBoxes of the problem. */ public: /*! @@ -66,8 +64,7 @@ class CDeformationDriver { * \param[in] confFile - Configuration file name. * \param[in] MPICommunicator - MPI communicator for SU2. */ - CDeformationDriver(char* confFile, - SU2_Comm MPICommunicator); + CDeformationDriver(char* confFile, SU2_Comm MPICommunicator); /*! * \brief Destructor of the class. diff --git a/SU2_DEF/src/drivers/CDeformationDriver.cpp b/SU2_DEF/src/drivers/CDeformationDriver.cpp index 9ceb6b65fc5..eb4524c6376 100644 --- a/SU2_DEF/src/drivers/CDeformationDriver.cpp +++ b/SU2_DEF/src/drivers/CDeformationDriver.cpp @@ -1,7 +1,7 @@ /*! - * \file SU2_DEF.cpp - * \brief Main file of Mesh Deformation Code (SU2_DEF). - * \author F. Palacios, T. Economon + * \file CDeformationDriver.hpp + * \brief Main subroutines for driving the mesh deformation. + * \author T. Economon, H. Kline, R. Sanchez * \version 7.1.1 "Blackbird" * * SU2 Project Website: https://su2code.github.io @@ -27,8 +27,10 @@ #include "../../include/drivers/CDeformationDriver.hpp" + #include "../../../Common/include/geometry/CPhysicalGeometry.hpp" #include "../../../SU2_CFD/include/output/CMeshOutput.hpp" + using namespace std; CDeformationDriver::CDeformationDriver(char* confFile, SU2_Comm MPICommunicator) { @@ -49,9 +51,10 @@ CDeformationDriver::CDeformationDriver(char* confFile, SU2_Comm MPICommunicator) strcpy(config_file_name, confFile); /*--- Initialize the configuration of the driver ---*/ - driver_config = new CConfig(config_file_name, SU2_COMPONENT::SU2_DEF, false); + driver_config = nullptr; + driver_config = new CConfig(config_file_name, SU2_COMPONENT::SU2_DEF); - nZone = driver_config->GetnZone(); + nZone = driver_config->GetnZone(); /*--- Initialize containers --- */ @@ -430,7 +433,6 @@ void CDeformationDriver::Run() { } } - if ((config_container[ZONE_0]->GetDesign_Variable(0) != NO_DEFORMATION) && (config_container[ZONE_0]->GetDesign_Variable(0) != SCALE_GRID) && (config_container[ZONE_0]->GetDesign_Variable(0) != TRANSLATE_GRID) && @@ -443,6 +445,17 @@ void CDeformationDriver::Run() { surface_movement[ZONE_0]->WriteFFDInfo(surface_movement, geometry_container, config_container); } + + /*--- Synchronization point after a single solver iteration. Compute the + wall clock time required. ---*/ + + StopTime = SU2_MPI::Wtime(); + + UsedTimeCompute = StopTime-StartTime; + if (rank == MASTER_NODE) { + cout << "\nCompleted in " << fixed << UsedTimeCompute << " seconds on "<< size; + if (size == 1) cout << " core." << endl; else cout << " cores." << endl; + } } void CDeformationDriver::Postprocessing() { @@ -502,19 +515,8 @@ void CDeformationDriver::Postprocessing() { if (rank == MASTER_NODE) cout << "Deleted COutput class." << endl; - /*--- Synchronization point after a single solver iteration. Compute the - wall clock time required. ---*/ - - StopTime = SU2_MPI::Wtime(); - - UsedTimeCompute = StopTime-StartTime; - if (rank == MASTER_NODE) { - cout << "\nCompleted in " << fixed << UsedTimeCompute << " seconds on "<< size; - if (size == 1) cout << " core." << endl; else cout << " cores." << endl; - } - /*--- Exit the solver cleanly ---*/ if (rank == MASTER_NODE) cout << endl << "------------------------- Exit Success (SU2_DEF) ------------------------" << endl << endl; - } +} From 6facf5b1fe5b49b9f97430ee1f46f3ed978d4cd4 Mon Sep 17 00:00:00 2001 From: aa-g Date: Tue, 1 Jun 2021 21:36:01 +0200 Subject: [PATCH 05/68] Add CDiscAdjDeformationDriver --- .../include/drivers/CDeformationDriver.hpp | 4 +- .../drivers/CDiscAdjDeformationDriver.hpp | 155 +++ SU2_DEF/src/drivers/CDeformationDriver.cpp | 61 +- .../src/drivers/CDiscAdjDeformationDriver.cpp | 945 ++++++++++++++++++ SU2_DEF/src/meson.build | 44 +- SU2_DOT/src/meson.build | 9 +- SU2_PY/pySU2/meson.build | 10 +- SU2_PY/pySU2/pySU2ad.i | 2 + 8 files changed, 1192 insertions(+), 38 deletions(-) create mode 100644 SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp create mode 100644 SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp diff --git a/SU2_DEF/include/drivers/CDeformationDriver.hpp b/SU2_DEF/include/drivers/CDeformationDriver.hpp index 905cdf106c6..8a424ff32fd 100644 --- a/SU2_DEF/include/drivers/CDeformationDriver.hpp +++ b/SU2_DEF/include/drivers/CDeformationDriver.hpp @@ -95,11 +95,11 @@ class CDeformationDriver { /*! * \brief Construction of the edge-based data structure. */ - void Geometrical_Preprocessing(CConfig *config, CGeometry *&geometry); + void Geometrical_Preprocessing(); /*! * \brief Preprocess the output container. */ - void Output_Preprocessing(CConfig *config, CGeometry *geometry, COutput *&output); + void Output_Preprocessing(); }; diff --git a/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp b/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp new file mode 100644 index 00000000000..f3635ab694b --- /dev/null +++ b/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp @@ -0,0 +1,155 @@ +/*! +* \file CDiscAdjDeformationDriver.cpp +* \brief Main subroutines for driving the projection of sensitivities. + * \author T. Economon, H. Kline, R. Sanchez + * \version 7.1.1 "Blackbird" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2021, SU2 Contributors (cf. AUTHORS.md) + * + * SU2 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * SU2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SU2. If not, see . + */ + +#pragma once + +#define ENABLE_MAPS +#include "../../../Common/include/CConfig.hpp" +#undef ENABLE_MAPS + +#include "../../../Common/include/parallelization/mpi_structure.hpp" + +#include "../../../Common/include/geometry/CGeometry.hpp" +#include "../../../Common/include/fem/fem_geometry_structure.hpp" +#include "../../../Common/include/grid_movement/CSurfaceMovement.hpp" +#include "../../../Common/include/grid_movement/CVolumetricMovement.hpp" +#include "../../../SU2_CFD/include/output/COutput.hpp" +#include "../../../SU2_CFD/include/output/CBaselineOutput.hpp" +#include "../../../SU2_CFD/include/solvers/CBaselineSolver.hpp" + +/*! + * \class CDiscAdjDeformationDriver + * \brief Class for driving sensitivity DiscAdjDeformations. + * \author A. Gastaldi, H. Patel + * \version 7.1.1 "Blackbird" + */ +class CDiscAdjDeformationDriver { +protected: + char config_file_name[MAX_STRING_SIZE]; + int rank, + size; + unsigned short iZone, nZone = SINGLE_ZONE; + unsigned short iInst; + unsigned short* nInst; + su2double StartTime, /*!< \brief Start point of the timer for performance benchmarking.*/ + StopTime, /*!< \brief Stop point of the timer for performance benchmarking.*/ + UsedTimePreproc, /*!< \brief Elapsed time between Start and Stop point of the timer for tracking preprocessing phase.*/ + UsedTimeCompute, /*!< \brief Elapsed time between Start and Stop point of the timer for tracking compute phase.*/ + UsedTime; /*!< \brief Elapsed time between Start and Stop point of the timer.*/ + su2double** Gradient; + ofstream Gradient_file; + CConfig *driver_config; /*!< \brief Definition of the driver configuration. */ + CConfig **config_container; /*!< \brief Definition of the particular problem. */ + CGeometry ***geometry_container; /*!< \brief Geometrical definition of the problem. */ + CSurfaceMovement **surface_movement; + CVolumetricMovement **grid_movement; + COutput **output_container; /*!< \brief Pointer to the COutput class. */ + +public: + /*! + * \brief Constructor of the class. + * \param[in] confFile - Configuration file name. + * \param[in] MPICommunicator - MPI communicator for SU2. + */ + CDiscAdjDeformationDriver(char* confFile, SU2_Comm MPICommunicator); + + /*! + * \brief Destructor of the class. + */ + ~CDiscAdjDeformationDriver(void); + + /*! + * \brief [Overload] Launch the computation for single-zone problems. + */ + void Run(); + + /*! + * \brief Deallocation routine + */ + void Postprocessing(); + +protected: + /*! + * \brief Init_Containers + */ + void SetContainers_Null(); + + /*! + * \brief Read in the config and mesh files. + */ + void Input_Preprocessing(); + + /*! + * \brief Construction of the edge-based data structure. + */ + void Geometrical_Preprocessing(); + + /*! + * \brief Preprocess the output container. + */ + void Output_Preprocessing(); + + /*! + * \brief DiscAdjDeformation of the surface sensitivity using finite differences (FD). + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] surface_movement - Surface movement class of the problem. + * \param[in] Gradient_file - Output file to store the gradient data. + */ + + void SetDiscAdjDeformation_FD(CGeometry *geometry, CConfig *config, CSurfaceMovement *surface_movement, su2double **Gradient); + + /*! + * \brief DiscAdjDeformation of the surface sensitivity using algorithmic differentiation (AD). + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] surface_movement - Surface movement class of the problem. + * \param[in] Gradient_file - Output file to store the gradient data. + */ + + void SetDiscAdjDeformation_AD(CGeometry *geometry, CConfig *config, CSurfaceMovement *surface_movement, su2double **Gradient); + + /*! + * \brief Prints the gradient information to a file. + * \param[in] Gradient - The gradient data. + * \param[in] config - Definition of the particular problem. + * \param[in] Gradient_file - Output file to store the gradient data. + */ + + void OutputGradient(su2double** Gradient, CConfig* config, ofstream& Gradient_file); + + /*! + * \brief Write the sensitivity (including mesh sensitivity) computed with the discrete adjoint method + * on the surface and in the volume to a file. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] val_nZone - Number of Zones. + */ + + void SetSensitivity_Files(CGeometry ***geometry, CConfig **config, unsigned short val_nZone); + +}; diff --git a/SU2_DEF/src/drivers/CDeformationDriver.cpp b/SU2_DEF/src/drivers/CDeformationDriver.cpp index eb4524c6376..b12d24154a9 100644 --- a/SU2_DEF/src/drivers/CDeformationDriver.cpp +++ b/SU2_DEF/src/drivers/CDeformationDriver.cpp @@ -68,17 +68,13 @@ CDeformationDriver::CDeformationDriver(char* confFile, SU2_Comm MPICommunicator) StartTime = SU2_MPI::Wtime(); - for (iZone = 0; iZone < nZone; iZone++) { + /*--- Preprocessing of the geometry for all zones. ---*/ - /*--- Preprocessing of the geometry for all zones. ---*/ + Geometrical_Preprocessing(); - Geometrical_Preprocessing(config_container[iZone], geometry_container[iZone]); + /*--- Preprocessing of the output for all zones. ---*/ - /*--- Preprocessing of the output for all zones. ---*/ - - Output_Preprocessing(config_container[iZone], geometry_container[iZone], output_container[iZone]); - - } + Output_Preprocessing(); /*--- Preprocessing time is reported now, but not included in the next compute portion. ---*/ @@ -150,7 +146,9 @@ void CDeformationDriver::Input_Preprocessing() { } } -void CDeformationDriver::Geometrical_Preprocessing(CConfig *config, CGeometry *&geometry) { +void CDeformationDriver::Geometrical_Preprocessing() { + + for (iZone = 0; iZone < nZone; iZone++) { /*--- Definition of the geometry class to store the primal grid in the partitioning process. ---*/ @@ -158,15 +156,15 @@ void CDeformationDriver::Geometrical_Preprocessing(CConfig *config, CGeometry *& /*--- All ranks process the grid and call ParMETIS for partitioning ---*/ - geometry_aux = new CPhysicalGeometry(config, iZone, nZone); + 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); + geometry_aux->SetColorGrid_Parallel(config_container[iZone]); /*--- Build the grid data structures using the ParMETIS coloring. ---*/ - geometry = new CPhysicalGeometry(geometry_aux, config); + geometry_container[iZone] = new CPhysicalGeometry(geometry_aux, config_container[iZone]); /*--- Deallocate the memory of geometry_aux ---*/ @@ -174,11 +172,11 @@ void CDeformationDriver::Geometrical_Preprocessing(CConfig *config, CGeometry *& /*--- Add the Send/Receive boundaries ---*/ - geometry->SetSendReceive(config); + geometry_container[iZone]->SetSendReceive(config_container[iZone]); /*--- Add the Send/Receive boundaries ---*/ - geometry->SetBoundaries(config); + geometry_container[iZone]->SetBoundaries(config_container[iZone]); /*--- Computational grid preprocesing ---*/ @@ -187,51 +185,56 @@ void CDeformationDriver::Geometrical_Preprocessing(CConfig *config, CGeometry *& /*--- Compute elements surrounding points, points surrounding points ---*/ if (rank == MASTER_NODE) cout << "Setting local point connectivity." <SetPoint_Connectivity(); + geometry_container[iZone]->SetPoint_Connectivity(); /*--- Check the orientation before computing geometrical quantities ---*/ - geometry->SetBoundVolume(); - if (config->GetReorientElements()) { + geometry_container[iZone]->SetBoundVolume(); + if (config_container[iZone]->GetReorientElements()) { if (rank == MASTER_NODE) cout << "Checking the numerical grid orientation of the interior elements." <Check_IntElem_Orientation(config); - geometry->Check_BoundElem_Orientation(config); + geometry_container[iZone]->Check_IntElem_Orientation(config_container[iZone]); + geometry_container[iZone]->Check_BoundElem_Orientation(config_container[iZone]); } /*--- Create the edge structure ---*/ if (rank == MASTER_NODE) cout << "Identify edges and vertices." <SetEdges(); - geometry->SetVertex(config); + geometry_container[iZone]->SetEdges(); + geometry_container[iZone]->SetVertex(config_container[iZone]); - if (config->GetDesign_Variable(0) != NO_DEFORMATION) { + if (config_container[iZone]->GetDesign_Variable(0) != NO_DEFORMATION) { /*--- Create the dual control volume structures ---*/ if (rank == MASTER_NODE) cout << "Setting the bound control volume structure." << endl; - geometry->SetControlVolume(config, ALLOCATE); - geometry->SetBoundControlVolume(config, ALLOCATE); + geometry_container[iZone]->SetControlVolume(config_container[iZone], ALLOCATE); + geometry_container[iZone]->SetBoundControlVolume(config_container[iZone], ALLOCATE); } /*--- Create the point-to-point MPI communication structures. ---*/ - geometry->PreprocessP2PComms(geometry, config); + geometry_container[iZone]->PreprocessP2PComms(geometry_container[iZone], config_container[iZone]); + } } -void CDeformationDriver::Output_Preprocessing(CConfig *config, CGeometry *geometry, COutput *&output) { +void CDeformationDriver::Output_Preprocessing() { + + for (iZone = 0; iZone < nZone; iZone++) { /*--- Allocate the mesh output ---*/ - output = new CMeshOutput(config, geometry->GetnDim()); + output_container[iZone] = new CMeshOutput(config_container[iZone], geometry_container[iZone]->GetnDim()); /*--- Preprocess the volume output ---*/ - output->PreprocessVolumeOutput(config); + output_container[iZone]->PreprocessVolumeOutput(config_container[iZone]); /*--- Preprocess history --- */ - output->PreprocessHistoryOutput(config, false); + output_container[iZone]->PreprocessHistoryOutput(config_container[iZone], false); + + } } void CDeformationDriver::Run() { diff --git a/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp b/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp new file mode 100644 index 00000000000..923901fee8b --- /dev/null +++ b/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp @@ -0,0 +1,945 @@ +/*! + * \file CDiscAdjDeformationDriver.cpp + * \brief Main subroutines for driving the projection of sensitivities. + * \author T. Economon, H. Kline, R. Sanchez + * \version 7.1.1 "Blackbird" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2021, SU2 Contributors (cf. AUTHORS.md) + * + * SU2 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * SU2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SU2. If not, see . + */ + +#include "../../include/drivers/CDiscAdjDeformationDriver.hpp" + +#include "../../../Common/include/geometry/CPhysicalGeometry.hpp" + +using namespace std; + +CDiscAdjDeformationDriver::CDiscAdjDeformationDriver(char* confFile, SU2_Comm MPICommunicator) { + + /*--- Initialize Medipack (must also be here so it is initialized from python) ---*/ + #ifdef HAVE_MPI + #if defined(CODI_REVERSE_TYPE) || defined(CODI_FORWARD_TYPE) + SU2_MPI::Init_AMPI(); + #endif + #endif + + SU2_MPI::SetComm(MPICommunicator); + + rank = SU2_MPI::GetRank(); + size = SU2_MPI::GetSize(); + + /*--- Copy the config filename ---*/ + strcpy(config_file_name, confFile); + + /*--- 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) ---*/ + + driver_config = new CConfig(config_file_name, SU2_COMPONENT::SU2_DOT); + + nZone = driver_config->GetnZone(); + + /*--- Initialize containers --- */ + + SetContainers_Null(); + + /*--- Preprocessing of the config files. ---*/ + + Input_Preprocessing(); + + /*--- Set up a timer for performance benchmarking ---*/ + + StartTime = SU2_MPI::Wtime(); + + /*--- Preprocessing of the geometry for all zones. ---*/ + + Geometrical_Preprocessing(); + + /*--- Preprocessing of the outputs for all zones. ---*/ + + Output_Preprocessing(); + + /*--- Preprocessing time is reported now, but not included in the next compute portion. ---*/ + + StopTime = SU2_MPI::Wtime(); + + /*--- Compute/print the total time for performance benchmarking. ---*/ + + UsedTime = StopTime-StartTime; + UsedTimePreproc = UsedTime; + UsedTimeCompute = 0.0; + +} + +CDiscAdjDeformationDriver::~CDiscAdjDeformationDriver(void) { + +} + +void CDiscAdjDeformationDriver::SetContainers_Null() { + + /*--- Definition of the containers per zones ---*/ + + config_container = new CConfig*[nZone] (); + geometry_container = new CGeometry**[nZone] (); + surface_movement = new CSurfaceMovement*[nZone] (); + grid_movement = new CVolumetricMovement*[nZone] (); + + nInst = new unsigned short[nZone]; + for (iZone = 0; iZone < nZone; iZone++) { + nInst[iZone] = 1; + } +} + +void CDiscAdjDeformationDriver::Input_Preprocessing() { + + // TODO Check that config is for Discrete Adjoint ! + + /*--- Initialize a char to store the zone filename ---*/ + char zone_file_name[MAX_STRING_SIZE]; + + /*--- 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. ---*/ + + if (driver_config->GetnConfigFiles() > 0){ + strcpy(zone_file_name, driver_config->GetConfigFilename(iZone).c_str()); + config_container[iZone] = new CConfig(driver_config, zone_file_name, SU2_COMPONENT::SU2_DOT, iZone, nZone, true); + } else { + config_container[iZone] = new CConfig(driver_config, config_file_name, SU2_COMPONENT::SU2_DOT, iZone, nZone, true); + } + + config_container[iZone]->SetMPICommunicator(SU2_MPI::GetComm()); + } + + /*--- Set the multizone part of the problem. ---*/ + if (driver_config->GetMultizone_Problem()){ + for (iZone = 0; iZone < nZone; iZone++) { + /*--- Set the interface markers for multizone ---*/ + config_container[iZone]->SetMultizone(driver_config, config_container); + } + } +} + +void CDiscAdjDeformationDriver::Geometrical_Preprocessing() { + + /*--- 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++) { + + /*--- Determine whether or not the FEM solver is used, which decides the + type of geometry classes that are instantiated. ---*/ + const bool fem_solver = config_container[iZone]->GetFEMSolver(); + + /*--- Read the number of instances for each zone ---*/ + + nInst[iZone] = config_container[iZone]->GetnTimeInstances(); + + geometry_container[iZone] = new CGeometry*[nInst[iZone]]; + + for (iInst = 0; iInst < nInst[iZone]; iInst++){ + + /*--- Definition of the geometry class to store the primal grid in the partitioning process. ---*/ + + CGeometry *geometry_aux = nullptr; + + /*--- 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) ---*/ + + if ( fem_solver ) geometry_aux->SetColorFEMGrid_Parallel(config_container[iZone]); + else geometry_aux->SetColorGrid_Parallel(config_container[iZone]); + + /*--- Build the grid data structures using the ParMETIS coloring. ---*/ + + if( fem_solver ) { + switch( config_container[iZone]->GetKind_FEM_Flow() ) { + case DG: { + geometry_container[iZone][iInst] = new CMeshFEM_DG(geometry_aux, config_container[iZone]); + break; + } + } + } + else { + geometry_container[iZone][iInst] = new CPhysicalGeometry(geometry_aux, config_container[iZone]); + } + + /*--- Deallocate the memory of geometry_aux ---*/ + + delete geometry_aux; + + /*--- Add the Send/Receive boundaries ---*/ + + geometry_container[iZone][iInst]->SetSendReceive(config_container[iZone]); + + /*--- Add the Send/Receive boundaries ---*/ + + geometry_container[iZone][iInst]->SetBoundaries(config_container[iZone]); + + /*--- Create the vertex structure (required for MPI) ---*/ + + if (rank == MASTER_NODE) cout << "Identify vertices." << endl; + geometry_container[iZone][iInst]->SetVertex(config_container[iZone]); + + /*--- Store the global to local mapping after preprocessing. ---*/ + + if (rank == MASTER_NODE) cout << "Storing a mapping from global to local point index." << endl; + geometry_container[iZone][iInst]->SetGlobal_to_Local_Point(); + + /* Test for a fem solver, because some more work must be done. */ + + if (fem_solver) { + + /*--- Carry out a dynamic cast to CMeshFEM_DG, such that it is not needed to + define all virtual functions in the base class CGeometry. ---*/ + CMeshFEM_DG *DGMesh = dynamic_cast(geometry_container[iZone][iInst]); + + /*--- Determine the standard elements for the volume elements. ---*/ + if (rank == MASTER_NODE) cout << "Creating standard volume elements." << endl; + DGMesh->CreateStandardVolumeElements(config_container[iZone]); + + /*--- Create the face information needed to compute the contour integral + for the elements in the Discontinuous Galerkin formulation. ---*/ + if (rank == MASTER_NODE) cout << "Creating face information." << endl; + DGMesh->CreateFaces(config_container[iZone]); + } + } + + if (rank == MASTER_NODE) + cout << "\n----------------------- Preprocessing computations ----------------------" << endl; + + /*--- Compute elements surrounding points, points surrounding points ---*/ + + if (rank == MASTER_NODE) cout << "Setting local point connectivity." << endl; + geometry_container[iZone][INST_0]->SetPoint_Connectivity(); + + /*--- Check the orientation before computing geometrical quantities ---*/ + + geometry_container[iZone][INST_0]->SetBoundVolume(); + if (config_container[iZone]->GetReorientElements()) { + if (rank == MASTER_NODE) cout << "Checking the numerical grid orientation of the elements." << endl; + geometry_container[iZone][INST_0]->Check_IntElem_Orientation(config_container[iZone]); + geometry_container[iZone][INST_0]->Check_BoundElem_Orientation(config_container[iZone]); + } + + /*--- Create the edge structure ---*/ + + if (rank == MASTER_NODE) cout << "Identify edges and vertices." << endl; + geometry_container[iZone][INST_0]->SetEdges(); geometry_container[iZone][INST_0]->SetVertex(config_container[iZone]); + + /*--- Create the dual control volume structures ---*/ + + if (rank == MASTER_NODE) cout << "Setting the bound control volume structure." << endl; + geometry_container[iZone][INST_0]->SetBoundControlVolume(config_container[ZONE_0], ALLOCATE); + + /*--- Store the global to local mapping after preprocessing. ---*/ + + if (rank == MASTER_NODE) cout << "Storing a mapping from global to local point index." << endl; + geometry_container[iZone][INST_0]->SetGlobal_to_Local_Point(); + + /*--- Create the point-to-point MPI communication structures. ---*/ + + geometry_container[iZone][INST_0]->PreprocessP2PComms(geometry_container[iZone][INST_0], config_container[iZone]); + + } +} + +void CDiscAdjDeformationDriver::Output_Preprocessing() { + +} + +void CDiscAdjDeformationDriver::Run() { + + for (iZone = 0; iZone < nZone; iZone++) { + if (rank == MASTER_NODE) cout << "Reading volume sensitivities at each node from file." << endl; + grid_movement[iZone] = new CVolumetricMovement(geometry_container[iZone][INST_0], config_container[iZone]); + + /*--- Read in sensitivities from file. ---*/ + if (config_container[ZONE_0]->GetSensitivity_Format() == UNORDERED_ASCII) + geometry_container[iZone][INST_0]->ReadUnorderedSensitivity(config_container[iZone]); + else + geometry_container[iZone][INST_0]->SetSensitivity(config_container[iZone]); + + if (rank == MASTER_NODE) cout << "\n---------------------- Mesh sensitivity computation ---------------------" << endl; + grid_movement[iZone]->SetVolume_Deformation(geometry_container[iZone][INST_0], config_container[iZone], false, true); + } + + if (rank == MASTER_NODE) cout << "\n------------------------ Mesh sensitivity Output ------------------------" << endl; + SetSensitivity_Files(geometry_container, config_container, nZone); + + /*--- Initialize structure to store the gradient ---*/ + Gradient = new su2double*[config_container[ZONE_0]->GetnDV()]; + + for (auto iDV = 0u; iDV < config_container[ZONE_0]->GetnDV(); iDV++) { + /*--- Initialize to zero ---*/ + Gradient[iDV] = new su2double[config_container[ZONE_0]->GetnDV_Value(iDV)](); + } + + Gradient_file.precision(driver_config->OptionIsSet("OUTPUT_PRECISION") ? driver_config->GetOutput_Precision() : 6); + + /*--- For multizone computations the gradient contributions are summed up and written into one file. ---*/ + for (iZone = 0; iZone < nZone; iZone++){ + if ((config_container[iZone]->GetDesign_Variable(0) != NONE) && + (config_container[iZone]->GetDesign_Variable(0) != SURFACE_FILE)) { + + if (rank == MASTER_NODE) + cout << "\n---------- Start gradient evaluation using sensitivity information ----------" << endl; + + /*--- Definition of the Class for surface deformation ---*/ + + surface_movement[iZone] = new CSurfaceMovement(); + + /*--- Copy coordinates to the surface structure ---*/ + + surface_movement[iZone]->CopyBoundary(geometry_container[iZone][INST_0], config_container[iZone]); + + /*--- If AD mode is enabled we can use it to compute the projection, + * otherwise we use finite differences. ---*/ + + if (config_container[iZone]->GetAD_Mode()) + SetDiscAdjDeformation_AD(geometry_container[iZone][INST_0], config_container[iZone], surface_movement[iZone] , Gradient); + else + SetDiscAdjDeformation_FD(geometry_container[iZone][INST_0], config_container[iZone], surface_movement[iZone] , Gradient); + + } + } // for iZone + + /*--- Write the gradient to a file ---*/ + + if (rank == MASTER_NODE) + Gradient_file.open(config_container[ZONE_0]->GetObjFunc_Grad_FileName().c_str(), ios::out); + + /*--- Print gradients to screen and writes to file ---*/ + + OutputGradient(Gradient, config_container[ZONE_0], Gradient_file); + +} + +void CDiscAdjDeformationDriver::Postprocessing() { + + for (auto iDV = 0u; iDV < config_container[ZONE_0]->GetnDV(); iDV++){ + delete [] Gradient[iDV]; + } + delete [] Gradient; + + delete driver_config; + driver_config = nullptr; + + if (rank == MASTER_NODE) + cout << "\n------------------------- Solver Postprocessing -------------------------" << endl; + + if (geometry_container != nullptr) { + for (iZone = 0; iZone < nZone; iZone++) { + if (geometry_container[iZone] != nullptr) { + for (iInst = 0; iInst < nInst[iZone]; iInst++){ + if (geometry_container[iZone][iInst] != nullptr) { + delete geometry_container[iZone][iInst]; + } + } + delete geometry_container[iZone]; + } + } + delete [] geometry_container; + } + if (rank == MASTER_NODE) cout << "Deleted CGeometry container." << endl; + + if (surface_movement != nullptr) { + for (iZone = 0; iZone < nZone; iZone++) { + if (surface_movement[iZone] != nullptr) { + delete surface_movement[iZone]; + } + } + delete [] surface_movement; + } + if (rank == MASTER_NODE) cout << "Deleted CSurfaceMovement class." << endl; + + if (grid_movement != nullptr) { + for (iZone = 0; iZone < nZone; iZone++) { + if (grid_movement[iZone] != nullptr) { + delete grid_movement[iZone]; + } + } + delete [] grid_movement; + } + if (rank == MASTER_NODE) cout << "Deleted CVolumetricMovement class." << endl; + + if (config_container != nullptr) { + for (iZone = 0; iZone < nZone; iZone++) { + if (config_container[iZone] != nullptr) { + delete config_container[iZone]; + } + } + delete [] config_container; + } + if (rank == MASTER_NODE) cout << "Deleted CConfig container." << endl; + +} + +void CDiscAdjDeformationDriver::SetDiscAdjDeformation_FD(CGeometry *geometry, CConfig *config, CSurfaceMovement *surface_movement, su2double** Gradient){ + + unsigned short iDV, nDV, iFFDBox, nDV_Value, iMarker, iDim; + unsigned long iVertex, iPoint; + su2double delta_eps, my_Gradient, localGradient, *Normal, dS, *VarCoord, Sensitivity, + dalpha[3], deps[3], dalpha_deps; + bool *UpdatePoint, MoveSurface, Local_MoveSurface; + CFreeFormDefBox **FFDBox; + + int rank = SU2_MPI::GetRank(); + + nDV = config->GetnDV(); + + /*--- Boolean controlling points to be updated ---*/ + + UpdatePoint = new bool[geometry->GetnPoint()]; + + /*--- Definition of the FFD deformation class ---*/ + + unsigned short nFFDBox = MAX_NUMBER_FFD; + FFDBox = new CFreeFormDefBox*[nFFDBox]; + for (iFFDBox = 0; iFFDBox < MAX_NUMBER_FFD; iFFDBox++) FFDBox[iFFDBox] = nullptr; + + for (iDV = 0; iDV < nDV; iDV++){ + nDV_Value = config->GetnDV_Value(iDV); + if (nDV_Value != 1){ + SU2_MPI::Error("The DiscAdjDeformation using finite differences currently only supports a fixed direction of movement for FFD points.", CURRENT_FUNCTION); + } + } + + /*--- Continuous adjoint gradient computation ---*/ + + if (rank == MASTER_NODE) + cout << "Evaluate functional gradient using Finite Differences." << endl; + + for (iDV = 0; iDV < nDV; iDV++) { + + MoveSurface = true; + Local_MoveSurface = true; + + /*--- 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_TWIST_2D) || + (config->GetDesign_Variable(iDV) == FFD_CONTROL_POINT) || + (config->GetDesign_Variable(iDV) == FFD_NACELLE) || + (config->GetDesign_Variable(iDV) == FFD_GULL) || + (config->GetDesign_Variable(iDV) == FFD_TWIST) || + (config->GetDesign_Variable(iDV) == FFD_ROTATION) || + (config->GetDesign_Variable(iDV) == FFD_CAMBER) || + (config->GetDesign_Variable(iDV) == FFD_THICKNESS) || + (config->GetDesign_Variable(iDV) == FFD_ANGLE_OF_ATTACK)) { + + /*--- 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_movement->ReadFFDInfo(geometry, config, FFDBox, config->GetMesh_FileName()); + + /*--- If the FFDBox was not defined in the input file ---*/ + if (!surface_movement->GetFFDBoxDefinition()) { + SU2_MPI::Error("The input grid doesn't have the entire FFD information!", CURRENT_FUNCTION); + } + + for (iFFDBox = 0; iFFDBox < surface_movement->GetnFFDBox(); iFFDBox++) { + + if (rank == MASTER_NODE) cout << "Checking FFD box dimension." << endl; + surface_movement->CheckFFDDimension(geometry, config, FFDBox[iFFDBox], iFFDBox); + + if (rank == MASTER_NODE) cout << "Check the FFD box intersections with the solid surfaces." << endl; + surface_movement->CheckFFDIntersections(geometry, config, FFDBox[iFFDBox], iFFDBox); + + } + + if (rank == MASTER_NODE) + cout <<"-------------------------------------------------------------------------" << endl; + + } + + if (rank == MASTER_NODE) { + cout << endl << "Design variable number "<< iDV <<"." << endl; + cout << "Performing 3D deformation of the surface." << endl; + } + + /*--- Apply the control point change ---*/ + + MoveSurface = false; + + for (iFFDBox = 0; iFFDBox < surface_movement->GetnFFDBox(); iFFDBox++) { + + /*--- Reset FFD box ---*/ + + switch (config->GetDesign_Variable(iDV) ) { + case FFD_CONTROL_POINT_2D : Local_MoveSurface = surface_movement->SetFFDCPChange_2D(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; + case FFD_CAMBER_2D : Local_MoveSurface = surface_movement->SetFFDCamber_2D(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; + case FFD_THICKNESS_2D : Local_MoveSurface = surface_movement->SetFFDThickness_2D(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; + case FFD_TWIST_2D : Local_MoveSurface = surface_movement->SetFFDTwist_2D(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; + case FFD_CONTROL_POINT : Local_MoveSurface = surface_movement->SetFFDCPChange(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; + case FFD_NACELLE : Local_MoveSurface = surface_movement->SetFFDNacelle(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; + case FFD_GULL : Local_MoveSurface = surface_movement->SetFFDGull(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; + case FFD_TWIST : Local_MoveSurface = surface_movement->SetFFDTwist(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; + case FFD_ROTATION : Local_MoveSurface = surface_movement->SetFFDRotation(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; + case FFD_CAMBER : Local_MoveSurface = surface_movement->SetFFDCamber(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; + case FFD_THICKNESS : Local_MoveSurface = surface_movement->SetFFDThickness(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; + case FFD_CONTROL_SURFACE : Local_MoveSurface = surface_movement->SetFFDControl_Surface(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; + case FFD_ANGLE_OF_ATTACK : Gradient[iDV][0] = config->GetAoA_Sens(); break; + } + + /*--- Recompute cartesian coordinates using the new control points position ---*/ + + if (Local_MoveSurface) { + MoveSurface = true; + surface_movement->SetCartesianCoord(geometry, config, FFDBox[iFFDBox], iFFDBox, true); + } + + } + + } + + /*--- Hicks Henne design variable ---*/ + + else if (config->GetDesign_Variable(iDV) == HICKS_HENNE) { + surface_movement->SetHicksHenne(geometry, config, iDV, true); + } + + /*--- Surface bump design variable ---*/ + + else if (config->GetDesign_Variable(iDV) == SURFACE_BUMP) { + surface_movement->SetSurface_Bump(geometry, config, iDV, true); + } + + /*--- Kulfan (CST) design variable ---*/ + + else if (config->GetDesign_Variable(iDV) == CST) { + surface_movement->SetCST(geometry, config, iDV, true); + } + + /*--- Displacement design variable ---*/ + + else if (config->GetDesign_Variable(iDV) == TRANSLATION) { + surface_movement->SetTranslation(geometry, config, iDV, true); + } + + /*--- Angle of Attack design variable ---*/ + + else if (config->GetDesign_Variable(iDV) == ANGLE_OF_ATTACK) { + Gradient[iDV][0] = config->GetAoA_Sens(); + } + + /*--- Scale design variable ---*/ + + else if (config->GetDesign_Variable(iDV) == SCALE) { + surface_movement->SetScale(geometry, config, iDV, true); + } + + /*--- Rotation design variable ---*/ + + else if (config->GetDesign_Variable(iDV) == ROTATION) { + surface_movement->SetRotation(geometry, config, iDV, true); + } + + /*--- NACA_4Digits design variable ---*/ + + else if (config->GetDesign_Variable(iDV) == NACA_4DIGITS) { + surface_movement->SetNACA_4Digits(geometry, config); + } + + /*--- Parabolic design variable ---*/ + + else if (config->GetDesign_Variable(iDV) == PARABOLIC) { + surface_movement->SetParabolic(geometry, config); + } + + /*--- Design variable not implement ---*/ + + else { + if (rank == MASTER_NODE) + cout << "Design Variable not implement yet" << endl; + } + + /*--- Load the delta change in the design variable (finite difference step). ---*/ + + if ((config->GetDesign_Variable(iDV) != ANGLE_OF_ATTACK) && + (config->GetDesign_Variable(iDV) != FFD_ANGLE_OF_ATTACK)) { + + /*--- If the Angle of attack is not involved, reset the value of the gradient ---*/ + + my_Gradient = 0.0; Gradient[iDV][0] = 0.0; + + if (MoveSurface) { + + delta_eps = config->GetDV_Value(iDV); + + for (iPoint = 0; iPoint < geometry->GetnPoint(); iPoint++) + UpdatePoint[iPoint] = true; + + for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { + if (config->GetMarker_All_DV(iMarker) == YES) { + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { + + iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + if ((iPoint < geometry->GetnPointDomain()) && UpdatePoint[iPoint]) { + + Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); + VarCoord = geometry->vertex[iMarker][iVertex]->GetVarCoord(); + Sensitivity = geometry->vertex[iMarker][iVertex]->GetAuxVar(); + + dS = 0.0; + for (iDim = 0; iDim < geometry->GetnDim(); iDim++) { + dS += Normal[iDim]*Normal[iDim]; + deps[iDim] = VarCoord[iDim] / delta_eps; + } + dS = sqrt(dS); + + dalpha_deps = 0.0; + for (iDim = 0; iDim < geometry->GetnDim(); iDim++) { + dalpha[iDim] = Normal[iDim] / dS; + dalpha_deps -= dalpha[iDim]*deps[iDim]; + } + + my_Gradient += Sensitivity*dalpha_deps; + UpdatePoint[iPoint] = false; + } + } + } + } + } + + SU2_MPI::Allreduce(&my_Gradient, &localGradient, 1, MPI_DOUBLE, MPI_SUM, SU2_MPI::GetComm()); + Gradient[iDV][0] += localGradient; + } + } + + /*--- Delete memory for parameterization. ---*/ + + if (FFDBox != nullptr) { + for (iFFDBox = 0; iFFDBox < MAX_NUMBER_FFD; iFFDBox++) { + if (FFDBox[iFFDBox] != nullptr) { + delete FFDBox[iFFDBox]; + } + } + delete [] FFDBox; + } + + delete [] UpdatePoint; + +} + + +void CDiscAdjDeformationDriver::SetDiscAdjDeformation_AD(CGeometry *geometry, CConfig *config, CSurfaceMovement *surface_movement, su2double** Gradient){ + + su2double DV_Value, *VarCoord, Sensitivity, my_Gradient, localGradient, *Normal, Area = 0.0; + unsigned short iDV_Value = 0, iMarker, nMarker, iDim, nDim, iDV, nDV, nDV_Value; + unsigned long iVertex, nVertex, iPoint; + + int rank = SU2_MPI::GetRank(); + + nMarker = config->GetnMarker_All(); + nDim = geometry->GetnDim(); + nDV = config->GetnDV(); + + VarCoord = nullptr; + + /*--- Discrete adjoint gradient computation ---*/ + + if (rank == MASTER_NODE) + cout << endl << "Evaluate functional gradient using Algorithmic Differentiation (ZONE " << config->GetiZone() << ")." << endl; + + /*--- Start recording of operations ---*/ + + AD::StartRecording(); + + /*--- Register design variables as input and set them to zero + * (since we want to have the derivative at alpha = 0, i.e. for the current design) ---*/ + + + + for (iDV = 0; iDV < nDV; iDV++){ + + nDV_Value = config->GetnDV_Value(iDV); + + for (iDV_Value = 0; iDV_Value < nDV_Value; iDV_Value++){ + + /*--- Initilization with su2double resets the index ---*/ + + DV_Value = 0.0; + + AD::RegisterInput(DV_Value); + + config->SetDV_Value(iDV, iDV_Value, DV_Value); + } + } + + /*--- Call the surface deformation routine ---*/ + + surface_movement->SetSurface_Deformation(geometry, config); + + /*--- Stop the recording --- */ + + AD::StopRecording(); + + /*--- Create a structure to identify points that have been already visited. + * We need that to make sure to set the sensitivity of surface points only once + * (Markers share points, so we would visit them more than once in the loop over the markers below) ---*/ + + bool* visited = new bool[geometry->GetnPoint()]; + for (iPoint = 0; iPoint < geometry->GetnPoint(); iPoint++){ + visited[iPoint] = false; + } + + /*--- Initialize the derivatives of the output of the surface deformation routine + * with the discrete adjoints from the CFD solution ---*/ + + for (iMarker = 0; iMarker < nMarker; iMarker++) { + if (config->GetMarker_All_DV(iMarker) == YES) { + nVertex = geometry->nVertex[iMarker]; + for (iVertex = 0; iVertex vertex[iMarker][iVertex]->GetNode(); + if (!visited[iPoint]){ + VarCoord = geometry->vertex[iMarker][iVertex]->GetVarCoord(); + Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); + + Area = 0.0; + for (iDim = 0; iDim < nDim; iDim++){ + Area += Normal[iDim]*Normal[iDim]; + } + Area = sqrt(Area); + + for (iDim = 0; iDim < nDim; iDim++){ + if (config->GetDiscrete_Adjoint()){ + Sensitivity = geometry->GetSensitivity(iPoint, iDim); + } else { + Sensitivity = -Normal[iDim]*geometry->vertex[iMarker][iVertex]->GetAuxVar()/Area; + } + SU2_TYPE::SetDerivative(VarCoord[iDim], SU2_TYPE::GetValue(Sensitivity)); + } + visited[iPoint] = true; + } + } + } + } + + delete [] visited; + + /*--- Compute derivatives and extract gradient ---*/ + + AD::ComputeAdjoint(); + + for (iDV = 0; iDV < nDV; iDV++){ + nDV_Value = config->GetnDV_Value(iDV); + + for (iDV_Value = 0; iDV_Value < nDV_Value; iDV_Value++){ + DV_Value = config->GetDV_Value(iDV, iDV_Value); + my_Gradient = SU2_TYPE::GetDerivative(DV_Value); + SU2_MPI::Allreduce(&my_Gradient, &localGradient, 1, MPI_DOUBLE, MPI_SUM, SU2_MPI::GetComm()); + + /*--- Angle of Attack design variable (this is different, + the value comes form the input file) ---*/ + + if ((config->GetDesign_Variable(iDV) == ANGLE_OF_ATTACK) || + (config->GetDesign_Variable(iDV) == FFD_ANGLE_OF_ATTACK)) { + Gradient[iDV][iDV_Value] = config->GetAoA_Sens(); + } + + Gradient[iDV][iDV_Value] += localGradient; + } + } + + AD::Reset(); + +} + +void CDiscAdjDeformationDriver::OutputGradient(su2double** Gradient, CConfig* config, ofstream& Gradient_file){ + + unsigned short nDV, iDV, iDV_Value, nDV_Value; + + int rank = SU2_MPI::GetRank(); + + nDV = config->GetnDV(); + + /*--- Loop through all design variables and their gradients ---*/ + + for (iDV = 0; iDV < nDV; iDV++){ + nDV_Value = config->GetnDV_Value(iDV); + if (rank == MASTER_NODE){ + + /*--- Print the kind of design variable on screen ---*/ + + cout << endl << "Design variable ("; + for (std::map::const_iterator it = Param_Map.begin(); it != Param_Map.end(); ++it ){ + if (it->second == config->GetDesign_Variable(iDV)){ + cout << it->first << ") number "<< iDV << "." << endl; + } + } + + /*--- Print the kind of objective function to screen ---*/ + + for (std::map::const_iterator it = Objective_Map.begin(); it != Objective_Map.end(); ++it ){ + if (it->second == config->GetKind_ObjFunc()){ + cout << it->first << " gradient : "; + if (iDV == 0) Gradient_file << it->first << " gradient " << endl; + } + } + + /*--- Print the gradient to file and screen ---*/ + + for (iDV_Value = 0; iDV_Value < nDV_Value; iDV_Value++){ + cout << Gradient[iDV][iDV_Value]; + if (iDV_Value != nDV_Value-1 ){ + cout << ", "; + } + Gradient_file << Gradient[iDV][iDV_Value] << endl; + } + cout << endl; + cout <<"-------------------------------------------------------------------------" << endl; + } + } +} + + +void CDiscAdjDeformationDriver::SetSensitivity_Files(CGeometry ***geometry, CConfig **config, unsigned short val_nZone) { + + unsigned short iMarker,iDim, nDim, nMarker, nVar; + unsigned long iVertex, iPoint, nPoint, nVertex; + su2double *Normal, Prod, Sens = 0.0, SensDim, Area; + + unsigned short iZone; + + CSolver *solver = nullptr; + COutput *output = nullptr; + + for (iZone = 0; iZone < val_nZone; iZone++) { + + nPoint = geometry[iZone][INST_0]->GetnPoint(); + nDim = geometry[iZone][INST_0]->GetnDim(); + nMarker = config[iZone]->GetnMarker_All(); + nVar = nDim + 1; + + /*--- We create a baseline solver to easily merge the sensitivity information ---*/ + + vector fieldnames; + fieldnames.push_back("\"Point\""); + fieldnames.push_back("\"x\""); + fieldnames.push_back("\"y\""); + if (nDim == 3) { + fieldnames.push_back("\"z\""); + } + fieldnames.push_back("\"Sensitivity_x\""); + fieldnames.push_back("\"Sensitivity_y\""); + if (nDim == 3) { + fieldnames.push_back("\"Sensitivity_z\""); + } + fieldnames.push_back("\"Surface_Sensitivity\""); + + solver = new CBaselineSolver(geometry[iZone][INST_0], config[iZone], nVar+nDim, fieldnames); + + for (iPoint = 0; iPoint < nPoint; iPoint++) { + for (iDim = 0; iDim < nDim; iDim++) { + solver->GetNodes()->SetSolution(iPoint, iDim, geometry[iZone][INST_0]->nodes->GetCoord(iPoint, iDim)); + solver->GetNodes()->SetSolution(iPoint, iDim+nDim, geometry[iZone][INST_0]->GetSensitivity(iPoint, iDim)); + } + } + + /*--- Compute the sensitivity in normal direction ---*/ + + for (iMarker = 0; iMarker < nMarker; iMarker++) { + + if(config[iZone]->GetSolid_Wall(iMarker) || (config[iZone]->GetMarker_All_DV(iMarker) == YES )) { + + nVertex = geometry[iZone][INST_0]->GetnVertex(iMarker); + + for (iVertex = 0; iVertex < nVertex; iVertex++) { + iPoint = geometry[iZone][INST_0]->vertex[iMarker][iVertex]->GetNode(); + Normal = geometry[iZone][INST_0]->vertex[iMarker][iVertex]->GetNormal(); + Prod = 0.0; + Area = 0.0; + for (iDim = 0; iDim < nDim; iDim++) { + + /*--- Retrieve the gradient calculated with discrete adjoint method ---*/ + + SensDim = geometry[iZone][INST_0]->GetSensitivity(iPoint, iDim); + + /*--- Calculate scalar product for DiscAdjDeformation onto the normal vector ---*/ + + Prod += Normal[iDim]*SensDim; + + Area += Normal[iDim]*Normal[iDim]; + } + + Area = sqrt(Area); + + /*--- DiscAdjDeformation of the gradient onto the normal vector of the surface ---*/ + + Sens = Prod/Area; + + solver->GetNodes()->SetSolution(iPoint, 2*nDim, Sens); + + } + } + } + + output = new CBaselineOutput(config[iZone], nDim, solver); + output->PreprocessVolumeOutput(config[iZone]); + output->PreprocessHistoryOutput(config[iZone], false); + + /*--- Load the data --- */ + + output->Load_Data(geometry[iZone][INST_0], config[iZone], &solver); + + /*--- Set the surface filename ---*/ + + output->SetSurface_Filename(config[iZone]->GetSurfSens_FileName()); + + /*--- Set the volume filename ---*/ + + output->SetVolume_Filename(config[iZone]->GetVolSens_FileName()); + + /*--- Write to file ---*/ + + for (unsigned short iFile = 0; iFile < config[iZone]->GetnVolumeOutputFiles(); iFile++){ + auto FileFormat = config[iZone]->GetVolumeOutputFiles(); + if (FileFormat[iFile] != RESTART_ASCII && + FileFormat[iFile] != RESTART_BINARY && + FileFormat[iFile] != CSV) + output->WriteToFile(config[iZone], geometry[iZone][INST_0], FileFormat[iFile]); + } + + /*--- Free memory ---*/ + + delete output; + delete solver; + + } + +} diff --git a/SU2_DEF/src/meson.build b/SU2_DEF/src/meson.build index a6681c5c88d..0f19687b7bc 100644 --- a/SU2_DEF/src/meson.build +++ b/SU2_DEF/src/meson.build @@ -1,7 +1,8 @@ su2_def_include = include_directories('./') su2_def_src = files([ 'SU2_DEF.cpp', - 'drivers/CDeformationDriver.cpp' + 'drivers/CDeformationDriver.cpp', + 'drivers/CDiscAdjDeformationDriver.cpp' ]) if get_option('enable-normal') @@ -12,6 +13,7 @@ su2_cfd_obj = su2_cfd_lib.extract_objects(['solvers/CSolver.cpp', 'output/tools/CWindowingTools.cpp', 'output/CMeshOutput.cpp', 'output/output_structure_legacy.cpp', + 'output/CBaselineOutput.cpp', 'variables/CBaselineVariable.cpp', 'variables/CVariable.cpp', 'output/filewriter/CParallelDataSorter.cpp', @@ -49,3 +51,43 @@ su2_cfd_obj = su2_cfd_lib.extract_objects(['solvers/CSolver.cpp', objects : su2_cfd_obj, cpp_args :[default_warning_flags, su2_cpp_args]) endif + +if get_option('enable-autodiff') +su2_cfd_obj_ad = su2_cfd_lib_ad.extract_objects(['solvers/CSolver.cpp', + 'solvers/CBaselineSolver.cpp', + 'CMarkerProfileReaderFVM.cpp', + 'output/COutput.cpp', + 'output/tools/CWindowingTools.cpp', + 'output/output_structure_legacy.cpp', + 'output/CBaselineOutput.cpp', + 'output/filewriter/CParallelDataSorter.cpp', + 'output/filewriter/CParallelFileWriter.cpp', + 'output/filewriter/CFEMDataSorter.cpp', + 'output/filewriter/CSurfaceFEMDataSorter.cpp', + 'output/filewriter/CFVMDataSorter.cpp', + 'output/filewriter/CSurfaceFVMDataSorter.cpp', + 'output/filewriter/CCSVFileWriter.cpp', + 'output/filewriter/CSTLFileWriter.cpp', + 'output/filewriter/CTecplotFileWriter.cpp', + 'output/filewriter/CTecplotBinaryFileWriter.cpp', + 'output/filewriter/CParaviewFileWriter.cpp', + 'output/filewriter/CParaviewBinaryFileWriter.cpp', + 'output/filewriter/CSU2FileWriter.cpp', + 'output/filewriter/CSU2BinaryFileWriter.cpp', + 'output/filewriter/CSU2MeshFileWriter.cpp', + 'output/filewriter/CParaviewXMLFileWriter.cpp', + 'output/filewriter/CParaviewVTMFileWriter.cpp', + 'variables/CBaselineVariable.cpp', + 'variables/CVariable.cpp', + 'limiters/CLimiterDetails.cpp']) + + su2_def_lib_ad = static_library('SU2core_DEF_AD', + su2_def_src, + install : false, + dependencies : [su2_deps, codi_dep, commonAD_dep], + cpp_args: [default_warning_flags, su2_cpp_args, codi_rev_args]) + + su2_def_dep_ad = declare_dependency(link_with: su2_def_lib_ad, + include_directories: su2_def_include) + +endif diff --git a/SU2_DOT/src/meson.build b/SU2_DOT/src/meson.build index 4b01f4f3547..8fd80741329 100644 --- a/SU2_DOT/src/meson.build +++ b/SU2_DOT/src/meson.build @@ -1,4 +1,4 @@ -su2_dot_src = ['SU2_DOT.cpp'] +su2_dot_src = 'SU2_DOT.cpp' if get_option('enable-normal') su2_cfd_obj = su2_cfd_lib.extract_objects(['solvers/CSolver.cpp', @@ -28,10 +28,11 @@ if get_option('enable-normal') 'variables/CBaselineVariable.cpp', 'variables/CVariable.cpp', 'limiters/CLimiterDetails.cpp']) + su2_dot = executable('SU2_DOT', - su2_dot_src, + su2_dot_src, install: true, - dependencies: [su2_deps, common_dep], + dependencies: [su2_deps, common_dep], objects : su2_cfd_obj, cpp_args :[default_warning_flags, su2_cpp_args]) @@ -69,7 +70,7 @@ if get_option('enable-autodiff') su2_dot_ad = executable('SU2_DOT_AD', su2_dot_src, install: true, - dependencies: [su2_deps, codi_dep, commonAD_dep], + dependencies: [su2_deps, codi_dep, commonAD_dep], objects : su2_cfd_obj_ad, cpp_args : [default_warning_flags, su2_cpp_args, codi_rev_args]) diff --git a/SU2_PY/pySU2/meson.build b/SU2_PY/pySU2/meson.build index 1aab2e53b50..59b6a063347 100644 --- a/SU2_PY/pySU2/meson.build +++ b/SU2_PY/pySU2/meson.build @@ -28,7 +28,10 @@ if get_option('enable-normal') '_pysu2', cpp_source, dependencies: [wrapper_deps, common_dep, su2_deps], - objects: [su2_cfd_lib.extract_all_objects(), su2_def_lib.extract_objects('drivers/CDeformationDriver.cpp')], + objects: [ + su2_cfd_lib.extract_all_objects(), + su2_def_lib.extract_objects('drivers/CDeformationDriver.cpp') + ], install: true, include_directories : mpi4py_include, cpp_args : [default_warning_flags,su2_cpp_args], @@ -44,7 +47,10 @@ if get_option('enable-autodiff') '_pysu2ad', cpp_source, dependencies: [wrapper_deps, commonAD_dep, su2_deps, codi_dep], - objects: su2_cfd_lib_ad.extract_all_objects(), + objects: [ + su2_cfd_lib_ad.extract_all_objects(), + su2_def_lib_ad.extract_objects('drivers/CDiscAdjDeformationDriver.cpp') + ], install: true, include_directories : mpi4py_include, cpp_args : [default_warning_flags, su2_cpp_args, codi_rev_args], diff --git a/SU2_PY/pySU2/pySU2ad.i b/SU2_PY/pySU2/pySU2ad.i index 4409fd93fcb..ff7eaf6cb51 100644 --- a/SU2_PY/pySU2/pySU2ad.i +++ b/SU2_PY/pySU2/pySU2ad.i @@ -42,6 +42,7 @@ threads="1" #include "../../SU2_CFD/include/drivers/CSinglezoneDriver.hpp" #include "../../SU2_CFD/include/drivers/CMultizoneDriver.hpp" #include "../../SU2_CFD/include/drivers/CDiscAdjSinglezoneDriver.hpp" +#include "../../SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp" %} @@ -91,3 +92,4 @@ const unsigned int ZONE_1 = 1; /*!< \brief Definition of the first grid domain. %include "../../SU2_CFD/include/drivers/CSinglezoneDriver.hpp" %include "../../SU2_CFD/include/drivers/CMultizoneDriver.hpp" %include "../../SU2_CFD/include/drivers/CDiscAdjSinglezoneDriver.hpp" +%include "../../SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp" From bb2c03044cf60e4106eb7041f5152477052b2a71 Mon Sep 17 00:00:00 2001 From: aa-g Date: Tue, 22 Jun 2021 19:34:31 +0200 Subject: [PATCH 06/68] Integrate CMeshSolver for mesh deformation based on linear elasticity solver --- .../geometry/primal_grid/CPrimalGrid.hpp | 1 + SU2_CFD/include/solvers/CMeshSolver.hpp | 15 +- SU2_CFD/include/solvers/CSolver.hpp | 12 +- SU2_CFD/src/iteration/CIteration.cpp | 2 +- SU2_CFD/src/solvers/CMeshSolver.cpp | 58 ++++++- .../include/drivers/CDeformationDriver.hpp | 30 +++- SU2_DEF/src/drivers/CDeformationDriver.cpp | 152 ++++++++++++++---- SU2_DEF/src/meson.build | 10 ++ 8 files changed, 245 insertions(+), 35 deletions(-) diff --git a/Common/include/geometry/primal_grid/CPrimalGrid.hpp b/Common/include/geometry/primal_grid/CPrimalGrid.hpp index 5697b6fbf07..e5b7f19ca50 100644 --- a/Common/include/geometry/primal_grid/CPrimalGrid.hpp +++ b/Common/include/geometry/primal_grid/CPrimalGrid.hpp @@ -32,6 +32,7 @@ #include #include +#include #include #include "../../CConfig.hpp" diff --git a/SU2_CFD/include/solvers/CMeshSolver.hpp b/SU2_CFD/include/solvers/CMeshSolver.hpp index 5a4a6d927f0..2b8cdb04b9e 100644 --- a/SU2_CFD/include/solvers/CMeshSolver.hpp +++ b/SU2_CFD/include/solvers/CMeshSolver.hpp @@ -129,6 +129,7 @@ class CMeshSolver final : public CFEASolver { /*! * \brief Grid deformation using the linear elasticity equations. * \param[in] geometry - Geometrical definition of the problem. + * \param[in] numerics - Numerics used in the solution. * \param[in] config - Definition of the particular problem. */ void DeformMesh(CGeometry **geometry, @@ -136,12 +137,20 @@ class CMeshSolver final : public CFEASolver { CConfig *config) override; /*! - * \brief Set the stiffness of the mesh. + * \brief Grid deformation using the linear elasticity equations (no multigrid). * \param[in] geometry - Geometrical definition of the problem. + * \param[in] numerics - Numerics used in the solution. + * \param[in] config - Definition of the particular problem. + */ + void DeformMesh(CGeometry *geometry, + CNumerics **numerics, + CConfig *config) override; + /*! + * \brief Set the stiffness of the mesh. + * \param[in] numerics - Numerics used in the solution. * \param[in] config - Definition of the particular problem. */ - void SetMesh_Stiffness(CGeometry **geometry, - CNumerics **numerics, + void SetMesh_Stiffness(CNumerics **numerics, CConfig *config) override; /*! diff --git a/SU2_CFD/include/solvers/CSolver.hpp b/SU2_CFD/include/solvers/CSolver.hpp index ad1889ce9f4..8263a8ae064 100644 --- a/SU2_CFD/include/solvers/CSolver.hpp +++ b/SU2_CFD/include/solvers/CSolver.hpp @@ -4205,8 +4205,16 @@ class CSolver { * \param[in] config - Definition of the particular problem. * \param[in] referenceCoord - Determine if the mesh is deformed from the reference or from the current coordinates. */ - inline virtual void SetMesh_Stiffness(CGeometry **geometry, - CNumerics **numerics, + inline virtual void DeformMesh(CGeometry *geometry, + CNumerics **numerics, + CConfig *config) { } + + /*! + * \brief A virtual member. + * \param[in] config - Definition of the particular problem. + * \param[in] referenceCoord - Determine if the mesh is deformed from the reference or from the current coordinates. + */ + inline virtual void SetMesh_Stiffness(CNumerics **numerics, CConfig *config) { } /*! diff --git a/SU2_CFD/src/iteration/CIteration.cpp b/SU2_CFD/src/iteration/CIteration.cpp index 3fbe23c695c..fe27147992a 100644 --- a/SU2_CFD/src/iteration/CIteration.cpp +++ b/SU2_CFD/src/iteration/CIteration.cpp @@ -163,7 +163,7 @@ void CIteration::SetMesh_Deformation(CGeometry** geometry, CSolver** solver, CNu /*--- Set the stiffness of each element mesh into the mesh numerics ---*/ - solver[MESH_SOL]->SetMesh_Stiffness(geometry, numerics[MESH_SOL], config); + solver[MESH_SOL]->SetMesh_Stiffness(numerics[MESH_SOL], config); /*--- Deform the volume grid around the new boundary locations ---*/ diff --git a/SU2_CFD/src/solvers/CMeshSolver.cpp b/SU2_CFD/src/solvers/CMeshSolver.cpp index 06af9b8408c..ab0446da994 100644 --- a/SU2_CFD/src/solvers/CMeshSolver.cpp +++ b/SU2_CFD/src/solvers/CMeshSolver.cpp @@ -420,7 +420,7 @@ void CMeshSolver::SetWallDistance(CGeometry *geometry, CConfig *config) { END_SU2_OMP_PARALLEL } -void CMeshSolver::SetMesh_Stiffness(CGeometry **geometry, CNumerics **numerics, CConfig *config){ +void CMeshSolver::SetMesh_Stiffness(CNumerics **numerics, CConfig *config){ if (stiffness_set) return; @@ -542,6 +542,62 @@ void CMeshSolver::DeformMesh(CGeometry **geometry, CNumerics **numerics, CConfig } +void CMeshSolver::DeformMesh(CGeometry *geometry, CNumerics **numerics, CConfig *config){ + + if (multizone) nodes->Set_BGSSolution_k(); + + /*--- Capture a few MPI dependencies for AD. ---*/ + geometry->InitiateComms(geometry, config, COORDINATES); + geometry->CompleteComms(geometry, config, COORDINATES); + + InitiateComms(geometry, config, SOLUTION); + CompleteComms(geometry, config, SOLUTION); + + InitiateComms(geometry, config, MESH_DISPLACEMENTS); + CompleteComms(geometry, config, MESH_DISPLACEMENTS); + + /*--- Compute the stiffness matrix, no point recording because we clear the residual. ---*/ + + const bool wasActive = AD::BeginPassive(); + + Compute_StiffMatrix(geometry, numerics, config); + + AD::EndPassive(wasActive); + + /*--- Clear residual (loses AD info), we do not want an incremental solution. ---*/ + SU2_OMP_PARALLEL { + LinSysRes.SetValZero(); + if (time_domain && config->GetFSI_Simulation()) LinSysSol.SetValZero(); + } + END_SU2_OMP_PARALLEL + + /*--- Impose boundary conditions (all of them are ESSENTIAL BC's - displacements). ---*/ + SetBoundaryDisplacements(geometry, config, false); + + /*--- Solve the linear system. ---*/ + Solve_System(geometry, config); + + SU2_OMP_PARALLEL { + + /*--- Update the grid coordinates and cell volumes using the solution + of the linear system (usol contains the x, y, z displacements). ---*/ + UpdateGridCoord(geometry, config); + + /*--- Update the dual grid. ---*/ + UpdateDualGrid(geometry, config); + + /*--- Check for failed deformation (negative volumes). ---*/ + SetMinMaxVolume(geometry, config, true); + + /*--- The Grid Velocity is only computed if the problem is time domain ---*/ + if (time_domain && !config->GetFSI_Simulation()) + ComputeGridVelocity(geometry, config); + + } + END_SU2_OMP_PARALLEL + +} + void CMeshSolver::UpdateGridCoord(CGeometry *geometry, CConfig *config){ /*--- Update the grid coordinates using the solution of the linear system ---*/ diff --git a/SU2_DEF/include/drivers/CDeformationDriver.hpp b/SU2_DEF/include/drivers/CDeformationDriver.hpp index 8a424ff32fd..2601f378ad8 100644 --- a/SU2_DEF/include/drivers/CDeformationDriver.hpp +++ b/SU2_DEF/include/drivers/CDeformationDriver.hpp @@ -1,4 +1,4 @@ -/*! + /*! * \file CDeformationDriver.hpp * \brief Headers of the main subroutines for driving the mesh deformation. * \author T. Economon, H. Kline, R. Sanchez @@ -32,6 +32,7 @@ #include "../../../Common/include/grid_movement/CSurfaceMovement.hpp" #include "../../../Common/include/grid_movement/CVolumetricMovement.hpp" #include "../../../SU2_CFD/include/output/COutput.hpp" +#include "../../../SU2_CFD/include/numerics/CNumerics.hpp" #include "../../../Common/include/geometry/CGeometry.hpp" /*! @@ -56,6 +57,8 @@ class CDeformationDriver { CGeometry **geometry_container; /*!< \brief Geometrical definition of the problem. */ CSurfaceMovement **surface_movement; /*!< \brief Surface movement classes of the problem. */ CVolumetricMovement **grid_movement; /*!< \brief Volume grid movement classes of the problem. */ + CSolver **solver_container; + CNumerics ***numerics_container; COutput **output_container; /*!< \brief Pointer to the COutput class. */ public: @@ -76,6 +79,11 @@ class CDeformationDriver { */ void Run(); + /*! + * \brief Output the mesh. + */ + void Output(); + /*! * \brief Deallocation routine */ @@ -102,4 +110,24 @@ class CDeformationDriver { */ void Output_Preprocessing(); + /*! + * \brief Preprocess the mesh solver container. + */ + void Solver_Preprocessing(); + + /*! + * \brief Preprocess the numerics container. + */ + void Numerics_Preprocessing(); + + /*! + * \brief Mesh deformation based on linear elasticity solver (CMeshSolver). + */ + void Update(); + + /*! + * \brief Mesh deformation based on legacy implementation. + */ + void Update_Legacy(); + }; diff --git a/SU2_DEF/src/drivers/CDeformationDriver.cpp b/SU2_DEF/src/drivers/CDeformationDriver.cpp index b12d24154a9..b330c7fc343 100644 --- a/SU2_DEF/src/drivers/CDeformationDriver.cpp +++ b/SU2_DEF/src/drivers/CDeformationDriver.cpp @@ -29,7 +29,9 @@ #include "../../include/drivers/CDeformationDriver.hpp" #include "../../../Common/include/geometry/CPhysicalGeometry.hpp" +#include "../../../SU2_CFD/include/solvers/CMeshSolver.hpp" #include "../../../SU2_CFD/include/output/CMeshOutput.hpp" +#include "../../../SU2_CFD/include/numerics/elasticity/CFEALinearElasticity.hpp" using namespace std; @@ -76,6 +78,18 @@ CDeformationDriver::CDeformationDriver(char* confFile, SU2_Comm MPICommunicator) Output_Preprocessing(); + if (driver_config->GetDeform_Mesh()){ + + /*--- Preprocessing of the mesh solver for all zones. ---*/ + + Solver_Preprocessing(); + + /*--- Preprocessing of the mesh solver for all zones. ---*/ + + Numerics_Preprocessing(); + + } + /*--- Preprocessing time is reported now, but not included in the next compute portion. ---*/ StopTime = SU2_MPI::Wtime(); @@ -98,17 +112,22 @@ void CDeformationDriver::SetContainers_Null() { the SU2_DEF code. In general, the pointers are instantiated down a hierarchy over all zones as described in the comments below. ---*/ config_container = new CConfig*[nZone]; + output_container = new COutput*[nZone]; geometry_container = new CGeometry*[nZone]; surface_movement = new CSurfaceMovement*[nZone]; grid_movement = new CVolumetricMovement*[nZone]; - output_container = new COutput*[nZone]; + + solver_container = new CSolver*[nZone]; + numerics_container = new CNumerics**[nZone]; for (iZone = 0; iZone < nZone; iZone++) { config_container[iZone] = nullptr; + output_container[iZone] = nullptr; geometry_container[iZone] = nullptr; surface_movement[iZone] = nullptr; grid_movement[iZone] = nullptr; - output_container[iZone] = nullptr; + solver_container[iZone] = nullptr; + numerics_container[iZone] = nullptr; } } @@ -137,10 +156,13 @@ void CDeformationDriver::Input_Preprocessing() { config_container[iZone]->SetMPICommunicator(SU2_MPI::GetComm()); } - /*--- Set the multizone part of the problem. ---*/ + /*--- Set the multizone part of the problem. ---*/ + if (driver_config->GetMultizone_Problem()){ for (iZone = 0; iZone < nZone; iZone++) { + /*--- Set the interface markers for multizone ---*/ + config_container[iZone]->SetMultizone(driver_config, config_container); } } @@ -237,6 +259,30 @@ void CDeformationDriver::Output_Preprocessing() { } } +void CDeformationDriver::Solver_Preprocessing() { + + for (iZone = 0; iZone < nZone; iZone++) { + solver_container[iZone] = new CMeshSolver(geometry_container[iZone], config_container[iZone]); + } + +} + +void CDeformationDriver::Numerics_Preprocessing() { + + for (iZone = 0; iZone < nZone; iZone++) { + numerics_container[iZone] = new CNumerics* [omp_get_num_threads() * MAX_TERMS](); + + for (int thread = 0; thread < omp_get_max_threads(); ++thread) { + const int iTerm = FEA_TERM + thread * MAX_TERMS; + const int nDim = geometry_container[iZone]->GetnDim(); + + numerics_container[iZone][iTerm] = new CFEAMeshElasticity(nDim, nDim, geometry_container[iZone]->GetnElem(), config_container[iZone]); + } + + } + +} + void CDeformationDriver::Run() { /* --- Start measuring computation time ---*/ @@ -245,6 +291,47 @@ void CDeformationDriver::Run() { /*--- Surface grid deformation using design variables ---*/ + if (driver_config->GetDeform_Mesh()) { + Update(); + } + else { + Update_Legacy(); + } + + /*--- Synchronization point after a single solver iteration. Compute the + wall clock time required. ---*/ + + StopTime = SU2_MPI::Wtime(); + + UsedTimeCompute = StopTime-StartTime; + if (rank == MASTER_NODE) { + cout << "\nCompleted in " << fixed << UsedTimeCompute << " seconds on "<< size; + + if (size == 1) cout << " core." << endl; else cout << " cores." << endl; + } + + /*--- Output the deformed mesh ---*/ + Output(); + +} + +void CDeformationDriver::Update() { + + for (iZone = 0; iZone < nZone; iZone++){ + + /*--- Set the stiffness of each element mesh into the mesh numerics ---*/ + + solver_container[iZone]->SetMesh_Stiffness(numerics_container[iZone], config_container[iZone]); + + /*--- Deform the volume grid around the new boundary locations ---*/ + + solver_container[iZone]->DeformMesh(geometry_container[iZone], numerics_container[iZone], config_container[iZone]); + + } +} + +void CDeformationDriver::Update_Legacy() { + for (iZone = 0; iZone < nZone; iZone++){ if (config_container[iZone]->GetDesign_Variable(0) != NO_DEFORMATION) { @@ -392,12 +479,14 @@ void CDeformationDriver::Run() { } - /*--- Computational grid preprocesing ---*/ +} - if (rank == MASTER_NODE) cout << endl << "----------------------- Write deformed grid files -----------------------" << endl; +void CDeformationDriver::Output() { /*--- Output deformed grid for visualization, if requested (surface and volumetric), in parallel - requires to move all the data to the master node---*/ + requires to move all the data to the master node---*/ + + if (rank == MASTER_NODE) cout << endl << "----------------------- Write deformed grid files -----------------------" << endl; for (iZone = 0; iZone < nZone; iZone++){ @@ -427,7 +516,7 @@ void CDeformationDriver::Run() { /*--- Set the file names for the visualization files ---*/ output_container[iZone]->SetVolume_Filename("volume_deformed"); - output_container[iZone]->SetSurface_Filename("surface_deformed"); + output_container[iZone]->SetSurface_Filename("surfac e_deformed"); for (unsigned short iFile = 0; iFile < config_container[iZone]->GetnVolumeOutputFiles(); iFile++){ auto FileFormat = config_container[iZone]->GetVolumeOutputFiles(); @@ -436,38 +525,47 @@ void CDeformationDriver::Run() { } } - if ((config_container[ZONE_0]->GetDesign_Variable(0) != NO_DEFORMATION) && - (config_container[ZONE_0]->GetDesign_Variable(0) != SCALE_GRID) && - (config_container[ZONE_0]->GetDesign_Variable(0) != TRANSLATE_GRID) && - (config_container[ZONE_0]->GetDesign_Variable(0) != ROTATE_GRID)) { - - /*--- Write the the free-form deformation boxes after deformation. ---*/ - - if (rank == MASTER_NODE) cout << "Adding any FFD information to the SU2 file." << endl; - - surface_movement[ZONE_0]->WriteFFDInfo(surface_movement, geometry_container, config_container); + if (!driver_config->GetDeform_Mesh()) { + if ((config_container[ZONE_0]->GetDesign_Variable(0) != NO_DEFORMATION) && + (config_container[ZONE_0]->GetDesign_Variable(0) != SCALE_GRID) && + (config_container[ZONE_0]->GetDesign_Variable(0) != TRANSLATE_GRID) && + (config_container[ZONE_0]->GetDesign_Variable(0) != ROTATE_GRID)) { - } + /*--- Write the the free-form deformation boxes after deformation. ---*/ - /*--- Synchronization point after a single solver iteration. Compute the - wall clock time required. ---*/ + if (rank == MASTER_NODE) cout << "Adding any FFD information to the SU2 file." << endl; - StopTime = SU2_MPI::Wtime(); + surface_movement[ZONE_0]->WriteFFDInfo(surface_movement, geometry_container, config_container); - UsedTimeCompute = StopTime-StartTime; - if (rank == MASTER_NODE) { - cout << "\nCompleted in " << fixed << UsedTimeCompute << " seconds on "<< size; - if (size == 1) cout << " core." << endl; else cout << " cores." << endl; } + } } void CDeformationDriver::Postprocessing() { + if (rank == MASTER_NODE) cout << endl <<"------------------------- Solver Postprocessing -------------------------" << endl; delete driver_config; driver_config = nullptr; + for (iZone = 0; iZone < nZone; iZone++) { + if (numerics_container[iZone] != nullptr) { + for (unsigned int iTerm = 0; iTerm < MAX_TERMS*omp_get_max_threads(); iTerm++) { + delete numerics_container[iZone][iTerm]; + } + delete [] numerics_container[iZone]; + } + } + delete [] numerics_container; + if (rank == MASTER_NODE) cout << "Deleted CNumerics container." << endl; + + for (iZone = 0; iZone < nZone; iZone++) { + delete solver_container[iZone]; + } + delete [] solver_container; + if (rank == MASTER_NODE) cout << "Deleted CSolver container." << endl; + if (geometry_container != nullptr) { for (iZone = 0; iZone < nZone; iZone++) { if (geometry_container[iZone] != nullptr) { @@ -506,6 +604,8 @@ void CDeformationDriver::Postprocessing() { } delete [] config_container; } + if (rank == MASTER_NODE) cout << "Deleted CConfig container." << endl; + if (output_container != nullptr) { for (iZone = 0; iZone < nZone; iZone++) { if (output_container[iZone] != nullptr) { @@ -514,8 +614,6 @@ void CDeformationDriver::Postprocessing() { } delete [] output_container; } - if (rank == MASTER_NODE) cout << "Deleted CConfig container." << endl; - if (rank == MASTER_NODE) cout << "Deleted COutput class." << endl; /*--- Exit the solver cleanly ---*/ diff --git a/SU2_DEF/src/meson.build b/SU2_DEF/src/meson.build index 0f19687b7bc..ecd2c2faf86 100644 --- a/SU2_DEF/src/meson.build +++ b/SU2_DEF/src/meson.build @@ -8,6 +8,11 @@ if get_option('enable-normal') su2_cfd_obj = su2_cfd_lib.extract_objects(['solvers/CSolver.cpp', 'solvers/CBaselineSolver.cpp', + 'solvers/CMeshSolver.cpp', + 'solvers/CFEASolver.cpp', + 'numerics/CNumerics.cpp', + 'numerics/elasticity/CFEAElasticity.cpp', + 'numerics/elasticity/CFEALinearElasticity.cpp', 'CMarkerProfileReaderFVM.cpp', 'output/COutput.cpp', 'output/tools/CWindowingTools.cpp', @@ -16,6 +21,11 @@ su2_cfd_obj = su2_cfd_lib.extract_objects(['solvers/CSolver.cpp', 'output/CBaselineOutput.cpp', 'variables/CBaselineVariable.cpp', 'variables/CVariable.cpp', + 'variables/CFEAVariable.cpp', + 'variables/CFEABoundVariable.cpp', + 'variables/CMeshElement.cpp', + 'variables/CMeshVariable.cpp', + 'variables/CMeshBoundVariable.cpp', 'output/filewriter/CParallelDataSorter.cpp', 'output/filewriter/CFVMDataSorter.cpp', 'output/filewriter/CFEMDataSorter.cpp', From c44014888000d625489c28fd0e04dec85b518a86 Mon Sep 17 00:00:00 2001 From: aa-g Date: Tue, 22 Jun 2021 20:53:48 +0200 Subject: [PATCH 07/68] Fix merge 29e45213f1c5c27db241da16665bebad41d20d4f --- SU2_CFD/src/solvers/CMeshSolver.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/SU2_CFD/src/solvers/CMeshSolver.cpp b/SU2_CFD/src/solvers/CMeshSolver.cpp index f51bda27186..b3605563473 100644 --- a/SU2_CFD/src/solvers/CMeshSolver.cpp +++ b/SU2_CFD/src/solvers/CMeshSolver.cpp @@ -586,16 +586,17 @@ void CMeshSolver::DeformMesh(CGeometry *geometry, CNumerics **numerics, CConfig of the linear system (usol contains the x, y, z displacements). ---*/ UpdateGridCoord(geometry, config); - /*--- Update the dual grid. ---*/ - UpdateDualGrid(geometry, config); + /*--- Update the dual grid (without multigrid). ---*/ + geometry->InitiateComms(geometry, config, COORDINATES); + geometry->CompleteComms(geometry, config, COORDINATES); + + geometry->SetControlVolume(config, UPDATE); + geometry->SetBoundControlVolume(config, UPDATE); + geometry->SetMaxLength(config); /*--- Check for failed deformation (negative volumes). ---*/ SetMinMaxVolume(geometry, config, true); - /*--- The Grid Velocity is only computed if the problem is time domain ---*/ - if (time_domain && !config->GetFSI_Simulation()) - ComputeGridVelocity(geometry, config); - } END_SU2_OMP_PARALLEL From 169be9a4067cebc7495485069a72e21ce1930087 Mon Sep 17 00:00:00 2001 From: aa-g Date: Wed, 23 Jun 2021 00:43:00 +0200 Subject: [PATCH 08/68] Add marker- and vertex-data getters and setters (+ minor fixes) --- .../include/drivers/CDeformationDriver.hpp | 83 ++++++++ SU2_DEF/src/SU2_DEF.cpp | 1 + SU2_DEF/src/drivers/CDeformationDriver.cpp | 193 +++++++++++++++++- 3 files changed, 276 insertions(+), 1 deletion(-) diff --git a/SU2_DEF/include/drivers/CDeformationDriver.hpp b/SU2_DEF/include/drivers/CDeformationDriver.hpp index 2601f378ad8..cfb92560262 100644 --- a/SU2_DEF/include/drivers/CDeformationDriver.hpp +++ b/SU2_DEF/include/drivers/CDeformationDriver.hpp @@ -89,6 +89,89 @@ class CDeformationDriver { */ void Postprocessing(); + /*! + * \brief Get all the deformable boundary marker tags. + * \return List of deformable boundary markers tags. + */ + vector GetAllDeformMeshMarkersTag() const; + + /*! + * \brief Get all the boundary markers tags with their associated indices. + * \return List of boundary markers tags with their indices. + */ + map GetAllBoundaryMarkers() const; + + /*! + * \brief Get all the boundary markers tags with their associated types. + * \return List of boundary markers tags with their types. + */ + map GetAllBoundaryMarkersType() const; + + /*! + * \brief Get the number of vertices (halo nodes included) from a specified marker. + * \param[in] iMarker - Marker identifier. + * \return Number of vertices. + */ + unsigned long GetNumberVertices(unsigned short iMarker) const; + + /*! + * \brief Get the number of halo vertices from a specified marker. + * \param[in] iMarker - Marker identifier. + * \return Number of vertices. + */ + unsigned long GetNumberHaloVertices(unsigned short iMarker) const; + + /*! + * \brief Check if a vertex is physical or not (halo node) on a specified marker. + * \param[in] iMarker - Marker identifier. + * \param[in] iVertex - Vertex identifier. + * \return True if the specified vertex is a halo node. + */ + bool IsAHaloNode(unsigned short iMarker, unsigned long iVertex) const; + + /*! + * \brief Get the global index of a vertex on a specified marker. + * \param[in] iMarker - Marker identifier. + * \param[in] iVertex - Vertex identifier. + * \return Vertex global index. + */ + unsigned long GetVertexGlobalIndex(unsigned short iMarker, unsigned long iVertex) const; + + /*! + * \brief Get undeformed coordinates from the mesh solver. + * \param[in] iMarker - Marker identifier. + * \param[in] iVertex - Vertex identifier. + * \return x,y,z coordinates of the vertex. + */ + vector GetInitialMeshCoord(unsigned short iMarker, unsigned long iVertex) const; + + /*! + * \brief Get the unit normal (vector) at a vertex on a specified marker. + * \param[in] iMarker - Marker identifier. + * \param[in] iVertex - Vertex identifier. + * \return Unit normal (vector) at the vertex. + */ + vector GetVertexNormal(unsigned short iMarker, unsigned long iVertex, bool unitNormal = false) const; + + inline vector GetVertexUnitNormal(unsigned short iMarker, unsigned long iVertex) const { + return GetVertexNormal(iMarker, iVertex, true); + } + + /*! + * \brief Set the mesh displacement for the elasticity mesh solver. + * \param[in] iMarker - Marker identifier. + * \param[in] iVertex - Vertex identifier. + * \param[in] DispX - Value of the mesh displacement in the direction X. + * \param[in] DispY - Value of the mesh displacement in the direction Y. + * \param[in] DispZ - Value of the mesh displacement in the direction Z. + */ + void SetMeshDisplacement(unsigned short iMarker, unsigned long iVertex, passivedouble DispX, passivedouble DispY, passivedouble DispZ); + + /*! + * \brief Communicate the boundary mesh displacements in a python call + */ + void CommunicateMeshDisplacement(void); + protected: /*! * \brief Init_Containers diff --git a/SU2_DEF/src/SU2_DEF.cpp b/SU2_DEF/src/SU2_DEF.cpp index ea0ce32bcb2..f383f2f7746 100644 --- a/SU2_DEF/src/SU2_DEF.cpp +++ b/SU2_DEF/src/SU2_DEF.cpp @@ -55,6 +55,7 @@ int main(int argc, char *argv[]) { else { strcpy(config_file_name, "default.cfg"); } /*--- Initialize the mesh deformation driver ---*/ + driver = new CDeformationDriver(config_file_name, comm); /*--- Launch the main external loop of the solver. ---*/ diff --git a/SU2_DEF/src/drivers/CDeformationDriver.cpp b/SU2_DEF/src/drivers/CDeformationDriver.cpp index b330c7fc343..3f8d5ce71ac 100644 --- a/SU2_DEF/src/drivers/CDeformationDriver.cpp +++ b/SU2_DEF/src/drivers/CDeformationDriver.cpp @@ -29,6 +29,7 @@ #include "../../include/drivers/CDeformationDriver.hpp" #include "../../../Common/include/geometry/CPhysicalGeometry.hpp" +#include "../../../Common/include/toolboxes/geometry_toolbox.hpp" #include "../../../SU2_CFD/include/solvers/CMeshSolver.hpp" #include "../../../SU2_CFD/include/output/CMeshOutput.hpp" #include "../../../SU2_CFD/include/numerics/elasticity/CFEALinearElasticity.hpp" @@ -516,7 +517,7 @@ void CDeformationDriver::Output() { /*--- Set the file names for the visualization files ---*/ output_container[iZone]->SetVolume_Filename("volume_deformed"); - output_container[iZone]->SetSurface_Filename("surfac e_deformed"); + output_container[iZone]->SetSurface_Filename("surface_deformed"); for (unsigned short iFile = 0; iFile < config_container[iZone]->GetnVolumeOutputFiles(); iFile++){ auto FileFormat = config_container[iZone]->GetVolumeOutputFiles(); @@ -621,3 +622,193 @@ void CDeformationDriver::Postprocessing() { if (rank == MASTER_NODE) cout << endl << "------------------------- Exit Success (SU2_DEF) ------------------------" << endl << endl; } + +vector CDeformationDriver::GetAllDeformMeshMarkersTag() const { + + vector interfaceBoundariesTagList; + unsigned short iMarker, nBoundariesMarker; + string Marker_Tag; + + nBoundariesMarker = config_container[ZONE_0]->GetnMarker_Deform_Mesh(); + interfaceBoundariesTagList.resize(nBoundariesMarker); + + for(iMarker=0; iMarker < nBoundariesMarker; iMarker++){ + Marker_Tag = config_container[ZONE_0]->GetMarker_Deform_Mesh_TagBound(iMarker); + interfaceBoundariesTagList[iMarker] = Marker_Tag; + } + + return interfaceBoundariesTagList; +} + +map CDeformationDriver::GetAllBoundaryMarkers() const { + + map allBoundariesMap; + unsigned short iMarker, nBoundaryMarkers; + string Marker_Tag; + + nBoundaryMarkers = config_container[ZONE_0]->GetnMarker_All(); + + for(iMarker=0; iMarker < nBoundaryMarkers; iMarker++){ + Marker_Tag = config_container[ZONE_0]->GetMarker_All_TagBound(iMarker); + allBoundariesMap[Marker_Tag] = iMarker; + } + + return allBoundariesMap; +} + +map CDeformationDriver::GetAllBoundaryMarkersType() const { + + map allBoundariesTypeMap; + unsigned short iMarker, KindBC; + string Marker_Tag, Marker_Type; + + for(iMarker=0; iMarker < config_container[ZONE_0]->GetnMarker_All(); iMarker++){ + Marker_Tag = config_container[ZONE_0]->GetMarker_All_TagBound(iMarker); + KindBC = config_container[ZONE_0]->GetMarker_All_KindBC(iMarker); + switch(KindBC){ + case EULER_WALL: + Marker_Type = "EULER_WALL"; + break; + case FAR_FIELD: + Marker_Type = "FARFIELD"; + break; + case ISOTHERMAL: + Marker_Type = "ISOTHERMAL"; + break; + case HEAT_FLUX: + Marker_Type = "HEATFLUX"; + break; + case INLET_FLOW: + Marker_Type = "INLET_FLOW"; + break; + case OUTLET_FLOW: + Marker_Type = "OUTLET_FLOW"; + break; + case SYMMETRY_PLANE: + Marker_Type = "SYMMETRY"; + break; + case SEND_RECEIVE: + Marker_Type = "SEND_RECEIVE"; + break; + default: + Marker_Type = "UNKNOWN_TYPE"; + } + allBoundariesTypeMap[Marker_Tag] = Marker_Type; + } + + return allBoundariesTypeMap; +} + +unsigned long CDeformationDriver::GetNumberVertices(unsigned short iMarker) const { + + return geometry_container[ZONE_0]->nVertex[iMarker]; + +} + +unsigned long CDeformationDriver::GetNumberHaloVertices(unsigned short iMarker) const { + + unsigned long nHaloVertices, iVertex, iPoint; + + nHaloVertices = 0; + for(iVertex = 0; iVertex < geometry_container[ZONE_0]->nVertex[iMarker]; iVertex++){ + iPoint = geometry_container[ZONE_0]->vertex[iMarker][iVertex]->GetNode(); + if(!(geometry_container[ZONE_0]->nodes->GetDomain(iPoint))) nHaloVertices += 1; + } + + return nHaloVertices; + +} + +unsigned long CDeformationDriver::GetVertexGlobalIndex(unsigned short iMarker, unsigned long iVertex) const { + + unsigned long iPoint, GlobalIndex; + + iPoint = geometry_container[ZONE_0]->vertex[iMarker][iVertex]->GetNode(); + GlobalIndex = geometry_container[ZONE_0]->nodes->GetGlobalIndex(iPoint); + + return GlobalIndex; + +} + +bool CDeformationDriver::IsAHaloNode(unsigned short iMarker, unsigned long iVertex) const { + + unsigned long iPoint; + + iPoint = geometry_container[ZONE_0]->vertex[iMarker][iVertex]->GetNode(); + if(geometry_container[ZONE_0]->nodes->GetDomain(iPoint)) return false; + else return true; + +} + +vector CDeformationDriver::GetInitialMeshCoord(unsigned short iMarker, unsigned long iVertex) const { + + vector coord(3,0.0); + vector coord_passive(3, 0.0); + + auto iPoint = geometry_container[ZONE_0]->vertex[iMarker][iVertex]->GetNode(); + + for (auto iDim = 0 ; iDim < geometry_container[ZONE_0]->GetnDim(); iDim++){ + coord[iDim] = solver_container[ZONE_0]->GetNodes()->GetMesh_Coord(iPoint,iDim); + } + + coord_passive[0] = SU2_TYPE::GetValue(coord[0]); + coord_passive[1] = SU2_TYPE::GetValue(coord[1]); + coord_passive[2] = SU2_TYPE::GetValue(coord[2]); + + return coord_passive; +} + +vector CDeformationDriver::GetVertexNormal(unsigned short iMarker, unsigned long iVertex, bool unitNormal) const { + + int nDim = geometry_container[ZONE_0]->GetnDim(); + + su2double *Normal; + su2double Area; + vector ret_Normal(3, 0.0); + vector ret_Normal_passive(3, 0.0); + + Normal = geometry_container[ZONE_0]->vertex[iMarker][iVertex]->GetNormal(); + + if (!unitNormal) { + + ret_Normal_passive[0] = SU2_TYPE::GetValue(Normal[0]); + ret_Normal_passive[1] = SU2_TYPE::GetValue(Normal[1]); + if(nDim>2) ret_Normal_passive[2] = SU2_TYPE::GetValue(Normal[2]); + + return ret_Normal_passive; + } + + Area = GeometryToolbox::Norm(nDim, Normal); + + ret_Normal[0] = Normal[0]/Area; + ret_Normal[1] = Normal[1]/Area; + if(nDim>2) ret_Normal[2] = Normal[2]/Area; + + ret_Normal_passive[0] = SU2_TYPE::GetValue(ret_Normal[0]); + ret_Normal_passive[1] = SU2_TYPE::GetValue(ret_Normal[1]); + ret_Normal_passive[2] = SU2_TYPE::GetValue(ret_Normal[2]); + + return ret_Normal_passive; +} + +void CDeformationDriver::SetMeshDisplacement(unsigned short iMarker, unsigned long iVertex, passivedouble DispX, passivedouble DispY, passivedouble DispZ) { + + unsigned long iPoint; + su2double MeshDispl[3] = {0.0,0.0,0.0}; + + MeshDispl[0] = DispX; + MeshDispl[1] = DispY; + MeshDispl[2] = DispZ; + + iPoint = geometry_container[ZONE_0]->vertex[iMarker][iVertex]->GetNode(); + + solver_container[ZONE_0]->GetNodes()->SetBound_Disp(iPoint, MeshDispl); + +} + +void CDeformationDriver::CommunicateMeshDisplacement(void) { + + solver_container[ZONE_0]->InitiateComms(geometry_container[ZONE_0], config_container[ZONE_0], MESH_DISPLACEMENTS); + solver_container[ZONE_0]->CompleteComms(geometry_container[ZONE_0], config_container[ZONE_0], MESH_DISPLACEMENTS); + +} From e818703eaa73ae9cc5bfe78bcf20a19b69b57aa7 Mon Sep 17 00:00:00 2001 From: patelha57 Date: Tue, 22 Jun 2021 17:20:16 -0400 Subject: [PATCH 09/68] Remove nullptr checks, update AD register input code, minor code fixes --- .../drivers/CDiscAdjDeformationDriver.hpp | 4 - SU2_DEF/src/drivers/CDeformationDriver.cpp | 96 +++++++++---------- .../src/drivers/CDiscAdjDeformationDriver.cpp | 30 ++---- 3 files changed, 50 insertions(+), 80 deletions(-) diff --git a/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp b/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp index f3635ab694b..7901776a9f1 100644 --- a/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp +++ b/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp @@ -27,12 +27,8 @@ #pragma once -#define ENABLE_MAPS #include "../../../Common/include/CConfig.hpp" -#undef ENABLE_MAPS - #include "../../../Common/include/parallelization/mpi_structure.hpp" - #include "../../../Common/include/geometry/CGeometry.hpp" #include "../../../Common/include/fem/fem_geometry_structure.hpp" #include "../../../Common/include/grid_movement/CSurfaceMovement.hpp" diff --git a/SU2_DEF/src/drivers/CDeformationDriver.cpp b/SU2_DEF/src/drivers/CDeformationDriver.cpp index 3f8d5ce71ac..8c8155dfaa5 100644 --- a/SU2_DEF/src/drivers/CDeformationDriver.cpp +++ b/SU2_DEF/src/drivers/CDeformationDriver.cpp @@ -173,70 +173,70 @@ void CDeformationDriver::Geometrical_Preprocessing() { for (iZone = 0; iZone < nZone; iZone++) { - /*--- Definition of the geometry class to store the primal grid in the partitioning process. ---*/ + /*--- Definition of the geometry class to store the primal grid in the partitioning process. ---*/ - CGeometry *geometry_aux = nullptr; + CGeometry *geometry_aux = nullptr; - /*--- All ranks process the grid and call ParMETIS for partitioning ---*/ + /*--- All ranks process the grid and call ParMETIS for partitioning ---*/ - geometry_aux = new CPhysicalGeometry(config_container[iZone], iZone, nZone); + geometry_aux = new CPhysicalGeometry(config_container[iZone], iZone, nZone); - /*--- Color the initial grid and set the send-receive domains (ParMETIS) ---*/ + /*--- Color the initial grid and set the send-receive domains (ParMETIS) ---*/ - geometry_aux->SetColorGrid_Parallel(config_container[iZone]); + geometry_aux->SetColorGrid_Parallel(config_container[iZone]); - /*--- Build the grid data structures using the ParMETIS coloring. ---*/ + /*--- Build the grid data structures using the ParMETIS coloring. ---*/ - geometry_container[iZone] = new CPhysicalGeometry(geometry_aux, config_container[iZone]); + geometry_container[iZone] = new CPhysicalGeometry(geometry_aux, config_container[iZone]); - /*--- Deallocate the memory of geometry_aux ---*/ + /*--- Deallocate the memory of geometry_aux ---*/ - delete geometry_aux; + delete geometry_aux; - /*--- Add the Send/Receive boundaries ---*/ + /*--- Add the Send/Receive boundaries ---*/ - geometry_container[iZone]->SetSendReceive(config_container[iZone]); + geometry_container[iZone]->SetSendReceive(config_container[iZone]); - /*--- Add the Send/Receive boundaries ---*/ + /*--- Add the Send/Receive boundaries ---*/ - geometry_container[iZone]->SetBoundaries(config_container[iZone]); + geometry_container[iZone]->SetBoundaries(config_container[iZone]); - /*--- Computational grid preprocesing ---*/ + /*--- Computational grid preprocesing ---*/ - if (rank == MASTER_NODE) cout << endl << "----------------------- Preprocessing computations ----------------------" << endl; + if (rank == MASTER_NODE) cout << endl << "----------------------- Preprocessing computations ----------------------" << endl; - /*--- Compute elements surrounding points, points surrounding points ---*/ + /*--- Compute elements surrounding points, points surrounding points ---*/ - if (rank == MASTER_NODE) cout << "Setting local point connectivity." <SetPoint_Connectivity(); + if (rank == MASTER_NODE) cout << "Setting local point connectivity." <SetPoint_Connectivity(); - /*--- Check the orientation before computing geometrical quantities ---*/ + /*--- Check the orientation before computing geometrical quantities ---*/ - geometry_container[iZone]->SetBoundVolume(); - if (config_container[iZone]->GetReorientElements()) { - if (rank == MASTER_NODE) cout << "Checking the numerical grid orientation of the interior elements." <Check_IntElem_Orientation(config_container[iZone]); - geometry_container[iZone]->Check_BoundElem_Orientation(config_container[iZone]); - } + geometry_container[iZone]->SetBoundVolume(); + if (config_container[iZone]->GetReorientElements()) { + if (rank == MASTER_NODE) cout << "Checking the numerical grid orientation of the interior elements." <Check_IntElem_Orientation(config_container[iZone]); + geometry_container[iZone]->Check_BoundElem_Orientation(config_container[iZone]); + } - /*--- Create the edge structure ---*/ + /*--- Create the edge structure ---*/ - if (rank == MASTER_NODE) cout << "Identify edges and vertices." <SetEdges(); - geometry_container[iZone]->SetVertex(config_container[iZone]); + if (rank == MASTER_NODE) cout << "Identify edges and vertices." <SetEdges(); + geometry_container[iZone]->SetVertex(config_container[iZone]); - if (config_container[iZone]->GetDesign_Variable(0) != NO_DEFORMATION) { + if (config_container[iZone]->GetDesign_Variable(0) != NO_DEFORMATION) { - /*--- Create the dual control volume structures ---*/ + /*--- Create the dual control volume structures ---*/ - if (rank == MASTER_NODE) cout << "Setting the bound control volume structure." << endl; - geometry_container[iZone]->SetControlVolume(config_container[iZone], ALLOCATE); - geometry_container[iZone]->SetBoundControlVolume(config_container[iZone], ALLOCATE); - } + if (rank == MASTER_NODE) cout << "Setting the bound control volume structure." << endl; + geometry_container[iZone]->SetControlVolume(config_container[iZone], ALLOCATE); + geometry_container[iZone]->SetBoundControlVolume(config_container[iZone], ALLOCATE); + } - /*--- Create the point-to-point MPI communication structures. ---*/ + /*--- Create the point-to-point MPI communication structures. ---*/ - geometry_container[iZone]->PreprocessP2PComms(geometry_container[iZone], config_container[iZone]); + geometry_container[iZone]->PreprocessP2PComms(geometry_container[iZone], config_container[iZone]); } } @@ -569,9 +569,7 @@ void CDeformationDriver::Postprocessing() { if (geometry_container != nullptr) { for (iZone = 0; iZone < nZone; iZone++) { - if (geometry_container[iZone] != nullptr) { - delete geometry_container[iZone]; - } + delete geometry_container[iZone]; } delete [] geometry_container; } @@ -579,9 +577,7 @@ void CDeformationDriver::Postprocessing() { if (surface_movement != nullptr) { for (iZone = 0; iZone < nZone; iZone++) { - if (surface_movement[iZone] != nullptr) { - delete surface_movement[iZone]; - } + delete surface_movement[iZone]; } delete [] surface_movement; } @@ -589,9 +585,7 @@ void CDeformationDriver::Postprocessing() { if (grid_movement != nullptr) { for (iZone = 0; iZone < nZone; iZone++) { - if (grid_movement[iZone] != nullptr) { - delete grid_movement[iZone]; - } + delete grid_movement[iZone]; } delete [] grid_movement; } @@ -599,9 +593,7 @@ void CDeformationDriver::Postprocessing() { if (config_container != nullptr) { for (iZone = 0; iZone < nZone; iZone++) { - if (config_container[iZone] != nullptr) { - delete config_container[iZone]; - } + delete config_container[iZone]; } delete [] config_container; } @@ -609,9 +601,7 @@ void CDeformationDriver::Postprocessing() { if (output_container != nullptr) { for (iZone = 0; iZone < nZone; iZone++) { - if (output_container[iZone] != nullptr) { - delete output_container[iZone]; - } + delete output_container[iZone]; } delete [] output_container; } diff --git a/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp b/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp index 923901fee8b..f95c9f36455 100644 --- a/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp +++ b/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp @@ -358,9 +358,7 @@ void CDiscAdjDeformationDriver::Postprocessing() { for (iZone = 0; iZone < nZone; iZone++) { if (geometry_container[iZone] != nullptr) { for (iInst = 0; iInst < nInst[iZone]; iInst++){ - if (geometry_container[iZone][iInst] != nullptr) { - delete geometry_container[iZone][iInst]; - } + delete geometry_container[iZone][iInst]; } delete geometry_container[iZone]; } @@ -371,9 +369,7 @@ void CDiscAdjDeformationDriver::Postprocessing() { if (surface_movement != nullptr) { for (iZone = 0; iZone < nZone; iZone++) { - if (surface_movement[iZone] != nullptr) { - delete surface_movement[iZone]; - } + delete surface_movement[iZone]; } delete [] surface_movement; } @@ -381,9 +377,7 @@ void CDiscAdjDeformationDriver::Postprocessing() { if (grid_movement != nullptr) { for (iZone = 0; iZone < nZone; iZone++) { - if (grid_movement[iZone] != nullptr) { - delete grid_movement[iZone]; - } + delete grid_movement[iZone]; } delete [] grid_movement; } @@ -391,9 +385,7 @@ void CDiscAdjDeformationDriver::Postprocessing() { if (config_container != nullptr) { for (iZone = 0; iZone < nZone; iZone++) { - if (config_container[iZone] != nullptr) { - delete config_container[iZone]; - } + delete config_container[iZone]; } delete [] config_container; } @@ -683,21 +675,13 @@ void CDiscAdjDeformationDriver::SetDiscAdjDeformation_AD(CGeometry *geometry, CC /*--- Register design variables as input and set them to zero * (since we want to have the derivative at alpha = 0, i.e. for the current design) ---*/ - - for (iDV = 0; iDV < nDV; iDV++){ - nDV_Value = config->GetnDV_Value(iDV); - - for (iDV_Value = 0; iDV_Value < nDV_Value; iDV_Value++){ - - /*--- Initilization with su2double resets the index ---*/ - - DV_Value = 0.0; + for (iDV_Value = 0; iDV_Value < config->GetnDV_Value(iDV); iDV_Value++){ - AD::RegisterInput(DV_Value); + config->SetDV_Value(iDV, iDV_Value, 0.0); - config->SetDV_Value(iDV, iDV_Value, DV_Value); + AD::RegisterInput(config->GetDV_Value(iDV, iDV_Value)); } } From 31c969e16507ae80d69105ea8c9190071d54a08d Mon Sep 17 00:00:00 2001 From: patelha57 Date: Tue, 22 Jun 2021 17:40:55 -0400 Subject: [PATCH 10/68] Simplify cfd and cfd_ad library links --- SU2_DEF/src/meson.build | 67 ++--------------------------------------- 1 file changed, 2 insertions(+), 65 deletions(-) diff --git a/SU2_DEF/src/meson.build b/SU2_DEF/src/meson.build index ecd2c2faf86..f7edd9f0a19 100644 --- a/SU2_DEF/src/meson.build +++ b/SU2_DEF/src/meson.build @@ -6,44 +6,7 @@ su2_def_src = files([ ]) if get_option('enable-normal') -su2_cfd_obj = su2_cfd_lib.extract_objects(['solvers/CSolver.cpp', - 'solvers/CBaselineSolver.cpp', - 'solvers/CMeshSolver.cpp', - 'solvers/CFEASolver.cpp', - 'numerics/CNumerics.cpp', - 'numerics/elasticity/CFEAElasticity.cpp', - 'numerics/elasticity/CFEALinearElasticity.cpp', - 'CMarkerProfileReaderFVM.cpp', - 'output/COutput.cpp', - 'output/tools/CWindowingTools.cpp', - 'output/CMeshOutput.cpp', - 'output/output_structure_legacy.cpp', - 'output/CBaselineOutput.cpp', - 'variables/CBaselineVariable.cpp', - 'variables/CVariable.cpp', - 'variables/CFEAVariable.cpp', - 'variables/CFEABoundVariable.cpp', - 'variables/CMeshElement.cpp', - 'variables/CMeshVariable.cpp', - 'variables/CMeshBoundVariable.cpp', - 'output/filewriter/CParallelDataSorter.cpp', - 'output/filewriter/CFVMDataSorter.cpp', - 'output/filewriter/CFEMDataSorter.cpp', - 'output/filewriter/CSurfaceFEMDataSorter.cpp', - 'output/filewriter/CSurfaceFVMDataSorter.cpp', - 'output/filewriter/CParallelFileWriter.cpp', - 'output/filewriter/CParaviewFileWriter.cpp', - 'output/filewriter/CParaviewBinaryFileWriter.cpp', - 'output/filewriter/CTecplotFileWriter.cpp', - 'output/filewriter/CTecplotBinaryFileWriter.cpp', - 'output/filewriter/CCSVFileWriter.cpp', - 'output/filewriter/CSTLFileWriter.cpp', - 'output/filewriter/CSU2FileWriter.cpp', - 'output/filewriter/CSU2BinaryFileWriter.cpp', - 'output/filewriter/CParaviewXMLFileWriter.cpp', - 'output/filewriter/CParaviewVTMFileWriter.cpp', - 'output/filewriter/CSU2MeshFileWriter.cpp', - 'limiters/CLimiterDetails.cpp']) +su2_cfd_obj = su2_cfd_lib.extract_all_objects() su2_def_lib = static_library('SU2core_DEF', su2_def_src, @@ -63,33 +26,7 @@ su2_cfd_obj = su2_cfd_lib.extract_objects(['solvers/CSolver.cpp', endif if get_option('enable-autodiff') -su2_cfd_obj_ad = su2_cfd_lib_ad.extract_objects(['solvers/CSolver.cpp', - 'solvers/CBaselineSolver.cpp', - 'CMarkerProfileReaderFVM.cpp', - 'output/COutput.cpp', - 'output/tools/CWindowingTools.cpp', - 'output/output_structure_legacy.cpp', - 'output/CBaselineOutput.cpp', - 'output/filewriter/CParallelDataSorter.cpp', - 'output/filewriter/CParallelFileWriter.cpp', - 'output/filewriter/CFEMDataSorter.cpp', - 'output/filewriter/CSurfaceFEMDataSorter.cpp', - 'output/filewriter/CFVMDataSorter.cpp', - 'output/filewriter/CSurfaceFVMDataSorter.cpp', - 'output/filewriter/CCSVFileWriter.cpp', - 'output/filewriter/CSTLFileWriter.cpp', - 'output/filewriter/CTecplotFileWriter.cpp', - 'output/filewriter/CTecplotBinaryFileWriter.cpp', - 'output/filewriter/CParaviewFileWriter.cpp', - 'output/filewriter/CParaviewBinaryFileWriter.cpp', - 'output/filewriter/CSU2FileWriter.cpp', - 'output/filewriter/CSU2BinaryFileWriter.cpp', - 'output/filewriter/CSU2MeshFileWriter.cpp', - 'output/filewriter/CParaviewXMLFileWriter.cpp', - 'output/filewriter/CParaviewVTMFileWriter.cpp', - 'variables/CBaselineVariable.cpp', - 'variables/CVariable.cpp', - 'limiters/CLimiterDetails.cpp']) +su2_cfd_obj_ad = su2_cfd_lib_ad.extract_all_objects() su2_def_lib_ad = static_library('SU2core_DEF_AD', su2_def_src, From fd959313969af95c06b6057f003bcdd9869ed447 Mon Sep 17 00:00:00 2001 From: Harsh Patel <51417692+patelha57@users.noreply.github.com> Date: Mon, 28 Jun 2021 10:55:13 -0400 Subject: [PATCH 11/68] Remove redundant nullptr in CDeformationDriver Co-authored-by: Pedro Gomes <38071223+pcarruscag@users.noreply.github.com> --- SU2_DEF/src/drivers/CDeformationDriver.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/SU2_DEF/src/drivers/CDeformationDriver.cpp b/SU2_DEF/src/drivers/CDeformationDriver.cpp index 8c8155dfaa5..c95c45493be 100644 --- a/SU2_DEF/src/drivers/CDeformationDriver.cpp +++ b/SU2_DEF/src/drivers/CDeformationDriver.cpp @@ -54,7 +54,6 @@ CDeformationDriver::CDeformationDriver(char* confFile, SU2_Comm MPICommunicator) strcpy(config_file_name, confFile); /*--- Initialize the configuration of the driver ---*/ - driver_config = nullptr; driver_config = new CConfig(config_file_name, SU2_COMPONENT::SU2_DEF); nZone = driver_config->GetnZone(); From 90dbc0da26f37b22be01723b9cc4e96e5ad10da4 Mon Sep 17 00:00:00 2001 From: aa-g Date: Tue, 25 Jan 2022 17:55:31 +0100 Subject: [PATCH 12/68] Merge develop --- externals/meson | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/externals/meson b/externals/meson index 41c650a040d..29ef4478df6 160000 --- a/externals/meson +++ b/externals/meson @@ -1 +1 @@ -Subproject commit 41c650a040d50e0912d268af7a903a9ce1456dfa +Subproject commit 29ef4478df6d3aaca40c7993f125b29409be1de2 From 1e2b91fe7c099a9587bf2df958d4702d83ce76ef Mon Sep 17 00:00:00 2001 From: patelha57 Date: Sun, 13 Feb 2022 23:34:48 -0800 Subject: [PATCH 13/68] Updates for PR1300 --- Common/include/drivers/CDriverBase.hpp | 343 ++++ Common/src/drivers/CDriverBase.cpp | 547 ++++++ Common/src/drivers/meson.build | 1 + Common/src/meson.build | 1 + SU2_CFD/include/drivers/CDriver.hpp | 1661 ++++++++--------- SU2_CFD/src/drivers/CDriver.cpp | 3 +- SU2_CFD/src/python_wrapper_structure.cpp | 197 -- .../include/drivers/CDeformationDriver.hpp | 115 +- .../drivers/CDiscAdjDeformationDriver.hpp | 225 +-- SU2_DEF/src/drivers/CDeformationDriver.cpp | 1092 +++++------ .../src/drivers/CDiscAdjDeformationDriver.cpp | 1395 +++++++------- SU2_DOT/include/SU2_DOT.hpp | 69 +- SU2_DOT/src/SU2_DOT.cpp | 1060 +---------- SU2_PY/pySU2/pySU2.i | 1 + SU2_PY/pySU2/pySU2ad.i | 1 + 15 files changed, 3035 insertions(+), 3676 deletions(-) create mode 100644 Common/include/drivers/CDriverBase.hpp create mode 100644 Common/src/drivers/CDriverBase.cpp create mode 100644 Common/src/drivers/meson.build diff --git a/Common/include/drivers/CDriverBase.hpp b/Common/include/drivers/CDriverBase.hpp new file mode 100644 index 00000000000..7291411e397 --- /dev/null +++ b/Common/include/drivers/CDriverBase.hpp @@ -0,0 +1,343 @@ +/*! + * \file CDriverBase.hpp + * \brief Base class template for all drivers. + * \author H. Patel, A. Gastaldi + * \version 7.3.0 "Blackbird" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2021, SU2 Contributors (cf. AUTHORS.md) + * + * SU2 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * SU2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SU2. If not, see . + */ + +#pragma once + +#include "../CConfig.hpp" +#include "../../../SU2_CFD/include/numerics/CNumerics.hpp" +#include "../../../SU2_CFD/include/solvers/CSolver.hpp" +#include "../../../SU2_CFD/include/output/COutput.hpp" + +class CDriverBase { + +protected: + + int rank, /*!< \brief MPI Rank. */ + size; /*!< \brief MPI Size. */ + char* config_file_name; /*!< \brief Configuration file name of the problem.*/ + + su2double StartTime, /*!< \brief Start point of the timer for performance benchmarking.*/ + StopTime, /*!< \brief Stop point of the timer for performance benchmarking.*/ + UsedTimePreproc, /*!< \brief Elapsed time between Start and Stop point of the timer for tracking preprocessing phase.*/ + UsedTimeCompute, /*!< \brief Elapsed time between Start and Stop point of the timer for tracking compute phase.*/ + UsedTime; /*!< \brief Elapsed time between Start and Stop point of the timer.*/ + + unsigned long TimeIter; + + unsigned short iMesh, /*!< \brief Iterator on mesh levels.*/ + iZone, /*!< \brief Iterator on zones.*/ + nZone, /*!< \brief Total number of zones in the problem. */ + nDim, /*!< \brief Number of dimensions.*/ + iInst, /*!< \brief Iterator on instance levels.*/ + *nInst, /*!< \brief Total number of instances in the problem (per zone). */ + **interface_types; /*!< \brief Type of coupling between the distinct (physical) zones.*/ + + CConfig **config_container; /*!< \brief Definition of the particular problem. */ + CConfig *driver_config; /*!< \brief Definition of the driver configuration. */ + COutput **output_container; /*!< \brief Pointer to the COutput class. */ + COutput *driver_output; /*!< \brief Definition of the driver output. */ + CGeometry ****geometry_container; /*!< \brief Geometrical definition of the problem. */ + CSolver *****solver_container; /*!< \brief Container vector with all the solutions. */ + CNumerics ******numerics_container; /*!< \brief Description of the numerical method (the way in which the equations are solved). */ + CSurfaceMovement **surface_movement; /*!< \brief Surface movement classes of the problem. */ + CVolumetricMovement ***grid_movement; /*!< \brief Volume grid movement classes of the problem. */ + CFreeFormDefBox*** FFDBox; /*!< \brief FFD FFDBoxes of the problem. */ + +public: + + /*! + * \brief Constructor of the class. + * \param[in] confFile - Configuration file name. + * \param[in] val_nZone - Total number of zones. + * \param[in] MPICommunicator - MPI communicator for SU2. + */ + CDriverBase(char* confFile, unsigned short val_nZone, SU2_Comm MPICommunicator); + + /*! + * \brief Destructor of the class. + */ + ~CDriverBase(void); + + /*! + * \brief A virtual member. + */ + virtual void Preprocessing() {}; + + /*! + * \brief A virtual member. + */ + virtual void Run() {}; + + /*! + * \brief A virtual member. + */ + virtual void Update() {}; + + /*! + * \brief A virtual member. + */ + virtual void Update_Legacy() {}; + + /*! + * \brief A virtual member. + */ + virtual void Output() {}; + + /*! + * \brief A virtual member. + */ + virtual void Postprocessing() {}; + + /*! + * \brief Get all the boundary markers tags with their associated indices. + * \return List of boundary markers tags with their indices. + */ + map GetBoundaryMarkerIndices() const; + + /*! + * \brief Get all the boundary markers tags with their associated types. + * \return List of boundary markers tags with their types. + */ + map GetBoundaryMarkerTypes() const; + + /*! + * \brief Get all the deformable boundary marker tags. + * \return List of deformable boundary markers tags. + */ + vector GetDeformableMarkerTags() const; + + /*! + * \brief Get the number of mesh dimensions. + * \return Number of dimensions. + */ + unsigned long GetNumberDimensions() const; + + /*! + * \brief Get the number of mesh elements. + * \return Number of elements. + */ + unsigned long GetNumberElements() const; + + /*! + * \brief Get the number of mesh elements from a specified marker. + * \param[in] iMarker - Marker identifier. + * \return Number of elements. + */ + unsigned long GetNumberElementsMarker(unsigned short iMarker) const; + + /*! + * \brief Get the number of mesh vertices. + * \return Number of vertices. + */ + unsigned long GetNumberVertices() const; + + /*! + * \brief Get the number of mesh vertices from a specified marker. + * \param[in] iMarker - Marker identifier. + * \return Number of vertices. + */ + unsigned long GetNumberVerticesMarker(unsigned short iMarker) const; + + /*! + * \brief Get the number of halo mesh vertices. + * \return Number of vertices. + */ + unsigned long GetNumberHaloVertices() const; + + /*! + * \brief Get the number of halo mesh vertices from a specified marker. + * \param[in] iMarker - Marker identifier. + * \return Number of vertices. + */ + unsigned long GetNumberHaloVerticesMarker(unsigned short iMarker) const; + + /*! + * \brief Get global IDs of mesh vertices. + * \return Global vertex IDs. + */ + vector GetVertexIDs() const; + + /*! + * \brief Get global IDs of mesh vertices. + * \param[in] iMarker - Marker identifier. + * \return Global vertex IDs. + */ + vector GetVertexIDsMarker(unsigned short iMarker) const; + + /*! + * \brief Get global IDs of mesh elements. + * \return Global element IDs. + */ + vector GetElementIDs() const; + + /*! + * \brief Get global IDs of mesh elements. + * \param[in] iMarker - Marker identifier. + * \return Global element IDs. + */ + vector GetElementIDsMarker(unsigned short iMarker) const; + + /*! + * \brief Get the connected point IDs of mesh elements. + * \return Element connectivities (nElem, nNode) + */ + vector> GetConnectivity() const; + + /*! + * \brief Get the connected point IDs of mesh elements on a specified marker. + * \param[in] iMarker - Marker identifier. + * \return Element connectivities (nBound, nNode). + */ + vector> GetConnectivityMarker(unsigned short iMarker) const; + + /*! + * \brief Get halo node stauts of mesh vertices. + * \return Point domain status. + */ + vector GetDomain() const; + + /*! + * \brief Get halo node stauts of mesh marker vertices. + * \param[in] iMarker - Marker identifier. + * \return Point domain status. + */ + vector GetDomainMarker(unsigned short iMarker) const; + + /*! + * \brief Get the coordinates of the mesh points. + * \return Point coordinates (nPoint*nDim). + */ + vector GetCoordinates() const; + + /*! + * \brief Get the coordinates of the mesh points on the specified marker. + * \param[in] iMarker - Marker identifier. + * \return Point coordinates (nVertex*nDim). + */ + vector GetCoordinatesMarker(unsigned short iMarker) const; + + /*! + * \brief Set the coordinates of the mesh points. + * \param[in] values - Point coordinates (nPoint*nDim). + */ + void SetCoordinates(vector values); + + /*! + * \brief Set the coordinates of the mesh points on the specified marker. + * \param[in] iMarker - Marker identifier. + * \param[in] values - Point coordinates (nVertex*nDim). + */ + void SetCoordinatesMarker(unsigned short iMarker, vector values); + + /*! + * \brief Get the vertex displacements on the specified marker. + * \param[in] iMarker - Marker identifier. + * \return Vertex displacements (nVertex*nDim). + */ + vector GetDisplacementsMarker(unsigned short iMarker) const; + + /*! + * \brief Set the vertex displacements on the specified marker. + * \param[in] iMarker - Marker identifier. + * \param[in] values - Vertex displacements (nVertex*nDim). + */ + void SetDisplacementsMarker(unsigned short iMarker, vector values); + + /*! + * \brief Get the vertex velocities on the specified marker. + * \param[in] iMarker - Marker identifier. + * \return Vertex velocities (nVertex*nDim). + */ + vector GetVelocitiesMarker(unsigned short iMarker) const; + + /*! + * \brief Set the vertex velocities on the specified marker. + * \param[in] iMarker - Marker identifier. + * \param[in] values - Vertex velocities (nVertex*nDim). + */ + void SetVelocitiesMarker(unsigned short iMarker, vector values); + + /*! + * \brief Get undeformed coordinates from mesh solver on the specified marker. + * \param[in] iMarker - Marker identifier. + * \return Initial point coordinates (nVertex*nDim). + */ + vector GetInitialCoordinatesMarker(unsigned short iMarker) const; + + /*! + * \brief Get the vertex normal vectors on the specified marker. + * \param[in] iMarker - Marker identifier. + * \param[in] UnitNormal - Boolean to indicate if unit normal vector should be returned. + * \return Normal vector at the vertex (nVertex*nDim). + */ + vector GetVertexNormalsMarker(unsigned short iMarker, bool UnitNormal = false) const; + + /*! + * \brief Communicate the boundary mesh displacements in a python call + */ + void CommunicateMeshDisplacements(void); + +protected: + + /*! + * \brief Initialize Containers + */ + void SetContainers_Null(); + + /*! + * \brief Read in the config and mesh files. + */ + void Input_Preprocessing(CConfig **&config, CConfig *&driver_config); + + /*! + * \brief Construction of the edge-based data structure and the multigrid structure. + */ + void Geometrical_Preprocessing(CConfig *config, CGeometry **&geometry, bool dummy); + + /*! + * \brief Definition and allocation of all solution classes. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void Solver_Preprocessing(CConfig *config, CGeometry **geometry, CSolver ***&solver); + + /*! + * \brief Definition and allocation of all solver classes. + * \param[in] numerics_container - Description of the numerical method (the way in which the equations are solved). + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + void Numerics_Preprocessing(CConfig *config, CGeometry **geometry, CSolver ***solver, CNumerics ****&numerics) const; + + /*! + * \brief Preprocess the output container. + */ + void Output_Preprocessing(CConfig **config, CConfig *driver_config, COutput **&output_container, COutput *&driver_output); + +}; diff --git a/Common/src/drivers/CDriverBase.cpp b/Common/src/drivers/CDriverBase.cpp new file mode 100644 index 00000000000..094113173ec --- /dev/null +++ b/Common/src/drivers/CDriverBase.cpp @@ -0,0 +1,547 @@ +/*! + * \file CDriverBase.hpp + * \brief Base class template for all drivers. + * \author H. Patel, A. Gastaldi + * \version 7.3.0 "Blackbird" + * + * SU2 Project Website: https://su2code.github.io + * + * The SU2 Project is maintained by the SU2 Foundation + * (http://su2foundation.org) + * + * Copyright 2012-2021, SU2 Contributors (cf. AUTHORS.md) + * + * SU2 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser/ General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * SU2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with SU2. If not, see . + */ + +#include "../../include/drivers/CDriverBase.hpp" + +#include "../../include/geometry/CPhysicalGeometry.hpp" +#include "../../include/toolboxes/geometry_toolbox.hpp" + +using namespace std; + +CDriverBase::CDriverBase(char* confFile, unsigned short val_nZone, SU2_Comm MPICommunicator): + config_file_name(confFile), + StartTime(0.0), + StopTime(0.0), + UsedTime(0.0), + TimeIter(0), + nZone() +{ + +} + +CDriverBase::~CDriverBase(void) { + +} + +void CDriverBase::SetContainers_Null() { + + /*--- Create pointers to all of the classes that may be used by drivers. In general, the pointers are instantiated down a + hierarchy over all zones, multigrid levels, equation sets, and equation + terms as described in the comments below. ---*/ + + nInst = nullptr; + + config_container = nullptr; + output_container = nullptr; + geometry_container = nullptr; + solver_container = nullptr; + numerics_container = nullptr; + + surface_movement = nullptr; + grid_movement = nullptr; + FFDBox = nullptr; + + nInst = new unsigned short[nZone] (); + + config_container = new CConfig*[nZone] (); + output_container = new COutput*[nZone] (); + geometry_container = new CGeometry***[nZone] (); + solver_container = new CSolver****[nZone] (); + numerics_container = new CNumerics*****[nZone] (); + + surface_movement = new CSurfaceMovement*[nZone] (); + grid_movement = new CVolumetricMovement**[nZone] (); + FFDBox = new CFreeFormDefBox**[nZone] (); + + driver_config = nullptr; + driver_output = nullptr; + + for (iZone = 0; iZone < nZone; iZone++) { + nInst[iZone] = 1; + } +} + +map CDriverBase::GetBoundaryMarkerIndices() const { + CConfig* config = config_container[ZONE_0]; + + const auto nBoundaryMarkers = config->GetnMarker_All(); + map allBoundariesMap; + + for (auto iMarker = 0u; iMarker < nBoundaryMarkers; iMarker++) { + auto Marker_Tag = config->GetMarker_All_TagBound(iMarker); + allBoundariesMap[Marker_Tag] = iMarker; + } + + return allBoundariesMap; +} + +map CDriverBase::GetBoundaryMarkerTypes() const { + CConfig* config = config_container[ZONE_0]; + + map allBoundariesTypeMap; + string Marker_Type; + + for (auto iMarker = 0u; iMarker < config->GetnMarker_All(); iMarker++) { + auto Marker_Tag = config->GetMarker_All_TagBound(iMarker); + auto KindBC = config->GetMarker_All_KindBC(iMarker); + + switch(KindBC) { + case EULER_WALL: + Marker_Type = "EULER_WALL"; + break; + case FAR_FIELD: + Marker_Type = "FARFIELD"; + break; + case ISOTHERMAL: + Marker_Type = "ISOTHERMAL"; + break; + case HEAT_FLUX: + Marker_Type = "HEATFLUX"; + break; + case INLET_FLOW: + Marker_Type = "INLET_FLOW"; + break; + case OUTLET_FLOW: + Marker_Type = "OUTLET_FLOW"; + break; + case SYMMETRY_PLANE: + Marker_Type = "SYMMETRY"; + break; + case SEND_RECEIVE: + Marker_Type = "SEND_RECEIVE"; + break; + default: + Marker_Type = "UNKNOWN_TYPE"; + } + allBoundariesTypeMap[Marker_Tag] = Marker_Type; + } + + return allBoundariesTypeMap; +} + +vector CDriverBase::GetDeformableMarkerTags() const { + CConfig* config = config_container[ZONE_0]; + + const auto nBoundariesMarker = config->GetnMarker_Deform_Mesh(); + vector interfaceBoundariesTagList; + + interfaceBoundariesTagList.resize(nBoundariesMarker); + + for (auto iMarker = 0u; iMarker < nBoundariesMarker; iMarker++) { + auto Marker_Tag = config->GetMarker_Deform_Mesh_TagBound(iMarker); + interfaceBoundariesTagList[iMarker] = Marker_Tag; + } + + return interfaceBoundariesTagList; +} + +unsigned long CDriverBase::GetNumberDimensions() const { + return geometry_container[ZONE_0][INST_0][MESH_0]->GetnDim(); +} + +unsigned long CDriverBase::GetNumberElements() const { + return geometry_container[ZONE_0][INST_0][MESH_0]->GetnElem(); +} + +unsigned long CDriverBase::GetNumberElementsMarker(unsigned short iMarker) const { + return geometry_container[ZONE_0][INST_0][MESH_0]->GetnElem_Bound(iMarker); +} + +unsigned long CDriverBase::GetNumberVertices() const { + return geometry_container[ZONE_0][INST_0][MESH_0]->GetnPoint(); +} + +unsigned long CDriverBase::GetNumberVerticesMarker(unsigned short iMarker) const { + return geometry_container[ZONE_0][INST_0][MESH_0]->GetnVertex(iMarker); +} + +unsigned long CDriverBase::GetNumberHaloVertices() const { + CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; + + const auto nPoint = geometry->GetnPoint(); + unsigned long nHaloVertices = 0; + + for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { + if (!(geometry->nodes->GetDomain(iPoint))) { + nHaloVertices += 1; + } + } + + return nHaloVertices; +} + +unsigned long CDriverBase::GetNumberHaloVerticesMarker(unsigned short iMarker) const { + CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; + + const auto nVertex = geometry->GetnVertex(iMarker); + unsigned long nHaloVertices = 0; + + for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { + auto iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + if (!(geometry->nodes->GetDomain(iPoint))) { + nHaloVertices += 1; + } + } + + return nHaloVertices; +} + +vector CDriverBase::GetVertexIDs() const { + CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; + + const auto nPoint = geometry->GetnPoint(); + vector values; + + for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { + values.push_back(geometry->nodes->GetGlobalIndex(iPoint)); + } + + return values; +} + +vector CDriverBase::GetVertexIDsMarker(unsigned short iMarker) const { + CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; + + const auto nVertex = geometry->GetnVertex(iMarker); + vector values; + + for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { + auto iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + + values.push_back(geometry->nodes->GetGlobalIndex(iPoint)); + } + + return values; +} + +vector CDriverBase::GetElementIDs() const { + CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; + + const auto nElem = geometry->GetnElem(); + vector values; + + for (auto iElem = 0ul; iElem < nElem; iElem++) { + values.push_back(geometry->elem[iElem]->GetGlobalIndex()); + } + + return values; +} + +vector CDriverBase::GetElementIDsMarker(unsigned short iMarker) const { + CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; + + const auto nBound = geometry->GetnElem_Bound(iMarker); + vector values; + + for (auto iBound = 0ul; iBound < nBound; iBound++) { + values.push_back(geometry->bound[iMarker][iBound]->GetGlobalIndex()); + } + + return values; +} + +vector> CDriverBase::GetConnectivity() const { + CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; + + const auto nElem = geometry->GetnElem(); + vector> values(nElem); + + for (auto iElem = 0ul; iElem < nElem; iElem++) { + unsigned short nNode = geometry->elem[iElem]->GetnNodes(); + + for (auto iNode = 0u; iNode < nNode; iNode++) { + values[iElem].push_back(geometry->elem[iElem]->GetNode(iNode)); + } + } + + return values; +} + +vector> CDriverBase::GetConnectivityMarker(unsigned short iMarker) const { + CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; + + const auto nBound = geometry->GetnElem_Bound(iMarker); + vector> values(nBound); + + for (auto iBound = 0ul; iBound < nBound; iBound++) { + unsigned short nNode = geometry->bound[iMarker][iBound]->GetnNodes(); + + for (auto iNode = 0u; iNode < nNode; iNode++) { + values[iBound].push_back(geometry->bound[iMarker][iBound]->GetNode(iNode)); + } + } + + return values; +} + +vector CDriverBase::GetDomain() const { + CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; + + const auto nPoint = geometry->GetnPoint(); + vector values(nPoint); + + for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { + values.push_back(geometry->nodes->GetDomain(iPoint)); + } + + return values; +} + +vector CDriverBase::GetDomainMarker(unsigned short iMarker) const { + CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; + + const auto nVertex = geometry->GetnVertex(iMarker); + vector values(nVertex); + + for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { + auto iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + + values.push_back(geometry->nodes->GetDomain(iPoint)); + } + + return values; +} + +vector CDriverBase::GetCoordinates() const { + CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; + + const auto nPoint = geometry->GetnPoint(); + vector values(nPoint*nDim, 0.0); + su2double value; + + for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { + for (auto iDim = 0u; iDim < nDim; iDim++) { + value = geometry->nodes->GetCoord(iPoint, iDim); + values[iPoint*nDim + iDim] = SU2_TYPE::GetValue(value); + } + } + + return values; +} + +vector CDriverBase::GetCoordinatesMarker(unsigned short iMarker) const { + CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; + + const auto nVertex = geometry->GetnVertex(iMarker); + vector values(nVertex*nDim, 0.0); + su2double value; + + for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { + auto iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + + for (auto iDim = 0u; iDim < nDim; iDim++) { + value = geometry->nodes->GetCoord(iPoint, iDim); + values[iVertex*nDim + iDim] = SU2_TYPE::GetValue(value); + } + } + + return values; +} + +void CDriverBase::SetCoordinates(vector values) { + CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; + + const auto nPoint = geometry->GetnPoint(); + if (values.size() != nPoint*nDim) { + SU2_MPI::Error("Size does not match nPoint * nDim!", CURRENT_FUNCTION); + } + + for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { + for (auto iDim = 0u; iDim < nDim; iDim++) { + geometry->nodes->SetCoord(iPoint, iDim, values[iPoint*nDim + iDim]); + } + } +} + +void CDriverBase::SetCoordinatesMarker(unsigned short iMarker, vector values) { + CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; + + const auto nVertex = geometry->GetnVertex(iMarker); + if (values.size() != nVertex*nDim) { + SU2_MPI::Error("Size does not match nVertex * nDim!", CURRENT_FUNCTION); + } + + for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { + auto iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + + for (auto iDim = 0u; iDim < nDim; iDim++) { + geometry->nodes->SetCoord(iPoint, iDim, values[iVertex*nDim + iDim]); + } + } +} + +vector CDriverBase::GetDisplacementsMarker(unsigned short iMarker) const { + CConfig* config = config_container[ZONE_0]; + CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; + CSolver* solver = solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]; + + if (!config->GetDeform_Mesh()) { + return {}; + } + + const auto nVertex = geometry->GetnVertex(iMarker); + vector values(nVertex*nDim, 0.0); + su2double value; + + for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { + auto iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + + for (auto iDim = 0u; iDim < nDim; iDim++) { + value = solver->GetNodes()->GetBound_Disp(iPoint, iDim); + values[iVertex*nDim + iDim] = SU2_TYPE::GetValue(value); + } + } + + return values; +} + +void CDriverBase::SetDisplacementsMarker(unsigned short iMarker, vector values) { + CConfig* config = config_container[ZONE_0]; + CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; + CSolver* solver = solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]; + + if (!config->GetDeform_Mesh()) { + SU2_MPI::Error("Mesh solver is not defined!", CURRENT_FUNCTION); + } + + const auto nVertex = geometry->GetnVertex(iMarker); + if (values.size() != nVertex*nDim) { + SU2_MPI::Error("Size does not match nVertex * nDim!", CURRENT_FUNCTION); + } + + for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { + auto iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + + for (auto iDim = 0u; iDim < nDim; iDim++) { + solver->GetNodes()->SetBound_Disp(iPoint, iDim, values[iVertex*nDim + iDim]); + } + } +} + +vector CDriverBase::GetVelocitiesMarker(unsigned short iMarker) const { + CConfig* config = config_container[ZONE_0]; + CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; + CSolver* solver = solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]; + + if (!config->GetDeform_Mesh()) { + return {}; + } + + const auto nVertex = geometry->GetnVertex(iMarker); + vector values(nVertex*nDim, 0.0); + su2double value; + + for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { + auto iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + + for (auto iDim = 0u; iDim < nDim; iDim++) { + value = solver->GetNodes()->GetBound_Vel(iPoint, iDim); + values[iVertex*nDim + iDim] = SU2_TYPE::GetValue(value); + } + } + + return values; +} + +void CDriverBase::SetVelocitiesMarker(unsigned short iMarker, vector values) { + CConfig* config = config_container[ZONE_0]; + CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; + CSolver* solver = solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]; + + if (!config->GetDeform_Mesh()) { + SU2_MPI::Error("Mesh solver is not defined!", CURRENT_FUNCTION); + } + + const auto nVertex = geometry->GetnVertex(iMarker); + if (values.size() != nVertex*nDim) { + SU2_MPI::Error("Size does not match nVertex * nDim!", CURRENT_FUNCTION); + } + + for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { + auto iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + + for (auto iDim = 0u; iDim < nDim; iDim++) { + solver->GetNodes()->SetBound_Vel(iPoint, iDim, values[iVertex*nDim + iDim]); + } + } +} + +vector CDriverBase::GetInitialCoordinatesMarker(unsigned short iMarker) const { + CConfig* config = config_container[ZONE_0]; + CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; + CSolver* solver = solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]; + + if (!config->GetDeform_Mesh()) { + return {}; + } + + const auto nVertex = geometry->GetnVertex(iMarker); + vector values(nVertex*nDim, 0.0); + su2double value; + + for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { + auto iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + + for (auto iDim = 0u; iDim < nDim; iDim++) { + value = solver->GetNodes()->GetMesh_Coord(iPoint, iDim); + values[iVertex*nDim + iDim] = SU2_TYPE::GetValue(value); + } + } + + return values; +} + +vector CDriverBase::GetVertexNormalsMarker(unsigned short iMarker, bool UnitNormal) const { + CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; + + const auto nVertex = geometry->GetnVertex(iMarker); + vector values(nVertex*nDim, 0.0); + + for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { + auto Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); + auto Area = GeometryToolbox::Norm(nDim, Normal); + + for (auto iDim = 0u; iDim < nDim; iDim++) { + if (!UnitNormal) { + values[iVertex*nDim + iDim] = SU2_TYPE::GetValue(Normal[iDim]); + } else { + values[iVertex*nDim + iDim] = SU2_TYPE::GetValue(Normal[iDim]/Area); + } + } + } + + return values; +} + +void CDriverBase::CommunicateMeshDisplacements(void) { + CConfig* config = config_container[ZONE_0]; + CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; + CSolver* solver = solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]; + + solver->InitiateComms(geometry, config, MESH_DISPLACEMENTS); + solver->CompleteComms(geometry, config, MESH_DISPLACEMENTS); +} diff --git a/Common/src/drivers/meson.build b/Common/src/drivers/meson.build new file mode 100644 index 00000000000..bcee2ba35cb --- /dev/null +++ b/Common/src/drivers/meson.build @@ -0,0 +1 @@ +common_src += files(['CDriverBase.cpp']) diff --git a/Common/src/meson.build b/Common/src/meson.build index b3e0726e70c..4902f8bf9ab 100644 --- a/Common/src/meson.build +++ b/Common/src/meson.build @@ -13,6 +13,7 @@ subdir('geometry/elements') subdir('geometry/dual_grid') subdir('geometry/primal_grid') subdir('geometry/meshreader') +subdir('drivers') subdir('interface_interpolation') subdir('fem') subdir('grid_movement') diff --git a/SU2_CFD/include/drivers/CDriver.hpp b/SU2_CFD/include/drivers/CDriver.hpp index 7f27dab3bbe..32843db8c50 100644 --- a/SU2_CFD/include/drivers/CDriver.hpp +++ b/SU2_CFD/include/drivers/CDriver.hpp @@ -1,4 +1,4 @@ -/*! +/*! * \file driver_structure.hpp * \brief Headers of the main subroutines for driving single or multi-zone problems. * The subroutines and functions are in the driver_structure.cpp file. @@ -35,6 +35,7 @@ #include "../interfaces/CInterface.hpp" #include "../../../Common/include/geometry/CGeometry.hpp" +#include "../../../Common/include/drivers/CDriverBase.hpp" using namespace std; @@ -48,739 +49,629 @@ class COutput; * \brief Parent class for driving an iteration of a single or multi-zone problem. * \author T. Economon */ -class CDriver { -protected: - int rank, /*!< \brief MPI Rank. */ - size; /*!< \brief MPI Size. */ - char* config_file_name; /*!< \brief Configuration file name of the problem.*/ - char runtime_file_name[MAX_STRING_SIZE]; - su2double StartTime, /*!< \brief Start point of the timer for performance benchmarking.*/ - StopTime, /*!< \brief Stop point of the timer for performance benchmarking.*/ - UsedTimePreproc, /*!< \brief Elapsed time between Start and Stop point of the timer for tracking preprocessing phase.*/ - UsedTimeCompute, /*!< \brief Elapsed time between Start and Stop point of the timer for tracking compute phase.*/ - UsedTimeOutput, /*!< \brief Elapsed time between Start and Stop point of the timer for tracking output phase.*/ - UsedTime; /*!< \brief Elapsed time between Start and Stop point of the timer.*/ - su2double BandwidthSum = 0.0; /*!< \brief Aggregate value of the bandwidth for writing restarts (to be average later).*/ - unsigned long IterCount, /*!< \brief Iteration count stored for performance benchmarking.*/ - OutputCount; /*!< \brief Output count stored for performance benchmarking.*/ - unsigned long DOFsPerPoint; /*!< \brief Number of unknowns at each vertex, i.e., number of equations solved. */ - su2double Mpoints; /*!< \brief Total number of grid points in millions in the calculation (including ghost points).*/ - su2double MpointsDomain; /*!< \brief Total number of grid points in millions in the calculation (excluding ghost points).*/ - su2double MDOFs; /*!< \brief Total number of DOFs in millions in the calculation (including ghost points).*/ - su2double MDOFsDomain; /*!< \brief Total number of DOFs in millions in the calculation (excluding ghost points).*/ - unsigned long TimeIter; /*!< \brief External iteration.*/ - ofstream **ConvHist_file; /*!< \brief Convergence history file.*/ - ofstream FSIHist_file; /*!< \brief FSI convergence history file.*/ - unsigned short iMesh, /*!< \brief Iterator on mesh levels.*/ - iZone, /*!< \brief Iterator on zones.*/ - nZone, /*!< \brief Total number of zones in the problem. */ - nDim, /*!< \brief Number of dimensions.*/ - iInst, /*!< \brief Iterator on instance levels.*/ - *nInst, /*!< \brief Total number of instances in the problem (per zone). */ - **interface_types; /*!< \brief Type of coupling between the distinct (physical) zones.*/ - bool StopCalc, /*!< \brief Stop computation flag.*/ - mixingplane, /*!< \brief mixing-plane simulation flag.*/ - fsi, /*!< \brief FSI simulation flag.*/ - fem_solver; /*!< \brief FEM fluid solver simulation flag. */ - CIteration ***iteration_container; /*!< \brief Container vector with all the iteration methods. */ - COutput **output_container; /*!< \brief Pointer to the COutput class. */ - CIntegration ****integration_container; /*!< \brief Container vector with all the integration methods. */ - CGeometry ****geometry_container; /*!< \brief Geometrical definition of the problem. */ - CSolver *****solver_container; /*!< \brief Container vector with all the solutions. */ - CNumerics ******numerics_container; /*!< \brief Description of the numerical method (the way in which the equations are solved). */ - CConfig **config_container; /*!< \brief Definition of the particular problem. */ - CConfig *driver_config; /*!< \brief Definition of the driver configuration. */ - COutput *driver_output; /*!< \brief Definition of the driver output. */ - CSurfaceMovement **surface_movement; /*!< \brief Surface movement classes of the problem. */ - CVolumetricMovement ***grid_movement; /*!< \brief Volume grid movement classes of the problem. */ - CFreeFormDefBox*** FFDBox; /*!< \brief FFD FFDBoxes of the problem. */ - vector > > - interpolator_container; /*!< \brief Definition of the interpolation method between non-matching discretizations of the interface. */ - CInterface ***interface_container; /*!< \brief Definition of the interface of information and physics. */ - bool dry_run; /*!< \brief Flag if SU2_CFD was started as dry-run via "SU2_CFD -d .cfg" */ +class CDriver : public CDriverBase { + +protected: + + char runtime_file_name[MAX_STRING_SIZE]; + su2double UsedTimeOutput; /*!< \brief Elapsed time between Start and Stop point of the timer for tracking output phase.*/ + + su2double BandwidthSum = 0.0; /*!< \brief Aggregate value of the bandwidth for writing restarts (to be average later).*/ + unsigned long IterCount, /*!< \brief Iteration count stored for performance benchmarking.*/ + OutputCount; /*!< \brief Output count stored for performance benchmarking.*/ + unsigned long DOFsPerPoint; /*!< \brief Number of unknowns at each vertex, i.e., number of equations solved. */ + su2double Mpoints; /*!< \brief Total number of grid points in millions in the calculation (including ghost points).*/ + su2double MpointsDomain; /*!< \brief Total number of grid points in millions in the calculation (excluding ghost points).*/ + su2double MDOFs; /*!< \brief Total number of DOFs in millions in the calculation (including ghost points).*/ + su2double MDOFsDomain; /*!< \brief Total number of DOFs in millions in the calculation (excluding ghost points).*/ + + ofstream **ConvHist_file; /*!< \brief Convergence history file.*/ + ofstream FSIHist_file; /*!< \brief FSI convergence history file.*/ + + bool StopCalc, /*!< \brief Stop computation flag.*/ + mixingplane, /*!< \brief mixing-plane simulation flag.*/ + fsi, /*!< \brief FSI simulation flag.*/ + fem_solver; /*!< \brief FEM fluid solver simulation flag. */ + + CIteration ***iteration_container; /*!< \brief Container vector with all the iteration methods. */ + CIntegration ****integration_container; /*!< \brief Container vector with all the integration methods. */ + vector > > + interpolator_container; /*!< \brief Definition of the interpolation method between non-matching discretizations of the interface. */ + CInterface ***interface_container; /*!< \brief Definition of the interface of information and physics. */ + bool dry_run; /*!< \brief Flag if SU2_CFD was started as dry-run via "SU2_CFD -d .cfg" */ + public: - - /*! - * \brief Constructor of the class. - * \param[in] confFile - Configuration file name. - * \param[in] val_nZone - Total number of zones. - * \param[in] val_nDim - Number of dimensions. - * \param[in] MPICommunicator - MPI communicator for SU2. - */ - CDriver(char* confFile, - unsigned short val_nZone, - SU2_Comm MPICommunicator, bool dummy_geo); - - /*! - * \brief Destructor of the class. - */ - virtual ~CDriver(void); - - /*! - * \brief A virtual member. - */ - virtual void Run() { }; - + + /*! + * \brief Constructor of the class. + * \param[in] confFile - Configuration file name. + * \param[in] val_nZone - Total number of zones. + * \param[in] val_nDim - Number of dimensions. + * \param[in] MPICommunicator - MPI communicator for SU2. + */ + CDriver(char* confFile, + unsigned short val_nZone, + SU2_Comm MPICommunicator, bool dummy_geo); + + /*! + * \brief Destructor of the class. + */ + virtual ~CDriver(void); + + /*! + * \brief A virtual member. + */ + virtual void Run() { }; + protected: - - /*! - * \brief Init_Containers - */ - void SetContainers_Null(); - - /*! - * \brief Read in the config and mesh files. - */ - void Input_Preprocessing(CConfig **&config, CConfig *&driver_config); - - /*! - * \brief Construction of the edge-based data structure and the multigrid structure. - */ - void Geometrical_Preprocessing(CConfig *config, CGeometry **&geometry, bool dummy); - - /*! - * \brief Do the geometrical preprocessing for the DG FEM solver. - */ - void Geometrical_Preprocessing_DGFEM(CConfig *config, CGeometry **&geometry); - - /*! - * \brief Geometrical_Preprocessing_FVM - */ - void Geometrical_Preprocessing_FVM(CConfig *config, CGeometry **&geometry); - - /*! - * \brief Definition of the physics iteration class or within a single zone. - * \param[in] iteration_container - Pointer to the iteration container to be instantiated. - * \param[in] config - Definition of the particular problem. - * \param[in] iZone - Index of the zone. - */ - void Iteration_Preprocessing(CConfig *config, CIteration *&iteration) const; - - /*! - * \brief Definition and allocation of all solution classes. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void Solver_Preprocessing(CConfig *config, CGeometry **geometry, CSolver ***&solver); - - /*! - * \brief Restart of the solvers from the restart files. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void Solver_Restart(CSolver ***solver, CGeometry **geometry, CConfig *config, bool update_geo); - - /*! - * \brief Definition and allocation of all solution classes. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void Solver_Postprocessing(CSolver ****solver, CGeometry **geometry, CConfig *config, unsigned short val_iInst); - - /*! - * \brief Definition and allocation of all integration classes. - * \param[in] config - Definition of the particular problem. - * \param[in] solver - Container vector with all the solutions. - * \param[out] integration - Container vector with all the integration methods. - */ - void Integration_Preprocessing(CConfig *config, CSolver **solver, CIntegration **&integration) const; - - /*! - * \brief Definition and allocation of all integration classes. - * \param[in] integration_container - Container vector with all the integration methods. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void Integration_Postprocessing(CIntegration ***integration, CGeometry **geometry, CConfig *config, unsigned short val_iInst); - - /*! - * \brief Definition and allocation of all interface classes. - */ - void Interface_Preprocessing(CConfig **config, CSolver *****solver, CGeometry ****geometry, - unsigned short **interface_types, CInterface ***interface, - vector > > &interpolation); - - /*! - * \brief Definition and allocation of all solver classes. - * \param[in] numerics_container - Description of the numerical method (the way in which the equations are solved). - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - void Numerics_Preprocessing(CConfig *config, CGeometry **geometry, CSolver ***solver, CNumerics ****&numerics) const; - - /*! - * \brief Helper to instantiate turbulence numerics specialized for different flow solvers. - */ - template - void InstantiateTurbulentNumerics(unsigned short nVar_Turb, int offset, const CConfig *config, - const CSolver* turb_solver, CNumerics ****&numerics) const; - - /*! - * \brief Helper to instantiate species transport numerics specialized for different flow solvers. - */ - template - void InstantiateSpeciesNumerics(unsigned short nVar_Species, int offset, const CConfig *config, - const CSolver* species_solver, CNumerics ****&numerics) const; - - /*! - * \brief Definition and allocation of all solver classes. - * \param[in] numerics_container - Description of the numerical method (the way in which the equations are solved). - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void Numerics_Postprocessing(CNumerics *****numerics, CSolver ***solver, CGeometry **geometry, CConfig *config, unsigned short val_iInst); - - /*! - * \brief GridMovement_Preprocessing - * \param config - * \param geometry - * \param solver - * \param iteration - * \param grid_movement - * \param surface_movement - */ - void DynamicMesh_Preprocessing(CConfig *config, CGeometry **geometry, CSolver ***solver, CIteration *iteration, CVolumetricMovement *&grid_movement, CSurfaceMovement *&surface_movement) const; - - /*! - * \brief Initialize Python interface functionalities - */ - void PythonInterface_Preprocessing(CConfig** config, CGeometry**** geometry, CSolver***** solver); - - /*! - * \brief Preprocess the output container. - */ - void Output_Preprocessing(CConfig **config, CConfig *driver_config, COutput **&output_container, COutput *&driver_output); - - /*! - * \brief Initiate value for static mesh movement such as the gridVel for the ROTATING frame. - */ - void StaticMesh_Preprocessing(const CConfig *config, CGeometry **geometry); - - /*! - * \brief Initiate value for static mesh movement such as the gridVel for the ROTATING frame. - */ - void Turbomachinery_Preprocessing(CConfig** config, CGeometry**** geometry, CSolver***** solver, - CInterface*** interface); - - /*! - * \brief A virtual member. - * \param[in] donorZone - zone in which the displacements will be predicted. - * \param[in] targetZone - zone which receives the predicted displacements. - */ - virtual void Predict_Displacements(unsigned short donorZone, unsigned short targetZone) {} - - /*! - * \brief A virtual member. - * \param[in] donorZone - zone in which the tractions will be predicted. - * \param[in] targetZone - zone which receives the predicted traction. - */ - virtual void Predict_Tractions(unsigned short donorZone, unsigned short targetZone) {} - - /*! - * \brief A virtual member. - * \param[in] donorZone - zone in which the displacements will be transferred. - * \param[in] targetZone - zone which receives the tractions transferred. - */ - virtual void Transfer_Displacements(unsigned short donorZone, unsigned short targetZone) {} - - /*! - * \brief A virtual member. - * \param[in] donorZone - zone from which the tractions will be transferred. - * \param[in] targetZone - zone which receives the tractions transferred. - */ - virtual void Transfer_Tractions(unsigned short donorZone, unsigned short targetZone) {} - - /*! - * \brief A virtual member. - * \param[in] donorZone - origin of the information. - * \param[in] targetZone - destination of the information. - * \param[in] iOuterIter - Fluid-Structure Interaction subiteration. - */ - virtual void Relaxation_Displacements(unsigned short donorZone, unsigned short targetZone, unsigned long iOuterIter) {} - - /*! - * \brief A virtual member. - * \param[in] donorZone - origin of the information. - * \param[in] targetZone - destination of the information. - * \param[in] iOuterIter - Fluid-Structure Interaction subiteration. - */ - virtual void Relaxation_Tractions(unsigned short donorZone, unsigned short targetZone, unsigned long iOuterIter) {} - - /*! - * \brief A virtual member to run a Block Gauss-Seidel iteration in multizone problems. - */ - virtual void Run_GaussSeidel(){} - - /*! - * \brief A virtual member to run a Block-Jacobi iteration in multizone problems. - */ - virtual void Run_Jacobi(){} - - /*! - * \brief A virtual member. - */ - virtual void Update() {} - - /*! - * \brief Print out the direct residuals. - * \param[in] kind_recording - Type of recording (full list in ENUM_RECORDING, option_structure.hpp) - */ - void Print_DirectResidual(RECORDING kind_recording); - + + /*! + * \brief Init_Containers + */ + void SetContainers_Null(); + + /*! + * \brief Read in the config and mesh files. + */ + void Input_Preprocessing(CConfig **&config, CConfig *&driver_config); + + /*! + * \brief Construction of the edge-based data structure and the multigrid structure. + */ + void Geometrical_Preprocessing(CConfig *config, CGeometry **&geometry, bool dummy); + + /*! + * \brief Do the geometrical preprocessing for the DG FEM solver. + */ + void Geometrical_Preprocessing_DGFEM(CConfig *config, CGeometry **&geometry); + + /*! + * \brief Geometrical_Preprocessing_FVM + */ + void Geometrical_Preprocessing_FVM(CConfig *config, CGeometry **&geometry); + + /*! + * \brief Definition of the physics iteration class or within a single zone. + * \param[in] iteration_container - Pointer to the iteration container to be instantiated. + * \param[in] config - Definition of the particular problem. + * \param[in] iZone - Index of the zone. + */ + void Iteration_Preprocessing(CConfig *config, CIteration *&iteration) const; + + /*! + * \brief Definition and allocation of all solution classes. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void Solver_Preprocessing(CConfig *config, CGeometry **geometry, CSolver ***&solver); + + /*! + * \brief Restart of the solvers from the restart files. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void Solver_Restart(CSolver ***solver, CGeometry **geometry, CConfig *config, bool update_geo); + + /*! + * \brief Definition and allocation of all solution classes. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void Solver_Postprocessing(CSolver ****solver, CGeometry **geometry, CConfig *config, unsigned short val_iInst); + + /*! + * \brief Definition and allocation of all integration classes. + * \param[in] config - Definition of the particular problem. + * \param[in] solver - Container vector with all the solutions. + * \param[out] integration - Container vector with all the integration methods. + */ + void Integration_Preprocessing(CConfig *config, CSolver **solver, CIntegration **&integration) const; + + /*! + * \brief Definition and allocation of all integration classes. + * \param[in] integration_container - Container vector with all the integration methods. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void Integration_Postprocessing(CIntegration ***integration, CGeometry **geometry, CConfig *config, unsigned short val_iInst); + + /*! + * \brief Definition and allocation of all interface classes. + */ + void Interface_Preprocessing(CConfig **config, CSolver *****solver, CGeometry ****geometry, + unsigned short **interface_types, CInterface ***interface, + vector > > &interpolation); + + /*! + * \brief Definition and allocation of all solver classes. + * \param[in] numerics_container - Description of the numerical method (the way in which the equations are solved). + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + void Numerics_Preprocessing(CConfig *config, CGeometry **geometry, CSolver ***solver, CNumerics ****&numerics) const; + + /*! + * \brief Helper to instantiate turbulence numerics specialized for different flow solvers. + */ + template + void InstantiateTurbulentNumerics(unsigned short nVar_Turb, int offset, const CConfig *config, + const CSolver* turb_solver, CNumerics ****&numerics) const; + + /*! + * \brief Helper to instantiate species transport numerics specialized for different flow solvers. + */ + template + void InstantiateSpeciesNumerics(unsigned short nVar_Species, int offset, const CConfig *config, + const CSolver* species_solver, CNumerics ****&numerics) const; + + /*! + * \brief Definition and allocation of all solver classes. + * \param[in] numerics_container - Description of the numerical method (the way in which the equations are solved). + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void Numerics_Postprocessing(CNumerics *****numerics, CSolver ***solver, CGeometry **geometry, CConfig *config, unsigned short val_iInst); + + /*! + * \brief GridMovement_Preprocessing + * \param config + * \param geometry + * \param solver + * \param iteration + * \param grid_movement + * \param surface_movement + */ + void DynamicMesh_Preprocessing(CConfig *config, CGeometry **geometry, CSolver ***solver, CIteration *iteration, CVolumetricMovement *&grid_movement, CSurfaceMovement *&surface_movement) const; + + /*! + * \brief Initialize Python interface functionalities + */ + void PythonInterface_Preprocessing(CConfig** config, CGeometry**** geometry, CSolver***** solver); + + /*! + * \brief Preprocess the output container. + */ + void Output_Preprocessing(CConfig **config, CConfig *driver_config, COutput **&output_container, COutput *&driver_output); + + /*! + * \brief Initiate value for static mesh movement such as the gridVel for the ROTATING frame. + */ + void StaticMesh_Preprocessing(const CConfig *config, CGeometry **geometry); + + /*! + * \brief Initiate value for static mesh movement such as the gridVel for the ROTATING frame. + */ + void Turbomachinery_Preprocessing(CConfig** config, CGeometry**** geometry, CSolver***** solver, + CInterface*** interface); + + /*! + * \brief A virtual member. + * \param[in] donorZone - zone in which the displacements will be predicted. + * \param[in] targetZone - zone which receives the predicted displacements. + */ + virtual void Predict_Displacements(unsigned short donorZone, unsigned short targetZone) {} + + /*! + * \brief A virtual member. + * \param[in] donorZone - zone in which the tractions will be predicted. + * \param[in] targetZone - zone which receives the predicted traction. + */ + virtual void Predict_Tractions(unsigned short donorZone, unsigned short targetZone) {} + + /*! + * \brief A virtual member. + * \param[in] donorZone - zone in which the displacements will be transferred. + * \param[in] targetZone - zone which receives the tractions transferred. + */ + virtual void Transfer_Displacements(unsigned short donorZone, unsigned short targetZone) {} + + /*! + * \brief A virtual member. + * \param[in] donorZone - zone from which the tractions will be transferred. + * \param[in] targetZone - zone which receives the tractions transferred. + */ + virtual void Transfer_Tractions(unsigned short donorZone, unsigned short targetZone) {} + + /*! + * \brief A virtual member. + * \param[in] donorZone - origin of the information. + * \param[in] targetZone - destination of the information. + * \param[in] iOuterIter - Fluid-Structure Interaction subiteration. + */ + virtual void Relaxation_Displacements(unsigned short donorZone, unsigned short targetZone, unsigned long iOuterIter) {} + + /*! + * \brief A virtual member. + * \param[in] donorZone - origin of the information. + * \param[in] targetZone - destination of the information. + * \param[in] iOuterIter - Fluid-Structure Interaction subiteration. + */ + virtual void Relaxation_Tractions(unsigned short donorZone, unsigned short targetZone, unsigned long iOuterIter) {} + + /*! + * \brief A virtual member to run a Block Gauss-Seidel iteration in multizone problems. + */ + virtual void Run_GaussSeidel(){} + + /*! + * \brief A virtual member to run a Block-Jacobi iteration in multizone problems. + */ + virtual void Run_Jacobi(){} + + /*! + * \brief A virtual member. + */ + virtual void Update() {} + + /*! + * \brief Print out the direct residuals. + * \param[in] kind_recording - Type of recording (full list in ENUM_RECORDING, option_structure.hpp) + */ + void Print_DirectResidual(RECORDING kind_recording); + public: - - /*! - * \brief Launch the computation for all zones and all physics. - */ - virtual void StartSolver() {} - - /*! - * \brief Deallocation routine - */ - void Postprocessing(); - - /*! - * \brief A virtual member. - */ - virtual void ResetConvergence(); - - /*! - * \brief Perform some pre-processing before an iteration of the physics. - */ - virtual void Preprocess(unsigned long TimeIter){ } - - /*! - * \brief Monitor the computation. - */ - virtual bool Monitor(unsigned long TimeIter){ return false; } - - /*! - * \brief Output the solution in solution file. - */ - virtual void Output(unsigned long TimeIter){ } - - /*! - * \brief Perform a dynamic mesh deformation, including grid velocity computation and update of the multigrid structure. - */ - virtual void DynamicMeshUpdate(unsigned long TimeIter) { } - - /*! - * \brief Perform a dynamic mesh deformation, including grid velocity computation and update of the multigrid structure. - */ - virtual void DynamicMeshUpdate(unsigned short val_iZone, unsigned long TimeIter) { } - - /*! - * \brief Perform a mesh deformation as initial condition. - */ - virtual void SetInitialMesh() { } - - /*! - * \brief Process the boundary conditions and update the multigrid structure. - */ - void BoundaryConditionsUpdate(); - - /*! - * \brief Get the total drag. - * \return Total drag. - */ - passivedouble Get_Drag() const; - - /*! - * \brief Get the total lift. - * \return Total lift. - */ - passivedouble Get_Lift() const; - - /*! - * \brief Get the total x moment. - * \return Total x moment. - */ - passivedouble Get_Mx() const; - - /*! - * \brief Get the total y moment. - * \return Total y moment. - */ - passivedouble Get_My() const; - - /*! - * \brief Get the total z moment. - * \return Total z moment. - */ - passivedouble Get_Mz() const; - - /*! - * \brief Get the total drag coefficient. - * \return Total drag coefficient. - */ - passivedouble Get_DragCoeff() const; - - /*! - * \brief Get the total lift coefficient. - * \return Total lift coefficient. - */ - passivedouble Get_LiftCoeff() const; - - /*! - * \brief Get the number of vertices (halo nodes included) from a specified marker. - * \param[in] iMarker - Marker identifier. - * \return Number of vertices. - */ - unsigned long GetNumberVertices(unsigned short iMarker) const; - - /*! - * \brief Get the number of halo vertices from a specified marker. - * \param[in] iMarker - Marker identifier. - * \return Number of vertices. - */ - unsigned long GetNumberHaloVertices(unsigned short iMarker) const; - - /*! - * \brief Check if a vertex is physical or not (halo node) on a specified marker. - * \param[in] iMarker - Marker identifier. - * \param[in] iVertex - Vertex identifier. - * \return True if the specified vertex is a halo node. - */ - bool IsAHaloNode(unsigned short iMarker, unsigned long iVertex) const; - - /*! - * \brief Get the number of external iterations. - * \return Number of external iterations. - */ - unsigned long GetnTimeIter() const; - - /*! - * \brief Get the current external iteration. - * \return Current external iteration. - */ - unsigned long GetTime_Iter() const; - - /*! - * \brief Get the unsteady time step. - * \return Unsteady time step. - */ - passivedouble GetUnsteady_TimeStep() const; - - /*! - * \brief Get the name of the output file for the surface. - * \return File name for the surface output. - */ - string GetSurfaceFileName() const; - - /*! - * \brief Get the global index of a vertex on a specified marker. - * \param[in] iMarker - Marker identifier. - * \param[in] iVertex - Vertex identifier. - * \return Vertex global index. - */ - unsigned long GetVertexGlobalIndex(unsigned short iMarker, unsigned long iVertex) const; - - /*! - * \brief Get undeformed coordinates from the mesh solver. - * \param[in] iMarker - Marker identifier. - * \param[in] iVertex - Vertex identifier. - * \return x,y,z coordinates of the vertex. - */ - vector GetInitialMeshCoord(unsigned short iMarker, unsigned long iVertex) const; - - /*! - * \brief Get the temperature at a vertex on a specified marker. - * \param[in] iMarker - Marker identifier. - * \param[in] iVertex - Vertex identifier. - * \return Temperature of the vertex. - */ - passivedouble GetVertexTemperature(unsigned short iMarker, unsigned long iVertex) const; - - /*! - * \brief Set the temperature of a vertex on a specified marker. - * \param[in] iMarker - Marker identifier. - * \param[in] iVertex - Vertex identifier. - * \param[in] val_WallTemp - Value of the temperature. - */ - void SetVertexTemperature(unsigned short iMarker, unsigned long iVertex, passivedouble val_WallTemp); - - /*! - * \brief Get the heat flux at a vertex on a specified marker (3 components). - * \param[in] iMarker - Marker identifier. - * \param[in] iVertex - Vertex identifier. - * \return True if the vertex is a halo node. - */ - vector GetVertexHeatFluxes(unsigned short iMarker, unsigned long iVertex) const; - - /*! - * \brief Get the wall normal component of the heat flux at a vertex on a specified marker. - * \param[in] iMarker - Marker identifier. - * \param[in] iVertex - Vertex identifier. - * \return Wall normal component of the heat flux at the vertex. - */ - passivedouble GetVertexNormalHeatFlux(unsigned short iMarker, unsigned long iVertex) const; - - /*! - * \brief Set the wall normal component of the heat flux at a vertex on a specified marker. - * \param[in] iMarker - Marker identifier. - * \param[in] iVertex - Vertex identifier. - * \param[in] val_WallHeatFlux - Value of the normal heat flux. - */ - void SetVertexNormalHeatFlux(unsigned short iMarker, unsigned long iVertex, passivedouble val_WallHeatFlux); - - /*! - * \brief Get the thermal conductivity at a vertex on a specified marker. - * \param[in] iMarker - Marker identifier. - * \param[in] iVertex - Vertex identifier. - * \return Thermal conductivity at the vertex. - */ - passivedouble GetThermalConductivity(unsigned short iMarker, unsigned long iVertex) const; - - /*! - * \brief Preprocess the inlets via file input for all solvers. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void Inlet_Preprocessing(CSolver ***solver, CGeometry **geometry, CConfig *config) const; - - /*! - * \brief Get the normal (vector) at a vertex on a specified marker. - * \param[in] iMarker - Marker identifier. - * \param[in] iVertex - Vertex identifier. - * \param[in] unitNormal - Bool to normalise the vector. - * \return Normal (vector) at the vertex. - */ - vector GetVertexNormal(unsigned short iMarker, unsigned long iVertex, bool unitNormal = false) const; - - /*! - * \brief Get the unit normal (vector) at a vertex on a specified marker. - * \param[in] iMarker - Marker identifier. - * \param[in] iVertex - Vertex identifier. - * \return Unit normal (vector) at the vertex. - */ - inline vector GetVertexUnitNormal(unsigned short iMarker, unsigned long iVertex) const { - return GetVertexNormal(iMarker, iVertex, true); - } - - /*! - * \brief Get all the boundary markers tags. - * \return List of boundary markers tags. - */ - vector GetAllBoundaryMarkersTag() const; - - /*! - * \brief Get all the deformable boundary marker tags. - * \return List of deformable boundary markers tags. - */ - vector GetAllDeformMeshMarkersTag() const; - - /*! - * \brief Get all the heat transfer boundary markers tags. - * \return List of heat transfer boundary markers tags. - */ - vector GetAllCHTMarkersTag() const; - - /*! - * \brief Get all the (subsonic) inlet boundary markers tags. - * \return List of inlet boundary markers tags. - */ - vector GetAllInletMarkersTag() const; - - /*! - * \brief Get all the boundary markers tags with their associated indices. - * \return List of boundary markers tags with their indices. - */ - map GetAllBoundaryMarkers() const; - - /*! - * \brief Get all the boundary markers tags with their associated types. - * \return List of boundary markers tags with their types. - */ - map GetAllBoundaryMarkersType() const; - - /*! - * \brief Set the mesh displacement for the elasticity mesh solver. - * \param[in] iMarker - Marker identifier. - * \param[in] iVertex - Vertex identifier. - * \param[in] DispX - Value of the mesh displacement in the direction X. - * \param[in] DispY - Value of the mesh displacement in the direction Y. - * \param[in] DispZ - Value of the mesh displacement in the direction Z. - */ - void SetMeshDisplacement(unsigned short iMarker, unsigned long iVertex, passivedouble DispX, passivedouble DispY, passivedouble DispZ); - - /*! - * \brief Communicate the boundary mesh displacements in a python call - */ - void CommunicateMeshDisplacement(void); - - /*! - * \brief Return the sensitivities of the mesh boundary vertices. - * \param[in] iMarker - Marker identifier. - * \param[in] iVertex - Vertex identifier. - * \return Vector of sensitivities. - */ - vector GetMeshDisp_Sensitivity(unsigned short iMarker, unsigned long iVertex) const; - - /*! - * \brief Set the load in X direction for the structural solver. - * \param[in] iMarker - Marker identifier. - * \param[in] iVertex - Vertex identifier. - * \param[in] LoadX - Value of the load in the direction X. - * \param[in] LoadX - Value of the load in the direction Y. - * \param[in] LoadX - Value of the load in the direction Z. - */ - void SetFEA_Loads(unsigned short iMarker, unsigned long iVertex, passivedouble LoadX, - passivedouble LoadY, passivedouble LoadZ); - - /*! - * \brief Return the displacements from the FEA solver. - * \param[in] iMarker - Marker identifier. - * \param[in] iVertex - Vertex identifier. - * \return Vector of displacements. - */ - vector GetFEA_Displacements(unsigned short iMarker, unsigned long iVertex) const; - - /*! - * \brief Return the velocities from the FEA Solver. - * \param[in] iMarker - Marker identifier. - * \param[in] iVertex - Vertex identifier. - * \return Vector of velocities. - */ - vector GetFEA_Velocity(unsigned short iMarker, unsigned long iVertex) const; - - /*! - * \brief Return the velocities from the FEA Solver. - * \param[in] iMarker - Marker identifier. - * \param[in] iVertex - Vertex identifier. - * \return Vector of velocities at time n. - */ - vector GetFEA_Velocity_n(unsigned short iMarker, unsigned long iVertex) const; - - /*! - * \brief Get the sensitivity of the flow loads for the structural solver. - * \param[in] iMarker - Marker identifier. - * \param[in] iVertex - Vertex identifier. - * \param[in] LoadX - Value of the load in the direction X. - * \param[in] LoadX - Value of the load in the direction Y. - * \param[in] LoadX - Value of the load in the direction Z. - */ - vector GetFlowLoad_Sensitivity(unsigned short iMarker, unsigned long iVertex) const; - - /*! - * \brief Get the flow load (from the extra step - the repeated methods should be unified once the postprocessing - * strategy is in place). - * \param[in] iMarker - Marker identifier. - * \param[in] iVertex - Vertex identifier. - */ - vector GetFlowLoad(unsigned short iMarker, unsigned long iVertex) const; - - /*! - * \brief Set the adjoint of the flow tractions (from the extra step - - * the repeated methods should be unified once the postprocessing strategy is in place). - * \param[in] iMarker - Marker identifier. - * \param[in] iVertex - Vertex identifier. - * \param[in] val_AdjointX - Value of the adjoint in the direction X. - * \param[in] val_AdjointY - Value of the adjoint in the direction Y. - * \param[in] val_AdjointZ - Value of the adjoint in the direction Z. - */ - void SetFlowLoad_Adjoint(unsigned short iMarker, unsigned long iVertex, passivedouble val_AdjointX, - passivedouble val_AdjointY, passivedouble val_AdjointZ); - - /*! - * \brief Set the adjoint of the structural displacements (from an outside source) - * \param[in] iMarker - Marker identifier. - * \param[in] iVertex - Vertex identifier. - * \param[in] val_AdjointX - Value of the adjoint in the direction X. - * \param[in] val_AdjointY - Value of the adjoint in the direction Y. - * \param[in] val_AdjointZ - Value of the adjoint in the direction Z. - */ - void SetSourceTerm_DispAdjoint(unsigned short iMarker, unsigned long iVertex, passivedouble val_AdjointX, - passivedouble val_AdjointY, passivedouble val_AdjointZ); - void SetSourceTerm_VelAdjoint(unsigned short iMarker, unsigned long iVertex, passivedouble val_AdjointX, - passivedouble val_AdjointY, passivedouble val_AdjointZ); - - /*! - * \brief Set the position of the heat source. - * \param[in] alpha - Angle of rotation respect to Z axis. - * \param[in] pos_x - Position X. - * \param[in] pos_y - Position Y. - * \param[in] pos_z - Position Z. - */ - void SetHeatSource_Position(passivedouble alpha, passivedouble pos_x, passivedouble pos_y, passivedouble pos_z); - - /*! - * \brief Set the direction of the inlet. - * \param[in] iMarker - Marker index. - * \param[in] alpha - Angle (Zpos). - */ - void SetInlet_Angle(unsigned short iMarker, passivedouble alpha); - - /*! - * \brief Sum the number of primal or adjoint variables for all solvers in a given zone. - * \param[in] iZone - Index of the zone. - * \param[in] adjoint - True to consider adjoint solvers instead of primal. - * \return Total number of solution variables. - */ - unsigned short GetTotalNumberOfVariables(unsigned short iZone, bool adjoint) const { - unsigned short nVar = 0; - for (auto iSol = 0u; iSol < MAX_SOLS; iSol++) { - auto solver = solver_container[iZone][INST_0][MESH_0][iSol]; - if (solver && (solver->GetAdjoint() == adjoint)) nVar += solver->GetnVar(); + + /*! + * \brief Launch the computation for all zones and all physics. + */ + virtual void StartSolver() {} + + /*! + * \brief Deallocation routine + */ + void Postprocessing(); + + /*! + * \brief A virtual member. + */ + virtual void ResetConvergence(); + + /*! + * \brief Perform some pre-processing before an iteration of the physics. + */ + virtual void Preprocess(unsigned long TimeIter){ } + + /*! + * \brief Monitor the computation. + */ + virtual bool Monitor(unsigned long TimeIter){ return false; } + + /*! + * \brief Output the solution in solution file. + */ + virtual void Output(unsigned long TimeIter){ } + + /*! + * \brief Perform a dynamic mesh deformation, including grid velocity computation and update of the multigrid structure. + */ + virtual void DynamicMeshUpdate(unsigned long TimeIter) { } + + /*! + * \brief Perform a dynamic mesh deformation, including grid velocity computation and update of the multigrid structure. + */ + virtual void DynamicMeshUpdate(unsigned short val_iZone, unsigned long TimeIter) { } + + /*! + * \brief Perform a mesh deformation as initial condition. + */ + virtual void SetInitialMesh() { } + + /*! + * \brief Process the boundary conditions and update the multigrid structure. + */ + void BoundaryConditionsUpdate(); + + /*! + * \brief Get the total drag. + * \return Total drag. + */ + passivedouble Get_Drag() const; + + /*! + * \brief Get the total lift. + * \return Total lift. + */ + passivedouble Get_Lift() const; + + /*! + * \brief Get the total x moment. + * \return Total x moment. + */ + passivedouble Get_Mx() const; + + /*! + * \brief Get the total y moment. + * \return Total y moment. + */ + passivedouble Get_My() const; + + /*! + * \brief Get the total z moment. + * \return Total z moment. + */ + passivedouble Get_Mz() const; + + /*! + * \brief Get the total drag coefficient. + * \return Total drag coefficient. + */ + passivedouble Get_DragCoeff() const; + + /*! + * \brief Get the total lift coefficient. + * \return Total lift coefficient. + */ + passivedouble Get_LiftCoeff() const; + + /*! + * \brief Get the number of external iterations. + * \return Number of external iterations. + */ + unsigned long GetnTimeIter() const; + + /*! + * \brief Get the current external iteration. + * \return Current external iteration. + */ + unsigned long GetTime_Iter() const; + + /*! + * \brief Get the unsteady time step. + * \return Unsteady time step. + */ + passivedouble GetUnsteady_TimeStep() const; + + /*! + * \brief Get the name of the output file for the surface. + * \return File name for the surface output. + */ + string GetSurfaceFileName() const; + + /*! + * \brief Get the temperature at a vertex on a specified marker. + * \param[in] iMarker - Marker identifier. + * \param[in] iVertex - Vertex identifier. + * \return Temperature of the vertex. + */ + passivedouble GetVertexTemperature(unsigned short iMarker, unsigned long iVertex) const; + + /*! + * \brief Set the temperature of a vertex on a specified marker. + * \param[in] iMarker - Marker identifier. + * \param[in] iVertex - Vertex identifier. + * \param[in] val_WallTemp - Value of the temperature. + */ + void SetVertexTemperature(unsigned short iMarker, unsigned long iVertex, passivedouble val_WallTemp); + + /*! + * \brief Get the heat flux at a vertex on a specified marker (3 components). + * \param[in] iMarker - Marker identifier. + * \param[in] iVertex - Vertex identifier. + * \return True if the vertex is a halo node. + */ + vector GetVertexHeatFluxes(unsigned short iMarker, unsigned long iVertex) const; + + /*! + * \brief Get the wall normal component of the heat flux at a vertex on a specified marker. + * \param[in] iMarker - Marker identifier. + * \param[in] iVertex - Vertex identifier. + * \return Wall normal component of the heat flux at the vertex. + */ + passivedouble GetVertexNormalHeatFlux(unsigned short iMarker, unsigned long iVertex) const; + + /*! + * \brief Set the wall normal component of the heat flux at a vertex on a specified marker. + * \param[in] iMarker - Marker identifier. + * \param[in] iVertex - Vertex identifier. + * \param[in] val_WallHeatFlux - Value of the normal heat flux. + */ + void SetVertexNormalHeatFlux(unsigned short iMarker, unsigned long iVertex, passivedouble val_WallHeatFlux); + + /*! + * \brief Get the thermal conductivity at a vertex on a specified marker. + * \param[in] iMarker - Marker identifier. + * \param[in] iVertex - Vertex identifier. + * \return Thermal conductivity at the vertex. + */ + passivedouble GetThermalConductivity(unsigned short iMarker, unsigned long iVertex) const; + + /*! + * \brief Preprocess the inlets via file input for all solvers. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void Inlet_Preprocessing(CSolver ***solver, CGeometry **geometry, CConfig *config) const; + + /*! + * \brief Get all the boundary markers tags. + * \return List of boundary markers tags. + */ + vector GetAllBoundaryMarkersTag() const; + + /*! + * \brief Get all the heat transfer boundary markers tags. + * \return List of heat transfer boundary markers tags. + */ + vector GetAllCHTMarkersTag() const; + + /*! + * \brief Get all the (subsonic) inlet boundary markers tags. + * \return List of inlet boundary markers tags. + */ + vector GetAllInletMarkersTag() const; + + /*! + * \brief Return the sensitivities of the mesh boundary vertices. + * \param[in] iMarker - Marker identifier. + * \param[in] iVertex - Vertex identifier. + * \return Vector of sensitivities. + */ + vector GetMeshDisp_Sensitivity(unsigned short iMarker, unsigned long iVertex) const; + + /*! + * \brief Set the load in X direction for the structural solver. + * \param[in] iMarker - Marker identifier. + * \param[in] iVertex - Vertex identifier. + * \param[in] LoadX - Value of the load in the direction X. + * \param[in] LoadX - Value of the load in the direction Y. + * \param[in] LoadX - Value of the load in the direction Z. + */ + void SetFEA_Loads(unsigned short iMarker, unsigned long iVertex, passivedouble LoadX, passivedouble LoadY, passivedouble LoadZ); + + /*! + * \brief Return the displacements from the FEA solver. + * \param[in] iMarker - Marker identifier. + * \param[in] iVertex - Vertex identifier. + * \return Vector of displacements. + */ + vector GetFEA_Displacements(unsigned short iMarker, unsigned long iVertex) const; + + /*! + * \brief Return the velocities from the FEA Solver. + * \param[in] iMarker - Marker identifier. + * \param[in] iVertex - Vertex identifier. + * \return Vector of velocities. + */ + vector GetFEA_Velocity(unsigned short iMarker, unsigned long iVertex) const; + + /*! + * \brief Return the velocities from the FEA Solver. + * \param[in] iMarker - Marker identifier. + * \param[in] iVertex - Vertex identifier. + * \return Vector of velocities at time n. + */ + vector GetFEA_Velocity_n(unsigned short iMarker, unsigned long iVertex) const; + + /*! + * \brief Get the sensitivity of the flow loads for the structural solver. + * \param[in] iMarker - Marker identifier. + * \param[in] iVertex - Vertex identifier. + * \param[in] LoadX - Value of the load in the direction X. + * \param[in] LoadX - Value of the load in the direction Y. + * \param[in] LoadX - Value of the load in the direction Z. + */ + vector GetFlowLoad_Sensitivity(unsigned short iMarker, unsigned long iVertex) const; + + /*! + * \brief Get the flow load (from the extra step - the repeated methods should be unified once the postprocessing + * strategy is in place). + * \param[in] iMarker - Marker identifier. + * \param[in] iVertex - Vertex identifier. + */ + vector GetFlowLoad(unsigned short iMarker, unsigned long iVertex) const; + + /*! + * \brief Set the adjoint of the flow tractions (from the extra step - + * the repeated methods should be unified once the postprocessing strategy is in place). + * \param[in] iMarker - Marker identifier. + * \param[in] iVertex - Vertex identifier. + * \param[in] val_AdjointX - Value of the adjoint in the direction X. + * \param[in] val_AdjointY - Value of the adjoint in the direction Y. + * \param[in] val_AdjointZ - Value of the adjoint in the direction Z. + */ + void SetFlowLoad_Adjoint(unsigned short iMarker, unsigned long iVertex, passivedouble val_AdjointX, + passivedouble val_AdjointY, passivedouble val_AdjointZ); + + /*! + * \brief Set the adjoint of the structural displacements (from an outside source) + * \param[in] iMarker - Marker identifier. + * \param[in] iVertex - Vertex identifier. + * \param[in] val_AdjointX - Value of the adjoint in the direction X. + * \param[in] val_AdjointY - Value of the adjoint in the direction Y. + * \param[in] val_AdjointZ - Value of the adjoint in the direction Z. + */ + void SetSourceTerm_DispAdjoint(unsigned short iMarker, unsigned long iVertex, passivedouble val_AdjointX, + passivedouble val_AdjointY, passivedouble val_AdjointZ); + void SetSourceTerm_VelAdjoint(unsigned short iMarker, unsigned long iVertex, passivedouble val_AdjointX, + passivedouble val_AdjointY, passivedouble val_AdjointZ); + + /*! + * \brief Set the position of the heat source. + * \param[in] alpha - Angle of rotation respect to Z axis. + * \param[in] pos_x - Position X. + * \param[in] pos_y - Position Y. + * \param[in] pos_z - Position Z. + */ + void SetHeatSource_Position(passivedouble alpha, passivedouble pos_x, passivedouble pos_y, passivedouble pos_z); + + /*! + * \brief Set the direction of the inlet. + * \param[in] iMarker - Marker index. + * \param[in] alpha - Angle (Zpos). + */ + void SetInlet_Angle(unsigned short iMarker, passivedouble alpha); + + /*! + * \brief Sum the number of primal or adjoint variables for all solvers in a given zone. + * \param[in] iZone - Index of the zone. + * \param[in] adjoint - True to consider adjoint solvers instead of primal. + * \return Total number of solution variables. + */ + unsigned short GetTotalNumberOfVariables(unsigned short iZone, bool adjoint) const { + unsigned short nVar = 0; + for (auto iSol = 0u; iSol < MAX_SOLS; iSol++) { + auto solver = solver_container[iZone][INST_0][MESH_0][iSol]; + if (solver && (solver->GetAdjoint() == adjoint)) nVar += solver->GetnVar(); + } + return nVar; } - return nVar; - } - - /*! - * \brief Set the solution of all solvers (adjoint or primal) in a zone. - * \param[in] iZone - Index of the zone. - * \param[in] adjoint - True to consider adjoint solvers instead of primal. - * \param[in] solution - Solution object with interface (iPoint,iVar). - * \tparam Old - If true set "old solutions" instead. - */ - template - void SetAllSolutions(unsigned short iZone, bool adjoint, const Container& solution) { - const auto nPoint = geometry_container[iZone][INST_0][MESH_0]->GetnPoint(); - for (auto iSol = 0u, offset = 0u; iSol < MAX_SOLS; ++iSol) { - auto solver = solver_container[iZone][INST_0][MESH_0][iSol]; - if (!(solver && (solver->GetAdjoint() == adjoint))) continue; - for (auto iPoint = 0ul; iPoint < nPoint; ++iPoint) - for (auto iVar = 0ul; iVar < solver->GetnVar(); ++iVar) - if (!Old) solver->GetNodes()->SetSolution(iPoint, iVar, solution(iPoint,offset+iVar)); - else solver->GetNodes()->SetSolution_Old(iPoint, iVar, solution(iPoint,offset+iVar)); - offset += solver->GetnVar(); + + /*! + * \brief Set the solution of all solvers (adjoint or primal) in a zone. + * \param[in] iZone - Index of the zone. + * \param[in] adjoint - True to consider adjoint solvers instead of primal. + * \param[in] solution - Solution object with interface (iPoint,iVar). + * \tparam Old - If true set "old solutions" instead. + */ + template + void SetAllSolutions(unsigned short iZone, bool adjoint, const Container& solution) { + const auto nPoint = geometry_container[iZone][INST_0][MESH_0]->GetnPoint(); + for (auto iSol = 0u, offset = 0u; iSol < MAX_SOLS; ++iSol) { + auto solver = solver_container[iZone][INST_0][MESH_0][iSol]; + if (!(solver && (solver->GetAdjoint() == adjoint))) continue; + for (auto iPoint = 0ul; iPoint < nPoint; ++iPoint) + for (auto iVar = 0ul; iVar < solver->GetnVar(); ++iVar) + if (!Old) solver->GetNodes()->SetSolution(iPoint, iVar, solution(iPoint,offset+iVar)); + else solver->GetNodes()->SetSolution_Old(iPoint, iVar, solution(iPoint,offset+iVar)); + offset += solver->GetnVar(); + } } - } - - /*! - * \brief Set the "old solution" of all solvers (adjoint or primal) in a zone. - */ - template - void SetAllSolutionsOld(unsigned short iZone, bool adjoint, const Container& solution) { - SetAllSolutions(iZone, adjoint, solution); - } - - /*! - * \brief Get the solution of all solvers (adjoint or primal) in a zone. - * \param[in] iZone - Index of the zone. - * \param[in] adjoint - True to consider adjoint solvers instead of primal. - * \param[out] solution - Solution object with interface (iPoint,iVar). - */ - template - void GetAllSolutions(unsigned short iZone, bool adjoint, Container& solution) const { - const auto nPoint = geometry_container[iZone][INST_0][MESH_0]->GetnPoint(); - for (auto iSol = 0u, offset = 0u; iSol < MAX_SOLS; ++iSol) { - auto solver = solver_container[iZone][INST_0][MESH_0][iSol]; - if (!(solver && (solver->GetAdjoint() == adjoint))) continue; - const auto& sol = solver->GetNodes()->GetSolution(); - for (auto iPoint = 0ul; iPoint < nPoint; ++iPoint) - for (auto iVar = 0ul; iVar < solver->GetnVar(); ++iVar) - solution(iPoint,offset+iVar) = SU2_TYPE::GetValue(sol(iPoint,iVar)); - offset += solver->GetnVar(); + + /*! + * \brief Set the "old solution" of all solvers (adjoint or primal) in a zone. + */ + template + void SetAllSolutionsOld(unsigned short iZone, bool adjoint, const Container& solution) { + SetAllSolutions(iZone, adjoint, solution); } - } - + + /*! + * \brief Get the solution of all solvers (adjoint or primal) in a zone. + * \param[in] iZone - Index of the zone. + * \param[in] adjoint - True to consider adjoint solvers instead of primal. + * \param[out] solution - Solution object with interface (iPoint,iVar). + */ + template + void GetAllSolutions(unsigned short iZone, bool adjoint, Container& solution) const { + const auto nPoint = geometry_container[iZone][INST_0][MESH_0]->GetnPoint(); + for (auto iSol = 0u, offset = 0u; iSol < MAX_SOLS; ++iSol) { + auto solver = solver_container[iZone][INST_0][MESH_0][iSol]; + if (!(solver && (solver->GetAdjoint() == adjoint))) continue; + const auto& sol = solver->GetNodes()->GetSolution(); + for (auto iPoint = 0ul; iPoint < nPoint; ++iPoint) + for (auto iVar = 0ul; iVar < solver->GetnVar(); ++iVar) + solution(iPoint,offset+iVar) = SU2_TYPE::GetValue(sol(iPoint,iVar)); + offset += solver->GetnVar(); + } + } + }; /*! @@ -789,69 +680,69 @@ class CDriver { * \author T. Economon, G. Gori */ class CFluidDriver : public CDriver { - + protected: - unsigned long Max_Iter; - + unsigned long Max_Iter; + protected: - - /*! - * \brief Constructor of the class. - * \param[in] confFile - Configuration file name. - * \param[in] val_nZone - Total number of zones. - * \param[in] val_nDim - Number of dimensions. - * \param[in] MPICommunicator - MPI communicator for SU2. - */ - CFluidDriver(char* confFile, - unsigned short val_nZone, - SU2_Comm MPICommunicator); - + + /*! + * \brief Constructor of the class. + * \param[in] confFile - Configuration file name. + * \param[in] val_nZone - Total number of zones. + * \param[in] val_nDim - Number of dimensions. + * \param[in] MPICommunicator - MPI communicator for SU2. + */ + CFluidDriver(char* confFile, + unsigned short val_nZone, + SU2_Comm MPICommunicator); + public: - /*! - * \brief Destructor of the class. - */ - ~CFluidDriver(void) override; - - /*! - * \brief Launch the computation for all zones and all physics. - */ - void StartSolver() override; - - /*! - * \brief Run a single iteration of the physics within multiple zones. - */ - void Run() override; - - /*! - * \brief Update the dual-time solution within multiple zones. - */ - void Update() override; - - /*! - * \brief Output the solution in solution file. - */ - void Output(unsigned long InnerIter) override; - - /*! - * \brief Monitor the computation. - */ - bool Monitor(unsigned long ExtIter) override; - - /*! - * \brief Perform some pre-processing before an iteration of the physics. - */ - void Preprocess(unsigned long Iter) override; - - /*! - * \brief Perform a dynamic mesh deformation, included grid velocity computation and the update of the multigrid structure (multiple zone). - */ - void DynamicMeshUpdate(unsigned long TimeIter) override; - - /*! - * \brief Transfer data among different zones (multiple zone). - */ - void Transfer_Data(unsigned short donorZone, unsigned short targetZone); - + /*! + * \brief Destructor of the class. + */ + ~CFluidDriver(void) override; + + /*! + * \brief Launch the computation for all zones and all physics. + */ + void StartSolver() override; + + /*! + * \brief Run a single iteration of the physics within multiple zones. + */ + void Run() override; + + /*! + * \brief Update the dual-time solution within multiple zones. + */ + void Update() override; + + /*! + * \brief Output the solution in solution file. + */ + void Output(unsigned long InnerIter) override; + + /*! + * \brief Monitor the computation. + */ + bool Monitor(unsigned long ExtIter) override; + + /*! + * \brief Perform some pre-processing before an iteration of the physics. + */ + void Preprocess(unsigned long Iter) override; + + /*! + * \brief Perform a dynamic mesh deformation, included grid velocity computation and the update of the multigrid structure (multiple zone). + */ + void DynamicMeshUpdate(unsigned long TimeIter) override; + + /*! + * \brief Transfer data among different zones (multiple zone). + */ + void Transfer_Data(unsigned short donorZone, unsigned short targetZone); + }; @@ -862,50 +753,50 @@ class CFluidDriver : public CDriver { */ class CTurbomachineryDriver : public CFluidDriver { private: - COutputLegacy* output_legacy; - + COutputLegacy* output_legacy; + public: - - /*! - * \brief Constructor of the class. - * \param[in] confFile - Configuration file name. - * \param[in] val_nZone - Total number of zones. - * \param[in] val_nDim - Number of dimensions. - * \param[in] val_periodic - Bool for periodic BCs. - * \param[in] MPICommunicator - MPI communicator for SU2. - */ - CTurbomachineryDriver(char* confFile, - unsigned short val_nZone, - SU2_Comm MPICommunicator); - - /*! - * \brief Destructor of the class. - */ - ~CTurbomachineryDriver(void) override; - - /*! - * \brief Run a single iteration of the physics within multiple zones. - */ - - void Run() override; - - /*! - * \brief Set Mixing Plane interface within multiple zones. - */ - void SetMixingPlane(unsigned short iZone); - - /*! - * \brief Set Mixing Plane interface within multiple zones. - */ - void SetTurboPerformance(unsigned short targetZone); - - /*! - * \brief Monitor the computation. - */ - bool Monitor(unsigned long TimeIter) override; - - - + + /*! + * \brief Constructor of the class. + * \param[in] confFile - Configuration file name. + * \param[in] val_nZone - Total number of zones. + * \param[in] val_nDim - Number of dimensions. + * \param[in] val_periodic - Bool for periodic BCs. + * \param[in] MPICommunicator - MPI communicator for SU2. + */ + CTurbomachineryDriver(char* confFile, + unsigned short val_nZone, + SU2_Comm MPICommunicator); + + /*! + * \brief Destructor of the class. + */ + ~CTurbomachineryDriver(void) override; + + /*! + * \brief Run a single iteration of the physics within multiple zones. + */ + + void Run() override; + + /*! + * \brief Set Mixing Plane interface within multiple zones. + */ + void SetMixingPlane(unsigned short iZone); + + /*! + * \brief Set Mixing Plane interface within multiple zones. + */ + void SetTurboPerformance(unsigned short targetZone); + + /*! + * \brief Monitor the computation. + */ + bool Monitor(unsigned long TimeIter) override; + + + }; /*! @@ -914,61 +805,61 @@ class CTurbomachineryDriver : public CFluidDriver { * \author T. Economon */ class CHBDriver : public CFluidDriver { - + private: - COutputLegacy* output_legacy; - unsigned short nInstHB; - su2double **D; /*!< \brief Harmonic Balance operator. */ - + COutputLegacy* output_legacy; + unsigned short nInstHB; + su2double **D; /*!< \brief Harmonic Balance operator. */ + public: - - /*! - * \brief Constructor of the class. - * \param[in] confFile - Configuration file name. - * \param[in] val_nZone - Total number of zones. - * \param[in] val_nDim - Number of dimensions. - * \param[in] MPICommunicator - MPI communicator for SU2. - */ - CHBDriver(char* confFile, - unsigned short val_nZone, - SU2_Comm MPICommunicator); - - /*! - * \brief Destructor of the class. - */ - ~CHBDriver(void) override; - - /*! - * \brief Run a single iteration of a Harmonic Balance problem. - */ - void Run() override; - - /*! - * \brief Computation and storage of the Harmonic Balance method source terms. - * \author T. Economon, K. Naik - * \param[in] iZone - Current zone number. - */ - void SetHarmonicBalance(unsigned short iZone); - - /*! - * \brief Precondition Harmonic Balance source term for stability - * \author J. Howison - */ - void StabilizeHarmonicBalance(); - - /*! - * \brief Computation of the Harmonic Balance operator matrix for harmonic balance. - * \author A. Rubino, S. Nimmagadda - */ - void ComputeHB_Operator(); - - /*! - * \brief Update the solution for the Harmonic Balance. - */ - void Update() override; - - /*! - * \brief Reset the convergence flag (set to false) of the solver for the Harmonic Balance. - */ - void ResetConvergence() override; + + /*! + * \brief Constructor of the class. + * \param[in] confFile - Configuration file name. + * \param[in] val_nZone - Total number of zones. + * \param[in] val_nDim - Number of dimensions. + * \param[in] MPICommunicator - MPI communicator for SU2. + */ + CHBDriver(char* confFile, + unsigned short val_nZone, + SU2_Comm MPICommunicator); + + /*! + * \brief Destructor of the class. + */ + ~CHBDriver(void) override; + + /*! + * \brief Run a single iteration of a Harmonic Balance problem. + */ + void Run() override; + + /*! + * \brief Computation and storage of the Harmonic Balance method source terms. + * \author T. Economon, K. Naik + * \param[in] iZone - Current zone number. + */ + void SetHarmonicBalance(unsigned short iZone); + + /*! + * \brief Precondition Harmonic Balance source term for stability + * \author J. Howison + */ + void StabilizeHarmonicBalance(); + + /*! + * \brief Computation of the Harmonic Balance operator matrix for harmonic balance. + * \author A. Rubino, S. Nimmagadda + */ + void ComputeHB_Operator(); + + /*! + * \brief Update the solution for the Harmonic Balance. + */ + void Update() override; + + /*! + * \brief Reset the convergence flag (set to false) of the solver for the Harmonic Balance. + */ + void ResetConvergence() override; }; diff --git a/SU2_CFD/src/drivers/CDriver.cpp b/SU2_CFD/src/drivers/CDriver.cpp index fa14d73fe34..dcb8447d591 100644 --- a/SU2_CFD/src/drivers/CDriver.cpp +++ b/SU2_CFD/src/drivers/CDriver.cpp @@ -107,8 +107,7 @@ #include CDriver::CDriver(char* confFile, unsigned short val_nZone, SU2_Comm MPICommunicator, bool dummy_geo) : - config_file_name(confFile), StartTime(0.0), StopTime(0.0), UsedTime(0.0), - TimeIter(0), nZone(val_nZone), StopCalc(false), fsi(false), fem_solver(false), dry_run(dummy_geo) { + CDriverBase(confFile, val_nZone, MPICommunicator), StopCalc(false), fsi(false), fem_solver(false), dry_run(dummy_geo) { /*--- Initialize Medipack (must also be here so it is initialized from python) ---*/ #ifdef HAVE_MPI diff --git a/SU2_CFD/src/python_wrapper_structure.cpp b/SU2_CFD/src/python_wrapper_structure.cpp index 206c81492d1..2f85546f4d3 100644 --- a/SU2_CFD/src/python_wrapper_structure.cpp +++ b/SU2_CFD/src/python_wrapper_structure.cpp @@ -166,99 +166,6 @@ passivedouble CDriver::Get_LiftCoeff() const { return SU2_TYPE::GetValue(CLift); } -///////////////////////////////////////////////////////////////////////////// -/* Functions to obtain information from the geometry/mesh */ -///////////////////////////////////////////////////////////////////////////// - -unsigned long CDriver::GetNumberVertices(unsigned short iMarker) const { - - return geometry_container[ZONE_0][INST_0][MESH_0]->nVertex[iMarker]; - -} - -unsigned long CDriver::GetNumberHaloVertices(unsigned short iMarker) const { - - unsigned long nHaloVertices, iVertex, iPoint; - - nHaloVertices = 0; - for(iVertex = 0; iVertex < geometry_container[ZONE_0][INST_0][MESH_0]->nVertex[iMarker]; iVertex++){ - iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); - if(!(geometry_container[ZONE_0][INST_0][MESH_0]->nodes->GetDomain(iPoint))) nHaloVertices += 1; - } - - return nHaloVertices; - -} - -unsigned long CDriver::GetVertexGlobalIndex(unsigned short iMarker, unsigned long iVertex) const { - - unsigned long iPoint, GlobalIndex; - - iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); - GlobalIndex = geometry_container[ZONE_0][INST_0][MESH_0]->nodes->GetGlobalIndex(iPoint); - - return GlobalIndex; - -} - -bool CDriver::IsAHaloNode(unsigned short iMarker, unsigned long iVertex) const { - - unsigned long iPoint; - - iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); - if(geometry_container[ZONE_0][INST_0][MESH_0]->nodes->GetDomain(iPoint)) return false; - else return true; - -} - -vector CDriver::GetInitialMeshCoord(unsigned short iMarker, unsigned long iVertex) const { - - vector coord(3,0.0); - vector coord_passive(3, 0.0); - - auto iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); - for (auto iDim = 0 ; iDim < nDim ; iDim++){ - coord[iDim] = solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->GetMesh_Coord(iPoint,iDim); - } - - coord_passive[0] = SU2_TYPE::GetValue(coord[0]); - coord_passive[1] = SU2_TYPE::GetValue(coord[1]); - coord_passive[2] = SU2_TYPE::GetValue(coord[2]); - - return coord_passive; -} - -vector CDriver::GetVertexNormal(unsigned short iMarker, unsigned long iVertex, bool unitNormal) const { - - su2double *Normal; - su2double Area; - vector ret_Normal(3, 0.0); - vector ret_Normal_passive(3, 0.0); - - Normal = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNormal(); - - if (!unitNormal) { - - ret_Normal_passive[0] = SU2_TYPE::GetValue(Normal[0]); - ret_Normal_passive[1] = SU2_TYPE::GetValue(Normal[1]); - if(nDim>2) ret_Normal_passive[2] = SU2_TYPE::GetValue(Normal[2]); - - return ret_Normal_passive; - } - - Area = GeometryToolbox::Norm(nDim, Normal); - - ret_Normal[0] = Normal[0]/Area; - ret_Normal[1] = Normal[1]/Area; - if(nDim>2) ret_Normal[2] = Normal[2]/Area; - - ret_Normal_passive[0] = SU2_TYPE::GetValue(ret_Normal[0]); - ret_Normal_passive[1] = SU2_TYPE::GetValue(ret_Normal[1]); - ret_Normal_passive[2] = SU2_TYPE::GetValue(ret_Normal[2]); - - return ret_Normal_passive; -} - ////////////////////////////////////////////////////////////////////////////////// /* Functions to obtain global parameters from SU2 (time steps, delta t, ecc...) */ ////////////////////////////////////////////////////////////////////////////////// @@ -430,23 +337,6 @@ vector CDriver::GetAllBoundaryMarkersTag() const { return boundariesTagList; } -vector CDriver::GetAllDeformMeshMarkersTag() const { - - vector interfaceBoundariesTagList; - unsigned short iMarker, nBoundariesMarker; - string Marker_Tag; - - nBoundariesMarker = config_container[ZONE_0]->GetnMarker_Deform_Mesh(); - interfaceBoundariesTagList.resize(nBoundariesMarker); - - for(iMarker=0; iMarker < nBoundariesMarker; iMarker++){ - Marker_Tag = config_container[ZONE_0]->GetMarker_Deform_Mesh_TagBound(iMarker); - interfaceBoundariesTagList[iMarker] = Marker_Tag; - } - - return interfaceBoundariesTagList; -} - vector CDriver::GetAllCHTMarkersTag() const { vector CHTBoundariesTagList; @@ -486,65 +376,6 @@ vector CDriver::GetAllInletMarkersTag() const { return BoundariesTagList; } -map CDriver::GetAllBoundaryMarkers() const { - - map allBoundariesMap; - unsigned short iMarker, nBoundaryMarkers; - string Marker_Tag; - - nBoundaryMarkers = config_container[ZONE_0]->GetnMarker_All(); - - for(iMarker=0; iMarker < nBoundaryMarkers; iMarker++){ - Marker_Tag = config_container[ZONE_0]->GetMarker_All_TagBound(iMarker); - allBoundariesMap[Marker_Tag] = iMarker; - } - - return allBoundariesMap; -} - -map CDriver::GetAllBoundaryMarkersType() const { - - map allBoundariesTypeMap; - unsigned short iMarker, KindBC; - string Marker_Tag, Marker_Type; - - for(iMarker=0; iMarker < config_container[ZONE_0]->GetnMarker_All(); iMarker++){ - Marker_Tag = config_container[ZONE_0]->GetMarker_All_TagBound(iMarker); - KindBC = config_container[ZONE_0]->GetMarker_All_KindBC(iMarker); - switch(KindBC){ - case EULER_WALL: - Marker_Type = "EULER_WALL"; - break; - case FAR_FIELD: - Marker_Type = "FARFIELD"; - break; - case ISOTHERMAL: - Marker_Type = "ISOTHERMAL"; - break; - case HEAT_FLUX: - Marker_Type = "HEATFLUX"; - break; - case INLET_FLOW: - Marker_Type = "INLET_FLOW"; - break; - case OUTLET_FLOW: - Marker_Type = "OUTLET_FLOW"; - break; - case SYMMETRY_PLANE: - Marker_Type = "SYMMETRY"; - break; - case SEND_RECEIVE: - Marker_Type = "SEND_RECEIVE"; - break; - default: - Marker_Type = "UNKNOWN_TYPE"; - } - allBoundariesTypeMap[Marker_Tag] = Marker_Type; - } - - return allBoundariesTypeMap; -} - void CDriver::SetHeatSource_Position(passivedouble alpha, passivedouble pos_x, passivedouble pos_y, passivedouble pos_z){ CSolver *solver = solver_container[ZONE_0][INST_0][MESH_0][RAD_SOL]; @@ -837,34 +668,6 @@ void CDriver::SetSourceTerm_VelAdjoint(unsigned short iMarker, unsigned long iVe } -//////////////////////////////////////////////////////////////////////////////// -/* Functions related to mesh deformation */ -//////////////////////////////////////////////////////////////////////////////// - -void CDriver::SetMeshDisplacement(unsigned short iMarker, unsigned long iVertex, passivedouble DispX, passivedouble DispY, passivedouble DispZ) { - - unsigned long iPoint; - su2double MeshDispl[3] = {0.0,0.0,0.0}; - - MeshDispl[0] = DispX; - MeshDispl[1] = DispY; - MeshDispl[2] = DispZ; - - iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); - - solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->SetBound_Disp(iPoint,MeshDispl); - -} - -void CDriver::CommunicateMeshDisplacement(void) { - - solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->InitiateComms(geometry_container[ZONE_0][INST_0][MESH_0], - config_container[ZONE_0], MESH_DISPLACEMENTS); - solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->CompleteComms(geometry_container[ZONE_0][INST_0][MESH_0], - config_container[ZONE_0], MESH_DISPLACEMENTS); - -} - //////////////////////////////////////////////////////////////////////////////// /* Functions related to flow loads */ //////////////////////////////////////////////////////////////////////////////// diff --git a/SU2_DEF/include/drivers/CDeformationDriver.hpp b/SU2_DEF/include/drivers/CDeformationDriver.hpp index 8196faeda5a..5c1d7c0da4e 100644 --- a/SU2_DEF/include/drivers/CDeformationDriver.hpp +++ b/SU2_DEF/include/drivers/CDeformationDriver.hpp @@ -1,8 +1,8 @@ - /*! +/*! * \file CDeformationDriver.hpp * \brief Headers of the main subroutines for driving the mesh deformation. - * \author T. Economon, H. Kline, R. Sanchez - * \version 7.1.1 "Blackbird" + * \author A. Gastaldi, H. Patel + * \version 7.3.0 "Blackbird" * * SU2 Project Website: https://su2code.github.io * @@ -38,32 +38,12 @@ #include "../../../SU2_CFD/include/output/COutput.hpp" #include "../../../SU2_CFD/include/numerics/CNumerics.hpp" #include "../../../Common/include/geometry/CGeometry.hpp" +#include "../../../Common/include/drivers/CDriverBase.hpp" + +class CDeformationDriver : public CDriverBase { -/*! - * \class CDeformationDriver - * \brief Class for driving mesh deformation solvers. - * \author A. Gastaldi, H. Patel - * \version 7.1.1 "Blackbird" - */ -class CDeformationDriver { protected: - char config_file_name[MAX_STRING_SIZE]; - int rank, - size; - su2double StartTime, /*!< \brief Start point of the timer for performance benchmarking.*/ - StopTime, /*!< \brief Stop point of the timer for performance benchmarking.*/ - UsedTimePreproc, /*!< \brief Elapsed time between Start and Stop point of the timer for tracking preprocessing phase.*/ - UsedTimeCompute, /*!< \brief Elapsed time between Start and Stop point of the timer for tracking compute phase.*/ - UsedTime; /*!< \brief Elapsed time between Start and Stop point of the timer.*/ - unsigned short iZone, nZone = SINGLE_ZONE; - CConfig *driver_config; /*!< \brief Definition of the driver configuration. */ - CConfig **config_container; /*!< \brief Definition of the particular problem. */ - CGeometry **geometry_container; /*!< \brief Geometrical definition of the problem. */ - CSurfaceMovement **surface_movement; /*!< \brief Surface movement classes of the problem. */ - CVolumetricMovement **grid_movement; /*!< \brief Volume grid movement classes of the problem. */ - CSolver **solver_container; CNumerics ***numerics_container; - COutput **output_container; /*!< \brief Pointer to the COutput class. */ public: /*! @@ -93,88 +73,7 @@ class CDeformationDriver { */ void Postprocessing(); - /*! - * \brief Get all the deformable boundary marker tags. - * \return List of deformable boundary markers tags. - */ - vector GetAllDeformMeshMarkersTag() const; - - /*! - * \brief Get all the boundary markers tags with their associated indices. - * \return List of boundary markers tags with their indices. - */ - map GetAllBoundaryMarkers() const; - - /*! - * \brief Get all the boundary markers tags with their associated types. - * \return List of boundary markers tags with their types. - */ - map GetAllBoundaryMarkersType() const; - - /*! - * \brief Get the number of vertices (halo nodes included) from a specified marker. - * \param[in] iMarker - Marker identifier. - * \return Number of vertices. - */ - unsigned long GetNumberVertices(unsigned short iMarker) const; - - /*! - * \brief Get the number of halo vertices from a specified marker. - * \param[in] iMarker - Marker identifier. - * \return Number of vertices. - */ - unsigned long GetNumberHaloVertices(unsigned short iMarker) const; - - /*! - * \brief Check if a vertex is physical or not (halo node) on a specified marker. - * \param[in] iMarker - Marker identifier. - * \param[in] iVertex - Vertex identifier. - * \return True if the specified vertex is a halo node. - */ - bool IsAHaloNode(unsigned short iMarker, unsigned long iVertex) const; - - /*! - * \brief Get the global index of a vertex on a specified marker. - * \param[in] iMarker - Marker identifier. - * \param[in] iVertex - Vertex identifier. - * \return Vertex global index. - */ - unsigned long GetVertexGlobalIndex(unsigned short iMarker, unsigned long iVertex) const; - - /*! - * \brief Get undeformed coordinates from the mesh solver. - * \param[in] iMarker - Marker identifier. - * \param[in] iVertex - Vertex identifier. - * \return x,y,z coordinates of the vertex. - */ - vector GetInitialMeshCoord(unsigned short iMarker, unsigned long iVertex) const; - - /*! - * \brief Get the unit normal (vector) at a vertex on a specified marker. - * \param[in] iMarker - Marker identifier. - * \param[in] iVertex - Vertex identifier. - * \return Unit normal (vector) at the vertex. - */ - vector GetVertexNormal(unsigned short iMarker, unsigned long iVertex, bool unitNormal = false) const; - - inline vector GetVertexUnitNormal(unsigned short iMarker, unsigned long iVertex) const { - return GetVertexNormal(iMarker, iVertex, true); - } - - /*! - * \brief Set the mesh displacement for the elasticity mesh solver. - * \param[in] iMarker - Marker identifier. - * \param[in] iVertex - Vertex identifier. - * \param[in] DispX - Value of the mesh displacement in the direction X. - * \param[in] DispY - Value of the mesh displacement in the direction Y. - * \param[in] DispZ - Value of the mesh displacement in the direction Z. - */ - void SetMeshDisplacement(unsigned short iMarker, unsigned long iVertex, passivedouble DispX, passivedouble DispY, passivedouble DispZ); - - /*! - * \brief Communicate the boundary mesh displacements in a python call - */ - void CommunicateMeshDisplacement(void); + void CommunicateMeshDisplacements(void); protected: /*! diff --git a/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp b/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp index 36cf9daab8f..41a1df49b2c 100644 --- a/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp +++ b/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp @@ -1,8 +1,8 @@ /*! -* \file CDiscAdjDeformationDriver.cpp -* \brief Main subroutines for driving the projection of sensitivities. + * \file CDiscAdjDeformationDriver.cpp + * \brief Headers of the main subroutines for driving the projection of sensitivities. * \author T. Economon, H. Kline, R. Sanchez - * \version 7.1.1 "Blackbird" + * \version 7.3.0 "Blackbird" * * SU2 Project Website: https://su2code.github.io * @@ -40,115 +40,126 @@ #include "../../../SU2_CFD/include/output/CBaselineOutput.hpp" #include "../../../SU2_CFD/include/solvers/CBaselineSolver.hpp" +#include "../../../Common/include/drivers/CDriverBase.hpp" +#include "../../../SU2_CFD/include/solvers/CGradientSmoothingSolver.hpp" +#include "../../../SU2_CFD/include/numerics/CGradSmoothing.hpp" + /*! * \class CDiscAdjDeformationDriver - * \brief Class for driving sensitivity DiscAdjDeformations. + * \brief Class for driving sensitivity projections. * \author A. Gastaldi, H. Patel - * \version 7.1.1 "Blackbird" + * \version 7.3.0 "Blackbird" */ -class CDiscAdjDeformationDriver { -protected: - char config_file_name[MAX_STRING_SIZE]; - int rank, - size; - unsigned short iZone, nZone = SINGLE_ZONE; - unsigned short iInst; - unsigned short* nInst; - su2double StartTime, /*!< \brief Start point of the timer for performance benchmarking.*/ - StopTime, /*!< \brief Stop point of the timer for performance benchmarking.*/ - UsedTimePreproc, /*!< \brief Elapsed time between Start and Stop point of the timer for tracking preprocessing phase.*/ - UsedTimeCompute, /*!< \brief Elapsed time between Start and Stop point of the timer for tracking compute phase.*/ - UsedTime; /*!< \brief Elapsed time between Start and Stop point of the timer.*/ - su2double** Gradient; - ofstream Gradient_file; - CConfig *driver_config; /*!< \brief Definition of the driver configuration. */ - CConfig **config_container; /*!< \brief Definition of the particular problem. */ - CGeometry ***geometry_container; /*!< \brief Geometrical definition of the problem. */ - CSurfaceMovement **surface_movement; - CVolumetricMovement **grid_movement; - COutput **output_container; /*!< \brief Pointer to the COutput class. */ +class CDiscAdjDeformationDriver : public CDriverBase { +protected: + su2double** Gradient; + ofstream Gradient_file; + CGeometry ***geometry_container; /*!< \brief Geometrical definition of the problem. */ + CSurfaceMovement **surface_movement; + CVolumetricMovement **grid_movement; + public: - /*! - * \brief Constructor of the class. - * \param[in] confFile - Configuration file name. - * \param[in] MPICommunicator - MPI communicator for SU2. - */ - CDiscAdjDeformationDriver(char* confFile, SU2_Comm MPICommunicator); - - /*! - * \brief Destructor of the class. - */ - ~CDiscAdjDeformationDriver(void); - - /*! - * \brief [Overload] Launch the computation for single-zone problems. - */ - void Run(); - - /*! - * \brief Deallocation routine - */ - void Postprocessing(); - + /*! + * \brief Constructor of the class. + * \param[in] confFile - Configuration file name. + * \param[in] MPICommunicator - MPI communicator for SU2. + */ + CDiscAdjDeformationDriver(char* confFile, SU2_Comm MPICommunicator); + + /*! + * \brief Destructor of the class. + */ + ~CDiscAdjDeformationDriver(void); + + /*! + * \brief [Overload] Launch the computation for single-zone problems. + */ + void Run(); + + /*! + * \brief Deallocation routine + */ + void Postprocessing(); + protected: - /*! - * \brief Init_Containers - */ - void SetContainers_Null(); - - /*! - * \brief Read in the config and mesh files. - */ - void Input_Preprocessing(); - - /*! - * \brief Construction of the edge-based data structure. - */ - void Geometrical_Preprocessing(); - - /*! - * \brief Preprocess the output container. - */ - void Output_Preprocessing(); - - /*! - * \brief DiscAdjDeformation of the surface sensitivity using finite differences (FD). - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] surface_movement - Surface movement class of the problem. - * \param[in] Gradient_file - Output file to store the gradient data. - */ - - void SetDiscAdjDeformation_FD(CGeometry *geometry, CConfig *config, CSurfaceMovement *surface_movement, su2double **Gradient); - - /*! - * \brief DiscAdjDeformation of the surface sensitivity using algorithmic differentiation (AD). - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] surface_movement - Surface movement class of the problem. - * \param[in] Gradient_file - Output file to store the gradient data. - */ - - void SetDiscAdjDeformation_AD(CGeometry *geometry, CConfig *config, CSurfaceMovement *surface_movement, su2double **Gradient); - - /*! - * \brief Prints the gradient information to a file. - * \param[in] Gradient - The gradient data. - * \param[in] config - Definition of the particular problem. - * \param[in] Gradient_file - Output file to store the gradient data. - */ - - void OutputGradient(su2double** Gradient, CConfig* config, ofstream& Gradient_file); - - /*! - * \brief Write the sensitivity (including mesh sensitivity) computed with the discrete adjoint method - * on the surface and in the volume to a file. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] val_nZone - Number of Zones. - */ - - void SetSensitivity_Files(CGeometry ***geometry, CConfig **config, unsigned short val_nZone); - + /*! + * \brief Init_Containers + */ + void SetContainers_Null(); + + /*! + * \brief Read in the config and mesh files. + */ + void Input_Preprocessing(); + + /*! + * \brief Construction of the edge-based data structure. + */ + void Geometrical_Preprocessing(); + + /*! + * \brief Preprocess the output container. + */ + void Output_Preprocessing(); + + /*! + * \brief Projection of the surface sensitivity using finite differences (FD). + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] surface_movement - Surface movement class of the problem. + * \param[in] Gradient_file - Output file to store the gradient data. + */ + + void SetProjection_FD(CGeometry *geometry, CConfig *config, CSurfaceMovement *surface_movement, su2double **Gradient); + + /*! + * \brief Projection of the surface sensitivity using algorithmic differentiation (AD). + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] surface_movement - Surface movement class of the problem. + * \param[in] Gradient_file - Output file to store the gradient data. + */ + + void SetProjection_AD(CGeometry *geometry, CConfig *config, CSurfaceMovement *surface_movement, su2double **Gradient); + + /*! + * \brief Prints the gradient information to a file. + * \param[in] Gradient - The gradient data. + * \param[in] config - Definition of the particular problem. + * \param[in] Gradient_file - Output file to store the gradient data. + */ + + void OutputGradient(su2double** Gradient, CConfig* config, ofstream& Gradient_file); + + /*! + * \brief Write the sensitivity (including mesh sensitivity) computed with the discrete adjoint method + * on the surface and in the volume to a file. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] val_nZone - Number of Zones. + */ + + void SetSensitivity_Files(CGeometry ***geometry, CConfig **config, unsigned short val_nZone); + + /*! + * \brief Treatment of derivatives with the Sobolev smoothing solver. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] grid_movement - Volumetric movement class of the problem. + */ + + void DerivativeTreatment_MeshSensitivity(CGeometry *geometry, CConfig *config, CVolumetricMovement *grid_movement); + + /*! + * \brief Treatment of derivatives with the Sobolev smoothing solver. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] grid_movement - Volumetric movement class of the problem. + * \param[in] surface_movement - Surface movement class of the problem. + * \param[in] Gradient - Output array to store the gradient data. + */ + + void DerivativeTreatment_Gradient(CGeometry *geometry, CConfig *config, CVolumetricMovement *grid_movement, CSurfaceMovement *surface_movement, su2double **Gradient); + }; diff --git a/SU2_DEF/src/drivers/CDeformationDriver.cpp b/SU2_DEF/src/drivers/CDeformationDriver.cpp index 81973fc7608..90563e93f2f 100644 --- a/SU2_DEF/src/drivers/CDeformationDriver.cpp +++ b/SU2_DEF/src/drivers/CDeformationDriver.cpp @@ -1,8 +1,8 @@ /*! - * \file CDeformationDriver.hpp + * \file CDeformationDriver.cpp * \brief Main subroutines for driving the mesh deformation. - * \author T. Economon, H. Kline, R. Sanchez - * \version 7.1.1 "Blackbird" + * \author A. Gastaldi, H. Patel + * \version 7.3.0 "Blackbird" * * SU2 Project Website: https://su2code.github.io * @@ -25,7 +25,6 @@ * License along with SU2. If not, see . */ - #include "../../include/drivers/CDeformationDriver.hpp" #include "../../../Common/include/geometry/CPhysicalGeometry.hpp" @@ -36,770 +35,589 @@ using namespace std; -CDeformationDriver::CDeformationDriver(char* confFile, SU2_Comm MPICommunicator) { - - /*--- Initialize Medipack (must also be here so it is initialized from python) ---*/ - #ifdef HAVE_MPI - #if defined(CODI_REVERSE_TYPE) || defined(CODI_FORWARD_TYPE) - SU2_MPI::Init_AMPI(); - #endif - #endif - - SU2_MPI::SetComm(MPICommunicator); - - rank = SU2_MPI::GetRank(); - size = SU2_MPI::GetSize(); - - /*--- Copy the config filename ---*/ - strcpy(config_file_name, confFile); - - /*--- Initialize the configuration of the driver ---*/ - driver_config = new CConfig(config_file_name, SU2_COMPONENT::SU2_DEF); - - nZone = driver_config->GetnZone(); - - /*--- Initialize containers --- */ - - SetContainers_Null(); - - /*--- Preprocessing of the config files. ---*/ - - Input_Preprocessing(); - - /*--- Set up a timer for performance benchmarking ---*/ - - StartTime = SU2_MPI::Wtime(); - - /*--- Preprocessing of the geometry for all zones. ---*/ - - Geometrical_Preprocessing(); - - /*--- Preprocessing of the output for all zones. ---*/ - - Output_Preprocessing(); - - if (driver_config->GetDeform_Mesh()){ - - /*--- Preprocessing of the mesh solver for all zones. ---*/ - - Solver_Preprocessing(); - - /*--- Preprocessing of the mesh solver for all zones. ---*/ - - Numerics_Preprocessing(); - - } - - /*--- Preprocessing time is reported now, but not included in the next compute portion. ---*/ - - StopTime = SU2_MPI::Wtime(); - - /*--- Compute/print the total time for performance benchmarking. ---*/ - - UsedTime = StopTime-StartTime; - UsedTimePreproc = UsedTime; - UsedTimeCompute = 0.0; - +CDeformationDriver::CDeformationDriver(char* confFile, SU2_Comm MPICommunicator): + CDriverBase(confFile, 1, MPICommunicator) +{ + + /*--- Initialize Medipack (must also be here so it is initialized from python) ---*/ +#ifdef HAVE_MPI +#if defined(CODI_REVERSE_TYPE) || defined(CODI_FORWARD_TYPE) + SU2_MPI::Init_AMPI(); +#endif +#endif + + SU2_MPI::SetComm(MPICommunicator); + + rank = SU2_MPI::GetRank(); + size = SU2_MPI::GetSize(); + + /*--- Copy the config filename ---*/ + strcpy(config_file_name, confFile); + + /*--- Initialize the configuration of the driver ---*/ + driver_config = new CConfig(config_file_name, SU2_COMPONENT::SU2_DEF); + + nZone = driver_config->GetnZone(); + + /*--- Initialize containers --- */ + + SetContainers_Null(); + + /*--- Preprocessing of the config files. ---*/ + + Input_Preprocessing(); + + /*--- Set up a timer for performance benchmarking ---*/ + + StartTime = SU2_MPI::Wtime(); + + /*--- Preprocessing of the geometry for all zones. ---*/ + + Geometrical_Preprocessing(); + + /*--- Preprocessing of the output for all zones. ---*/ + + Output_Preprocessing(); + + if (driver_config->GetDeform_Mesh()){ + + /*--- Preprocessing of the mesh solver for all zones. ---*/ + + Solver_Preprocessing(); + + /*--- Preprocessing of the mesh solver for all zones. ---*/ + + Numerics_Preprocessing(); + + } + + /*--- Preprocessing time is reported now, but not included in the next compute portion. ---*/ + + StopTime = SU2_MPI::Wtime(); + + /*--- Compute/print the total time for performance benchmarking. ---*/ + + UsedTime = StopTime-StartTime; + UsedTimePreproc = UsedTime; + UsedTimeCompute = 0.0; + } CDeformationDriver::~CDeformationDriver(void) { - + } void CDeformationDriver::SetContainers_Null() { - + /*--- Create pointers to all of the classes that may be used throughout - the SU2_DEF code. In general, the pointers are instantiated down a - hierarchy over all zones as described in the comments below. ---*/ + the SU2_DEF code. In general, the pointers are instantiated down a + hierarchy over all zones as described in the comments below. ---*/ config_container = new CConfig*[nZone]; output_container = new COutput*[nZone]; - geometry_container = new CGeometry*[nZone]; + geometry_container = new CGeometry***[nZone]; surface_movement = new CSurfaceMovement*[nZone]; - grid_movement = new CVolumetricMovement*[nZone]; - - solver_container = new CSolver*[nZone]; + grid_movement = new CVolumetricMovement**[nZone]; + + solver_container = new CSolver****[nZone]; numerics_container = new CNumerics**[nZone]; - + for (iZone = 0; iZone < nZone; iZone++) { - config_container[iZone] = nullptr; - output_container[iZone] = nullptr; - geometry_container[iZone] = nullptr; - surface_movement[iZone] = nullptr; - grid_movement[iZone] = nullptr; - solver_container[iZone] = nullptr; - numerics_container[iZone] = nullptr; + config_container[iZone] = nullptr; + output_container[iZone] = nullptr; + geometry_container[iZone] = nullptr; + surface_movement[iZone] = nullptr; + grid_movement[iZone] = nullptr; + solver_container[iZone] = nullptr; + numerics_container[iZone] = nullptr; } } void CDeformationDriver::Input_Preprocessing() { - + /*--- Initialize a char to store the zone filename ---*/ char zone_file_name[MAX_STRING_SIZE]; - + /*--- 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. ---*/ - + 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. ---*/ - + + /*--- 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. ---*/ + if (driver_config->GetnConfigFiles() > 0){ strcpy(zone_file_name, driver_config->GetConfigFilename(iZone).c_str()); config_container[iZone] = new CConfig(driver_config, zone_file_name, SU2_COMPONENT::SU2_DEF, iZone, nZone, true); } else { config_container[iZone] = new CConfig(driver_config, config_file_name, SU2_COMPONENT::SU2_DEF, iZone, nZone, true); } - + config_container[iZone]->SetMPICommunicator(SU2_MPI::GetComm()); } - + /*--- Set the multizone part of the problem. ---*/ - + if (driver_config->GetMultizone_Problem()){ for (iZone = 0; iZone < nZone; iZone++) { - + /*--- Set the interface markers for multizone ---*/ - + config_container[iZone]->SetMultizone(driver_config, config_container); } } } void CDeformationDriver::Geometrical_Preprocessing() { - + for (iZone = 0; iZone < nZone; iZone++) { - - /*--- Definition of the geometry class to store the primal grid in the partitioning process. ---*/ - - CGeometry *geometry_aux = nullptr; - - /*--- 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]); - - /*--- Build the grid data structures using the ParMETIS coloring. ---*/ - - geometry_container[iZone] = new CPhysicalGeometry(geometry_aux, config_container[iZone]); - - /*--- 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]); - - /*--- Computational grid preprocesing ---*/ - - if (rank == MASTER_NODE) cout << endl << "----------------------- Preprocessing computations ----------------------" << endl; - - /*--- Compute elements surrounding points, points surrounding points ---*/ - - if (rank == MASTER_NODE) cout << "Setting local point connectivity." <SetPoint_Connectivity(); - - /*--- Check the orientation before computing geometrical quantities ---*/ - - geometry_container[iZone]->SetBoundVolume(); - if (config_container[iZone]->GetReorientElements()) { - if (rank == MASTER_NODE) cout << "Checking the numerical grid orientation of the interior elements." <Check_IntElem_Orientation(config_container[iZone]); - geometry_container[iZone]->Check_BoundElem_Orientation(config_container[iZone]); - } - - /*--- Create the edge structure ---*/ - - if (rank == MASTER_NODE) cout << "Identify edges and vertices." <SetEdges(); - geometry_container[iZone]->SetVertex(config_container[iZone]); - - if (config_container[iZone]->GetDesign_Variable(0) != NO_DEFORMATION) { - - /*--- Create the dual control volume structures ---*/ - - if (rank == MASTER_NODE) cout << "Setting the bound control volume structure." << endl; - geometry_container[iZone]->SetControlVolume(config_container[iZone], ALLOCATE); - geometry_container[iZone]->SetBoundControlVolume(config_container[iZone], ALLOCATE); - } - - /*--- Create the point-to-point MPI communication structures. ---*/ - - geometry_container[iZone]->PreprocessP2PComms(geometry_container[iZone], config_container[iZone]); - + + /*--- Definition of the geometry class to store the primal grid in the partitioning process. ---*/ + + CGeometry *geometry_aux = nullptr; + + /*--- 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]); + + /*--- Build the grid data structures using the ParMETIS coloring. ---*/ + + geometry_container[iZone][INST_0][MESH_0] = new CPhysicalGeometry(geometry_aux, config_container[iZone]); + + /*--- Deallocate the memory of geometry_aux ---*/ + + delete geometry_aux; + + /*--- Add the Send/Receive boundaries ---*/ + + geometry_container[iZone][INST_0][MESH_0]->SetSendReceive(config_container[iZone]); + + /*--- Add the Send/Receive boundaries ---*/ + + geometry_container[iZone][INST_0][MESH_0]->SetBoundaries(config_container[iZone]); + + /*--- Computational grid preprocesing ---*/ + + if (rank == MASTER_NODE) cout << endl << "----------------------- Preprocessing computations ----------------------" << endl; + + /*--- Compute elements surrounding points, points surrounding points ---*/ + + if (rank == MASTER_NODE) cout << "Setting local point connectivity." <SetPoint_Connectivity(); + + /*--- Check the orientation before computing geometrical quantities ---*/ + + geometry_container[iZone][INST_0][MESH_0]->SetBoundVolume(); + if (config_container[iZone]->GetReorientElements()) { + if (rank == MASTER_NODE) cout << "Checking the numerical grid orientation of the interior elements." <Check_IntElem_Orientation(config_container[iZone]); + geometry_container[iZone][INST_0][MESH_0]->Check_BoundElem_Orientation(config_container[iZone]); + } + + /*--- Create the edge structure ---*/ + + if (rank == MASTER_NODE) cout << "Identify edges and vertices." <SetEdges(); + geometry_container[iZone][INST_0][MESH_0]->SetVertex(config_container[iZone]); + + if (config_container[iZone]->GetDesign_Variable(0) != NO_DEFORMATION) { + + /*--- Create the dual control volume structures ---*/ + + if (rank == MASTER_NODE) cout << "Setting the bound control volume structure." << endl; + geometry_container[iZone][INST_0][MESH_0]->SetControlVolume(config_container[iZone], ALLOCATE); + geometry_container[iZone][INST_0][MESH_0]->SetBoundControlVolume(config_container[iZone], ALLOCATE); + } + + /*--- Create the point-to-point MPI communication structures. ---*/ + + geometry_container[iZone][INST_0][MESH_0]->PreprocessP2PComms(geometry_container[iZone][INST_0][MESH_0], config_container[iZone]); + } } void CDeformationDriver::Output_Preprocessing() { - - for (iZone = 0; iZone < nZone; iZone++) { - + + for (iZone = 0; iZone < nZone; iZone++) { + /*--- Allocate the mesh output ---*/ - - output_container[iZone] = new CMeshOutput(config_container[iZone], geometry_container[iZone]->GetnDim()); - + + output_container[iZone] = new CMeshOutput(config_container[iZone], geometry_container[iZone][INST_0][MESH_0]->GetnDim()); + /*--- Preprocess the volume output ---*/ - + output_container[iZone]->PreprocessVolumeOutput(config_container[iZone]); - + /*--- Preprocess history --- */ - + output_container[iZone]->PreprocessHistoryOutput(config_container[iZone], false); - + } } void CDeformationDriver::Solver_Preprocessing() { - - for (iZone = 0; iZone < nZone; iZone++) { - solver_container[iZone] = new CMeshSolver(geometry_container[iZone], config_container[iZone]); - } - + + for (iZone = 0; iZone < nZone; iZone++) { + solver_container[iZone][INST_0][MESH_0][MESH_SOL] = new CMeshSolver(geometry_container[iZone][INST_0][MESH_0], config_container[iZone]); + } + } void CDeformationDriver::Numerics_Preprocessing() { - - for (iZone = 0; iZone < nZone; iZone++) { - numerics_container[iZone] = new CNumerics* [omp_get_num_threads() * MAX_TERMS](); - - for (int thread = 0; thread < omp_get_max_threads(); ++thread) { - const int iTerm = FEA_TERM + thread * MAX_TERMS; - const int nDim = geometry_container[iZone]->GetnDim(); - - numerics_container[iZone][iTerm] = new CFEAMeshElasticity(nDim, nDim, geometry_container[iZone]->GetnElem(), config_container[iZone]); + + for (iZone = 0; iZone < nZone; iZone++) { + numerics_container[iZone] = new CNumerics* [omp_get_num_threads() * MAX_TERMS](); + + for (int thread = 0; thread < omp_get_max_threads(); ++thread) { + const int iTerm = FEA_TERM + thread * MAX_TERMS; + const int nDim = geometry_container[iZone][INST_0][MESH_0]->GetnDim(); + + numerics_container[iZone][iTerm] = new CFEAMeshElasticity(nDim, nDim, geometry_container[iZone][INST_0][MESH_0]->GetnElem(), config_container[iZone]); + } + } - - } - + } void CDeformationDriver::Run() { - + /* --- Start measuring computation time ---*/ - + StartTime = SU2_MPI::Wtime(); - + /*--- Surface grid deformation using design variables ---*/ - + if (driver_config->GetDeform_Mesh()) { Update(); } else { Update_Legacy(); } - + /*--- Synchronization point after a single solver iteration. Compute the - wall clock time required. ---*/ - + wall clock time required. ---*/ + StopTime = SU2_MPI::Wtime(); - + UsedTimeCompute = StopTime-StartTime; if (rank == MASTER_NODE) { - cout << "\nCompleted in " << fixed << UsedTimeCompute << " seconds on "<< size; - - if (size == 1) cout << " core." << endl; else cout << " cores." << endl; + cout << "\nCompleted in " << fixed << UsedTimeCompute << " seconds on "<< size; + + if (size == 1) cout << " core." << endl; else cout << " cores." << endl; } - + /*--- Output the deformed mesh ---*/ Output(); - + } void CDeformationDriver::Update() { - + for (iZone = 0; iZone < nZone; iZone++){ - - /*--- Set the stiffness of each element mesh into the mesh numerics ---*/ - - solver_container[iZone]->SetMesh_Stiffness(numerics_container[iZone], config_container[iZone]); - - /*--- Deform the volume grid around the new boundary locations ---*/ - - solver_container[iZone]->DeformMesh(geometry_container[iZone], numerics_container[iZone], config_container[iZone]); - + + /*--- Set the stiffness of each element mesh into the mesh numerics ---*/ + + solver_container[iZone][INST_0][MESH_0][MESH_SOL]->SetMesh_Stiffness(numerics_container[iZone], config_container[iZone]); + + /*--- Deform the volume grid around the new boundary locations ---*/ + + solver_container[iZone][INST_0][MESH_0][MESH_SOL]->DeformMesh(geometry_container[iZone][INST_0][MESH_0], numerics_container[iZone], config_container[iZone]); + } } void CDeformationDriver::Update_Legacy() { - + for (iZone = 0; iZone < nZone; iZone++){ - - if (config_container[iZone]->GetDesign_Variable(0) != NO_DEFORMATION) { - - /*--- Definition of the Class for grid movement ---*/ - grid_movement[iZone] = new CVolumetricMovement(geometry_container[iZone], config_container[iZone]); - - /*--- Save original coordinates to be reused in convexity checking procedure ---*/ - auto OriginalCoordinates = geometry_container[iZone]->nodes->GetCoord(); - - /*--- First check for volumetric grid deformation/transformations ---*/ - - if (config_container[iZone]->GetDesign_Variable(0) == SCALE_GRID) { - - if (rank == MASTER_NODE) - cout << endl << "--------------------- Volumetric grid scaling (ZONE " << iZone <<") ------------------" << endl; - grid_movement[iZone]->SetVolume_Scaling(geometry_container[iZone], config_container[iZone], false); - - } else if (config_container[iZone]->GetDesign_Variable(0) == TRANSLATE_GRID) { - - if (rank == MASTER_NODE) - cout << endl << "------------------- Volumetric grid translation (ZONE " << iZone <<") ----------------" << endl; - grid_movement[iZone]->SetVolume_Translation(geometry_container[iZone], config_container[iZone], false); - - } else if (config_container[iZone]->GetDesign_Variable(0) == ROTATE_GRID) { - - if (rank == MASTER_NODE) - cout << endl << "--------------------- Volumetric grid rotation (ZONE " << iZone <<") -----------------" << endl; - grid_movement[iZone]->SetVolume_Rotation(geometry_container[iZone], config_container[iZone], false); - - } else { - - /*--- If no volume-type deformations are requested, then this is a - surface-based deformation or FFD set up. ---*/ - - if (rank == MASTER_NODE) - cout << endl << "--------------------- Surface grid deformation (ZONE " << iZone <<") -----------------" << endl; - - /*--- Definition and initialization of the surface deformation class ---*/ - - surface_movement[iZone] = new CSurfaceMovement(); - - /*--- Copy coordinates to the surface structure ---*/ - - surface_movement[iZone]->CopyBoundary(geometry_container[iZone], config_container[iZone]); - - /*--- Surface grid deformation ---*/ - - if (rank == MASTER_NODE) cout << "Performing the deformation of the surface grid." << endl; - auto TotalDeformation = surface_movement[iZone]->SetSurface_Deformation(geometry_container[iZone], config_container[iZone]); - - if (config_container[iZone]->GetDesign_Variable(0) != FFD_SETTING) { - - if (rank == MASTER_NODE) - cout << endl << "------------------- Volumetric grid deformation (ZONE " << iZone <<") ----------------" << endl; - - if (rank == MASTER_NODE) - cout << "Performing the deformation of the volumetric grid." << endl; - grid_movement[iZone]->SetVolume_Deformation(geometry_container[iZone], config_container[iZone], false); - - /*--- Get parameters for convexity check ---*/ - bool ConvexityCheck; - unsigned short ConvexityCheck_MaxIter, ConvexityCheck_MaxDepth; - - tie(ConvexityCheck, ConvexityCheck_MaxIter, ConvexityCheck_MaxDepth) = config_container[iZone]->GetConvexityCheck(); - - /*--- Recursively change deformations if there are nonconvex elements. ---*/ - - if (ConvexityCheck && geometry_container[iZone]->GetnNonconvexElements() > 0) { - if (rank == MASTER_NODE) { - cout << "Nonconvex elements present after deformation. " << endl; - cout << "Recursively lowering deformation magnitude." << endl; - } - - /*--- Load initial deformation values ---*/ - auto InitialDeformation = TotalDeformation; - - unsigned short ConvexityCheckIter, RecursionDepth = 0; - su2double DeformationFactor = 1.0, DeformationDifference = 1.0; - for (ConvexityCheckIter = 1; ConvexityCheckIter <= ConvexityCheck_MaxIter; ConvexityCheckIter++) { - - /*--- Recursively change deformation magnitude: - decrease if there are nonconvex elements, increase otherwise ---*/ - DeformationDifference /= 2.0; - - if (geometry_container[iZone]->GetnNonconvexElements() > 0) { - DeformationFactor -= DeformationDifference; - } else { - RecursionDepth += 1; - - if (RecursionDepth == ConvexityCheck_MaxDepth) { - if (rank == MASTER_NODE) { - cout << "Maximum recursion depth reached." << endl; - cout << "Remaining amount of original deformation: "; - cout << DeformationFactor*100.0 << " percent. " << endl; - } - break; - } - - DeformationFactor += DeformationDifference; - } - - /*--- Load mesh to start every iteration with an undeformed grid ---*/ - for (auto iPoint = 0ul; iPoint < OriginalCoordinates.rows(); iPoint++) { - for (auto iDim = 0ul; iDim < OriginalCoordinates.cols(); iDim++) { - geometry_container[iZone]->nodes->SetCoord(iPoint, iDim, OriginalCoordinates(iPoint,iDim)); - } - } - - /*--- Set deformation magnitude as percentage of initial deformation ---*/ - for (auto iDV = 0u; iDV < driver_config->GetnDV(); iDV++) { - for (auto iDV_Value = 0u; iDV_Value < driver_config->GetnDV_Value(iDV); iDV_Value++) { - config_container[iZone]->SetDV_Value(iDV, iDV_Value, InitialDeformation[iDV][iDV_Value]*DeformationFactor); - } - } - - /*--- Surface grid deformation ---*/ - if (rank == MASTER_NODE) cout << "Performing the deformation of the surface grid." << endl; - - TotalDeformation = surface_movement[iZone]->SetSurface_Deformation(geometry_container[iZone], config_container[iZone]); - + + if (config_container[iZone]->GetDesign_Variable(0) != NO_DEFORMATION) { + + /*--- Definition of the Class for grid movement ---*/ + grid_movement[iZone][INST_0] = new CVolumetricMovement(geometry_container[iZone][INST_0][MESH_0], config_container[iZone]); + + /*--- Save original coordinates to be reused in convexity checking procedure ---*/ + auto OriginalCoordinates = geometry_container[iZone][INST_0][MESH_0]->nodes->GetCoord(); + + /*--- First check for volumetric grid deformation/transformations ---*/ + + if (config_container[iZone]->GetDesign_Variable(0) == SCALE_GRID) { + if (rank == MASTER_NODE) - cout << endl << "------------------- Volumetric grid deformation (ZONE " << iZone <<") ----------------" << endl; - + cout << endl << "--------------------- Volumetric grid scaling (ZONE " << iZone <<") ------------------" << endl; + grid_movement[iZone][INST_0]->SetVolume_Scaling(geometry_container[iZone][INST_0][MESH_0], config_container[iZone], false); + + } else if (config_container[iZone]->GetDesign_Variable(0) == TRANSLATE_GRID) { + if (rank == MASTER_NODE) - cout << "Performing the deformation of the volumetric grid." << endl; - grid_movement[iZone]->SetVolume_Deformation(geometry_container[iZone], config_container[iZone], false); - - if (rank == MASTER_NODE) { - cout << "Number of nonconvex elements for iteration " << ConvexityCheckIter << ": "; - cout << geometry_container[iZone]->GetnNonconvexElements() << endl; - cout << "Remaining amount of original deformation: "; - cout << DeformationFactor*100.0 << " percent. " << endl; + cout << endl << "------------------- Volumetric grid translation (ZONE " << iZone <<") ----------------" << endl; + grid_movement[iZone][INST_0]->SetVolume_Translation(geometry_container[iZone][INST_0][MESH_0], config_container[iZone], false); + + } else if (config_container[iZone]->GetDesign_Variable(0) == ROTATE_GRID) { + + if (rank == MASTER_NODE) + cout << endl << "--------------------- Volumetric grid rotation (ZONE " << iZone <<") -----------------" << endl; + grid_movement[iZone][INST_0]->SetVolume_Rotation(geometry_container[iZone][INST_0][MESH_0], config_container[iZone], false); + + } else { + + /*--- If no volume-type deformations are requested, then this is a + surface-based deformation or FFD set up. ---*/ + + if (rank == MASTER_NODE) + cout << endl << "--------------------- Surface grid deformation (ZONE " << iZone <<") -----------------" << endl; + + /*--- Definition and initialization of the surface deformation class ---*/ + + surface_movement[iZone] = new CSurfaceMovement(); + + /*--- Copy coordinates to the surface structure ---*/ + + surface_movement[iZone]->CopyBoundary(geometry_container[iZone][INST_0][MESH_0], config_container[iZone]); + + /*--- Surface grid deformation ---*/ + + if (rank == MASTER_NODE) cout << "Performing the deformation of the surface grid." << endl; + auto TotalDeformation = surface_movement[iZone]->SetSurface_Deformation(geometry_container[iZone][INST_0][MESH_0], config_container[iZone]); + + if (config_container[iZone]->GetDesign_Variable(0) != FFD_SETTING) { + + if (rank == MASTER_NODE) + cout << endl << "------------------- Volumetric grid deformation (ZONE " << iZone <<") ----------------" << endl; + + if (rank == MASTER_NODE) + cout << "Performing the deformation of the volumetric grid." << endl; + grid_movement[iZone][INST_0]->SetVolume_Deformation(geometry_container[iZone][INST_0][MESH_0], config_container[iZone], false); + + /*--- Get parameters for convexity check ---*/ + bool ConvexityCheck; + unsigned short ConvexityCheck_MaxIter, ConvexityCheck_MaxDepth; + + tie(ConvexityCheck, ConvexityCheck_MaxIter, ConvexityCheck_MaxDepth) = config_container[iZone]->GetConvexityCheck(); + + /*--- Recursively change deformations if there are nonconvex elements. ---*/ + + if (ConvexityCheck && geometry_container[iZone][INST_0][MESH_0]->GetnNonconvexElements() > 0) { + if (rank == MASTER_NODE) { + cout << "Nonconvex elements present after deformation. " << endl; + cout << "Recursively lowering deformation magnitude." << endl; + } + + /*--- Load initial deformation values ---*/ + auto InitialDeformation = TotalDeformation; + + unsigned short ConvexityCheckIter, RecursionDepth = 0; + su2double DeformationFactor = 1.0, DeformationDifference = 1.0; + for (ConvexityCheckIter = 1; ConvexityCheckIter <= ConvexityCheck_MaxIter; ConvexityCheckIter++) { + + /*--- Recursively change deformation magnitude: + decrease if there are nonconvex elements, increase otherwise ---*/ + DeformationDifference /= 2.0; + + if (geometry_container[iZone][INST_0][MESH_0]->GetnNonconvexElements() > 0) { + DeformationFactor -= DeformationDifference; + } else { + RecursionDepth += 1; + + if (RecursionDepth == ConvexityCheck_MaxDepth) { + if (rank == MASTER_NODE) { + cout << "Maximum recursion depth reached." << endl; + cout << "Remaining amount of original deformation: "; + cout << DeformationFactor*100.0 << " percent. " << endl; + } + break; + } + + DeformationFactor += DeformationDifference; + } + + /*--- Load mesh to start every iteration with an undeformed grid ---*/ + for (auto iPoint = 0ul; iPoint < OriginalCoordinates.rows(); iPoint++) { + for (auto iDim = 0ul; iDim < OriginalCoordinates.cols(); iDim++) { + geometry_container[iZone][INST_0][MESH_0]->nodes->SetCoord(iPoint, iDim, OriginalCoordinates(iPoint,iDim)); + } + } + + /*--- Set deformation magnitude as percentage of initial deformation ---*/ + for (auto iDV = 0u; iDV < driver_config->GetnDV(); iDV++) { + for (auto iDV_Value = 0u; iDV_Value < driver_config->GetnDV_Value(iDV); iDV_Value++) { + config_container[iZone]->SetDV_Value(iDV, iDV_Value, InitialDeformation[iDV][iDV_Value]*DeformationFactor); + } + } + + /*--- Surface grid deformation ---*/ + if (rank == MASTER_NODE) cout << "Performing the deformation of the surface grid." << endl; + + TotalDeformation = surface_movement[iZone]->SetSurface_Deformation(geometry_container[iZone][INST_0][MESH_0], config_container[iZone]); + + if (rank == MASTER_NODE) + cout << endl << "------------------- Volumetric grid deformation (ZONE " << iZone <<") ----------------" << endl; + + if (rank == MASTER_NODE) + cout << "Performing the deformation of the volumetric grid." << endl; + grid_movement[iZone][INST_0]->SetVolume_Deformation(geometry_container[iZone][INST_0][MESH_0], config_container[iZone], false); + + if (rank == MASTER_NODE) { + cout << "Number of nonconvex elements for iteration " << ConvexityCheckIter << ": "; + cout << geometry_container[iZone][INST_0][MESH_0]->GetnNonconvexElements() << endl; + cout << "Remaining amount of original deformation: "; + cout << DeformationFactor*100.0 << " percent. " << endl; + } + + } + + } + } - - } - + } - - } - + } - - } - + } - + } void CDeformationDriver::Output() { - + /*--- Output deformed grid for visualization, if requested (surface and volumetric), in parallel - requires to move all the data to the master node---*/ - + requires to move all the data to the master node---*/ + if (rank == MASTER_NODE) cout << endl << "----------------------- Write deformed grid files -----------------------" << endl; - + for (iZone = 0; iZone < nZone; iZone++){ - - /*--- Compute Mesh Quality if requested. Necessary geometry preprocessing re-done beforehand. ---*/ - - if (config_container[iZone]->GetWrt_MeshQuality() && !driver_config->GetStructuralProblem()) { - - if (rank == MASTER_NODE) cout << "Recompute geometry properties necessary to evaluate mesh quality statistics.\n"; - - geometry_container[iZone]->SetPoint_Connectivity(); - geometry_container[iZone]->SetBoundVolume(); - geometry_container[iZone]->SetEdges(); - geometry_container[iZone]->SetVertex(config_container[iZone]); - geometry_container[iZone]->SetControlVolume(config_container[iZone], ALLOCATE); - geometry_container[iZone]->SetBoundControlVolume(config_container[iZone], ALLOCATE); - - if (rank == MASTER_NODE) cout << "Computing mesh quality statistics for the dual control volumes.\n"; - geometry_container[iZone]->ComputeMeshQualityStatistics(config_container[iZone]); - }// Mesh Quality Output - - /*--- Load the data --- */ - - output_container[iZone]->Load_Data(geometry_container[iZone], config_container[iZone], nullptr); - - output_container[iZone]->WriteToFile(config_container[iZone], geometry_container[iZone], OUTPUT_TYPE::MESH, driver_config->GetMesh_Out_FileName()); - - /*--- Set the file names for the visualization files ---*/ - - output_container[iZone]->SetVolume_Filename("volume_deformed"); - output_container[iZone]->SetSurface_Filename("surface_deformed"); - - for (unsigned short iFile = 0; iFile < config_container[iZone]->GetnVolumeOutputFiles(); iFile++){ - auto FileFormat = config_container[iZone]->GetVolumeOutputFiles(); - if (FileFormat[iFile] != OUTPUT_TYPE::RESTART_ASCII && - FileFormat[iFile] != OUTPUT_TYPE::RESTART_BINARY && - FileFormat[iFile] != OUTPUT_TYPE::CSV) - output_container[iZone]->WriteToFile(config_container[iZone], geometry_container[iZone], FileFormat[iFile]); - } + + /*--- Compute Mesh Quality if requested. Necessary geometry preprocessing re-done beforehand. ---*/ + + if (config_container[iZone]->GetWrt_MeshQuality() && !driver_config->GetStructuralProblem()) { + + if (rank == MASTER_NODE) cout << "Recompute geometry properties necessary to evaluate mesh quality statistics.\n"; + + geometry_container[iZone][INST_0][MESH_0]->SetPoint_Connectivity(); + geometry_container[iZone][INST_0][MESH_0]->SetBoundVolume(); + geometry_container[iZone][INST_0][MESH_0]->SetEdges(); + geometry_container[iZone][INST_0][MESH_0]->SetVertex(config_container[iZone]); + geometry_container[iZone][INST_0][MESH_0]->SetControlVolume(config_container[iZone], ALLOCATE); + geometry_container[iZone][INST_0][MESH_0]->SetBoundControlVolume(config_container[iZone], ALLOCATE); + + if (rank == MASTER_NODE) cout << "Computing mesh quality statistics for the dual control volumes.\n"; + geometry_container[iZone][INST_0][MESH_0]->ComputeMeshQualityStatistics(config_container[iZone]); + }// Mesh Quality Output + + /*--- Load the data --- */ + + output_container[iZone]->Load_Data(geometry_container[iZone][INST_0][MESH_0], config_container[iZone], nullptr); + + output_container[iZone]->WriteToFile(config_container[iZone], geometry_container[iZone][INST_0][MESH_0], OUTPUT_TYPE::MESH, driver_config->GetMesh_Out_FileName()); + + /*--- Set the file names for the visualization files ---*/ + + output_container[iZone]->SetVolume_Filename("volume_deformed"); + output_container[iZone]->SetSurface_Filename("surface_deformed"); + + for (unsigned short iFile = 0; iFile < config_container[iZone]->GetnVolumeOutputFiles(); iFile++){ + auto FileFormat = config_container[iZone]->GetVolumeOutputFiles(); + if (FileFormat[iFile] != OUTPUT_TYPE::RESTART_ASCII && + FileFormat[iFile] != OUTPUT_TYPE::RESTART_BINARY && + FileFormat[iFile] != OUTPUT_TYPE::CSV) + output_container[iZone]->WriteToFile(config_container[iZone], geometry_container[iZone][INST_0][MESH_0], FileFormat[iFile]); + } } - + if (!driver_config->GetDeform_Mesh()) { - if ((config_container[ZONE_0]->GetDesign_Variable(0) != NO_DEFORMATION) && - (config_container[ZONE_0]->GetDesign_Variable(0) != SCALE_GRID) && - (config_container[ZONE_0]->GetDesign_Variable(0) != TRANSLATE_GRID) && - (config_container[ZONE_0]->GetDesign_Variable(0) != ROTATE_GRID)) { - - /*--- Write the the free-form deformation boxes after deformation. ---*/ - - if (rank == MASTER_NODE) cout << "Adding any FFD information to the SU2 file." << endl; - - surface_movement[ZONE_0]->WriteFFDInfo(surface_movement, geometry_container, config_container); - + if ((config_container[ZONE_0]->GetDesign_Variable(0) != NO_DEFORMATION) && + (config_container[ZONE_0]->GetDesign_Variable(0) != SCALE_GRID) && + (config_container[ZONE_0]->GetDesign_Variable(0) != TRANSLATE_GRID) && + (config_container[ZONE_0]->GetDesign_Variable(0) != ROTATE_GRID)) { + + /*--- Write the the free-form deformation boxes after deformation. ---*/ + + if (rank == MASTER_NODE) cout << "Adding any FFD information to the SU2 file." << endl; + + surface_movement[ZONE_0]->WriteFFDInfo(surface_movement, geometry_container[INST_0][MESH_0], config_container); + + } } - } } void CDeformationDriver::Postprocessing() { - + if (rank == MASTER_NODE) - cout << endl <<"------------------------- Solver Postprocessing -------------------------" << endl; - + cout << endl <<"------------------------- Solver Postprocessing -------------------------" << endl; + delete driver_config; driver_config = nullptr; - + for (iZone = 0; iZone < nZone; iZone++) { - if (numerics_container[iZone] != nullptr) { - for (unsigned int iTerm = 0; iTerm < MAX_TERMS*omp_get_max_threads(); iTerm++) { - delete numerics_container[iZone][iTerm]; + if (numerics_container[iZone] != nullptr) { + for (unsigned int iTerm = 0; iTerm < MAX_TERMS*omp_get_max_threads(); iTerm++) { + delete numerics_container[iZone][iTerm]; + } + delete [] numerics_container[iZone]; } - delete [] numerics_container[iZone]; - } } delete [] numerics_container; if (rank == MASTER_NODE) cout << "Deleted CNumerics container." << endl; - + for (iZone = 0; iZone < nZone; iZone++) { - delete solver_container[iZone]; + delete solver_container[iZone][INST_0][MESH_0][MESH_SOL]; } delete [] solver_container; if (rank == MASTER_NODE) cout << "Deleted CSolver container." << endl; - + if (geometry_container != nullptr) { - for (iZone = 0; iZone < nZone; iZone++) { - delete geometry_container[iZone]; - } - delete [] geometry_container; + for (iZone = 0; iZone < nZone; iZone++) { + delete geometry_container[iZone][INST_0][MESH_0]; + } + delete [] geometry_container; } if (rank == MASTER_NODE) cout << "Deleted CGeometry container." << endl; - + if (surface_movement != nullptr) { - for (iZone = 0; iZone < nZone; iZone++) { - delete surface_movement[iZone]; - } - delete [] surface_movement; + for (iZone = 0; iZone < nZone; iZone++) { + delete surface_movement[iZone]; + } + delete [] surface_movement; } if (rank == MASTER_NODE) cout << "Deleted CSurfaceMovement class." << endl; - + if (grid_movement != nullptr) { - for (iZone = 0; iZone < nZone; iZone++) { - delete grid_movement[iZone]; - } - delete [] grid_movement; + for (iZone = 0; iZone < nZone; iZone++) { + delete grid_movement[iZone][INST_0]; + } + delete [] grid_movement; } if (rank == MASTER_NODE) cout << "Deleted CVolumetricMovement class." << endl; - + if (config_container != nullptr) { - for (iZone = 0; iZone < nZone; iZone++) { - delete config_container[iZone]; - } - delete [] config_container; + for (iZone = 0; iZone < nZone; iZone++) { + delete config_container[iZone]; + } + delete [] config_container; } if (rank == MASTER_NODE) cout << "Deleted CConfig container." << endl; - + if (output_container != nullptr) { - for (iZone = 0; iZone < nZone; iZone++) { - delete output_container[iZone]; - } - delete [] output_container; + for (iZone = 0; iZone < nZone; iZone++) { + delete output_container[iZone]; + } + delete [] output_container; } if (rank == MASTER_NODE) cout << "Deleted COutput class." << endl; - + /*--- Exit the solver cleanly ---*/ - + if (rank == MASTER_NODE) - cout << endl << "------------------------- Exit Success (SU2_DEF) ------------------------" << endl << endl; -} - -vector CDeformationDriver::GetAllDeformMeshMarkersTag() const { - - vector interfaceBoundariesTagList; - unsigned short iMarker, nBoundariesMarker; - string Marker_Tag; - - nBoundariesMarker = config_container[ZONE_0]->GetnMarker_Deform_Mesh(); - interfaceBoundariesTagList.resize(nBoundariesMarker); - - for(iMarker=0; iMarker < nBoundariesMarker; iMarker++){ - Marker_Tag = config_container[ZONE_0]->GetMarker_Deform_Mesh_TagBound(iMarker); - interfaceBoundariesTagList[iMarker] = Marker_Tag; - } - - return interfaceBoundariesTagList; -} - -map CDeformationDriver::GetAllBoundaryMarkers() const { - - map allBoundariesMap; - unsigned short iMarker, nBoundaryMarkers; - string Marker_Tag; - - nBoundaryMarkers = config_container[ZONE_0]->GetnMarker_All(); - - for(iMarker=0; iMarker < nBoundaryMarkers; iMarker++){ - Marker_Tag = config_container[ZONE_0]->GetMarker_All_TagBound(iMarker); - allBoundariesMap[Marker_Tag] = iMarker; - } - - return allBoundariesMap; -} - -map CDeformationDriver::GetAllBoundaryMarkersType() const { - - map allBoundariesTypeMap; - unsigned short iMarker, KindBC; - string Marker_Tag, Marker_Type; - - for(iMarker=0; iMarker < config_container[ZONE_0]->GetnMarker_All(); iMarker++){ - Marker_Tag = config_container[ZONE_0]->GetMarker_All_TagBound(iMarker); - KindBC = config_container[ZONE_0]->GetMarker_All_KindBC(iMarker); - switch(KindBC){ - case EULER_WALL: - Marker_Type = "EULER_WALL"; - break; - case FAR_FIELD: - Marker_Type = "FARFIELD"; - break; - case ISOTHERMAL: - Marker_Type = "ISOTHERMAL"; - break; - case HEAT_FLUX: - Marker_Type = "HEATFLUX"; - break; - case INLET_FLOW: - Marker_Type = "INLET_FLOW"; - break; - case OUTLET_FLOW: - Marker_Type = "OUTLET_FLOW"; - break; - case SYMMETRY_PLANE: - Marker_Type = "SYMMETRY"; - break; - case SEND_RECEIVE: - Marker_Type = "SEND_RECEIVE"; - break; - default: - Marker_Type = "UNKNOWN_TYPE"; - } - allBoundariesTypeMap[Marker_Tag] = Marker_Type; - } - - return allBoundariesTypeMap; -} - -unsigned long CDeformationDriver::GetNumberVertices(unsigned short iMarker) const { - - return geometry_container[ZONE_0]->nVertex[iMarker]; - -} - -unsigned long CDeformationDriver::GetNumberHaloVertices(unsigned short iMarker) const { - - unsigned long nHaloVertices, iVertex, iPoint; - - nHaloVertices = 0; - for(iVertex = 0; iVertex < geometry_container[ZONE_0]->nVertex[iMarker]; iVertex++){ - iPoint = geometry_container[ZONE_0]->vertex[iMarker][iVertex]->GetNode(); - if(!(geometry_container[ZONE_0]->nodes->GetDomain(iPoint))) nHaloVertices += 1; - } - - return nHaloVertices; - -} - -unsigned long CDeformationDriver::GetVertexGlobalIndex(unsigned short iMarker, unsigned long iVertex) const { - - unsigned long iPoint, GlobalIndex; - - iPoint = geometry_container[ZONE_0]->vertex[iMarker][iVertex]->GetNode(); - GlobalIndex = geometry_container[ZONE_0]->nodes->GetGlobalIndex(iPoint); - - return GlobalIndex; - -} - -bool CDeformationDriver::IsAHaloNode(unsigned short iMarker, unsigned long iVertex) const { - - unsigned long iPoint; - - iPoint = geometry_container[ZONE_0]->vertex[iMarker][iVertex]->GetNode(); - if(geometry_container[ZONE_0]->nodes->GetDomain(iPoint)) return false; - else return true; - -} - -vector CDeformationDriver::GetInitialMeshCoord(unsigned short iMarker, unsigned long iVertex) const { - - vector coord(3,0.0); - vector coord_passive(3, 0.0); - - auto iPoint = geometry_container[ZONE_0]->vertex[iMarker][iVertex]->GetNode(); - - for (auto iDim = 0 ; iDim < geometry_container[ZONE_0]->GetnDim(); iDim++){ - coord[iDim] = solver_container[ZONE_0]->GetNodes()->GetMesh_Coord(iPoint,iDim); - } - - coord_passive[0] = SU2_TYPE::GetValue(coord[0]); - coord_passive[1] = SU2_TYPE::GetValue(coord[1]); - coord_passive[2] = SU2_TYPE::GetValue(coord[2]); - - return coord_passive; + cout << endl << "------------------------- Exit Success (SU2_DEF) ------------------------" << endl << endl; } -vector CDeformationDriver::GetVertexNormal(unsigned short iMarker, unsigned long iVertex, bool unitNormal) const { - - int nDim = geometry_container[ZONE_0]->GetnDim(); - - su2double *Normal; - su2double Area; - vector ret_Normal(3, 0.0); - vector ret_Normal_passive(3, 0.0); - - Normal = geometry_container[ZONE_0]->vertex[iMarker][iVertex]->GetNormal(); - - if (!unitNormal) { - - ret_Normal_passive[0] = SU2_TYPE::GetValue(Normal[0]); - ret_Normal_passive[1] = SU2_TYPE::GetValue(Normal[1]); - if(nDim>2) ret_Normal_passive[2] = SU2_TYPE::GetValue(Normal[2]); - - return ret_Normal_passive; - } - - Area = GeometryToolbox::Norm(nDim, Normal); - - ret_Normal[0] = Normal[0]/Area; - ret_Normal[1] = Normal[1]/Area; - if(nDim>2) ret_Normal[2] = Normal[2]/Area; - - ret_Normal_passive[0] = SU2_TYPE::GetValue(ret_Normal[0]); - ret_Normal_passive[1] = SU2_TYPE::GetValue(ret_Normal[1]); - ret_Normal_passive[2] = SU2_TYPE::GetValue(ret_Normal[2]); - - return ret_Normal_passive; -} - -void CDeformationDriver::SetMeshDisplacement(unsigned short iMarker, unsigned long iVertex, passivedouble DispX, passivedouble DispY, passivedouble DispZ) { - - unsigned long iPoint; - su2double MeshDispl[3] = {0.0,0.0,0.0}; - - MeshDispl[0] = DispX; - MeshDispl[1] = DispY; - MeshDispl[2] = DispZ; - - iPoint = geometry_container[ZONE_0]->vertex[iMarker][iVertex]->GetNode(); - - solver_container[ZONE_0]->GetNodes()->SetBound_Disp(iPoint, MeshDispl); - -} - -void CDeformationDriver::CommunicateMeshDisplacement(void) { - - solver_container[ZONE_0]->InitiateComms(geometry_container[ZONE_0], config_container[ZONE_0], MESH_DISPLACEMENTS); - solver_container[ZONE_0]->CompleteComms(geometry_container[ZONE_0], config_container[ZONE_0], MESH_DISPLACEMENTS); - +void CDeformationDriver::CommunicateMeshDisplacements(void) { + + solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->InitiateComms(geometry_container[ZONE_0][INST_0][MESH_0], config_container[ZONE_0], MESH_DISPLACEMENTS); + solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->CompleteComms(geometry_container[ZONE_0][INST_0][MESH_0], config_container[ZONE_0], MESH_DISPLACEMENTS); + } diff --git a/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp b/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp index 195dbf59aa6..63555b249c2 100644 --- a/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp +++ b/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp @@ -1,8 +1,8 @@ /*! * \file CDiscAdjDeformationDriver.cpp * \brief Main subroutines for driving the projection of sensitivities. - * \author T. Economon, H. Kline, R. Sanchez - * \version 7.1.1 "Blackbird" + * \author T. Economon, H. Kline, R. Sanchez, A. Gastaldi, H. Patel + * \version 7.3.0 "Blackbird" * * SU2 Project Website: https://su2code.github.io * @@ -31,76 +31,77 @@ using namespace std; -CDiscAdjDeformationDriver::CDiscAdjDeformationDriver(char* confFile, SU2_Comm MPICommunicator) { - +CDiscAdjDeformationDriver::CDiscAdjDeformationDriver(char* confFile, SU2_Comm MPICommunicator): + CDriverBase(confFile, 1, MPICommunicator) +{ /*--- Initialize Medipack (must also be here so it is initialized from python) ---*/ - #ifdef HAVE_MPI - #if defined(CODI_REVERSE_TYPE) || defined(CODI_FORWARD_TYPE) - SU2_MPI::Init_AMPI(); - #endif - #endif - +#ifdef HAVE_MPI +#if defined(CODI_REVERSE_TYPE) || defined(CODI_FORWARD_TYPE) + SU2_MPI::Init_AMPI(); +#endif +#endif + SU2_MPI::SetComm(MPICommunicator); - + rank = SU2_MPI::GetRank(); size = SU2_MPI::GetSize(); - + /*--- Copy the config filename ---*/ strcpy(config_file_name, confFile); - + /*--- 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) ---*/ - + file the number of zones and dimensions from the numerical grid (required + for variables allocation) ---*/ + driver_config = new CConfig(config_file_name, SU2_COMPONENT::SU2_DOT); - + nZone = driver_config->GetnZone(); - + /*--- Initialize containers --- */ - + SetContainers_Null(); - + /*--- Preprocessing of the config files. ---*/ - + Input_Preprocessing(); - + /*--- Set up a timer for performance benchmarking ---*/ - + StartTime = SU2_MPI::Wtime(); - + /*--- Preprocessing of the geometry for all zones. ---*/ - + Geometrical_Preprocessing(); - + /*--- Preprocessing of the outputs for all zones. ---*/ - + Output_Preprocessing(); - + /*--- Preprocessing time is reported now, but not included in the next compute portion. ---*/ - + StopTime = SU2_MPI::Wtime(); - + /*--- Compute/print the total time for performance benchmarking. ---*/ - + UsedTime = StopTime-StartTime; UsedTimePreproc = UsedTime; UsedTimeCompute = 0.0; - + } CDiscAdjDeformationDriver::~CDiscAdjDeformationDriver(void) { - + } void CDiscAdjDeformationDriver::SetContainers_Null() { - + /*--- Definition of the containers per zones ---*/ - + config_container = new CConfig*[nZone] (); geometry_container = new CGeometry**[nZone] (); surface_movement = new CSurfaceMovement*[nZone] (); grid_movement = new CVolumetricMovement*[nZone] (); - + nInst = new unsigned short[nZone]; for (iZone = 0; iZone < nZone; iZone++) { nInst[iZone] = 1; @@ -108,32 +109,34 @@ void CDiscAdjDeformationDriver::SetContainers_Null() { } void CDiscAdjDeformationDriver::Input_Preprocessing() { - - // TODO Check that config is for Discrete Adjoint ! + + if (!config_container[iZone]->GetDiscrete_Adjoint()) { + SU2_MPI::Error("The discrete adjoint solver was not specified in the configuration file.", CURRENT_FUNCTION); + } /*--- Initialize a char to store the zone filename ---*/ char zone_file_name[MAX_STRING_SIZE]; - + /*--- 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. ---*/ - + 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. ---*/ - + + /*--- 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. ---*/ + if (driver_config->GetnConfigFiles() > 0){ strcpy(zone_file_name, driver_config->GetConfigFilename(iZone).c_str()); config_container[iZone] = new CConfig(driver_config, zone_file_name, SU2_COMPONENT::SU2_DOT, iZone, nZone, true); } else { config_container[iZone] = new CConfig(driver_config, config_file_name, SU2_COMPONENT::SU2_DOT, iZone, nZone, true); } - + config_container[iZone]->SetMPICommunicator(SU2_MPI::GetComm()); } - + /*--- Set the multizone part of the problem. ---*/ if (driver_config->GetMultizone_Problem()){ for (iZone = 0; iZone < nZone; iZone++) { @@ -144,216 +147,224 @@ void CDiscAdjDeformationDriver::Input_Preprocessing() { } void CDiscAdjDeformationDriver::Geometrical_Preprocessing() { - + /*--- 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++) { - + + for (iZone = 0; iZone < nZone; iZone++) { + /*--- Determine whether or not the FEM solver is used, which decides the type of geometry classes that are instantiated. ---*/ const bool fem_solver = config_container[iZone]->GetFEMSolver(); - + /*--- Read the number of instances for each zone ---*/ - + nInst[iZone] = config_container[iZone]->GetnTimeInstances(); - + geometry_container[iZone] = new CGeometry*[nInst[iZone]]; - + for (iInst = 0; iInst < nInst[iZone]; iInst++){ - + /*--- Definition of the geometry class to store the primal grid in the partitioning process. ---*/ - + CGeometry *geometry_aux = nullptr; - + /*--- 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) ---*/ - + if ( fem_solver ) geometry_aux->SetColorFEMGrid_Parallel(config_container[iZone]); else geometry_aux->SetColorGrid_Parallel(config_container[iZone]); - + /*--- Build the grid data structures using the ParMETIS coloring. ---*/ - + if( fem_solver ) { switch( config_container[iZone]->GetKind_FEM_Flow() ) { - case DG: { - geometry_container[iZone][iInst] = new CMeshFEM_DG(geometry_aux, config_container[iZone]); - break; - } + case DG: { + geometry_container[iZone][iInst] = new CMeshFEM_DG(geometry_aux, config_container[iZone]); + break; + } } } else { geometry_container[iZone][iInst] = new CPhysicalGeometry(geometry_aux, config_container[iZone]); } - + /*--- Deallocate the memory of geometry_aux ---*/ - + delete geometry_aux; - + /*--- Add the Send/Receive boundaries ---*/ - + geometry_container[iZone][iInst]->SetSendReceive(config_container[iZone]); - + /*--- Add the Send/Receive boundaries ---*/ - + geometry_container[iZone][iInst]->SetBoundaries(config_container[iZone]); - + /*--- Create the vertex structure (required for MPI) ---*/ - + if (rank == MASTER_NODE) cout << "Identify vertices." << endl; geometry_container[iZone][iInst]->SetVertex(config_container[iZone]); - + /*--- Store the global to local mapping after preprocessing. ---*/ - + if (rank == MASTER_NODE) cout << "Storing a mapping from global to local point index." << endl; geometry_container[iZone][iInst]->SetGlobal_to_Local_Point(); - + /* Test for a fem solver, because some more work must be done. */ - + if (fem_solver) { - + /*--- Carry out a dynamic cast to CMeshFEM_DG, such that it is not needed to define all virtual functions in the base class CGeometry. ---*/ CMeshFEM_DG *DGMesh = dynamic_cast(geometry_container[iZone][iInst]); - + /*--- Determine the standard elements for the volume elements. ---*/ if (rank == MASTER_NODE) cout << "Creating standard volume elements." << endl; DGMesh->CreateStandardVolumeElements(config_container[iZone]); - + /*--- Create the face information needed to compute the contour integral for the elements in the Discontinuous Galerkin formulation. ---*/ if (rank == MASTER_NODE) cout << "Creating face information." << endl; DGMesh->CreateFaces(config_container[iZone]); } } - + if (rank == MASTER_NODE) - cout << "\n----------------------- Preprocessing computations ----------------------" << endl; - + cout << "\n----------------------- Preprocessing computations ----------------------" << endl; + /*--- Compute elements surrounding points, points surrounding points ---*/ - + if (rank == MASTER_NODE) cout << "Setting local point connectivity." << endl; geometry_container[iZone][INST_0]->SetPoint_Connectivity(); - + /*--- Check the orientation before computing geometrical quantities ---*/ - + geometry_container[iZone][INST_0]->SetBoundVolume(); if (config_container[iZone]->GetReorientElements()) { if (rank == MASTER_NODE) cout << "Checking the numerical grid orientation of the elements." << endl; geometry_container[iZone][INST_0]->Check_IntElem_Orientation(config_container[iZone]); geometry_container[iZone][INST_0]->Check_BoundElem_Orientation(config_container[iZone]); } - + /*--- Create the edge structure ---*/ - + if (rank == MASTER_NODE) cout << "Identify edges and vertices." << endl; geometry_container[iZone][INST_0]->SetEdges(); geometry_container[iZone][INST_0]->SetVertex(config_container[iZone]); - + /*--- Create the dual control volume structures ---*/ - + if (rank == MASTER_NODE) cout << "Setting the bound control volume structure." << endl; geometry_container[iZone][INST_0]->SetBoundControlVolume(config_container[ZONE_0], ALLOCATE); - + /*--- Store the global to local mapping after preprocessing. ---*/ - + if (rank == MASTER_NODE) cout << "Storing a mapping from global to local point index." << endl; geometry_container[iZone][INST_0]->SetGlobal_to_Local_Point(); - + /*--- Create the point-to-point MPI communication structures. ---*/ - + geometry_container[iZone][INST_0]->PreprocessP2PComms(geometry_container[iZone][INST_0], config_container[iZone]); - + } } void CDiscAdjDeformationDriver::Output_Preprocessing() { - + } void CDiscAdjDeformationDriver::Run() { - + for (iZone = 0; iZone < nZone; iZone++) { - if (rank == MASTER_NODE) cout << "Reading volume sensitivities at each node from file." << endl; - grid_movement[iZone] = new CVolumetricMovement(geometry_container[iZone][INST_0], config_container[iZone]); - - /*--- Read in sensitivities from file. ---*/ - if (config_container[ZONE_0]->GetSensitivity_Format() == UNORDERED_ASCII) - geometry_container[iZone][INST_0]->ReadUnorderedSensitivity(config_container[iZone]); - else - geometry_container[iZone][INST_0]->SetSensitivity(config_container[iZone]); - - if (rank == MASTER_NODE) cout << "\n---------------------- Mesh sensitivity computation ---------------------" << endl; + if (rank == MASTER_NODE) cout << "Reading volume sensitivities at each node from file." << endl; + grid_movement[iZone] = new CVolumetricMovement(geometry_container[iZone][INST_0], config_container[iZone]); + + /*--- Read in sensitivities from file. ---*/ + if (config_container[ZONE_0]->GetSensitivity_Format() == UNORDERED_ASCII) + geometry_container[iZone][INST_0]->ReadUnorderedSensitivity(config_container[iZone]); + else + geometry_container[iZone][INST_0]->SetSensitivity(config_container[iZone]); + + if (rank == MASTER_NODE) cout << "\n---------------------- Mesh sensitivity computation ---------------------" << endl; + if (config_container[iZone]->GetDiscrete_Adjoint() && config_container[iZone]->GetSmoothGradient() && + config_container[iZone]->GetSobMode() == ENUM_SOBOLEV_MODUS::MESH_LEVEL) { + DerivativeTreatment_MeshSensitivity(geometry_container[iZone][INST_0], config_container[iZone], grid_movement[iZone]); + } else { grid_movement[iZone]->SetVolume_Deformation(geometry_container[iZone][INST_0], config_container[iZone], false, true); + } } - + if (rank == MASTER_NODE) cout << "\n------------------------ Mesh sensitivity Output ------------------------" << endl; SetSensitivity_Files(geometry_container, config_container, nZone); - + /*--- Initialize structure to store the gradient ---*/ Gradient = new su2double*[config_container[ZONE_0]->GetnDV()]; - + for (auto iDV = 0u; iDV < config_container[ZONE_0]->GetnDV(); iDV++) { /*--- Initialize to zero ---*/ Gradient[iDV] = new su2double[config_container[ZONE_0]->GetnDV_Value(iDV)](); } - + Gradient_file.precision(driver_config->OptionIsSet("OUTPUT_PRECISION") ? driver_config->GetOutput_Precision() : 6); - + /*--- For multizone computations the gradient contributions are summed up and written into one file. ---*/ for (iZone = 0; iZone < nZone; iZone++){ if ((config_container[iZone]->GetDesign_Variable(0) != NONE) && (config_container[iZone]->GetDesign_Variable(0) != SURFACE_FILE)) { - - if (rank == MASTER_NODE) - cout << "\n---------- Start gradient evaluation using sensitivity information ----------" << endl; - - /*--- Definition of the Class for surface deformation ---*/ - - surface_movement[iZone] = new CSurfaceMovement(); - - /*--- Copy coordinates to the surface structure ---*/ - - surface_movement[iZone]->CopyBoundary(geometry_container[iZone][INST_0], config_container[iZone]); - - /*--- If AD mode is enabled we can use it to compute the projection, - * otherwise we use finite differences. ---*/ - - if (config_container[iZone]->GetAD_Mode()) - SetDiscAdjDeformation_AD(geometry_container[iZone][INST_0], config_container[iZone], surface_movement[iZone] , Gradient); - else - SetDiscAdjDeformation_FD(geometry_container[iZone][INST_0], config_container[iZone], surface_movement[iZone] , Gradient); - + + if (rank == MASTER_NODE) + cout << "\n---------- Start gradient evaluation using sensitivity information ----------" << endl; + + /*--- Definition of the Class for surface deformation ---*/ + + surface_movement[iZone] = new CSurfaceMovement(); + + /*--- Copy coordinates to the surface structure ---*/ + + surface_movement[iZone]->CopyBoundary(geometry_container[iZone][INST_0], config_container[iZone]); + + /*--- If AD mode is enabled we can use it to compute the projection, + * otherwise we use finite differences. ---*/ + + if (config_container[iZone]->GetAD_Mode()) + if (config_container[iZone]->GetSmoothGradient()) { + DerivativeTreatment_Gradient(geometry_container[iZone][INST_0], config_container[iZone], grid_movement[iZone], surface_movement[iZone] , Gradient); + } else { + SetProjection_AD(geometry_container[iZone][INST_0], config_container[iZone], surface_movement[iZone] , Gradient); + } + } else { + SetProjection_FD(geometry_container[iZone][INST_0], config_container[iZone], surface_movement[iZone] , Gradient); } } // for iZone - + /*--- Write the gradient to a file ---*/ - + if (rank == MASTER_NODE) Gradient_file.open(config_container[ZONE_0]->GetObjFunc_Grad_FileName().c_str(), ios::out); - + /*--- Print gradients to screen and writes to file ---*/ - + OutputGradient(Gradient, config_container[ZONE_0], Gradient_file); - + } void CDiscAdjDeformationDriver::Postprocessing() { - + for (auto iDV = 0u; iDV < config_container[ZONE_0]->GetnDV(); iDV++){ - delete [] Gradient[iDV]; + delete [] Gradient[iDV]; } delete [] Gradient; - + delete driver_config; driver_config = nullptr; - + if (rank == MASTER_NODE) cout << "\n------------------------- Solver Postprocessing -------------------------" << endl; - + if (geometry_container != nullptr) { for (iZone = 0; iZone < nZone; iZone++) { if (geometry_container[iZone] != nullptr) { @@ -366,7 +377,7 @@ void CDiscAdjDeformationDriver::Postprocessing() { delete [] geometry_container; } if (rank == MASTER_NODE) cout << "Deleted CGeometry container." << endl; - + if (surface_movement != nullptr) { for (iZone = 0; iZone < nZone; iZone++) { delete surface_movement[iZone]; @@ -374,7 +385,7 @@ void CDiscAdjDeformationDriver::Postprocessing() { delete [] surface_movement; } if (rank == MASTER_NODE) cout << "Deleted CSurfaceMovement class." << endl; - + if (grid_movement != nullptr) { for (iZone = 0; iZone < nZone; iZone++) { delete grid_movement[iZone]; @@ -382,7 +393,7 @@ void CDiscAdjDeformationDriver::Postprocessing() { delete [] grid_movement; } if (rank == MASTER_NODE) cout << "Deleted CVolumetricMovement class." << endl; - + if (config_container != nullptr) { for (iZone = 0; iZone < nZone; iZone++) { delete config_container[iZone]; @@ -390,540 +401,620 @@ void CDiscAdjDeformationDriver::Postprocessing() { delete [] config_container; } if (rank == MASTER_NODE) cout << "Deleted CConfig container." << endl; - + } -void CDiscAdjDeformationDriver::SetDiscAdjDeformation_FD(CGeometry *geometry, CConfig *config, CSurfaceMovement *surface_movement, su2double** Gradient){ - - unsigned short iDV, nDV, iFFDBox, nDV_Value, iMarker, iDim; - unsigned long iVertex, iPoint; - su2double delta_eps, my_Gradient, localGradient, *Normal, dS, *VarCoord, Sensitivity, - dalpha[3], deps[3], dalpha_deps; - bool *UpdatePoint, MoveSurface, Local_MoveSurface; - CFreeFormDefBox **FFDBox; - - int rank = SU2_MPI::GetRank(); - - nDV = config->GetnDV(); - - /*--- Boolean controlling points to be updated ---*/ - - UpdatePoint = new bool[geometry->GetnPoint()]; - - /*--- Definition of the FFD deformation class ---*/ - - unsigned short nFFDBox = MAX_NUMBER_FFD; - FFDBox = new CFreeFormDefBox*[nFFDBox]; - for (iFFDBox = 0; iFFDBox < MAX_NUMBER_FFD; iFFDBox++) FFDBox[iFFDBox] = nullptr; - - for (iDV = 0; iDV < nDV; iDV++){ - nDV_Value = config->GetnDV_Value(iDV); - if (nDV_Value != 1){ - SU2_MPI::Error("The DiscAdjDeformation using finite differences currently only supports a fixed direction of movement for FFD points.", CURRENT_FUNCTION); +void CDiscAdjDeformationDriver::SetProjection_FD(CGeometry *geometry, CConfig *config, CSurfaceMovement *surface_movement, su2double** Gradient){ + + unsigned short iDV, nDV, iFFDBox, nDV_Value, iMarker, iDim; + unsigned long iVertex, iPoint; + su2double delta_eps, my_Gradient, localGradient, *Normal, dS, *VarCoord, Sensitivity, + dalpha[3], deps[3], dalpha_deps; + bool *UpdatePoint, MoveSurface, Local_MoveSurface; + CFreeFormDefBox **FFDBox; + + int rank = SU2_MPI::GetRank(); + + nDV = config->GetnDV(); + + /*--- Boolean controlling points to be updated ---*/ + + UpdatePoint = new bool[geometry->GetnPoint()]; + + /*--- Definition of the FFD deformation class ---*/ + + unsigned short nFFDBox = MAX_NUMBER_FFD; + FFDBox = new CFreeFormDefBox*[nFFDBox]; + for (iFFDBox = 0; iFFDBox < MAX_NUMBER_FFD; iFFDBox++) FFDBox[iFFDBox] = nullptr; + + for (iDV = 0; iDV < nDV; iDV++){ + nDV_Value = config->GetnDV_Value(iDV); + if (nDV_Value != 1){ + SU2_MPI::Error("The projection using finite differences currently only supports a fixed direction of movement for FFD points.", CURRENT_FUNCTION); + } } - } - - /*--- Continuous adjoint gradient computation ---*/ - - if (rank == MASTER_NODE) - cout << "Evaluate functional gradient using Finite Differences." << endl; - - for (iDV = 0; iDV < nDV; iDV++) { - - MoveSurface = true; - Local_MoveSurface = true; - - /*--- 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_TWIST_2D) || - (config->GetDesign_Variable(iDV) == FFD_CONTROL_POINT) || - (config->GetDesign_Variable(iDV) == FFD_NACELLE) || - (config->GetDesign_Variable(iDV) == FFD_GULL) || - (config->GetDesign_Variable(iDV) == FFD_TWIST) || - (config->GetDesign_Variable(iDV) == FFD_ROTATION) || - (config->GetDesign_Variable(iDV) == FFD_CAMBER) || - (config->GetDesign_Variable(iDV) == FFD_THICKNESS) || - (config->GetDesign_Variable(iDV) == FFD_ANGLE_OF_ATTACK)) { - - /*--- 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_movement->ReadFFDInfo(geometry, config, FFDBox, config->GetMesh_FileName()); - - /*--- If the FFDBox was not defined in the input file ---*/ - if (!surface_movement->GetFFDBoxDefinition()) { - SU2_MPI::Error("The input grid doesn't have the entire FFD information!", CURRENT_FUNCTION); + + /*--- Continuous adjoint gradient computation ---*/ + + if (rank == MASTER_NODE) + cout << "Evaluate functional gradient using Finite Differences." << endl; + + for (iDV = 0; iDV < nDV; iDV++) { + + MoveSurface = true; + Local_MoveSurface = true; + + /*--- 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_TWIST_2D) || + (config->GetDesign_Variable(iDV) == FFD_CONTROL_POINT) || + (config->GetDesign_Variable(iDV) == FFD_NACELLE) || + (config->GetDesign_Variable(iDV) == FFD_GULL) || + (config->GetDesign_Variable(iDV) == FFD_TWIST) || + (config->GetDesign_Variable(iDV) == FFD_ROTATION) || + (config->GetDesign_Variable(iDV) == FFD_CAMBER) || + (config->GetDesign_Variable(iDV) == FFD_THICKNESS) || + (config->GetDesign_Variable(iDV) == FFD_ANGLE_OF_ATTACK)) { + + /*--- 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_movement->ReadFFDInfo(geometry, config, FFDBox, config->GetMesh_FileName()); + + /*--- If the FFDBox was not defined in the input file ---*/ + if (!surface_movement->GetFFDBoxDefinition()) { + SU2_MPI::Error("The input grid doesn't have the entire FFD information!", CURRENT_FUNCTION); + } + + for (iFFDBox = 0; iFFDBox < surface_movement->GetnFFDBox(); iFFDBox++) { + + if (rank == MASTER_NODE) cout << "Checking FFD box dimension." << endl; + surface_movement->CheckFFDDimension(geometry, config, FFDBox[iFFDBox], iFFDBox); + + if (rank == MASTER_NODE) cout << "Check the FFD box intersections with the solid surfaces." << endl; + surface_movement->CheckFFDIntersections(geometry, config, FFDBox[iFFDBox], iFFDBox); + + } + + if (rank == MASTER_NODE) + cout <<"-------------------------------------------------------------------------" << endl; + + } + + if (rank == MASTER_NODE) { + cout << endl << "Design variable number "<< iDV <<"." << endl; + cout << "Performing 3D deformation of the surface." << endl; + } + + /*--- Apply the control point change ---*/ + + MoveSurface = false; + + for (iFFDBox = 0; iFFDBox < surface_movement->GetnFFDBox(); iFFDBox++) { + + /*--- Reset FFD box ---*/ + + switch (config->GetDesign_Variable(iDV) ) { + case FFD_CONTROL_POINT_2D : Local_MoveSurface = surface_movement->SetFFDCPChange_2D(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; + case FFD_CAMBER_2D : Local_MoveSurface = surface_movement->SetFFDCamber_2D(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; + case FFD_THICKNESS_2D : Local_MoveSurface = surface_movement->SetFFDThickness_2D(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; + case FFD_TWIST_2D : Local_MoveSurface = surface_movement->SetFFDTwist_2D(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; + case FFD_CONTROL_POINT : Local_MoveSurface = surface_movement->SetFFDCPChange(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; + case FFD_NACELLE : Local_MoveSurface = surface_movement->SetFFDNacelle(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; + case FFD_GULL : Local_MoveSurface = surface_movement->SetFFDGull(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; + case FFD_TWIST : Local_MoveSurface = surface_movement->SetFFDTwist(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; + case FFD_ROTATION : Local_MoveSurface = surface_movement->SetFFDRotation(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; + case FFD_CAMBER : Local_MoveSurface = surface_movement->SetFFDCamber(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; + case FFD_THICKNESS : Local_MoveSurface = surface_movement->SetFFDThickness(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; + case FFD_CONTROL_SURFACE : Local_MoveSurface = surface_movement->SetFFDControl_Surface(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; + case FFD_ANGLE_OF_ATTACK : Gradient[iDV][0] = config->GetAoA_Sens(); break; + } + + /*--- Recompute cartesian coordinates using the new control points position ---*/ + + if (Local_MoveSurface) { + MoveSurface = true; + surface_movement->SetCartesianCoord(geometry, config, FFDBox[iFFDBox], iFFDBox, true); + } + + } + } - - for (iFFDBox = 0; iFFDBox < surface_movement->GetnFFDBox(); iFFDBox++) { - - if (rank == MASTER_NODE) cout << "Checking FFD box dimension." << endl; - surface_movement->CheckFFDDimension(geometry, config, FFDBox[iFFDBox], iFFDBox); - - if (rank == MASTER_NODE) cout << "Check the FFD box intersections with the solid surfaces." << endl; - surface_movement->CheckFFDIntersections(geometry, config, FFDBox[iFFDBox], iFFDBox); - + + /*--- Hicks Henne design variable ---*/ + + else if (config->GetDesign_Variable(iDV) == HICKS_HENNE) { + surface_movement->SetHicksHenne(geometry, config, iDV, true); } - - if (rank == MASTER_NODE) - cout <<"-------------------------------------------------------------------------" << endl; - - } - - if (rank == MASTER_NODE) { - cout << endl << "Design variable number "<< iDV <<"." << endl; - cout << "Performing 3D deformation of the surface." << endl; - } - - /*--- Apply the control point change ---*/ - - MoveSurface = false; - - for (iFFDBox = 0; iFFDBox < surface_movement->GetnFFDBox(); iFFDBox++) { - - /*--- Reset FFD box ---*/ - - switch (config->GetDesign_Variable(iDV) ) { - case FFD_CONTROL_POINT_2D : Local_MoveSurface = surface_movement->SetFFDCPChange_2D(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; - case FFD_CAMBER_2D : Local_MoveSurface = surface_movement->SetFFDCamber_2D(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; - case FFD_THICKNESS_2D : Local_MoveSurface = surface_movement->SetFFDThickness_2D(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; - case FFD_TWIST_2D : Local_MoveSurface = surface_movement->SetFFDTwist_2D(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; - case FFD_CONTROL_POINT : Local_MoveSurface = surface_movement->SetFFDCPChange(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; - case FFD_NACELLE : Local_MoveSurface = surface_movement->SetFFDNacelle(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; - case FFD_GULL : Local_MoveSurface = surface_movement->SetFFDGull(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; - case FFD_TWIST : Local_MoveSurface = surface_movement->SetFFDTwist(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; - case FFD_ROTATION : Local_MoveSurface = surface_movement->SetFFDRotation(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; - case FFD_CAMBER : Local_MoveSurface = surface_movement->SetFFDCamber(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; - case FFD_THICKNESS : Local_MoveSurface = surface_movement->SetFFDThickness(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; - case FFD_CONTROL_SURFACE : Local_MoveSurface = surface_movement->SetFFDControl_Surface(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; - case FFD_ANGLE_OF_ATTACK : Gradient[iDV][0] = config->GetAoA_Sens(); break; + + /*--- Surface bump design variable ---*/ + + else if (config->GetDesign_Variable(iDV) == SURFACE_BUMP) { + surface_movement->SetSurface_Bump(geometry, config, iDV, true); } - - /*--- Recompute cartesian coordinates using the new control points position ---*/ - - if (Local_MoveSurface) { - MoveSurface = true; - surface_movement->SetCartesianCoord(geometry, config, FFDBox[iFFDBox], iFFDBox, true); + + /*--- Kulfan (CST) design variable ---*/ + + else if (config->GetDesign_Variable(iDV) == CST) { + surface_movement->SetCST(geometry, config, iDV, true); } - - } - - } - - /*--- Hicks Henne design variable ---*/ - - else if (config->GetDesign_Variable(iDV) == HICKS_HENNE) { - surface_movement->SetHicksHenne(geometry, config, iDV, true); - } - - /*--- Surface bump design variable ---*/ - - else if (config->GetDesign_Variable(iDV) == SURFACE_BUMP) { - surface_movement->SetSurface_Bump(geometry, config, iDV, true); - } - - /*--- Kulfan (CST) design variable ---*/ - - else if (config->GetDesign_Variable(iDV) == CST) { - surface_movement->SetCST(geometry, config, iDV, true); - } - - /*--- Displacement design variable ---*/ - - else if (config->GetDesign_Variable(iDV) == TRANSLATION) { - surface_movement->SetTranslation(geometry, config, iDV, true); - } - - /*--- Angle of Attack design variable ---*/ - - else if (config->GetDesign_Variable(iDV) == ANGLE_OF_ATTACK) { - Gradient[iDV][0] = config->GetAoA_Sens(); - } - - /*--- Scale design variable ---*/ - - else if (config->GetDesign_Variable(iDV) == SCALE) { - surface_movement->SetScale(geometry, config, iDV, true); - } - - /*--- Rotation design variable ---*/ - - else if (config->GetDesign_Variable(iDV) == ROTATION) { - surface_movement->SetRotation(geometry, config, iDV, true); - } - - /*--- NACA_4Digits design variable ---*/ - - else if (config->GetDesign_Variable(iDV) == NACA_4DIGITS) { - surface_movement->SetNACA_4Digits(geometry, config); - } - - /*--- Parabolic design variable ---*/ - - else if (config->GetDesign_Variable(iDV) == PARABOLIC) { - surface_movement->SetParabolic(geometry, config); - } - - /*--- Design variable not implement ---*/ - - else { - if (rank == MASTER_NODE) - cout << "Design Variable not implement yet" << endl; - } - - /*--- Load the delta change in the design variable (finite difference step). ---*/ - - if ((config->GetDesign_Variable(iDV) != ANGLE_OF_ATTACK) && - (config->GetDesign_Variable(iDV) != FFD_ANGLE_OF_ATTACK)) { - - /*--- If the Angle of attack is not involved, reset the value of the gradient ---*/ - - my_Gradient = 0.0; Gradient[iDV][0] = 0.0; - - if (MoveSurface) { - - delta_eps = config->GetDV_Value(iDV); - - for (iPoint = 0; iPoint < geometry->GetnPoint(); iPoint++) - UpdatePoint[iPoint] = true; - - for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { - if (config->GetMarker_All_DV(iMarker) == YES) { - for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - - iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); - if ((iPoint < geometry->GetnPointDomain()) && UpdatePoint[iPoint]) { - - Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); - VarCoord = geometry->vertex[iMarker][iVertex]->GetVarCoord(); - Sensitivity = geometry->vertex[iMarker][iVertex]->GetAuxVar(); - - dS = 0.0; - for (iDim = 0; iDim < geometry->GetnDim(); iDim++) { - dS += Normal[iDim]*Normal[iDim]; - deps[iDim] = VarCoord[iDim] / delta_eps; - } - dS = sqrt(dS); - - dalpha_deps = 0.0; - for (iDim = 0; iDim < geometry->GetnDim(); iDim++) { - dalpha[iDim] = Normal[iDim] / dS; - dalpha_deps -= dalpha[iDim]*deps[iDim]; + + /*--- Displacement design variable ---*/ + + else if (config->GetDesign_Variable(iDV) == TRANSLATION) { + surface_movement->SetTranslation(geometry, config, iDV, true); + } + + /*--- Angle of Attack design variable ---*/ + + else if (config->GetDesign_Variable(iDV) == ANGLE_OF_ATTACK) { + Gradient[iDV][0] = config->GetAoA_Sens(); + } + + /*--- Scale design variable ---*/ + + else if (config->GetDesign_Variable(iDV) == SCALE) { + surface_movement->SetScale(geometry, config, iDV, true); + } + + /*--- Rotation design variable ---*/ + + else if (config->GetDesign_Variable(iDV) == ROTATION) { + surface_movement->SetRotation(geometry, config, iDV, true); + } + + /*--- NACA_4Digits design variable ---*/ + + else if (config->GetDesign_Variable(iDV) == NACA_4DIGITS) { + surface_movement->SetNACA_4Digits(geometry, config); + } + + /*--- Parabolic design variable ---*/ + + else if (config->GetDesign_Variable(iDV) == PARABOLIC) { + surface_movement->SetParabolic(geometry, config); + } + + /*--- Design variable not implemented ---*/ + + else { + if (rank == MASTER_NODE) + cout << "Design Variable not implemented yet" << endl; + } + + /*--- Load the delta change in the design variable (finite difference step). ---*/ + + if ((config->GetDesign_Variable(iDV) != ANGLE_OF_ATTACK) && + (config->GetDesign_Variable(iDV) != FFD_ANGLE_OF_ATTACK)) { + + /*--- If the Angle of attack is not involved, reset the value of the gradient ---*/ + + my_Gradient = 0.0; Gradient[iDV][0] = 0.0; + + if (MoveSurface) { + + delta_eps = config->GetDV_Value(iDV); + + for (iPoint = 0; iPoint < geometry->GetnPoint(); iPoint++) + UpdatePoint[iPoint] = true; + + for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { + if (config->GetMarker_All_DV(iMarker) == YES) { + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { + + iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + if ((iPoint < geometry->GetnPointDomain()) && UpdatePoint[iPoint]) { + + Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); + VarCoord = geometry->vertex[iMarker][iVertex]->GetVarCoord(); + Sensitivity = geometry->vertex[iMarker][iVertex]->GetAuxVar(); + + dS = 0.0; + for (iDim = 0; iDim < geometry->GetnDim(); iDim++) { + dS += Normal[iDim]*Normal[iDim]; + deps[iDim] = VarCoord[iDim] / delta_eps; + } + dS = sqrt(dS); + + dalpha_deps = 0.0; + for (iDim = 0; iDim < geometry->GetnDim(); iDim++) { + dalpha[iDim] = Normal[iDim] / dS; + dalpha_deps -= dalpha[iDim]*deps[iDim]; + } + + my_Gradient += Sensitivity*dalpha_deps; + UpdatePoint[iPoint] = false; + } + } + } } - - my_Gradient += Sensitivity*dalpha_deps; - UpdatePoint[iPoint] = false; - } } - } + + SU2_MPI::Allreduce(&my_Gradient, &localGradient, 1, MPI_DOUBLE, MPI_SUM, SU2_MPI::GetComm()); + Gradient[iDV][0] += localGradient; } - } - - SU2_MPI::Allreduce(&my_Gradient, &localGradient, 1, MPI_DOUBLE, MPI_SUM, SU2_MPI::GetComm()); - Gradient[iDV][0] += localGradient; } - } - - /*--- Delete memory for parameterization. ---*/ - - if (FFDBox != nullptr) { - for (iFFDBox = 0; iFFDBox < MAX_NUMBER_FFD; iFFDBox++) { - if (FFDBox[iFFDBox] != nullptr) { - delete FFDBox[iFFDBox]; - } + + /*--- Delete memory for parameterization. ---*/ + + if (FFDBox != nullptr) { + for (iFFDBox = 0; iFFDBox < MAX_NUMBER_FFD; iFFDBox++) { + if (FFDBox[iFFDBox] != nullptr) { + delete FFDBox[iFFDBox]; + } + } + delete [] FFDBox; } - delete [] FFDBox; - } - - delete [] UpdatePoint; - + + delete [] UpdatePoint; + } -void CDiscAdjDeformationDriver::SetDiscAdjDeformation_AD(CGeometry *geometry, CConfig *config, CSurfaceMovement *surface_movement, su2double** Gradient){ - - su2double DV_Value, *VarCoord, Sensitivity, my_Gradient, localGradient, *Normal, Area = 0.0; - unsigned short iDV_Value = 0, iMarker, nMarker, iDim, nDim, iDV, nDV, nDV_Value; - unsigned long iVertex, nVertex, iPoint; - - int rank = SU2_MPI::GetRank(); - - nMarker = config->GetnMarker_All(); - nDim = geometry->GetnDim(); - nDV = config->GetnDV(); - - VarCoord = nullptr; - - /*--- Discrete adjoint gradient computation ---*/ - - if (rank == MASTER_NODE) - cout << endl << "Evaluate functional gradient using Algorithmic Differentiation (ZONE " << config->GetiZone() << ")." << endl; - - /*--- Start recording of operations ---*/ - - AD::StartRecording(); - - /*--- Register design variables as input and set them to zero - * (since we want to have the derivative at alpha = 0, i.e. for the current design) ---*/ - - for (iDV = 0; iDV < nDV; iDV++){ - - for (iDV_Value = 0; iDV_Value < config->GetnDV_Value(iDV); iDV_Value++){ - - config->SetDV_Value(iDV, iDV_Value, 0.0); - - AD::RegisterInput(config->GetDV_Value(iDV, iDV_Value)); +void CDiscAdjDeformationDriver::SetProjection_AD(CGeometry *geometry, CConfig *config, CSurfaceMovement *surface_movement, su2double** Gradient){ + + su2double *VarCoord = nullptr, Sensitivity, my_Gradient, localGradient, *Normal, Area = 0.0; + unsigned short iDV_Value = 0, iMarker, nMarker, iDim, nDim, iDV, nDV; + unsigned long iVertex, nVertex, iPoint; + + const int rank = SU2_MPI::GetRank(); + + nMarker = config->GetnMarker_All(); + nDim = geometry->GetnDim(); + nDV = config->GetnDV(); + + /*--- Discrete adjoint gradient computation ---*/ + + if (rank == MASTER_NODE) + cout << endl << "Evaluate functional gradient using Algorithmic Differentiation (ZONE " << config->GetiZone() << ")." << endl; + + /*--- Start recording of operations ---*/ + + AD::StartRecording(); + + /*--- Register design variables as input and set them to zero + * (since we want to have the derivative at alpha = 0, i.e. for the current design) ---*/ + + for (iDV = 0; iDV < nDV; iDV++){ + + for (iDV_Value = 0; iDV_Value < config->GetnDV_Value(iDV); iDV_Value++){ + + config->SetDV_Value(iDV, iDV_Value, 0.0); + + AD::RegisterInput(config->GetDV_Value(iDV, iDV_Value)); + } } - } - - /*--- Call the surface deformation routine ---*/ - - surface_movement->SetSurface_Deformation(geometry, config); - - /*--- Stop the recording --- */ - - AD::StopRecording(); - - /*--- Create a structure to identify points that have been already visited. - * We need that to make sure to set the sensitivity of surface points only once - * (Markers share points, so we would visit them more than once in the loop over the markers below) ---*/ - - bool* visited = new bool[geometry->GetnPoint()]; - for (iPoint = 0; iPoint < geometry->GetnPoint(); iPoint++){ - visited[iPoint] = false; - } - - /*--- Initialize the derivatives of the output of the surface deformation routine - * with the discrete adjoints from the CFD solution ---*/ - - for (iMarker = 0; iMarker < nMarker; iMarker++) { - if (config->GetMarker_All_DV(iMarker) == YES) { - nVertex = geometry->nVertex[iMarker]; - for (iVertex = 0; iVertex vertex[iMarker][iVertex]->GetNode(); - if (!visited[iPoint]){ - VarCoord = geometry->vertex[iMarker][iVertex]->GetVarCoord(); - Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); - - Area = 0.0; - for (iDim = 0; iDim < nDim; iDim++){ - Area += Normal[iDim]*Normal[iDim]; - } - Area = sqrt(Area); - - for (iDim = 0; iDim < nDim; iDim++){ - if (config->GetDiscrete_Adjoint()){ - Sensitivity = geometry->GetSensitivity(iPoint, iDim); - } else { - Sensitivity = -Normal[iDim]*geometry->vertex[iMarker][iVertex]->GetAuxVar()/Area; + + /*--- Call the surface deformation routine ---*/ + + surface_movement->SetSurface_Deformation(geometry, config); + + /*--- Stop the recording --- */ + + AD::StopRecording(); + + /*--- Create a structure to identify points that have been already visited. + * We need that to make sure to set the sensitivity of surface points only once + * (Markers share points, so we would visit them more than once in the loop over the markers below) ---*/ + + vector visited(geometry->GetnPoint(), false); + + /*--- Initialize the derivatives of the output of the surface deformation routine + * with the discrete adjoints from the CFD solution ---*/ + + for (iMarker = 0; iMarker < nMarker; iMarker++) { + if (config->GetMarker_All_DV(iMarker) == YES) { + nVertex = geometry->nVertex[iMarker]; + for (iVertex = 0; iVertex vertex[iMarker][iVertex]->GetNode(); + if (!visited[iPoint]){ + VarCoord = geometry->vertex[iMarker][iVertex]->GetVarCoord(); + Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); + + Area = 0.0; + for (iDim = 0; iDim < nDim; iDim++){ + Area += Normal[iDim]*Normal[iDim]; + } + Area = sqrt(Area); + + for (iDim = 0; iDim < nDim; iDim++){ + if (config->GetDiscrete_Adjoint()){ + Sensitivity = geometry->GetSensitivity(iPoint, iDim); + } else { + Sensitivity = -Normal[iDim]*geometry->vertex[iMarker][iVertex]->GetAuxVar()/Area; + } + SU2_TYPE::SetDerivative(VarCoord[iDim], SU2_TYPE::GetValue(Sensitivity)); + } + visited[iPoint] = true; + } } - SU2_TYPE::SetDerivative(VarCoord[iDim], SU2_TYPE::GetValue(Sensitivity)); - } - visited[iPoint] = true; } - } } - } - - delete [] visited; - - /*--- Compute derivatives and extract gradient ---*/ - - AD::ComputeAdjoint(); - - for (iDV = 0; iDV < nDV; iDV++){ - nDV_Value = config->GetnDV_Value(iDV); - - for (iDV_Value = 0; iDV_Value < nDV_Value; iDV_Value++){ - DV_Value = config->GetDV_Value(iDV, iDV_Value); - my_Gradient = SU2_TYPE::GetDerivative(DV_Value); - SU2_MPI::Allreduce(&my_Gradient, &localGradient, 1, MPI_DOUBLE, MPI_SUM, SU2_MPI::GetComm()); - - /*--- Angle of Attack design variable (this is different, - the value comes form the input file) ---*/ - - if ((config->GetDesign_Variable(iDV) == ANGLE_OF_ATTACK) || - (config->GetDesign_Variable(iDV) == FFD_ANGLE_OF_ATTACK)) { - Gradient[iDV][iDV_Value] = config->GetAoA_Sens(); - } - - Gradient[iDV][iDV_Value] += localGradient; + + /*--- Compute derivatives and extract gradient ---*/ + + AD::ComputeAdjoint(); + + for (iDV = 0; iDV < nDV; iDV++){ + + for (iDV_Value = 0; iDV_Value < config->GetnDV_Value(iDV); iDV_Value++) { + + my_Gradient = SU2_TYPE::GetDerivative(config->GetDV_Value(iDV, iDV_Value)); + + SU2_MPI::Allreduce(&my_Gradient, &localGradient, 1, MPI_DOUBLE, MPI_SUM, SU2_MPI::GetComm()); + + /*--- Angle of Attack design variable (this is different, + the value comes form the input file) ---*/ + + if ((config->GetDesign_Variable(iDV) == ANGLE_OF_ATTACK) || + (config->GetDesign_Variable(iDV) == FFD_ANGLE_OF_ATTACK)) { + Gradient[iDV][iDV_Value] = config->GetAoA_Sens(); + } + + Gradient[iDV][iDV_Value] += localGradient; + } } - } - - AD::Reset(); - + + AD::Reset(); + } void CDiscAdjDeformationDriver::OutputGradient(su2double** Gradient, CConfig* config, ofstream& Gradient_file){ - - unsigned short nDV, iDV, iDV_Value, nDV_Value; - - int rank = SU2_MPI::GetRank(); - - nDV = config->GetnDV(); - - /*--- Loop through all design variables and their gradients ---*/ - - for (iDV = 0; iDV < nDV; iDV++){ - nDV_Value = config->GetnDV_Value(iDV); - if (rank == MASTER_NODE){ - - /*--- Print the kind of design variable on screen ---*/ - - cout << endl << "Design variable ("; - for (std::map::const_iterator it = Param_Map.begin(); it != Param_Map.end(); ++it ){ - if (it->second == config->GetDesign_Variable(iDV)){ - cout << it->first << ") number "<< iDV << "." << endl; - } - } - - /*--- Print the kind of objective function to screen ---*/ - - for (std::map::const_iterator it = Objective_Map.begin(); it != Objective_Map.end(); ++it ){ - if (it->second == config->GetKind_ObjFunc()){ - cout << it->first << " gradient : "; - if (iDV == 0) Gradient_file << it->first << " gradient " << endl; + + unsigned short nDV, iDV, iDV_Value, nDV_Value; + + int rank = SU2_MPI::GetRank(); + + nDV = config->GetnDV(); + + /*--- Loop through all design variables and their gradients ---*/ + + for (iDV = 0; iDV < nDV; iDV++){ + nDV_Value = config->GetnDV_Value(iDV); + if (rank == MASTER_NODE){ + + /*--- Print the kind of design variable on screen ---*/ + + cout << endl << "Design variable ("; + for (std::map::const_iterator it = Param_Map.begin(); it != Param_Map.end(); ++it ){ + if (it->second == config->GetDesign_Variable(iDV)){ + cout << it->first << ") number "<< iDV << "." << endl; + } + } + + /*--- Print the kind of objective function to screen ---*/ + + for (std::map::const_iterator it = Objective_Map.begin(); it != Objective_Map.end(); ++it ){ + if (it->second == config->GetKind_ObjFunc()){ + cout << it->first << " gradient : "; + if (iDV == 0) Gradient_file << it->first << " gradient " << endl; + } + } + + /*--- Print the gradient to file and screen ---*/ + + for (iDV_Value = 0; iDV_Value < nDV_Value; iDV_Value++){ + cout << Gradient[iDV][iDV_Value]; + if (iDV_Value != nDV_Value-1 ){ + cout << ", "; + } + Gradient_file << Gradient[iDV][iDV_Value] << endl; + } + cout << endl; + cout <<"-------------------------------------------------------------------------" << endl; } - } - - /*--- Print the gradient to file and screen ---*/ - - for (iDV_Value = 0; iDV_Value < nDV_Value; iDV_Value++){ - cout << Gradient[iDV][iDV_Value]; - if (iDV_Value != nDV_Value-1 ){ - cout << ", "; - } - Gradient_file << Gradient[iDV][iDV_Value] << endl; - } - cout << endl; - cout <<"-------------------------------------------------------------------------" << endl; } - } } void CDiscAdjDeformationDriver::SetSensitivity_Files(CGeometry ***geometry, CConfig **config, unsigned short val_nZone) { - - unsigned short iMarker,iDim, nDim, nMarker, nVar; - unsigned long iVertex, iPoint, nPoint, nVertex; - su2double *Normal, Prod, Sens = 0.0, SensDim, Area; - - unsigned short iZone; - - CSolver *solver = nullptr; - COutput *output = nullptr; - - for (iZone = 0; iZone < val_nZone; iZone++) { - - nPoint = geometry[iZone][INST_0]->GetnPoint(); - nDim = geometry[iZone][INST_0]->GetnDim(); - nMarker = config[iZone]->GetnMarker_All(); - nVar = nDim + 1; - - /*--- We create a baseline solver to easily merge the sensitivity information ---*/ - - vector fieldnames; - fieldnames.push_back("\"Point\""); - fieldnames.push_back("\"x\""); - fieldnames.push_back("\"y\""); - if (nDim == 3) { - fieldnames.push_back("\"z\""); - } - fieldnames.push_back("\"Sensitivity_x\""); - fieldnames.push_back("\"Sensitivity_y\""); - if (nDim == 3) { - fieldnames.push_back("\"Sensitivity_z\""); - } - fieldnames.push_back("\"Surface_Sensitivity\""); - - solver = new CBaselineSolver(geometry[iZone][INST_0], config[iZone], nVar+nDim, fieldnames); - - for (iPoint = 0; iPoint < nPoint; iPoint++) { - for (iDim = 0; iDim < nDim; iDim++) { - solver->GetNodes()->SetSolution(iPoint, iDim, geometry[iZone][INST_0]->nodes->GetCoord(iPoint, iDim)); - solver->GetNodes()->SetSolution(iPoint, iDim+nDim, geometry[iZone][INST_0]->GetSensitivity(iPoint, iDim)); - } - } - - /*--- Compute the sensitivity in normal direction ---*/ - - for (iMarker = 0; iMarker < nMarker; iMarker++) { - - if(config[iZone]->GetSolid_Wall(iMarker) || (config[iZone]->GetMarker_All_DV(iMarker) == YES )) { - - nVertex = geometry[iZone][INST_0]->GetnVertex(iMarker); - - for (iVertex = 0; iVertex < nVertex; iVertex++) { - iPoint = geometry[iZone][INST_0]->vertex[iMarker][iVertex]->GetNode(); - Normal = geometry[iZone][INST_0]->vertex[iMarker][iVertex]->GetNormal(); - Prod = 0.0; - Area = 0.0; - for (iDim = 0; iDim < nDim; iDim++) { - - /*--- Retrieve the gradient calculated with discrete adjoint method ---*/ - - SensDim = geometry[iZone][INST_0]->GetSensitivity(iPoint, iDim); - - /*--- Calculate scalar product for DiscAdjDeformation onto the normal vector ---*/ - - Prod += Normal[iDim]*SensDim; - - Area += Normal[iDim]*Normal[iDim]; - } - - Area = sqrt(Area); - - /*--- DiscAdjDeformation of the gradient onto the normal vector of the surface ---*/ - - Sens = Prod/Area; - - solver->GetNodes()->SetSolution(iPoint, 2*nDim, Sens); - + + unsigned short iMarker,iDim, nDim, nMarker, nVar; + unsigned long iVertex, iPoint, nPoint, nVertex; + su2double *Normal, Prod, Sens = 0.0, SensDim, Area; + + unsigned short iZone; + + CSolver *solver = nullptr; + COutput *output = nullptr; + + for (iZone = 0; iZone < val_nZone; iZone++) { + + nPoint = geometry[iZone][INST_0]->GetnPoint(); + nDim = geometry[iZone][INST_0]->GetnDim(); + nMarker = config[iZone]->GetnMarker_All(); + nVar = nDim + 1; + + /*--- We create a baseline solver to easily merge the sensitivity information ---*/ + + vector fieldnames; + fieldnames.push_back("\"Point\""); + fieldnames.push_back("\"x\""); + fieldnames.push_back("\"y\""); + if (nDim == 3) { + fieldnames.push_back("\"z\""); } - } - } - - output = new CBaselineOutput(config[iZone], nDim, solver); - output->PreprocessVolumeOutput(config[iZone]); - output->PreprocessHistoryOutput(config[iZone], false); - - /*--- Load the data --- */ - - output->Load_Data(geometry[iZone][INST_0], config[iZone], &solver); - - /*--- Set the surface filename ---*/ - - output->SetSurface_Filename(config[iZone]->GetSurfSens_FileName()); - - /*--- Set the volume filename ---*/ - - output->SetVolume_Filename(config[iZone]->GetVolSens_FileName()); - - /*--- Write to file ---*/ + fieldnames.push_back("\"Sensitivity_x\""); + fieldnames.push_back("\"Sensitivity_y\""); + if (nDim == 3) { + fieldnames.push_back("\"Sensitivity_z\""); + } + fieldnames.push_back("\"Surface_Sensitivity\""); + + solver = new CBaselineSolver(geometry[iZone][INST_0], config[iZone], nVar+nDim, fieldnames); + + for (iPoint = 0; iPoint < nPoint; iPoint++) { + for (iDim = 0; iDim < nDim; iDim++) { + solver->GetNodes()->SetSolution(iPoint, iDim, geometry[iZone][INST_0]->nodes->GetCoord(iPoint, iDim)); + solver->GetNodes()->SetSolution(iPoint, iDim+nDim, geometry[iZone][INST_0]->GetSensitivity(iPoint, iDim)); + } + } + + /*--- Compute the sensitivity in normal direction ---*/ + + for (iMarker = 0; iMarker < nMarker; iMarker++) { + + if(config[iZone]->GetSolid_Wall(iMarker) || (config[iZone]->GetMarker_All_DV(iMarker) == YES )) { + + nVertex = geometry[iZone][INST_0]->GetnVertex(iMarker); + + for (iVertex = 0; iVertex < nVertex; iVertex++) { + iPoint = geometry[iZone][INST_0]->vertex[iMarker][iVertex]->GetNode(); + Normal = geometry[iZone][INST_0]->vertex[iMarker][iVertex]->GetNormal(); + Prod = 0.0; + Area = 0.0; + for (iDim = 0; iDim < nDim; iDim++) { + + /*--- Retrieve the gradient calculated with discrete adjoint method ---*/ + + SensDim = geometry[iZone][INST_0]->GetSensitivity(iPoint, iDim); + + /*--- Calculate scalar product for projection onto the normal vector ---*/ + + Prod += Normal[iDim]*SensDim; + + Area += Normal[iDim]*Normal[iDim]; + } + + Area = sqrt(Area); + + /*--- Projection of the gradient onto the normal vector of the surface ---*/ + + Sens = Prod/Area; + + solver->GetNodes()->SetSolution(iPoint, 2*nDim, Sens); + + } + } + } + + output = new CBaselineOutput(config[iZone], nDim, solver); + output->PreprocessVolumeOutput(config[iZone]); + output->PreprocessHistoryOutput(config[iZone], false); + + /*--- Load the data --- */ + + output->Load_Data(geometry[iZone][INST_0], config[iZone], &solver); + + /*--- Set the surface filename ---*/ + + output->SetSurface_Filename(config[iZone]->GetSurfSens_FileName()); + + /*--- Set the volume filename ---*/ + + output->SetVolume_Filename(config[iZone]->GetVolSens_FileName()); + + /*--- Write to file ---*/ + + for (unsigned short iFile = 0; iFile < config[iZone]->GetnVolumeOutputFiles(); iFile++){ + auto FileFormat = config[iZone]->GetVolumeOutputFiles(); + if (FileFormat[iFile] != OUTPUT_TYPE::RESTART_ASCII && + FileFormat[iFile] != OUTPUT_TYPE::RESTART_BINARY && + FileFormat[iFile] != OUTPUT_TYPE::CSV) + output->WriteToFile(config[iZone], geometry[iZone][INST_0], FileFormat[iFile]); + } + + /*--- Free memory ---*/ + + delete output; + delete solver; + + } + +} - for (unsigned short iFile = 0; iFile < config[iZone]->GetnVolumeOutputFiles(); iFile++){ - auto FileFormat = config[iZone]->GetVolumeOutputFiles(); - if (FileFormat[iFile] != OUTPUT_TYPE::RESTART_ASCII && - FileFormat[iFile] != OUTPUT_TYPE::RESTART_BINARY && - FileFormat[iFile] != OUTPUT_TYPE::CSV) - output->WriteToFile(config[iZone], geometry[iZone][INST_0], FileFormat[iFile]); +void CDiscAdjDeformationDriver::DerivativeTreatment_MeshSensitivity(CGeometry *geometry, CConfig *config, CVolumetricMovement *grid_movement) { + + int rank = SU2_MPI::GetRank(); + + /*--- Warning if choosen smoothing mode is unsupported. + * This is the default option if the user has not specified a mode in the config file. ---*/ + if (config->GetSobMode() == ENUM_SOBOLEV_MODUS::NONE) { + SU2_MPI::Error("Unsupported operation modus for the Sobolev Smoothing Solver.", CURRENT_FUNCTION); + } + + /*-- Construct the smoothing solver and numerics ---*/ + std::unique_ptr solver(new CGradientSmoothingSolver(geometry, config)); + unsigned dim = (config->GetSmoothOnSurface() ? geometry->GetnDim() - 1 : geometry->GetnDim()); + std::unique_ptr numerics(new CGradSmoothing(dim, config)); + + if (rank == MASTER_NODE) cout << "Sobolev Smoothing of derivatives is active." << endl; + + /*--- Apply the smoothing procedure on the mesh level. ---*/ + if (config->GetSobMode() == ENUM_SOBOLEV_MODUS::MESH_LEVEL) { + if (rank == MASTER_NODE) cout << " working on mesh level" << endl; + + /*--- Work with the surface derivatives. ---*/ + if (config->GetSmoothOnSurface()) { + + /*--- Project to surface and then smooth on surface. ---*/ + grid_movement->SetVolume_Deformation(geometry, config, false, true); + + /*--- Get the sensitivities from the geometry class to work with. ---*/ + solver->ReadSensFromGeometry(geometry); + + /*--- Perform the smoothing procedure on all boundaries marked as DV marker. ---*/ + solver->ApplyGradientSmoothingSurface(geometry, numerics.get(), config); + + /*--- After appling the solver write the results back ---*/ + solver->WriteSensToGeometry(geometry); + + /*--- Work with the volume derivatives. ---*/ + } else { + + /*--- Get the sensitivities from the geometry class to work with. ---*/ + solver->ReadSensFromGeometry(geometry); + + solver->ApplyGradientSmoothingVolume(geometry, numerics.get(), config); + + /*--- After appling the solver write the results back ---*/ + solver->WriteSensToGeometry(geometry); + + /*--- Projection is applied after smoothing. ---*/ + grid_movement->SetVolume_Deformation(geometry, config, false, true); + } + } + +} - /*--- Free memory ---*/ - - delete output; - delete solver; - - } - +void CDiscAdjDeformationDriver::DerivativeTreatment_Gradient(CGeometry *geometry, CConfig *config, CVolumetricMovement* grid_movement, CSurfaceMovement *surface_movement, su2double** Gradient) { + + int rank = SU2_MPI::GetRank(); + + /*--- Error if choosen smoothing mode is unsupported. + * This is the default option if the user has not specified a mode in the config file. ---*/ + if (config->GetSobMode() == ENUM_SOBOLEV_MODUS::NONE) { + SU2_MPI::Error("Unsupported operation modus for the Sobolev Smoothing Solver.", CURRENT_FUNCTION); + } + + /*-- Construct the smoothing solver and numerics ---*/ + std::unique_ptr solver(new CGradientSmoothingSolver(geometry, config)); + unsigned dim = (config->GetSmoothOnSurface() ? geometry->GetnDim() - 1 : geometry->GetnDim()); + std::unique_ptr numerics(new CGradSmoothing(dim, config)); + + if (rank == MASTER_NODE) cout << "Sobolev Smoothing of derivatives is active." << endl; + + /*--- Get the sensitivities from the geometry class to work with. ---*/ + solver->ReadSensFromGeometry(geometry); + + /*--- Apply the smoothing procedure on the DV level. ---*/ + if (config->GetSobMode() == ENUM_SOBOLEV_MODUS::PARAM_LEVEL_COMPLETE) { + solver->ApplyGradientSmoothingDV(geometry, numerics.get(), surface_movement, grid_movement, config, Gradient); + + /*--- If smoothing already took place on the mesh level, or none is requested, just do standard projection. ---*/ + } else if (config->GetSobMode() == ENUM_SOBOLEV_MODUS::ONLY_GRAD || + config->GetSobMode() == ENUM_SOBOLEV_MODUS::MESH_LEVEL) { + solver->RecordTapeAndCalculateOriginalGradient(geometry, surface_movement, grid_movement, config, Gradient); + } + } diff --git a/SU2_DOT/include/SU2_DOT.hpp b/SU2_DOT/include/SU2_DOT.hpp index 857b1e18376..5fa74b3a533 100644 --- a/SU2_DOT/include/SU2_DOT.hpp +++ b/SU2_DOT/include/SU2_DOT.hpp @@ -26,7 +26,6 @@ * License along with SU2. If not, see . */ - #pragma once #define ENABLE_MAPS @@ -41,72 +40,6 @@ #include #include -#include "../../Common/include/geometry/CPhysicalGeometry.hpp" -#include "../../Common/include/fem/fem_geometry_structure.hpp" -#include "../../SU2_CFD/include/output/CBaselineOutput.hpp" -#include "../../SU2_CFD/include/solvers/CBaselineSolver.hpp" - -#include "../../SU2_CFD/include/solvers/CGradientSmoothingSolver.hpp" -#include "../../SU2_CFD/include/numerics/CGradSmoothing.hpp" +#include "../../SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp" using namespace std; - - -/*! - * \brief Projection of the surface sensitivity using finite differences (FD). - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] surface_movement - Surface movement class of the problem. - * \param[in] Gradient_file - Output file to store the gradient data. - */ - -void SetProjection_FD(CGeometry *geometry, CConfig *config, CSurfaceMovement *surface_movement, su2double **Gradient); - -/*! - * \brief Projection of the surface sensitivity using algorithmic differentiation (AD). - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] surface_movement - Surface movement class of the problem. - * \param[in] Gradient_file - Output file to store the gradient data. - */ - -void SetProjection_AD(CGeometry *geometry, CConfig *config, CSurfaceMovement *surface_movement, su2double **Gradient); - -/*! - * \brief Prints the gradient information to a file. - * \param[in] Gradient - The gradient data. - * \param[in] config - Definition of the particular problem. - * \param[in] Gradient_file - Output file to store the gradient data. - */ - -void OutputGradient(su2double** Gradient, CConfig* config, ofstream& Gradient_file); - -/*! - * \brief Write the sensitivity (including mesh sensitivity) computed with the discrete adjoint method - * on the surface and in the volume to a file. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] val_nZone - Number of Zones. - */ - -void SetSensitivity_Files(CGeometry ***geometry, CConfig **config, unsigned short val_nZone); - -/*! - * \brief Treatment of derivatives with the Sobolev smoothing solver. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] grid_movement - Volumetric movement class of the problem. - */ - -void DerivativeTreatment_MeshSensitivity(CGeometry *geometry, CConfig *config, CVolumetricMovement *grid_movement); - -/*! - * \brief Treatment of derivatives with the Sobolev smoothing solver. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] grid_movement - Volumetric movement class of the problem. - * \param[in] surface_movement - Surface movement class of the problem. - * \param[in] Gradient - Output array to store the gradient data. - */ - -void DerivativeTreatment_Gradient(CGeometry *geometry, CConfig *config, CVolumetricMovement *grid_movement, CSurfaceMovement *surface_movement, su2double **Gradient); diff --git a/SU2_DOT/src/SU2_DOT.cpp b/SU2_DOT/src/SU2_DOT.cpp index 077923ea359..c4632a3eac1 100644 --- a/SU2_DOT/src/SU2_DOT.cpp +++ b/SU2_DOT/src/SU2_DOT.cpp @@ -27,1030 +27,50 @@ #include "../include/SU2_DOT.hpp" + using namespace std; int main(int argc, char *argv[]) { - - unsigned short iZone, iInst; - su2double StartTime = 0.0, StopTime = 0.0, UsedTime = 0.0; - - char config_file_name[MAX_STRING_SIZE]; - - /*--- OpenMP initialization ---*/ - - omp_initialize(); - - /*--- MPI initialization, and buffer setting ---*/ - + + char config_file_name[MAX_STRING_SIZE]; + + /*--- Create a pointer to the main SU2_DEF Driver ---*/ + + CDiscAdjDeformationDriver* driver = nullptr; + + /*--- MPI initialization ---*/ + #if defined(HAVE_OMP) && defined(HAVE_MPI) - int provided; - SU2_MPI::Init_thread(&argc, &argv, MPI_THREAD_FUNNELED, &provided); + int provided; + SU2_MPI::Init_thread(&argc, &argv, MPI_THREAD_FUNNELED, &provided); #else - SU2_MPI::Init(&argc, &argv); -#endif - SU2_MPI::Comm MPICommunicator = SU2_MPI::GetComm(); - - const int rank = SU2_MPI::GetRank(); - const int size = SU2_MPI::GetSize(); - - /*--- AD initialization ---*/ -#ifdef HAVE_OPDI - AD::getGlobalTape().initialize(); -#endif - - /*--- Pointer to different structures that will be used throughout the entire code ---*/ - - CConfig **config_container = nullptr; - CConfig *driver_config = nullptr; - CGeometry ***geometry_container = nullptr; - CSurfaceMovement **surface_movement = nullptr; - CVolumetricMovement **grid_movement = nullptr; - unsigned short *nInst = nullptr; - - /*--- 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 = nullptr; - config = new CConfig(config_file_name, SU2_COMPONENT::SU2_DOT); - - const auto nZone = config->GetnZone(); - - /*--- Definition of the containers per zones ---*/ - - config_container = new CConfig*[nZone] (); - geometry_container = new CGeometry**[nZone] (); - surface_movement = new CSurfaceMovement*[nZone] (); - grid_movement = new CVolumetricMovement*[nZone] (); - - nInst = new unsigned short[nZone]; - driver_config = nullptr; - - for (iZone = 0; iZone < nZone; iZone++) { - nInst[iZone] = 1; - } - - /*--- Initialize the configuration of the driver ---*/ - driver_config = new CConfig(config_file_name, SU2_COMPONENT::SU2_DOT, false); - - /*--- Initialize a char to store the zone filename ---*/ - char zone_file_name[MAX_STRING_SIZE]; - - /*--- 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. ---*/ - - if (driver_config->GetnConfigFiles() > 0){ - strcpy(zone_file_name, driver_config->GetConfigFilename(iZone).c_str()); - config_container[iZone] = new CConfig(driver_config, zone_file_name, SU2_COMPONENT::SU2_DOT, iZone, nZone, true); - } - else{ - config_container[iZone] = new CConfig(driver_config, config_file_name, SU2_COMPONENT::SU2_DOT, iZone, nZone, true); - } - config_container[iZone]->SetMPICommunicator(MPICommunicator); - - } - - /*--- Set the multizone part of the problem. ---*/ - if (driver_config->GetMultizone_Problem()){ - for (iZone = 0; iZone < nZone; iZone++) { - /*--- Set the interface markers for multizone ---*/ - config_container[iZone]->SetMultizone(driver_config, config_container); - } - } - - /*--- 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++) { - - /*--- Determine whether or not the FEM solver is used, which decides the - type of geometry classes that are instantiated. ---*/ - const bool fem_solver = config_container[iZone]->GetFEMSolver(); - - /*--- Read the number of instances for each zone ---*/ - - nInst[iZone] = config_container[iZone]->GetnTimeInstances(); - - geometry_container[iZone] = new CGeometry*[nInst[iZone]]; - - for (iInst = 0; iInst < nInst[iZone]; iInst++){ - - /*--- Definition of the geometry class to store the primal grid in the partitioning process. ---*/ - - CGeometry *geometry_aux = nullptr; - - /*--- 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) ---*/ - - if ( fem_solver ) geometry_aux->SetColorFEMGrid_Parallel(config_container[iZone]); - else geometry_aux->SetColorGrid_Parallel(config_container[iZone]); - - /*--- Build the grid data structures using the ParMETIS coloring. ---*/ - - if( fem_solver ) { - switch( config_container[iZone]->GetKind_FEM_Flow() ) { - case DG: { - geometry_container[iZone][iInst] = new CMeshFEM_DG(geometry_aux, config_container[iZone]); - break; - } - } - } - else { - geometry_container[iZone][iInst] = new CPhysicalGeometry(geometry_aux, config_container[iZone]); - } - - /*--- Deallocate the memory of geometry_aux ---*/ - - delete geometry_aux; - - /*--- Add the Send/Receive boundaries ---*/ - - geometry_container[iZone][iInst]->SetSendReceive(config_container[iZone]); - - /*--- Add the Send/Receive boundaries ---*/ - - geometry_container[iZone][iInst]->SetBoundaries(config_container[iZone]); - - /*--- Create the vertex structure (required for MPI) ---*/ - - if (rank == MASTER_NODE) cout << "Identify vertices." << endl; - geometry_container[iZone][iInst]->SetVertex(config_container[iZone]); - - /*--- Store the global to local mapping after preprocessing. ---*/ - - if (rank == MASTER_NODE) cout << "Storing a mapping from global to local point index." << endl; - geometry_container[iZone][iInst]->SetGlobal_to_Local_Point(); - - /* Test for a fem solver, because some more work must be done. */ - - if (fem_solver) { - - /*--- Carry out a dynamic cast to CMeshFEM_DG, such that it is not needed to - define all virtual functions in the base class CGeometry. ---*/ - CMeshFEM_DG *DGMesh = dynamic_cast(geometry_container[iZone][iInst]); - - /*--- Determine the standard elements for the volume elements. ---*/ - if (rank == MASTER_NODE) cout << "Creating standard volume elements." << endl; - DGMesh->CreateStandardVolumeElements(config_container[iZone]); - - /*--- Create the face information needed to compute the contour integral - for the elements in the Discontinuous Galerkin formulation. ---*/ - if (rank == MASTER_NODE) cout << "Creating face information." << endl; - DGMesh->CreateFaces(config_container[iZone]); - } - } - } - - /*--- Set up a timer for performance benchmarking (preprocessing time is included) ---*/ - - StartTime = SU2_MPI::Wtime(); - - for (iZone = 0; iZone < nZone; iZone++) { - - if (rank == MASTER_NODE) - cout << "\n----------------------- Preprocessing computations ----------------------" << endl; - - /*--- Compute elements surrounding points, points surrounding points ---*/ - - if (rank == MASTER_NODE) cout << "Setting local point connectivity." << endl; - geometry_container[iZone][INST_0]->SetPoint_Connectivity(); - - /*--- Check the orientation before computing geometrical quantities ---*/ - - geometry_container[iZone][INST_0]->SetBoundVolume(); - if (config_container[iZone]->GetReorientElements()) { - if (rank == MASTER_NODE) cout << "Checking the numerical grid orientation of the elements." << endl; - geometry_container[iZone][INST_0]->Check_IntElem_Orientation(config_container[iZone]); - geometry_container[iZone][INST_0]->Check_BoundElem_Orientation(config_container[iZone]); - } - - /*--- Create the edge structure ---*/ - - if (rank == MASTER_NODE) cout << "Identify edges and vertices." << endl; - geometry_container[iZone][INST_0]->SetEdges(); geometry_container[iZone][INST_0]->SetVertex(config_container[iZone]); - - /*--- Create the dual control volume structures ---*/ - - if (rank == MASTER_NODE) cout << "Setting the bound control volume structure." << endl; - geometry_container[iZone][INST_0]->SetBoundControlVolume(config_container[ZONE_0], ALLOCATE); - - /*--- Store the global to local mapping after preprocessing. ---*/ - - if (rank == MASTER_NODE) cout << "Storing a mapping from global to local point index." << endl; - geometry_container[iZone][INST_0]->SetGlobal_to_Local_Point(); - - /*--- Create the point-to-point MPI communication structures. ---*/ - - geometry_container[iZone][INST_0]->PreprocessP2PComms(geometry_container[iZone][INST_0], config_container[iZone]); - - /*--- 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 (!config_container[iZone]->GetDiscrete_Adjoint()) { - if (rank == MASTER_NODE) cout << "Reading surface sensitivities at each node from file." << endl; - geometry_container[iZone][INST_0]->SetBoundSensitivity(config_container[iZone]); - } - else { - if (rank == MASTER_NODE) cout << "Reading volume sensitivities at each node from file." << endl; - grid_movement[iZone] = new CVolumetricMovement(geometry_container[iZone][INST_0], config_container[iZone]); - - /*--- Read in sensitivities from file. ---*/ - if (config_container[ZONE_0]->GetSensitivity_Format() == UNORDERED_ASCII) - geometry_container[iZone][INST_0]->ReadUnorderedSensitivity(config_container[iZone]); - else - geometry_container[iZone][INST_0]->SetSensitivity(config_container[iZone]); - - if (rank == MASTER_NODE) - cout << "\n---------------------- Mesh sensitivity computation ---------------------" << endl; - - if(config_container[iZone]->GetDiscrete_Adjoint() && config_container[iZone]->GetSmoothGradient() && - config_container[iZone]->GetSobMode() == ENUM_SOBOLEV_MODUS::MESH_LEVEL) { - DerivativeTreatment_MeshSensitivity(geometry_container[iZone][INST_0], config_container[iZone], grid_movement[iZone]); - } else { - grid_movement[iZone]->SetVolume_Deformation(geometry_container[iZone][INST_0], config_container[iZone], false, true); - } - - } - } - - - if (config_container[ZONE_0]->GetDiscrete_Adjoint()) { - if (rank == MASTER_NODE) - cout << "\n------------------------ Mesh sensitivity Output ------------------------" << endl; - SetSensitivity_Files(geometry_container, config_container, nZone); - } - - /*--- Initialize structure to store the gradient ---*/ - su2double** Gradient = new su2double*[config_container[ZONE_0]->GetnDV()]; - - for (auto iDV = 0u; iDV < config_container[ZONE_0]->GetnDV(); iDV++) { - /*--- Initialize to zero ---*/ - Gradient[iDV] = new su2double[config_container[ZONE_0]->GetnDV_Value(iDV)](); - } - - ofstream Gradient_file; - Gradient_file.precision(config->OptionIsSet("OUTPUT_PRECISION") ? config->GetOutput_Precision() : 6); - - /*--- For multizone computations the gradient contributions are summed up and written into one file. ---*/ - for (iZone = 0; iZone < nZone; iZone++){ - if ((config_container[iZone]->GetDesign_Variable(0) != NONE) && - (config_container[iZone]->GetDesign_Variable(0) != SURFACE_FILE)) { - - if (rank == MASTER_NODE) - cout << "\n---------- Start gradient evaluation using sensitivity information ----------" << endl; - - /*--- Definition of the Class for surface deformation ---*/ - - surface_movement[iZone] = new CSurfaceMovement(); - - /*--- Copy coordinates to the surface structure ---*/ - - surface_movement[iZone]->CopyBoundary(geometry_container[iZone][INST_0], config_container[iZone]); - - /*--- If AD mode is enabled we can use it to compute the projection, - * otherwise we use finite differences. ---*/ - - if (config_container[iZone]->GetAD_Mode()) { - if (config_container[iZone]->GetSmoothGradient()) { - DerivativeTreatment_Gradient(geometry_container[iZone][INST_0], config_container[iZone], grid_movement[iZone], surface_movement[iZone] , Gradient); - } else { - SetProjection_AD(geometry_container[iZone][INST_0], config_container[iZone], surface_movement[iZone] , Gradient); - } - } else { - SetProjection_FD(geometry_container[iZone][INST_0], config_container[iZone], surface_movement[iZone] , Gradient); - } - } - } // for iZone - - /*--- Write the gradient to a file ---*/ - - if (rank == MASTER_NODE) - Gradient_file.open(config_container[ZONE_0]->GetObjFunc_Grad_FileName().c_str(), ios::out); - - /*--- Print gradients to screen and writes to file ---*/ - - OutputGradient(Gradient, config_container[ZONE_0], Gradient_file); - - for (auto iDV = 0u; iDV < config_container[ZONE_0]->GetnDV(); iDV++){ - delete [] Gradient[iDV]; - } - delete [] Gradient; - - delete config; - config = nullptr; - - if (rank == MASTER_NODE) - cout << "\n------------------------- Solver Postprocessing -------------------------" << endl; - - if (geometry_container != nullptr) { - for (iZone = 0; iZone < nZone; iZone++) { - if (geometry_container[iZone] != nullptr) { - for (iInst = 0; iInst < nInst[iZone]; iInst++){ - if (geometry_container[iZone][iInst] != nullptr) { - delete geometry_container[iZone][iInst]; - } - } - delete geometry_container[iZone]; - } - } - delete [] geometry_container; - } - if (rank == MASTER_NODE) cout << "Deleted CGeometry container." << endl; - - if (surface_movement != nullptr) { - for (iZone = 0; iZone < nZone; iZone++) { - if (surface_movement[iZone] != nullptr) { - delete surface_movement[iZone]; - } - } - delete [] surface_movement; - } - if (rank == MASTER_NODE) cout << "Deleted CSurfaceMovement class." << endl; - - if (grid_movement != nullptr) { - for (iZone = 0; iZone < nZone; iZone++) { - if (grid_movement[iZone] != nullptr) { - delete grid_movement[iZone]; - } - } - delete [] grid_movement; - } - if (rank == MASTER_NODE) cout << "Deleted CVolumetricMovement class." << endl; - - delete config; - config = nullptr; - if (config_container != nullptr) { - for (iZone = 0; iZone < nZone; iZone++) { - if (config_container[iZone] != nullptr) { - delete config_container[iZone]; - } - } - delete [] config_container; - } - if (rank == MASTER_NODE) cout << "Deleted CConfig container." << endl; - - /*--- Synchronization point after a single solver iteration. Compute the - wall clock time required. ---*/ - - StopTime = SU2_MPI::Wtime(); - - /*--- 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 ---*/ - - if (rank == MASTER_NODE) - cout << "\n------------------------- Exit Success (SU2_DOT) ------------------------\n" << endl; - - /*--- Finalize AD, if necessary. ---*/ -#ifdef HAVE_OPDI - AD::getGlobalTape().finalize(); + SU2_MPI::Init(&argc, &argv); #endif - - /*--- Finalize MPI parallelization. ---*/ - SU2_MPI::Finalize(); - - /*--- Finalize OpenMP. ---*/ - omp_finalize(); - - return EXIT_SUCCESS; - -} - -void SetProjection_FD(CGeometry *geometry, CConfig *config, CSurfaceMovement *surface_movement, su2double** Gradient){ - - unsigned short iDV, nDV, iFFDBox, nDV_Value, iMarker, iDim; - unsigned long iVertex, iPoint; - su2double delta_eps, my_Gradient, localGradient, *Normal, dS, *VarCoord, Sensitivity, - dalpha[3], deps[3], dalpha_deps; - bool *UpdatePoint, MoveSurface, Local_MoveSurface; - CFreeFormDefBox **FFDBox; - - int rank = SU2_MPI::GetRank(); - - nDV = config->GetnDV(); - - /*--- Boolean controlling points to be updated ---*/ - - UpdatePoint = new bool[geometry->GetnPoint()]; - - /*--- Definition of the FFD deformation class ---*/ - - unsigned short nFFDBox = MAX_NUMBER_FFD; - FFDBox = new CFreeFormDefBox*[nFFDBox]; - for (iFFDBox = 0; iFFDBox < MAX_NUMBER_FFD; iFFDBox++) FFDBox[iFFDBox] = nullptr; - - for (iDV = 0; iDV < nDV; iDV++){ - nDV_Value = config->GetnDV_Value(iDV); - if (nDV_Value != 1){ - SU2_MPI::Error("The projection using finite differences currently only supports a fixed direction of movement for FFD points.", CURRENT_FUNCTION); - } - } - - /*--- Continuous adjoint gradient computation ---*/ - - if (rank == MASTER_NODE) - cout << "Evaluate functional gradient using Finite Differences." << endl; - - for (iDV = 0; iDV < nDV; iDV++) { - - MoveSurface = true; - Local_MoveSurface = true; - - /*--- 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_TWIST_2D) || - (config->GetDesign_Variable(iDV) == FFD_CONTROL_POINT) || - (config->GetDesign_Variable(iDV) == FFD_NACELLE) || - (config->GetDesign_Variable(iDV) == FFD_GULL) || - (config->GetDesign_Variable(iDV) == FFD_TWIST) || - (config->GetDesign_Variable(iDV) == FFD_ROTATION) || - (config->GetDesign_Variable(iDV) == FFD_CAMBER) || - (config->GetDesign_Variable(iDV) == FFD_THICKNESS) || - (config->GetDesign_Variable(iDV) == FFD_ANGLE_OF_ATTACK)) { - - /*--- 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_movement->ReadFFDInfo(geometry, config, FFDBox, config->GetMesh_FileName()); - - /*--- If the FFDBox was not defined in the input file ---*/ - if (!surface_movement->GetFFDBoxDefinition()) { - SU2_MPI::Error("The input grid doesn't have the entire FFD information!", CURRENT_FUNCTION); - } - - for (iFFDBox = 0; iFFDBox < surface_movement->GetnFFDBox(); iFFDBox++) { - - if (rank == MASTER_NODE) cout << "Checking FFD box dimension." << endl; - surface_movement->CheckFFDDimension(geometry, config, FFDBox[iFFDBox], iFFDBox); - - if (rank == MASTER_NODE) cout << "Check the FFD box intersections with the solid surfaces." << endl; - surface_movement->CheckFFDIntersections(geometry, config, FFDBox[iFFDBox], iFFDBox); - - } - - if (rank == MASTER_NODE) - cout <<"-------------------------------------------------------------------------" << endl; - - } - - if (rank == MASTER_NODE) { - cout << endl << "Design variable number "<< iDV <<"." << endl; - cout << "Performing 3D deformation of the surface." << endl; - } - - /*--- Apply the control point change ---*/ - - MoveSurface = false; - - for (iFFDBox = 0; iFFDBox < surface_movement->GetnFFDBox(); iFFDBox++) { - - /*--- Reset FFD box ---*/ - - switch (config->GetDesign_Variable(iDV) ) { - case FFD_CONTROL_POINT_2D : Local_MoveSurface = surface_movement->SetFFDCPChange_2D(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; - case FFD_CAMBER_2D : Local_MoveSurface = surface_movement->SetFFDCamber_2D(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; - case FFD_THICKNESS_2D : Local_MoveSurface = surface_movement->SetFFDThickness_2D(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; - case FFD_TWIST_2D : Local_MoveSurface = surface_movement->SetFFDTwist_2D(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; - case FFD_CONTROL_POINT : Local_MoveSurface = surface_movement->SetFFDCPChange(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; - case FFD_NACELLE : Local_MoveSurface = surface_movement->SetFFDNacelle(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; - case FFD_GULL : Local_MoveSurface = surface_movement->SetFFDGull(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; - case FFD_TWIST : Local_MoveSurface = surface_movement->SetFFDTwist(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; - case FFD_ROTATION : Local_MoveSurface = surface_movement->SetFFDRotation(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; - case FFD_CAMBER : Local_MoveSurface = surface_movement->SetFFDCamber(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; - case FFD_THICKNESS : Local_MoveSurface = surface_movement->SetFFDThickness(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; - case FFD_CONTROL_SURFACE : Local_MoveSurface = surface_movement->SetFFDControl_Surface(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; - case FFD_ANGLE_OF_ATTACK : Gradient[iDV][0] = config->GetAoA_Sens(); break; - } - - /*--- Recompute cartesian coordinates using the new control points position ---*/ - - if (Local_MoveSurface) { - MoveSurface = true; - surface_movement->SetCartesianCoord(geometry, config, FFDBox[iFFDBox], iFFDBox, true); - } - - } - - } - - /*--- Hicks Henne design variable ---*/ - - else if (config->GetDesign_Variable(iDV) == HICKS_HENNE) { - surface_movement->SetHicksHenne(geometry, config, iDV, true); - } - - /*--- Surface bump design variable ---*/ - - else if (config->GetDesign_Variable(iDV) == SURFACE_BUMP) { - surface_movement->SetSurface_Bump(geometry, config, iDV, true); - } - - /*--- Kulfan (CST) design variable ---*/ - - else if (config->GetDesign_Variable(iDV) == CST) { - surface_movement->SetCST(geometry, config, iDV, true); - } - - /*--- Displacement design variable ---*/ - - else if (config->GetDesign_Variable(iDV) == TRANSLATION) { - surface_movement->SetTranslation(geometry, config, iDV, true); - } - - /*--- Angle of Attack design variable ---*/ - - else if (config->GetDesign_Variable(iDV) == ANGLE_OF_ATTACK) { - Gradient[iDV][0] = config->GetAoA_Sens(); - } - - /*--- Scale design variable ---*/ - - else if (config->GetDesign_Variable(iDV) == SCALE) { - surface_movement->SetScale(geometry, config, iDV, true); - } - - /*--- Rotation design variable ---*/ - - else if (config->GetDesign_Variable(iDV) == ROTATION) { - surface_movement->SetRotation(geometry, config, iDV, true); - } - - /*--- NACA_4Digits design variable ---*/ - - else if (config->GetDesign_Variable(iDV) == NACA_4DIGITS) { - surface_movement->SetNACA_4Digits(geometry, config); - } - - /*--- Parabolic design variable ---*/ - - else if (config->GetDesign_Variable(iDV) == PARABOLIC) { - surface_movement->SetParabolic(geometry, config); - } - - /*--- Design variable not implemented ---*/ - - else { - if (rank == MASTER_NODE) - cout << "Design Variable not implemented yet" << endl; - } - - /*--- Load the delta change in the design variable (finite difference step). ---*/ - - if ((config->GetDesign_Variable(iDV) != ANGLE_OF_ATTACK) && - (config->GetDesign_Variable(iDV) != FFD_ANGLE_OF_ATTACK)) { - - /*--- If the Angle of attack is not involved, reset the value of the gradient ---*/ - - my_Gradient = 0.0; Gradient[iDV][0] = 0.0; - - if (MoveSurface) { - - delta_eps = config->GetDV_Value(iDV); - - for (iPoint = 0; iPoint < geometry->GetnPoint(); iPoint++) - UpdatePoint[iPoint] = true; - - for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { - if (config->GetMarker_All_DV(iMarker) == YES) { - for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - - iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); - if ((iPoint < geometry->GetnPointDomain()) && UpdatePoint[iPoint]) { - - Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); - VarCoord = geometry->vertex[iMarker][iVertex]->GetVarCoord(); - Sensitivity = geometry->vertex[iMarker][iVertex]->GetAuxVar(); - - dS = 0.0; - for (iDim = 0; iDim < geometry->GetnDim(); iDim++) { - dS += Normal[iDim]*Normal[iDim]; - deps[iDim] = VarCoord[iDim] / delta_eps; - } - dS = sqrt(dS); - - dalpha_deps = 0.0; - for (iDim = 0; iDim < geometry->GetnDim(); iDim++) { - dalpha[iDim] = Normal[iDim] / dS; - dalpha_deps -= dalpha[iDim]*deps[iDim]; - } - - my_Gradient += Sensitivity*dalpha_deps; - UpdatePoint[iPoint] = false; - } - } - } - } - } - - SU2_MPI::Allreduce(&my_Gradient, &localGradient, 1, MPI_DOUBLE, MPI_SUM, SU2_MPI::GetComm()); - Gradient[iDV][0] += localGradient; - } - } - - /*--- Delete memory for parameterization. ---*/ - - if (FFDBox != nullptr) { - for (iFFDBox = 0; iFFDBox < MAX_NUMBER_FFD; iFFDBox++) { - if (FFDBox[iFFDBox] != nullptr) { - delete FFDBox[iFFDBox]; - } - } - delete [] FFDBox; - } - - delete [] UpdatePoint; - -} - - -void SetProjection_AD(CGeometry *geometry, CConfig *config, CSurfaceMovement *surface_movement, su2double** Gradient){ - - su2double *VarCoord = nullptr, Sensitivity, my_Gradient, localGradient, *Normal, Area = 0.0; - unsigned short iDV_Value = 0, iMarker, nMarker, iDim, nDim, iDV, nDV; - unsigned long iVertex, nVertex, iPoint; - - const int rank = SU2_MPI::GetRank(); - - nMarker = config->GetnMarker_All(); - nDim = geometry->GetnDim(); - nDV = config->GetnDV(); - - /*--- Discrete adjoint gradient computation ---*/ - - if (rank == MASTER_NODE) - cout << endl << "Evaluate functional gradient using Algorithmic Differentiation (ZONE " << config->GetiZone() << ")." << endl; - - /*--- Start recording of operations ---*/ - - AD::StartRecording(); - - /*--- Register design variables as input and set them to zero - * (since we want to have the derivative at alpha = 0, i.e. for the current design) ---*/ - - for (iDV = 0; iDV < nDV; iDV++){ - - for (iDV_Value = 0; iDV_Value < config->GetnDV_Value(iDV); iDV_Value++){ - - config->SetDV_Value(iDV, iDV_Value, 0.0); - - AD::RegisterInput(config->GetDV_Value(iDV, iDV_Value)); - } - } - - /*--- Call the surface deformation routine ---*/ - - surface_movement->SetSurface_Deformation(geometry, config); - - /*--- Stop the recording --- */ - - AD::StopRecording(); - - /*--- Create a structure to identify points that have been already visited. - * We need that to make sure to set the sensitivity of surface points only once - * (Markers share points, so we would visit them more than once in the loop over the markers below) ---*/ - - vector visited(geometry->GetnPoint(), false); - - /*--- Initialize the derivatives of the output of the surface deformation routine - * with the discrete adjoints from the CFD solution ---*/ - - for (iMarker = 0; iMarker < nMarker; iMarker++) { - if (config->GetMarker_All_DV(iMarker) == YES) { - nVertex = geometry->nVertex[iMarker]; - for (iVertex = 0; iVertex vertex[iMarker][iVertex]->GetNode(); - if (!visited[iPoint]){ - VarCoord = geometry->vertex[iMarker][iVertex]->GetVarCoord(); - Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); - - Area = 0.0; - for (iDim = 0; iDim < nDim; iDim++){ - Area += Normal[iDim]*Normal[iDim]; - } - Area = sqrt(Area); - - for (iDim = 0; iDim < nDim; iDim++){ - if (config->GetDiscrete_Adjoint()){ - Sensitivity = geometry->GetSensitivity(iPoint, iDim); - } else { - Sensitivity = -Normal[iDim]*geometry->vertex[iMarker][iVertex]->GetAuxVar()/Area; - } - SU2_TYPE::SetDerivative(VarCoord[iDim], SU2_TYPE::GetValue(Sensitivity)); - } - visited[iPoint] = true; - } - } - } - } - - /*--- Compute derivatives and extract gradient ---*/ - - AD::ComputeAdjoint(); - - for (iDV = 0; iDV < nDV; iDV++){ - - for (iDV_Value = 0; iDV_Value < config->GetnDV_Value(iDV); iDV_Value++){ - - my_Gradient = SU2_TYPE::GetDerivative(config->GetDV_Value(iDV, iDV_Value)); - - SU2_MPI::Allreduce(&my_Gradient, &localGradient, 1, MPI_DOUBLE, MPI_SUM, SU2_MPI::GetComm()); - - /*--- Angle of Attack design variable (this is different, - the value comes form the input file) ---*/ - - if ((config->GetDesign_Variable(iDV) == ANGLE_OF_ATTACK) || - (config->GetDesign_Variable(iDV) == FFD_ANGLE_OF_ATTACK)) { - Gradient[iDV][iDV_Value] = config->GetAoA_Sens(); - } - - Gradient[iDV][iDV_Value] += localGradient; - } - } - - AD::Reset(); - -} - -void OutputGradient(su2double** Gradient, CConfig* config, ofstream& Gradient_file){ - - unsigned short nDV, iDV, iDV_Value, nDV_Value; - - int rank = SU2_MPI::GetRank(); - - nDV = config->GetnDV(); - - /*--- Loop through all design variables and their gradients ---*/ - - for (iDV = 0; iDV < nDV; iDV++){ - nDV_Value = config->GetnDV_Value(iDV); - if (rank == MASTER_NODE){ - - /*--- Print the kind of design variable on screen ---*/ - - cout << endl << "Design variable ("; - for (std::map::const_iterator it = Param_Map.begin(); it != Param_Map.end(); ++it ){ - if (it->second == config->GetDesign_Variable(iDV)){ - cout << it->first << ") number "<< iDV << "." << endl; - } - } - - /*--- Print the kind of objective function to screen ---*/ - - for (std::map::const_iterator it = Objective_Map.begin(); it != Objective_Map.end(); ++it ){ - if (it->second == config->GetKind_ObjFunc()){ - cout << it->first << " gradient : "; - if (iDV == 0) Gradient_file << it->first << " gradient " << endl; - } - } - - /*--- Print the gradient to file and screen ---*/ - - for (iDV_Value = 0; iDV_Value < nDV_Value; iDV_Value++){ - cout << Gradient[iDV][iDV_Value]; - if (iDV_Value != nDV_Value-1 ){ - cout << ", "; - } - Gradient_file << Gradient[iDV][iDV_Value] << endl; - } - cout << endl; - cout <<"-------------------------------------------------------------------------" << endl; - } - } -} - - -void SetSensitivity_Files(CGeometry ***geometry, CConfig **config, unsigned short val_nZone) { - - unsigned short iMarker,iDim, nDim, nMarker, nVar; - unsigned long iVertex, iPoint, nPoint, nVertex; - su2double *Normal, Prod, Sens = 0.0, SensDim, Area; - - unsigned short iZone; - - CSolver *solver = nullptr; - COutput *output = nullptr; - - for (iZone = 0; iZone < val_nZone; iZone++) { - - nPoint = geometry[iZone][INST_0]->GetnPoint(); - nDim = geometry[iZone][INST_0]->GetnDim(); - nMarker = config[iZone]->GetnMarker_All(); - nVar = nDim + 1; - - /*--- We create a baseline solver to easily merge the sensitivity information ---*/ - - vector fieldnames; - fieldnames.push_back("\"Point\""); - fieldnames.push_back("\"x\""); - fieldnames.push_back("\"y\""); - if (nDim == 3) { - fieldnames.push_back("\"z\""); - } - fieldnames.push_back("\"Sensitivity_x\""); - fieldnames.push_back("\"Sensitivity_y\""); - if (nDim == 3) { - fieldnames.push_back("\"Sensitivity_z\""); - } - fieldnames.push_back("\"Surface_Sensitivity\""); - - solver = new CBaselineSolver(geometry[iZone][INST_0], config[iZone], nVar+nDim, fieldnames); - - for (iPoint = 0; iPoint < nPoint; iPoint++) { - for (iDim = 0; iDim < nDim; iDim++) { - solver->GetNodes()->SetSolution(iPoint, iDim, geometry[iZone][INST_0]->nodes->GetCoord(iPoint, iDim)); - solver->GetNodes()->SetSolution(iPoint, iDim+nDim, geometry[iZone][INST_0]->GetSensitivity(iPoint, iDim)); - } - } - - /*--- Compute the sensitivity in normal direction ---*/ - - for (iMarker = 0; iMarker < nMarker; iMarker++) { - - if(config[iZone]->GetSolid_Wall(iMarker) || (config[iZone]->GetMarker_All_DV(iMarker) == YES )) { - - nVertex = geometry[iZone][INST_0]->GetnVertex(iMarker); - - for (iVertex = 0; iVertex < nVertex; iVertex++) { - iPoint = geometry[iZone][INST_0]->vertex[iMarker][iVertex]->GetNode(); - Normal = geometry[iZone][INST_0]->vertex[iMarker][iVertex]->GetNormal(); - Prod = 0.0; - Area = 0.0; - for (iDim = 0; iDim < nDim; iDim++) { - - /*--- Retrieve the gradient calculated with discrete adjoint method ---*/ - - SensDim = geometry[iZone][INST_0]->GetSensitivity(iPoint, iDim); - - /*--- Calculate scalar product for projection onto the normal vector ---*/ - - Prod += Normal[iDim]*SensDim; - - Area += Normal[iDim]*Normal[iDim]; - } - - Area = sqrt(Area); - - /*--- Projection of the gradient onto the normal vector of the surface ---*/ - - Sens = Prod/Area; - - solver->GetNodes()->SetSolution(iPoint, 2*nDim, Sens); - - } - } - } - - output = new CBaselineOutput(config[iZone], nDim, solver); - output->PreprocessVolumeOutput(config[iZone]); - output->PreprocessHistoryOutput(config[iZone], false); - - /*--- Load the data --- */ - - output->Load_Data(geometry[iZone][INST_0], config[iZone], &solver); - - /*--- Set the surface filename ---*/ - - output->SetSurface_Filename(config[iZone]->GetSurfSens_FileName()); - - /*--- Set the volume filename ---*/ - - output->SetVolume_Filename(config[iZone]->GetVolSens_FileName()); - - /*--- Write to file ---*/ - - for (unsigned short iFile = 0; iFile < config[iZone]->GetnVolumeOutputFiles(); iFile++){ - auto FileFormat = config[iZone]->GetVolumeOutputFiles(); - if (FileFormat[iFile] != OUTPUT_TYPE::RESTART_ASCII && - FileFormat[iFile] != OUTPUT_TYPE::RESTART_BINARY && - FileFormat[iFile] != OUTPUT_TYPE::CSV) - output->WriteToFile(config[iZone], geometry[iZone][INST_0], FileFormat[iFile]); - } - - /*--- Free memory ---*/ - - delete output; - delete solver; - - } - -} - -void DerivativeTreatment_MeshSensitivity(CGeometry *geometry, CConfig *config, CVolumetricMovement *grid_movement) { - - int rank = SU2_MPI::GetRank(); - - /*--- Warning if choosen smoothing mode is unsupported. - * This is the default option if the user has not specified a mode in the config file. ---*/ - if (config->GetSobMode() == ENUM_SOBOLEV_MODUS::NONE) { - SU2_MPI::Error("Unsupported operation modus for the Sobolev Smoothing Solver.", CURRENT_FUNCTION); - } - - /*-- Construct the smoothing solver and numerics ---*/ - std::unique_ptr solver(new CGradientSmoothingSolver(geometry, config)); - unsigned dim = (config->GetSmoothOnSurface() ? geometry->GetnDim() - 1 : geometry->GetnDim()); - std::unique_ptr numerics(new CGradSmoothing(dim, config)); - - if (rank == MASTER_NODE) cout << "Sobolev Smoothing of derivatives is active." << endl; - - /*--- Apply the smoothing procedure on the mesh level. ---*/ - if (config->GetSobMode() == ENUM_SOBOLEV_MODUS::MESH_LEVEL) { - if (rank == MASTER_NODE) cout << " working on mesh level" << endl; - - /*--- Work with the surface derivatives. ---*/ - if (config->GetSmoothOnSurface()) { - - /*--- Project to surface and then smooth on surface. ---*/ - grid_movement->SetVolume_Deformation(geometry, config, false, true); - - /*--- Get the sensitivities from the geometry class to work with. ---*/ - solver->ReadSensFromGeometry(geometry); - - /*--- Perform the smoothing procedure on all boundaries marked as DV marker. ---*/ - solver->ApplyGradientSmoothingSurface(geometry, numerics.get(), config); - - /*--- After appling the solver write the results back ---*/ - solver->WriteSensToGeometry(geometry); - - /*--- Work with the volume derivatives. ---*/ - } else { - - /*--- Get the sensitivities from the geometry class to work with. ---*/ - solver->ReadSensFromGeometry(geometry); - - solver->ApplyGradientSmoothingVolume(geometry, numerics.get(), config); - - /*--- After appling the solver write the results back ---*/ - solver->WriteSensToGeometry(geometry); - - /*--- Projection is applied after smoothing. ---*/ - grid_movement->SetVolume_Deformation(geometry, config, false, true); - } - - } - -} - -void DerivativeTreatment_Gradient(CGeometry *geometry, CConfig *config, CVolumetricMovement* grid_movement, CSurfaceMovement *surface_movement, su2double** Gradient) { - - int rank = SU2_MPI::GetRank(); - - /*--- Error if choosen smoothing mode is unsupported. - * This is the default option if the user has not specified a mode in the config file. ---*/ - if (config->GetSobMode() == ENUM_SOBOLEV_MODUS::NONE) { - SU2_MPI::Error("Unsupported operation modus for the Sobolev Smoothing Solver.", CURRENT_FUNCTION); - } - - /*-- Construct the smoothing solver and numerics ---*/ - std::unique_ptr solver(new CGradientSmoothingSolver(geometry, config)); - unsigned dim = (config->GetSmoothOnSurface() ? geometry->GetnDim() - 1 : geometry->GetnDim()); - std::unique_ptr numerics(new CGradSmoothing(dim, config)); - - if (rank == MASTER_NODE) cout << "Sobolev Smoothing of derivatives is active." << endl; - - /*--- Get the sensitivities from the geometry class to work with. ---*/ - solver->ReadSensFromGeometry(geometry); - - /*--- Apply the smoothing procedure on the DV level. ---*/ - if (config->GetSobMode() == ENUM_SOBOLEV_MODUS::PARAM_LEVEL_COMPLETE) { - solver->ApplyGradientSmoothingDV(geometry, numerics.get(), surface_movement, grid_movement, config, Gradient); - - /*--- If smoothing already took place on the mesh level, or none is requested, just do standard projection. ---*/ - } else if (config->GetSobMode() == ENUM_SOBOLEV_MODUS::ONLY_GRAD || - config->GetSobMode() == ENUM_SOBOLEV_MODUS::MESH_LEVEL) { - solver->RecordTapeAndCalculateOriginalGradient(geometry, surface_movement, grid_movement, config, Gradient); - } - + SU2_MPI::Comm comm = SU2_MPI::GetComm(); + + /*--- 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"); } + + /*--- Initialize the mesh deformation driver ---*/ + + driver = new CDiscAdjDeformationDriver(config_file_name, comm); + + /*--- Launch the main external loop of the solver. ---*/ + + driver->Run(); + + /*--- Postprocess all the containers, close history file, exit SU2. ---*/ + + driver->Postprocessing(); + + delete driver; + + /*--- Finalize MPI parallelization ---*/ + SU2_MPI::Finalize(); + + return EXIT_SUCCESS; + } diff --git a/SU2_PY/pySU2/pySU2.i b/SU2_PY/pySU2/pySU2.i index 4cbb9afc3bd..e5cdf388fe0 100644 --- a/SU2_PY/pySU2/pySU2.i +++ b/SU2_PY/pySU2/pySU2.i @@ -50,6 +50,7 @@ threads="1" %import "../../Common/include/code_config.hpp" %import "../../Common/include/basic_types/datatype_structure.hpp" %import "../../Common/include/parallelization/mpi_structure.hpp" +%import "../../Common/include/drivers/CDriverBase.hpp" %include "std_string.i" %include "std_vector.i" %include "std_map.i" diff --git a/SU2_PY/pySU2/pySU2ad.i b/SU2_PY/pySU2/pySU2ad.i index e2e3bfbc54c..f0c6702a940 100644 --- a/SU2_PY/pySU2/pySU2ad.i +++ b/SU2_PY/pySU2/pySU2ad.i @@ -50,6 +50,7 @@ threads="1" %import "../../Common/include/code_config.hpp" %import "../../Common/include/basic_types/datatype_structure.hpp" %import "../../Common/include/parallelization/mpi_structure.hpp" +%import "../../Common/include/drivers/CDriverBase.hpp" %include "std_string.i" %include "std_vector.i" %include "std_map.i" From de94b6dc8057b1f67efe393b13149d6ad53c7f2f Mon Sep 17 00:00:00 2001 From: patelha57 Date: Mon, 14 Feb 2022 10:54:30 -0800 Subject: [PATCH 14/68] Introduce dependency of SU2_DOT on SU2_DEF --- SU2_DOT/src/meson.build | 4 ++-- meson.build | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/SU2_DOT/src/meson.build b/SU2_DOT/src/meson.build index 0f0b5234dcd..3cda6c961ed 100644 --- a/SU2_DOT/src/meson.build +++ b/SU2_DOT/src/meson.build @@ -5,7 +5,7 @@ if get_option('enable-normal') su2_dot = executable('SU2_DOT', su2_dot_src, install: true, - dependencies: [su2_deps, common_dep, su2_cfd_dep], + dependencies: [su2_deps, common_dep, su2_cfd_dep, su2_def_dep], cpp_args :[default_warning_flags, su2_cpp_args]) endif @@ -15,7 +15,7 @@ if get_option('enable-autodiff') su2_dot_ad = executable('SU2_DOT_AD', su2_dot_src, install: true, - dependencies: [su2_deps, codi_dep, commonAD_dep, su2_cfd_dep_ad], + dependencies: [su2_deps, codi_dep, commonAD_dep, su2_cfd_dep_ad, su2_def_dep_ad], cpp_args : [default_warning_flags, su2_cpp_args, codi_rev_args]) endif diff --git a/meson.build b/meson.build index ebb7be89255..597fc38ab7a 100644 --- a/meson.build +++ b/meson.build @@ -230,10 +230,10 @@ endif subdir('Common/src') # compile SU2_CFD executable subdir('SU2_CFD/src') -# compile SU2_DOT executable -subdir('SU2_DOT/src') # compile SU2_DEF executable subdir('SU2_DEF/src') +# compile SU2_DOT executable +subdir('SU2_DOT/src') # compile SU2_GEO executable subdir('SU2_GEO/src') # compile SU2_SOL executable From 1c57ad34350a4c8bba680fd56b8ef51c29e965d9 Mon Sep 17 00:00:00 2001 From: aa-g Date: Mon, 14 Feb 2022 23:01:35 +0100 Subject: [PATCH 15/68] [WIP] Small fixes --- .../grid_movement/CSurfaceMovement.hpp | 2 +- Common/src/grid_movement/CSurfaceMovement.cpp | 6 +- SU2_CFD/src/drivers/CDriver.cpp | 2 +- .../include/drivers/CDeformationDriver.hpp | 11 +- SU2_DEF/src/drivers/CDeformationDriver.cpp | 105 +++++++++++------- 5 files changed, 75 insertions(+), 51 deletions(-) diff --git a/Common/include/grid_movement/CSurfaceMovement.hpp b/Common/include/grid_movement/CSurfaceMovement.hpp index 45acfd2aa74..700fa6dbe32 100644 --- a/Common/include/grid_movement/CSurfaceMovement.hpp +++ b/Common/include/grid_movement/CSurfaceMovement.hpp @@ -443,7 +443,7 @@ class CSurfaceMovement : public CGridMovement { * \param[in] geometry - Geometrical definition of the problem. * \param[in] val_mesh_filename - Name of the grid output file. */ - void WriteFFDInfo(CSurfaceMovement **surface_movement, CGeometry **geometry, CConfig **config); + void WriteFFDInfo(CSurfaceMovement **surface_movement, CGeometry ****geometry, CConfig **config); /*! * \brief Get information about if there is a complete FFDBox definition, or it is necessary to diff --git a/Common/src/grid_movement/CSurfaceMovement.cpp b/Common/src/grid_movement/CSurfaceMovement.cpp index 3d346c13950..8c57008d9ea 100644 --- a/Common/src/grid_movement/CSurfaceMovement.cpp +++ b/Common/src/grid_movement/CSurfaceMovement.cpp @@ -4674,7 +4674,7 @@ void CSurfaceMovement::MergeFFDInfo(CGeometry *geometry, CConfig *config) { } -void CSurfaceMovement::WriteFFDInfo(CSurfaceMovement** surface_movement, CGeometry **geometry, CConfig **config) { +void CSurfaceMovement::WriteFFDInfo(CSurfaceMovement** surface_movement, CGeometry ****geometry, CConfig **config) { unsigned short iOrder, jOrder, kOrder, iFFDBox, iCornerPoints, iParentFFDBox, iChildFFDBox, iZone; @@ -4685,13 +4685,13 @@ void CSurfaceMovement::WriteFFDInfo(CSurfaceMovement** surface_movement, CGeomet bool polar = (config[ZONE_0]->GetFFD_CoordSystem() == POLAR); - unsigned short nDim = geometry[ZONE_0]->GetnDim(); + unsigned short nDim = geometry[ZONE_0][INST_0][MESH_0]->GetnDim(); for (iZone = 0; iZone < config[ZONE_0]->GetnZone(); iZone++){ /*--- Merge the parallel FFD info ---*/ - surface_movement[iZone]->MergeFFDInfo(geometry[iZone], config[iZone]); + surface_movement[iZone]->MergeFFDInfo(geometry[iZone][INST_0][MESH_0], config[iZone]); if (iZone > 0){ diff --git a/SU2_CFD/src/drivers/CDriver.cpp b/SU2_CFD/src/drivers/CDriver.cpp index dcb8447d591..53ec9afc51a 100644 --- a/SU2_CFD/src/drivers/CDriver.cpp +++ b/SU2_CFD/src/drivers/CDriver.cpp @@ -343,7 +343,7 @@ void CDriver::SetContainers_Null(){ interface_container = new CInterface**[nZone] (); interface_types = new unsigned short*[nZone] (); output_container = new COutput*[nZone] (); - nInst = new unsigned short[nZone] (); + nInst = new unsigned short[nZone] (); // TODO: remove (moved to base class) driver_config = nullptr; driver_output = nullptr; diff --git a/SU2_DEF/include/drivers/CDeformationDriver.hpp b/SU2_DEF/include/drivers/CDeformationDriver.hpp index 5c1d7c0da4e..20b260f6eff 100644 --- a/SU2_DEF/include/drivers/CDeformationDriver.hpp +++ b/SU2_DEF/include/drivers/CDeformationDriver.hpp @@ -42,9 +42,6 @@ class CDeformationDriver : public CDriverBase { -protected: - CNumerics ***numerics_container; - public: /*! * \brief Constructor of the class. @@ -76,10 +73,10 @@ class CDeformationDriver : public CDriverBase { void CommunicateMeshDisplacements(void); protected: - /*! - * \brief Init_Containers - */ - void SetContainers_Null(); + // /*! + // * \brief Init_Containers + // */ + // void SetContainer_Null(); /*! * \brief Read in the config and mesh files. diff --git a/SU2_DEF/src/drivers/CDeformationDriver.cpp b/SU2_DEF/src/drivers/CDeformationDriver.cpp index 90563e93f2f..22f58ebb574 100644 --- a/SU2_DEF/src/drivers/CDeformationDriver.cpp +++ b/SU2_DEF/src/drivers/CDeformationDriver.cpp @@ -54,11 +54,6 @@ CDeformationDriver::CDeformationDriver(char* confFile, SU2_Comm MPICommunicator) /*--- Copy the config filename ---*/ strcpy(config_file_name, confFile); - /*--- Initialize the configuration of the driver ---*/ - driver_config = new CConfig(config_file_name, SU2_COMPONENT::SU2_DEF); - - nZone = driver_config->GetnZone(); - /*--- Initialize containers --- */ SetContainers_Null(); @@ -107,36 +102,41 @@ CDeformationDriver::~CDeformationDriver(void) { } -void CDeformationDriver::SetContainers_Null() { - - /*--- Create pointers to all of the classes that may be used throughout - the SU2_DEF code. In general, the pointers are instantiated down a - hierarchy over all zones as described in the comments below. ---*/ - config_container = new CConfig*[nZone]; - output_container = new COutput*[nZone]; - geometry_container = new CGeometry***[nZone]; - surface_movement = new CSurfaceMovement*[nZone]; - grid_movement = new CVolumetricMovement**[nZone]; - - solver_container = new CSolver****[nZone]; - numerics_container = new CNumerics**[nZone]; - - for (iZone = 0; iZone < nZone; iZone++) { - config_container[iZone] = nullptr; - output_container[iZone] = nullptr; - geometry_container[iZone] = nullptr; - surface_movement[iZone] = nullptr; - grid_movement[iZone] = nullptr; - solver_container[iZone] = nullptr; - numerics_container[iZone] = nullptr; - } -} +// void CDeformationDriver::SetContainers_Null() { +// +// /*--- Create pointers to all of the classes that may be used throughout +// the SU2_DEF code. In general, the pointers are instantiated down a +// hierarchy over all zones as described in the comments below. ---*/ +// config_container = new CConfig*[nZone]; +// output_container = new COutput*[nZone]; +// geometry_container = new CGeometry***[nZone]; +// surface_movement = new CSurfaceMovement*[nZone]; +// grid_movement = new CVolumetricMovement**[nZone]; +// +// solver_container = new CSolver****[nZone]; +// numerics_container = new CNumerics**[nZone]; +// +// for (iZone = 0; iZone < nZone; iZone++) { +// config_container[iZone] = nullptr; +// output_container[iZone] = nullptr; +// geometry_container[iZone] = nullptr; +// surface_movement[iZone] = nullptr; +// grid_movement[iZone] = nullptr; +// solver_container[iZone] = nullptr; +// numerics_container[iZone] = nullptr; +// } +// } void CDeformationDriver::Input_Preprocessing() { /*--- Initialize a char to store the zone filename ---*/ char zone_file_name[MAX_STRING_SIZE]; + /*--- Initialize the configuration of the driver ---*/ + driver_config = new CConfig(config_file_name, SU2_COMPONENT::SU2_DEF); + + nZone = driver_config->GetnZone(); + /*--- 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. ---*/ @@ -186,7 +186,11 @@ void CDeformationDriver::Geometrical_Preprocessing() { geometry_aux->SetColorGrid_Parallel(config_container[iZone]); /*--- Build the grid data structures using the ParMETIS coloring. ---*/ - + unsigned short nInst_Zone = nInst[iZone]; + unsigned short nMesh = 1; + + geometry_container[iZone] = new CGeometry**[nInst_Zone] (); + geometry_container[iZone][INST_0] = new CGeometry*[nMesh] (); geometry_container[iZone][INST_0][MESH_0] = new CPhysicalGeometry(geometry_aux, config_container[iZone]); /*--- Deallocate the memory of geometry_aux ---*/ @@ -263,21 +267,36 @@ void CDeformationDriver::Output_Preprocessing() { void CDeformationDriver::Solver_Preprocessing() { for (iZone = 0; iZone < nZone; iZone++) { + unsigned short nInst_Zone = nInst[iZone]; + unsigned short nMesh = 1; + unsigned short nSols = MAX_SOLS; + + + solver_container[iZone] = new CSolver*** [nInst_Zone] (); + solver_container[iZone][INST_0] = new CSolver** [nMesh] (); + solver_container[iZone][INST_0][MESH_0] = new CSolver* [nSols] (); solver_container[iZone][INST_0][MESH_0][MESH_SOL] = new CMeshSolver(geometry_container[iZone][INST_0][MESH_0], config_container[iZone]); - } - + } } void CDeformationDriver::Numerics_Preprocessing() { for (iZone = 0; iZone < nZone; iZone++) { - numerics_container[iZone] = new CNumerics* [omp_get_num_threads() * MAX_TERMS](); + unsigned short nInst_Zone = nInst[iZone]; + unsigned short nMesh = 1; + unsigned short nSols = MAX_SOLS; + unsigned int nTerm = omp_get_num_threads() * MAX_TERMS; + + numerics_container[iZone] = new CNumerics**** [nInst_Zone] (); + numerics_container[iZone][INST_0] = new CNumerics*** [nMesh] (); + numerics_container[iZone][INST_0][MESH_0] = new CNumerics** [nSols] (); + numerics_container[iZone][INST_0][MESH_0][MESH_SOL] = new CNumerics* [nTerm] (); for (int thread = 0; thread < omp_get_max_threads(); ++thread) { const int iTerm = FEA_TERM + thread * MAX_TERMS; const int nDim = geometry_container[iZone][INST_0][MESH_0]->GetnDim(); - numerics_container[iZone][iTerm] = new CFEAMeshElasticity(nDim, nDim, geometry_container[iZone][INST_0][MESH_0]->GetnElem(), config_container[iZone]); + numerics_container[iZone][INST_0][MESH_0][MESH_SOL][iTerm] = new CFEAMeshElasticity(nDim, nDim, geometry_container[iZone][INST_0][MESH_0]->GetnElem(), config_container[iZone]); } } @@ -322,11 +341,11 @@ void CDeformationDriver::Update() { /*--- Set the stiffness of each element mesh into the mesh numerics ---*/ - solver_container[iZone][INST_0][MESH_0][MESH_SOL]->SetMesh_Stiffness(numerics_container[iZone], config_container[iZone]); + solver_container[iZone][INST_0][MESH_0][MESH_SOL]->SetMesh_Stiffness(numerics_container[iZone][INST_0][MESH_0][MESH_SOL], config_container[iZone]); /*--- Deform the volume grid around the new boundary locations ---*/ - solver_container[iZone][INST_0][MESH_0][MESH_SOL]->DeformMesh(geometry_container[iZone][INST_0][MESH_0], numerics_container[iZone], config_container[iZone]); + solver_container[iZone][INST_0][MESH_0][MESH_SOL]->DeformMesh(geometry_container[iZone][INST_0][MESH_0], numerics_container[iZone][INST_0][MESH_0][MESH_SOL], config_container[iZone]); } } @@ -511,7 +530,7 @@ void CDeformationDriver::Output() { /*--- Load the data --- */ output_container[iZone]->Load_Data(geometry_container[iZone][INST_0][MESH_0], config_container[iZone], nullptr); - + output_container[iZone]->WriteToFile(config_container[iZone], geometry_container[iZone][INST_0][MESH_0], OUTPUT_TYPE::MESH, driver_config->GetMesh_Out_FileName()); /*--- Set the file names for the visualization files ---*/ @@ -538,7 +557,7 @@ void CDeformationDriver::Output() { if (rank == MASTER_NODE) cout << "Adding any FFD information to the SU2 file." << endl; - surface_movement[ZONE_0]->WriteFFDInfo(surface_movement, geometry_container[INST_0][MESH_0], config_container); + surface_movement[ZONE_0]->WriteFFDInfo(surface_movement, geometry_container, config_container); } } @@ -555,7 +574,10 @@ void CDeformationDriver::Postprocessing() { for (iZone = 0; iZone < nZone; iZone++) { if (numerics_container[iZone] != nullptr) { for (unsigned int iTerm = 0; iTerm < MAX_TERMS*omp_get_max_threads(); iTerm++) { - delete numerics_container[iZone][iTerm]; + delete numerics_container[iZone][INST_0][MESH_0][MESH_SOL][iTerm]; + delete [] numerics_container[iZone][INST_0][MESH_0][MESH_SOL]; + delete [] numerics_container[iZone][INST_0][MESH_0]; + delete [] numerics_container[iZone][INST_0]; } delete [] numerics_container[iZone]; } @@ -565,6 +587,9 @@ void CDeformationDriver::Postprocessing() { for (iZone = 0; iZone < nZone; iZone++) { delete solver_container[iZone][INST_0][MESH_0][MESH_SOL]; + delete [] solver_container[iZone][INST_0][MESH_0]; + delete [] solver_container[iZone][INST_0]; + delete [] solver_container[iZone]; } delete [] solver_container; if (rank == MASTER_NODE) cout << "Deleted CSolver container." << endl; @@ -572,6 +597,8 @@ void CDeformationDriver::Postprocessing() { if (geometry_container != nullptr) { for (iZone = 0; iZone < nZone; iZone++) { delete geometry_container[iZone][INST_0][MESH_0]; + delete [] geometry_container[iZone][INST_0]; + delete [] geometry_container[iZone]; } delete [] geometry_container; } From 342d3a204c36f1affc49d8e4b443e6684c7d097b Mon Sep 17 00:00:00 2001 From: patelha57 Date: Tue, 15 Feb 2022 15:21:07 -0800 Subject: [PATCH 16/68] Fix 'unknown module' SWIG warning for CDriverBase --- SU2_PY/pySU2/pySU2.i | 5 +++-- SU2_PY/pySU2/pySU2ad.i | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/SU2_PY/pySU2/pySU2.i b/SU2_PY/pySU2/pySU2.i index e5cdf388fe0..02ba990a514 100644 --- a/SU2_PY/pySU2/pySU2.i +++ b/SU2_PY/pySU2/pySU2.i @@ -38,6 +38,7 @@ threads="1" ) pysu2 %{ +#include "../../Common/include/drivers/CDriverBase.hpp" #include "../../SU2_CFD/include/drivers/CDriver.hpp" #include "../../SU2_CFD/include/drivers/CSinglezoneDriver.hpp" #include "../../SU2_CFD/include/drivers/CMultizoneDriver.hpp" @@ -50,7 +51,7 @@ threads="1" %import "../../Common/include/code_config.hpp" %import "../../Common/include/basic_types/datatype_structure.hpp" %import "../../Common/include/parallelization/mpi_structure.hpp" -%import "../../Common/include/drivers/CDriverBase.hpp" + %include "std_string.i" %include "std_vector.i" %include "std_map.i" @@ -88,7 +89,7 @@ const unsigned int MESH_1 = 1; /*!< \brief Definition of the finest grid level. const unsigned int ZONE_0 = 0; /*!< \brief Definition of the first grid domain. */ const unsigned int ZONE_1 = 1; /*!< \brief Definition of the first grid domain. */ -// CDriver class +%include "../../Common/include/drivers/CDriverBase.hpp" %include "../../SU2_CFD/include/drivers/CDriver.hpp" %include "../../SU2_CFD/include/drivers/CSinglezoneDriver.hpp" %include "../../SU2_CFD/include/drivers/CMultizoneDriver.hpp" diff --git a/SU2_PY/pySU2/pySU2ad.i b/SU2_PY/pySU2/pySU2ad.i index f0c6702a940..27a2dfe6cd1 100644 --- a/SU2_PY/pySU2/pySU2ad.i +++ b/SU2_PY/pySU2/pySU2ad.i @@ -38,6 +38,7 @@ threads="1" ) pysu2ad %{ +#include "../../Common/include/drivers/CDriverBase.hpp" #include "../../SU2_CFD/include/drivers/CDriver.hpp" #include "../../SU2_CFD/include/drivers/CSinglezoneDriver.hpp" #include "../../SU2_CFD/include/drivers/CMultizoneDriver.hpp" @@ -50,7 +51,7 @@ threads="1" %import "../../Common/include/code_config.hpp" %import "../../Common/include/basic_types/datatype_structure.hpp" %import "../../Common/include/parallelization/mpi_structure.hpp" -%import "../../Common/include/drivers/CDriverBase.hpp" + %include "std_string.i" %include "std_vector.i" %include "std_map.i" @@ -88,7 +89,7 @@ const unsigned int MESH_1 = 1; /*!< \brief Definition of the finest grid level. const unsigned int ZONE_0 = 0; /*!< \brief Definition of the first grid domain. */ const unsigned int ZONE_1 = 1; /*!< \brief Definition of the first grid domain. */ -// CDriver class +%include "../../Common/include/drivers/CDriverBase.hpp" %include "../../SU2_CFD/include/drivers/CDriver.hpp" %include "../../SU2_CFD/include/drivers/CSinglezoneDriver.hpp" %include "../../SU2_CFD/include/drivers/CMultizoneDriver.hpp" From bfb175c15a5086847a69507869b2071a90a87232 Mon Sep 17 00:00:00 2001 From: aa-g Date: Wed, 16 Feb 2022 20:43:05 +0100 Subject: [PATCH 17/68] Fix small issues in getters, skip FFD output if not defined --- Common/src/drivers/CDriverBase.cpp | 13 ++++---- .../include/drivers/CDeformationDriver.hpp | 3 ++ SU2_DEF/src/drivers/CDeformationDriver.cpp | 30 ++++++++++--------- SU2_PY/pySU2/pySU2.i | 3 ++ SU2_PY/pySU2/pySU2ad.i | 3 ++ 5 files changed, 31 insertions(+), 21 deletions(-) diff --git a/Common/src/drivers/CDriverBase.cpp b/Common/src/drivers/CDriverBase.cpp index 094113173ec..7d7de27aabd 100644 --- a/Common/src/drivers/CDriverBase.cpp +++ b/Common/src/drivers/CDriverBase.cpp @@ -65,24 +65,23 @@ void CDriverBase::SetContainers_Null() { grid_movement = nullptr; FFDBox = nullptr; - nInst = new unsigned short[nZone] (); - config_container = new CConfig*[nZone] (); output_container = new COutput*[nZone] (); geometry_container = new CGeometry***[nZone] (); solver_container = new CSolver****[nZone] (); numerics_container = new CNumerics*****[nZone] (); - surface_movement = new CSurfaceMovement*[nZone] (); grid_movement = new CVolumetricMovement**[nZone] (); FFDBox = new CFreeFormDefBox**[nZone] (); - driver_config = nullptr; - driver_output = nullptr; + nInst = new unsigned short[nZone] (); for (iZone = 0; iZone < nZone; iZone++) { nInst[iZone] = 1; } + + driver_config = nullptr; + driver_output = nullptr; } map CDriverBase::GetBoundaryMarkerIndices() const { @@ -302,7 +301,7 @@ vector CDriverBase::GetDomain() const { CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; const auto nPoint = geometry->GetnPoint(); - vector values(nPoint); + vector values; for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { values.push_back(geometry->nodes->GetDomain(iPoint)); @@ -315,7 +314,7 @@ vector CDriverBase::GetDomainMarker(unsigned short iMarker) const { CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; const auto nVertex = geometry->GetnVertex(iMarker); - vector values(nVertex); + vector values; for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { auto iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); diff --git a/SU2_DEF/include/drivers/CDeformationDriver.hpp b/SU2_DEF/include/drivers/CDeformationDriver.hpp index 20b260f6eff..6d64c4b6f2f 100644 --- a/SU2_DEF/include/drivers/CDeformationDriver.hpp +++ b/SU2_DEF/include/drivers/CDeformationDriver.hpp @@ -42,6 +42,9 @@ class CDeformationDriver : public CDriverBase { +protected: + bool haveSurfaceDeformation = false; // flag used to determine whether surface deformation is available for output + public: /*! * \brief Constructor of the class. diff --git a/SU2_DEF/src/drivers/CDeformationDriver.cpp b/SU2_DEF/src/drivers/CDeformationDriver.cpp index 22f58ebb574..c1e6136b970 100644 --- a/SU2_DEF/src/drivers/CDeformationDriver.cpp +++ b/SU2_DEF/src/drivers/CDeformationDriver.cpp @@ -116,14 +116,7 @@ CDeformationDriver::~CDeformationDriver(void) { // solver_container = new CSolver****[nZone]; // numerics_container = new CNumerics**[nZone]; // -// for (iZone = 0; iZone < nZone; iZone++) { -// config_container[iZone] = nullptr; -// output_container[iZone] = nullptr; -// geometry_container[iZone] = nullptr; -// surface_movement[iZone] = nullptr; -// grid_movement[iZone] = nullptr; -// solver_container[iZone] = nullptr; -// numerics_container[iZone] = nullptr; + // } // } @@ -243,6 +236,9 @@ void CDeformationDriver::Geometrical_Preprocessing() { geometry_container[iZone][INST_0][MESH_0]->PreprocessP2PComms(geometry_container[iZone][INST_0][MESH_0], config_container[iZone]); } + + /*--- Get the number of dimensions ---*/ + nDim = geometry_container[ZONE_0][INST_0][MESH_0]->GetnDim(); } void CDeformationDriver::Output_Preprocessing() { @@ -351,6 +347,8 @@ void CDeformationDriver::Update() { } void CDeformationDriver::Update_Legacy() { + + std::cout << "UPDATE LEGACY CALLED" << std::endl; for (iZone = 0; iZone < nZone; iZone++){ @@ -393,6 +391,7 @@ void CDeformationDriver::Update_Legacy() { /*--- Definition and initialization of the surface deformation class ---*/ surface_movement[iZone] = new CSurfaceMovement(); + haveSurfaceDeformation = true; /*--- Copy coordinates to the surface structure ---*/ @@ -553,12 +552,15 @@ void CDeformationDriver::Output() { (config_container[ZONE_0]->GetDesign_Variable(0) != TRANSLATE_GRID) && (config_container[ZONE_0]->GetDesign_Variable(0) != ROTATE_GRID)) { - /*--- Write the the free-form deformation boxes after deformation. ---*/ - - if (rank == MASTER_NODE) cout << "Adding any FFD information to the SU2 file." << endl; - - surface_movement[ZONE_0]->WriteFFDInfo(surface_movement, geometry_container, config_container); - + /*--- Write the the free-form deformation boxes after deformation (if defined). ---*/ + if (true) { + if (rank == MASTER_NODE) cout << "No FFD information available." << endl; + } + else { + if (rank == MASTER_NODE) cout << "Adding any FFD information to the SU2 file." << endl; + + surface_movement[ZONE_0]->WriteFFDInfo(surface_movement, geometry_container, config_container); + } } } } diff --git a/SU2_PY/pySU2/pySU2.i b/SU2_PY/pySU2/pySU2.i index 02ba990a514..0125ffd1e6b 100644 --- a/SU2_PY/pySU2/pySU2.i +++ b/SU2_PY/pySU2/pySU2.i @@ -63,6 +63,9 @@ threads="1" #endif namespace std { + %template() vector; + %template() vector; + %template() vector>; %template() vector; %template() vector; %template() vector; diff --git a/SU2_PY/pySU2/pySU2ad.i b/SU2_PY/pySU2/pySU2ad.i index 27a2dfe6cd1..a1f47b6bf2b 100644 --- a/SU2_PY/pySU2/pySU2ad.i +++ b/SU2_PY/pySU2/pySU2ad.i @@ -63,6 +63,9 @@ threads="1" #endif namespace std { + %template() vector; + %template() vector; + %template() vector>; %template() vector; %template() vector; %template() vector; From 1fdb8374e38a89972b4e81c81c786661083f79dc Mon Sep 17 00:00:00 2001 From: aa-g Date: Fri, 18 Feb 2022 20:54:24 +0100 Subject: [PATCH 18/68] Remove some code duplication and fix memory leaks --- Common/include/drivers/CDriverBase.hpp | 2 +- Common/src/drivers/CDriverBase.cpp | 6 +- .../include/drivers/CDeformationDriver.hpp | 5 - .../drivers/CDiscAdjDeformationDriver.hpp | 11 +- SU2_DEF/src/drivers/CDeformationDriver.cpp | 46 ++--- .../src/drivers/CDiscAdjDeformationDriver.cpp | 169 ++++++++++-------- 6 files changed, 123 insertions(+), 116 deletions(-) diff --git a/Common/include/drivers/CDriverBase.hpp b/Common/include/drivers/CDriverBase.hpp index 7291411e397..28619eab44e 100644 --- a/Common/include/drivers/CDriverBase.hpp +++ b/Common/include/drivers/CDriverBase.hpp @@ -80,7 +80,7 @@ class CDriverBase { /*! * \brief Destructor of the class. */ - ~CDriverBase(void); + virtual ~CDriverBase(void); /*! * \brief A virtual member. diff --git a/Common/src/drivers/CDriverBase.cpp b/Common/src/drivers/CDriverBase.cpp index 7d7de27aabd..4ec2d3b1a27 100644 --- a/Common/src/drivers/CDriverBase.cpp +++ b/Common/src/drivers/CDriverBase.cpp @@ -38,7 +38,7 @@ CDriverBase::CDriverBase(char* confFile, unsigned short val_nZone, SU2_Comm MPIC StopTime(0.0), UsedTime(0.0), TimeIter(0), - nZone() + nZone(val_nZone) { } @@ -53,8 +53,6 @@ void CDriverBase::SetContainers_Null() { hierarchy over all zones, multigrid levels, equation sets, and equation terms as described in the comments below. ---*/ - nInst = nullptr; - config_container = nullptr; output_container = nullptr; geometry_container = nullptr; @@ -74,7 +72,7 @@ void CDriverBase::SetContainers_Null() { grid_movement = new CVolumetricMovement**[nZone] (); FFDBox = new CFreeFormDefBox**[nZone] (); - nInst = new unsigned short[nZone] (); + nInst = new unsigned short[nZone]; for (iZone = 0; iZone < nZone; iZone++) { nInst[iZone] = 1; diff --git a/SU2_DEF/include/drivers/CDeformationDriver.hpp b/SU2_DEF/include/drivers/CDeformationDriver.hpp index 6d64c4b6f2f..329c660bb4c 100644 --- a/SU2_DEF/include/drivers/CDeformationDriver.hpp +++ b/SU2_DEF/include/drivers/CDeformationDriver.hpp @@ -76,11 +76,6 @@ class CDeformationDriver : public CDriverBase { void CommunicateMeshDisplacements(void); protected: - // /*! - // * \brief Init_Containers - // */ - // void SetContainer_Null(); - /*! * \brief Read in the config and mesh files. */ diff --git a/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp b/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp index 41a1df49b2c..1f1f79b76c1 100644 --- a/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp +++ b/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp @@ -54,10 +54,7 @@ class CDiscAdjDeformationDriver : public CDriverBase { protected: su2double** Gradient; - ofstream Gradient_file; - CGeometry ***geometry_container; /*!< \brief Geometrical definition of the problem. */ - CSurfaceMovement **surface_movement; - CVolumetricMovement **grid_movement; + ofstream Gradient_file; public: /*! @@ -83,10 +80,6 @@ class CDiscAdjDeformationDriver : public CDriverBase { void Postprocessing(); protected: - /*! - * \brief Init_Containers - */ - void SetContainers_Null(); /*! * \brief Read in the config and mesh files. @@ -140,7 +133,7 @@ class CDiscAdjDeformationDriver : public CDriverBase { * \param[in] val_nZone - Number of Zones. */ - void SetSensitivity_Files(CGeometry ***geometry, CConfig **config, unsigned short val_nZone); + void SetSensitivity_Files(CGeometry ****geometry, CConfig **config, unsigned short val_nZone); /*! * \brief Treatment of derivatives with the Sobolev smoothing solver. diff --git a/SU2_DEF/src/drivers/CDeformationDriver.cpp b/SU2_DEF/src/drivers/CDeformationDriver.cpp index c1e6136b970..8bf4b8b9e98 100644 --- a/SU2_DEF/src/drivers/CDeformationDriver.cpp +++ b/SU2_DEF/src/drivers/CDeformationDriver.cpp @@ -51,9 +51,6 @@ CDeformationDriver::CDeformationDriver(char* confFile, SU2_Comm MPICommunicator) rank = SU2_MPI::GetRank(); size = SU2_MPI::GetSize(); - /*--- Copy the config filename ---*/ - strcpy(config_file_name, confFile); - /*--- Initialize containers --- */ SetContainers_Null(); @@ -102,24 +99,6 @@ CDeformationDriver::~CDeformationDriver(void) { } -// void CDeformationDriver::SetContainers_Null() { -// -// /*--- Create pointers to all of the classes that may be used throughout -// the SU2_DEF code. In general, the pointers are instantiated down a -// hierarchy over all zones as described in the comments below. ---*/ -// config_container = new CConfig*[nZone]; -// output_container = new COutput*[nZone]; -// geometry_container = new CGeometry***[nZone]; -// surface_movement = new CSurfaceMovement*[nZone]; -// grid_movement = new CVolumetricMovement**[nZone]; -// -// solver_container = new CSolver****[nZone]; -// numerics_container = new CNumerics**[nZone]; -// - -// } -// } - void CDeformationDriver::Input_Preprocessing() { /*--- Initialize a char to store the zone filename ---*/ @@ -142,6 +121,7 @@ void CDeformationDriver::Input_Preprocessing() { if (driver_config->GetnConfigFiles() > 0){ strcpy(zone_file_name, driver_config->GetConfigFilename(iZone).c_str()); + config_container[iZone] = new CConfig(driver_config, zone_file_name, SU2_COMPONENT::SU2_DEF, iZone, nZone, true); } else { config_container[iZone] = new CConfig(driver_config, config_file_name, SU2_COMPONENT::SU2_DEF, iZone, nZone, true); @@ -179,6 +159,7 @@ void CDeformationDriver::Geometrical_Preprocessing() { geometry_aux->SetColorGrid_Parallel(config_container[iZone]); /*--- Build the grid data structures using the ParMETIS coloring. ---*/ + unsigned short nInst_Zone = nInst[iZone]; unsigned short nMesh = 1; @@ -348,13 +329,13 @@ void CDeformationDriver::Update() { void CDeformationDriver::Update_Legacy() { - std::cout << "UPDATE LEGACY CALLED" << std::endl; - for (iZone = 0; iZone < nZone; iZone++){ if (config_container[iZone]->GetDesign_Variable(0) != NO_DEFORMATION) { + unsigned short nInst_Zone = nInst[iZone]; /*--- Definition of the Class for grid movement ---*/ + grid_movement[iZone] = new CVolumetricMovement* [nInst_Zone] (); grid_movement[iZone][INST_0] = new CVolumetricMovement(geometry_container[iZone][INST_0][MESH_0], config_container[iZone]); /*--- Save original coordinates to be reused in convexity checking procedure ---*/ @@ -588,10 +569,12 @@ void CDeformationDriver::Postprocessing() { if (rank == MASTER_NODE) cout << "Deleted CNumerics container." << endl; for (iZone = 0; iZone < nZone; iZone++) { - delete solver_container[iZone][INST_0][MESH_0][MESH_SOL]; - delete [] solver_container[iZone][INST_0][MESH_0]; - delete [] solver_container[iZone][INST_0]; - delete [] solver_container[iZone]; + if (solver_container[iZone] != nullptr) { + delete solver_container[iZone][INST_0][MESH_0][MESH_SOL]; + delete [] solver_container[iZone][INST_0][MESH_0]; + delete [] solver_container[iZone][INST_0]; + delete [] solver_container[iZone]; + } } delete [] solver_container; if (rank == MASTER_NODE) cout << "Deleted CSolver container." << endl; @@ -606,6 +589,12 @@ void CDeformationDriver::Postprocessing() { } if (rank == MASTER_NODE) cout << "Deleted CGeometry container." << endl; + for (iZone = 0; iZone < nZone; iZone++) { + delete [] FFDBox[iZone]; + } + delete [] FFDBox; + if (rank == MASTER_NODE) cout << "Deleted CFreeFormDefBox class." << endl; + if (surface_movement != nullptr) { for (iZone = 0; iZone < nZone; iZone++) { delete surface_movement[iZone]; @@ -617,6 +606,7 @@ void CDeformationDriver::Postprocessing() { if (grid_movement != nullptr) { for (iZone = 0; iZone < nZone; iZone++) { delete grid_movement[iZone][INST_0]; + delete [] grid_movement[iZone]; } delete [] grid_movement; } @@ -638,6 +628,8 @@ void CDeformationDriver::Postprocessing() { } if (rank == MASTER_NODE) cout << "Deleted COutput class." << endl; + if (nInst != nullptr) delete [] nInst; + /*--- Exit the solver cleanly ---*/ if (rank == MASTER_NODE) diff --git a/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp b/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp index 63555b249c2..fea679b6f55 100644 --- a/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp +++ b/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp @@ -46,17 +46,6 @@ CDiscAdjDeformationDriver::CDiscAdjDeformationDriver(char* confFile, SU2_Comm MP rank = SU2_MPI::GetRank(); size = SU2_MPI::GetSize(); - /*--- Copy the config filename ---*/ - strcpy(config_file_name, confFile); - - /*--- 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) ---*/ - - driver_config = new CConfig(config_file_name, SU2_COMPONENT::SU2_DOT); - - nZone = driver_config->GetnZone(); - /*--- Initialize containers --- */ SetContainers_Null(); @@ -93,30 +82,16 @@ CDiscAdjDeformationDriver::~CDiscAdjDeformationDriver(void) { } -void CDiscAdjDeformationDriver::SetContainers_Null() { - - /*--- Definition of the containers per zones ---*/ - - config_container = new CConfig*[nZone] (); - geometry_container = new CGeometry**[nZone] (); - surface_movement = new CSurfaceMovement*[nZone] (); - grid_movement = new CVolumetricMovement*[nZone] (); - - nInst = new unsigned short[nZone]; - for (iZone = 0; iZone < nZone; iZone++) { - nInst[iZone] = 1; - } -} - void CDiscAdjDeformationDriver::Input_Preprocessing() { - - if (!config_container[iZone]->GetDiscrete_Adjoint()) { - SU2_MPI::Error("The discrete adjoint solver was not specified in the configuration file.", CURRENT_FUNCTION); - } /*--- Initialize a char to store the zone filename ---*/ char zone_file_name[MAX_STRING_SIZE]; + /*--- Initialize the configuration of the driver ---*/ + driver_config = new CConfig(config_file_name, SU2_COMPONENT::SU2_DEF); + + nZone = driver_config->GetnZone(); + /*--- 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. ---*/ @@ -135,6 +110,11 @@ void CDiscAdjDeformationDriver::Input_Preprocessing() { } config_container[iZone]->SetMPICommunicator(SU2_MPI::GetComm()); + + if (!config_container[iZone]->GetDiscrete_Adjoint()) { + SU2_MPI::Error("The discrete adjoint solver was not specified in the configuration file.", CURRENT_FUNCTION); + } + } /*--- Set the multizone part of the problem. ---*/ @@ -151,6 +131,7 @@ void CDiscAdjDeformationDriver::Geometrical_Preprocessing() { /*--- 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. ---*/ + unsigned short nMesh = 1; for (iZone = 0; iZone < nZone; iZone++) { @@ -162,7 +143,7 @@ void CDiscAdjDeformationDriver::Geometrical_Preprocessing() { nInst[iZone] = config_container[iZone]->GetnTimeInstances(); - geometry_container[iZone] = new CGeometry*[nInst[iZone]]; + geometry_container[iZone] = new CGeometry**[nInst[iZone]]; for (iInst = 0; iInst < nInst[iZone]; iInst++){ @@ -184,13 +165,15 @@ void CDiscAdjDeformationDriver::Geometrical_Preprocessing() { if( fem_solver ) { switch( config_container[iZone]->GetKind_FEM_Flow() ) { case DG: { - geometry_container[iZone][iInst] = new CMeshFEM_DG(geometry_aux, config_container[iZone]); + geometry_container[iZone][iInst] = new CGeometry*[nMesh]; + geometry_container[iZone][iInst][MESH_0] = new CMeshFEM_DG(geometry_aux, config_container[iZone]); break; } } } else { - geometry_container[iZone][iInst] = new CPhysicalGeometry(geometry_aux, config_container[iZone]); + geometry_container[iZone][iInst] = new CGeometry*[nMesh]; + geometry_container[iZone][iInst][MESH_0] = new CPhysicalGeometry(geometry_aux, config_container[iZone]); } /*--- Deallocate the memory of geometry_aux ---*/ @@ -199,21 +182,21 @@ void CDiscAdjDeformationDriver::Geometrical_Preprocessing() { /*--- Add the Send/Receive boundaries ---*/ - geometry_container[iZone][iInst]->SetSendReceive(config_container[iZone]); + geometry_container[iZone][iInst][MESH_0]->SetSendReceive(config_container[iZone]); /*--- Add the Send/Receive boundaries ---*/ - geometry_container[iZone][iInst]->SetBoundaries(config_container[iZone]); + geometry_container[iZone][iInst][MESH_0]->SetBoundaries(config_container[iZone]); /*--- Create the vertex structure (required for MPI) ---*/ if (rank == MASTER_NODE) cout << "Identify vertices." << endl; - geometry_container[iZone][iInst]->SetVertex(config_container[iZone]); + geometry_container[iZone][iInst][MESH_0]->SetVertex(config_container[iZone]); /*--- Store the global to local mapping after preprocessing. ---*/ if (rank == MASTER_NODE) cout << "Storing a mapping from global to local point index." << endl; - geometry_container[iZone][iInst]->SetGlobal_to_Local_Point(); + geometry_container[iZone][iInst][MESH_0]->SetGlobal_to_Local_Point(); /* Test for a fem solver, because some more work must be done. */ @@ -221,7 +204,7 @@ void CDiscAdjDeformationDriver::Geometrical_Preprocessing() { /*--- Carry out a dynamic cast to CMeshFEM_DG, such that it is not needed to define all virtual functions in the base class CGeometry. ---*/ - CMeshFEM_DG *DGMesh = dynamic_cast(geometry_container[iZone][iInst]); + CMeshFEM_DG *DGMesh = dynamic_cast(geometry_container[iZone][iInst][MESH_0]); /*--- Determine the standard elements for the volume elements. ---*/ if (rank == MASTER_NODE) cout << "Creating standard volume elements." << endl; @@ -240,35 +223,35 @@ void CDiscAdjDeformationDriver::Geometrical_Preprocessing() { /*--- Compute elements surrounding points, points surrounding points ---*/ if (rank == MASTER_NODE) cout << "Setting local point connectivity." << endl; - geometry_container[iZone][INST_0]->SetPoint_Connectivity(); + geometry_container[iZone][INST_0][MESH_0]->SetPoint_Connectivity(); /*--- Check the orientation before computing geometrical quantities ---*/ - geometry_container[iZone][INST_0]->SetBoundVolume(); + geometry_container[iZone][INST_0][MESH_0]->SetBoundVolume(); if (config_container[iZone]->GetReorientElements()) { if (rank == MASTER_NODE) cout << "Checking the numerical grid orientation of the elements." << endl; - geometry_container[iZone][INST_0]->Check_IntElem_Orientation(config_container[iZone]); - geometry_container[iZone][INST_0]->Check_BoundElem_Orientation(config_container[iZone]); + geometry_container[iZone][INST_0][MESH_0]->Check_IntElem_Orientation(config_container[iZone]); + geometry_container[iZone][INST_0][MESH_0]->Check_BoundElem_Orientation(config_container[iZone]); } /*--- Create the edge structure ---*/ if (rank == MASTER_NODE) cout << "Identify edges and vertices." << endl; - geometry_container[iZone][INST_0]->SetEdges(); geometry_container[iZone][INST_0]->SetVertex(config_container[iZone]); + geometry_container[iZone][INST_0][MESH_0]->SetEdges(); geometry_container[iZone][INST_0][MESH_0]->SetVertex(config_container[iZone]); /*--- Create the dual control volume structures ---*/ if (rank == MASTER_NODE) cout << "Setting the bound control volume structure." << endl; - geometry_container[iZone][INST_0]->SetBoundControlVolume(config_container[ZONE_0], ALLOCATE); + geometry_container[iZone][INST_0][MESH_0]->SetBoundControlVolume(config_container[ZONE_0], ALLOCATE); /*--- Store the global to local mapping after preprocessing. ---*/ if (rank == MASTER_NODE) cout << "Storing a mapping from global to local point index." << endl; - geometry_container[iZone][INST_0]->SetGlobal_to_Local_Point(); + geometry_container[iZone][INST_0][MESH_0]->SetGlobal_to_Local_Point(); /*--- Create the point-to-point MPI communication structures. ---*/ - geometry_container[iZone][INST_0]->PreprocessP2PComms(geometry_container[iZone][INST_0], config_container[iZone]); + geometry_container[iZone][INST_0][MESH_0]->PreprocessP2PComms(geometry_container[iZone][INST_0][MESH_0], config_container[iZone]); } } @@ -281,20 +264,23 @@ void CDiscAdjDeformationDriver::Run() { for (iZone = 0; iZone < nZone; iZone++) { if (rank == MASTER_NODE) cout << "Reading volume sensitivities at each node from file." << endl; - grid_movement[iZone] = new CVolumetricMovement(geometry_container[iZone][INST_0], config_container[iZone]); + unsigned short nInst_Zone = nInst[iZone]; + + grid_movement[iZone] = new CVolumetricMovement* [nInst_Zone] (); + grid_movement[iZone][INST_0] = new CVolumetricMovement(geometry_container[iZone][INST_0][MESH_0], config_container[iZone]); /*--- Read in sensitivities from file. ---*/ if (config_container[ZONE_0]->GetSensitivity_Format() == UNORDERED_ASCII) - geometry_container[iZone][INST_0]->ReadUnorderedSensitivity(config_container[iZone]); + geometry_container[iZone][INST_0][MESH_0]->ReadUnorderedSensitivity(config_container[iZone]); else - geometry_container[iZone][INST_0]->SetSensitivity(config_container[iZone]); + geometry_container[iZone][INST_0][MESH_0]->SetSensitivity(config_container[iZone]); if (rank == MASTER_NODE) cout << "\n---------------------- Mesh sensitivity computation ---------------------" << endl; if (config_container[iZone]->GetDiscrete_Adjoint() && config_container[iZone]->GetSmoothGradient() && config_container[iZone]->GetSobMode() == ENUM_SOBOLEV_MODUS::MESH_LEVEL) { - DerivativeTreatment_MeshSensitivity(geometry_container[iZone][INST_0], config_container[iZone], grid_movement[iZone]); + DerivativeTreatment_MeshSensitivity(geometry_container[iZone][INST_0][MESH_0], config_container[iZone], grid_movement[iZone][INST_0]); } else { - grid_movement[iZone]->SetVolume_Deformation(geometry_container[iZone][INST_0], config_container[iZone], false, true); + grid_movement[iZone][INST_0]->SetVolume_Deformation(geometry_container[iZone][INST_0][MESH_0], config_container[iZone], false, true); } } @@ -325,19 +311,19 @@ void CDiscAdjDeformationDriver::Run() { /*--- Copy coordinates to the surface structure ---*/ - surface_movement[iZone]->CopyBoundary(geometry_container[iZone][INST_0], config_container[iZone]); + surface_movement[iZone]->CopyBoundary(geometry_container[iZone][INST_0][MESH_0], config_container[iZone]); /*--- If AD mode is enabled we can use it to compute the projection, * otherwise we use finite differences. ---*/ if (config_container[iZone]->GetAD_Mode()) if (config_container[iZone]->GetSmoothGradient()) { - DerivativeTreatment_Gradient(geometry_container[iZone][INST_0], config_container[iZone], grid_movement[iZone], surface_movement[iZone] , Gradient); + DerivativeTreatment_Gradient(geometry_container[iZone][INST_0][MESH_0], config_container[iZone], grid_movement[iZone][INST_0], surface_movement[iZone] , Gradient); } else { - SetProjection_AD(geometry_container[iZone][INST_0], config_container[iZone], surface_movement[iZone] , Gradient); + SetProjection_AD(geometry_container[iZone][INST_0][MESH_0], config_container[iZone], surface_movement[iZone] , Gradient); } } else { - SetProjection_FD(geometry_container[iZone][INST_0], config_container[iZone], surface_movement[iZone] , Gradient); + SetProjection_FD(geometry_container[iZone][INST_0][MESH_0], config_container[iZone], surface_movement[iZone] , Gradient); } } // for iZone @@ -365,19 +351,42 @@ void CDiscAdjDeformationDriver::Postprocessing() { if (rank == MASTER_NODE) cout << "\n------------------------- Solver Postprocessing -------------------------" << endl; + for (iZone = 0; iZone < nZone; iZone++) { + if (numerics_container[iZone] != nullptr) { + delete [] numerics_container[iZone]; + } + } + delete [] numerics_container; + if (rank == MASTER_NODE) cout << "Deleted CNumerics container." << endl; + + for (iZone = 0; iZone < nZone; iZone++) { + if (solver_container[iZone] != nullptr) { + delete [] solver_container[iZone]; + } + } + delete [] solver_container; + if (rank == MASTER_NODE) cout << "Deleted CSolver container." << endl; + if (geometry_container != nullptr) { for (iZone = 0; iZone < nZone; iZone++) { if (geometry_container[iZone] != nullptr) { for (iInst = 0; iInst < nInst[iZone]; iInst++){ - delete geometry_container[iZone][iInst]; + delete geometry_container[iZone][iInst][MESH_0]; + delete [] geometry_container[iZone][iInst]; } - delete geometry_container[iZone]; + delete [] geometry_container[iZone]; } } delete [] geometry_container; } if (rank == MASTER_NODE) cout << "Deleted CGeometry container." << endl; + for (iZone = 0; iZone < nZone; iZone++) { + delete [] FFDBox[iZone]; + } + delete [] FFDBox; + if (rank == MASTER_NODE) cout << "Deleted CFreeFormDefBox class." << endl; + if (surface_movement != nullptr) { for (iZone = 0; iZone < nZone; iZone++) { delete surface_movement[iZone]; @@ -388,7 +397,12 @@ void CDiscAdjDeformationDriver::Postprocessing() { if (grid_movement != nullptr) { for (iZone = 0; iZone < nZone; iZone++) { - delete grid_movement[iZone]; + if (grid_movement[iZone] != nullptr) { + for (iInst = 0; iInst < nInst[iZone]; iInst++){ + delete grid_movement[iZone][iInst]; + } + delete [] grid_movement[iZone]; + } } delete [] grid_movement; } @@ -402,6 +416,21 @@ void CDiscAdjDeformationDriver::Postprocessing() { } if (rank == MASTER_NODE) cout << "Deleted CConfig container." << endl; + if (output_container != nullptr) { + for (iZone = 0; iZone < nZone; iZone++) { + delete output_container[iZone]; + } + delete [] output_container; + } + if (rank == MASTER_NODE) cout << "Deleted COutput class." << endl; + + if (nInst != nullptr) delete [] nInst; + + /*--- Exit the solver cleanly ---*/ + + if (rank == MASTER_NODE) + cout << endl << "------------------------- Exit Success (SU2_DEF_AD) ------------------------" << endl << endl; + } void CDiscAdjDeformationDriver::SetProjection_FD(CGeometry *geometry, CConfig *config, CSurfaceMovement *surface_movement, su2double** Gradient){ @@ -816,7 +845,7 @@ void CDiscAdjDeformationDriver::OutputGradient(su2double** Gradient, CConfig* co } -void CDiscAdjDeformationDriver::SetSensitivity_Files(CGeometry ***geometry, CConfig **config, unsigned short val_nZone) { +void CDiscAdjDeformationDriver::SetSensitivity_Files(CGeometry ****geometry, CConfig **config, unsigned short val_nZone) { unsigned short iMarker,iDim, nDim, nMarker, nVar; unsigned long iVertex, iPoint, nPoint, nVertex; @@ -829,8 +858,8 @@ void CDiscAdjDeformationDriver::SetSensitivity_Files(CGeometry ***geometry, CCon for (iZone = 0; iZone < val_nZone; iZone++) { - nPoint = geometry[iZone][INST_0]->GetnPoint(); - nDim = geometry[iZone][INST_0]->GetnDim(); + nPoint = geometry[iZone][INST_0][MESH_0]->GetnPoint(); + nDim = geometry[iZone][INST_0][MESH_0]->GetnDim(); nMarker = config[iZone]->GetnMarker_All(); nVar = nDim + 1; @@ -850,12 +879,12 @@ void CDiscAdjDeformationDriver::SetSensitivity_Files(CGeometry ***geometry, CCon } fieldnames.push_back("\"Surface_Sensitivity\""); - solver = new CBaselineSolver(geometry[iZone][INST_0], config[iZone], nVar+nDim, fieldnames); + solver = new CBaselineSolver(geometry[iZone][INST_0][MESH_0], config[iZone], nVar+nDim, fieldnames); for (iPoint = 0; iPoint < nPoint; iPoint++) { for (iDim = 0; iDim < nDim; iDim++) { - solver->GetNodes()->SetSolution(iPoint, iDim, geometry[iZone][INST_0]->nodes->GetCoord(iPoint, iDim)); - solver->GetNodes()->SetSolution(iPoint, iDim+nDim, geometry[iZone][INST_0]->GetSensitivity(iPoint, iDim)); + solver->GetNodes()->SetSolution(iPoint, iDim, geometry[iZone][INST_0][MESH_0]->nodes->GetCoord(iPoint, iDim)); + solver->GetNodes()->SetSolution(iPoint, iDim+nDim, geometry[iZone][INST_0][MESH_0]->GetSensitivity(iPoint, iDim)); } } @@ -865,18 +894,18 @@ void CDiscAdjDeformationDriver::SetSensitivity_Files(CGeometry ***geometry, CCon if(config[iZone]->GetSolid_Wall(iMarker) || (config[iZone]->GetMarker_All_DV(iMarker) == YES )) { - nVertex = geometry[iZone][INST_0]->GetnVertex(iMarker); + nVertex = geometry[iZone][INST_0][MESH_0]->GetnVertex(iMarker); for (iVertex = 0; iVertex < nVertex; iVertex++) { - iPoint = geometry[iZone][INST_0]->vertex[iMarker][iVertex]->GetNode(); - Normal = geometry[iZone][INST_0]->vertex[iMarker][iVertex]->GetNormal(); + iPoint = geometry[iZone][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); + Normal = geometry[iZone][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNormal(); Prod = 0.0; Area = 0.0; for (iDim = 0; iDim < nDim; iDim++) { /*--- Retrieve the gradient calculated with discrete adjoint method ---*/ - SensDim = geometry[iZone][INST_0]->GetSensitivity(iPoint, iDim); + SensDim = geometry[iZone][INST_0][MESH_0]->GetSensitivity(iPoint, iDim); /*--- Calculate scalar product for projection onto the normal vector ---*/ @@ -903,7 +932,7 @@ void CDiscAdjDeformationDriver::SetSensitivity_Files(CGeometry ***geometry, CCon /*--- Load the data --- */ - output->Load_Data(geometry[iZone][INST_0], config[iZone], &solver); + output->Load_Data(geometry[iZone][INST_0][MESH_0], config[iZone], &solver); /*--- Set the surface filename ---*/ @@ -920,7 +949,7 @@ void CDiscAdjDeformationDriver::SetSensitivity_Files(CGeometry ***geometry, CCon if (FileFormat[iFile] != OUTPUT_TYPE::RESTART_ASCII && FileFormat[iFile] != OUTPUT_TYPE::RESTART_BINARY && FileFormat[iFile] != OUTPUT_TYPE::CSV) - output->WriteToFile(config[iZone], geometry[iZone][INST_0], FileFormat[iFile]); + output->WriteToFile(config[iZone], geometry[iZone][INST_0][MESH_0], FileFormat[iFile]); } /*--- Free memory ---*/ From 58dd9716b427dcdda705eddd5dea8f1519ac8858 Mon Sep 17 00:00:00 2001 From: patelha57 Date: Sun, 20 Feb 2022 14:37:30 -0800 Subject: [PATCH 19/68] Run clang-format on files --- Common/src/drivers/CDriverBase.cpp | 14 +- SU2_CFD/src/drivers/CDriver.cpp | 7264 ++++++++--------- SU2_CFD/src/python_wrapper_structure.cpp | 1034 +-- SU2_DEF/include/SU2_DEF.hpp | 1 - .../include/drivers/CDeformationDriver.hpp | 134 +- .../drivers/CDiscAdjDeformationDriver.hpp | 2 +- SU2_DEF/src/SU2_DEF.cpp | 79 +- SU2_DEF/src/drivers/CDeformationDriver.cpp | 24 +- .../src/drivers/CDiscAdjDeformationDriver.cpp | 16 +- 9 files changed, 4283 insertions(+), 4285 deletions(-) diff --git a/Common/src/drivers/CDriverBase.cpp b/Common/src/drivers/CDriverBase.cpp index 4ec2d3b1a27..98d05d65305 100644 --- a/Common/src/drivers/CDriverBase.cpp +++ b/Common/src/drivers/CDriverBase.cpp @@ -33,12 +33,12 @@ using namespace std; CDriverBase::CDriverBase(char* confFile, unsigned short val_nZone, SU2_Comm MPICommunicator): - config_file_name(confFile), - StartTime(0.0), - StopTime(0.0), - UsedTime(0.0), - TimeIter(0), - nZone(val_nZone) +config_file_name(confFile), +StartTime(0.0), +StopTime(0.0), +UsedTime(0.0), +TimeIter(0), +nZone(val_nZone) { } @@ -77,7 +77,7 @@ void CDriverBase::SetContainers_Null() { for (iZone = 0; iZone < nZone; iZone++) { nInst[iZone] = 1; } - + driver_config = nullptr; driver_output = nullptr; } diff --git a/SU2_CFD/src/drivers/CDriver.cpp b/SU2_CFD/src/drivers/CDriver.cpp index 53ec9afc51a..082a777d36c 100644 --- a/SU2_CFD/src/drivers/CDriver.cpp +++ b/SU2_CFD/src/drivers/CDriver.cpp @@ -107,3889 +107,3889 @@ #include CDriver::CDriver(char* confFile, unsigned short val_nZone, SU2_Comm MPICommunicator, bool dummy_geo) : - CDriverBase(confFile, val_nZone, MPICommunicator), StopCalc(false), fsi(false), fem_solver(false), dry_run(dummy_geo) { - - /*--- Initialize Medipack (must also be here so it is initialized from python) ---*/ +CDriverBase(confFile, val_nZone, MPICommunicator), StopCalc(false), fsi(false), fem_solver(false), dry_run(dummy_geo) { + + /*--- Initialize Medipack (must also be here so it is initialized from python) ---*/ #ifdef HAVE_MPI - #if defined(CODI_REVERSE_TYPE) || defined(CODI_FORWARD_TYPE) +#if defined(CODI_REVERSE_TYPE) || defined(CODI_FORWARD_TYPE) SU2_MPI::Init_AMPI(); - #endif #endif - - SU2_MPI::SetComm(MPICommunicator); - - rank = SU2_MPI::GetRank(); - size = SU2_MPI::GetSize(); - - /*--- Start timer to track preprocessing for benchmarking. ---*/ - - StartTime = SU2_MPI::Wtime(); - - /*--- Initialize containers with null --- */ - - SetContainers_Null(); - - /*--- Preprocessing of the config files. ---*/ - - Input_Preprocessing(config_container, driver_config); - - /*--- Retrieve dimension from mesh file ---*/ - - nDim = CConfig::GetnDim(config_container[ZONE_0]->GetMesh_FileName(), - config_container[ZONE_0]->GetMesh_FileFormat()); - - /*--- Output preprocessing ---*/ - - Output_Preprocessing(config_container, driver_config, output_container, driver_output); - - - for (iZone = 0; iZone < nZone; iZone++) { - - /*--- Read the number of instances for each zone ---*/ - - nInst[iZone] = config_container[iZone]->GetnTimeInstances(); - - geometry_container[iZone] = new CGeometry** [nInst[iZone]] (); - iteration_container[iZone] = new CIteration* [nInst[iZone]] (); - solver_container[iZone] = new CSolver*** [nInst[iZone]] (); - integration_container[iZone] = new CIntegration** [nInst[iZone]] (); - numerics_container[iZone] = new CNumerics**** [nInst[iZone]] (); - grid_movement[iZone] = new CVolumetricMovement* [nInst[iZone]] (); - - /*--- Allocate transfer and interpolation container --- */ - - interface_container[iZone] = new CInterface*[nZone] (); - interpolator_container[iZone].resize(nZone); - - for (iInst = 0; iInst < nInst[iZone]; iInst++) { - - config_container[iZone]->SetiInst(iInst); - - /*--- Preprocessing of the geometry for all zones. In this routine, the edge- - based data structure is constructed, i.e. node and cell neighbors are - identified and linked, face areas and volumes of the dual mesh cells are - computed, and the multigrid levels are created using an agglomeration procedure. ---*/ - - Geometrical_Preprocessing(config_container[iZone], geometry_container[iZone][iInst], dry_run); - +#endif + + SU2_MPI::SetComm(MPICommunicator); + + rank = SU2_MPI::GetRank(); + size = SU2_MPI::GetSize(); + + /*--- Start timer to track preprocessing for benchmarking. ---*/ + + StartTime = SU2_MPI::Wtime(); + + /*--- Initialize containers with null --- */ + + SetContainers_Null(); + + /*--- Preprocessing of the config files. ---*/ + + Input_Preprocessing(config_container, driver_config); + + /*--- Retrieve dimension from mesh file ---*/ + + nDim = CConfig::GetnDim(config_container[ZONE_0]->GetMesh_FileName(), + config_container[ZONE_0]->GetMesh_FileFormat()); + + /*--- Output preprocessing ---*/ + + Output_Preprocessing(config_container, driver_config, output_container, driver_output); + + + for (iZone = 0; iZone < nZone; iZone++) { + + /*--- Read the number of instances for each zone ---*/ + + nInst[iZone] = config_container[iZone]->GetnTimeInstances(); + + geometry_container[iZone] = new CGeometry** [nInst[iZone]] (); + iteration_container[iZone] = new CIteration* [nInst[iZone]] (); + solver_container[iZone] = new CSolver*** [nInst[iZone]] (); + integration_container[iZone] = new CIntegration** [nInst[iZone]] (); + numerics_container[iZone] = new CNumerics**** [nInst[iZone]] (); + grid_movement[iZone] = new CVolumetricMovement* [nInst[iZone]] (); + + /*--- Allocate transfer and interpolation container --- */ + + interface_container[iZone] = new CInterface*[nZone] (); + interpolator_container[iZone].resize(nZone); + + for (iInst = 0; iInst < nInst[iZone]; iInst++) { + + config_container[iZone]->SetiInst(iInst); + + /*--- Preprocessing of the geometry for all zones. In this routine, the edge- + based data structure is constructed, i.e. node and cell neighbors are + identified and linked, face areas and volumes of the dual mesh cells are + computed, and the multigrid levels are created using an agglomeration procedure. ---*/ + + Geometrical_Preprocessing(config_container[iZone], geometry_container[iZone][iInst], dry_run); + + } } - } - - /*--- Before we proceed with the zone loop we have to compute the wall distances. + + /*--- Before we proceed with the zone loop we have to compute the wall distances. * This computation depends on all zones at once. ---*/ - if (rank == MASTER_NODE) - cout << "Computing wall distances." << endl; - - CGeometry::ComputeWallDistance(config_container, geometry_container); - - for (iZone = 0; iZone < nZone; iZone++) { - - for (iInst = 0; iInst < nInst[iZone]; iInst++){ - - /*--- Definition of the solver class: solver_container[#ZONES][#INSTANCES][#MG_GRIDS][#EQ_SYSTEMS]. - The solver classes are specific to a particular set of governing equations, - and they contain the subroutines with instructions for computing each spatial - term of the PDE, i.e. loops over the edges to compute convective and viscous - fluxes, loops over the nodes to compute source terms, and routines for - imposing various boundary condition type for the PDE. ---*/ - - Solver_Preprocessing(config_container[iZone], geometry_container[iZone][iInst], solver_container[iZone][iInst]); - - /*--- Definition of the numerical method class: - numerics_container[#ZONES][#INSTANCES][#MG_GRIDS][#EQ_SYSTEMS][#EQ_TERMS]. - The numerics class contains the implementation of the numerical methods for - evaluating convective or viscous fluxes between any two nodes in the edge-based - data structure (centered, upwind, galerkin), as well as any source terms - (piecewise constant reconstruction) evaluated in each dual mesh volume. ---*/ - - Numerics_Preprocessing(config_container[iZone], geometry_container[iZone][iInst], - solver_container[iZone][iInst], numerics_container[iZone][iInst]); - - /*--- Definition of the integration class: integration_container[#ZONES][#INSTANCES][#EQ_SYSTEMS]. - The integration class orchestrates the execution of the spatial integration - subroutines contained in the solver class (including multigrid) for computing - the residual at each node, R(U) and then integrates the equations to a - steady state or time-accurately. ---*/ - - Integration_Preprocessing(config_container[iZone], solver_container[iZone][iInst][MESH_0], - integration_container[iZone][iInst]); - - /*--- Instantiate the type of physics iteration to be executed within each zone. For - example, one can execute the same physics across multiple zones (mixing plane), - different physics in different zones (fluid-structure interaction), or couple multiple - systems tightly within a single zone by creating a new iteration class (e.g., RANS). ---*/ - - Iteration_Preprocessing(config_container[iZone], iteration_container[iZone][iInst]); - - /*--- Dynamic mesh processing. ---*/ - - DynamicMesh_Preprocessing(config_container[iZone], geometry_container[iZone][iInst], solver_container[iZone][iInst], - iteration_container[iZone][iInst], grid_movement[iZone][iInst], surface_movement[iZone]); - /*--- Static mesh processing. ---*/ - - StaticMesh_Preprocessing(config_container[iZone], geometry_container[iZone][iInst]); - - } - - } - - /*! --- Compute the wall distance again to correctly compute the derivatives if we are running direct diff mode --- */ - if (driver_config->GetDirectDiff() == D_DESIGN){ - CGeometry::ComputeWallDistance(config_container, geometry_container); - } - - /*--- Definition of the interface and transfer conditions between different zones. ---*/ - - if (nZone > 1) { if (rank == MASTER_NODE) - cout << endl <<"------------------- Multizone Interface Preprocessing -------------------" << endl; - - Interface_Preprocessing(config_container, solver_container, geometry_container, - interface_types, interface_container, interpolator_container); - } - - if (fsi) { + cout << "Computing wall distances." << endl; + + CGeometry::ComputeWallDistance(config_container, geometry_container); + for (iZone = 0; iZone < nZone; iZone++) { - for (iInst = 0; iInst < nInst[iZone]; iInst++){ - Solver_Restart(solver_container[iZone][iInst], geometry_container[iZone][iInst], - config_container[iZone], true); - } + + for (iInst = 0; iInst < nInst[iZone]; iInst++){ + + /*--- Definition of the solver class: solver_container[#ZONES][#INSTANCES][#MG_GRIDS][#EQ_SYSTEMS]. + The solver classes are specific to a particular set of governing equations, + and they contain the subroutines with instructions for computing each spatial + term of the PDE, i.e. loops over the edges to compute convective and viscous + fluxes, loops over the nodes to compute source terms, and routines for + imposing various boundary condition type for the PDE. ---*/ + + Solver_Preprocessing(config_container[iZone], geometry_container[iZone][iInst], solver_container[iZone][iInst]); + + /*--- Definition of the numerical method class: + numerics_container[#ZONES][#INSTANCES][#MG_GRIDS][#EQ_SYSTEMS][#EQ_TERMS]. + The numerics class contains the implementation of the numerical methods for + evaluating convective or viscous fluxes between any two nodes in the edge-based + data structure (centered, upwind, galerkin), as well as any source terms + (piecewise constant reconstruction) evaluated in each dual mesh volume. ---*/ + + Numerics_Preprocessing(config_container[iZone], geometry_container[iZone][iInst], + solver_container[iZone][iInst], numerics_container[iZone][iInst]); + + /*--- Definition of the integration class: integration_container[#ZONES][#INSTANCES][#EQ_SYSTEMS]. + The integration class orchestrates the execution of the spatial integration + subroutines contained in the solver class (including multigrid) for computing + the residual at each node, R(U) and then integrates the equations to a + steady state or time-accurately. ---*/ + + Integration_Preprocessing(config_container[iZone], solver_container[iZone][iInst][MESH_0], + integration_container[iZone][iInst]); + + /*--- Instantiate the type of physics iteration to be executed within each zone. For + example, one can execute the same physics across multiple zones (mixing plane), + different physics in different zones (fluid-structure interaction), or couple multiple + systems tightly within a single zone by creating a new iteration class (e.g., RANS). ---*/ + + Iteration_Preprocessing(config_container[iZone], iteration_container[iZone][iInst]); + + /*--- Dynamic mesh processing. ---*/ + + DynamicMesh_Preprocessing(config_container[iZone], geometry_container[iZone][iInst], solver_container[iZone][iInst], + iteration_container[iZone][iInst], grid_movement[iZone][iInst], surface_movement[iZone]); + /*--- Static mesh processing. ---*/ + + StaticMesh_Preprocessing(config_container[iZone], geometry_container[iZone][iInst]); + + } + } - } - - if (config_container[ZONE_0]->GetBoolTurbomachinery()){ - if (rank == MASTER_NODE) - cout << endl <<"---------------------- Turbomachinery Preprocessing ---------------------" << endl; - - Turbomachinery_Preprocessing(config_container, geometry_container, solver_container, interface_container); - } - - - PythonInterface_Preprocessing(config_container, geometry_container, solver_container); - - - /*--- Preprocessing time is reported now, but not included in the next compute portion. ---*/ - - StopTime = SU2_MPI::Wtime(); - - /*--- Compute/print the total time for performance benchmarking. ---*/ - - UsedTime = StopTime-StartTime; - UsedTimePreproc = UsedTime; - UsedTimeCompute = 0.0; - UsedTimeOutput = 0.0; - IterCount = 0; - OutputCount = 0; - MDOFs = 0.0; - MDOFsDomain = 0.0; - Mpoints = 0.0; - MpointsDomain = 0.0; - for (iZone = 0; iZone < nZone; iZone++) { - Mpoints += geometry_container[iZone][INST_0][MESH_0]->GetGlobal_nPoint()/(1.0e6); - MpointsDomain += geometry_container[iZone][INST_0][MESH_0]->GetGlobal_nPointDomain()/(1.0e6); - MDOFs += DOFsPerPoint*geometry_container[iZone][INST_0][MESH_0]->GetGlobal_nPoint()/(1.0e6); - MDOFsDomain += DOFsPerPoint*geometry_container[iZone][INST_0][MESH_0]->GetGlobal_nPointDomain()/(1.0e6); - } - - /*--- Reset timer for compute/output performance benchmarking. ---*/ - - StopTime = SU2_MPI::Wtime(); - - /*--- Compute/print the total time for performance benchmarking. ---*/ - - UsedTime = StopTime-StartTime; - UsedTimePreproc = UsedTime; - - /*--- Reset timer for compute performance benchmarking. ---*/ - - StartTime = SU2_MPI::Wtime(); - + + /*! --- Compute the wall distance again to correctly compute the derivatives if we are running direct diff mode --- */ + if (driver_config->GetDirectDiff() == D_DESIGN){ + CGeometry::ComputeWallDistance(config_container, geometry_container); + } + + /*--- Definition of the interface and transfer conditions between different zones. ---*/ + + if (nZone > 1) { + if (rank == MASTER_NODE) + cout << endl <<"------------------- Multizone Interface Preprocessing -------------------" << endl; + + Interface_Preprocessing(config_container, solver_container, geometry_container, + interface_types, interface_container, interpolator_container); + } + + if (fsi) { + for (iZone = 0; iZone < nZone; iZone++) { + for (iInst = 0; iInst < nInst[iZone]; iInst++){ + Solver_Restart(solver_container[iZone][iInst], geometry_container[iZone][iInst], + config_container[iZone], true); + } + } + } + + if (config_container[ZONE_0]->GetBoolTurbomachinery()){ + if (rank == MASTER_NODE) + cout << endl <<"---------------------- Turbomachinery Preprocessing ---------------------" << endl; + + Turbomachinery_Preprocessing(config_container, geometry_container, solver_container, interface_container); + } + + + PythonInterface_Preprocessing(config_container, geometry_container, solver_container); + + + /*--- Preprocessing time is reported now, but not included in the next compute portion. ---*/ + + StopTime = SU2_MPI::Wtime(); + + /*--- Compute/print the total time for performance benchmarking. ---*/ + + UsedTime = StopTime-StartTime; + UsedTimePreproc = UsedTime; + UsedTimeCompute = 0.0; + UsedTimeOutput = 0.0; + IterCount = 0; + OutputCount = 0; + MDOFs = 0.0; + MDOFsDomain = 0.0; + Mpoints = 0.0; + MpointsDomain = 0.0; + for (iZone = 0; iZone < nZone; iZone++) { + Mpoints += geometry_container[iZone][INST_0][MESH_0]->GetGlobal_nPoint()/(1.0e6); + MpointsDomain += geometry_container[iZone][INST_0][MESH_0]->GetGlobal_nPointDomain()/(1.0e6); + MDOFs += DOFsPerPoint*geometry_container[iZone][INST_0][MESH_0]->GetGlobal_nPoint()/(1.0e6); + MDOFsDomain += DOFsPerPoint*geometry_container[iZone][INST_0][MESH_0]->GetGlobal_nPointDomain()/(1.0e6); + } + + /*--- Reset timer for compute/output performance benchmarking. ---*/ + + StopTime = SU2_MPI::Wtime(); + + /*--- Compute/print the total time for performance benchmarking. ---*/ + + UsedTime = StopTime-StartTime; + UsedTimePreproc = UsedTime; + + /*--- Reset timer for compute performance benchmarking. ---*/ + + StartTime = SU2_MPI::Wtime(); + } void CDriver::SetContainers_Null(){ - - /*--- Create pointers to all of the classes that may be used throughout - the SU2_CFD code. In general, the pointers are instantiated down a - hierarchy over all zones, multigrid levels, equation sets, and equation - terms as described in the comments below. ---*/ - - ConvHist_file = nullptr; - iteration_container = nullptr; - output_container = nullptr; - integration_container = nullptr; - geometry_container = nullptr; - solver_container = nullptr; - numerics_container = nullptr; - config_container = nullptr; - surface_movement = nullptr; - grid_movement = nullptr; - FFDBox = nullptr; - interface_container = nullptr; - interface_types = nullptr; - nInst = nullptr; - - /*--- Definition and of the containers for all possible zones. ---*/ - - iteration_container = new CIteration**[nZone] (); - solver_container = new CSolver****[nZone] (); - integration_container = new CIntegration***[nZone] (); - numerics_container = new CNumerics*****[nZone] (); - config_container = new CConfig*[nZone] (); - geometry_container = new CGeometry***[nZone] (); - surface_movement = new CSurfaceMovement*[nZone] (); - grid_movement = new CVolumetricMovement**[nZone] (); - FFDBox = new CFreeFormDefBox**[nZone] (); - interpolator_container.resize(nZone); - interface_container = new CInterface**[nZone] (); - interface_types = new unsigned short*[nZone] (); - output_container = new COutput*[nZone] (); - nInst = new unsigned short[nZone] (); // TODO: remove (moved to base class) - driver_config = nullptr; - driver_output = nullptr; - - for (iZone = 0; iZone < nZone; iZone++) { - interface_types[iZone] = new unsigned short[nZone]; - nInst[iZone] = 1; - } - - strcpy(runtime_file_name, "runtime.dat"); - + + /*--- Create pointers to all of the classes that may be used throughout + the SU2_CFD code. In general, the pointers are instantiated down a + hierarchy over all zones, multigrid levels, equation sets, and equation + terms as described in the comments below. ---*/ + + ConvHist_file = nullptr; + iteration_container = nullptr; + output_container = nullptr; + integration_container = nullptr; + geometry_container = nullptr; + solver_container = nullptr; + numerics_container = nullptr; + config_container = nullptr; + surface_movement = nullptr; + grid_movement = nullptr; + FFDBox = nullptr; + interface_container = nullptr; + interface_types = nullptr; + nInst = nullptr; + + /*--- Definition and of the containers for all possible zones. ---*/ + + iteration_container = new CIteration**[nZone] (); + solver_container = new CSolver****[nZone] (); + integration_container = new CIntegration***[nZone] (); + numerics_container = new CNumerics*****[nZone] (); + config_container = new CConfig*[nZone] (); + geometry_container = new CGeometry***[nZone] (); + surface_movement = new CSurfaceMovement*[nZone] (); + grid_movement = new CVolumetricMovement**[nZone] (); + FFDBox = new CFreeFormDefBox**[nZone] (); + interpolator_container.resize(nZone); + interface_container = new CInterface**[nZone] (); + interface_types = new unsigned short*[nZone] (); + output_container = new COutput*[nZone] (); + nInst = new unsigned short[nZone] (); // TODO: remove (moved to base class) + driver_config = nullptr; + driver_output = nullptr; + + for (iZone = 0; iZone < nZone; iZone++) { + interface_types[iZone] = new unsigned short[nZone]; + nInst[iZone] = 1; + } + + strcpy(runtime_file_name, "runtime.dat"); + } void CDriver::Postprocessing() { - - const bool wrt_perf = config_container[ZONE_0]->GetWrt_Performance(); - + + const bool wrt_perf = config_container[ZONE_0]->GetWrt_Performance(); + /*--- Output some information to the console. ---*/ - - if (rank == MASTER_NODE) { - - /*--- Print out the number of non-physical points and reconstructions ---*/ - - if (config_container[ZONE_0]->GetNonphysical_Points() > 0) - cout << "Warning: there are " << config_container[ZONE_0]->GetNonphysical_Points() << " non-physical points in the solution." << endl; - if (config_container[ZONE_0]->GetNonphysical_Reconstr() > 0) - cout << "Warning: " << config_container[ZONE_0]->GetNonphysical_Reconstr() << " reconstructed states for upwinding are non-physical." << endl; - } - - if (rank == MASTER_NODE) - cout << endl <<"------------------------- Solver Postprocessing -------------------------" << endl; - - for (iZone = 0; iZone < nZone; iZone++) { - for (iInst = 0; iInst < nInst[iZone]; iInst++){ - Numerics_Postprocessing(numerics_container[iZone], solver_container[iZone][iInst], - geometry_container[iZone][iInst], config_container[iZone], iInst); - } - delete [] numerics_container[iZone]; - } - delete [] numerics_container; - if (rank == MASTER_NODE) cout << "Deleted CNumerics container." << endl; - - for (iZone = 0; iZone < nZone; iZone++) { - for (iInst = 0; iInst < nInst[iZone]; iInst++){ - Integration_Postprocessing(integration_container[iZone], - geometry_container[iZone][iInst], - config_container[iZone], - iInst); - } - delete [] integration_container[iZone]; - } - delete [] integration_container; - if (rank == MASTER_NODE) cout << "Deleted CIntegration container." << endl; - - for (iZone = 0; iZone < nZone; iZone++) { - for (iInst = 0; iInst < nInst[iZone]; iInst++){ - Solver_Postprocessing(solver_container[iZone], - geometry_container[iZone][iInst], - config_container[iZone], - iInst); - } - delete [] solver_container[iZone]; - } - delete [] solver_container; - if (rank == MASTER_NODE) cout << "Deleted CSolver container." << endl; - - for (iZone = 0; iZone < nZone; iZone++) { - for (iInst = 0; iInst < nInst[iZone]; iInst++) - delete iteration_container[iZone][iInst]; - delete [] iteration_container[iZone]; - } - delete [] iteration_container; - if (rank == MASTER_NODE) cout << "Deleted CIteration container." << endl; - - if (interface_container != nullptr) { + + if (rank == MASTER_NODE) { + + /*--- Print out the number of non-physical points and reconstructions ---*/ + + if (config_container[ZONE_0]->GetNonphysical_Points() > 0) + cout << "Warning: there are " << config_container[ZONE_0]->GetNonphysical_Points() << " non-physical points in the solution." << endl; + if (config_container[ZONE_0]->GetNonphysical_Reconstr() > 0) + cout << "Warning: " << config_container[ZONE_0]->GetNonphysical_Reconstr() << " reconstructed states for upwinding are non-physical." << endl; + } + + if (rank == MASTER_NODE) + cout << endl <<"------------------------- Solver Postprocessing -------------------------" << endl; + for (iZone = 0; iZone < nZone; iZone++) { - if (interface_container[iZone] != nullptr) { - for (unsigned short jZone = 0; jZone < nZone; jZone++) - delete interface_container[iZone][jZone]; - delete [] interface_container[iZone]; - } + for (iInst = 0; iInst < nInst[iZone]; iInst++){ + Numerics_Postprocessing(numerics_container[iZone], solver_container[iZone][iInst], + geometry_container[iZone][iInst], config_container[iZone], iInst); + } + delete [] numerics_container[iZone]; } - delete [] interface_container; - if (rank == MASTER_NODE) cout << "Deleted CInterface container." << endl; - } - - if (interface_types != nullptr) { - for (iZone = 0; iZone < nZone; iZone++) - delete [] interface_types[iZone]; - delete [] interface_types; - } - - for (iZone = 0; iZone < nZone; iZone++) { - if (geometry_container[iZone] != nullptr) { - for (iInst = 0; iInst < nInst[iZone]; iInst++){ - for (unsigned short iMGlevel = 0; iMGlevel < config_container[iZone]->GetnMGLevels()+1; iMGlevel++) - delete geometry_container[iZone][iInst][iMGlevel]; - delete [] geometry_container[iZone][iInst]; - } - delete [] geometry_container[iZone]; - } - } - delete [] geometry_container; - if (rank == MASTER_NODE) cout << "Deleted CGeometry container." << endl; - - for (iZone = 0; iZone < nZone; iZone++) { - delete [] FFDBox[iZone]; - } - delete [] FFDBox; - if (rank == MASTER_NODE) cout << "Deleted CFreeFormDefBox class." << endl; - - for (iZone = 0; iZone < nZone; iZone++) { - delete surface_movement[iZone]; - } - delete [] surface_movement; - if (rank == MASTER_NODE) cout << "Deleted CSurfaceMovement class." << endl; - - for (iZone = 0; iZone < nZone; iZone++) { - for (iInst = 0; iInst < nInst[iZone]; iInst++) - delete grid_movement[iZone][iInst]; - delete [] grid_movement[iZone]; - } - delete [] grid_movement; - if (rank == MASTER_NODE) cout << "Deleted CVolumetricMovement class." << endl; - - /*--- Output profiling information ---*/ - // Note that for now this is called only by a single thread, but all - // necessary variables have been made thread private for safety (tick/tock)!! - - config_container[ZONE_0]->SetProfilingCSV(); - config_container[ZONE_0]->GEMMProfilingCSV(); - - /*--- Deallocate config container ---*/ - if (config_container!= nullptr) { - for (iZone = 0; iZone < nZone; iZone++) - delete config_container[iZone]; - delete [] config_container; - } - delete driver_config; - if (rank == MASTER_NODE) cout << "Deleted CConfig container." << endl; - - delete [] nInst; - if (rank == MASTER_NODE) cout << "Deleted nInst container." << endl; - - /*--- Deallocate output container ---*/ - - if (output_container!= nullptr) { - for (iZone = 0; iZone < nZone; iZone++) - delete output_container[iZone]; - delete [] output_container; - } - - delete driver_output; - - if (rank == MASTER_NODE) cout << "Deleted COutput class." << endl; - - if (rank == MASTER_NODE) cout << "-------------------------------------------------------------------------" << endl; - - - /*--- Stop the timer and output the final performance summary. ---*/ - - StopTime = SU2_MPI::Wtime(); - - UsedTime = StopTime-StartTime; - UsedTimeCompute += UsedTime; - - if ((rank == MASTER_NODE) && (wrt_perf)) { - su2double TotalTime = UsedTimePreproc + UsedTimeCompute + UsedTimeOutput; - cout.precision(6); - cout << endl << endl <<"-------------------------- Performance Summary --------------------------" << endl; - cout << "Simulation totals:" << endl; - cout << setw(25) << "Wall-clock time (hrs):" << setw(12) << (TotalTime)/(60.0*60.0) << " | "; - cout << setw(20) << "Core-hrs:" << setw(12) << size*TotalTime/(60.0*60.0) << endl; - cout << setw(25) << "Cores:" << setw(12) << size << " | "; - cout << setw(20) << "DOFs/point:" << setw(12) << DOFsPerPoint << endl; - cout << setw(25) << "Points/core:" << setw(12) << 1.0e6*MpointsDomain/size << " | "; - cout << setw(20) << "Ghost points/core:" << setw(12) << 1.0e6*(Mpoints-MpointsDomain)/size << endl; - cout << setw(25) << "Ghost/Owned Point Ratio:" << setw(12) << (Mpoints-MpointsDomain)/MpointsDomain << " | " << endl; - cout << endl; - cout << "Preprocessing phase:" << endl; - cout << setw(25) << "Preproc. Time (s):" << setw(12)<< UsedTimePreproc << " | "; - cout << setw(20) << "Preproc. Time (%):" << setw(12)<< ((UsedTimePreproc * 100.0) / (TotalTime)) << endl; - cout << endl; - cout << "Compute phase:" << endl; - cout << setw(25) << "Compute Time (s):" << setw(12)<< UsedTimeCompute << " | "; - cout << setw(20) << "Compute Time (%):" << setw(12)<< ((UsedTimeCompute * 100.0) / (TotalTime)) << endl; - cout << setw(25) << "Iteration count:" << setw(12)<< IterCount << " | "; - if (IterCount != 0) { - cout << setw(20) << "Avg. s/iter:" << setw(12)<< UsedTimeCompute/IterCount << endl; - cout << setw(25) << "Core-s/iter/Mpoints:" << setw(12)<< size*UsedTimeCompute/IterCount/Mpoints << " | "; - cout << setw(20) << "Mpoints/s:" << setw(12)<< Mpoints*IterCount/UsedTimeCompute << endl; - } else cout << endl; - cout << endl; - cout << "Output phase:" << endl; - cout << setw(25) << "Output Time (s):" << setw(12)<< UsedTimeOutput << " | "; - cout << setw(20) << "Output Time (%):" << setw(12)<< ((UsedTimeOutput * 100.0) / (TotalTime)) << endl; - cout << setw(25) << "Output count:" << setw(12)<< OutputCount << " | "; - if (OutputCount != 0) { - cout << setw(20)<< "Avg. s/output:" << setw(12)<< UsedTimeOutput/OutputCount << endl; - if (BandwidthSum > 0) { - cout << setw(25)<< "Restart Aggr. BW (MB/s):" << setw(12)<< BandwidthSum/OutputCount << " | "; - cout << setw(20)<< "MB/s/core:" << setw(12)<< BandwidthSum/OutputCount/size << endl; - } - } else cout << endl; - cout << "-------------------------------------------------------------------------" << endl; - cout << endl; - } - - /*--- Exit the solver cleanly ---*/ - - if (rank == MASTER_NODE) - cout << endl <<"------------------------- Exit Success (SU2_CFD) ------------------------" << endl << endl; - -} - - -void CDriver::Input_Preprocessing(CConfig **&config, CConfig *&driver_config) { - - char zone_file_name[MAX_STRING_SIZE]; - - /*--- Initialize the configuration of the driver ---*/ - - driver_config = new CConfig(config_file_name, SU2_COMPONENT::SU2_CFD, false); - - for (iZone = 0; iZone < nZone; iZone++) { - - if (rank == MASTER_NODE){ - cout << endl << "Parsing config file for zone " << iZone << endl; + delete [] numerics_container; + if (rank == MASTER_NODE) cout << "Deleted CNumerics container." << endl; + + for (iZone = 0; iZone < nZone; iZone++) { + for (iInst = 0; iInst < nInst[iZone]; iInst++){ + Integration_Postprocessing(integration_container[iZone], + geometry_container[iZone][iInst], + config_container[iZone], + iInst); + } + delete [] integration_container[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. ---*/ - - if (driver_config->GetnConfigFiles() > 0){ - - strcpy(zone_file_name, driver_config->GetConfigFilename(iZone).c_str()); - config[iZone] = new CConfig(driver_config, zone_file_name, SU2_COMPONENT::SU2_CFD, iZone, nZone, true); + delete [] integration_container; + if (rank == MASTER_NODE) cout << "Deleted CIntegration container." << endl; + + for (iZone = 0; iZone < nZone; iZone++) { + for (iInst = 0; iInst < nInst[iZone]; iInst++){ + Solver_Postprocessing(solver_container[iZone], + geometry_container[iZone][iInst], + config_container[iZone], + iInst); + } + delete [] solver_container[iZone]; } - else{ - config[iZone] = new CConfig(driver_config, config_file_name, SU2_COMPONENT::SU2_CFD, iZone, nZone, true); + delete [] solver_container; + if (rank == MASTER_NODE) cout << "Deleted CSolver container." << endl; + + for (iZone = 0; iZone < nZone; iZone++) { + for (iInst = 0; iInst < nInst[iZone]; iInst++) + delete iteration_container[iZone][iInst]; + delete [] iteration_container[iZone]; + } + delete [] iteration_container; + if (rank == MASTER_NODE) cout << "Deleted CIteration container." << endl; + + if (interface_container != nullptr) { + for (iZone = 0; iZone < nZone; iZone++) { + if (interface_container[iZone] != nullptr) { + for (unsigned short jZone = 0; jZone < nZone; jZone++) + delete interface_container[iZone][jZone]; + delete [] interface_container[iZone]; + } + } + delete [] interface_container; + if (rank == MASTER_NODE) cout << "Deleted CInterface container." << endl; } - - /*--- Set the MPI communicator ---*/ - - config[iZone]->SetMPICommunicator(SU2_MPI::GetComm()); - } - - - /*--- Set the multizone part of the problem. ---*/ - if (driver_config->GetMultizone_Problem()){ + + if (interface_types != nullptr) { + for (iZone = 0; iZone < nZone; iZone++) + delete [] interface_types[iZone]; + delete [] interface_types; + } + for (iZone = 0; iZone < nZone; iZone++) { - /*--- Set the interface markers for multizone ---*/ - config_container[iZone]->SetMultizone(driver_config, config_container); + if (geometry_container[iZone] != nullptr) { + for (iInst = 0; iInst < nInst[iZone]; iInst++){ + for (unsigned short iMGlevel = 0; iMGlevel < config_container[iZone]->GetnMGLevels()+1; iMGlevel++) + delete geometry_container[iZone][iInst][iMGlevel]; + delete [] geometry_container[iZone][iInst]; + } + delete [] geometry_container[iZone]; + } } - } - - /*--- Determine whether or not the FEM solver is used, which decides the type of - * geometry classes that are instantiated. Only adapted for single-zone problems ---*/ - - fem_solver = config_container[ZONE_0]->GetFEMSolver(); - - fsi = config_container[ZONE_0]->GetFSI_Simulation(); -} - -void CDriver::Geometrical_Preprocessing(CConfig* config, CGeometry **&geometry, bool dummy){ - - if (!dummy){ - if (rank == MASTER_NODE) - cout << endl <<"------------------- Geometry Preprocessing ( Zone " << config->GetiZone() <<" ) -------------------" << endl; - - if( fem_solver ) { - switch( config->GetKind_FEM_Flow() ) { - case DG: { - Geometrical_Preprocessing_DGFEM(config, geometry); - break; - } - } + delete [] geometry_container; + if (rank == MASTER_NODE) cout << "Deleted CGeometry container." << endl; + + for (iZone = 0; iZone < nZone; iZone++) { + delete [] FFDBox[iZone]; + } + delete [] FFDBox; + if (rank == MASTER_NODE) cout << "Deleted CFreeFormDefBox class." << endl; + + for (iZone = 0; iZone < nZone; iZone++) { + delete surface_movement[iZone]; } - else { - Geometrical_Preprocessing_FVM(config, geometry); + delete [] surface_movement; + if (rank == MASTER_NODE) cout << "Deleted CSurfaceMovement class." << endl; + + for (iZone = 0; iZone < nZone; iZone++) { + for (iInst = 0; iInst < nInst[iZone]; iInst++) + delete grid_movement[iZone][iInst]; + delete [] grid_movement[iZone]; + } + delete [] grid_movement; + if (rank == MASTER_NODE) cout << "Deleted CVolumetricMovement class." << endl; + + /*--- Output profiling information ---*/ + // Note that for now this is called only by a single thread, but all + // necessary variables have been made thread private for safety (tick/tock)!! + + config_container[ZONE_0]->SetProfilingCSV(); + config_container[ZONE_0]->GEMMProfilingCSV(); + + /*--- Deallocate config container ---*/ + if (config_container!= nullptr) { + for (iZone = 0; iZone < nZone; iZone++) + delete config_container[iZone]; + delete [] config_container; + } + delete driver_config; + if (rank == MASTER_NODE) cout << "Deleted CConfig container." << endl; + + delete [] nInst; + if (rank == MASTER_NODE) cout << "Deleted nInst container." << endl; + + /*--- Deallocate output container ---*/ + + if (output_container!= nullptr) { + for (iZone = 0; iZone < nZone; iZone++) + delete output_container[iZone]; + delete [] output_container; + } + + delete driver_output; + + if (rank == MASTER_NODE) cout << "Deleted COutput class." << endl; + + if (rank == MASTER_NODE) cout << "-------------------------------------------------------------------------" << endl; + + + /*--- Stop the timer and output the final performance summary. ---*/ + + StopTime = SU2_MPI::Wtime(); + + UsedTime = StopTime-StartTime; + UsedTimeCompute += UsedTime; + + if ((rank == MASTER_NODE) && (wrt_perf)) { + su2double TotalTime = UsedTimePreproc + UsedTimeCompute + UsedTimeOutput; + cout.precision(6); + cout << endl << endl <<"-------------------------- Performance Summary --------------------------" << endl; + cout << "Simulation totals:" << endl; + cout << setw(25) << "Wall-clock time (hrs):" << setw(12) << (TotalTime)/(60.0*60.0) << " | "; + cout << setw(20) << "Core-hrs:" << setw(12) << size*TotalTime/(60.0*60.0) << endl; + cout << setw(25) << "Cores:" << setw(12) << size << " | "; + cout << setw(20) << "DOFs/point:" << setw(12) << DOFsPerPoint << endl; + cout << setw(25) << "Points/core:" << setw(12) << 1.0e6*MpointsDomain/size << " | "; + cout << setw(20) << "Ghost points/core:" << setw(12) << 1.0e6*(Mpoints-MpointsDomain)/size << endl; + cout << setw(25) << "Ghost/Owned Point Ratio:" << setw(12) << (Mpoints-MpointsDomain)/MpointsDomain << " | " << endl; + cout << endl; + cout << "Preprocessing phase:" << endl; + cout << setw(25) << "Preproc. Time (s):" << setw(12)<< UsedTimePreproc << " | "; + cout << setw(20) << "Preproc. Time (%):" << setw(12)<< ((UsedTimePreproc * 100.0) / (TotalTime)) << endl; + cout << endl; + cout << "Compute phase:" << endl; + cout << setw(25) << "Compute Time (s):" << setw(12)<< UsedTimeCompute << " | "; + cout << setw(20) << "Compute Time (%):" << setw(12)<< ((UsedTimeCompute * 100.0) / (TotalTime)) << endl; + cout << setw(25) << "Iteration count:" << setw(12)<< IterCount << " | "; + if (IterCount != 0) { + cout << setw(20) << "Avg. s/iter:" << setw(12)<< UsedTimeCompute/IterCount << endl; + cout << setw(25) << "Core-s/iter/Mpoints:" << setw(12)<< size*UsedTimeCompute/IterCount/Mpoints << " | "; + cout << setw(20) << "Mpoints/s:" << setw(12)<< Mpoints*IterCount/UsedTimeCompute << endl; + } else cout << endl; + cout << endl; + cout << "Output phase:" << endl; + cout << setw(25) << "Output Time (s):" << setw(12)<< UsedTimeOutput << " | "; + cout << setw(20) << "Output Time (%):" << setw(12)<< ((UsedTimeOutput * 100.0) / (TotalTime)) << endl; + cout << setw(25) << "Output count:" << setw(12)<< OutputCount << " | "; + if (OutputCount != 0) { + cout << setw(20)<< "Avg. s/output:" << setw(12)<< UsedTimeOutput/OutputCount << endl; + if (BandwidthSum > 0) { + cout << setw(25)<< "Restart Aggr. BW (MB/s):" << setw(12)<< BandwidthSum/OutputCount << " | "; + cout << setw(20)<< "MB/s/core:" << setw(12)<< BandwidthSum/OutputCount/size << endl; + } + } else cout << endl; + cout << "-------------------------------------------------------------------------" << endl; + cout << endl; } - } else { + + /*--- Exit the solver cleanly ---*/ + if (rank == MASTER_NODE) - cout << endl <<"-------------------------- Using Dummy Geometry -------------------------" << endl; + cout << endl <<"------------------------- Exit Success (SU2_CFD) ------------------------" << endl << endl; + +} - unsigned short iMGlevel; - geometry = new CGeometry*[config->GetnMGLevels()+1] (); +void CDriver::Input_Preprocessing(CConfig **&config, CConfig *&driver_config) { + + char zone_file_name[MAX_STRING_SIZE]; + + /*--- Initialize the configuration of the driver ---*/ + + driver_config = new CConfig(config_file_name, SU2_COMPONENT::SU2_CFD, false); + + for (iZone = 0; iZone < nZone; iZone++) { + + if (rank == MASTER_NODE){ + cout << endl << "Parsing config file for zone " << iZone << endl; + } + /*--- 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. ---*/ + + if (driver_config->GetnConfigFiles() > 0){ + + strcpy(zone_file_name, driver_config->GetConfigFilename(iZone).c_str()); + config[iZone] = new CConfig(driver_config, zone_file_name, SU2_COMPONENT::SU2_CFD, iZone, nZone, true); + } + else{ + config[iZone] = new CConfig(driver_config, config_file_name, SU2_COMPONENT::SU2_CFD, iZone, nZone, true); + } + + /*--- Set the MPI communicator ---*/ + + config[iZone]->SetMPICommunicator(SU2_MPI::GetComm()); + } + + + /*--- Set the multizone part of the problem. ---*/ + if (driver_config->GetMultizone_Problem()){ + for (iZone = 0; iZone < nZone; iZone++) { + /*--- Set the interface markers for multizone ---*/ + config_container[iZone]->SetMultizone(driver_config, config_container); + } + } + + /*--- Determine whether or not the FEM solver is used, which decides the type of + * geometry classes that are instantiated. Only adapted for single-zone problems ---*/ + + fem_solver = config_container[ZONE_0]->GetFEMSolver(); + + fsi = config_container[ZONE_0]->GetFSI_Simulation(); +} - if (!fem_solver){ - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - geometry[iMGlevel] = new CDummyGeometry(config); - } +void CDriver::Geometrical_Preprocessing(CConfig* config, CGeometry **&geometry, bool dummy){ + + if (!dummy){ + if (rank == MASTER_NODE) + cout << endl <<"------------------- Geometry Preprocessing ( Zone " << config->GetiZone() <<" ) -------------------" << endl; + + if( fem_solver ) { + switch( config->GetKind_FEM_Flow() ) { + case DG: { + Geometrical_Preprocessing_DGFEM(config, geometry); + break; + } + } + } + else { + Geometrical_Preprocessing_FVM(config, geometry); + } } else { - geometry[MESH_0] = new CDummyMeshFEM_DG(config); + if (rank == MASTER_NODE) + cout << endl <<"-------------------------- Using Dummy Geometry -------------------------" << endl; + + unsigned short iMGlevel; + + geometry = new CGeometry*[config->GetnMGLevels()+1] (); + + if (!fem_solver){ + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + geometry[iMGlevel] = new CDummyGeometry(config); + } + } else { + geometry[MESH_0] = new CDummyMeshFEM_DG(config); + } + + nDim = geometry[MESH_0]->GetnDim(); } - - nDim = geometry[MESH_0]->GetnDim(); - } - - /*--- Computation of positive surface area in the z-plane which is used for + + /*--- Computation of positive surface area in the z-plane which is used for the calculation of force coefficient (non-dimensionalization). ---*/ - - geometry[MESH_0]->SetPositive_ZArea(config); - - /*--- Set the actuator disk boundary conditions, if necessary. ---*/ - - for (iMesh = 0; iMesh <= config->GetnMGLevels(); iMesh++) { - geometry[iMesh]->MatchActuator_Disk(config); - } - - /*--- If we have any periodic markers in this calculation, we must - match the periodic points found on both sides of the periodic BC. - Note that the current implementation requires a 1-to-1 matching of - periodic points on the pair of periodic faces after the translation - or rotation is taken into account. ---*/ - - if ((config->GetnMarker_Periodic() != 0) && !fem_solver) { + + geometry[MESH_0]->SetPositive_ZArea(config); + + /*--- Set the actuator disk boundary conditions, if necessary. ---*/ + for (iMesh = 0; iMesh <= config->GetnMGLevels(); iMesh++) { - - /*--- Note that we loop over pairs of periodic markers individually - so that repeated nodes on adjacent periodic faces are properly - accounted for in multiple places. ---*/ - - for (unsigned short iPeriodic = 1; iPeriodic <= config->GetnMarker_Periodic()/2; iPeriodic++) { - geometry[iMesh]->MatchPeriodic(config, iPeriodic); - } - - /*--- For Streamwise Periodic flow, find a unique reference node on the dedicated inlet marker. ---*/ - if (config->GetKind_Streamwise_Periodic() != ENUM_STREAMWISE_PERIODIC::NONE) - geometry[iMesh]->FindUniqueNode_PeriodicBound(config); - - /*--- Initialize the communication framework for the periodic BCs. ---*/ - geometry[iMesh]->PreprocessPeriodicComms(geometry[iMesh], config); - - } - } - - /*--- If activated by the compile directive, perform a partition analysis. ---*/ -#if PARTITION - if (!dummy){ - if( fem_solver ) Partition_Analysis_FEM(geometry[MESH_0], config); - else Partition_Analysis(geometry[MESH_0], config); - } -#endif - - /*--- Check if Euler & Symmetry markers are straight/plane. This information - is used in the Euler & Symmetry boundary routines. ---*/ - if((config_container[iZone]->GetnMarker_Euler() != 0 || - config_container[iZone]->GetnMarker_SymWall() != 0) && - !fem_solver) { - - if (rank == MASTER_NODE) - cout << "Checking if Euler & Symmetry markers are straight/plane:" << endl; - - for (iMesh = 0; iMesh <= config_container[iZone]->GetnMGLevels(); iMesh++) - geometry_container[iZone][iInst][iMesh]->ComputeSurf_Straightness(config_container[iZone], (iMesh==MESH_0) ); - - } - -} - -void CDriver::Geometrical_Preprocessing_FVM(CConfig *config, CGeometry **&geometry) { - - unsigned short iZone = config->GetiZone(), iMGlevel; - unsigned short requestedMGlevels = config->GetnMGLevels(); - const bool fea = config->GetStructuralProblem(); - - /*--- Definition of the geometry class to store the primal grid in the partitioning process. - * All ranks process the grid and call ParMETIS for partitioning ---*/ - - CGeometry *geometry_aux = new CPhysicalGeometry(config, iZone, nZone); - - /*--- Set the dimension --- */ - - nDim = geometry_aux->GetnDim(); - - /*--- Color the initial grid and set the send-receive domains (ParMETIS) ---*/ - - geometry_aux->SetColorGrid_Parallel(config); - - /*--- Allocate the memory of the current domain, and divide the grid - between the ranks. ---*/ - - geometry = new CGeometry *[config->GetnMGLevels()+1] (); - - /*--- Build the grid data structures using the ParMETIS coloring. ---*/ - - geometry[MESH_0] = new CPhysicalGeometry(geometry_aux, config); - - /*--- Deallocate the memory of geometry_aux and solver_aux ---*/ - - delete geometry_aux; - - /*--- Add the Send/Receive boundaries ---*/ - geometry[MESH_0]->SetSendReceive(config); - - /*--- Add the Send/Receive boundaries ---*/ - geometry[MESH_0]->SetBoundaries(config); - - /*--- Compute elements surrounding points, points surrounding points ---*/ - - if (rank == MASTER_NODE) cout << "Setting point connectivity." << endl; - geometry[MESH_0]->SetPoint_Connectivity(); - - /*--- Renumbering points using Reverse Cuthill McKee ordering ---*/ - - if (rank == MASTER_NODE) cout << "Renumbering points (Reverse Cuthill McKee Ordering)." << endl; - geometry[MESH_0]->SetRCM_Ordering(config); - - /*--- recompute elements surrounding points, points surrounding points ---*/ - - if (rank == MASTER_NODE) cout << "Recomputing point connectivity." << endl; - geometry[MESH_0]->SetPoint_Connectivity(); - - /*--- Compute elements surrounding elements ---*/ - - if (rank == MASTER_NODE) cout << "Setting element connectivity." << endl; - geometry[MESH_0]->SetElement_Connectivity(); - - /*--- Check the orientation before computing geometrical quantities ---*/ - - geometry[MESH_0]->SetBoundVolume(); - if (config->GetReorientElements()) { - if (rank == MASTER_NODE) cout << "Checking the numerical grid orientation." << endl; - geometry[MESH_0]->Check_IntElem_Orientation(config); - geometry[MESH_0]->Check_BoundElem_Orientation(config); - } - - /*--- Create the edge structure ---*/ - - if (rank == MASTER_NODE) cout << "Identifying edges and vertices." << endl; - geometry[MESH_0]->SetEdges(); - geometry[MESH_0]->SetVertex(config); - - /*--- Create the control volume structures ---*/ - - if (rank == MASTER_NODE) cout << "Setting the control volume structure." << endl; - SU2_OMP_PARALLEL { - geometry[MESH_0]->SetControlVolume(config, ALLOCATE); - geometry[MESH_0]->SetBoundControlVolume(config, ALLOCATE); - } - END_SU2_OMP_PARALLEL - - /*--- Visualize a dual control volume if requested ---*/ - - if ((config->GetVisualize_CV() >= 0) && - (config->GetVisualize_CV() < (long)geometry[MESH_0]->GetGlobal_nPointDomain())) - geometry[MESH_0]->VisualizeControlVolume(config); - - /*--- Identify closest normal neighbor ---*/ - - if (rank == MASTER_NODE) cout << "Searching for the closest normal neighbors to the surfaces." << endl; - geometry[MESH_0]->FindNormal_Neighbor(config); - - /*--- Store the global to local mapping. ---*/ - - if (rank == MASTER_NODE) cout << "Storing a mapping from global to local point index." << endl; - geometry[MESH_0]->SetGlobal_to_Local_Point(); - - /*--- Compute the surface curvature ---*/ - - if (!fea) { - if (rank == MASTER_NODE) cout << "Compute the surface curvature." << endl; - geometry[MESH_0]->ComputeSurf_Curvature(config); - } - - /*--- Check for periodicity and disable MG if necessary. ---*/ - - if (rank == MASTER_NODE) cout << "Checking for periodicity." << endl; - geometry[MESH_0]->Check_Periodicity(config); - - /*--- Compute mesh quality statistics on the fine grid. ---*/ - - if (!fea) { - if (rank == MASTER_NODE) - cout << "Computing mesh quality statistics for the dual control volumes." << endl; - geometry[MESH_0]->ComputeMeshQualityStatistics(config); - } - - geometry[MESH_0]->SetMGLevel(MESH_0); - if ((config->GetnMGLevels() != 0) && (rank == MASTER_NODE)) - cout << "Setting the multigrid structure." << endl; - - /*--- Loop over all the new grid ---*/ - - for (iMGlevel = 1; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - - /*--- Create main agglomeration structure ---*/ - - geometry[iMGlevel] = new CMultiGridGeometry(geometry[iMGlevel-1], config, iMGlevel); - - /*--- Compute points surrounding points. ---*/ - - geometry[iMGlevel]->SetPoint_Connectivity(geometry[iMGlevel-1]); - - /*--- Create the edge structure ---*/ - - geometry[iMGlevel]->SetEdges(); - geometry[iMGlevel]->SetVertex(geometry[iMGlevel-1], config); - - /*--- Create the control volume structures ---*/ - - geometry[iMGlevel]->SetControlVolume(geometry[iMGlevel-1], ALLOCATE); - geometry[iMGlevel]->SetBoundControlVolume(geometry[iMGlevel-1], ALLOCATE); - geometry[iMGlevel]->SetCoord(geometry[iMGlevel-1]); - - /*--- Find closest neighbor to a surface point ---*/ - - geometry[iMGlevel]->FindNormal_Neighbor(config); - - /*--- Store our multigrid index. ---*/ - - geometry[iMGlevel]->SetMGLevel(iMGlevel); - - /*--- Protect against the situation that we were not able to complete - the agglomeration for this level, i.e., there weren't enough points. - We need to check if we changed the total number of levels and delete - the incomplete CMultiGridGeometry object. ---*/ - - if (config->GetnMGLevels() != requestedMGlevels) { - delete geometry[iMGlevel]; - geometry[iMGlevel] = nullptr; - break; - } - - } - - if (config->GetWrt_MultiGrid()) geometry[MESH_0]->ColorMGLevels(config->GetnMGLevels(), geometry); - - /*--- For unsteady simulations, initialize the grid volumes - and coordinates for previous solutions. Loop over all zones/grids ---*/ - - if ((config->GetTime_Marching() != TIME_MARCHING::STEADY) && config->GetDynamic_Grid()) { - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - - /*--- Update cell volume ---*/ - geometry[iMGlevel]->nodes->SetVolume_n(); - geometry[iMGlevel]->nodes->SetVolume_nM1(); - - if (config->GetGrid_Movement()) { - /*--- Update point coordinates ---*/ - geometry[iMGlevel]->nodes->SetCoord_n(); - geometry[iMGlevel]->nodes->SetCoord_n1(); - } + geometry[iMesh]->MatchActuator_Disk(config); + } + + /*--- If we have any periodic markers in this calculation, we must + match the periodic points found on both sides of the periodic BC. + Note that the current implementation requires a 1-to-1 matching of + periodic points on the pair of periodic faces after the translation + or rotation is taken into account. ---*/ + + if ((config->GetnMarker_Periodic() != 0) && !fem_solver) { + for (iMesh = 0; iMesh <= config->GetnMGLevels(); iMesh++) { + + /*--- Note that we loop over pairs of periodic markers individually + so that repeated nodes on adjacent periodic faces are properly + accounted for in multiple places. ---*/ + + for (unsigned short iPeriodic = 1; iPeriodic <= config->GetnMarker_Periodic()/2; iPeriodic++) { + geometry[iMesh]->MatchPeriodic(config, iPeriodic); + } + + /*--- For Streamwise Periodic flow, find a unique reference node on the dedicated inlet marker. ---*/ + if (config->GetKind_Streamwise_Periodic() != ENUM_STREAMWISE_PERIODIC::NONE) + geometry[iMesh]->FindUniqueNode_PeriodicBound(config); + + /*--- Initialize the communication framework for the periodic BCs. ---*/ + geometry[iMesh]->PreprocessPeriodicComms(geometry[iMesh], config); + + } } - } - - - /*--- Create the data structure for MPI point-to-point communications. ---*/ - - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) - geometry[iMGlevel]->PreprocessP2PComms(geometry[iMGlevel], config); - - - /*--- Perform a few preprocessing routines and communications. ---*/ - - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - - /*--- Compute the max length. ---*/ - - if (!fea) { - if ((rank == MASTER_NODE) && (iMGlevel == MESH_0)) - cout << "Finding max control volume width." << endl; - geometry[iMGlevel]->SetMaxLength(config); - } - - /*--- Communicate the number of neighbors. This is needed for - some centered schemes and for multigrid in parallel. ---*/ - - if ((rank == MASTER_NODE) && (size > SINGLE_NODE) && (iMGlevel == MESH_0)) - cout << "Communicating number of neighbors." << endl; - geometry[iMGlevel]->InitiateComms(geometry[iMGlevel], config, NEIGHBORS); - geometry[iMGlevel]->CompleteComms(geometry[iMGlevel], config, NEIGHBORS); - } - -} - -void CDriver::Geometrical_Preprocessing_DGFEM(CConfig* config, CGeometry **&geometry) { - - /*--- Definition of the geometry class to store the primal grid in the partitioning process. ---*/ - /*--- All ranks process the grid and call ParMETIS for partitioning ---*/ - - CGeometry *geometry_aux = new CPhysicalGeometry(config, iZone, nZone); - - /*--- Set the dimension --- */ - - nDim = geometry_aux->GetnDim(); - - /*--- For the FEM solver with time-accurate local time-stepping, use - a dummy solver class to retrieve the initial flow state. ---*/ - - CSolver *solver_aux = new CFEM_DG_EulerSolver(config, nDim, MESH_0); - - /*--- Color the initial grid and set the send-receive domains (ParMETIS) ---*/ - - geometry_aux->SetColorFEMGrid_Parallel(config); - - /*--- Allocate the memory of the current domain, and divide the grid - between the ranks. ---*/ - - geometry = new CGeometry *[config->GetnMGLevels()+1] (); - - geometry[MESH_0] = new CMeshFEM_DG(geometry_aux, config); - - /*--- Deallocate the memory of geometry_aux and solver_aux ---*/ - - delete geometry_aux; - delete solver_aux; - - /*--- Add the Send/Receive boundaries ---*/ - geometry[MESH_0]->SetSendReceive(config); - - /*--- Add the Send/Receive boundaries ---*/ - geometry[MESH_0]->SetBoundaries(config); - - /*--- Carry out a dynamic cast to CMeshFEM_DG, such that it is not needed to - define all virtual functions in the base class CGeometry. ---*/ - CMeshFEM_DG *DGMesh = dynamic_cast(geometry[MESH_0]); - - /*--- Determine the standard elements for the volume elements. ---*/ - if (rank == MASTER_NODE) cout << "Creating standard volume elements." << endl; - DGMesh->CreateStandardVolumeElements(config); - - /*--- Create the face information needed to compute the contour integral - for the elements in the Discontinuous Galerkin formulation. ---*/ - if (rank == MASTER_NODE) cout << "Creating face information." << endl; - DGMesh->CreateFaces(config); - - /*--- Compute the metric terms of the volume elements. ---*/ - if (rank == MASTER_NODE) cout << "Computing metric terms volume elements." << endl; - DGMesh->MetricTermsVolumeElements(config); - - /*--- Compute the metric terms of the surface elements. ---*/ - if (rank == MASTER_NODE) cout << "Computing metric terms surface elements." << endl; - DGMesh->MetricTermsSurfaceElements(config); - - /*--- Compute a length scale of the volume elements. ---*/ - if (rank == MASTER_NODE) cout << "Computing length scale volume elements." << endl; - DGMesh->LengthScaleVolumeElements(); - - /*--- Compute the coordinates of the integration points. ---*/ - if (rank == MASTER_NODE) cout << "Computing coordinates of the integration points." << endl; - DGMesh->CoordinatesIntegrationPoints(); - - /*--- Compute the coordinates of the location of the solution DOFs. This is different - from the grid points when a different polynomial degree is used to represent the - geometry and solution. ---*/ - if (rank == MASTER_NODE) cout << "Computing coordinates of the solution DOFs." << endl; - DGMesh->CoordinatesSolDOFs(); - - /*--- Perform the preprocessing tasks when wall functions are used. ---*/ - if (rank == MASTER_NODE) cout << "Preprocessing for the wall functions. " << endl; - DGMesh->WallFunctionPreprocessing(config); - - /*--- Store the global to local mapping. ---*/ - if (rank == MASTER_NODE) cout << "Storing a mapping from global to local DOF index." << endl; - geometry[MESH_0]->SetGlobal_to_Local_Point(); - - - /*--- Loop to create the coarser grid levels. ---*/ - - for(unsigned short iMGlevel=1; iMGlevel<=config->GetnMGLevels(); iMGlevel++) { - - SU2_MPI::Error("Geometrical_Preprocessing_DGFEM: Coarse grid levels not implemented yet.", - CURRENT_FUNCTION); - } - -} - -void CDriver::Solver_Preprocessing(CConfig* config, CGeometry** geometry, CSolver ***&solver) { - - MAIN_SOLVER kindSolver = config->GetKind_Solver(); - - if (rank == MASTER_NODE) - cout << endl <<"-------------------- Solver Preprocessing ( Zone " << config->GetiZone() <<" ) --------------------" << endl; - - solver = new CSolver**[config->GetnMGLevels()+1] (); - - for (iMesh = 0; iMesh <= config->GetnMGLevels(); iMesh++){ - solver[iMesh] = CSolverFactory::CreateSolverContainer(kindSolver, config, geometry[iMesh], iMesh); - } - - /*--- Count the number of DOFs per solution point. ---*/ - - DOFsPerPoint = 0; - - for (unsigned int iSol = 0; iSol < MAX_SOLS; iSol++) - if (solver[MESH_0][iSol]) DOFsPerPoint += solver[MESH_0][iSol]->GetnVar(); - - /*--- Restart solvers, for FSI the geometry cannot be updated because the interpolation classes - * should always use the undeformed mesh (otherwise the results would not be repeatable). ---*/ - - if (!fsi) Solver_Restart(solver, geometry, config, true); - - /*--- Set up any necessary inlet profiles ---*/ - - Inlet_Preprocessing(solver, geometry, config); - -} - -void CDriver::Inlet_Preprocessing(CSolver ***solver, CGeometry **geometry, - CConfig *config) const { - - /*--- Adjust iteration number for unsteady restarts. ---*/ - - const bool adjoint = config->GetDiscrete_Adjoint() || config->GetContinuous_Adjoint(); - - int val_iter = 0; - - if (config->GetTime_Domain()) { - val_iter = adjoint? config->GetUnst_AdjointIter() : config->GetRestart_Iter(); - val_iter -= 1; - if (!adjoint && config->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_2ND) - val_iter -= 1; - if (!adjoint && !config->GetRestart()) val_iter = 0; - } - - /*--- Load inlet profile files for any of the active solver containers. - Note that these routines fill the fine grid data structures for the markers - and restrict values down to all coarser MG levels. ---*/ - - if (config->GetInlet_Profile_From_File()) { - - /*--- Use LoadInletProfile() routines for the particular solver. ---*/ - - if (rank == MASTER_NODE) { - cout << endl; - cout << "Reading inlet profile from file: "; - cout << config->GetInlet_FileName() << endl; - } - - if (solver[MESH_0][FLOW_SOL]) { - solver[MESH_0][FLOW_SOL]->LoadInletProfile(geometry, solver, config, val_iter, FLOW_SOL, INLET_FLOW); - } - if (solver[MESH_0][TURB_SOL]) { - solver[MESH_0][TURB_SOL]->LoadInletProfile(geometry, solver, config, val_iter, TURB_SOL, INLET_FLOW); - } - if (solver[MESH_0][SPECIES_SOL]) { - solver[MESH_0][SPECIES_SOL]->LoadInletProfile(geometry, solver, config, val_iter, SPECIES_SOL, INLET_FLOW); - } - - /*--- Exit if profiles were requested for a solver that is not available. ---*/ - - if (!config->GetFluidProblem()) { - SU2_MPI::Error(string("Inlet profile specification via file (C++) has not been \n") + - string("implemented yet for this solver.\n") + - string("Please set SPECIFIED_INLET_PROFILE= NO and try again."), CURRENT_FUNCTION); - } - - } else { - - /*--- Uniform inlets or python-customized inlets ---*/ - - /* --- Initialize quantities for inlet boundary - * This routine does not check if they python wrapper is being used to - * set custom boundary conditions. This is intentional; the - * default values for python custom BCs are initialized with the default - * values specified in the config (avoiding non physical values) --- */ - - for (unsigned short iMesh = 0; iMesh <= config->GetnMGLevels(); iMesh++) { - for(unsigned short iMarker=0; iMarker < config->GetnMarker_All(); iMarker++) { - if (solver[iMesh][FLOW_SOL]) solver[iMesh][FLOW_SOL]->SetUniformInlet(config, iMarker); - if (solver[iMesh][TURB_SOL]) solver[iMesh][TURB_SOL]->SetUniformInlet(config, iMarker); - if (solver[iMesh][SPECIES_SOL]) solver[iMesh][SPECIES_SOL]->SetUniformInlet(config, iMarker); - } - } - - } - -} - -void CDriver::Solver_Restart(CSolver ***solver, CGeometry **geometry, - CConfig *config, bool update_geo) { - - /*--- Check for restarts and use the LoadRestart() routines. ---*/ - - const bool restart = config->GetRestart(); - const bool restart_flow = config->GetRestart_Flow(); - - /*--- Adjust iteration number for unsteady restarts. ---*/ - - int val_iter = 0; - - const bool adjoint = (config->GetDiscrete_Adjoint() || config->GetContinuous_Adjoint()); - const bool time_domain = config->GetTime_Domain(); - const bool dt_step_2nd = (config->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_2ND) && - !config->GetStructuralProblem() && !config->GetFEMSolver() && - !adjoint && time_domain; - - if (time_domain) { - if (adjoint) val_iter = config->GetUnst_AdjointIter() - 1; - else val_iter = config->GetRestart_Iter() - 1 - dt_step_2nd; - } - - /*--- Restart direct solvers. ---*/ - - if (restart || restart_flow) { - for (auto iSol = 0u; iSol < MAX_SOLS; ++iSol) { - auto sol = solver[MESH_0][iSol]; - if (sol && !sol->GetAdjoint()) { - /*--- Note that the mesh solver always loads the most recent file (and not -2). ---*/ - SU2_OMP_PARALLEL_(if(sol->GetHasHybridParallel())) - sol->LoadRestart(geometry, solver, config, val_iter + (iSol==MESH_SOL && dt_step_2nd), update_geo); - END_SU2_OMP_PARALLEL - } - } - } - - /*--- Restart adjoint solvers. ---*/ - - if (restart) { - if ((config->GetKind_Solver() == MAIN_SOLVER::TEMPLATE_SOLVER) || - (config->GetKind_Solver() == MAIN_SOLVER::ADJ_RANS && !config->GetFrozen_Visc_Cont())) { - SU2_MPI::Error("A restart capability has not been implemented yet for this solver.\n" - "Please set RESTART_SOL= NO and try again.", CURRENT_FUNCTION); - } - - for (auto iSol = 0u; iSol < MAX_SOLS; ++iSol) { - auto sol = solver[MESH_0][iSol]; - if (sol && sol->GetAdjoint()) - sol->LoadRestart(geometry, solver, config, val_iter, update_geo); - } - } - -} - -void CDriver::Solver_Postprocessing(CSolver ****solver, CGeometry **geometry, - CConfig *config, unsigned short val_iInst) { - - for (int iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - for (unsigned int iSol = 0; iSol < MAX_SOLS; iSol++){ - delete solver[val_iInst][iMGlevel][iSol]; - } - delete [] solver[val_iInst][iMGlevel]; - } - delete [] solver[val_iInst]; - - CSolverFactory::ClearSolverMeta(); - -} - -void CDriver::Integration_Preprocessing(CConfig *config, CSolver **solver, CIntegration **&integration) const { - - if (rank == MASTER_NODE) - cout << endl <<"----------------- Integration Preprocessing ( Zone " << config->GetiZone() <<" ) ------------------" << endl; - - MAIN_SOLVER kindMainSolver = config->GetKind_Solver(); - - integration = CIntegrationFactory::CreateIntegrationContainer(kindMainSolver, solver); - -} - -void CDriver::Integration_Postprocessing(CIntegration ***integration, CGeometry **geometry, CConfig *config, unsigned short val_iInst) { - - for (unsigned int iSol = 0; iSol < MAX_SOLS; iSol++){ - delete integration[val_iInst][iSol]; - } - - delete [] integration[val_iInst]; - -} - -template -void CDriver::InstantiateTurbulentNumerics(unsigned short nVar_Turb, int offset, const CConfig *config, - const CSolver* turb_solver, CNumerics ****&numerics) const { - const int conv_term = CONV_TERM + offset; - const int visc_term = VISC_TERM + offset; - - const int source_first_term = SOURCE_FIRST_TERM + offset; - const int source_second_term = SOURCE_SECOND_TERM + offset; - - const int conv_bound_term = CONV_BOUND_TERM + offset; - const int visc_bound_term = VISC_BOUND_TERM + offset; - - bool spalart_allmaras, neg_spalart_allmaras, e_spalart_allmaras, comp_spalart_allmaras, e_comp_spalart_allmaras, menter_sst; - spalart_allmaras = neg_spalart_allmaras = e_spalart_allmaras = comp_spalart_allmaras = e_comp_spalart_allmaras = menter_sst = false; - - /*--- Assign turbulence model booleans ---*/ - - switch (config->GetKind_Turb_Model()) { - case TURB_MODEL::NONE: - SU2_MPI::Error("No turbulence model selected.", CURRENT_FUNCTION); - break; - case TURB_MODEL::SA: spalart_allmaras = true; break; - case TURB_MODEL::SA_NEG: neg_spalart_allmaras = true; break; - case TURB_MODEL::SA_E: e_spalart_allmaras = true; break; - case TURB_MODEL::SA_COMP: comp_spalart_allmaras = true; break; - case TURB_MODEL::SA_E_COMP: e_comp_spalart_allmaras = true; break; - case TURB_MODEL::SST: menter_sst = true; break; - case TURB_MODEL::SST_SUST: menter_sst = true; break; - } - - /*--- If the Menter SST model is used, store the constants of the model and determine the - free stream values of the turbulent kinetic energy and dissipation rate. ---*/ - - const su2double *constants = nullptr; - su2double kine_Inf = 0.0, omega_Inf = 0.0; - - if (menter_sst) { - constants = turb_solver->GetConstants(); - kine_Inf = turb_solver->GetTke_Inf(); - omega_Inf = turb_solver->GetOmega_Inf(); - } - - /*--- Definition of the convective scheme for each equation and mesh level ---*/ - - switch (config->GetKind_ConvNumScheme_Turb()) { - case NO_UPWIND: - SU2_MPI::Error("Config file is missing the CONV_NUM_METHOD_TURB option.", CURRENT_FUNCTION); - break; - case SPACE_UPWIND : - for (auto iMGlevel = 0u; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - if (spalart_allmaras || neg_spalart_allmaras || e_spalart_allmaras || comp_spalart_allmaras || e_comp_spalart_allmaras) { - numerics[iMGlevel][TURB_SOL][conv_term] = new CUpwSca_TurbSA(nDim, nVar_Turb, config); - } - else if (menter_sst) numerics[iMGlevel][TURB_SOL][conv_term] = new CUpwSca_TurbSST(nDim, nVar_Turb, config); - } - break; - default: - SU2_MPI::Error("Invalid convective scheme for the turbulence equations.", CURRENT_FUNCTION); - break; - } - - /*--- Definition of the viscous scheme for each equation and mesh level ---*/ - - for (auto iMGlevel = 0u; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - if (spalart_allmaras || e_spalart_allmaras || comp_spalart_allmaras || e_comp_spalart_allmaras) { - numerics[iMGlevel][TURB_SOL][visc_term] = new CAvgGrad_TurbSA(nDim, nVar_Turb, true, config); - } - else if (neg_spalart_allmaras) - numerics[iMGlevel][TURB_SOL][visc_term] = new CAvgGrad_TurbSA_Neg(nDim, nVar_Turb, true, config); - else if (menter_sst) - numerics[iMGlevel][TURB_SOL][visc_term] = new CAvgGrad_TurbSST(nDim, nVar_Turb, constants, true, config); - } - - /*--- Definition of the source term integration scheme for each equation and mesh level ---*/ - - for (auto iMGlevel = 0u; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - auto& turb_source_first_term = numerics[iMGlevel][TURB_SOL][source_first_term]; - - if (spalart_allmaras) - turb_source_first_term = new CSourcePieceWise_TurbSA(nDim, nVar_Turb, config); - else if (e_spalart_allmaras) - turb_source_first_term = new CSourcePieceWise_TurbSA_E(nDim, nVar_Turb, config); - else if (comp_spalart_allmaras) - turb_source_first_term = new CSourcePieceWise_TurbSA_COMP(nDim, nVar_Turb, config); - else if (e_comp_spalart_allmaras) - turb_source_first_term = new CSourcePieceWise_TurbSA_E_COMP(nDim, nVar_Turb, config); - else if (neg_spalart_allmaras) - turb_source_first_term = new CSourcePieceWise_TurbSA_Neg(nDim, nVar_Turb, config); - else if (menter_sst) - turb_source_first_term = new CSourcePieceWise_TurbSST(nDim, nVar_Turb, constants, kine_Inf, omega_Inf, - config); - - numerics[iMGlevel][TURB_SOL][source_second_term] = new CSourceNothing(nDim, nVar_Turb, config); - } - - /*--- Definition of the boundary condition method ---*/ - - for (auto iMGlevel = 0u; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - if (spalart_allmaras || e_spalart_allmaras || comp_spalart_allmaras || e_comp_spalart_allmaras) { - numerics[iMGlevel][TURB_SOL][conv_bound_term] = new CUpwSca_TurbSA(nDim, nVar_Turb, config); - numerics[iMGlevel][TURB_SOL][visc_bound_term] = new CAvgGrad_TurbSA(nDim, nVar_Turb, false, config); - } - else if (neg_spalart_allmaras) { - numerics[iMGlevel][TURB_SOL][conv_bound_term] = new CUpwSca_TurbSA(nDim, nVar_Turb, config); - numerics[iMGlevel][TURB_SOL][visc_bound_term] = new CAvgGrad_TurbSA_Neg(nDim, nVar_Turb, false, config); - } - else if (menter_sst) { - numerics[iMGlevel][TURB_SOL][conv_bound_term] = new CUpwSca_TurbSST(nDim, nVar_Turb, config); - numerics[iMGlevel][TURB_SOL][visc_bound_term] = new CAvgGrad_TurbSST(nDim, nVar_Turb, constants, false, - config); - } - } -} -/*--- Explicit instantiation of the template above, needed because it is defined in a cpp file, instead of hpp. ---*/ -template void CDriver::InstantiateTurbulentNumerics>( - unsigned short, int, const CConfig*, const CSolver*, CNumerics****&) const; - -template void CDriver::InstantiateTurbulentNumerics>( - unsigned short, int, const CConfig*, const CSolver*, CNumerics****&) const; - -template void CDriver::InstantiateTurbulentNumerics>( - unsigned short, int, const CConfig*, const CSolver*, CNumerics****&) const; - -template -void CDriver::InstantiateSpeciesNumerics(unsigned short nVar_Species, int offset, const CConfig *config, - const CSolver* species_solver, CNumerics ****&numerics) const { - const int conv_term = CONV_TERM + offset; - const int visc_term = VISC_TERM + offset; - - const int source_first_term = SOURCE_FIRST_TERM + offset; - const int source_second_term = SOURCE_SECOND_TERM + offset; - - const int conv_bound_term = CONV_BOUND_TERM + offset; - const int visc_bound_term = VISC_BOUND_TERM + offset; - - /*--- Definition of the convective scheme for each equation and mesh level. Also for boundary conditions. ---*/ - - switch (config->GetKind_ConvNumScheme_Species()) { - case NONE : - break; - case SPACE_UPWIND : - for (auto iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - numerics[iMGlevel][SPECIES_SOL][conv_term] = new CUpwSca_Species(nDim, nVar_Species, config); - numerics[iMGlevel][SPECIES_SOL][conv_bound_term] = new CUpwSca_Species(nDim, nVar_Species, config); - } - break; - default : - SU2_MPI::Error("Invalid convective scheme for the species transport equations. Use SCALAR_UPWIND.", CURRENT_FUNCTION); - break; - } - - /*--- Definition of the viscous scheme for each equation and mesh level ---*/ - - for (auto iMGlevel = 0u; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - numerics[iMGlevel][SPECIES_SOL][visc_term] = new CAvgGrad_Species(nDim, nVar_Species, true, config); - numerics[iMGlevel][SPECIES_SOL][visc_bound_term] = new CAvgGrad_Species(nDim, nVar_Species, false, config); - } - - /*--- Definition of the source term integration scheme for each equation and mesh level ---*/ - - for (auto iMGlevel = 0u; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - if (config->GetAxisymmetric() == YES) { - numerics[iMGlevel][SPECIES_SOL][source_first_term] = new CSourceAxisymmetric_Species(nDim, nVar_Species, config); - } - else { - numerics[iMGlevel][SPECIES_SOL][source_first_term] = new CSourceNothing(nDim, nVar_Species, config); - } - numerics[iMGlevel][SPECIES_SOL][source_second_term] = new CSourceNothing(nDim, nVar_Species, config); - } -} -/*--- Explicit instantiation of the template above, needed because it is defined in a cpp file, instead of hpp. ---*/ -template void CDriver::InstantiateSpeciesNumerics>( - unsigned short, int, const CConfig*, const CSolver*, CNumerics****&) const; - -template void CDriver::InstantiateSpeciesNumerics>( - unsigned short, int, const CConfig*, const CSolver*, CNumerics****&) const; - -template void CDriver::InstantiateSpeciesNumerics>( - unsigned short, int, const CConfig*, const CSolver*, CNumerics****&) const; - -void CDriver::Numerics_Preprocessing(CConfig *config, CGeometry **geometry, CSolver ***solver, CNumerics ****&numerics) const { - - if (rank == MASTER_NODE) - cout << endl <<"------------------- Numerics Preprocessing ( Zone " << config->GetiZone() <<" ) -------------------" << endl; - - unsigned short iMGlevel, iSol, - - nVar_Template = 0, - nVar_Flow = 0, - nVar_NEMO = 0, - nPrimVar_NEMO = 0, - nPrimVarGrad_NEMO = 0, - nVar_Trans = 0, - nVar_Turb = 0, - nVar_Species = 0, - nVar_Adj_Flow = 0, - nVar_Adj_Turb = 0, - nVar_FEM = 0, - nVar_Rad = 0, - nVar_Heat = 0; - - numerics = new CNumerics***[config->GetnMGLevels()+1] (); - - bool compressible = false; - bool incompressible = false; - bool ideal_gas = (config->GetKind_FluidModel() == STANDARD_AIR) || (config->GetKind_FluidModel() == IDEAL_GAS); - bool roe_low_dissipation = (config->GetKind_RoeLowDiss() != NO_ROELOWDISS); - - /*--- Initialize some useful booleans ---*/ - bool euler, ns, NEMO_euler, NEMO_ns, turbulent, adj_euler, adj_ns, adj_turb, fem_euler, fem_ns; - bool fem, heat, transition, template_solver; - - euler = ns = NEMO_euler = NEMO_ns = turbulent = adj_euler = adj_ns = adj_turb = fem_euler = fem_ns = false; - fem = heat = transition = template_solver = false; - bool species = false; - - /*--- Assign booleans ---*/ - switch (config->GetKind_Solver()) { - case MAIN_SOLVER::TEMPLATE_SOLVER: - template_solver = true; break; - - case MAIN_SOLVER::EULER: - case MAIN_SOLVER::DISC_ADJ_EULER: - euler = compressible = true; break; - - case MAIN_SOLVER::NAVIER_STOKES: - case MAIN_SOLVER::DISC_ADJ_NAVIER_STOKES: - ns = compressible = true; - species = (config->GetKind_Species_Model() != SPECIES_MODEL::NONE); break; - - case MAIN_SOLVER::NEMO_EULER: - NEMO_euler = compressible = true; break; - - case MAIN_SOLVER::NEMO_NAVIER_STOKES: - NEMO_ns = compressible = true; break; - - case MAIN_SOLVER::RANS: - case MAIN_SOLVER::DISC_ADJ_RANS: - ns = compressible = turbulent = true; - transition = (config->GetKind_Trans_Model() == TURB_TRANS_MODEL::LM); - species = config->GetKind_Species_Model() != SPECIES_MODEL::NONE; break; - - case MAIN_SOLVER::INC_EULER: - case MAIN_SOLVER::DISC_ADJ_INC_EULER: - euler = incompressible = true; break; - - case MAIN_SOLVER::INC_NAVIER_STOKES: - case MAIN_SOLVER::DISC_ADJ_INC_NAVIER_STOKES: - ns = incompressible = true; - heat = config->GetWeakly_Coupled_Heat(); - species = (config->GetKind_Species_Model() != SPECIES_MODEL::NONE); break; - - case MAIN_SOLVER::INC_RANS: - case MAIN_SOLVER::DISC_ADJ_INC_RANS: - ns = incompressible = turbulent = true; - heat = config->GetWeakly_Coupled_Heat(); - transition = (config->GetKind_Trans_Model() == TURB_TRANS_MODEL::LM); - species = (config->GetKind_Species_Model() != SPECIES_MODEL::NONE); break; - - case MAIN_SOLVER::FEM_EULER: - case MAIN_SOLVER::DISC_ADJ_FEM_EULER: - fem_euler = compressible = true; break; - - case MAIN_SOLVER::FEM_NAVIER_STOKES: - case MAIN_SOLVER::DISC_ADJ_FEM_NS: - fem_ns = compressible = true; break; - - case MAIN_SOLVER::FEM_RANS: - case MAIN_SOLVER::DISC_ADJ_FEM_RANS: - fem_ns = compressible = true; break; - - case MAIN_SOLVER::FEM_LES: - fem_ns = compressible = true; break; - - case MAIN_SOLVER::HEAT_EQUATION: - case MAIN_SOLVER::DISC_ADJ_HEAT: - heat = true; break; - - case MAIN_SOLVER::FEM_ELASTICITY: - case MAIN_SOLVER::DISC_ADJ_FEM: - fem = true; break; - - case MAIN_SOLVER::ADJ_EULER: - adj_euler = euler = compressible = true; break; - - case MAIN_SOLVER::ADJ_NAVIER_STOKES: - adj_ns = ns = compressible = true; - turbulent = (config->GetKind_Turb_Model() != TURB_MODEL::NONE); break; - - case MAIN_SOLVER::ADJ_RANS: - adj_ns = ns = compressible = turbulent = true; - adj_turb = !config->GetFrozen_Visc_Cont(); break; - - default: - break; - - } - - /*--- Number of variables for the template ---*/ - - if (template_solver) nVar_Flow = solver[MESH_0][FLOW_SOL]->GetnVar(); - - /*--- Number of variables for direct problem ---*/ - - if (euler) nVar_Flow = solver[MESH_0][FLOW_SOL]->GetnVar(); - if (ns) nVar_Flow = solver[MESH_0][FLOW_SOL]->GetnVar(); - if (NEMO_euler) nVar_NEMO = solver[MESH_0][FLOW_SOL]->GetnVar(); - if (NEMO_ns) nVar_NEMO = solver[MESH_0][FLOW_SOL]->GetnVar(); - if (turbulent) nVar_Turb = solver[MESH_0][TURB_SOL]->GetnVar(); - if (transition) nVar_Trans = solver[MESH_0][TRANS_SOL]->GetnVar(); - if (species) nVar_Species = solver[MESH_0][SPECIES_SOL]->GetnVar(); - - if (fem_euler) nVar_Flow = solver[MESH_0][FLOW_SOL]->GetnVar(); - if (fem_ns) nVar_Flow = solver[MESH_0][FLOW_SOL]->GetnVar(); - - if (fem) nVar_FEM = solver[MESH_0][FEA_SOL]->GetnVar(); - if (heat) nVar_Heat = solver[MESH_0][HEAT_SOL]->GetnVar(); - - if (config->AddRadiation()) nVar_Rad = solver[MESH_0][RAD_SOL]->GetnVar(); - - /*--- Number of variables for adjoint problem ---*/ - - if (adj_euler) nVar_Adj_Flow = solver[MESH_0][ADJFLOW_SOL]->GetnVar(); - if (adj_ns) nVar_Adj_Flow = solver[MESH_0][ADJFLOW_SOL]->GetnVar(); - if (adj_turb) nVar_Adj_Turb = solver[MESH_0][ADJTURB_SOL]->GetnVar(); - - /*--- Additional Variables required for NEMO solver ---*/ - - if (NEMO_euler || NEMO_ns) nPrimVar_NEMO = solver[MESH_0][FLOW_SOL]->GetnPrimVar(); - if (NEMO_euler || NEMO_ns) nPrimVarGrad_NEMO = solver[MESH_0][FLOW_SOL]->GetnPrimVarGrad(); - - /*--- Definition of the Class for the numerical method: - numerics_container[INSTANCE_LEVEL][MESH_LEVEL][EQUATION][EQ_TERM] ---*/ - - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - numerics[iMGlevel] = new CNumerics** [MAX_SOLS]; - for (iSol = 0; iSol < MAX_SOLS; iSol++) - numerics[iMGlevel][iSol] = new CNumerics* [MAX_TERMS*omp_get_max_threads()](); - } - - /*--- Instantiate one numerics object per thread for each required term. ---*/ - - for (int thread = 0; thread < omp_get_max_threads(); ++thread) - { - const int offset = thread * MAX_TERMS; - - const int conv_term = CONV_TERM + offset; - const int visc_term = VISC_TERM + offset; - - const int source_first_term = SOURCE_FIRST_TERM + offset; - const int source_second_term = SOURCE_SECOND_TERM + offset; - - const int conv_bound_term = CONV_BOUND_TERM + offset; - const int visc_bound_term = VISC_BOUND_TERM + offset; - - const int fea_term = FEA_TERM + offset; - - /*--- Solver definition for the template problem ---*/ - if (template_solver) { - - /*--- Definition of the convective scheme for each equation and mesh level ---*/ - switch (config->GetKind_ConvNumScheme_Template()) { - case SPACE_CENTERED : case SPACE_UPWIND : - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) - numerics[iMGlevel][TEMPLATE_SOL][conv_term] = new CConvective_Template(nDim, nVar_Template, config); - break; - default: - SU2_MPI::Error("Convective scheme not implemented (template_solver).", CURRENT_FUNCTION); - break; - } - - /*--- Definition of the viscous scheme for each equation and mesh level ---*/ - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) - numerics[iMGlevel][TEMPLATE_SOL][visc_term] = new CViscous_Template(nDim, nVar_Template, config); - - /*--- Definition of the source term integration scheme for each equation and mesh level ---*/ - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) - numerics[iMGlevel][TEMPLATE_SOL][source_first_term] = new CSource_Template(nDim, nVar_Template, config); - - /*--- Definition of the boundary condition method ---*/ - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - numerics[iMGlevel][TEMPLATE_SOL][conv_bound_term] = new CConvective_Template(nDim, nVar_Template, config); - } - - } - - /*--- Solver definition for the Potential, Euler, Navier-Stokes problems ---*/ - if ((euler) || (ns)) { - - /*--- Definition of the convective scheme for each equation and mesh level ---*/ - switch (config->GetKind_ConvNumScheme_Flow()) { - case NO_CONVECTIVE : - SU2_MPI::Error("Config file is missing the CONV_NUM_METHOD_FLOW option.", CURRENT_FUNCTION); - break; - - case SPACE_CENTERED : - if (compressible) { - /*--- "conv_term" is not instantiated as all compressible centered schemes are vectorized. ---*/ - - /*--- Definition of the boundary condition method ---*/ - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) - numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwRoe_Flow(nDim, nVar_Flow, config, false); - - } - if (incompressible) { - /*--- Incompressible flow, use preconditioning method ---*/ - switch (config->GetKind_Centered_Flow()) { - case LAX : numerics[MESH_0][FLOW_SOL][conv_term] = new CCentLaxInc_Flow(nDim, nVar_Flow, config); break; - case JST : numerics[MESH_0][FLOW_SOL][conv_term] = new CCentJSTInc_Flow(nDim, nVar_Flow, config); break; - default: - SU2_MPI::Error("Invalid centered scheme or not implemented.\n Currently, only JST and LAX-FRIEDRICH are available for incompressible flows.", CURRENT_FUNCTION); - break; - } - for (iMGlevel = 1; iMGlevel <= config->GetnMGLevels(); iMGlevel++) - numerics[iMGlevel][FLOW_SOL][conv_term] = new CCentLaxInc_Flow(nDim, nVar_Flow, config); - - /*--- Definition of the boundary condition method ---*/ - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) - numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwFDSInc_Flow(nDim, nVar_Flow, config); - - } - break; - case SPACE_UPWIND : - if (compressible) { - /*--- Compressible flow ---*/ - switch (config->GetKind_Upwind_Flow()) { - case ROE: - if (ideal_gas) { - - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwRoe_Flow(nDim, nVar_Flow, config, roe_low_dissipation); - numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwRoe_Flow(nDim, nVar_Flow, config, false); - } - } else { - - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwGeneralRoe_Flow(nDim, nVar_Flow, config); - numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwGeneralRoe_Flow(nDim, nVar_Flow, config); - } - } - break; - - case AUSM: - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwAUSM_Flow(nDim, nVar_Flow, config); - numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwAUSM_Flow(nDim, nVar_Flow, config); - } - break; - - case AUSMPLUSUP: - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwAUSMPLUSUP_Flow(nDim, nVar_Flow, config); - numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwAUSMPLUSUP_Flow(nDim, nVar_Flow, config); - } - break; - - case AUSMPLUSUP2: - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwAUSMPLUSUP2_Flow(nDim, nVar_Flow, config); - numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwAUSMPLUSUP2_Flow(nDim, nVar_Flow, config); - } - break; - - case TURKEL: - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwTurkel_Flow(nDim, nVar_Flow, config); - numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwTurkel_Flow(nDim, nVar_Flow, config); - } - break; - - case L2ROE: - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwL2Roe_Flow(nDim, nVar_Flow, config); - numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwL2Roe_Flow(nDim, nVar_Flow, config); - } - break; - case LMROE: - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwLMRoe_Flow(nDim, nVar_Flow, config); - numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwLMRoe_Flow(nDim, nVar_Flow, config); - } - break; - - case SLAU: - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwSLAU_Flow(nDim, nVar_Flow, config, roe_low_dissipation); - numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwSLAU_Flow(nDim, nVar_Flow, config, false); - } - break; - - case SLAU2: - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwSLAU2_Flow(nDim, nVar_Flow, config, roe_low_dissipation); - numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwSLAU2_Flow(nDim, nVar_Flow, config, false); - } - break; - - case HLLC: - if (ideal_gas) { - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwHLLC_Flow(nDim, nVar_Flow, config); - numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwHLLC_Flow(nDim, nVar_Flow, config); - } - } - else { - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwGeneralHLLC_Flow(nDim, nVar_Flow, config); - numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwGeneralHLLC_Flow(nDim, nVar_Flow, config); - } - } - break; - - case MSW: - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwMSW_Flow(nDim, nVar_Flow, config); - numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwMSW_Flow(nDim, nVar_Flow, config); - } - break; - - case CUSP: - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwCUSP_Flow(nDim, nVar_Flow, config); - numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwCUSP_Flow(nDim, nVar_Flow, config); - } - break; - - default: - SU2_MPI::Error("Invalid upwind scheme or not implemented.", CURRENT_FUNCTION); - break; - } - - } - if (incompressible) { - /*--- Incompressible flow, use artificial compressibility method ---*/ - switch (config->GetKind_Upwind_Flow()) { - case FDS: - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwFDSInc_Flow(nDim, nVar_Flow, config); - numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwFDSInc_Flow(nDim, nVar_Flow, config); - } - break; - default: - SU2_MPI::Error("Invalid upwind scheme or not implemented.\n Currently, only FDS is available for incompressible flows.", CURRENT_FUNCTION); - break; - } - } - break; - - default: - SU2_MPI::Error("Invalid convective scheme for the Euler / Navier-Stokes equations.", CURRENT_FUNCTION); - break; - } - - /*--- Definition of the viscous scheme for each equation and mesh level ---*/ - if (compressible) { - if (ideal_gas) { - - /*--- Compressible flow Ideal gas ---*/ - numerics[MESH_0][FLOW_SOL][visc_term] = new CAvgGrad_Flow(nDim, nVar_Flow, true, config); - for (iMGlevel = 1; iMGlevel <= config->GetnMGLevels(); iMGlevel++) - numerics[iMGlevel][FLOW_SOL][visc_term] = new CAvgGrad_Flow(nDim, nVar_Flow, false, config); - - /*--- Definition of the boundary condition method ---*/ - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) - numerics[iMGlevel][FLOW_SOL][visc_bound_term] = new CAvgGrad_Flow(nDim, nVar_Flow, false, config); - - } else { - - /*--- Compressible flow Real gas ---*/ - numerics[MESH_0][FLOW_SOL][visc_term] = new CGeneralAvgGrad_Flow(nDim, nVar_Flow, true, config); - for (iMGlevel = 1; iMGlevel <= config->GetnMGLevels(); iMGlevel++) - numerics[iMGlevel][FLOW_SOL][visc_term] = new CGeneralAvgGrad_Flow(nDim, nVar_Flow, false, config); - - /*--- Definition of the boundary condition method ---*/ - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) - numerics[iMGlevel][FLOW_SOL][visc_bound_term] = new CGeneralAvgGrad_Flow(nDim, nVar_Flow, false, config); - - } - } - if (incompressible) { - /*--- Incompressible flow, use preconditioning method ---*/ - numerics[MESH_0][FLOW_SOL][visc_term] = new CAvgGradInc_Flow(nDim, nVar_Flow, true, config); - for (iMGlevel = 1; iMGlevel <= config->GetnMGLevels(); iMGlevel++) - numerics[iMGlevel][FLOW_SOL][visc_term] = new CAvgGradInc_Flow(nDim, nVar_Flow, false, config); - - /*--- Definition of the boundary condition method ---*/ - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) - numerics[iMGlevel][FLOW_SOL][visc_bound_term] = new CAvgGradInc_Flow(nDim, nVar_Flow, false, config); - } - - /*--- Definition of the source term integration scheme for each equation and mesh level ---*/ - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - - if (config->GetBody_Force() == YES) { - if (incompressible) - numerics[iMGlevel][FLOW_SOL][source_first_term] = new CSourceIncBodyForce(nDim, nVar_Flow, config); - else - numerics[iMGlevel][FLOW_SOL][source_first_term] = new CSourceBodyForce(nDim, nVar_Flow, config); - } - else if (incompressible && (config->GetKind_Streamwise_Periodic() != ENUM_STREAMWISE_PERIODIC::NONE)) { - numerics[iMGlevel][FLOW_SOL][source_first_term] = new CSourceIncStreamwise_Periodic(nDim, nVar_Flow, config); - } - else if (incompressible && (config->GetKind_DensityModel() == INC_DENSITYMODEL::BOUSSINESQ)) { - numerics[iMGlevel][FLOW_SOL][source_first_term] = new CSourceBoussinesq(nDim, nVar_Flow, config); - } - else if (config->GetRotating_Frame() == YES) { - if (incompressible) - numerics[iMGlevel][FLOW_SOL][source_first_term] = new CSourceIncRotatingFrame_Flow(nDim, nVar_Flow, config); - else - numerics[iMGlevel][FLOW_SOL][source_first_term] = new CSourceRotatingFrame_Flow(nDim, nVar_Flow, config); - } - else if (config->GetAxisymmetric() == YES) { - if (incompressible) - numerics[iMGlevel][FLOW_SOL][source_first_term] = new CSourceIncAxisymmetric_Flow(nDim, nVar_Flow, config); - else if (ideal_gas) - numerics[iMGlevel][FLOW_SOL][source_first_term] = new CSourceAxisymmetric_Flow(nDim, nVar_Flow, config); - else - numerics[iMGlevel][FLOW_SOL][source_first_term] = new CSourceGeneralAxisymmetric_Flow(nDim, nVar_Flow, config); - } - else if (config->GetGravityForce() == YES) { - numerics[iMGlevel][FLOW_SOL][source_first_term] = new CSourceGravity(nDim, nVar_Flow, config); - } - else if (config->GetWind_Gust() == YES) { - numerics[iMGlevel][FLOW_SOL][source_first_term] = new CSourceWindGust(nDim, nVar_Flow, config); - } - else { - numerics[iMGlevel][FLOW_SOL][source_first_term] = new CSourceNothing(nDim, nVar_Flow, config); - } - - /*--- At the moment it is necessary to have the RHT equation in order to have a volumetric heat source. ---*/ - if (config->AddRadiation()) - numerics[iMGlevel][FLOW_SOL][source_second_term] = new CSourceRadiation(nDim, nVar_Flow, config); - else if ((incompressible && (config->GetKind_Streamwise_Periodic() != ENUM_STREAMWISE_PERIODIC::NONE)) && - (config->GetEnergy_Equation() && !config->GetStreamwise_Periodic_Temperature())) - numerics[iMGlevel][FLOW_SOL][source_second_term] = new CSourceIncStreamwisePeriodic_Outlet(nDim, nVar_Flow, config); - else - numerics[iMGlevel][FLOW_SOL][source_second_term] = new CSourceNothing(nDim, nVar_Flow, config); - } - - } - - /*--- Solver definition for the Potential, Euler, Navier-Stokes NEMO problems ---*/ - - if (NEMO_euler || NEMO_ns) { - - /*--- Definition of the convective scheme for each equation and mesh level ---*/ - switch (config->GetKind_ConvNumScheme_Flow()) { - case NO_CONVECTIVE : - SU2_MPI::Error("Config file is missing the CONV_NUM_METHOD_FLOW option.", CURRENT_FUNCTION); - break; - - case SPACE_CENTERED : - if (compressible) { - /*--- Compressible flow ---*/ - switch (config->GetKind_Centered_Flow()) { - case LAX : numerics[MESH_0][FLOW_SOL][conv_term] = new CCentLax_NEMO(nDim, nVar_NEMO, nPrimVar_NEMO, nPrimVarGrad_NEMO, config); break; - default: - SU2_MPI::Error("Invalid centered scheme or not implemented.", CURRENT_FUNCTION); - break; - } - - for (iMGlevel = 1; iMGlevel <= config->GetnMGLevels(); iMGlevel++) - numerics[iMGlevel][FLOW_SOL][conv_term] = new CCentLax_NEMO(nDim, nVar_NEMO, nPrimVar_NEMO, nPrimVarGrad_NEMO, config); - - /*--- Definition of the boundary condition method ---*/ - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) - numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwRoe_NEMO(nDim, nVar_NEMO, nPrimVar_NEMO, nPrimVarGrad_NEMO, config); - } - break; - case SPACE_UPWIND : - if (compressible) { - /*--- Compressible flow ---*/ - switch (config->GetKind_Upwind_Flow()) { - case ROE: - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwRoe_NEMO(nDim, nVar_NEMO, nPrimVar_NEMO, nPrimVarGrad_NEMO, config); - numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwRoe_NEMO(nDim, nVar_NEMO, nPrimVar_NEMO, nPrimVarGrad_NEMO, config); - } - break; - - case AUSM: - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwAUSM_NEMO(nDim, nVar_NEMO, nPrimVar_NEMO, nPrimVarGrad_NEMO, config); - numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwAUSM_NEMO(nDim, nVar_NEMO, nPrimVar_NEMO, nPrimVarGrad_NEMO, config); - } - break; - - case AUSMPLUSUP2: - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwAUSMPLUSUP2_NEMO(nDim, nVar_NEMO, nPrimVar_NEMO, nPrimVarGrad_NEMO, config); - numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwAUSMPLUSUP2_NEMO(nDim, nVar_NEMO, nPrimVar_NEMO, nPrimVarGrad_NEMO, config); - } - break; - - case MSW: - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwMSW_NEMO(nDim, nVar_NEMO, nPrimVar_NEMO, nPrimVarGrad_NEMO, config); - numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwMSW_NEMO(nDim, nVar_NEMO, nPrimVar_NEMO, nPrimVarGrad_NEMO, config); - } - break; - - case AUSMPWPLUS: - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwAUSMPWplus_NEMO(nDim, nVar_NEMO, nPrimVar_NEMO, nPrimVarGrad_NEMO, config); - numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwAUSMPWplus_NEMO(nDim, nVar_NEMO, nPrimVar_NEMO, nPrimVarGrad_NEMO, config); - } - break; - - default: - SU2_MPI::Error("Invalid upwind scheme or not implemented.", CURRENT_FUNCTION); - break; - } - - } - break; - - default: - SU2_MPI::Error("Invalid convective scheme for the NEMO Euler / Navier-Stokes equations.", CURRENT_FUNCTION); - break; + + /*--- If activated by the compile directive, perform a partition analysis. ---*/ +#if PARTITION + if (!dummy){ + if( fem_solver ) Partition_Analysis_FEM(geometry[MESH_0], config); + else Partition_Analysis(geometry[MESH_0], config); } - - /*--- Definition of the viscous scheme for each equation and mesh level ---*/ - if (compressible) { - - numerics[MESH_0][FLOW_SOL][visc_term] = new CAvgGradCorrected_NEMO(nDim, nVar_NEMO, nPrimVar_NEMO, nPrimVarGrad_NEMO, config); - for (iMGlevel = 1; iMGlevel <= config->GetnMGLevels(); iMGlevel++) - numerics[iMGlevel][FLOW_SOL][visc_term] = new CAvgGrad_NEMO(nDim, nVar_NEMO, nPrimVar_NEMO, nPrimVarGrad_NEMO, config); - - /*--- Definition of the boundary condition method ---*/ - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) - numerics[iMGlevel][FLOW_SOL][visc_bound_term] = new CAvgGrad_NEMO(nDim, nVar_NEMO, nPrimVar_NEMO, nPrimVarGrad_NEMO, config); +#endif + + /*--- Check if Euler & Symmetry markers are straight/plane. This information + is used in the Euler & Symmetry boundary routines. ---*/ + if((config_container[iZone]->GetnMarker_Euler() != 0 || + config_container[iZone]->GetnMarker_SymWall() != 0) && + !fem_solver) { + + if (rank == MASTER_NODE) + cout << "Checking if Euler & Symmetry markers are straight/plane:" << endl; + + for (iMesh = 0; iMesh <= config_container[iZone]->GetnMGLevels(); iMesh++) + geometry_container[iZone][iInst][iMesh]->ComputeSurf_Straightness(config_container[iZone], (iMesh==MESH_0) ); + } + +} - /*--- Definition of the source term integration scheme for each equation and mesh level ---*/ +void CDriver::Geometrical_Preprocessing_FVM(CConfig *config, CGeometry **&geometry) { + + unsigned short iZone = config->GetiZone(), iMGlevel; + unsigned short requestedMGlevels = config->GetnMGLevels(); + const bool fea = config->GetStructuralProblem(); + + /*--- Definition of the geometry class to store the primal grid in the partitioning process. + * All ranks process the grid and call ParMETIS for partitioning ---*/ + + CGeometry *geometry_aux = new CPhysicalGeometry(config, iZone, nZone); + + /*--- Set the dimension --- */ + + nDim = geometry_aux->GetnDim(); + + /*--- Color the initial grid and set the send-receive domains (ParMETIS) ---*/ + + geometry_aux->SetColorGrid_Parallel(config); + + /*--- Allocate the memory of the current domain, and divide the grid + between the ranks. ---*/ + + geometry = new CGeometry *[config->GetnMGLevels()+1] (); + + /*--- Build the grid data structures using the ParMETIS coloring. ---*/ + + geometry[MESH_0] = new CPhysicalGeometry(geometry_aux, config); + + /*--- Deallocate the memory of geometry_aux and solver_aux ---*/ + + delete geometry_aux; + + /*--- Add the Send/Receive boundaries ---*/ + geometry[MESH_0]->SetSendReceive(config); + + /*--- Add the Send/Receive boundaries ---*/ + geometry[MESH_0]->SetBoundaries(config); + + /*--- Compute elements surrounding points, points surrounding points ---*/ + + if (rank == MASTER_NODE) cout << "Setting point connectivity." << endl; + geometry[MESH_0]->SetPoint_Connectivity(); + + /*--- Renumbering points using Reverse Cuthill McKee ordering ---*/ + + if (rank == MASTER_NODE) cout << "Renumbering points (Reverse Cuthill McKee Ordering)." << endl; + geometry[MESH_0]->SetRCM_Ordering(config); + + /*--- recompute elements surrounding points, points surrounding points ---*/ + + if (rank == MASTER_NODE) cout << "Recomputing point connectivity." << endl; + geometry[MESH_0]->SetPoint_Connectivity(); + + /*--- Compute elements surrounding elements ---*/ + + if (rank == MASTER_NODE) cout << "Setting element connectivity." << endl; + geometry[MESH_0]->SetElement_Connectivity(); + + /*--- Check the orientation before computing geometrical quantities ---*/ + + geometry[MESH_0]->SetBoundVolume(); + if (config->GetReorientElements()) { + if (rank == MASTER_NODE) cout << "Checking the numerical grid orientation." << endl; + geometry[MESH_0]->Check_IntElem_Orientation(config); + geometry[MESH_0]->Check_BoundElem_Orientation(config); + } + + /*--- Create the edge structure ---*/ + + if (rank == MASTER_NODE) cout << "Identifying edges and vertices." << endl; + geometry[MESH_0]->SetEdges(); + geometry[MESH_0]->SetVertex(config); + + /*--- Create the control volume structures ---*/ + + if (rank == MASTER_NODE) cout << "Setting the control volume structure." << endl; + SU2_OMP_PARALLEL { + geometry[MESH_0]->SetControlVolume(config, ALLOCATE); + geometry[MESH_0]->SetBoundControlVolume(config, ALLOCATE); + } + END_SU2_OMP_PARALLEL + + /*--- Visualize a dual control volume if requested ---*/ + + if ((config->GetVisualize_CV() >= 0) && + (config->GetVisualize_CV() < (long)geometry[MESH_0]->GetGlobal_nPointDomain())) + geometry[MESH_0]->VisualizeControlVolume(config); + + /*--- Identify closest normal neighbor ---*/ + + if (rank == MASTER_NODE) cout << "Searching for the closest normal neighbors to the surfaces." << endl; + geometry[MESH_0]->FindNormal_Neighbor(config); + + /*--- Store the global to local mapping. ---*/ + + if (rank == MASTER_NODE) cout << "Storing a mapping from global to local point index." << endl; + geometry[MESH_0]->SetGlobal_to_Local_Point(); + + /*--- Compute the surface curvature ---*/ + + if (!fea) { + if (rank == MASTER_NODE) cout << "Compute the surface curvature." << endl; + geometry[MESH_0]->ComputeSurf_Curvature(config); + } + + /*--- Check for periodicity and disable MG if necessary. ---*/ + + if (rank == MASTER_NODE) cout << "Checking for periodicity." << endl; + geometry[MESH_0]->Check_Periodicity(config); + + /*--- Compute mesh quality statistics on the fine grid. ---*/ + + if (!fea) { + if (rank == MASTER_NODE) + cout << "Computing mesh quality statistics for the dual control volumes." << endl; + geometry[MESH_0]->ComputeMeshQualityStatistics(config); + } + + geometry[MESH_0]->SetMGLevel(MESH_0); + if ((config->GetnMGLevels() != 0) && (rank == MASTER_NODE)) + cout << "Setting the multigrid structure." << endl; + + /*--- Loop over all the new grid ---*/ + + for (iMGlevel = 1; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + + /*--- Create main agglomeration structure ---*/ + + geometry[iMGlevel] = new CMultiGridGeometry(geometry[iMGlevel-1], config, iMGlevel); + + /*--- Compute points surrounding points. ---*/ + + geometry[iMGlevel]->SetPoint_Connectivity(geometry[iMGlevel-1]); + + /*--- Create the edge structure ---*/ + + geometry[iMGlevel]->SetEdges(); + geometry[iMGlevel]->SetVertex(geometry[iMGlevel-1], config); + + /*--- Create the control volume structures ---*/ + + geometry[iMGlevel]->SetControlVolume(geometry[iMGlevel-1], ALLOCATE); + geometry[iMGlevel]->SetBoundControlVolume(geometry[iMGlevel-1], ALLOCATE); + geometry[iMGlevel]->SetCoord(geometry[iMGlevel-1]); + + /*--- Find closest neighbor to a surface point ---*/ + + geometry[iMGlevel]->FindNormal_Neighbor(config); + + /*--- Store our multigrid index. ---*/ + + geometry[iMGlevel]->SetMGLevel(iMGlevel); + + /*--- Protect against the situation that we were not able to complete + the agglomeration for this level, i.e., there weren't enough points. + We need to check if we changed the total number of levels and delete + the incomplete CMultiGridGeometry object. ---*/ + + if (config->GetnMGLevels() != requestedMGlevels) { + delete geometry[iMGlevel]; + geometry[iMGlevel] = nullptr; + break; + } + + } + + if (config->GetWrt_MultiGrid()) geometry[MESH_0]->ColorMGLevels(config->GetnMGLevels(), geometry); + + /*--- For unsteady simulations, initialize the grid volumes + and coordinates for previous solutions. Loop over all zones/grids ---*/ + + if ((config->GetTime_Marching() != TIME_MARCHING::STEADY) && config->GetDynamic_Grid()) { + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + + /*--- Update cell volume ---*/ + geometry[iMGlevel]->nodes->SetVolume_n(); + geometry[iMGlevel]->nodes->SetVolume_nM1(); + + if (config->GetGrid_Movement()) { + /*--- Update point coordinates ---*/ + geometry[iMGlevel]->nodes->SetCoord_n(); + geometry[iMGlevel]->nodes->SetCoord_n1(); + } + } + } + + + /*--- Create the data structure for MPI point-to-point communications. ---*/ + + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) + geometry[iMGlevel]->PreprocessP2PComms(geometry[iMGlevel], config); + + + /*--- Perform a few preprocessing routines and communications. ---*/ + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - - numerics[iMGlevel][FLOW_SOL][source_first_term] = new CSource_NEMO(nDim, nVar_NEMO, nPrimVar_NEMO, nPrimVarGrad_NEMO, config); - numerics[iMGlevel][FLOW_SOL][source_second_term] = new CSourceNothing(nDim, nVar_NEMO, config); + + /*--- Compute the max length. ---*/ + + if (!fea) { + if ((rank == MASTER_NODE) && (iMGlevel == MESH_0)) + cout << "Finding max control volume width." << endl; + geometry[iMGlevel]->SetMaxLength(config); + } + + /*--- Communicate the number of neighbors. This is needed for + some centered schemes and for multigrid in parallel. ---*/ + + if ((rank == MASTER_NODE) && (size > SINGLE_NODE) && (iMGlevel == MESH_0)) + cout << "Communicating number of neighbors." << endl; + geometry[iMGlevel]->InitiateComms(geometry[iMGlevel], config, NEIGHBORS); + geometry[iMGlevel]->CompleteComms(geometry[iMGlevel], config, NEIGHBORS); } - } + +} - /*--- Riemann solver definition for the Euler, Navier-Stokes problems for the FEM discretization. ---*/ - if ((fem_euler) || (fem_ns)) { +void CDriver::Geometrical_Preprocessing_DGFEM(CConfig* config, CGeometry **&geometry) { + + /*--- Definition of the geometry class to store the primal grid in the partitioning process. ---*/ + /*--- All ranks process the grid and call ParMETIS for partitioning ---*/ + + CGeometry *geometry_aux = new CPhysicalGeometry(config, iZone, nZone); + + /*--- Set the dimension --- */ + + nDim = geometry_aux->GetnDim(); + + /*--- For the FEM solver with time-accurate local time-stepping, use + a dummy solver class to retrieve the initial flow state. ---*/ + + CSolver *solver_aux = new CFEM_DG_EulerSolver(config, nDim, MESH_0); + + /*--- Color the initial grid and set the send-receive domains (ParMETIS) ---*/ + + geometry_aux->SetColorFEMGrid_Parallel(config); + + /*--- Allocate the memory of the current domain, and divide the grid + between the ranks. ---*/ + + geometry = new CGeometry *[config->GetnMGLevels()+1] (); + + geometry[MESH_0] = new CMeshFEM_DG(geometry_aux, config); + + /*--- Deallocate the memory of geometry_aux and solver_aux ---*/ + + delete geometry_aux; + delete solver_aux; + + /*--- Add the Send/Receive boundaries ---*/ + geometry[MESH_0]->SetSendReceive(config); + + /*--- Add the Send/Receive boundaries ---*/ + geometry[MESH_0]->SetBoundaries(config); + + /*--- Carry out a dynamic cast to CMeshFEM_DG, such that it is not needed to + define all virtual functions in the base class CGeometry. ---*/ + CMeshFEM_DG *DGMesh = dynamic_cast(geometry[MESH_0]); + + /*--- Determine the standard elements for the volume elements. ---*/ + if (rank == MASTER_NODE) cout << "Creating standard volume elements." << endl; + DGMesh->CreateStandardVolumeElements(config); + + /*--- Create the face information needed to compute the contour integral + for the elements in the Discontinuous Galerkin formulation. ---*/ + if (rank == MASTER_NODE) cout << "Creating face information." << endl; + DGMesh->CreateFaces(config); + + /*--- Compute the metric terms of the volume elements. ---*/ + if (rank == MASTER_NODE) cout << "Computing metric terms volume elements." << endl; + DGMesh->MetricTermsVolumeElements(config); + + /*--- Compute the metric terms of the surface elements. ---*/ + if (rank == MASTER_NODE) cout << "Computing metric terms surface elements." << endl; + DGMesh->MetricTermsSurfaceElements(config); + + /*--- Compute a length scale of the volume elements. ---*/ + if (rank == MASTER_NODE) cout << "Computing length scale volume elements." << endl; + DGMesh->LengthScaleVolumeElements(); + + /*--- Compute the coordinates of the integration points. ---*/ + if (rank == MASTER_NODE) cout << "Computing coordinates of the integration points." << endl; + DGMesh->CoordinatesIntegrationPoints(); + + /*--- Compute the coordinates of the location of the solution DOFs. This is different + from the grid points when a different polynomial degree is used to represent the + geometry and solution. ---*/ + if (rank == MASTER_NODE) cout << "Computing coordinates of the solution DOFs." << endl; + DGMesh->CoordinatesSolDOFs(); + + /*--- Perform the preprocessing tasks when wall functions are used. ---*/ + if (rank == MASTER_NODE) cout << "Preprocessing for the wall functions. " << endl; + DGMesh->WallFunctionPreprocessing(config); + + /*--- Store the global to local mapping. ---*/ + if (rank == MASTER_NODE) cout << "Storing a mapping from global to local DOF index." << endl; + geometry[MESH_0]->SetGlobal_to_Local_Point(); + + + /*--- Loop to create the coarser grid levels. ---*/ + + for(unsigned short iMGlevel=1; iMGlevel<=config->GetnMGLevels(); iMGlevel++) { + + SU2_MPI::Error("Geometrical_Preprocessing_DGFEM: Coarse grid levels not implemented yet.", + CURRENT_FUNCTION); + } + +} - switch (config->GetRiemann_Solver_FEM()) { - case ROE: - case LAX_FRIEDRICH: - /* Hard coded optimized implementation is used in the DG solver. No need to allocate the - corresponding entry in numerics. */ - break; +void CDriver::Solver_Preprocessing(CConfig* config, CGeometry** geometry, CSolver ***&solver) { + + MAIN_SOLVER kindSolver = config->GetKind_Solver(); + + if (rank == MASTER_NODE) + cout << endl <<"-------------------- Solver Preprocessing ( Zone " << config->GetiZone() <<" ) --------------------" << endl; + + solver = new CSolver**[config->GetnMGLevels()+1] (); + + for (iMesh = 0; iMesh <= config->GetnMGLevels(); iMesh++){ + solver[iMesh] = CSolverFactory::CreateSolverContainer(kindSolver, config, geometry[iMesh], iMesh); + } + + /*--- Count the number of DOFs per solution point. ---*/ + + DOFsPerPoint = 0; + + for (unsigned int iSol = 0; iSol < MAX_SOLS; iSol++) + if (solver[MESH_0][iSol]) DOFsPerPoint += solver[MESH_0][iSol]->GetnVar(); + + /*--- Restart solvers, for FSI the geometry cannot be updated because the interpolation classes + * should always use the undeformed mesh (otherwise the results would not be repeatable). ---*/ + + if (!fsi) Solver_Restart(solver, geometry, config, true); + + /*--- Set up any necessary inlet profiles ---*/ + + Inlet_Preprocessing(solver, geometry, config); + +} - case AUSM: - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwAUSM_Flow(nDim, nVar_Flow, config); - numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwAUSM_Flow(nDim, nVar_Flow, config); +void CDriver::Inlet_Preprocessing(CSolver ***solver, CGeometry **geometry, + CConfig *config) const { + + /*--- Adjust iteration number for unsteady restarts. ---*/ + + const bool adjoint = config->GetDiscrete_Adjoint() || config->GetContinuous_Adjoint(); + + int val_iter = 0; + + if (config->GetTime_Domain()) { + val_iter = adjoint? config->GetUnst_AdjointIter() : config->GetRestart_Iter(); + val_iter -= 1; + if (!adjoint && config->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_2ND) + val_iter -= 1; + if (!adjoint && !config->GetRestart()) val_iter = 0; + } + + /*--- Load inlet profile files for any of the active solver containers. + Note that these routines fill the fine grid data structures for the markers + and restrict values down to all coarser MG levels. ---*/ + + if (config->GetInlet_Profile_From_File()) { + + /*--- Use LoadInletProfile() routines for the particular solver. ---*/ + + if (rank == MASTER_NODE) { + cout << endl; + cout << "Reading inlet profile from file: "; + cout << config->GetInlet_FileName() << endl; } - break; - - case TURKEL: - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwTurkel_Flow(nDim, nVar_Flow, config); - numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwTurkel_Flow(nDim, nVar_Flow, config); + + if (solver[MESH_0][FLOW_SOL]) { + solver[MESH_0][FLOW_SOL]->LoadInletProfile(geometry, solver, config, val_iter, FLOW_SOL, INLET_FLOW); } - break; - - case HLLC: - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwHLLC_Flow(nDim, nVar_Flow, config); - numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwHLLC_Flow(nDim, nVar_Flow, config); - } - break; - - case MSW: - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwMSW_Flow(nDim, nVar_Flow, config); - numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwMSW_Flow(nDim, nVar_Flow, config); + if (solver[MESH_0][TURB_SOL]) { + solver[MESH_0][TURB_SOL]->LoadInletProfile(geometry, solver, config, val_iter, TURB_SOL, INLET_FLOW); } - break; - - case CUSP: - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwCUSP_Flow(nDim, nVar_Flow, config); - numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwCUSP_Flow(nDim, nVar_Flow, config); + if (solver[MESH_0][SPECIES_SOL]) { + solver[MESH_0][SPECIES_SOL]->LoadInletProfile(geometry, solver, config, val_iter, SPECIES_SOL, INLET_FLOW); } - break; - - default: - SU2_MPI::Error("Riemann solver not implemented.", CURRENT_FUNCTION); - break; - } - - } - - /*--- Solver definition for the turbulent model problem ---*/ - - if (turbulent) { - if (incompressible) - InstantiateTurbulentNumerics >(nVar_Turb, offset, config, - solver[MESH_0][TURB_SOL], numerics); - else if (NEMO_ns) - InstantiateTurbulentNumerics >(nVar_Turb, offset, config, - solver[MESH_0][TURB_SOL], numerics); - else - InstantiateTurbulentNumerics >(nVar_Turb, offset, config, - solver[MESH_0][TURB_SOL], numerics); - } - - /*--- Solver definition for the transition model problem ---*/ - if (transition) { - - /*--- Definition of the convective scheme for each equation and mesh level ---*/ - switch (config->GetKind_ConvNumScheme_Turb()) { - case NO_UPWIND: - SU2_MPI::Error("Config file is missing the CONV_NUM_METHOD_TURB option.", CURRENT_FUNCTION); - break; - case SPACE_UPWIND: - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - numerics[iMGlevel][TRANS_SOL][conv_term] = new CUpwSca_TransLM(nDim, nVar_Trans, config); + + /*--- Exit if profiles were requested for a solver that is not available. ---*/ + + if (!config->GetFluidProblem()) { + SU2_MPI::Error(string("Inlet profile specification via file (C++) has not been \n") + + string("implemented yet for this solver.\n") + + string("Please set SPECIFIED_INLET_PROFILE= NO and try again."), CURRENT_FUNCTION); + } + + } else { + + /*--- Uniform inlets or python-customized inlets ---*/ + + /* --- Initialize quantities for inlet boundary + * This routine does not check if they python wrapper is being used to + * set custom boundary conditions. This is intentional; the + * default values for python custom BCs are initialized with the default + * values specified in the config (avoiding non physical values) --- */ + + for (unsigned short iMesh = 0; iMesh <= config->GetnMGLevels(); iMesh++) { + for(unsigned short iMarker=0; iMarker < config->GetnMarker_All(); iMarker++) { + if (solver[iMesh][FLOW_SOL]) solver[iMesh][FLOW_SOL]->SetUniformInlet(config, iMarker); + if (solver[iMesh][TURB_SOL]) solver[iMesh][TURB_SOL]->SetUniformInlet(config, iMarker); + if (solver[iMesh][SPECIES_SOL]) solver[iMesh][SPECIES_SOL]->SetUniformInlet(config, iMarker); + } } - break; - default: - SU2_MPI::Error("Invalid convective scheme for the transition equations.", CURRENT_FUNCTION); - break; + } + +} - /*--- Definition of the viscous scheme for each equation and mesh level ---*/ - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - numerics[iMGlevel][TRANS_SOL][visc_term] = new CAvgGradCorrected_TransLM(nDim, nVar_Trans, config); +void CDriver::Solver_Restart(CSolver ***solver, CGeometry **geometry, + CConfig *config, bool update_geo) { + + /*--- Check for restarts and use the LoadRestart() routines. ---*/ + + const bool restart = config->GetRestart(); + const bool restart_flow = config->GetRestart_Flow(); + + /*--- Adjust iteration number for unsteady restarts. ---*/ + + int val_iter = 0; + + const bool adjoint = (config->GetDiscrete_Adjoint() || config->GetContinuous_Adjoint()); + const bool time_domain = config->GetTime_Domain(); + const bool dt_step_2nd = (config->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_2ND) && + !config->GetStructuralProblem() && !config->GetFEMSolver() && + !adjoint && time_domain; + + if (time_domain) { + if (adjoint) val_iter = config->GetUnst_AdjointIter() - 1; + else val_iter = config->GetRestart_Iter() - 1 - dt_step_2nd; + } + + /*--- Restart direct solvers. ---*/ + + if (restart || restart_flow) { + for (auto iSol = 0u; iSol < MAX_SOLS; ++iSol) { + auto sol = solver[MESH_0][iSol]; + if (sol && !sol->GetAdjoint()) { + /*--- Note that the mesh solver always loads the most recent file (and not -2). ---*/ + SU2_OMP_PARALLEL_(if(sol->GetHasHybridParallel())) + sol->LoadRestart(geometry, solver, config, val_iter + (iSol==MESH_SOL && dt_step_2nd), update_geo); + END_SU2_OMP_PARALLEL + } + } } - - /*--- Definition of the source term integration scheme for each equation and mesh level ---*/ - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - numerics[iMGlevel][TRANS_SOL][source_first_term] = new CSourcePieceWise_TransLM(nDim, nVar_Trans, config); - numerics[iMGlevel][TRANS_SOL][source_second_term] = new CSourceNothing(nDim, nVar_Trans, config); + + /*--- Restart adjoint solvers. ---*/ + + if (restart) { + if ((config->GetKind_Solver() == MAIN_SOLVER::TEMPLATE_SOLVER) || + (config->GetKind_Solver() == MAIN_SOLVER::ADJ_RANS && !config->GetFrozen_Visc_Cont())) { + SU2_MPI::Error("A restart capability has not been implemented yet for this solver.\n" + "Please set RESTART_SOL= NO and try again.", CURRENT_FUNCTION); + } + + for (auto iSol = 0u; iSol < MAX_SOLS; ++iSol) { + auto sol = solver[MESH_0][iSol]; + if (sol && sol->GetAdjoint()) + sol->LoadRestart(geometry, solver, config, val_iter, update_geo); + } } + +} - /*--- Definition of the boundary condition method ---*/ - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - numerics[iMGlevel][TRANS_SOL][conv_bound_term] = new CUpwLin_TransLM(nDim, nVar_Trans, config); +void CDriver::Solver_Postprocessing(CSolver ****solver, CGeometry **geometry, + CConfig *config, unsigned short val_iInst) { + + for (int iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + for (unsigned int iSol = 0; iSol < MAX_SOLS; iSol++){ + delete solver[val_iInst][iMGlevel][iSol]; + } + delete [] solver[val_iInst][iMGlevel]; } - } - - /*--- Solver definition for the species transport problem ---*/ - - if (species) { - if (incompressible) - InstantiateSpeciesNumerics >(nVar_Species, offset, config, - solver[MESH_0][SPECIES_SOL], numerics); - else if (compressible) - InstantiateSpeciesNumerics >(nVar_Species, offset, config, - solver[MESH_0][SPECIES_SOL], numerics); - else - SU2_MPI::Error("Species transport only available for standard compressible and incompressible flow.", CURRENT_FUNCTION); - } - - /*--- Solver definition of the finite volume heat solver ---*/ - if (heat) { - - /*--- Definition of the viscous scheme for each equation and mesh level ---*/ - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + delete [] solver[val_iInst]; + + CSolverFactory::ClearSolverMeta(); + +} - numerics[iMGlevel][HEAT_SOL][visc_term] = new CAvgGrad_Heat(nDim, nVar_Heat, config, true); - numerics[iMGlevel][HEAT_SOL][visc_bound_term] = new CAvgGrad_Heat(nDim, nVar_Heat, config, false); +void CDriver::Integration_Preprocessing(CConfig *config, CSolver **solver, CIntegration **&integration) const { + + if (rank == MASTER_NODE) + cout << endl <<"----------------- Integration Preprocessing ( Zone " << config->GetiZone() <<" ) ------------------" << endl; + + MAIN_SOLVER kindMainSolver = config->GetKind_Solver(); + + integration = CIntegrationFactory::CreateIntegrationContainer(kindMainSolver, solver); + +} - switch (config->GetKind_ConvNumScheme_Heat()) { +void CDriver::Integration_Postprocessing(CIntegration ***integration, CGeometry **geometry, CConfig *config, unsigned short val_iInst) { + + for (unsigned int iSol = 0; iSol < MAX_SOLS; iSol++){ + delete integration[val_iInst][iSol]; + } + + delete [] integration[val_iInst]; + +} +template +void CDriver::InstantiateTurbulentNumerics(unsigned short nVar_Turb, int offset, const CConfig *config, + const CSolver* turb_solver, CNumerics ****&numerics) const { + const int conv_term = CONV_TERM + offset; + const int visc_term = VISC_TERM + offset; + + const int source_first_term = SOURCE_FIRST_TERM + offset; + const int source_second_term = SOURCE_SECOND_TERM + offset; + + const int conv_bound_term = CONV_BOUND_TERM + offset; + const int visc_bound_term = VISC_BOUND_TERM + offset; + + bool spalart_allmaras, neg_spalart_allmaras, e_spalart_allmaras, comp_spalart_allmaras, e_comp_spalart_allmaras, menter_sst; + spalart_allmaras = neg_spalart_allmaras = e_spalart_allmaras = comp_spalart_allmaras = e_comp_spalart_allmaras = menter_sst = false; + + /*--- Assign turbulence model booleans ---*/ + + switch (config->GetKind_Turb_Model()) { + case TURB_MODEL::NONE: + SU2_MPI::Error("No turbulence model selected.", CURRENT_FUNCTION); + break; + case TURB_MODEL::SA: spalart_allmaras = true; break; + case TURB_MODEL::SA_NEG: neg_spalart_allmaras = true; break; + case TURB_MODEL::SA_E: e_spalart_allmaras = true; break; + case TURB_MODEL::SA_COMP: comp_spalart_allmaras = true; break; + case TURB_MODEL::SA_E_COMP: e_comp_spalart_allmaras = true; break; + case TURB_MODEL::SST: menter_sst = true; break; + case TURB_MODEL::SST_SUST: menter_sst = true; break; + } + + /*--- If the Menter SST model is used, store the constants of the model and determine the + free stream values of the turbulent kinetic energy and dissipation rate. ---*/ + + const su2double *constants = nullptr; + su2double kine_Inf = 0.0, omega_Inf = 0.0; + + if (menter_sst) { + constants = turb_solver->GetConstants(); + kine_Inf = turb_solver->GetTke_Inf(); + omega_Inf = turb_solver->GetOmega_Inf(); + } + + /*--- Definition of the convective scheme for each equation and mesh level ---*/ + + switch (config->GetKind_ConvNumScheme_Turb()) { + case NO_UPWIND: + SU2_MPI::Error("Config file is missing the CONV_NUM_METHOD_TURB option.", CURRENT_FUNCTION); + break; case SPACE_UPWIND : - numerics[iMGlevel][HEAT_SOL][conv_term] = new CUpwSca_Heat(nDim, nVar_Heat, config); - numerics[iMGlevel][HEAT_SOL][conv_bound_term] = new CUpwSca_Heat(nDim, nVar_Heat, config); - break; - - case SPACE_CENTERED : - numerics[iMGlevel][HEAT_SOL][conv_term] = new CCentSca_Heat(nDim, nVar_Heat, config); - numerics[iMGlevel][HEAT_SOL][conv_bound_term] = new CUpwSca_Heat(nDim, nVar_Heat, config); - break; - + for (auto iMGlevel = 0u; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + if (spalart_allmaras || neg_spalart_allmaras || e_spalart_allmaras || comp_spalart_allmaras || e_comp_spalart_allmaras) { + numerics[iMGlevel][TURB_SOL][conv_term] = new CUpwSca_TurbSA(nDim, nVar_Turb, config); + } + else if (menter_sst) numerics[iMGlevel][TURB_SOL][conv_term] = new CUpwSca_TurbSST(nDim, nVar_Turb, config); + } + break; default: - SU2_MPI::Error("Invalid convective scheme for the heat transfer equations.", CURRENT_FUNCTION); - break; - } + SU2_MPI::Error("Invalid convective scheme for the turbulence equations.", CURRENT_FUNCTION); + break; } - } - - /*--- Solver definition for the radiation model problem ---*/ - - if (config->AddRadiation()) { + /*--- Definition of the viscous scheme for each equation and mesh level ---*/ - numerics[MESH_0][RAD_SOL][VISC_TERM] = new CAvgGradCorrected_P1(nDim, nVar_Rad, config); - + + for (auto iMGlevel = 0u; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + if (spalart_allmaras || e_spalart_allmaras || comp_spalart_allmaras || e_comp_spalart_allmaras) { + numerics[iMGlevel][TURB_SOL][visc_term] = new CAvgGrad_TurbSA(nDim, nVar_Turb, true, config); + } + else if (neg_spalart_allmaras) + numerics[iMGlevel][TURB_SOL][visc_term] = new CAvgGrad_TurbSA_Neg(nDim, nVar_Turb, true, config); + else if (menter_sst) + numerics[iMGlevel][TURB_SOL][visc_term] = new CAvgGrad_TurbSST(nDim, nVar_Turb, constants, true, config); + } + /*--- Definition of the source term integration scheme for each equation and mesh level ---*/ - numerics[MESH_0][RAD_SOL][SOURCE_FIRST_TERM] = new CSourceP1(nDim, nVar_Rad, config); - + + for (auto iMGlevel = 0u; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + auto& turb_source_first_term = numerics[iMGlevel][TURB_SOL][source_first_term]; + + if (spalart_allmaras) + turb_source_first_term = new CSourcePieceWise_TurbSA(nDim, nVar_Turb, config); + else if (e_spalart_allmaras) + turb_source_first_term = new CSourcePieceWise_TurbSA_E(nDim, nVar_Turb, config); + else if (comp_spalart_allmaras) + turb_source_first_term = new CSourcePieceWise_TurbSA_COMP(nDim, nVar_Turb, config); + else if (e_comp_spalart_allmaras) + turb_source_first_term = new CSourcePieceWise_TurbSA_E_COMP(nDim, nVar_Turb, config); + else if (neg_spalart_allmaras) + turb_source_first_term = new CSourcePieceWise_TurbSA_Neg(nDim, nVar_Turb, config); + else if (menter_sst) + turb_source_first_term = new CSourcePieceWise_TurbSST(nDim, nVar_Turb, constants, kine_Inf, omega_Inf, + config); + + numerics[iMGlevel][TURB_SOL][source_second_term] = new CSourceNothing(nDim, nVar_Turb, config); + } + /*--- Definition of the boundary condition method ---*/ - numerics[MESH_0][RAD_SOL][VISC_BOUND_TERM] = new CAvgGradCorrected_P1(nDim, nVar_Rad, config); - } - - /*--- Solver definition for the flow adjoint problem ---*/ - - if (adj_euler || adj_ns) { - - if (incompressible) - SU2_MPI::Error("Convective schemes not implemented for incompressible continuous adjoint.", CURRENT_FUNCTION); - - /*--- Definition of the convective scheme for each equation and mesh level ---*/ - - switch (config->GetKind_ConvNumScheme_AdjFlow()) { - case NO_CONVECTIVE: - SU2_MPI::Error("Config file is missing the CONV_NUM_METHOD_ADJFLOW option.", CURRENT_FUNCTION); - break; - - case SPACE_CENTERED : - - if (compressible) { - - /*--- Compressible flow ---*/ - - switch (config->GetKind_Centered_AdjFlow()) { - case LAX : numerics[MESH_0][ADJFLOW_SOL][conv_term] = new CCentLax_AdjFlow(nDim, nVar_Adj_Flow, config); break; - case JST : numerics[MESH_0][ADJFLOW_SOL][conv_term] = new CCentJST_AdjFlow(nDim, nVar_Adj_Flow, config); break; - default: - SU2_MPI::Error("Centered scheme not implemented.", CURRENT_FUNCTION); - break; - } - - for (iMGlevel = 1; iMGlevel <= config->GetnMGLevels(); iMGlevel++) - numerics[iMGlevel][ADJFLOW_SOL][conv_term] = new CCentLax_AdjFlow(nDim, nVar_Adj_Flow, config); - - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) - numerics[iMGlevel][ADJFLOW_SOL][conv_bound_term] = new CUpwRoe_AdjFlow(nDim, nVar_Adj_Flow, config); - + + for (auto iMGlevel = 0u; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + if (spalart_allmaras || e_spalart_allmaras || comp_spalart_allmaras || e_comp_spalart_allmaras) { + numerics[iMGlevel][TURB_SOL][conv_bound_term] = new CUpwSca_TurbSA(nDim, nVar_Turb, config); + numerics[iMGlevel][TURB_SOL][visc_bound_term] = new CAvgGrad_TurbSA(nDim, nVar_Turb, false, config); } - break; - - case SPACE_UPWIND : - - if (compressible) { - - /*--- Compressible flow ---*/ - - switch (config->GetKind_Upwind_AdjFlow()) { - case ROE: - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - numerics[iMGlevel][ADJFLOW_SOL][conv_term] = new CUpwRoe_AdjFlow(nDim, nVar_Adj_Flow, config); - numerics[iMGlevel][ADJFLOW_SOL][conv_bound_term] = new CUpwRoe_AdjFlow(nDim, nVar_Adj_Flow, config); - } - break; - default: - SU2_MPI::Error("Upwind scheme not implemented.", CURRENT_FUNCTION); - break; - } + else if (neg_spalart_allmaras) { + numerics[iMGlevel][TURB_SOL][conv_bound_term] = new CUpwSca_TurbSA(nDim, nVar_Turb, config); + numerics[iMGlevel][TURB_SOL][visc_bound_term] = new CAvgGrad_TurbSA_Neg(nDim, nVar_Turb, false, config); + } + else if (menter_sst) { + numerics[iMGlevel][TURB_SOL][conv_bound_term] = new CUpwSca_TurbSST(nDim, nVar_Turb, config); + numerics[iMGlevel][TURB_SOL][visc_bound_term] = new CAvgGrad_TurbSST(nDim, nVar_Turb, constants, false, + config); } - break; - - default: - SU2_MPI::Error("Invalid convective scheme for the continuous adjoint Euler / Navier-Stokes equations.", CURRENT_FUNCTION); - break; } +} +/*--- Explicit instantiation of the template above, needed because it is defined in a cpp file, instead of hpp. ---*/ +template void CDriver::InstantiateTurbulentNumerics>( + unsigned short, int, const CConfig*, const CSolver*, CNumerics****&) const; - /*--- Definition of the viscous scheme for each equation and mesh level ---*/ - - if (compressible) { - - /*--- Compressible flow ---*/ - - numerics[MESH_0][ADJFLOW_SOL][visc_term] = new CAvgGradCorrected_AdjFlow(nDim, nVar_Adj_Flow, config); - numerics[MESH_0][ADJFLOW_SOL][visc_bound_term] = new CAvgGrad_AdjFlow(nDim, nVar_Adj_Flow, config); +template void CDriver::InstantiateTurbulentNumerics>( + unsigned short, int, const CConfig*, const CSolver*, CNumerics****&) const; - for (iMGlevel = 1; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - numerics[iMGlevel][ADJFLOW_SOL][visc_term] = new CAvgGrad_AdjFlow(nDim, nVar_Adj_Flow, config); - numerics[iMGlevel][ADJFLOW_SOL][visc_bound_term] = new CAvgGrad_AdjFlow(nDim, nVar_Adj_Flow, config); - } +template void CDriver::InstantiateTurbulentNumerics>( + unsigned short, int, const CConfig*, const CSolver*, CNumerics****&) const; +template +void CDriver::InstantiateSpeciesNumerics(unsigned short nVar_Species, int offset, const CConfig *config, + const CSolver* species_solver, CNumerics ****&numerics) const { + const int conv_term = CONV_TERM + offset; + const int visc_term = VISC_TERM + offset; + + const int source_first_term = SOURCE_FIRST_TERM + offset; + const int source_second_term = SOURCE_SECOND_TERM + offset; + + const int conv_bound_term = CONV_BOUND_TERM + offset; + const int visc_bound_term = VISC_BOUND_TERM + offset; + + /*--- Definition of the convective scheme for each equation and mesh level. Also for boundary conditions. ---*/ + + switch (config->GetKind_ConvNumScheme_Species()) { + case NONE : + break; + case SPACE_UPWIND : + for (auto iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + numerics[iMGlevel][SPECIES_SOL][conv_term] = new CUpwSca_Species(nDim, nVar_Species, config); + numerics[iMGlevel][SPECIES_SOL][conv_bound_term] = new CUpwSca_Species(nDim, nVar_Species, config); + } + break; + default : + SU2_MPI::Error("Invalid convective scheme for the species transport equations. Use SCALAR_UPWIND.", CURRENT_FUNCTION); + break; } - + + /*--- Definition of the viscous scheme for each equation and mesh level ---*/ + + for (auto iMGlevel = 0u; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + numerics[iMGlevel][SPECIES_SOL][visc_term] = new CAvgGrad_Species(nDim, nVar_Species, true, config); + numerics[iMGlevel][SPECIES_SOL][visc_bound_term] = new CAvgGrad_Species(nDim, nVar_Species, false, config); + } + /*--- Definition of the source term integration scheme for each equation and mesh level ---*/ - - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - - /*--- Note that RANS is incompatible with Axisymmetric or Rotational (Fix it!) ---*/ - - if (compressible) { - - if (adj_ns) { - - numerics[iMGlevel][ADJFLOW_SOL][source_first_term] = new CSourceViscous_AdjFlow(nDim, nVar_Adj_Flow, config); - - if (config->GetRotating_Frame() == YES) - numerics[iMGlevel][ADJFLOW_SOL][source_second_term] = new CSourceRotatingFrame_AdjFlow(nDim, nVar_Adj_Flow, config); - else - numerics[iMGlevel][ADJFLOW_SOL][source_second_term] = new CSourceConservative_AdjFlow(nDim, nVar_Adj_Flow, config); - + + for (auto iMGlevel = 0u; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + if (config->GetAxisymmetric() == YES) { + numerics[iMGlevel][SPECIES_SOL][source_first_term] = new CSourceAxisymmetric_Species(nDim, nVar_Species, config); } - else { - - if (config->GetRotating_Frame() == YES) - numerics[iMGlevel][ADJFLOW_SOL][source_first_term] = new CSourceRotatingFrame_AdjFlow(nDim, nVar_Adj_Flow, config); - else if (config->GetAxisymmetric() == YES) - numerics[iMGlevel][ADJFLOW_SOL][source_first_term] = new CSourceAxisymmetric_AdjFlow(nDim, nVar_Adj_Flow, config); - else - numerics[iMGlevel][ADJFLOW_SOL][source_first_term] = new CSourceNothing(nDim, nVar_Adj_Flow, config); - - numerics[iMGlevel][ADJFLOW_SOL][source_second_term] = new CSourceNothing(nDim, nVar_Adj_Flow, config); - + numerics[iMGlevel][SPECIES_SOL][source_first_term] = new CSourceNothing(nDim, nVar_Species, config); } - - } - - } - - } - - /*--- Solver definition for the turbulent adjoint problem ---*/ - if (adj_turb) { - - if (config->GetKind_Turb_Model() != TURB_MODEL::SA) - SU2_MPI::Error("Only the SA turbulence model can be used with the continuous adjoint solver.", CURRENT_FUNCTION); - - /*--- Definition of the convective scheme for each equation and mesh level ---*/ - switch (config->GetKind_ConvNumScheme_AdjTurb()) { - case NO_CONVECTIVE: - SU2_MPI::Error("Config file is missing the CONV_NUM_METHOD_ADJTURB option.", CURRENT_FUNCTION); - break; - case SPACE_UPWIND : - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) - numerics[iMGlevel][ADJTURB_SOL][conv_term] = new CUpwSca_AdjTurb(nDim, nVar_Adj_Turb, config); - break; - default: - SU2_MPI::Error("Convective scheme not implemented (adjoint turbulence).", CURRENT_FUNCTION); - break; - } - - /*--- Definition of the viscous scheme for each equation and mesh level ---*/ - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) - numerics[iMGlevel][ADJTURB_SOL][visc_term] = new CAvgGradCorrected_AdjTurb(nDim, nVar_Adj_Turb, config); - - /*--- Definition of the source term integration scheme for each equation and mesh level ---*/ - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - numerics[iMGlevel][ADJTURB_SOL][source_first_term] = new CSourcePieceWise_AdjTurb(nDim, nVar_Adj_Turb, config); - numerics[iMGlevel][ADJTURB_SOL][source_second_term] = new CSourceConservative_AdjTurb(nDim, nVar_Adj_Turb, config); + numerics[iMGlevel][SPECIES_SOL][source_second_term] = new CSourceNothing(nDim, nVar_Species, config); } +} +/*--- Explicit instantiation of the template above, needed because it is defined in a cpp file, instead of hpp. ---*/ +template void CDriver::InstantiateSpeciesNumerics>( + unsigned short, int, const CConfig*, const CSolver*, CNumerics****&) const; - /*--- Definition of the boundary condition method ---*/ - for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) - numerics[iMGlevel][ADJTURB_SOL][conv_bound_term] = new CUpwLin_AdjTurb(nDim, nVar_Adj_Turb, config); - - } +template void CDriver::InstantiateSpeciesNumerics>( + unsigned short, int, const CConfig*, const CSolver*, CNumerics****&) const; - /*--- Numerics definition for FEM-like problems. ---*/ +template void CDriver::InstantiateSpeciesNumerics>( + unsigned short, int, const CConfig*, const CSolver*, CNumerics****&) const; - if (fem) { - /*--- Initialize the container for FEA_TERM. This will be the only one for most of the cases. ---*/ - switch (config->GetGeometricConditions()) { - case STRUCT_DEFORMATION::SMALL: - switch (config->GetMaterialModel()) { - case STRUCT_MODEL::LINEAR_ELASTIC: - numerics[MESH_0][FEA_SOL][fea_term] = new CFEALinearElasticity(nDim, nVar_FEM, config); - break; - default: - SU2_MPI::Error("Material model does not correspond to geometric conditions.", CURRENT_FUNCTION); +void CDriver::Numerics_Preprocessing(CConfig *config, CGeometry **geometry, CSolver ***solver, CNumerics ****&numerics) const { + + if (rank == MASTER_NODE) + cout << endl <<"------------------- Numerics Preprocessing ( Zone " << config->GetiZone() <<" ) -------------------" << endl; + + unsigned short iMGlevel, iSol, + + nVar_Template = 0, + nVar_Flow = 0, + nVar_NEMO = 0, + nPrimVar_NEMO = 0, + nPrimVarGrad_NEMO = 0, + nVar_Trans = 0, + nVar_Turb = 0, + nVar_Species = 0, + nVar_Adj_Flow = 0, + nVar_Adj_Turb = 0, + nVar_FEM = 0, + nVar_Rad = 0, + nVar_Heat = 0; + + numerics = new CNumerics***[config->GetnMGLevels()+1] (); + + bool compressible = false; + bool incompressible = false; + bool ideal_gas = (config->GetKind_FluidModel() == STANDARD_AIR) || (config->GetKind_FluidModel() == IDEAL_GAS); + bool roe_low_dissipation = (config->GetKind_RoeLowDiss() != NO_ROELOWDISS); + + /*--- Initialize some useful booleans ---*/ + bool euler, ns, NEMO_euler, NEMO_ns, turbulent, adj_euler, adj_ns, adj_turb, fem_euler, fem_ns; + bool fem, heat, transition, template_solver; + + euler = ns = NEMO_euler = NEMO_ns = turbulent = adj_euler = adj_ns = adj_turb = fem_euler = fem_ns = false; + fem = heat = transition = template_solver = false; + bool species = false; + + /*--- Assign booleans ---*/ + switch (config->GetKind_Solver()) { + case MAIN_SOLVER::TEMPLATE_SOLVER: + template_solver = true; break; + + case MAIN_SOLVER::EULER: + case MAIN_SOLVER::DISC_ADJ_EULER: + euler = compressible = true; break; + + case MAIN_SOLVER::NAVIER_STOKES: + case MAIN_SOLVER::DISC_ADJ_NAVIER_STOKES: + ns = compressible = true; + species = (config->GetKind_Species_Model() != SPECIES_MODEL::NONE); break; + + case MAIN_SOLVER::NEMO_EULER: + NEMO_euler = compressible = true; break; + + case MAIN_SOLVER::NEMO_NAVIER_STOKES: + NEMO_ns = compressible = true; break; + + case MAIN_SOLVER::RANS: + case MAIN_SOLVER::DISC_ADJ_RANS: + ns = compressible = turbulent = true; + transition = (config->GetKind_Trans_Model() == TURB_TRANS_MODEL::LM); + species = config->GetKind_Species_Model() != SPECIES_MODEL::NONE; break; + + case MAIN_SOLVER::INC_EULER: + case MAIN_SOLVER::DISC_ADJ_INC_EULER: + euler = incompressible = true; break; + + case MAIN_SOLVER::INC_NAVIER_STOKES: + case MAIN_SOLVER::DISC_ADJ_INC_NAVIER_STOKES: + ns = incompressible = true; + heat = config->GetWeakly_Coupled_Heat(); + species = (config->GetKind_Species_Model() != SPECIES_MODEL::NONE); break; + + case MAIN_SOLVER::INC_RANS: + case MAIN_SOLVER::DISC_ADJ_INC_RANS: + ns = incompressible = turbulent = true; + heat = config->GetWeakly_Coupled_Heat(); + transition = (config->GetKind_Trans_Model() == TURB_TRANS_MODEL::LM); + species = (config->GetKind_Species_Model() != SPECIES_MODEL::NONE); break; + + case MAIN_SOLVER::FEM_EULER: + case MAIN_SOLVER::DISC_ADJ_FEM_EULER: + fem_euler = compressible = true; break; + + case MAIN_SOLVER::FEM_NAVIER_STOKES: + case MAIN_SOLVER::DISC_ADJ_FEM_NS: + fem_ns = compressible = true; break; + + case MAIN_SOLVER::FEM_RANS: + case MAIN_SOLVER::DISC_ADJ_FEM_RANS: + fem_ns = compressible = true; break; + + case MAIN_SOLVER::FEM_LES: + fem_ns = compressible = true; break; + + case MAIN_SOLVER::HEAT_EQUATION: + case MAIN_SOLVER::DISC_ADJ_HEAT: + heat = true; break; + + case MAIN_SOLVER::FEM_ELASTICITY: + case MAIN_SOLVER::DISC_ADJ_FEM: + fem = true; break; + + case MAIN_SOLVER::ADJ_EULER: + adj_euler = euler = compressible = true; break; + + case MAIN_SOLVER::ADJ_NAVIER_STOKES: + adj_ns = ns = compressible = true; + turbulent = (config->GetKind_Turb_Model() != TURB_MODEL::NONE); break; + + case MAIN_SOLVER::ADJ_RANS: + adj_ns = ns = compressible = turbulent = true; + adj_turb = !config->GetFrozen_Visc_Cont(); break; + + default: break; + + } + + /*--- Number of variables for the template ---*/ + + if (template_solver) nVar_Flow = solver[MESH_0][FLOW_SOL]->GetnVar(); + + /*--- Number of variables for direct problem ---*/ + + if (euler) nVar_Flow = solver[MESH_0][FLOW_SOL]->GetnVar(); + if (ns) nVar_Flow = solver[MESH_0][FLOW_SOL]->GetnVar(); + if (NEMO_euler) nVar_NEMO = solver[MESH_0][FLOW_SOL]->GetnVar(); + if (NEMO_ns) nVar_NEMO = solver[MESH_0][FLOW_SOL]->GetnVar(); + if (turbulent) nVar_Turb = solver[MESH_0][TURB_SOL]->GetnVar(); + if (transition) nVar_Trans = solver[MESH_0][TRANS_SOL]->GetnVar(); + if (species) nVar_Species = solver[MESH_0][SPECIES_SOL]->GetnVar(); + + if (fem_euler) nVar_Flow = solver[MESH_0][FLOW_SOL]->GetnVar(); + if (fem_ns) nVar_Flow = solver[MESH_0][FLOW_SOL]->GetnVar(); + + if (fem) nVar_FEM = solver[MESH_0][FEA_SOL]->GetnVar(); + if (heat) nVar_Heat = solver[MESH_0][HEAT_SOL]->GetnVar(); + + if (config->AddRadiation()) nVar_Rad = solver[MESH_0][RAD_SOL]->GetnVar(); + + /*--- Number of variables for adjoint problem ---*/ + + if (adj_euler) nVar_Adj_Flow = solver[MESH_0][ADJFLOW_SOL]->GetnVar(); + if (adj_ns) nVar_Adj_Flow = solver[MESH_0][ADJFLOW_SOL]->GetnVar(); + if (adj_turb) nVar_Adj_Turb = solver[MESH_0][ADJTURB_SOL]->GetnVar(); + + /*--- Additional Variables required for NEMO solver ---*/ + + if (NEMO_euler || NEMO_ns) nPrimVar_NEMO = solver[MESH_0][FLOW_SOL]->GetnPrimVar(); + if (NEMO_euler || NEMO_ns) nPrimVarGrad_NEMO = solver[MESH_0][FLOW_SOL]->GetnPrimVarGrad(); + + /*--- Definition of the Class for the numerical method: + numerics_container[INSTANCE_LEVEL][MESH_LEVEL][EQUATION][EQ_TERM] ---*/ + + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + numerics[iMGlevel] = new CNumerics** [MAX_SOLS]; + for (iSol = 0; iSol < MAX_SOLS; iSol++) + numerics[iMGlevel][iSol] = new CNumerics* [MAX_TERMS*omp_get_max_threads()](); + } + + /*--- Instantiate one numerics object per thread for each required term. ---*/ + + for (int thread = 0; thread < omp_get_max_threads(); ++thread) + { + const int offset = thread * MAX_TERMS; + + const int conv_term = CONV_TERM + offset; + const int visc_term = VISC_TERM + offset; + + const int source_first_term = SOURCE_FIRST_TERM + offset; + const int source_second_term = SOURCE_SECOND_TERM + offset; + + const int conv_bound_term = CONV_BOUND_TERM + offset; + const int visc_bound_term = VISC_BOUND_TERM + offset; + + const int fea_term = FEA_TERM + offset; + + /*--- Solver definition for the template problem ---*/ + if (template_solver) { + + /*--- Definition of the convective scheme for each equation and mesh level ---*/ + switch (config->GetKind_ConvNumScheme_Template()) { + case SPACE_CENTERED : case SPACE_UPWIND : + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) + numerics[iMGlevel][TEMPLATE_SOL][conv_term] = new CConvective_Template(nDim, nVar_Template, config); + break; + default: + SU2_MPI::Error("Convective scheme not implemented (template_solver).", CURRENT_FUNCTION); + break; + } + + /*--- Definition of the viscous scheme for each equation and mesh level ---*/ + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) + numerics[iMGlevel][TEMPLATE_SOL][visc_term] = new CViscous_Template(nDim, nVar_Template, config); + + /*--- Definition of the source term integration scheme for each equation and mesh level ---*/ + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) + numerics[iMGlevel][TEMPLATE_SOL][source_first_term] = new CSource_Template(nDim, nVar_Template, config); + + /*--- Definition of the boundary condition method ---*/ + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + numerics[iMGlevel][TEMPLATE_SOL][conv_bound_term] = new CConvective_Template(nDim, nVar_Template, config); + } + } - break; - case STRUCT_DEFORMATION::LARGE: - switch (config->GetMaterialModel()) { - case STRUCT_MODEL::LINEAR_ELASTIC: - SU2_MPI::Error("Material model does not correspond to geometric conditions.", CURRENT_FUNCTION); - break; - case STRUCT_MODEL::NEO_HOOKEAN: - if (config->GetMaterialCompressibility() == STRUCT_COMPRESS::COMPRESSIBLE) { - numerics[MESH_0][FEA_SOL][fea_term] = new CFEM_NeoHookean_Comp(nDim, nVar_FEM, config); - } else { - SU2_MPI::Error("Material model not implemented.", CURRENT_FUNCTION); + + /*--- Solver definition for the Potential, Euler, Navier-Stokes problems ---*/ + if ((euler) || (ns)) { + + /*--- Definition of the convective scheme for each equation and mesh level ---*/ + switch (config->GetKind_ConvNumScheme_Flow()) { + case NO_CONVECTIVE : + SU2_MPI::Error("Config file is missing the CONV_NUM_METHOD_FLOW option.", CURRENT_FUNCTION); + break; + + case SPACE_CENTERED : + if (compressible) { + /*--- "conv_term" is not instantiated as all compressible centered schemes are vectorized. ---*/ + + /*--- Definition of the boundary condition method ---*/ + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) + numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwRoe_Flow(nDim, nVar_Flow, config, false); + + } + if (incompressible) { + /*--- Incompressible flow, use preconditioning method ---*/ + switch (config->GetKind_Centered_Flow()) { + case LAX : numerics[MESH_0][FLOW_SOL][conv_term] = new CCentLaxInc_Flow(nDim, nVar_Flow, config); break; + case JST : numerics[MESH_0][FLOW_SOL][conv_term] = new CCentJSTInc_Flow(nDim, nVar_Flow, config); break; + default: + SU2_MPI::Error("Invalid centered scheme or not implemented.\n Currently, only JST and LAX-FRIEDRICH are available for incompressible flows.", CURRENT_FUNCTION); + break; + } + for (iMGlevel = 1; iMGlevel <= config->GetnMGLevels(); iMGlevel++) + numerics[iMGlevel][FLOW_SOL][conv_term] = new CCentLaxInc_Flow(nDim, nVar_Flow, config); + + /*--- Definition of the boundary condition method ---*/ + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) + numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwFDSInc_Flow(nDim, nVar_Flow, config); + + } + break; + case SPACE_UPWIND : + if (compressible) { + /*--- Compressible flow ---*/ + switch (config->GetKind_Upwind_Flow()) { + case ROE: + if (ideal_gas) { + + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwRoe_Flow(nDim, nVar_Flow, config, roe_low_dissipation); + numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwRoe_Flow(nDim, nVar_Flow, config, false); + } + } else { + + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwGeneralRoe_Flow(nDim, nVar_Flow, config); + numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwGeneralRoe_Flow(nDim, nVar_Flow, config); + } + } + break; + + case AUSM: + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwAUSM_Flow(nDim, nVar_Flow, config); + numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwAUSM_Flow(nDim, nVar_Flow, config); + } + break; + + case AUSMPLUSUP: + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwAUSMPLUSUP_Flow(nDim, nVar_Flow, config); + numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwAUSMPLUSUP_Flow(nDim, nVar_Flow, config); + } + break; + + case AUSMPLUSUP2: + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwAUSMPLUSUP2_Flow(nDim, nVar_Flow, config); + numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwAUSMPLUSUP2_Flow(nDim, nVar_Flow, config); + } + break; + + case TURKEL: + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwTurkel_Flow(nDim, nVar_Flow, config); + numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwTurkel_Flow(nDim, nVar_Flow, config); + } + break; + + case L2ROE: + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwL2Roe_Flow(nDim, nVar_Flow, config); + numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwL2Roe_Flow(nDim, nVar_Flow, config); + } + break; + case LMROE: + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwLMRoe_Flow(nDim, nVar_Flow, config); + numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwLMRoe_Flow(nDim, nVar_Flow, config); + } + break; + + case SLAU: + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwSLAU_Flow(nDim, nVar_Flow, config, roe_low_dissipation); + numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwSLAU_Flow(nDim, nVar_Flow, config, false); + } + break; + + case SLAU2: + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwSLAU2_Flow(nDim, nVar_Flow, config, roe_low_dissipation); + numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwSLAU2_Flow(nDim, nVar_Flow, config, false); + } + break; + + case HLLC: + if (ideal_gas) { + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwHLLC_Flow(nDim, nVar_Flow, config); + numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwHLLC_Flow(nDim, nVar_Flow, config); + } + } + else { + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwGeneralHLLC_Flow(nDim, nVar_Flow, config); + numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwGeneralHLLC_Flow(nDim, nVar_Flow, config); + } + } + break; + + case MSW: + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwMSW_Flow(nDim, nVar_Flow, config); + numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwMSW_Flow(nDim, nVar_Flow, config); + } + break; + + case CUSP: + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwCUSP_Flow(nDim, nVar_Flow, config); + numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwCUSP_Flow(nDim, nVar_Flow, config); + } + break; + + default: + SU2_MPI::Error("Invalid upwind scheme or not implemented.", CURRENT_FUNCTION); + break; + } + + } + if (incompressible) { + /*--- Incompressible flow, use artificial compressibility method ---*/ + switch (config->GetKind_Upwind_Flow()) { + case FDS: + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwFDSInc_Flow(nDim, nVar_Flow, config); + numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwFDSInc_Flow(nDim, nVar_Flow, config); + } + break; + default: + SU2_MPI::Error("Invalid upwind scheme or not implemented.\n Currently, only FDS is available for incompressible flows.", CURRENT_FUNCTION); + break; + } + } + break; + + default: + SU2_MPI::Error("Invalid convective scheme for the Euler / Navier-Stokes equations.", CURRENT_FUNCTION); + break; } - break; - case STRUCT_MODEL::KNOWLES: - if (config->GetMaterialCompressibility() == STRUCT_COMPRESS::NEARLY_INCOMP) { - numerics[MESH_0][FEA_SOL][fea_term] = new CFEM_Knowles_NearInc(nDim, nVar_FEM, config); - } else { - SU2_MPI::Error("Material model not implemented.", CURRENT_FUNCTION); + + /*--- Definition of the viscous scheme for each equation and mesh level ---*/ + if (compressible) { + if (ideal_gas) { + + /*--- Compressible flow Ideal gas ---*/ + numerics[MESH_0][FLOW_SOL][visc_term] = new CAvgGrad_Flow(nDim, nVar_Flow, true, config); + for (iMGlevel = 1; iMGlevel <= config->GetnMGLevels(); iMGlevel++) + numerics[iMGlevel][FLOW_SOL][visc_term] = new CAvgGrad_Flow(nDim, nVar_Flow, false, config); + + /*--- Definition of the boundary condition method ---*/ + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) + numerics[iMGlevel][FLOW_SOL][visc_bound_term] = new CAvgGrad_Flow(nDim, nVar_Flow, false, config); + + } else { + + /*--- Compressible flow Real gas ---*/ + numerics[MESH_0][FLOW_SOL][visc_term] = new CGeneralAvgGrad_Flow(nDim, nVar_Flow, true, config); + for (iMGlevel = 1; iMGlevel <= config->GetnMGLevels(); iMGlevel++) + numerics[iMGlevel][FLOW_SOL][visc_term] = new CGeneralAvgGrad_Flow(nDim, nVar_Flow, false, config); + + /*--- Definition of the boundary condition method ---*/ + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) + numerics[iMGlevel][FLOW_SOL][visc_bound_term] = new CGeneralAvgGrad_Flow(nDim, nVar_Flow, false, config); + + } } - break; - case STRUCT_MODEL::IDEAL_DE: - if (config->GetMaterialCompressibility() == STRUCT_COMPRESS::NEARLY_INCOMP) { - numerics[MESH_0][FEA_SOL][fea_term] = new CFEM_IdealDE(nDim, nVar_FEM, config); - } else { - SU2_MPI::Error("Material model not implemented.", CURRENT_FUNCTION); + if (incompressible) { + /*--- Incompressible flow, use preconditioning method ---*/ + numerics[MESH_0][FLOW_SOL][visc_term] = new CAvgGradInc_Flow(nDim, nVar_Flow, true, config); + for (iMGlevel = 1; iMGlevel <= config->GetnMGLevels(); iMGlevel++) + numerics[iMGlevel][FLOW_SOL][visc_term] = new CAvgGradInc_Flow(nDim, nVar_Flow, false, config); + + /*--- Definition of the boundary condition method ---*/ + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) + numerics[iMGlevel][FLOW_SOL][visc_bound_term] = new CAvgGradInc_Flow(nDim, nVar_Flow, false, config); } - break; + + /*--- Definition of the source term integration scheme for each equation and mesh level ---*/ + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + + if (config->GetBody_Force() == YES) { + if (incompressible) + numerics[iMGlevel][FLOW_SOL][source_first_term] = new CSourceIncBodyForce(nDim, nVar_Flow, config); + else + numerics[iMGlevel][FLOW_SOL][source_first_term] = new CSourceBodyForce(nDim, nVar_Flow, config); + } + else if (incompressible && (config->GetKind_Streamwise_Periodic() != ENUM_STREAMWISE_PERIODIC::NONE)) { + numerics[iMGlevel][FLOW_SOL][source_first_term] = new CSourceIncStreamwise_Periodic(nDim, nVar_Flow, config); + } + else if (incompressible && (config->GetKind_DensityModel() == INC_DENSITYMODEL::BOUSSINESQ)) { + numerics[iMGlevel][FLOW_SOL][source_first_term] = new CSourceBoussinesq(nDim, nVar_Flow, config); + } + else if (config->GetRotating_Frame() == YES) { + if (incompressible) + numerics[iMGlevel][FLOW_SOL][source_first_term] = new CSourceIncRotatingFrame_Flow(nDim, nVar_Flow, config); + else + numerics[iMGlevel][FLOW_SOL][source_first_term] = new CSourceRotatingFrame_Flow(nDim, nVar_Flow, config); + } + else if (config->GetAxisymmetric() == YES) { + if (incompressible) + numerics[iMGlevel][FLOW_SOL][source_first_term] = new CSourceIncAxisymmetric_Flow(nDim, nVar_Flow, config); + else if (ideal_gas) + numerics[iMGlevel][FLOW_SOL][source_first_term] = new CSourceAxisymmetric_Flow(nDim, nVar_Flow, config); + else + numerics[iMGlevel][FLOW_SOL][source_first_term] = new CSourceGeneralAxisymmetric_Flow(nDim, nVar_Flow, config); + } + else if (config->GetGravityForce() == YES) { + numerics[iMGlevel][FLOW_SOL][source_first_term] = new CSourceGravity(nDim, nVar_Flow, config); + } + else if (config->GetWind_Gust() == YES) { + numerics[iMGlevel][FLOW_SOL][source_first_term] = new CSourceWindGust(nDim, nVar_Flow, config); + } + else { + numerics[iMGlevel][FLOW_SOL][source_first_term] = new CSourceNothing(nDim, nVar_Flow, config); + } + + /*--- At the moment it is necessary to have the RHT equation in order to have a volumetric heat source. ---*/ + if (config->AddRadiation()) + numerics[iMGlevel][FLOW_SOL][source_second_term] = new CSourceRadiation(nDim, nVar_Flow, config); + else if ((incompressible && (config->GetKind_Streamwise_Periodic() != ENUM_STREAMWISE_PERIODIC::NONE)) && + (config->GetEnergy_Equation() && !config->GetStreamwise_Periodic_Temperature())) + numerics[iMGlevel][FLOW_SOL][source_second_term] = new CSourceIncStreamwisePeriodic_Outlet(nDim, nVar_Flow, config); + else + numerics[iMGlevel][FLOW_SOL][source_second_term] = new CSourceNothing(nDim, nVar_Flow, config); + } + } - break; - } - - /*--- The following definitions only make sense if we have a non-linear solution. ---*/ - if (config->GetGeometricConditions() == STRUCT_DEFORMATION::LARGE) { - - /*--- This allocates a container for electromechanical effects. ---*/ - - bool de_effects = config->GetDE_Effects(); - if (de_effects) - numerics[MESH_0][FEA_SOL][DE_TERM+offset] = new CFEM_DielectricElastomer(nDim, nVar_FEM, config); - - ifstream properties_file; - - string filename = config->GetFEA_FileName(); - if (nZone > 1) - filename = config->GetMultizone_FileName(filename, iZone, ".dat"); - - properties_file.open(filename.data(), ios::in); - - /*--- In case there is a properties file, containers are allocated for a number of material models. ---*/ - - if (!(properties_file.fail())) { - numerics[MESH_0][FEA_SOL][MAT_NHCOMP+offset] = new CFEM_NeoHookean_Comp(nDim, nVar_FEM, config); - numerics[MESH_0][FEA_SOL][MAT_IDEALDE+offset] = new CFEM_IdealDE(nDim, nVar_FEM, config); - numerics[MESH_0][FEA_SOL][MAT_KNOWLES+offset] = new CFEM_Knowles_NearInc(nDim, nVar_FEM, config); - } - } - } - - /*--- Instantiate the numerics for the mesh solver. ---*/ - if (config->GetDeform_Mesh()) - numerics[MESH_0][MESH_SOL][fea_term] = new CFEAMeshElasticity(nDim, nDim, geometry[MESH_0]->GetnElem(), config); - - } // end "per-thread" allocation loop - + + /*--- Solver definition for the Potential, Euler, Navier-Stokes NEMO problems ---*/ + + if (NEMO_euler || NEMO_ns) { + + /*--- Definition of the convective scheme for each equation and mesh level ---*/ + switch (config->GetKind_ConvNumScheme_Flow()) { + case NO_CONVECTIVE : + SU2_MPI::Error("Config file is missing the CONV_NUM_METHOD_FLOW option.", CURRENT_FUNCTION); + break; + + case SPACE_CENTERED : + if (compressible) { + /*--- Compressible flow ---*/ + switch (config->GetKind_Centered_Flow()) { + case LAX : numerics[MESH_0][FLOW_SOL][conv_term] = new CCentLax_NEMO(nDim, nVar_NEMO, nPrimVar_NEMO, nPrimVarGrad_NEMO, config); break; + default: + SU2_MPI::Error("Invalid centered scheme or not implemented.", CURRENT_FUNCTION); + break; + } + + for (iMGlevel = 1; iMGlevel <= config->GetnMGLevels(); iMGlevel++) + numerics[iMGlevel][FLOW_SOL][conv_term] = new CCentLax_NEMO(nDim, nVar_NEMO, nPrimVar_NEMO, nPrimVarGrad_NEMO, config); + + /*--- Definition of the boundary condition method ---*/ + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) + numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwRoe_NEMO(nDim, nVar_NEMO, nPrimVar_NEMO, nPrimVarGrad_NEMO, config); + } + break; + case SPACE_UPWIND : + if (compressible) { + /*--- Compressible flow ---*/ + switch (config->GetKind_Upwind_Flow()) { + case ROE: + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwRoe_NEMO(nDim, nVar_NEMO, nPrimVar_NEMO, nPrimVarGrad_NEMO, config); + numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwRoe_NEMO(nDim, nVar_NEMO, nPrimVar_NEMO, nPrimVarGrad_NEMO, config); + } + break; + + case AUSM: + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwAUSM_NEMO(nDim, nVar_NEMO, nPrimVar_NEMO, nPrimVarGrad_NEMO, config); + numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwAUSM_NEMO(nDim, nVar_NEMO, nPrimVar_NEMO, nPrimVarGrad_NEMO, config); + } + break; + + case AUSMPLUSUP2: + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwAUSMPLUSUP2_NEMO(nDim, nVar_NEMO, nPrimVar_NEMO, nPrimVarGrad_NEMO, config); + numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwAUSMPLUSUP2_NEMO(nDim, nVar_NEMO, nPrimVar_NEMO, nPrimVarGrad_NEMO, config); + } + break; + + case MSW: + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwMSW_NEMO(nDim, nVar_NEMO, nPrimVar_NEMO, nPrimVarGrad_NEMO, config); + numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwMSW_NEMO(nDim, nVar_NEMO, nPrimVar_NEMO, nPrimVarGrad_NEMO, config); + } + break; + + case AUSMPWPLUS: + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwAUSMPWplus_NEMO(nDim, nVar_NEMO, nPrimVar_NEMO, nPrimVarGrad_NEMO, config); + numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwAUSMPWplus_NEMO(nDim, nVar_NEMO, nPrimVar_NEMO, nPrimVarGrad_NEMO, config); + } + break; + + default: + SU2_MPI::Error("Invalid upwind scheme or not implemented.", CURRENT_FUNCTION); + break; + } + + } + break; + + default: + SU2_MPI::Error("Invalid convective scheme for the NEMO Euler / Navier-Stokes equations.", CURRENT_FUNCTION); + break; + } + + /*--- Definition of the viscous scheme for each equation and mesh level ---*/ + if (compressible) { + + numerics[MESH_0][FLOW_SOL][visc_term] = new CAvgGradCorrected_NEMO(nDim, nVar_NEMO, nPrimVar_NEMO, nPrimVarGrad_NEMO, config); + for (iMGlevel = 1; iMGlevel <= config->GetnMGLevels(); iMGlevel++) + numerics[iMGlevel][FLOW_SOL][visc_term] = new CAvgGrad_NEMO(nDim, nVar_NEMO, nPrimVar_NEMO, nPrimVarGrad_NEMO, config); + + /*--- Definition of the boundary condition method ---*/ + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) + numerics[iMGlevel][FLOW_SOL][visc_bound_term] = new CAvgGrad_NEMO(nDim, nVar_NEMO, nPrimVar_NEMO, nPrimVarGrad_NEMO, config); + } + + /*--- Definition of the source term integration scheme for each equation and mesh level ---*/ + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + + numerics[iMGlevel][FLOW_SOL][source_first_term] = new CSource_NEMO(nDim, nVar_NEMO, nPrimVar_NEMO, nPrimVarGrad_NEMO, config); + numerics[iMGlevel][FLOW_SOL][source_second_term] = new CSourceNothing(nDim, nVar_NEMO, config); + } + } + + /*--- Riemann solver definition for the Euler, Navier-Stokes problems for the FEM discretization. ---*/ + if ((fem_euler) || (fem_ns)) { + + switch (config->GetRiemann_Solver_FEM()) { + case ROE: + case LAX_FRIEDRICH: + /* Hard coded optimized implementation is used in the DG solver. No need to allocate the + corresponding entry in numerics. */ + break; + + case AUSM: + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwAUSM_Flow(nDim, nVar_Flow, config); + numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwAUSM_Flow(nDim, nVar_Flow, config); + } + break; + + case TURKEL: + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwTurkel_Flow(nDim, nVar_Flow, config); + numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwTurkel_Flow(nDim, nVar_Flow, config); + } + break; + + case HLLC: + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwHLLC_Flow(nDim, nVar_Flow, config); + numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwHLLC_Flow(nDim, nVar_Flow, config); + } + break; + + case MSW: + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwMSW_Flow(nDim, nVar_Flow, config); + numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwMSW_Flow(nDim, nVar_Flow, config); + } + break; + + case CUSP: + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + numerics[iMGlevel][FLOW_SOL][conv_term] = new CUpwCUSP_Flow(nDim, nVar_Flow, config); + numerics[iMGlevel][FLOW_SOL][conv_bound_term] = new CUpwCUSP_Flow(nDim, nVar_Flow, config); + } + break; + + default: + SU2_MPI::Error("Riemann solver not implemented.", CURRENT_FUNCTION); + break; + } + + } + + /*--- Solver definition for the turbulent model problem ---*/ + + if (turbulent) { + if (incompressible) + InstantiateTurbulentNumerics >(nVar_Turb, offset, config, + solver[MESH_0][TURB_SOL], numerics); + else if (NEMO_ns) + InstantiateTurbulentNumerics >(nVar_Turb, offset, config, + solver[MESH_0][TURB_SOL], numerics); + else + InstantiateTurbulentNumerics >(nVar_Turb, offset, config, + solver[MESH_0][TURB_SOL], numerics); + } + + /*--- Solver definition for the transition model problem ---*/ + if (transition) { + + /*--- Definition of the convective scheme for each equation and mesh level ---*/ + switch (config->GetKind_ConvNumScheme_Turb()) { + case NO_UPWIND: + SU2_MPI::Error("Config file is missing the CONV_NUM_METHOD_TURB option.", CURRENT_FUNCTION); + break; + case SPACE_UPWIND: + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + numerics[iMGlevel][TRANS_SOL][conv_term] = new CUpwSca_TransLM(nDim, nVar_Trans, config); + } + break; + default: + SU2_MPI::Error("Invalid convective scheme for the transition equations.", CURRENT_FUNCTION); + break; + } + + /*--- Definition of the viscous scheme for each equation and mesh level ---*/ + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + numerics[iMGlevel][TRANS_SOL][visc_term] = new CAvgGradCorrected_TransLM(nDim, nVar_Trans, config); + } + + /*--- Definition of the source term integration scheme for each equation and mesh level ---*/ + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + numerics[iMGlevel][TRANS_SOL][source_first_term] = new CSourcePieceWise_TransLM(nDim, nVar_Trans, config); + numerics[iMGlevel][TRANS_SOL][source_second_term] = new CSourceNothing(nDim, nVar_Trans, config); + } + + /*--- Definition of the boundary condition method ---*/ + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + numerics[iMGlevel][TRANS_SOL][conv_bound_term] = new CUpwLin_TransLM(nDim, nVar_Trans, config); + } + } + + /*--- Solver definition for the species transport problem ---*/ + + if (species) { + if (incompressible) + InstantiateSpeciesNumerics >(nVar_Species, offset, config, + solver[MESH_0][SPECIES_SOL], numerics); + else if (compressible) + InstantiateSpeciesNumerics >(nVar_Species, offset, config, + solver[MESH_0][SPECIES_SOL], numerics); + else + SU2_MPI::Error("Species transport only available for standard compressible and incompressible flow.", CURRENT_FUNCTION); + } + + /*--- Solver definition of the finite volume heat solver ---*/ + if (heat) { + + /*--- Definition of the viscous scheme for each equation and mesh level ---*/ + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + + numerics[iMGlevel][HEAT_SOL][visc_term] = new CAvgGrad_Heat(nDim, nVar_Heat, config, true); + numerics[iMGlevel][HEAT_SOL][visc_bound_term] = new CAvgGrad_Heat(nDim, nVar_Heat, config, false); + + switch (config->GetKind_ConvNumScheme_Heat()) { + + case SPACE_UPWIND : + numerics[iMGlevel][HEAT_SOL][conv_term] = new CUpwSca_Heat(nDim, nVar_Heat, config); + numerics[iMGlevel][HEAT_SOL][conv_bound_term] = new CUpwSca_Heat(nDim, nVar_Heat, config); + break; + + case SPACE_CENTERED : + numerics[iMGlevel][HEAT_SOL][conv_term] = new CCentSca_Heat(nDim, nVar_Heat, config); + numerics[iMGlevel][HEAT_SOL][conv_bound_term] = new CUpwSca_Heat(nDim, nVar_Heat, config); + break; + + default: + SU2_MPI::Error("Invalid convective scheme for the heat transfer equations.", CURRENT_FUNCTION); + break; + } + } + } + + /*--- Solver definition for the radiation model problem ---*/ + + if (config->AddRadiation()) { + /*--- Definition of the viscous scheme for each equation and mesh level ---*/ + numerics[MESH_0][RAD_SOL][VISC_TERM] = new CAvgGradCorrected_P1(nDim, nVar_Rad, config); + + /*--- Definition of the source term integration scheme for each equation and mesh level ---*/ + numerics[MESH_0][RAD_SOL][SOURCE_FIRST_TERM] = new CSourceP1(nDim, nVar_Rad, config); + + /*--- Definition of the boundary condition method ---*/ + numerics[MESH_0][RAD_SOL][VISC_BOUND_TERM] = new CAvgGradCorrected_P1(nDim, nVar_Rad, config); + } + + /*--- Solver definition for the flow adjoint problem ---*/ + + if (adj_euler || adj_ns) { + + if (incompressible) + SU2_MPI::Error("Convective schemes not implemented for incompressible continuous adjoint.", CURRENT_FUNCTION); + + /*--- Definition of the convective scheme for each equation and mesh level ---*/ + + switch (config->GetKind_ConvNumScheme_AdjFlow()) { + case NO_CONVECTIVE: + SU2_MPI::Error("Config file is missing the CONV_NUM_METHOD_ADJFLOW option.", CURRENT_FUNCTION); + break; + + case SPACE_CENTERED : + + if (compressible) { + + /*--- Compressible flow ---*/ + + switch (config->GetKind_Centered_AdjFlow()) { + case LAX : numerics[MESH_0][ADJFLOW_SOL][conv_term] = new CCentLax_AdjFlow(nDim, nVar_Adj_Flow, config); break; + case JST : numerics[MESH_0][ADJFLOW_SOL][conv_term] = new CCentJST_AdjFlow(nDim, nVar_Adj_Flow, config); break; + default: + SU2_MPI::Error("Centered scheme not implemented.", CURRENT_FUNCTION); + break; + } + + for (iMGlevel = 1; iMGlevel <= config->GetnMGLevels(); iMGlevel++) + numerics[iMGlevel][ADJFLOW_SOL][conv_term] = new CCentLax_AdjFlow(nDim, nVar_Adj_Flow, config); + + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) + numerics[iMGlevel][ADJFLOW_SOL][conv_bound_term] = new CUpwRoe_AdjFlow(nDim, nVar_Adj_Flow, config); + + } + break; + + case SPACE_UPWIND : + + if (compressible) { + + /*--- Compressible flow ---*/ + + switch (config->GetKind_Upwind_AdjFlow()) { + case ROE: + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + numerics[iMGlevel][ADJFLOW_SOL][conv_term] = new CUpwRoe_AdjFlow(nDim, nVar_Adj_Flow, config); + numerics[iMGlevel][ADJFLOW_SOL][conv_bound_term] = new CUpwRoe_AdjFlow(nDim, nVar_Adj_Flow, config); + } + break; + default: + SU2_MPI::Error("Upwind scheme not implemented.", CURRENT_FUNCTION); + break; + } + } + break; + + default: + SU2_MPI::Error("Invalid convective scheme for the continuous adjoint Euler / Navier-Stokes equations.", CURRENT_FUNCTION); + break; + } + + /*--- Definition of the viscous scheme for each equation and mesh level ---*/ + + if (compressible) { + + /*--- Compressible flow ---*/ + + numerics[MESH_0][ADJFLOW_SOL][visc_term] = new CAvgGradCorrected_AdjFlow(nDim, nVar_Adj_Flow, config); + numerics[MESH_0][ADJFLOW_SOL][visc_bound_term] = new CAvgGrad_AdjFlow(nDim, nVar_Adj_Flow, config); + + for (iMGlevel = 1; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + numerics[iMGlevel][ADJFLOW_SOL][visc_term] = new CAvgGrad_AdjFlow(nDim, nVar_Adj_Flow, config); + numerics[iMGlevel][ADJFLOW_SOL][visc_bound_term] = new CAvgGrad_AdjFlow(nDim, nVar_Adj_Flow, config); + } + + } + + /*--- Definition of the source term integration scheme for each equation and mesh level ---*/ + + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + + /*--- Note that RANS is incompatible with Axisymmetric or Rotational (Fix it!) ---*/ + + if (compressible) { + + if (adj_ns) { + + numerics[iMGlevel][ADJFLOW_SOL][source_first_term] = new CSourceViscous_AdjFlow(nDim, nVar_Adj_Flow, config); + + if (config->GetRotating_Frame() == YES) + numerics[iMGlevel][ADJFLOW_SOL][source_second_term] = new CSourceRotatingFrame_AdjFlow(nDim, nVar_Adj_Flow, config); + else + numerics[iMGlevel][ADJFLOW_SOL][source_second_term] = new CSourceConservative_AdjFlow(nDim, nVar_Adj_Flow, config); + + } + + else { + + if (config->GetRotating_Frame() == YES) + numerics[iMGlevel][ADJFLOW_SOL][source_first_term] = new CSourceRotatingFrame_AdjFlow(nDim, nVar_Adj_Flow, config); + else if (config->GetAxisymmetric() == YES) + numerics[iMGlevel][ADJFLOW_SOL][source_first_term] = new CSourceAxisymmetric_AdjFlow(nDim, nVar_Adj_Flow, config); + else + numerics[iMGlevel][ADJFLOW_SOL][source_first_term] = new CSourceNothing(nDim, nVar_Adj_Flow, config); + + numerics[iMGlevel][ADJFLOW_SOL][source_second_term] = new CSourceNothing(nDim, nVar_Adj_Flow, config); + + } + + } + + } + + } + + /*--- Solver definition for the turbulent adjoint problem ---*/ + if (adj_turb) { + + if (config->GetKind_Turb_Model() != TURB_MODEL::SA) + SU2_MPI::Error("Only the SA turbulence model can be used with the continuous adjoint solver.", CURRENT_FUNCTION); + + /*--- Definition of the convective scheme for each equation and mesh level ---*/ + switch (config->GetKind_ConvNumScheme_AdjTurb()) { + case NO_CONVECTIVE: + SU2_MPI::Error("Config file is missing the CONV_NUM_METHOD_ADJTURB option.", CURRENT_FUNCTION); + break; + case SPACE_UPWIND : + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) + numerics[iMGlevel][ADJTURB_SOL][conv_term] = new CUpwSca_AdjTurb(nDim, nVar_Adj_Turb, config); + break; + default: + SU2_MPI::Error("Convective scheme not implemented (adjoint turbulence).", CURRENT_FUNCTION); + break; + } + + /*--- Definition of the viscous scheme for each equation and mesh level ---*/ + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) + numerics[iMGlevel][ADJTURB_SOL][visc_term] = new CAvgGradCorrected_AdjTurb(nDim, nVar_Adj_Turb, config); + + /*--- Definition of the source term integration scheme for each equation and mesh level ---*/ + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + numerics[iMGlevel][ADJTURB_SOL][source_first_term] = new CSourcePieceWise_AdjTurb(nDim, nVar_Adj_Turb, config); + numerics[iMGlevel][ADJTURB_SOL][source_second_term] = new CSourceConservative_AdjTurb(nDim, nVar_Adj_Turb, config); + } + + /*--- Definition of the boundary condition method ---*/ + for (iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) + numerics[iMGlevel][ADJTURB_SOL][conv_bound_term] = new CUpwLin_AdjTurb(nDim, nVar_Adj_Turb, config); + + } + + /*--- Numerics definition for FEM-like problems. ---*/ + + if (fem) { + /*--- Initialize the container for FEA_TERM. This will be the only one for most of the cases. ---*/ + switch (config->GetGeometricConditions()) { + case STRUCT_DEFORMATION::SMALL: + switch (config->GetMaterialModel()) { + case STRUCT_MODEL::LINEAR_ELASTIC: + numerics[MESH_0][FEA_SOL][fea_term] = new CFEALinearElasticity(nDim, nVar_FEM, config); + break; + default: + SU2_MPI::Error("Material model does not correspond to geometric conditions.", CURRENT_FUNCTION); + break; + } + break; + case STRUCT_DEFORMATION::LARGE: + switch (config->GetMaterialModel()) { + case STRUCT_MODEL::LINEAR_ELASTIC: + SU2_MPI::Error("Material model does not correspond to geometric conditions.", CURRENT_FUNCTION); + break; + case STRUCT_MODEL::NEO_HOOKEAN: + if (config->GetMaterialCompressibility() == STRUCT_COMPRESS::COMPRESSIBLE) { + numerics[MESH_0][FEA_SOL][fea_term] = new CFEM_NeoHookean_Comp(nDim, nVar_FEM, config); + } else { + SU2_MPI::Error("Material model not implemented.", CURRENT_FUNCTION); + } + break; + case STRUCT_MODEL::KNOWLES: + if (config->GetMaterialCompressibility() == STRUCT_COMPRESS::NEARLY_INCOMP) { + numerics[MESH_0][FEA_SOL][fea_term] = new CFEM_Knowles_NearInc(nDim, nVar_FEM, config); + } else { + SU2_MPI::Error("Material model not implemented.", CURRENT_FUNCTION); + } + break; + case STRUCT_MODEL::IDEAL_DE: + if (config->GetMaterialCompressibility() == STRUCT_COMPRESS::NEARLY_INCOMP) { + numerics[MESH_0][FEA_SOL][fea_term] = new CFEM_IdealDE(nDim, nVar_FEM, config); + } else { + SU2_MPI::Error("Material model not implemented.", CURRENT_FUNCTION); + } + break; + } + break; + } + + /*--- The following definitions only make sense if we have a non-linear solution. ---*/ + if (config->GetGeometricConditions() == STRUCT_DEFORMATION::LARGE) { + + /*--- This allocates a container for electromechanical effects. ---*/ + + bool de_effects = config->GetDE_Effects(); + if (de_effects) + numerics[MESH_0][FEA_SOL][DE_TERM+offset] = new CFEM_DielectricElastomer(nDim, nVar_FEM, config); + + ifstream properties_file; + + string filename = config->GetFEA_FileName(); + if (nZone > 1) + filename = config->GetMultizone_FileName(filename, iZone, ".dat"); + + properties_file.open(filename.data(), ios::in); + + /*--- In case there is a properties file, containers are allocated for a number of material models. ---*/ + + if (!(properties_file.fail())) { + numerics[MESH_0][FEA_SOL][MAT_NHCOMP+offset] = new CFEM_NeoHookean_Comp(nDim, nVar_FEM, config); + numerics[MESH_0][FEA_SOL][MAT_IDEALDE+offset] = new CFEM_IdealDE(nDim, nVar_FEM, config); + numerics[MESH_0][FEA_SOL][MAT_KNOWLES+offset] = new CFEM_Knowles_NearInc(nDim, nVar_FEM, config); + } + } + } + + /*--- Instantiate the numerics for the mesh solver. ---*/ + if (config->GetDeform_Mesh()) + numerics[MESH_0][MESH_SOL][fea_term] = new CFEAMeshElasticity(nDim, nDim, geometry[MESH_0]->GetnElem(), config); + + } // end "per-thread" allocation loop + } void CDriver::Numerics_Postprocessing(CNumerics *****numerics, CSolver***, CGeometry**, CConfig *config, unsigned short val_iInst) { - - for (unsigned short iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { - - for (unsigned int iSol = 0; iSol < MAX_SOLS; iSol++) { - - for (unsigned int iTerm = 0; iTerm < MAX_TERMS*omp_get_max_threads(); iTerm++) { - - delete numerics[val_iInst][iMGlevel][iSol][iTerm]; - } - delete [] numerics[val_iInst][iMGlevel][iSol]; + + for (unsigned short iMGlevel = 0; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + + for (unsigned int iSol = 0; iSol < MAX_SOLS; iSol++) { + + for (unsigned int iTerm = 0; iTerm < MAX_TERMS*omp_get_max_threads(); iTerm++) { + + delete numerics[val_iInst][iMGlevel][iSol][iTerm]; + } + delete [] numerics[val_iInst][iMGlevel][iSol]; + } + delete[] numerics[val_iInst][iMGlevel]; } - delete[] numerics[val_iInst][iMGlevel]; - } - delete[] numerics[val_iInst]; - + delete[] numerics[val_iInst]; + } void CDriver::Iteration_Preprocessing(CConfig* config, CIteration *&iteration) const { - - if (rank == MASTER_NODE) - cout << endl <<"------------------- Iteration Preprocessing ( Zone " << config->GetiZone() <<" ) ------------------" << endl; - - iteration = CIterationFactory::CreateIteration(config->GetKind_Solver(), config); - + + if (rank == MASTER_NODE) + cout << endl <<"------------------- Iteration Preprocessing ( Zone " << config->GetiZone() <<" ) ------------------" << endl; + + iteration = CIterationFactory::CreateIteration(config->GetKind_Solver(), config); + } void CDriver::DynamicMesh_Preprocessing(CConfig *config, CGeometry **geometry, CSolver ***solver, CIteration* iteration, CVolumetricMovement *&grid_movement, CSurfaceMovement *&surface_movement) const{ - - /*--- Instantiate the geometry movement classes for the solution of unsteady - flows on dynamic meshes, including rigid mesh transformations, dynamically - deforming meshes, and preprocessing of harmonic balance. ---*/ - - if (!fem_solver && (config->GetGrid_Movement() || (config->GetDirectDiff() == D_DESIGN))) { - if (rank == MASTER_NODE) - cout << "Setting dynamic mesh structure for zone "<< iZone + 1<<"." << endl; - grid_movement = new CVolumetricMovement(geometry[MESH_0], config); - - surface_movement = new CSurfaceMovement(); - surface_movement->CopyBoundary(geometry[MESH_0], config); - if (config->GetTime_Marching() == TIME_MARCHING::HARMONIC_BALANCE){ - if (rank == MASTER_NODE) cout << endl << "Instance "<< iInst + 1 <<":" << endl; - iteration->SetGrid_Movement(geometry, surface_movement, grid_movement, solver, config, 0, iInst); + + /*--- Instantiate the geometry movement classes for the solution of unsteady + flows on dynamic meshes, including rigid mesh transformations, dynamically + deforming meshes, and preprocessing of harmonic balance. ---*/ + + if (!fem_solver && (config->GetGrid_Movement() || (config->GetDirectDiff() == D_DESIGN))) { + if (rank == MASTER_NODE) + cout << "Setting dynamic mesh structure for zone "<< iZone + 1<<"." << endl; + grid_movement = new CVolumetricMovement(geometry[MESH_0], config); + + surface_movement = new CSurfaceMovement(); + surface_movement->CopyBoundary(geometry[MESH_0], config); + if (config->GetTime_Marching() == TIME_MARCHING::HARMONIC_BALANCE){ + if (rank == MASTER_NODE) cout << endl << "Instance "<< iInst + 1 <<":" << endl; + iteration->SetGrid_Movement(geometry, surface_movement, grid_movement, solver, config, 0, iInst); + } } - } - - if (config->GetDirectDiff() == D_DESIGN) { - if (rank == MASTER_NODE) - cout << "Setting surface/volume derivatives." << endl; - - /*--- Set the surface derivatives, i.e. the derivative of the surface mesh nodes with respect to the design variables ---*/ - - surface_movement->SetSurface_Derivative(geometry[MESH_0],config); - - /*--- Call the volume deformation routine with derivative mode enabled. - This computes the derivative of the volume mesh with respect to the surface nodes ---*/ - - grid_movement->SetVolume_Deformation(geometry[MESH_0],config, true, true); - - /*--- Update the multi-grid structure to propagate the derivative information to the coarser levels ---*/ - - CGeometry::UpdateGeometry(geometry,config); - - } - + + if (config->GetDirectDiff() == D_DESIGN) { + if (rank == MASTER_NODE) + cout << "Setting surface/volume derivatives." << endl; + + /*--- Set the surface derivatives, i.e. the derivative of the surface mesh nodes with respect to the design variables ---*/ + + surface_movement->SetSurface_Derivative(geometry[MESH_0],config); + + /*--- Call the volume deformation routine with derivative mode enabled. + This computes the derivative of the volume mesh with respect to the surface nodes ---*/ + + grid_movement->SetVolume_Deformation(geometry[MESH_0],config, true, true); + + /*--- Update the multi-grid structure to propagate the derivative information to the coarser levels ---*/ + + CGeometry::UpdateGeometry(geometry,config); + + } + } void CDriver::Interface_Preprocessing(CConfig **config, CSolver***** solver, CGeometry**** geometry, unsigned short** interface_types, CInterface ***interface, vector > >& interpolation) { - - /*--- Setup interpolation and transfer for all possible donor/target pairs. ---*/ - - for (auto target = 0u; target < nZone; target++) { - - for (auto donor = 0u; donor < nZone; donor++) { - - /*--- Aliases to make code less verbose. ---*/ - auto& interface_type = interface_types[donor][target]; - - if (donor == target) { - interface_type = ZONES_ARE_EQUAL; - continue; - } - interface_type = NO_TRANSFER; - - /*--- If there is a common interface setup the interpolation and transfer. ---*/ - - if (!CInterpolator::CheckZonesInterface(config[donor], config[target])) { - interface_type = NO_COMMON_INTERFACE; - } - else { - /*--- Begin the creation of the communication pattern among zones. ---*/ - - if (rank == MASTER_NODE) cout << "From zone " << donor << " to zone " << target << ":" << endl; - - /*--- Setup the interpolation. ---*/ - - interpolation[donor][target] = unique_ptr(CInterpolatorFactory::CreateInterpolator( - geometry, config, interpolation[target][donor].get(), donor, target)); - - /*--- The type of variables transferred depends on the donor/target physics. ---*/ - - const bool heat_target = config[target]->GetHeatProblem(); - const bool fluid_target = config[target]->GetFluidProblem(); - const bool structural_target = config[target]->GetStructuralProblem(); - - const bool heat_donor = config[donor]->GetHeatProblem(); - const bool fluid_donor = config[donor]->GetFluidProblem(); - const bool structural_donor = config[donor]->GetStructuralProblem(); - - /*--- Initialize the appropriate transfer strategy. ---*/ - - if (rank == MASTER_NODE) cout << " Transferring "; - - if (fluid_donor && structural_target) { - interface_type = FLOW_TRACTION; - auto nConst = 2; - bool conservative = config[target]->GetConservativeInterpolation(); - if(!config[ZONE_0]->GetDiscrete_Adjoint()) { - interface[donor][target] = new CFlowTractionInterface(nDim, nConst, config[donor], conservative); - } else { - interface[donor][target] = new CDiscAdjFlowTractionInterface(nDim, nConst, config[donor], conservative); - } - if (rank == MASTER_NODE) cout << "fluid " << (conservative? "forces." : "tractions.") << endl; - } - else if (structural_donor && (fluid_target || heat_target)) { - if (solver_container[target][INST_0][MESH_0][MESH_SOL] == nullptr) { - SU2_MPI::Error("Mesh deformation was not correctly specified for the fluid/heat zone.\n" - "Use DEFORM_MESH=YES, and setup MARKER_DEFORM_MESH=(...)", CURRENT_FUNCTION); - } - interface_type = BOUNDARY_DISPLACEMENTS; - if (!config[donor]->GetTime_Domain()) interface[donor][target] = new CDisplacementsInterface(nDim, 0); - else interface[donor][target] = new CDisplacementsInterface(2*nDim, 0); - if (rank == MASTER_NODE) cout << "boundary displacements from the structural solver." << endl; - } - else if (fluid_donor && fluid_target) { - interface_type = SLIDING_INTERFACE; - auto nVar = solver[donor][INST_0][MESH_0][FLOW_SOL]->GetnPrimVar(); - interface[donor][target] = new CSlidingInterface(nVar, 0); - if (rank == MASTER_NODE) cout << "sliding interface." << endl; - } - else if (heat_donor || heat_target) { - if (heat_donor && heat_target) - SU2_MPI::Error("Conjugate heat transfer between solids is not implemented.", CURRENT_FUNCTION); - - const auto fluidZone = heat_target? donor : target; - - if (config[fluidZone]->GetEnergy_Equation() || (config[fluidZone]->GetKind_Regime() == ENUM_REGIME::COMPRESSIBLE)) - interface_type = heat_target? CONJUGATE_HEAT_FS : CONJUGATE_HEAT_SF; - else if (config[fluidZone]->GetWeakly_Coupled_Heat()) - interface_type = heat_target? CONJUGATE_HEAT_WEAKLY_FS : CONJUGATE_HEAT_WEAKLY_SF; - else + + /*--- Setup interpolation and transfer for all possible donor/target pairs. ---*/ + + for (auto target = 0u; target < nZone; target++) { + + for (auto donor = 0u; donor < nZone; donor++) { + + /*--- Aliases to make code less verbose. ---*/ + auto& interface_type = interface_types[donor][target]; + + if (donor == target) { + interface_type = ZONES_ARE_EQUAL; + continue; + } interface_type = NO_TRANSFER; - - if (interface_type != NO_TRANSFER) { - auto nVar = 4; - interface[donor][target] = new CConjugateHeatInterface(nVar, 0); - if (rank == MASTER_NODE) cout << "conjugate heat variables." << endl; - } - else { - if (rank == MASTER_NODE) cout << "NO heat variables." << endl; - } - } - else { - if (solver[donor][INST_0][MESH_0][FLOW_SOL] == nullptr) - SU2_MPI::Error("Could not determine the number of variables for transfer.", CURRENT_FUNCTION); - - auto nVar = solver[donor][INST_0][MESH_0][FLOW_SOL]->GetnVar(); - interface_type = CONSERVATIVE_VARIABLES; - interface[donor][target] = new CConservativeVarsInterface(nVar, 0); - if (rank == MASTER_NODE) cout << "generic conservative variables." << endl; - } - } - - /*--- Mixing plane for turbo machinery applications. ---*/ - - if (config[donor]->GetBoolMixingPlaneInterface()) { - interface_type = MIXING_PLANE; - auto nVar = solver[donor][INST_0][MESH_0][FLOW_SOL]->GetnVar(); - interface[donor][target] = new CMixingPlaneInterface(nVar, 0); - if (rank == MASTER_NODE) { - cout << "Set mixing-plane interface from donor zone " - << donor << " to target zone " << target << "." << endl; + + /*--- If there is a common interface setup the interpolation and transfer. ---*/ + + if (!CInterpolator::CheckZonesInterface(config[donor], config[target])) { + interface_type = NO_COMMON_INTERFACE; + } + else { + /*--- Begin the creation of the communication pattern among zones. ---*/ + + if (rank == MASTER_NODE) cout << "From zone " << donor << " to zone " << target << ":" << endl; + + /*--- Setup the interpolation. ---*/ + + interpolation[donor][target] = unique_ptr(CInterpolatorFactory::CreateInterpolator( + geometry, config, interpolation[target][donor].get(), donor, target)); + + /*--- The type of variables transferred depends on the donor/target physics. ---*/ + + const bool heat_target = config[target]->GetHeatProblem(); + const bool fluid_target = config[target]->GetFluidProblem(); + const bool structural_target = config[target]->GetStructuralProblem(); + + const bool heat_donor = config[donor]->GetHeatProblem(); + const bool fluid_donor = config[donor]->GetFluidProblem(); + const bool structural_donor = config[donor]->GetStructuralProblem(); + + /*--- Initialize the appropriate transfer strategy. ---*/ + + if (rank == MASTER_NODE) cout << " Transferring "; + + if (fluid_donor && structural_target) { + interface_type = FLOW_TRACTION; + auto nConst = 2; + bool conservative = config[target]->GetConservativeInterpolation(); + if(!config[ZONE_0]->GetDiscrete_Adjoint()) { + interface[donor][target] = new CFlowTractionInterface(nDim, nConst, config[donor], conservative); + } else { + interface[donor][target] = new CDiscAdjFlowTractionInterface(nDim, nConst, config[donor], conservative); + } + if (rank == MASTER_NODE) cout << "fluid " << (conservative? "forces." : "tractions.") << endl; + } + else if (structural_donor && (fluid_target || heat_target)) { + if (solver_container[target][INST_0][MESH_0][MESH_SOL] == nullptr) { + SU2_MPI::Error("Mesh deformation was not correctly specified for the fluid/heat zone.\n" + "Use DEFORM_MESH=YES, and setup MARKER_DEFORM_MESH=(...)", CURRENT_FUNCTION); + } + interface_type = BOUNDARY_DISPLACEMENTS; + if (!config[donor]->GetTime_Domain()) interface[donor][target] = new CDisplacementsInterface(nDim, 0); + else interface[donor][target] = new CDisplacementsInterface(2*nDim, 0); + if (rank == MASTER_NODE) cout << "boundary displacements from the structural solver." << endl; + } + else if (fluid_donor && fluid_target) { + interface_type = SLIDING_INTERFACE; + auto nVar = solver[donor][INST_0][MESH_0][FLOW_SOL]->GetnPrimVar(); + interface[donor][target] = new CSlidingInterface(nVar, 0); + if (rank == MASTER_NODE) cout << "sliding interface." << endl; + } + else if (heat_donor || heat_target) { + if (heat_donor && heat_target) + SU2_MPI::Error("Conjugate heat transfer between solids is not implemented.", CURRENT_FUNCTION); + + const auto fluidZone = heat_target? donor : target; + + if (config[fluidZone]->GetEnergy_Equation() || (config[fluidZone]->GetKind_Regime() == ENUM_REGIME::COMPRESSIBLE)) + interface_type = heat_target? CONJUGATE_HEAT_FS : CONJUGATE_HEAT_SF; + else if (config[fluidZone]->GetWeakly_Coupled_Heat()) + interface_type = heat_target? CONJUGATE_HEAT_WEAKLY_FS : CONJUGATE_HEAT_WEAKLY_SF; + else + interface_type = NO_TRANSFER; + + if (interface_type != NO_TRANSFER) { + auto nVar = 4; + interface[donor][target] = new CConjugateHeatInterface(nVar, 0); + if (rank == MASTER_NODE) cout << "conjugate heat variables." << endl; + } + else { + if (rank == MASTER_NODE) cout << "NO heat variables." << endl; + } + } + else { + if (solver[donor][INST_0][MESH_0][FLOW_SOL] == nullptr) + SU2_MPI::Error("Could not determine the number of variables for transfer.", CURRENT_FUNCTION); + + auto nVar = solver[donor][INST_0][MESH_0][FLOW_SOL]->GetnVar(); + interface_type = CONSERVATIVE_VARIABLES; + interface[donor][target] = new CConservativeVarsInterface(nVar, 0); + if (rank == MASTER_NODE) cout << "generic conservative variables." << endl; + } + } + + /*--- Mixing plane for turbo machinery applications. ---*/ + + if (config[donor]->GetBoolMixingPlaneInterface()) { + interface_type = MIXING_PLANE; + auto nVar = solver[donor][INST_0][MESH_0][FLOW_SOL]->GetnVar(); + interface[donor][target] = new CMixingPlaneInterface(nVar, 0); + if (rank == MASTER_NODE) { + cout << "Set mixing-plane interface from donor zone " + << donor << " to target zone " << target << "." << endl; + } + } + } - } - + } - - } - + } void CDriver::StaticMesh_Preprocessing(const CConfig *config, CGeometry** geometry){ - - unsigned short iMGlevel, iMGfine; - unsigned short Kind_Grid_Movement; - - unsigned short iZone = config->GetiZone(); - - Kind_Grid_Movement = config->GetKind_GridMovement(); - - if (!fem_solver) { - - switch (Kind_Grid_Movement) { - - case ROTATING_FRAME: - - /*--- Steadily rotating frame: set the grid velocities just once - before the first iteration flow solver. ---*/ - - if (rank == MASTER_NODE) { - cout << endl << " Setting rotating frame grid velocities"; - cout << " for zone " << iZone << "." << endl; + + unsigned short iMGlevel, iMGfine; + unsigned short Kind_Grid_Movement; + + unsigned short iZone = config->GetiZone(); + + Kind_Grid_Movement = config->GetKind_GridMovement(); + + if (!fem_solver) { + + switch (Kind_Grid_Movement) { + + case ROTATING_FRAME: + + /*--- Steadily rotating frame: set the grid velocities just once + before the first iteration flow solver. ---*/ + + if (rank == MASTER_NODE) { + cout << endl << " Setting rotating frame grid velocities"; + cout << " for zone " << iZone << "." << endl; + } + + /*--- Set the grid velocities on all multigrid levels for a steadily + rotating reference frame. ---*/ + + for (iMGlevel = 0; iMGlevel <= config_container[ZONE_0]->GetnMGLevels(); iMGlevel++){ + geometry[iMGlevel]->SetRotationalVelocity(config, true); + geometry[iMGlevel]->SetShroudVelocity(config); + } + + break; + + case STEADY_TRANSLATION: + + /*--- Set the translational velocity and hold the grid fixed during + the calculation (similar to rotating frame, but there is no extra + source term for translation). ---*/ + + if (rank == MASTER_NODE) + cout << endl << " Setting translational grid velocities." << endl; + + /*--- Set the translational velocity on all grid levels. ---*/ + + for (iMGlevel = 0; iMGlevel <= config_container[ZONE_0]->GetnMGLevels(); iMGlevel++) + geometry_container[iZone][INST_0][iMGlevel]->SetTranslationalVelocity(config, true); + + break; + + default: + break; } - - /*--- Set the grid velocities on all multigrid levels for a steadily - rotating reference frame. ---*/ - - for (iMGlevel = 0; iMGlevel <= config_container[ZONE_0]->GetnMGLevels(); iMGlevel++){ - geometry[iMGlevel]->SetRotationalVelocity(config, true); - geometry[iMGlevel]->SetShroudVelocity(config); + + if (config->GetnMarker_Moving() > 0) { + + /*--- Fixed wall velocities: set the grid velocities only one time + before the first iteration flow solver. ---*/ + if (rank == MASTER_NODE) + cout << endl << " Setting the moving wall velocities." << endl; + + geometry[MESH_0]->SetWallVelocity(config, true); + + /*--- Update the grid velocities on the coarser multigrid levels after + setting the moving wall velocities for the finest mesh. ---*/ + for (iMGlevel = 1; iMGlevel <= config->GetnMGLevels(); iMGlevel++){ + iMGfine = iMGlevel-1; + geometry[iMGlevel]->SetRestricted_GridVelocity(geometry[iMGfine]); + } } - - break; - - case STEADY_TRANSLATION: - - /*--- Set the translational velocity and hold the grid fixed during - the calculation (similar to rotating frame, but there is no extra - source term for translation). ---*/ - - if (rank == MASTER_NODE) - cout << endl << " Setting translational grid velocities." << endl; - - /*--- Set the translational velocity on all grid levels. ---*/ - - for (iMGlevel = 0; iMGlevel <= config_container[ZONE_0]->GetnMGLevels(); iMGlevel++) - geometry_container[iZone][INST_0][iMGlevel]->SetTranslationalVelocity(config, true); - - break; - - default: - break; - } - - if (config->GetnMarker_Moving() > 0) { - - /*--- Fixed wall velocities: set the grid velocities only one time - before the first iteration flow solver. ---*/ - if (rank == MASTER_NODE) - cout << endl << " Setting the moving wall velocities." << endl; - - geometry[MESH_0]->SetWallVelocity(config, true); - - /*--- Update the grid velocities on the coarser multigrid levels after - setting the moving wall velocities for the finest mesh. ---*/ - for (iMGlevel = 1; iMGlevel <= config->GetnMGLevels(); iMGlevel++){ - iMGfine = iMGlevel-1; - geometry[iMGlevel]->SetRestricted_GridVelocity(geometry[iMGfine]); - } - } - } else { - - /*--- Carry out a dynamic cast to CMeshFEM_DG, such that it is not needed to + } else { + + /*--- Carry out a dynamic cast to CMeshFEM_DG, such that it is not needed to define all virtual functions in the base class CGeometry. ---*/ - CMeshFEM_DG *DGMesh = dynamic_cast(geometry[MESH_0]); - - /*--- Initialize the static mesh movement, if necessary. ---*/ - const unsigned short Kind_Grid_Movement = config->GetKind_GridMovement(); - const bool initStaticMovement = (config->GetGrid_Movement() && - (Kind_Grid_Movement == MOVING_WALL || - Kind_Grid_Movement == ROTATING_FRAME || - Kind_Grid_Movement == STEADY_TRANSLATION)); - - if(initStaticMovement){ - if (rank == MASTER_NODE) cout << "Initialize Static Mesh Movement" << endl; - DGMesh->InitStaticMeshMovement(config, Kind_Grid_Movement, iZone); + CMeshFEM_DG *DGMesh = dynamic_cast(geometry[MESH_0]); + + /*--- Initialize the static mesh movement, if necessary. ---*/ + const unsigned short Kind_Grid_Movement = config->GetKind_GridMovement(); + const bool initStaticMovement = (config->GetGrid_Movement() && + (Kind_Grid_Movement == MOVING_WALL || + Kind_Grid_Movement == ROTATING_FRAME || + Kind_Grid_Movement == STEADY_TRANSLATION)); + + if(initStaticMovement){ + if (rank == MASTER_NODE) cout << "Initialize Static Mesh Movement" << endl; + DGMesh->InitStaticMeshMovement(config, Kind_Grid_Movement, iZone); + } } - } - + } void CDriver::Output_Preprocessing(CConfig **config, CConfig *driver_config, COutput **&output, COutput *&driver_output){ - - /*--- Definition of the output class (one for each zone). The output class - manages the writing of all restart, volume solution, surface solution, - surface comma-separated value, and convergence history files (both in serial - and in parallel). ---*/ - - for (iZone = 0; iZone < nZone; iZone++){ - - if (rank == MASTER_NODE) - cout << endl <<"-------------------- Output Preprocessing ( Zone " << iZone <<" ) --------------------" << endl; - - MAIN_SOLVER kindSolver = config[iZone]->GetKind_Solver(); - - output[iZone] = COutputFactory::CreateOutput(kindSolver, config[iZone], nDim); - - /*--- If dry-run is used, do not open/overwrite history file. ---*/ - output[iZone]->PreprocessHistoryOutput(config[iZone], !dry_run); - - output[iZone]->PreprocessVolumeOutput(config[iZone]); - - } - - if (driver_config->GetMultizone_Problem()){ - if (rank == MASTER_NODE) - cout << endl <<"------------------- Output Preprocessing ( Multizone ) ------------------" << endl; - - driver_output = COutputFactory::CreateMultizoneOutput(driver_config, config, nDim); - - driver_output->PreprocessMultizoneHistoryOutput(output, config, driver_config, !dry_run); - } - - /*--- Check for an unsteady restart. Update ExtIter if necessary. ---*/ - if (config_container[ZONE_0]->GetTime_Domain() && config_container[ZONE_0]->GetRestart()) - TimeIter = config_container[ZONE_0]->GetRestart_Iter(); - + + /*--- Definition of the output class (one for each zone). The output class + manages the writing of all restart, volume solution, surface solution, + surface comma-separated value, and convergence history files (both in serial + and in parallel). ---*/ + + for (iZone = 0; iZone < nZone; iZone++){ + + if (rank == MASTER_NODE) + cout << endl <<"-------------------- Output Preprocessing ( Zone " << iZone <<" ) --------------------" << endl; + + MAIN_SOLVER kindSolver = config[iZone]->GetKind_Solver(); + + output[iZone] = COutputFactory::CreateOutput(kindSolver, config[iZone], nDim); + + /*--- If dry-run is used, do not open/overwrite history file. ---*/ + output[iZone]->PreprocessHistoryOutput(config[iZone], !dry_run); + + output[iZone]->PreprocessVolumeOutput(config[iZone]); + + } + + if (driver_config->GetMultizone_Problem()){ + if (rank == MASTER_NODE) + cout << endl <<"------------------- Output Preprocessing ( Multizone ) ------------------" << endl; + + driver_output = COutputFactory::CreateMultizoneOutput(driver_config, config, nDim); + + driver_output->PreprocessMultizoneHistoryOutput(output, config, driver_config, !dry_run); + } + + /*--- Check for an unsteady restart. Update ExtIter if necessary. ---*/ + if (config_container[ZONE_0]->GetTime_Domain() && config_container[ZONE_0]->GetRestart()) + TimeIter = config_container[ZONE_0]->GetRestart_Iter(); + } void CDriver::Turbomachinery_Preprocessing(CConfig** config, CGeometry**** geometry, CSolver***** solver, CInterface*** interface){ - - unsigned short donorZone,targetZone, nMarkerInt, iMarkerInt; - unsigned short nSpanMax = 0; - bool restart = (config[ZONE_0]->GetRestart() || config[ZONE_0]->GetRestart_Flow()); - mixingplane = config[ZONE_0]->GetBoolMixingPlaneInterface(); - bool discrete_adjoint = config[ZONE_0]->GetDiscrete_Adjoint(); - su2double areaIn, areaOut, nBlades, flowAngleIn, flowAngleOut; - - /*--- Create turbovertex structure ---*/ - if (rank == MASTER_NODE) cout<GetBoolTurbomachinery()){ - geometry[iZone][INST_0][MESH_0]->ComputeNSpan(config[iZone], iZone, INFLOW, true); - geometry[iZone][INST_0][MESH_0]->ComputeNSpan(config[iZone], iZone, OUTFLOW, true); - if (rank == MASTER_NODE) cout <<"Number of span-wise sections in Zone "<< iZone<<": "<< config[iZone]->GetnSpanWiseSections() <<"."<< endl; - if (config[iZone]->GetnSpanWiseSections() > nSpanMax){ - nSpanMax = config[iZone]->GetnSpanWiseSections(); - } - - config[ZONE_0]->SetnSpan_iZones(config[iZone]->GetnSpanWiseSections(), iZone); - - geometry[iZone][INST_0][MESH_0]->SetTurboVertex(config[iZone], iZone, INFLOW, true); - geometry[iZone][INST_0][MESH_0]->SetTurboVertex(config[iZone], iZone, OUTFLOW, true); - } - } - - /*--- Set maximum number of Span among all zones ---*/ - for (iZone = 0; iZone < nZone; iZone++) { - if (config[iZone]->GetBoolTurbomachinery()){ - config[iZone]->SetnSpanMaxAllZones(nSpanMax); - } - } - if (rank == MASTER_NODE) cout<<"Max number of span-wise sections among all zones: "<< nSpanMax<<"."<< endl; - - - if (rank == MASTER_NODE) cout<<"Initialize solver containers for average and performance quantities." << endl; - for (iZone = 0; iZone < nZone; iZone++) { - solver[iZone][INST_0][MESH_0][FLOW_SOL]->InitTurboContainers(geometry[iZone][INST_0][MESH_0],config[iZone]); - } - -//TODO(turbo) make it general for turbo HB - if (rank == MASTER_NODE) cout<<"Compute inflow and outflow average geometric quantities." << endl; - for (iZone = 0; iZone < nZone; iZone++) { - geometry[iZone][INST_0][MESH_0]->SetAvgTurboValue(config[iZone], iZone, INFLOW, true); - geometry[iZone][INST_0][MESH_0]->SetAvgTurboValue(config[iZone],iZone, OUTFLOW, true); - geometry[iZone][INST_0][MESH_0]->GatherInOutAverageValues(config[iZone], true); - } - - - if(mixingplane){ - if (rank == MASTER_NODE) cout << "Set span-wise sections between zones on Mixing-Plane interface." << endl; - for (donorZone = 0; donorZone < nZone; donorZone++) { - for (targetZone = 0; targetZone < nZone; targetZone++) { - if (targetZone != donorZone){ - interface[donorZone][targetZone]->SetSpanWiseLevels(config[donorZone], config[targetZone]); - } - } - } - } - - if (rank == MASTER_NODE) cout << "Transfer average geometric quantities to zone 0." << endl; - for (iZone = 1; iZone < nZone; iZone++) { - interface[iZone][ZONE_0]->GatherAverageTurboGeoValues(geometry[iZone][INST_0][MESH_0],geometry[ZONE_0][INST_0][MESH_0], iZone); - } - - /*--- Transfer number of blade to ZONE_0 to correctly compute turbo performance---*/ - for (iZone = 1; iZone < nZone; iZone++) { - nBlades = config[iZone]->GetnBlades(iZone); - config[ZONE_0]->SetnBlades(iZone, nBlades); - } - - if (rank == MASTER_NODE){ + + unsigned short donorZone,targetZone, nMarkerInt, iMarkerInt; + unsigned short nSpanMax = 0; + bool restart = (config[ZONE_0]->GetRestart() || config[ZONE_0]->GetRestart_Flow()); + mixingplane = config[ZONE_0]->GetBoolMixingPlaneInterface(); + bool discrete_adjoint = config[ZONE_0]->GetDiscrete_Adjoint(); + su2double areaIn, areaOut, nBlades, flowAngleIn, flowAngleOut; + + /*--- Create turbovertex structure ---*/ + if (rank == MASTER_NODE) cout<GetSpanAreaIn(iZone, config[iZone]->GetnSpanWiseSections()); - areaOut = geometry[iZone][INST_0][MESH_0]->GetSpanAreaOut(iZone, config[iZone]->GetnSpanWiseSections()); - nBlades = config[iZone]->GetnBlades(iZone); - cout << "Inlet area for Row "<< iZone + 1<< ": " << areaIn*10000.0 <<" cm^2." <GetnMarker_MixingPlaneInterface()/2; - for (iMarkerInt = 1; iMarkerInt <= nMarkerInt; iMarkerInt++){ - for (targetZone = 0; targetZone < nZone; targetZone++) { - if (targetZone != donorZone){ - interface[donorZone][targetZone]->PreprocessAverage(geometry[donorZone][INST_0][MESH_0], geometry[targetZone][INST_0][MESH_0], - config[donorZone], config[targetZone], - iMarkerInt); - } + if (config[iZone]->GetBoolTurbomachinery()){ + geometry[iZone][INST_0][MESH_0]->ComputeNSpan(config[iZone], iZone, INFLOW, true); + geometry[iZone][INST_0][MESH_0]->ComputeNSpan(config[iZone], iZone, OUTFLOW, true); + if (rank == MASTER_NODE) cout <<"Number of span-wise sections in Zone "<< iZone<<": "<< config[iZone]->GetnSpanWiseSections() <<"."<< endl; + if (config[iZone]->GetnSpanWiseSections() > nSpanMax){ + nSpanMax = config[iZone]->GetnSpanWiseSections(); + } + + config[ZONE_0]->SetnSpan_iZones(config[iZone]->GetnSpanWiseSections(), iZone); + + geometry[iZone][INST_0][MESH_0]->SetTurboVertex(config[iZone], iZone, INFLOW, true); + geometry[iZone][INST_0][MESH_0]->SetTurboVertex(config[iZone], iZone, OUTFLOW, true); } - } } - } - - if(!restart && !discrete_adjoint){ - if (rank == MASTER_NODE) cout<<"Initialize turbomachinery solution quantities." << endl; - for(iZone = 0; iZone < nZone; iZone++) { - solver[iZone][INST_0][MESH_0][FLOW_SOL]->SetFreeStream_TurboSolution(config[iZone]); + + /*--- Set maximum number of Span among all zones ---*/ + for (iZone = 0; iZone < nZone; iZone++) { + if (config[iZone]->GetBoolTurbomachinery()){ + config[iZone]->SetnSpanMaxAllZones(nSpanMax); + } } - } - - if (rank == MASTER_NODE) cout<<"Initialize inflow and outflow average solution quantities." << endl; - for(iZone = 0; iZone < nZone; iZone++) { - solver[iZone][INST_0][MESH_0][FLOW_SOL]->PreprocessAverage(solver[iZone][INST_0][MESH_0], geometry[iZone][INST_0][MESH_0],config[iZone],INFLOW); - solver[iZone][INST_0][MESH_0][FLOW_SOL]->PreprocessAverage(solver[iZone][INST_0][MESH_0], geometry[iZone][INST_0][MESH_0],config[iZone],OUTFLOW); - solver[iZone][INST_0][MESH_0][FLOW_SOL]->TurboAverageProcess(solver[iZone][INST_0][MESH_0], geometry[iZone][INST_0][MESH_0],config[iZone],INFLOW); - solver[iZone][INST_0][MESH_0][FLOW_SOL]->TurboAverageProcess(solver[iZone][INST_0][MESH_0], geometry[iZone][INST_0][MESH_0],config[iZone],OUTFLOW); - solver[iZone][INST_0][MESH_0][FLOW_SOL]->GatherInOutAverageValues(config[iZone], geometry[iZone][INST_0][MESH_0]); - if (rank == MASTER_NODE){ - flowAngleIn = solver[iZone][INST_0][MESH_0][FLOW_SOL]->GetTurboVelocityIn(iZone, config[iZone]->GetnSpanWiseSections())[1]; - flowAngleIn /= solver[iZone][INST_0][MESH_0][FLOW_SOL]->GetTurboVelocityIn(iZone, config[iZone]->GetnSpanWiseSections())[0]; - flowAngleIn = atan(flowAngleIn)*180.0/PI_NUMBER; - cout << "Inlet flow angle for Row "<< iZone + 1<< ": "<< flowAngleIn <<"°." <GetTurboVelocityOut(iZone, config[iZone]->GetnSpanWiseSections())[1]; - flowAngleOut /= solver[iZone][INST_0][MESH_0][FLOW_SOL]->GetTurboVelocityOut(iZone, config[iZone]->GetnSpanWiseSections())[0]; - flowAngleOut = atan(flowAngleOut)*180.0/PI_NUMBER; - cout << "Outlet flow angle for Row "<< iZone + 1<< ": "<< flowAngleOut <<"°." <InitTurboContainers(geometry[iZone][INST_0][MESH_0],config[iZone]); } - } - -} - -CDriver::~CDriver(void) {} - -void CDriver::Print_DirectResidual(RECORDING kind_recording) { - - if (!(rank == MASTER_NODE && kind_recording == RECORDING::SOLUTION_VARIABLES)) return; - - const bool multizone = config_container[ZONE_0]->GetMultizone_Problem(); - - /*--- Helper lambda func to return lenghty [iVar][iZone] string. ---*/ - auto iVar_iZone2string = [&](unsigned short ivar, unsigned short izone) { - if (multizone) - return "[" + std::to_string(ivar) + "][" + std::to_string(izone) + "]"; - else - return "[" + std::to_string(ivar) + "]"; - }; - - /*--- Print residuals in the first iteration ---*/ - - const unsigned short fieldWidth = 15; - PrintingToolbox::CTablePrinter RMSTable(&std::cout); - RMSTable.SetPrecision(config_container[ZONE_0]->GetOutput_Precision()); - - /*--- The CTablePrinter requires two sweeps: - *--- 0. Add the colum names (addVals=0=false) plus CTablePrinter.PrintHeader() - *--- 1. Add the RMS-residual values (addVals=1=true) plus CTablePrinter.PrintFooter() ---*/ - for (int addVals = 0; addVals < 2; addVals++) { - - for (unsigned short iZone = 0; iZone < nZone; iZone++) { - - auto solvers = solver_container[iZone][INST_0][MESH_0]; - auto configs = config_container[iZone]; - - /*--- Note: the FEM-Flow solvers are availalbe for disc. adjoint runs only for SingleZone. ---*/ - if (configs->GetFluidProblem() || configs->GetFEMSolver()) { - - for (unsigned short iVar = 0; iVar < solvers[FLOW_SOL]->GetnVar(); iVar++) { - if (!addVals) - RMSTable.AddColumn("rms_Flow" + iVar_iZone2string(iVar, iZone), fieldWidth); - else - RMSTable << log10(solvers[FLOW_SOL]->GetRes_RMS(iVar)); - } - - if (configs->GetKind_Turb_Model() != TURB_MODEL::NONE && !configs->GetFrozen_Visc_Disc()) { - for (unsigned short iVar = 0; iVar < solvers[TURB_SOL]->GetnVar(); iVar++) { - if (!addVals) - RMSTable.AddColumn("rms_Turb" + iVar_iZone2string(iVar, iZone), fieldWidth); - else - RMSTable << log10(solvers[TURB_SOL]->GetRes_RMS(iVar)); - } - } - - if (configs->GetKind_Species_Model() != SPECIES_MODEL::NONE) { - for (unsigned short iVar = 0; iVar < solvers[SPECIES_SOL]->GetnVar(); iVar++) { - if (!addVals) - RMSTable.AddColumn("rms_Spec" + iVar_iZone2string(iVar, iZone), fieldWidth); - else - RMSTable << log10(solvers[SPECIES_SOL]->GetRes_RMS(iVar)); - } + + //TODO(turbo) make it general for turbo HB + if (rank == MASTER_NODE) cout<<"Compute inflow and outflow average geometric quantities." << endl; + for (iZone = 0; iZone < nZone; iZone++) { + geometry[iZone][INST_0][MESH_0]->SetAvgTurboValue(config[iZone], iZone, INFLOW, true); + geometry[iZone][INST_0][MESH_0]->SetAvgTurboValue(config[iZone],iZone, OUTFLOW, true); + geometry[iZone][INST_0][MESH_0]->GatherInOutAverageValues(config[iZone], true); + } + + + if(mixingplane){ + if (rank == MASTER_NODE) cout << "Set span-wise sections between zones on Mixing-Plane interface." << endl; + for (donorZone = 0; donorZone < nZone; donorZone++) { + for (targetZone = 0; targetZone < nZone; targetZone++) { + if (targetZone != donorZone){ + interface[donorZone][targetZone]->SetSpanWiseLevels(config[donorZone], config[targetZone]); + } + } } - - if (!multizone && configs->GetWeakly_Coupled_Heat()){ - if (!addVals) RMSTable.AddColumn("rms_Heat" + iVar_iZone2string(0, iZone), fieldWidth); - else RMSTable << log10(solvers[HEAT_SOL]->GetRes_RMS(0)); + } + + if (rank == MASTER_NODE) cout << "Transfer average geometric quantities to zone 0." << endl; + for (iZone = 1; iZone < nZone; iZone++) { + interface[iZone][ZONE_0]->GatherAverageTurboGeoValues(geometry[iZone][INST_0][MESH_0],geometry[ZONE_0][INST_0][MESH_0], iZone); + } + + /*--- Transfer number of blade to ZONE_0 to correctly compute turbo performance---*/ + for (iZone = 1; iZone < nZone; iZone++) { + nBlades = config[iZone]->GetnBlades(iZone); + config[ZONE_0]->SetnBlades(iZone, nBlades); + } + + if (rank == MASTER_NODE){ + for (iZone = 0; iZone < nZone; iZone++) { + areaIn = geometry[iZone][INST_0][MESH_0]->GetSpanAreaIn(iZone, config[iZone]->GetnSpanWiseSections()); + areaOut = geometry[iZone][INST_0][MESH_0]->GetSpanAreaOut(iZone, config[iZone]->GetnSpanWiseSections()); + nBlades = config[iZone]->GetnBlades(iZone); + cout << "Inlet area for Row "<< iZone + 1<< ": " << areaIn*10000.0 <<" cm^2." <AddRadiation()) { - if (!addVals) RMSTable.AddColumn("rms_Rad" + iVar_iZone2string(0, iZone), fieldWidth); - else RMSTable << log10(solvers[RAD_SOL]->GetRes_RMS(0)); + } + + + if(mixingplane){ + if (rank == MASTER_NODE) cout<<"Preprocessing of the Mixing-Plane Interface." << endl; + for (donorZone = 0; donorZone < nZone; donorZone++) { + nMarkerInt = config_container[donorZone]->GetnMarker_MixingPlaneInterface()/2; + for (iMarkerInt = 1; iMarkerInt <= nMarkerInt; iMarkerInt++){ + for (targetZone = 0; targetZone < nZone; targetZone++) { + if (targetZone != donorZone){ + interface[donorZone][targetZone]->PreprocessAverage(geometry[donorZone][INST_0][MESH_0], geometry[targetZone][INST_0][MESH_0], + config[donorZone], config[targetZone], + iMarkerInt); + } + } + } } - - } - else if (configs->GetStructuralProblem()) { - - if (configs->GetGeometricConditions() == STRUCT_DEFORMATION::LARGE){ - if (!addVals) { - RMSTable.AddColumn("UTOL-A", fieldWidth); - RMSTable.AddColumn("RTOL-A", fieldWidth); - RMSTable.AddColumn("ETOL-A", fieldWidth); - } - else { - RMSTable << log10(solvers[FEA_SOL]->GetRes_FEM(0)) - << log10(solvers[FEA_SOL]->GetRes_FEM(1)) - << log10(solvers[FEA_SOL]->GetRes_FEM(2)); - } + } + + if(!restart && !discrete_adjoint){ + if (rank == MASTER_NODE) cout<<"Initialize turbomachinery solution quantities." << endl; + for(iZone = 0; iZone < nZone; iZone++) { + solver[iZone][INST_0][MESH_0][FLOW_SOL]->SetFreeStream_TurboSolution(config[iZone]); } - else{ - if (!addVals) { - RMSTable.AddColumn("log10[RMS Ux]", fieldWidth); - RMSTable.AddColumn("log10[RMS Uy]", fieldWidth); - if (nDim == 3) RMSTable.AddColumn("log10[RMS Uz]", fieldWidth); - } - else { - RMSTable << log10(solvers[FEA_SOL]->GetRes_FEM(0)) - << log10(solvers[FEA_SOL]->GetRes_FEM(1)); - if (nDim == 3) RMSTable << log10(solvers[FEA_SOL]->GetRes_FEM(2)); - } + } + + if (rank == MASTER_NODE) cout<<"Initialize inflow and outflow average solution quantities." << endl; + for(iZone = 0; iZone < nZone; iZone++) { + solver[iZone][INST_0][MESH_0][FLOW_SOL]->PreprocessAverage(solver[iZone][INST_0][MESH_0], geometry[iZone][INST_0][MESH_0],config[iZone],INFLOW); + solver[iZone][INST_0][MESH_0][FLOW_SOL]->PreprocessAverage(solver[iZone][INST_0][MESH_0], geometry[iZone][INST_0][MESH_0],config[iZone],OUTFLOW); + solver[iZone][INST_0][MESH_0][FLOW_SOL]->TurboAverageProcess(solver[iZone][INST_0][MESH_0], geometry[iZone][INST_0][MESH_0],config[iZone],INFLOW); + solver[iZone][INST_0][MESH_0][FLOW_SOL]->TurboAverageProcess(solver[iZone][INST_0][MESH_0], geometry[iZone][INST_0][MESH_0],config[iZone],OUTFLOW); + solver[iZone][INST_0][MESH_0][FLOW_SOL]->GatherInOutAverageValues(config[iZone], geometry[iZone][INST_0][MESH_0]); + if (rank == MASTER_NODE){ + flowAngleIn = solver[iZone][INST_0][MESH_0][FLOW_SOL]->GetTurboVelocityIn(iZone, config[iZone]->GetnSpanWiseSections())[1]; + flowAngleIn /= solver[iZone][INST_0][MESH_0][FLOW_SOL]->GetTurboVelocityIn(iZone, config[iZone]->GetnSpanWiseSections())[0]; + flowAngleIn = atan(flowAngleIn)*180.0/PI_NUMBER; + cout << "Inlet flow angle for Row "<< iZone + 1<< ": "<< flowAngleIn <<"°." <GetTurboVelocityOut(iZone, config[iZone]->GetnSpanWiseSections())[1]; + flowAngleOut /= solver[iZone][INST_0][MESH_0][FLOW_SOL]->GetTurboVelocityOut(iZone, config[iZone]->GetnSpanWiseSections())[0]; + flowAngleOut = atan(flowAngleOut)*180.0/PI_NUMBER; + cout << "Outlet flow angle for Row "<< iZone + 1<< ": "<< flowAngleOut <<"°." <GetHeatProblem()) { - - if (!addVals) RMSTable.AddColumn("rms_Heat" + iVar_iZone2string(0, iZone), fieldWidth); - else RMSTable << log10(solvers[HEAT_SOL]->GetRes_RMS(0)); - } else { - SU2_MPI::Error("Invalid KindSolver for CDiscAdj-MultiZone/SingleZone-Driver.", CURRENT_FUNCTION); - } - } // loop iZone - - if (!addVals) RMSTable.PrintHeader(); - else RMSTable.PrintFooter(); - - } // for addVals - - cout << "\n-------------------------------------------------------------------------\n" << endl; +CDriver::~CDriver(void) {} +void CDriver::Print_DirectResidual(RECORDING kind_recording) { + + if (!(rank == MASTER_NODE && kind_recording == RECORDING::SOLUTION_VARIABLES)) return; + + const bool multizone = config_container[ZONE_0]->GetMultizone_Problem(); + + /*--- Helper lambda func to return lenghty [iVar][iZone] string. ---*/ + auto iVar_iZone2string = [&](unsigned short ivar, unsigned short izone) { + if (multizone) + return "[" + std::to_string(ivar) + "][" + std::to_string(izone) + "]"; + else + return "[" + std::to_string(ivar) + "]"; + }; + + /*--- Print residuals in the first iteration ---*/ + + const unsigned short fieldWidth = 15; + PrintingToolbox::CTablePrinter RMSTable(&std::cout); + RMSTable.SetPrecision(config_container[ZONE_0]->GetOutput_Precision()); + + /*--- The CTablePrinter requires two sweeps: + *--- 0. Add the colum names (addVals=0=false) plus CTablePrinter.PrintHeader() + *--- 1. Add the RMS-residual values (addVals=1=true) plus CTablePrinter.PrintFooter() ---*/ + for (int addVals = 0; addVals < 2; addVals++) { + + for (unsigned short iZone = 0; iZone < nZone; iZone++) { + + auto solvers = solver_container[iZone][INST_0][MESH_0]; + auto configs = config_container[iZone]; + + /*--- Note: the FEM-Flow solvers are availalbe for disc. adjoint runs only for SingleZone. ---*/ + if (configs->GetFluidProblem() || configs->GetFEMSolver()) { + + for (unsigned short iVar = 0; iVar < solvers[FLOW_SOL]->GetnVar(); iVar++) { + if (!addVals) + RMSTable.AddColumn("rms_Flow" + iVar_iZone2string(iVar, iZone), fieldWidth); + else + RMSTable << log10(solvers[FLOW_SOL]->GetRes_RMS(iVar)); + } + + if (configs->GetKind_Turb_Model() != TURB_MODEL::NONE && !configs->GetFrozen_Visc_Disc()) { + for (unsigned short iVar = 0; iVar < solvers[TURB_SOL]->GetnVar(); iVar++) { + if (!addVals) + RMSTable.AddColumn("rms_Turb" + iVar_iZone2string(iVar, iZone), fieldWidth); + else + RMSTable << log10(solvers[TURB_SOL]->GetRes_RMS(iVar)); + } + } + + if (configs->GetKind_Species_Model() != SPECIES_MODEL::NONE) { + for (unsigned short iVar = 0; iVar < solvers[SPECIES_SOL]->GetnVar(); iVar++) { + if (!addVals) + RMSTable.AddColumn("rms_Spec" + iVar_iZone2string(iVar, iZone), fieldWidth); + else + RMSTable << log10(solvers[SPECIES_SOL]->GetRes_RMS(iVar)); + } + } + + if (!multizone && configs->GetWeakly_Coupled_Heat()){ + if (!addVals) RMSTable.AddColumn("rms_Heat" + iVar_iZone2string(0, iZone), fieldWidth); + else RMSTable << log10(solvers[HEAT_SOL]->GetRes_RMS(0)); + } + + if (configs->AddRadiation()) { + if (!addVals) RMSTable.AddColumn("rms_Rad" + iVar_iZone2string(0, iZone), fieldWidth); + else RMSTable << log10(solvers[RAD_SOL]->GetRes_RMS(0)); + } + + } + else if (configs->GetStructuralProblem()) { + + if (configs->GetGeometricConditions() == STRUCT_DEFORMATION::LARGE){ + if (!addVals) { + RMSTable.AddColumn("UTOL-A", fieldWidth); + RMSTable.AddColumn("RTOL-A", fieldWidth); + RMSTable.AddColumn("ETOL-A", fieldWidth); + } + else { + RMSTable << log10(solvers[FEA_SOL]->GetRes_FEM(0)) + << log10(solvers[FEA_SOL]->GetRes_FEM(1)) + << log10(solvers[FEA_SOL]->GetRes_FEM(2)); + } + } + else{ + if (!addVals) { + RMSTable.AddColumn("log10[RMS Ux]", fieldWidth); + RMSTable.AddColumn("log10[RMS Uy]", fieldWidth); + if (nDim == 3) RMSTable.AddColumn("log10[RMS Uz]", fieldWidth); + } + else { + RMSTable << log10(solvers[FEA_SOL]->GetRes_FEM(0)) + << log10(solvers[FEA_SOL]->GetRes_FEM(1)); + if (nDim == 3) RMSTable << log10(solvers[FEA_SOL]->GetRes_FEM(2)); + } + } + + } + else if (configs->GetHeatProblem()) { + + if (!addVals) RMSTable.AddColumn("rms_Heat" + iVar_iZone2string(0, iZone), fieldWidth); + else RMSTable << log10(solvers[HEAT_SOL]->GetRes_RMS(0)); + } else { + SU2_MPI::Error("Invalid KindSolver for CDiscAdj-MultiZone/SingleZone-Driver.", CURRENT_FUNCTION); + } + } // loop iZone + + if (!addVals) RMSTable.PrintHeader(); + else RMSTable.PrintFooter(); + + } // for addVals + + cout << "\n-------------------------------------------------------------------------\n" << endl; + } CFluidDriver::CFluidDriver(char* confFile, unsigned short val_nZone, SU2_Comm MPICommunicator) : CDriver(confFile, val_nZone, MPICommunicator, false) { - Max_Iter = config_container[ZONE_0]->GetnInner_Iter(); + Max_Iter = config_container[ZONE_0]->GetnInner_Iter(); } CFluidDriver::~CFluidDriver(void) { } void CFluidDriver::StartSolver(){ - + #ifdef VTUNEPROF - __itt_resume(); + __itt_resume(); #endif - - /*--- Main external loop of the solver. Within this loop, each iteration ---*/ - - if (rank == MASTER_NODE){ - cout << endl <<"------------------------------ Begin Solver -----------------------------" << endl; - } - - unsigned long Iter = 0; - while ( Iter < Max_Iter ) { - - /*--- Perform some external iteration preprocessing. ---*/ - - Preprocess(Iter); - - /*--- Perform a dynamic mesh update if required. ---*/ - /*--- For the Disc.Adj. of a case with (rigidly) moving grid, the appropriate - mesh cordinates are read from the restart files. ---*/ - if (!fem_solver && - !(config_container[ZONE_0]->GetGrid_Movement() && config_container[ZONE_0]->GetDiscrete_Adjoint())) { - DynamicMeshUpdate(Iter); + + /*--- Main external loop of the solver. Within this loop, each iteration ---*/ + + if (rank == MASTER_NODE){ + cout << endl <<"------------------------------ Begin Solver -----------------------------" << endl; + } + + unsigned long Iter = 0; + while ( Iter < Max_Iter ) { + + /*--- Perform some external iteration preprocessing. ---*/ + + Preprocess(Iter); + + /*--- Perform a dynamic mesh update if required. ---*/ + /*--- For the Disc.Adj. of a case with (rigidly) moving grid, the appropriate + mesh cordinates are read from the restart files. ---*/ + if (!fem_solver && + !(config_container[ZONE_0]->GetGrid_Movement() && config_container[ZONE_0]->GetDiscrete_Adjoint())) { + DynamicMeshUpdate(Iter); + } + + /*--- Run a single iteration of the problem (fluid, elasticity, heat, ...). ---*/ + + Run(); + + /*--- Update the solution for dual time stepping strategy ---*/ + + Update(); + + /*--- Terminate the simulation if only the Jacobian must be computed. ---*/ + if (config_container[ZONE_0]->GetJacobian_Spatial_Discretization_Only()) break; + + /*--- Monitor the computations after each iteration. ---*/ + + Monitor(Iter); + + /*--- Output the solution in files. ---*/ + + Output(Iter); + + /*--- If the convergence criteria has been met, terminate the simulation. ---*/ + + if (StopCalc) break; + + Iter++; + } - - /*--- Run a single iteration of the problem (fluid, elasticity, heat, ...). ---*/ - - Run(); - - /*--- Update the solution for dual time stepping strategy ---*/ - - Update(); - - /*--- Terminate the simulation if only the Jacobian must be computed. ---*/ - if (config_container[ZONE_0]->GetJacobian_Spatial_Discretization_Only()) break; - - /*--- Monitor the computations after each iteration. ---*/ - - Monitor(Iter); - - /*--- Output the solution in files. ---*/ - - Output(Iter); - - /*--- If the convergence criteria has been met, terminate the simulation. ---*/ - - if (StopCalc) break; - - Iter++; - - } #ifdef VTUNEPROF - __itt_pause(); + __itt_pause(); #endif } void CFluidDriver::Preprocess(unsigned long Iter) { - - /*--- Set the value of the external iteration and physical time. ---*/ - - for (iZone = 0; iZone < nZone; iZone++) { - config_container[iZone]->SetInnerIter(Iter); - if (config_container[iZone]->GetTime_Marching() != TIME_MARCHING::STEADY) - config_container[iZone]->SetPhysicalTime(static_cast(Iter)*config_container[iZone]->GetDelta_UnstTimeND()); - else - config_container[iZone]->SetPhysicalTime(0.0); - } - - /*--- Set the initial condition for EULER/N-S/RANS and for a non FSI simulation ---*/ - - if(!fsi) { + + /*--- Set the value of the external iteration and physical time. ---*/ + for (iZone = 0; iZone < nZone; iZone++) { - if (config_container[iZone]->GetFluidProblem()) { - for (iInst = 0; iInst < nInst[iZone]; iInst++) { - solver_container[iZone][iInst][MESH_0][FLOW_SOL]->SetInitialCondition(geometry_container[iZone][INST_0], solver_container[iZone][iInst], config_container[iZone], Iter); + config_container[iZone]->SetInnerIter(Iter); + if (config_container[iZone]->GetTime_Marching() != TIME_MARCHING::STEADY) + config_container[iZone]->SetPhysicalTime(static_cast(Iter)*config_container[iZone]->GetDelta_UnstTimeND()); + else + config_container[iZone]->SetPhysicalTime(0.0); + } + + /*--- Set the initial condition for EULER/N-S/RANS and for a non FSI simulation ---*/ + + if(!fsi) { + for (iZone = 0; iZone < nZone; iZone++) { + if (config_container[iZone]->GetFluidProblem()) { + for (iInst = 0; iInst < nInst[iZone]; iInst++) { + solver_container[iZone][iInst][MESH_0][FLOW_SOL]->SetInitialCondition(geometry_container[iZone][INST_0], solver_container[iZone][iInst], config_container[iZone], Iter); + } + } } - } } - } } void CFluidDriver::Run() { - - unsigned short iZone, jZone, checkConvergence; - unsigned long IntIter, nIntIter; - bool unsteady; - - /*--- Run a single iteration of a multi-zone problem by looping over all - zones and executing the iterations. Note that data transers between zones - and other intermediate procedures may be required. ---*/ - - unsteady = (config_container[MESH_0]->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_1ST) || - (config_container[MESH_0]->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_2ND); - - /*--- Zone preprocessing ---*/ - - for (iZone = 0; iZone < nZone; iZone++) - iteration_container[iZone][INST_0]->Preprocess(output_container[iZone], integration_container, geometry_container, solver_container, numerics_container, config_container, surface_movement, grid_movement, FFDBox, iZone, INST_0); - - /*--- Updating zone interface communication patterns, - needed only for unsteady simulation since for steady problems - this is done once in the interpolator_container constructor - at the beginning of the computation ---*/ - - if ( unsteady ) { - for (iZone = 0; iZone < nZone; iZone++) { - for (jZone = 0; jZone < nZone; jZone++) - if(jZone != iZone && interpolator_container[iZone][jZone] != nullptr) - interpolator_container[iZone][jZone]->SetTransferCoeff(config_container); - } - } - - /*--- Begin Unsteady pseudo-time stepping internal loop, if not unsteady it does only one step --*/ - - if (unsteady) - nIntIter = config_container[MESH_0]->GetnInner_Iter(); - else - nIntIter = 1; - - for (IntIter = 0; IntIter < nIntIter; IntIter++) { - - /*--- At each pseudo time-step updates transfer data ---*/ - for (iZone = 0; iZone < nZone; iZone++) - for (jZone = 0; jZone < nZone; jZone++) - if(jZone != iZone && interface_container[iZone][jZone] != nullptr) - Transfer_Data(iZone, jZone); - - /*--- For each zone runs one single iteration ---*/ - - for (iZone = 0; iZone < nZone; iZone++) { - config_container[iZone]->SetInnerIter(IntIter); - iteration_container[iZone][INST_0]->Iterate(output_container[iZone], integration_container, geometry_container, solver_container, numerics_container, - config_container, surface_movement, grid_movement, FFDBox, iZone, INST_0); - } - - /*--- Check convergence in each zone --*/ - - checkConvergence = 0; - for (iZone = 0; iZone < nZone; iZone++) - checkConvergence += (int) integration_container[iZone][INST_0][FLOW_SOL]->GetConvergence(); - - /*--- If convergence was reached in every zone --*/ - - if (checkConvergence == nZone) break; - } - + + unsigned short iZone, jZone, checkConvergence; + unsigned long IntIter, nIntIter; + bool unsteady; + + /*--- Run a single iteration of a multi-zone problem by looping over all + zones and executing the iterations. Note that data transers between zones + and other intermediate procedures may be required. ---*/ + + unsteady = (config_container[MESH_0]->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_1ST) || + (config_container[MESH_0]->GetTime_Marching() == TIME_MARCHING::DT_STEPPING_2ND); + + /*--- Zone preprocessing ---*/ + + for (iZone = 0; iZone < nZone; iZone++) + iteration_container[iZone][INST_0]->Preprocess(output_container[iZone], integration_container, geometry_container, solver_container, numerics_container, config_container, surface_movement, grid_movement, FFDBox, iZone, INST_0); + + /*--- Updating zone interface communication patterns, + needed only for unsteady simulation since for steady problems + this is done once in the interpolator_container constructor + at the beginning of the computation ---*/ + + if ( unsteady ) { + for (iZone = 0; iZone < nZone; iZone++) { + for (jZone = 0; jZone < nZone; jZone++) + if(jZone != iZone && interpolator_container[iZone][jZone] != nullptr) + interpolator_container[iZone][jZone]->SetTransferCoeff(config_container); + } + } + + /*--- Begin Unsteady pseudo-time stepping internal loop, if not unsteady it does only one step --*/ + + if (unsteady) + nIntIter = config_container[MESH_0]->GetnInner_Iter(); + else + nIntIter = 1; + + for (IntIter = 0; IntIter < nIntIter; IntIter++) { + + /*--- At each pseudo time-step updates transfer data ---*/ + for (iZone = 0; iZone < nZone; iZone++) + for (jZone = 0; jZone < nZone; jZone++) + if(jZone != iZone && interface_container[iZone][jZone] != nullptr) + Transfer_Data(iZone, jZone); + + /*--- For each zone runs one single iteration ---*/ + + for (iZone = 0; iZone < nZone; iZone++) { + config_container[iZone]->SetInnerIter(IntIter); + iteration_container[iZone][INST_0]->Iterate(output_container[iZone], integration_container, geometry_container, solver_container, numerics_container, + config_container, surface_movement, grid_movement, FFDBox, iZone, INST_0); + } + + /*--- Check convergence in each zone --*/ + + checkConvergence = 0; + for (iZone = 0; iZone < nZone; iZone++) + checkConvergence += (int) integration_container[iZone][INST_0][FLOW_SOL]->GetConvergence(); + + /*--- If convergence was reached in every zone --*/ + + if (checkConvergence == nZone) break; + } + } void CFluidDriver::Transfer_Data(unsigned short donorZone, unsigned short targetZone) { - - interface_container[donorZone][targetZone]->BroadcastData(*interpolator_container[donorZone][targetZone].get(), - solver_container[donorZone][INST_0][MESH_0][FLOW_SOL], solver_container[targetZone][INST_0][MESH_0][FLOW_SOL], - geometry_container[donorZone][INST_0][MESH_0], geometry_container[targetZone][INST_0][MESH_0], - config_container[donorZone], config_container[targetZone]); - - if (config_container[targetZone]->GetKind_Solver() == MAIN_SOLVER::RANS) { + interface_container[donorZone][targetZone]->BroadcastData(*interpolator_container[donorZone][targetZone].get(), - solver_container[donorZone][INST_0][MESH_0][TURB_SOL], solver_container[targetZone][INST_0][MESH_0][TURB_SOL], - geometry_container[donorZone][INST_0][MESH_0], geometry_container[targetZone][INST_0][MESH_0], - config_container[donorZone], config_container[targetZone]); - } + solver_container[donorZone][INST_0][MESH_0][FLOW_SOL], solver_container[targetZone][INST_0][MESH_0][FLOW_SOL], + geometry_container[donorZone][INST_0][MESH_0], geometry_container[targetZone][INST_0][MESH_0], + config_container[donorZone], config_container[targetZone]); + + if (config_container[targetZone]->GetKind_Solver() == MAIN_SOLVER::RANS) { + interface_container[donorZone][targetZone]->BroadcastData(*interpolator_container[donorZone][targetZone].get(), + solver_container[donorZone][INST_0][MESH_0][TURB_SOL], solver_container[targetZone][INST_0][MESH_0][TURB_SOL], + geometry_container[donorZone][INST_0][MESH_0], geometry_container[targetZone][INST_0][MESH_0], + config_container[donorZone], config_container[targetZone]); + } } void CFluidDriver::Update() { - - for(iZone = 0; iZone < nZone; iZone++) - iteration_container[iZone][INST_0]->Update(output_container[iZone], integration_container, geometry_container, - solver_container, numerics_container, config_container, - surface_movement, grid_movement, FFDBox, iZone, INST_0); + + for(iZone = 0; iZone < nZone; iZone++) + iteration_container[iZone][INST_0]->Update(output_container[iZone], integration_container, geometry_container, + solver_container, numerics_container, config_container, + surface_movement, grid_movement, FFDBox, iZone, INST_0); } void CFluidDriver::DynamicMeshUpdate(unsigned long TimeIter) { - - bool harmonic_balance; - - for (iZone = 0; iZone < nZone; iZone++) { - harmonic_balance = (config_container[iZone]->GetTime_Marching() == TIME_MARCHING::HARMONIC_BALANCE); - /*--- Dynamic mesh update ---*/ - if ((config_container[iZone]->GetGrid_Movement()) && (!harmonic_balance)) { - iteration_container[iZone][INST_0]->SetGrid_Movement(geometry_container[iZone][INST_0], surface_movement[iZone], grid_movement[iZone][INST_0], solver_container[iZone][INST_0], config_container[iZone], 0, TimeIter ); + + bool harmonic_balance; + + for (iZone = 0; iZone < nZone; iZone++) { + harmonic_balance = (config_container[iZone]->GetTime_Marching() == TIME_MARCHING::HARMONIC_BALANCE); + /*--- Dynamic mesh update ---*/ + if ((config_container[iZone]->GetGrid_Movement()) && (!harmonic_balance)) { + iteration_container[iZone][INST_0]->SetGrid_Movement(geometry_container[iZone][INST_0], surface_movement[iZone], grid_movement[iZone][INST_0], solver_container[iZone][INST_0], config_container[iZone], 0, TimeIter ); + } } - } - + } bool CFluidDriver::Monitor(unsigned long ExtIter) { - - /*--- Synchronization point after a single solver iteration. Compute the - wall clock time required. ---*/ - - StopTime = SU2_MPI::Wtime(); - - IterCount++; - UsedTime = (StopTime - StartTime) + UsedTimeCompute; - - /*--- Check if there is any change in the runtime parameters ---*/ - - CConfig *runtime = nullptr; - strcpy(runtime_file_name, "runtime.dat"); - runtime = new CConfig(runtime_file_name, config_container[ZONE_0]); - runtime->SetTimeIter(ExtIter); - delete runtime; - - /*--- Check whether the current simulation has reached the specified - convergence criteria, and set StopCalc to true, if so. ---*/ - - switch (config_container[ZONE_0]->GetKind_Solver()) { - case MAIN_SOLVER::EULER: case MAIN_SOLVER::NAVIER_STOKES: case MAIN_SOLVER::RANS: - case MAIN_SOLVER::NEMO_EULER: case MAIN_SOLVER::NEMO_NAVIER_STOKES: - StopCalc = integration_container[ZONE_0][INST_0][FLOW_SOL]->GetConvergence(); break; - case MAIN_SOLVER::HEAT_EQUATION: - StopCalc = integration_container[ZONE_0][INST_0][HEAT_SOL]->GetConvergence(); break; - case MAIN_SOLVER::FEM_ELASTICITY: - StopCalc = integration_container[ZONE_0][INST_0][FEA_SOL]->GetConvergence(); break; - case MAIN_SOLVER::ADJ_EULER: case MAIN_SOLVER::ADJ_NAVIER_STOKES: case MAIN_SOLVER::ADJ_RANS: - case MAIN_SOLVER::DISC_ADJ_EULER: case MAIN_SOLVER::DISC_ADJ_NAVIER_STOKES: case MAIN_SOLVER::DISC_ADJ_RANS: - case MAIN_SOLVER::DISC_ADJ_INC_EULER: case MAIN_SOLVER::DISC_ADJ_INC_NAVIER_STOKES: case MAIN_SOLVER::DISC_ADJ_INC_RANS: - case MAIN_SOLVER::DISC_ADJ_FEM_EULER: case MAIN_SOLVER::DISC_ADJ_FEM_NS: case MAIN_SOLVER::DISC_ADJ_FEM_RANS: - StopCalc = integration_container[ZONE_0][INST_0][ADJFLOW_SOL]->GetConvergence(); break; - default: - break; - } - - /*--- Set StopCalc to true if max. number of iterations has been reached ---*/ - - StopCalc = StopCalc || (ExtIter == Max_Iter - 1); - - return StopCalc; - + + /*--- Synchronization point after a single solver iteration. Compute the + wall clock time required. ---*/ + + StopTime = SU2_MPI::Wtime(); + + IterCount++; + UsedTime = (StopTime - StartTime) + UsedTimeCompute; + + /*--- Check if there is any change in the runtime parameters ---*/ + + CConfig *runtime = nullptr; + strcpy(runtime_file_name, "runtime.dat"); + runtime = new CConfig(runtime_file_name, config_container[ZONE_0]); + runtime->SetTimeIter(ExtIter); + delete runtime; + + /*--- Check whether the current simulation has reached the specified + convergence criteria, and set StopCalc to true, if so. ---*/ + + switch (config_container[ZONE_0]->GetKind_Solver()) { + case MAIN_SOLVER::EULER: case MAIN_SOLVER::NAVIER_STOKES: case MAIN_SOLVER::RANS: + case MAIN_SOLVER::NEMO_EULER: case MAIN_SOLVER::NEMO_NAVIER_STOKES: + StopCalc = integration_container[ZONE_0][INST_0][FLOW_SOL]->GetConvergence(); break; + case MAIN_SOLVER::HEAT_EQUATION: + StopCalc = integration_container[ZONE_0][INST_0][HEAT_SOL]->GetConvergence(); break; + case MAIN_SOLVER::FEM_ELASTICITY: + StopCalc = integration_container[ZONE_0][INST_0][FEA_SOL]->GetConvergence(); break; + case MAIN_SOLVER::ADJ_EULER: case MAIN_SOLVER::ADJ_NAVIER_STOKES: case MAIN_SOLVER::ADJ_RANS: + case MAIN_SOLVER::DISC_ADJ_EULER: case MAIN_SOLVER::DISC_ADJ_NAVIER_STOKES: case MAIN_SOLVER::DISC_ADJ_RANS: + case MAIN_SOLVER::DISC_ADJ_INC_EULER: case MAIN_SOLVER::DISC_ADJ_INC_NAVIER_STOKES: case MAIN_SOLVER::DISC_ADJ_INC_RANS: + case MAIN_SOLVER::DISC_ADJ_FEM_EULER: case MAIN_SOLVER::DISC_ADJ_FEM_NS: case MAIN_SOLVER::DISC_ADJ_FEM_RANS: + StopCalc = integration_container[ZONE_0][INST_0][ADJFLOW_SOL]->GetConvergence(); break; + default: + break; + } + + /*--- Set StopCalc to true if max. number of iterations has been reached ---*/ + + StopCalc = StopCalc || (ExtIter == Max_Iter - 1); + + return StopCalc; + } void CFluidDriver::Output(unsigned long InnerIter) { - - for (iZone = 0; iZone < nZone; iZone++) { - const auto inst = config_container[iZone]->GetiInst(); - - for (iInst = 0; iInst < nInst[iZone]; ++iInst) { - config_container[iZone]->SetiInst(iInst); - output_container[iZone]->SetResult_Files(geometry_container[iZone][iInst][MESH_0], - config_container[iZone], - solver_container[iZone][iInst][MESH_0], - InnerIter, StopCalc); + + for (iZone = 0; iZone < nZone; iZone++) { + const auto inst = config_container[iZone]->GetiInst(); + + for (iInst = 0; iInst < nInst[iZone]; ++iInst) { + config_container[iZone]->SetiInst(iInst); + output_container[iZone]->SetResult_Files(geometry_container[iZone][iInst][MESH_0], + config_container[iZone], + solver_container[iZone][iInst][MESH_0], + InnerIter, StopCalc); + } + config_container[iZone]->SetiInst(inst); } - config_container[iZone]->SetiInst(inst); - } - + } CTurbomachineryDriver::CTurbomachineryDriver(char* confFile, unsigned short val_nZone, SU2_Comm MPICommunicator): - CFluidDriver(confFile, val_nZone, MPICommunicator) { - - output_legacy = COutputFactory::CreateLegacyOutput(config_container[ZONE_0]); - - /*--- LEGACY OUTPUT (going to be removed soon) --- */ - - /*--- Open the convergence history file ---*/ - ConvHist_file = nullptr; - ConvHist_file = new ofstream*[nZone]; - for (iZone = 0; iZone < nZone; iZone++) { - ConvHist_file[iZone] = nullptr; - if (rank == MASTER_NODE){ - ConvHist_file[iZone] = new ofstream[nInst[iZone]]; - for (iInst = 0; iInst < nInst[iZone]; iInst++) { - output_legacy->SetConvHistory_Header(&ConvHist_file[iZone][iInst], config_container[iZone], iZone, iInst); - } +CFluidDriver(confFile, val_nZone, MPICommunicator) { + + output_legacy = COutputFactory::CreateLegacyOutput(config_container[ZONE_0]); + + /*--- LEGACY OUTPUT (going to be removed soon) --- */ + + /*--- Open the convergence history file ---*/ + ConvHist_file = nullptr; + ConvHist_file = new ofstream*[nZone]; + for (iZone = 0; iZone < nZone; iZone++) { + ConvHist_file[iZone] = nullptr; + if (rank == MASTER_NODE){ + ConvHist_file[iZone] = new ofstream[nInst[iZone]]; + for (iInst = 0; iInst < nInst[iZone]; iInst++) { + output_legacy->SetConvHistory_Header(&ConvHist_file[iZone][iInst], config_container[iZone], iZone, iInst); + } + } + } + + if (nZone > 1){ + Max_Iter = config_container[ZONE_0]->GetnOuter_Iter(); } - } - - if (nZone > 1){ - Max_Iter = config_container[ZONE_0]->GetnOuter_Iter(); - } } CTurbomachineryDriver::~CTurbomachineryDriver(void) { - if (rank == MASTER_NODE){ - /*--- Close the convergence history file. ---*/ - for (iZone = 0; iZone < nZone; iZone++) { - for (iInst = 0; iInst < 1; iInst++) { - ConvHist_file[iZone][iInst].close(); - } - delete [] ConvHist_file[iZone]; + if (rank == MASTER_NODE){ + /*--- Close the convergence history file. ---*/ + for (iZone = 0; iZone < nZone; iZone++) { + for (iInst = 0; iInst < 1; iInst++) { + ConvHist_file[iZone][iInst].close(); + } + delete [] ConvHist_file[iZone]; + } + delete [] ConvHist_file; } - delete [] ConvHist_file; - } } void CTurbomachineryDriver::Run() { - - /*--- Run a single iteration of a multi-zone problem by looping over all - zones and executing the iterations. Note that data transers between zones - and other intermediate procedures may be required. ---*/ - - for (iZone = 0; iZone < nZone; iZone++) { - iteration_container[iZone][INST_0]->Preprocess(output_container[iZone], integration_container, geometry_container, - solver_container, numerics_container, config_container, - surface_movement, grid_movement, FFDBox, iZone, INST_0); - } - - /* --- Update the mixing-plane interface ---*/ - for (iZone = 0; iZone < nZone; iZone++) { - if(mixingplane)SetMixingPlane(iZone); - } - - for (iZone = 0; iZone < nZone; iZone++) { - iteration_container[iZone][INST_0]->Iterate(output_container[iZone], integration_container, geometry_container, - solver_container, numerics_container, config_container, - surface_movement, grid_movement, FFDBox, iZone, INST_0); - } - - for (iZone = 0; iZone < nZone; iZone++) { - iteration_container[iZone][INST_0]->Postprocess(output_container[iZone], integration_container, geometry_container, - solver_container, numerics_container, config_container, - surface_movement, grid_movement, FFDBox, iZone, INST_0); - } - - if (rank == MASTER_NODE){ - SetTurboPerformance(ZONE_0); - } - - + + /*--- Run a single iteration of a multi-zone problem by looping over all + zones and executing the iterations. Note that data transers between zones + and other intermediate procedures may be required. ---*/ + + for (iZone = 0; iZone < nZone; iZone++) { + iteration_container[iZone][INST_0]->Preprocess(output_container[iZone], integration_container, geometry_container, + solver_container, numerics_container, config_container, + surface_movement, grid_movement, FFDBox, iZone, INST_0); + } + + /* --- Update the mixing-plane interface ---*/ + for (iZone = 0; iZone < nZone; iZone++) { + if(mixingplane)SetMixingPlane(iZone); + } + + for (iZone = 0; iZone < nZone; iZone++) { + iteration_container[iZone][INST_0]->Iterate(output_container[iZone], integration_container, geometry_container, + solver_container, numerics_container, config_container, + surface_movement, grid_movement, FFDBox, iZone, INST_0); + } + + for (iZone = 0; iZone < nZone; iZone++) { + iteration_container[iZone][INST_0]->Postprocess(output_container[iZone], integration_container, geometry_container, + solver_container, numerics_container, config_container, + surface_movement, grid_movement, FFDBox, iZone, INST_0); + } + + if (rank == MASTER_NODE){ + SetTurboPerformance(ZONE_0); + } + + } void CTurbomachineryDriver::SetMixingPlane(unsigned short donorZone){ - - unsigned short targetZone, nMarkerInt, iMarkerInt ; - nMarkerInt = config_container[donorZone]->GetnMarker_MixingPlaneInterface()/2; - - /* --- transfer the average value from the donorZone to the targetZone*/ - for (iMarkerInt = 1; iMarkerInt <= nMarkerInt; iMarkerInt++){ - for (targetZone = 0; targetZone < nZone; targetZone++) { - if (targetZone != donorZone){ - interface_container[donorZone][targetZone]->AllgatherAverage(solver_container[donorZone][INST_0][MESH_0][FLOW_SOL],solver_container[targetZone][INST_0][MESH_0][FLOW_SOL], - geometry_container[donorZone][INST_0][MESH_0],geometry_container[targetZone][INST_0][MESH_0], - config_container[donorZone], config_container[targetZone], iMarkerInt ); - } + + unsigned short targetZone, nMarkerInt, iMarkerInt ; + nMarkerInt = config_container[donorZone]->GetnMarker_MixingPlaneInterface()/2; + + /* --- transfer the average value from the donorZone to the targetZone*/ + for (iMarkerInt = 1; iMarkerInt <= nMarkerInt; iMarkerInt++){ + for (targetZone = 0; targetZone < nZone; targetZone++) { + if (targetZone != donorZone){ + interface_container[donorZone][targetZone]->AllgatherAverage(solver_container[donorZone][INST_0][MESH_0][FLOW_SOL],solver_container[targetZone][INST_0][MESH_0][FLOW_SOL], + geometry_container[donorZone][INST_0][MESH_0],geometry_container[targetZone][INST_0][MESH_0], + config_container[donorZone], config_container[targetZone], iMarkerInt ); + } + } } - } } void CTurbomachineryDriver::SetTurboPerformance(unsigned short targetZone){ - - unsigned short donorZone; - //IMPORTANT this approach of multi-zone performances rely upon the fact that turbomachinery markers follow the natural (stator-rotor) development of the real machine. - /* --- transfer the local turboperfomance quantities (for each blade) from all the donorZones to the targetZone (ZONE_0) ---*/ - for (donorZone = 1; donorZone < nZone; donorZone++) { - interface_container[donorZone][targetZone]->GatherAverageValues(solver_container[donorZone][INST_0][MESH_0][FLOW_SOL],solver_container[targetZone][INST_0][MESH_0][FLOW_SOL], donorZone); - } - - /* --- compute turboperformance for each stage and the global machine ---*/ - - output_legacy->ComputeTurboPerformance(solver_container[targetZone][INST_0][MESH_0][FLOW_SOL], geometry_container[targetZone][INST_0][MESH_0], config_container[targetZone]); - + + unsigned short donorZone; + //IMPORTANT this approach of multi-zone performances rely upon the fact that turbomachinery markers follow the natural (stator-rotor) development of the real machine. + /* --- transfer the local turboperfomance quantities (for each blade) from all the donorZones to the targetZone (ZONE_0) ---*/ + for (donorZone = 1; donorZone < nZone; donorZone++) { + interface_container[donorZone][targetZone]->GatherAverageValues(solver_container[donorZone][INST_0][MESH_0][FLOW_SOL],solver_container[targetZone][INST_0][MESH_0][FLOW_SOL], donorZone); + } + + /* --- compute turboperformance for each stage and the global machine ---*/ + + output_legacy->ComputeTurboPerformance(solver_container[targetZone][INST_0][MESH_0][FLOW_SOL], geometry_container[targetZone][INST_0][MESH_0], config_container[targetZone]); + } bool CTurbomachineryDriver::Monitor(unsigned long ExtIter) { - - su2double rot_z_ini, rot_z_final ,rot_z; - su2double outPres_ini, outPres_final, outPres; - unsigned long rampFreq, finalRamp_Iter; - unsigned short iMarker, KindBC, KindBCOption; - string Marker_Tag; - - bool print; - - /*--- Synchronization point after a single solver iteration. Compute the - wall clock time required. ---*/ - - StopTime = SU2_MPI::Wtime(); - - IterCount++; - UsedTime = (StopTime - StartTime); - - - /*--- Check if there is any change in the runtime parameters ---*/ - CConfig *runtime = nullptr; - strcpy(runtime_file_name, "runtime.dat"); - runtime = new CConfig(runtime_file_name, config_container[ZONE_0]); - runtime->SetInnerIter(ExtIter); - delete runtime; - - /*--- Update the convergence history file (serial and parallel computations). ---*/ - - for (iZone = 0; iZone < nZone; iZone++) { - for (iInst = 0; iInst < nInst[iZone]; iInst++) - output_legacy->SetConvHistory_Body(&ConvHist_file[iZone][iInst], geometry_container, solver_container, - config_container, integration_container, false, UsedTime, iZone, iInst); - } - - /*--- ROTATING FRAME Ramp: Compute the updated rotational velocity. ---*/ - if (config_container[ZONE_0]->GetGrid_Movement() && config_container[ZONE_0]->GetRampRotatingFrame()) { - rampFreq = SU2_TYPE::Int(config_container[ZONE_0]->GetRampRotatingFrame_Coeff(1)); - finalRamp_Iter = SU2_TYPE::Int(config_container[ZONE_0]->GetRampRotatingFrame_Coeff(2)); - rot_z_ini = config_container[ZONE_0]->GetRampRotatingFrame_Coeff(0); - print = false; - if(ExtIter % rampFreq == 0 && ExtIter <= finalRamp_Iter){ - - for (iZone = 0; iZone < nZone; iZone++) { - rot_z_final = config_container[iZone]->GetFinalRotation_Rate_Z(); - if(abs(rot_z_final) > 0.0){ - rot_z = rot_z_ini + ExtIter*( rot_z_final - rot_z_ini)/finalRamp_Iter; - config_container[iZone]->SetRotation_Rate(2, rot_z); - if(rank == MASTER_NODE && print && ExtIter > 0) { - cout << endl << " Updated rotating frame grid velocities"; - cout << " for zone " << iZone << "." << endl; - } - geometry_container[iZone][INST_0][MESH_0]->SetRotationalVelocity(config_container[iZone], print); - geometry_container[iZone][INST_0][MESH_0]->SetShroudVelocity(config_container[iZone]); + + su2double rot_z_ini, rot_z_final ,rot_z; + su2double outPres_ini, outPres_final, outPres; + unsigned long rampFreq, finalRamp_Iter; + unsigned short iMarker, KindBC, KindBCOption; + string Marker_Tag; + + bool print; + + /*--- Synchronization point after a single solver iteration. Compute the + wall clock time required. ---*/ + + StopTime = SU2_MPI::Wtime(); + + IterCount++; + UsedTime = (StopTime - StartTime); + + + /*--- Check if there is any change in the runtime parameters ---*/ + CConfig *runtime = nullptr; + strcpy(runtime_file_name, "runtime.dat"); + runtime = new CConfig(runtime_file_name, config_container[ZONE_0]); + runtime->SetInnerIter(ExtIter); + delete runtime; + + /*--- Update the convergence history file (serial and parallel computations). ---*/ + + for (iZone = 0; iZone < nZone; iZone++) { + for (iInst = 0; iInst < nInst[iZone]; iInst++) + output_legacy->SetConvHistory_Body(&ConvHist_file[iZone][iInst], geometry_container, solver_container, + config_container, integration_container, false, UsedTime, iZone, iInst); + } + + /*--- ROTATING FRAME Ramp: Compute the updated rotational velocity. ---*/ + if (config_container[ZONE_0]->GetGrid_Movement() && config_container[ZONE_0]->GetRampRotatingFrame()) { + rampFreq = SU2_TYPE::Int(config_container[ZONE_0]->GetRampRotatingFrame_Coeff(1)); + finalRamp_Iter = SU2_TYPE::Int(config_container[ZONE_0]->GetRampRotatingFrame_Coeff(2)); + rot_z_ini = config_container[ZONE_0]->GetRampRotatingFrame_Coeff(0); + print = false; + if(ExtIter % rampFreq == 0 && ExtIter <= finalRamp_Iter){ + + for (iZone = 0; iZone < nZone; iZone++) { + rot_z_final = config_container[iZone]->GetFinalRotation_Rate_Z(); + if(abs(rot_z_final) > 0.0){ + rot_z = rot_z_ini + ExtIter*( rot_z_final - rot_z_ini)/finalRamp_Iter; + config_container[iZone]->SetRotation_Rate(2, rot_z); + if(rank == MASTER_NODE && print && ExtIter > 0) { + cout << endl << " Updated rotating frame grid velocities"; + cout << " for zone " << iZone << "." << endl; + } + geometry_container[iZone][INST_0][MESH_0]->SetRotationalVelocity(config_container[iZone], print); + geometry_container[iZone][INST_0][MESH_0]->SetShroudVelocity(config_container[iZone]); + } + } + + for (iZone = 0; iZone < nZone; iZone++) { + geometry_container[iZone][INST_0][MESH_0]->SetAvgTurboValue(config_container[iZone], iZone, INFLOW, false); + geometry_container[iZone][INST_0][MESH_0]->SetAvgTurboValue(config_container[iZone],iZone, OUTFLOW, false); + geometry_container[iZone][INST_0][MESH_0]->GatherInOutAverageValues(config_container[iZone], false); + + } + + for (iZone = 1; iZone < nZone; iZone++) { + interface_container[iZone][ZONE_0]->GatherAverageTurboGeoValues(geometry_container[iZone][INST_0][MESH_0],geometry_container[ZONE_0][INST_0][MESH_0], iZone); + } + } - } - - for (iZone = 0; iZone < nZone; iZone++) { - geometry_container[iZone][INST_0][MESH_0]->SetAvgTurboValue(config_container[iZone], iZone, INFLOW, false); - geometry_container[iZone][INST_0][MESH_0]->SetAvgTurboValue(config_container[iZone],iZone, OUTFLOW, false); - geometry_container[iZone][INST_0][MESH_0]->GatherInOutAverageValues(config_container[iZone], false); - - } - - for (iZone = 1; iZone < nZone; iZone++) { - interface_container[iZone][ZONE_0]->GatherAverageTurboGeoValues(geometry_container[iZone][INST_0][MESH_0],geometry_container[ZONE_0][INST_0][MESH_0], iZone); - } - } - } - - - /*--- Outlet Pressure Ramp: Compute the updated rotational velocity. ---*/ - if (config_container[ZONE_0]->GetRampOutletPressure()) { - rampFreq = SU2_TYPE::Int(config_container[ZONE_0]->GetRampOutletPressure_Coeff(1)); - finalRamp_Iter = SU2_TYPE::Int(config_container[ZONE_0]->GetRampOutletPressure_Coeff(2)); - outPres_ini = config_container[ZONE_0]->GetRampOutletPressure_Coeff(0); - outPres_final = config_container[ZONE_0]->GetFinalOutletPressure(); - - if(ExtIter % rampFreq == 0 && ExtIter <= finalRamp_Iter){ - outPres = outPres_ini + ExtIter*(outPres_final - outPres_ini)/finalRamp_Iter; - if(rank == MASTER_NODE) config_container[ZONE_0]->SetMonitotOutletPressure(outPres); - - for (iZone = 0; iZone < nZone; iZone++) { - for (iMarker = 0; iMarker < config_container[iZone]->GetnMarker_All(); iMarker++) { - KindBC = config_container[iZone]->GetMarker_All_KindBC(iMarker); - switch (KindBC) { - case RIEMANN_BOUNDARY: - Marker_Tag = config_container[iZone]->GetMarker_All_TagBound(iMarker); - KindBCOption = config_container[iZone]->GetKind_Data_Riemann(Marker_Tag); - if(KindBCOption == STATIC_PRESSURE || KindBCOption == RADIAL_EQUILIBRIUM ){ - SU2_MPI::Error("Outlet pressure ramp only implemented for NRBC", CURRENT_FUNCTION); - } - break; - case GILES_BOUNDARY: - Marker_Tag = config_container[iZone]->GetMarker_All_TagBound(iMarker); - KindBCOption = config_container[iZone]->GetKind_Data_Giles(Marker_Tag); - if(KindBCOption == STATIC_PRESSURE || KindBCOption == STATIC_PRESSURE_1D || KindBCOption == RADIAL_EQUILIBRIUM ){ - config_container[iZone]->SetGiles_Var1(outPres, Marker_Tag); + + + /*--- Outlet Pressure Ramp: Compute the updated rotational velocity. ---*/ + if (config_container[ZONE_0]->GetRampOutletPressure()) { + rampFreq = SU2_TYPE::Int(config_container[ZONE_0]->GetRampOutletPressure_Coeff(1)); + finalRamp_Iter = SU2_TYPE::Int(config_container[ZONE_0]->GetRampOutletPressure_Coeff(2)); + outPres_ini = config_container[ZONE_0]->GetRampOutletPressure_Coeff(0); + outPres_final = config_container[ZONE_0]->GetFinalOutletPressure(); + + if(ExtIter % rampFreq == 0 && ExtIter <= finalRamp_Iter){ + outPres = outPres_ini + ExtIter*(outPres_final - outPres_ini)/finalRamp_Iter; + if(rank == MASTER_NODE) config_container[ZONE_0]->SetMonitotOutletPressure(outPres); + + for (iZone = 0; iZone < nZone; iZone++) { + for (iMarker = 0; iMarker < config_container[iZone]->GetnMarker_All(); iMarker++) { + KindBC = config_container[iZone]->GetMarker_All_KindBC(iMarker); + switch (KindBC) { + case RIEMANN_BOUNDARY: + Marker_Tag = config_container[iZone]->GetMarker_All_TagBound(iMarker); + KindBCOption = config_container[iZone]->GetKind_Data_Riemann(Marker_Tag); + if(KindBCOption == STATIC_PRESSURE || KindBCOption == RADIAL_EQUILIBRIUM ){ + SU2_MPI::Error("Outlet pressure ramp only implemented for NRBC", CURRENT_FUNCTION); + } + break; + case GILES_BOUNDARY: + Marker_Tag = config_container[iZone]->GetMarker_All_TagBound(iMarker); + KindBCOption = config_container[iZone]->GetKind_Data_Giles(Marker_Tag); + if(KindBCOption == STATIC_PRESSURE || KindBCOption == STATIC_PRESSURE_1D || KindBCOption == RADIAL_EQUILIBRIUM ){ + config_container[iZone]->SetGiles_Var1(outPres, Marker_Tag); + } + break; + } + } } - break; - } } - } } - } - - - /*--- Check whether the current simulation has reached the specified - convergence criteria, and set StopCalc to true, if so. ---*/ - - switch (config_container[ZONE_0]->GetKind_Solver()) { - case MAIN_SOLVER::EULER: case MAIN_SOLVER::NAVIER_STOKES: case MAIN_SOLVER::RANS: - case MAIN_SOLVER::INC_EULER: case MAIN_SOLVER::INC_NAVIER_STOKES: case MAIN_SOLVER::INC_RANS: - case MAIN_SOLVER::NEMO_EULER: case MAIN_SOLVER::NEMO_NAVIER_STOKES: - StopCalc = integration_container[ZONE_0][INST_0][FLOW_SOL]->GetConvergence(); - break; - case MAIN_SOLVER::DISC_ADJ_EULER: case MAIN_SOLVER::DISC_ADJ_NAVIER_STOKES: case MAIN_SOLVER::DISC_ADJ_RANS: - case MAIN_SOLVER::DISC_ADJ_INC_EULER: case MAIN_SOLVER::DISC_ADJ_INC_NAVIER_STOKES: case MAIN_SOLVER::DISC_ADJ_INC_RANS: - case MAIN_SOLVER::DISC_ADJ_FEM_EULER: case MAIN_SOLVER::DISC_ADJ_FEM_NS: case MAIN_SOLVER::DISC_ADJ_FEM_RANS: - StopCalc = integration_container[ZONE_0][INST_0][ADJFLOW_SOL]->GetConvergence(); - break; - default: - break; - - } - - /*--- Set StopCalc to true if max. number of iterations has been reached ---*/ - - StopCalc = StopCalc || (ExtIter == Max_Iter - 1); - - return StopCalc; - + + + /*--- Check whether the current simulation has reached the specified + convergence criteria, and set StopCalc to true, if so. ---*/ + + switch (config_container[ZONE_0]->GetKind_Solver()) { + case MAIN_SOLVER::EULER: case MAIN_SOLVER::NAVIER_STOKES: case MAIN_SOLVER::RANS: + case MAIN_SOLVER::INC_EULER: case MAIN_SOLVER::INC_NAVIER_STOKES: case MAIN_SOLVER::INC_RANS: + case MAIN_SOLVER::NEMO_EULER: case MAIN_SOLVER::NEMO_NAVIER_STOKES: + StopCalc = integration_container[ZONE_0][INST_0][FLOW_SOL]->GetConvergence(); + break; + case MAIN_SOLVER::DISC_ADJ_EULER: case MAIN_SOLVER::DISC_ADJ_NAVIER_STOKES: case MAIN_SOLVER::DISC_ADJ_RANS: + case MAIN_SOLVER::DISC_ADJ_INC_EULER: case MAIN_SOLVER::DISC_ADJ_INC_NAVIER_STOKES: case MAIN_SOLVER::DISC_ADJ_INC_RANS: + case MAIN_SOLVER::DISC_ADJ_FEM_EULER: case MAIN_SOLVER::DISC_ADJ_FEM_NS: case MAIN_SOLVER::DISC_ADJ_FEM_RANS: + StopCalc = integration_container[ZONE_0][INST_0][ADJFLOW_SOL]->GetConvergence(); + break; + default: + break; + + } + + /*--- Set StopCalc to true if max. number of iterations has been reached ---*/ + + StopCalc = StopCalc || (ExtIter == Max_Iter - 1); + + return StopCalc; + } CHBDriver::CHBDriver(char* confFile, - unsigned short val_nZone, - SU2_Comm MPICommunicator) : CFluidDriver(confFile, - val_nZone, - MPICommunicator) { - unsigned short kInst; - - nInstHB = nInst[ZONE_0]; - - D = nullptr; - /*--- allocate dynamic memory for the Harmonic Balance operator ---*/ - D = new su2double*[nInstHB]; for (kInst = 0; kInst < nInstHB; kInst++) D[kInst] = new su2double[nInstHB]; - - output_legacy = COutputFactory::CreateLegacyOutput(config_container[ZONE_0]); - - /*--- Open the convergence history file ---*/ - ConvHist_file = nullptr; - ConvHist_file = new ofstream*[nZone]; - for (iZone = 0; iZone < nZone; iZone++) { - ConvHist_file[iZone] = nullptr; - if (rank == MASTER_NODE){ - ConvHist_file[iZone] = new ofstream[nInst[iZone]]; - for (iInst = 0; iInst < nInst[iZone]; iInst++) { - output_legacy->SetConvHistory_Header(&ConvHist_file[iZone][iInst], config_container[iZone], iZone, iInst); - } - } - } - - -} + unsigned short val_nZone, + SU2_Comm MPICommunicator) : CFluidDriver(confFile, + val_nZone, + MPICommunicator) { + unsigned short kInst; + + nInstHB = nInst[ZONE_0]; + + D = nullptr; + /*--- allocate dynamic memory for the Harmonic Balance operator ---*/ + D = new su2double*[nInstHB]; for (kInst = 0; kInst < nInstHB; kInst++) D[kInst] = new su2double[nInstHB]; + + output_legacy = COutputFactory::CreateLegacyOutput(config_container[ZONE_0]); + + /*--- Open the convergence history file ---*/ + ConvHist_file = nullptr; + ConvHist_file = new ofstream*[nZone]; + for (iZone = 0; iZone < nZone; iZone++) { + ConvHist_file[iZone] = nullptr; + if (rank == MASTER_NODE){ + ConvHist_file[iZone] = new ofstream[nInst[iZone]]; + for (iInst = 0; iInst < nInst[iZone]; iInst++) { + output_legacy->SetConvHistory_Header(&ConvHist_file[iZone][iInst], config_container[iZone], iZone, iInst); + } + } + } + + + } CHBDriver::~CHBDriver(void) { - - unsigned short kInst; - - /*--- delete dynamic memory for the Harmonic Balance operator ---*/ - for (kInst = 0; kInst < nInstHB; kInst++) delete [] D[kInst]; - delete [] D; - - if (rank == MASTER_NODE){ - /*--- Close the convergence history file. ---*/ - for (iZone = 0; iZone < nZone; iZone++) { - for (iInst = 0; iInst < nInstHB; iInst++) { - ConvHist_file[iZone][iInst].close(); + + unsigned short kInst; + + /*--- delete dynamic memory for the Harmonic Balance operator ---*/ + for (kInst = 0; kInst < nInstHB; kInst++) delete [] D[kInst]; + delete [] D; + + if (rank == MASTER_NODE){ + /*--- Close the convergence history file. ---*/ + for (iZone = 0; iZone < nZone; iZone++) { + for (iInst = 0; iInst < nInstHB; iInst++) { + ConvHist_file[iZone][iInst].close(); + } + delete [] ConvHist_file[iZone]; + } + delete [] ConvHist_file; } - delete [] ConvHist_file[iZone]; - } - delete [] ConvHist_file; - } } void CHBDriver::Run() { - - /*--- Run a single iteration of a Harmonic Balance problem. Preprocess all - all zones before beginning the iteration. ---*/ - - for (iInst = 0; iInst < nInstHB; iInst++) - iteration_container[ZONE_0][iInst]->Preprocess(output_container[ZONE_0], integration_container, geometry_container, - solver_container, numerics_container, config_container, - surface_movement, grid_movement, FFDBox, ZONE_0, iInst); - - for (iInst = 0; iInst < nInstHB; iInst++) - iteration_container[ZONE_0][iInst]->Iterate(output_container[ZONE_0], integration_container, geometry_container, - solver_container, numerics_container, config_container, - surface_movement, grid_movement, FFDBox, ZONE_0, iInst); - - /*--- Update the convergence history file (serial and parallel computations). ---*/ - - for (iZone = 0; iZone < nZone; iZone++) { - for (iInst = 0; iInst < nInst[iZone]; iInst++) - output_legacy->SetConvHistory_Body(&ConvHist_file[iZone][iInst], geometry_container, solver_container, - config_container, integration_container, false, UsedTime, iZone, iInst); - } - + + /*--- Run a single iteration of a Harmonic Balance problem. Preprocess all + all zones before beginning the iteration. ---*/ + + for (iInst = 0; iInst < nInstHB; iInst++) + iteration_container[ZONE_0][iInst]->Preprocess(output_container[ZONE_0], integration_container, geometry_container, + solver_container, numerics_container, config_container, + surface_movement, grid_movement, FFDBox, ZONE_0, iInst); + + for (iInst = 0; iInst < nInstHB; iInst++) + iteration_container[ZONE_0][iInst]->Iterate(output_container[ZONE_0], integration_container, geometry_container, + solver_container, numerics_container, config_container, + surface_movement, grid_movement, FFDBox, ZONE_0, iInst); + + /*--- Update the convergence history file (serial and parallel computations). ---*/ + + for (iZone = 0; iZone < nZone; iZone++) { + for (iInst = 0; iInst < nInst[iZone]; iInst++) + output_legacy->SetConvHistory_Body(&ConvHist_file[iZone][iInst], geometry_container, solver_container, + config_container, integration_container, false, UsedTime, iZone, iInst); + } + } void CHBDriver::Update() { - - for (iInst = 0; iInst < nInstHB; iInst++) { - /*--- Compute the harmonic balance terms across all zones ---*/ - SetHarmonicBalance(iInst); - - } - - /*--- Precondition the harmonic balance source terms ---*/ - if (config_container[ZONE_0]->GetHB_Precondition() == YES) { - StabilizeHarmonicBalance(); - - } - - for (iInst = 0; iInst < nInstHB; iInst++) { - - /*--- Update the harmonic balance terms across all zones ---*/ - iteration_container[ZONE_0][iInst]->Update(output_container[ZONE_0], integration_container, geometry_container, - solver_container, numerics_container, config_container, - surface_movement, grid_movement, FFDBox, ZONE_0, iInst); - - } - + + for (iInst = 0; iInst < nInstHB; iInst++) { + /*--- Compute the harmonic balance terms across all zones ---*/ + SetHarmonicBalance(iInst); + + } + + /*--- Precondition the harmonic balance source terms ---*/ + if (config_container[ZONE_0]->GetHB_Precondition() == YES) { + StabilizeHarmonicBalance(); + + } + + for (iInst = 0; iInst < nInstHB; iInst++) { + + /*--- Update the harmonic balance terms across all zones ---*/ + iteration_container[ZONE_0][iInst]->Update(output_container[ZONE_0], integration_container, geometry_container, + solver_container, numerics_container, config_container, + surface_movement, grid_movement, FFDBox, ZONE_0, iInst); + + } + } void CHBDriver::ResetConvergence() { - - for(iInst = 0; iInst < nZone; iInst++) { - switch (config_container[ZONE_0]->GetKind_Solver()) { - - case MAIN_SOLVER::EULER: case MAIN_SOLVER::NAVIER_STOKES: case MAIN_SOLVER::RANS: - integration_container[ZONE_0][iInst][FLOW_SOL]->SetConvergence(false); - if (config_container[ZONE_0]->GetKind_Solver() == MAIN_SOLVER::RANS) integration_container[ZONE_0][iInst][TURB_SOL]->SetConvergence(false); - if(config_container[ZONE_0]->GetKind_Trans_Model() == TURB_TRANS_MODEL::LM) integration_container[ZONE_0][iInst][TRANS_SOL]->SetConvergence(false); - break; - - case MAIN_SOLVER::FEM_ELASTICITY: - integration_container[ZONE_0][iInst][FEA_SOL]->SetConvergence(false); - break; - - case MAIN_SOLVER::ADJ_EULER: case MAIN_SOLVER::ADJ_NAVIER_STOKES: case MAIN_SOLVER::ADJ_RANS: case MAIN_SOLVER::DISC_ADJ_EULER: case MAIN_SOLVER::DISC_ADJ_NAVIER_STOKES: case MAIN_SOLVER::DISC_ADJ_RANS: - integration_container[ZONE_0][iInst][ADJFLOW_SOL]->SetConvergence(false); - if( (config_container[ZONE_0]->GetKind_Solver() == MAIN_SOLVER::ADJ_RANS) || (config_container[ZONE_0]->GetKind_Solver() == MAIN_SOLVER::DISC_ADJ_RANS) ) - integration_container[ZONE_0][iInst][ADJTURB_SOL]->SetConvergence(false); - break; - - default: - SU2_MPI::Error("Harmonic Balance has not been set up for this solver.", CURRENT_FUNCTION); + + for(iInst = 0; iInst < nZone; iInst++) { + switch (config_container[ZONE_0]->GetKind_Solver()) { + + case MAIN_SOLVER::EULER: case MAIN_SOLVER::NAVIER_STOKES: case MAIN_SOLVER::RANS: + integration_container[ZONE_0][iInst][FLOW_SOL]->SetConvergence(false); + if (config_container[ZONE_0]->GetKind_Solver() == MAIN_SOLVER::RANS) integration_container[ZONE_0][iInst][TURB_SOL]->SetConvergence(false); + if(config_container[ZONE_0]->GetKind_Trans_Model() == TURB_TRANS_MODEL::LM) integration_container[ZONE_0][iInst][TRANS_SOL]->SetConvergence(false); + break; + + case MAIN_SOLVER::FEM_ELASTICITY: + integration_container[ZONE_0][iInst][FEA_SOL]->SetConvergence(false); + break; + + case MAIN_SOLVER::ADJ_EULER: case MAIN_SOLVER::ADJ_NAVIER_STOKES: case MAIN_SOLVER::ADJ_RANS: case MAIN_SOLVER::DISC_ADJ_EULER: case MAIN_SOLVER::DISC_ADJ_NAVIER_STOKES: case MAIN_SOLVER::DISC_ADJ_RANS: + integration_container[ZONE_0][iInst][ADJFLOW_SOL]->SetConvergence(false); + if( (config_container[ZONE_0]->GetKind_Solver() == MAIN_SOLVER::ADJ_RANS) || (config_container[ZONE_0]->GetKind_Solver() == MAIN_SOLVER::DISC_ADJ_RANS) ) + integration_container[ZONE_0][iInst][ADJTURB_SOL]->SetConvergence(false); + break; + + default: + SU2_MPI::Error("Harmonic Balance has not been set up for this solver.", CURRENT_FUNCTION); + } } - } - + } void CHBDriver::SetHarmonicBalance(unsigned short iInst) { - - unsigned short iVar, jInst, iMGlevel; - unsigned short nVar = solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]->GetnVar(); - unsigned long iPoint; - bool implicit = (config_container[ZONE_0]->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); - bool adjoint = (config_container[ZONE_0]->GetContinuous_Adjoint()); - if (adjoint) { - implicit = (config_container[ZONE_0]->GetKind_TimeIntScheme_AdjFlow() == EULER_IMPLICIT); - } - - unsigned long InnerIter = config_container[ZONE_0]->GetInnerIter(); - - /*--- Retrieve values from the config file ---*/ - su2double *U = new su2double[nVar]; - su2double *U_old = new su2double[nVar]; - su2double *Psi = new su2double[nVar]; - su2double *Psi_old = new su2double[nVar]; - su2double *Source = new su2double[nVar]; - su2double deltaU, deltaPsi; - - /*--- Compute period of oscillation ---*/ - su2double period = config_container[ZONE_0]->GetHarmonicBalance_Period(); - - /*--- Non-dimensionalize the input period, if necessary. */ - period /= config_container[ZONE_0]->GetTime_Ref(); - - if (InnerIter == 0) - ComputeHB_Operator(); - - /*--- Compute various source terms for explicit direct, implicit direct, and adjoint problems ---*/ - /*--- Loop over all grid levels ---*/ - for (iMGlevel = 0; iMGlevel <= config_container[ZONE_0]->GetnMGLevels(); iMGlevel++) { - - /*--- Loop over each node in the volume mesh ---*/ - for (iPoint = 0; iPoint < geometry_container[ZONE_0][iInst][iMGlevel]->GetnPoint(); iPoint++) { - - for (iVar = 0; iVar < nVar; iVar++) { - Source[iVar] = 0.0; - } - - /*--- Step across the columns ---*/ - for (jInst = 0; jInst < nInstHB; jInst++) { - - /*--- Retrieve solution at this node in current zone ---*/ - for (iVar = 0; iVar < nVar; iVar++) { - - if (!adjoint) { - U[iVar] = solver_container[ZONE_0][jInst][iMGlevel][FLOW_SOL]->GetNodes()->GetSolution(iPoint, iVar); - Source[iVar] += U[iVar]*D[iInst][jInst]; - - if (implicit) { - U_old[iVar] = solver_container[ZONE_0][jInst][iMGlevel][FLOW_SOL]->GetNodes()->GetSolution_Old(iPoint, iVar); - deltaU = U[iVar] - U_old[iVar]; - Source[iVar] += deltaU*D[iInst][jInst]; + + unsigned short iVar, jInst, iMGlevel; + unsigned short nVar = solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]->GetnVar(); + unsigned long iPoint; + bool implicit = (config_container[ZONE_0]->GetKind_TimeIntScheme_Flow() == EULER_IMPLICIT); + bool adjoint = (config_container[ZONE_0]->GetContinuous_Adjoint()); + if (adjoint) { + implicit = (config_container[ZONE_0]->GetKind_TimeIntScheme_AdjFlow() == EULER_IMPLICIT); + } + + unsigned long InnerIter = config_container[ZONE_0]->GetInnerIter(); + + /*--- Retrieve values from the config file ---*/ + su2double *U = new su2double[nVar]; + su2double *U_old = new su2double[nVar]; + su2double *Psi = new su2double[nVar]; + su2double *Psi_old = new su2double[nVar]; + su2double *Source = new su2double[nVar]; + su2double deltaU, deltaPsi; + + /*--- Compute period of oscillation ---*/ + su2double period = config_container[ZONE_0]->GetHarmonicBalance_Period(); + + /*--- Non-dimensionalize the input period, if necessary. */ + period /= config_container[ZONE_0]->GetTime_Ref(); + + if (InnerIter == 0) + ComputeHB_Operator(); + + /*--- Compute various source terms for explicit direct, implicit direct, and adjoint problems ---*/ + /*--- Loop over all grid levels ---*/ + for (iMGlevel = 0; iMGlevel <= config_container[ZONE_0]->GetnMGLevels(); iMGlevel++) { + + /*--- Loop over each node in the volume mesh ---*/ + for (iPoint = 0; iPoint < geometry_container[ZONE_0][iInst][iMGlevel]->GetnPoint(); iPoint++) { + + for (iVar = 0; iVar < nVar; iVar++) { + Source[iVar] = 0.0; } - - } - - else { - Psi[iVar] = solver_container[ZONE_0][jInst][iMGlevel][ADJFLOW_SOL]->GetNodes()->GetSolution(iPoint, iVar); - Source[iVar] += Psi[iVar]*D[jInst][iInst]; - - if (implicit) { - Psi_old[iVar] = solver_container[ZONE_0][jInst][iMGlevel][ADJFLOW_SOL]->GetNodes()->GetSolution_Old(iPoint, iVar); - deltaPsi = Psi[iVar] - Psi_old[iVar]; - Source[iVar] += deltaPsi*D[jInst][iInst]; + + /*--- Step across the columns ---*/ + for (jInst = 0; jInst < nInstHB; jInst++) { + + /*--- Retrieve solution at this node in current zone ---*/ + for (iVar = 0; iVar < nVar; iVar++) { + + if (!adjoint) { + U[iVar] = solver_container[ZONE_0][jInst][iMGlevel][FLOW_SOL]->GetNodes()->GetSolution(iPoint, iVar); + Source[iVar] += U[iVar]*D[iInst][jInst]; + + if (implicit) { + U_old[iVar] = solver_container[ZONE_0][jInst][iMGlevel][FLOW_SOL]->GetNodes()->GetSolution_Old(iPoint, iVar); + deltaU = U[iVar] - U_old[iVar]; + Source[iVar] += deltaU*D[iInst][jInst]; + } + + } + + else { + Psi[iVar] = solver_container[ZONE_0][jInst][iMGlevel][ADJFLOW_SOL]->GetNodes()->GetSolution(iPoint, iVar); + Source[iVar] += Psi[iVar]*D[jInst][iInst]; + + if (implicit) { + Psi_old[iVar] = solver_container[ZONE_0][jInst][iMGlevel][ADJFLOW_SOL]->GetNodes()->GetSolution_Old(iPoint, iVar); + deltaPsi = Psi[iVar] - Psi_old[iVar]; + Source[iVar] += deltaPsi*D[jInst][iInst]; + } + } + } + + /*--- Store sources for current row ---*/ + for (iVar = 0; iVar < nVar; iVar++) { + if (!adjoint) { + solver_container[ZONE_0][iInst][iMGlevel][FLOW_SOL]->GetNodes()->SetHarmonicBalance_Source(iPoint, iVar, Source[iVar]); + } + else { + solver_container[ZONE_0][iInst][iMGlevel][ADJFLOW_SOL]->GetNodes()->SetHarmonicBalance_Source(iPoint, iVar, Source[iVar]); + } + } + } - } - } - - /*--- Store sources for current row ---*/ - for (iVar = 0; iVar < nVar; iVar++) { - if (!adjoint) { - solver_container[ZONE_0][iInst][iMGlevel][FLOW_SOL]->GetNodes()->SetHarmonicBalance_Source(iPoint, iVar, Source[iVar]); - } - else { - solver_container[ZONE_0][iInst][iMGlevel][ADJFLOW_SOL]->GetNodes()->SetHarmonicBalance_Source(iPoint, iVar, Source[iVar]); - } } - - } } - } - - /*--- Source term for a turbulence model ---*/ - if (config_container[ZONE_0]->GetKind_Solver() == MAIN_SOLVER::RANS) { - - /*--- Extra variables needed if we have a turbulence model. ---*/ - unsigned short nVar_Turb = solver_container[ZONE_0][INST_0][MESH_0][TURB_SOL]->GetnVar(); - su2double *U_Turb = new su2double[nVar_Turb]; - su2double *Source_Turb = new su2double[nVar_Turb]; - - /*--- Loop over only the finest mesh level (turbulence is always solved - on the original grid only). ---*/ - for (iPoint = 0; iPoint < geometry_container[ZONE_0][INST_0][MESH_0]->GetnPoint(); iPoint++) { - for (iVar = 0; iVar < nVar_Turb; iVar++) Source_Turb[iVar] = 0.0; - for (jInst = 0; jInst < nInstHB; jInst++) { - - /*--- Retrieve solution at this node in current zone ---*/ - for (iVar = 0; iVar < nVar_Turb; iVar++) { - U_Turb[iVar] = solver_container[ZONE_0][jInst][MESH_0][TURB_SOL]->GetNodes()->GetSolution(iPoint, iVar); - Source_Turb[iVar] += U_Turb[iVar]*D[iInst][jInst]; + + /*--- Source term for a turbulence model ---*/ + if (config_container[ZONE_0]->GetKind_Solver() == MAIN_SOLVER::RANS) { + + /*--- Extra variables needed if we have a turbulence model. ---*/ + unsigned short nVar_Turb = solver_container[ZONE_0][INST_0][MESH_0][TURB_SOL]->GetnVar(); + su2double *U_Turb = new su2double[nVar_Turb]; + su2double *Source_Turb = new su2double[nVar_Turb]; + + /*--- Loop over only the finest mesh level (turbulence is always solved + on the original grid only). ---*/ + for (iPoint = 0; iPoint < geometry_container[ZONE_0][INST_0][MESH_0]->GetnPoint(); iPoint++) { + for (iVar = 0; iVar < nVar_Turb; iVar++) Source_Turb[iVar] = 0.0; + for (jInst = 0; jInst < nInstHB; jInst++) { + + /*--- Retrieve solution at this node in current zone ---*/ + for (iVar = 0; iVar < nVar_Turb; iVar++) { + U_Turb[iVar] = solver_container[ZONE_0][jInst][MESH_0][TURB_SOL]->GetNodes()->GetSolution(iPoint, iVar); + Source_Turb[iVar] += U_Turb[iVar]*D[iInst][jInst]; + } + } + + /*--- Store sources for current iZone ---*/ + for (iVar = 0; iVar < nVar_Turb; iVar++) + solver_container[ZONE_0][iInst][MESH_0][TURB_SOL]->GetNodes()->SetHarmonicBalance_Source(iPoint, iVar, Source_Turb[iVar]); } - } - - /*--- Store sources for current iZone ---*/ - for (iVar = 0; iVar < nVar_Turb; iVar++) - solver_container[ZONE_0][iInst][MESH_0][TURB_SOL]->GetNodes()->SetHarmonicBalance_Source(iPoint, iVar, Source_Turb[iVar]); - } - - delete [] U_Turb; - delete [] Source_Turb; - } - - delete [] Source; - delete [] U; - delete [] U_old; - delete [] Psi; - delete [] Psi_old; - + + delete [] U_Turb; + delete [] Source_Turb; + } + + delete [] Source; + delete [] U; + delete [] U_old; + delete [] Psi; + delete [] Psi_old; + } void CHBDriver::StabilizeHarmonicBalance() { + + unsigned short i, j, k, iVar, iInst, jInst, iMGlevel; + unsigned short nVar = solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]->GetnVar(); + unsigned long iPoint; + bool adjoint = (config_container[ZONE_0]->GetContinuous_Adjoint()); + + /*--- Retrieve values from the config file ---*/ + su2double *Source = new su2double[nInstHB]; + su2double *Source_old = new su2double[nInstHB]; + su2double Delta; + + su2double **Pinv = new su2double*[nInstHB]; + su2double **P = new su2double*[nInstHB]; + for (iInst = 0; iInst < nInstHB; iInst++) { + Pinv[iInst] = new su2double[nInstHB]; + P[iInst] = new su2double[nInstHB]; + } + + /*--- Loop over all grid levels ---*/ + for (iMGlevel = 0; iMGlevel <= config_container[ZONE_0]->GetnMGLevels(); iMGlevel++) { + + /*--- Loop over each node in the volume mesh ---*/ + for (iPoint = 0; iPoint < geometry_container[ZONE_0][INST_0][iMGlevel]->GetnPoint(); iPoint++) { + + /*--- Get time step for current node ---*/ + Delta = solver_container[ZONE_0][INST_0][iMGlevel][FLOW_SOL]->GetNodes()->GetDelta_Time(iPoint); + + /*--- Setup stabilization matrix for this node ---*/ + for (iInst = 0; iInst < nInstHB; iInst++) { + for (jInst = 0; jInst < nInstHB; jInst++) { + if (jInst == iInst ) { + Pinv[iInst][jInst] = 1.0 + Delta*D[iInst][jInst]; + } + else { + Pinv[iInst][jInst] = Delta*D[iInst][jInst]; + } + } + } + + /*--- Invert stabilization matrix Pinv with Gauss elimination---*/ + + /*-- A temporary matrix to hold the inverse, dynamically allocated ---*/ + su2double **temp = new su2double*[nInstHB]; + for (i = 0; i < nInstHB; i++) { + temp[i] = new su2double[2 * nInstHB]; + } + + /*--- Copy the desired matrix into the temporary matrix ---*/ + for (i = 0; i < nInstHB; i++) { + for (j = 0; j < nInstHB; j++) { + temp[i][j] = Pinv[i][j]; + temp[i][nInstHB + j] = 0; + } + temp[i][nInstHB + i] = 1; + } + + su2double max_val; + unsigned short max_idx; + + /*--- Pivot each column such that the largest number possible divides the other rows ---*/ + for (k = 0; k < nInstHB - 1; k++) { + max_idx = k; + max_val = abs(temp[k][k]); + /*--- Find the largest value (pivot) in the column ---*/ + for (j = k; j < nInstHB; j++) { + if (abs(temp[j][k]) > max_val) { + max_idx = j; + max_val = abs(temp[j][k]); + } + } + + /*--- Move the row with the highest value up ---*/ + for (j = 0; j < (nInstHB * 2); j++) { + su2double d = temp[k][j]; + temp[k][j] = temp[max_idx][j]; + temp[max_idx][j] = d; + } + /*--- Subtract the moved row from all other rows ---*/ + for (i = k + 1; i < nInstHB; i++) { + su2double c = temp[i][k] / temp[k][k]; + for (j = 0; j < (nInstHB * 2); j++) { + temp[i][j] = temp[i][j] - temp[k][j] * c; + } + } + } + + /*--- Back-substitution ---*/ + for (k = nInstHB - 1; k > 0; k--) { + if (temp[k][k] != su2double(0.0)) { + for (int i = k - 1; i > -1; i--) { + su2double c = temp[i][k] / temp[k][k]; + for (j = 0; j < (nInstHB * 2); j++) { + temp[i][j] = temp[i][j] - temp[k][j] * c; + } + } + } + } + + /*--- Normalize the inverse ---*/ + for (i = 0; i < nInstHB; i++) { + su2double c = temp[i][i]; + for (j = 0; j < nInstHB; j++) { + temp[i][j + nInstHB] = temp[i][j + nInstHB] / c; + } + } + + /*--- Copy the inverse back to the main program flow ---*/ + for (i = 0; i < nInstHB; i++) { + for (j = 0; j < nInstHB; j++) { + P[i][j] = temp[i][j + nInstHB]; + } + } + + /*--- Delete dynamic template ---*/ + for (iInst = 0; iInst < nInstHB; iInst++) { + delete[] temp[iInst]; + } + delete[] temp; + + /*--- Loop through variables to precondition ---*/ + for (iVar = 0; iVar < nVar; iVar++) { + + /*--- Get current source terms (not yet preconditioned) and zero source array to prepare preconditioning ---*/ + for (iInst = 0; iInst < nInstHB; iInst++) { + Source_old[iInst] = solver_container[ZONE_0][iInst][iMGlevel][FLOW_SOL]->GetNodes()->GetHarmonicBalance_Source(iPoint, iVar); + Source[iInst] = 0; + } + + /*--- Step through columns ---*/ + for (iInst = 0; iInst < nInstHB; iInst++) { + for (jInst = 0; jInst < nInstHB; jInst++) { + Source[iInst] += P[iInst][jInst]*Source_old[jInst]; + } + + /*--- Store updated source terms for current node ---*/ + if (!adjoint) { + solver_container[ZONE_0][iInst][iMGlevel][FLOW_SOL]->GetNodes()->SetHarmonicBalance_Source(iPoint, iVar, Source[iInst]); + } + else { + solver_container[ZONE_0][iInst][iMGlevel][ADJFLOW_SOL]->GetNodes()->SetHarmonicBalance_Source(iPoint, iVar, Source[iInst]); + } + } + + } + } + } + + /*--- Deallocate dynamic memory ---*/ + for (iInst = 0; iInst < nInstHB; iInst++){ + delete [] P[iInst]; + delete [] Pinv[iInst]; + } + delete [] P; + delete [] Pinv; + delete [] Source; + delete [] Source_old; + +} - unsigned short i, j, k, iVar, iInst, jInst, iMGlevel; - unsigned short nVar = solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]->GetnVar(); - unsigned long iPoint; - bool adjoint = (config_container[ZONE_0]->GetContinuous_Adjoint()); - - /*--- Retrieve values from the config file ---*/ - su2double *Source = new su2double[nInstHB]; - su2double *Source_old = new su2double[nInstHB]; - su2double Delta; - - su2double **Pinv = new su2double*[nInstHB]; - su2double **P = new su2double*[nInstHB]; - for (iInst = 0; iInst < nInstHB; iInst++) { - Pinv[iInst] = new su2double[nInstHB]; - P[iInst] = new su2double[nInstHB]; - } - - /*--- Loop over all grid levels ---*/ - for (iMGlevel = 0; iMGlevel <= config_container[ZONE_0]->GetnMGLevels(); iMGlevel++) { - - /*--- Loop over each node in the volume mesh ---*/ - for (iPoint = 0; iPoint < geometry_container[ZONE_0][INST_0][iMGlevel]->GetnPoint(); iPoint++) { - - /*--- Get time step for current node ---*/ - Delta = solver_container[ZONE_0][INST_0][iMGlevel][FLOW_SOL]->GetNodes()->GetDelta_Time(iPoint); - - /*--- Setup stabilization matrix for this node ---*/ - for (iInst = 0; iInst < nInstHB; iInst++) { - for (jInst = 0; jInst < nInstHB; jInst++) { - if (jInst == iInst ) { - Pinv[iInst][jInst] = 1.0 + Delta*D[iInst][jInst]; - } - else { - Pinv[iInst][jInst] = Delta*D[iInst][jInst]; - } - } - } - - /*--- Invert stabilization matrix Pinv with Gauss elimination---*/ - - /*-- A temporary matrix to hold the inverse, dynamically allocated ---*/ - su2double **temp = new su2double*[nInstHB]; - for (i = 0; i < nInstHB; i++) { - temp[i] = new su2double[2 * nInstHB]; - } - - /*--- Copy the desired matrix into the temporary matrix ---*/ - for (i = 0; i < nInstHB; i++) { +void CHBDriver::ComputeHB_Operator() { + + const complex J(0.0,1.0); + unsigned short i, j, k, iInst; + + su2double *Omega_HB = new su2double[nInstHB]; + complex **E = new complex*[nInstHB]; + complex **Einv = new complex*[nInstHB]; + complex **DD = new complex*[nInstHB]; + for (iInst = 0; iInst < nInstHB; iInst++) { + E[iInst] = new complex[nInstHB]; + Einv[iInst] = new complex[nInstHB]; + DD[iInst] = new complex[nInstHB]; + } + + /*--- Get simualation period from config file ---*/ + su2double Period = config_container[ZONE_0]->GetHarmonicBalance_Period(); + + /*--- Non-dimensionalize the input period, if necessary. */ + Period /= config_container[ZONE_0]->GetTime_Ref(); + + /*--- Build the array containing the selected frequencies to solve ---*/ + for (iInst = 0; iInst < nInstHB; iInst++) { + Omega_HB[iInst] = config_container[ZONE_0]->GetOmega_HB()[iInst]; + Omega_HB[iInst] /= config_container[ZONE_0]->GetOmega_Ref(); //TODO: check + } + + /*--- Build the diagonal matrix of the frequencies DD ---*/ + for (i = 0; i < nInstHB; i++) { + for (k = 0; k < nInstHB; k++) { + if (k == i ) { + DD[i][k] = J*Omega_HB[k]; + } + } + } + + + /*--- Build the harmonic balance inverse matrix ---*/ + for (i = 0; i < nInstHB; i++) { + for (k = 0; k < nInstHB; k++) { + Einv[i][k] = complex(cos(Omega_HB[k]*(i*Period/nInstHB))) + J*complex(sin(Omega_HB[k]*(i*Period/nInstHB))); + } + } + + /*--- Invert inverse harmonic balance Einv with Gauss elimination ---*/ + + /*-- A temporary matrix to hold the inverse, dynamically allocated ---*/ + complex **temp = new complex*[nInstHB]; + for (i = 0; i < nInstHB; i++) { + temp[i] = new complex[2 * nInstHB]; + } + + /*--- Copy the desired matrix into the temporary matrix ---*/ + for (i = 0; i < nInstHB; i++) { for (j = 0; j < nInstHB; j++) { - temp[i][j] = Pinv[i][j]; - temp[i][nInstHB + j] = 0; + temp[i][j] = Einv[i][j]; + temp[i][nInstHB + j] = 0; } temp[i][nInstHB + i] = 1; - } - - su2double max_val; - unsigned short max_idx; - - /*--- Pivot each column such that the largest number possible divides the other rows ---*/ - for (k = 0; k < nInstHB - 1; k++) { + } + + su2double max_val; + unsigned short max_idx; + + /*--- Pivot each column such that the largest number possible divides the other rows ---*/ + for (k = 0; k < nInstHB - 1; k++) { max_idx = k; max_val = abs(temp[k][k]); /*--- Find the largest value (pivot) in the column ---*/ for (j = k; j < nInstHB; j++) { - if (abs(temp[j][k]) > max_val) { - max_idx = j; - max_val = abs(temp[j][k]); - } + if (abs(temp[j][k]) > max_val) { + max_idx = j; + max_val = abs(temp[j][k]); + } } - /*--- Move the row with the highest value up ---*/ for (j = 0; j < (nInstHB * 2); j++) { - su2double d = temp[k][j]; - temp[k][j] = temp[max_idx][j]; - temp[max_idx][j] = d; + complex d = temp[k][j]; + temp[k][j] = temp[max_idx][j]; + temp[max_idx][j] = d; } /*--- Subtract the moved row from all other rows ---*/ for (i = k + 1; i < nInstHB; i++) { - su2double c = temp[i][k] / temp[k][k]; - for (j = 0; j < (nInstHB * 2); j++) { - temp[i][j] = temp[i][j] - temp[k][j] * c; - } - } - } - - /*--- Back-substitution ---*/ - for (k = nInstHB - 1; k > 0; k--) { - if (temp[k][k] != su2double(0.0)) { - for (int i = k - 1; i > -1; i--) { - su2double c = temp[i][k] / temp[k][k]; + complex c = temp[i][k] / temp[k][k]; for (j = 0; j < (nInstHB * 2); j++) { - temp[i][j] = temp[i][j] - temp[k][j] * c; + temp[i][j] = temp[i][j] - temp[k][j] * c; } - } } - } - - /*--- Normalize the inverse ---*/ - for (i = 0; i < nInstHB; i++) { - su2double c = temp[i][i]; + } + /*--- Back-substitution ---*/ + for (k = nInstHB - 1; k > 0; k--) { + if (temp[k][k] != complex(0.0)) { + for (int i = k - 1; i > -1; i--) { + complex c = temp[i][k] / temp[k][k]; + for (j = 0; j < (nInstHB * 2); j++) { + temp[i][j] = temp[i][j] - temp[k][j] * c; + } + } + } + } + /*--- Normalize the inverse ---*/ + for (i = 0; i < nInstHB; i++) { + complex c = temp[i][i]; for (j = 0; j < nInstHB; j++) { - temp[i][j + nInstHB] = temp[i][j + nInstHB] / c; + temp[i][j + nInstHB] = temp[i][j + nInstHB] / c; } - } - - /*--- Copy the inverse back to the main program flow ---*/ - for (i = 0; i < nInstHB; i++) { + } + /*--- Copy the inverse back to the main program flow ---*/ + for (i = 0; i < nInstHB; i++) { for (j = 0; j < nInstHB; j++) { - P[i][j] = temp[i][j + nInstHB]; + E[i][j] = temp[i][j + nInstHB]; } - } - - /*--- Delete dynamic template ---*/ - for (iInst = 0; iInst < nInstHB; iInst++) { - delete[] temp[iInst]; - } - delete[] temp; - - /*--- Loop through variables to precondition ---*/ - for (iVar = 0; iVar < nVar; iVar++) { - - /*--- Get current source terms (not yet preconditioned) and zero source array to prepare preconditioning ---*/ - for (iInst = 0; iInst < nInstHB; iInst++) { - Source_old[iInst] = solver_container[ZONE_0][iInst][iMGlevel][FLOW_SOL]->GetNodes()->GetHarmonicBalance_Source(iPoint, iVar); - Source[iInst] = 0; + } + /*--- Delete dynamic template ---*/ + for (i = 0; i < nInstHB; i++) { + delete[] temp[i]; + } + delete[] temp; + + + /*--- Temporary matrix for performing product ---*/ + complex **Temp = new complex*[nInstHB]; + + /*--- Temporary complex HB operator ---*/ + complex **Dcpx = new complex*[nInstHB]; + + for (iInst = 0; iInst < nInstHB; iInst++){ + Temp[iInst] = new complex[nInstHB]; + Dcpx[iInst] = new complex[nInstHB]; + } + + + /*--- Calculation of the HB operator matrix ---*/ + for (int row = 0; row < nInstHB; row++) { + for (int col = 0; col < nInstHB; col++) { + for (int inner = 0; inner < nInstHB; inner++) { + Temp[row][col] += Einv[row][inner] * DD[inner][col]; + } } - - /*--- Step through columns ---*/ - for (iInst = 0; iInst < nInstHB; iInst++) { - for (jInst = 0; jInst < nInstHB; jInst++) { - Source[iInst] += P[iInst][jInst]*Source_old[jInst]; - } - - /*--- Store updated source terms for current node ---*/ - if (!adjoint) { - solver_container[ZONE_0][iInst][iMGlevel][FLOW_SOL]->GetNodes()->SetHarmonicBalance_Source(iPoint, iVar, Source[iInst]); - } - else { - solver_container[ZONE_0][iInst][iMGlevel][ADJFLOW_SOL]->GetNodes()->SetHarmonicBalance_Source(iPoint, iVar, Source[iInst]); - } + } + + unsigned short row, col, inner; + + for (row = 0; row < nInstHB; row++) { + for (col = 0; col < nInstHB; col++) { + for (inner = 0; inner < nInstHB; inner++) { + Dcpx[row][col] += Temp[row][inner] * E[inner][col]; + } } - - } } - } - - /*--- Deallocate dynamic memory ---*/ - for (iInst = 0; iInst < nInstHB; iInst++){ - delete [] P[iInst]; - delete [] Pinv[iInst]; - } - delete [] P; - delete [] Pinv; - delete [] Source; - delete [] Source_old; - -} - -void CHBDriver::ComputeHB_Operator() { - - const complex J(0.0,1.0); - unsigned short i, j, k, iInst; - - su2double *Omega_HB = new su2double[nInstHB]; - complex **E = new complex*[nInstHB]; - complex **Einv = new complex*[nInstHB]; - complex **DD = new complex*[nInstHB]; - for (iInst = 0; iInst < nInstHB; iInst++) { - E[iInst] = new complex[nInstHB]; - Einv[iInst] = new complex[nInstHB]; - DD[iInst] = new complex[nInstHB]; - } - - /*--- Get simualation period from config file ---*/ - su2double Period = config_container[ZONE_0]->GetHarmonicBalance_Period(); - - /*--- Non-dimensionalize the input period, if necessary. */ - Period /= config_container[ZONE_0]->GetTime_Ref(); - - /*--- Build the array containing the selected frequencies to solve ---*/ - for (iInst = 0; iInst < nInstHB; iInst++) { - Omega_HB[iInst] = config_container[ZONE_0]->GetOmega_HB()[iInst]; - Omega_HB[iInst] /= config_container[ZONE_0]->GetOmega_Ref(); //TODO: check - } - - /*--- Build the diagonal matrix of the frequencies DD ---*/ - for (i = 0; i < nInstHB; i++) { - for (k = 0; k < nInstHB; k++) { - if (k == i ) { - DD[i][k] = J*Omega_HB[k]; - } - } - } - - - /*--- Build the harmonic balance inverse matrix ---*/ - for (i = 0; i < nInstHB; i++) { - for (k = 0; k < nInstHB; k++) { - Einv[i][k] = complex(cos(Omega_HB[k]*(i*Period/nInstHB))) + J*complex(sin(Omega_HB[k]*(i*Period/nInstHB))); - } - } - - /*--- Invert inverse harmonic balance Einv with Gauss elimination ---*/ - - /*-- A temporary matrix to hold the inverse, dynamically allocated ---*/ - complex **temp = new complex*[nInstHB]; - for (i = 0; i < nInstHB; i++) { - temp[i] = new complex[2 * nInstHB]; - } - - /*--- Copy the desired matrix into the temporary matrix ---*/ - for (i = 0; i < nInstHB; i++) { - for (j = 0; j < nInstHB; j++) { - temp[i][j] = Einv[i][j]; - temp[i][nInstHB + j] = 0; - } - temp[i][nInstHB + i] = 1; - } - - su2double max_val; - unsigned short max_idx; - - /*--- Pivot each column such that the largest number possible divides the other rows ---*/ - for (k = 0; k < nInstHB - 1; k++) { - max_idx = k; - max_val = abs(temp[k][k]); - /*--- Find the largest value (pivot) in the column ---*/ - for (j = k; j < nInstHB; j++) { - if (abs(temp[j][k]) > max_val) { - max_idx = j; - max_val = abs(temp[j][k]); - } - } - /*--- Move the row with the highest value up ---*/ - for (j = 0; j < (nInstHB * 2); j++) { - complex d = temp[k][j]; - temp[k][j] = temp[max_idx][j]; - temp[max_idx][j] = d; - } - /*--- Subtract the moved row from all other rows ---*/ - for (i = k + 1; i < nInstHB; i++) { - complex c = temp[i][k] / temp[k][k]; - for (j = 0; j < (nInstHB * 2); j++) { - temp[i][j] = temp[i][j] - temp[k][j] * c; - } - } - } - /*--- Back-substitution ---*/ - for (k = nInstHB - 1; k > 0; k--) { - if (temp[k][k] != complex(0.0)) { - for (int i = k - 1; i > -1; i--) { - complex c = temp[i][k] / temp[k][k]; - for (j = 0; j < (nInstHB * 2); j++) { - temp[i][j] = temp[i][j] - temp[k][j] * c; - } - } - } - } - /*--- Normalize the inverse ---*/ - for (i = 0; i < nInstHB; i++) { - complex c = temp[i][i]; - for (j = 0; j < nInstHB; j++) { - temp[i][j + nInstHB] = temp[i][j + nInstHB] / c; - } - } - /*--- Copy the inverse back to the main program flow ---*/ - for (i = 0; i < nInstHB; i++) { - for (j = 0; j < nInstHB; j++) { - E[i][j] = temp[i][j + nInstHB]; - } - } - /*--- Delete dynamic template ---*/ - for (i = 0; i < nInstHB; i++) { - delete[] temp[i]; - } - delete[] temp; - - - /*--- Temporary matrix for performing product ---*/ - complex **Temp = new complex*[nInstHB]; - - /*--- Temporary complex HB operator ---*/ - complex **Dcpx = new complex*[nInstHB]; - - for (iInst = 0; iInst < nInstHB; iInst++){ - Temp[iInst] = new complex[nInstHB]; - Dcpx[iInst] = new complex[nInstHB]; - } - - - /*--- Calculation of the HB operator matrix ---*/ - for (int row = 0; row < nInstHB; row++) { - for (int col = 0; col < nInstHB; col++) { - for (int inner = 0; inner < nInstHB; inner++) { - Temp[row][col] += Einv[row][inner] * DD[inner][col]; - } - } - } - - unsigned short row, col, inner; - - for (row = 0; row < nInstHB; row++) { - for (col = 0; col < nInstHB; col++) { - for (inner = 0; inner < nInstHB; inner++) { - Dcpx[row][col] += Temp[row][inner] * E[inner][col]; - } - } - } - - /*--- Take just the real part of the HB operator matrix ---*/ - for (i = 0; i < nInstHB; i++) { - for (k = 0; k < nInstHB; k++) { - D[i][k] = real(Dcpx[i][k]); - } - } - - /*--- Deallocate dynamic memory ---*/ - for (iInst = 0; iInst < nInstHB; iInst++){ - delete [] E[iInst]; - delete [] Einv[iInst]; - delete [] DD[iInst]; - delete [] Temp[iInst]; - delete [] Dcpx[iInst]; - } - delete [] E; - delete [] Einv; - delete [] DD; - delete [] Temp; - delete [] Dcpx; - delete [] Omega_HB; - + + /*--- Take just the real part of the HB operator matrix ---*/ + for (i = 0; i < nInstHB; i++) { + for (k = 0; k < nInstHB; k++) { + D[i][k] = real(Dcpx[i][k]); + } + } + + /*--- Deallocate dynamic memory ---*/ + for (iInst = 0; iInst < nInstHB; iInst++){ + delete [] E[iInst]; + delete [] Einv[iInst]; + delete [] DD[iInst]; + delete [] Temp[iInst]; + delete [] Dcpx[iInst]; + } + delete [] E; + delete [] Einv; + delete [] DD; + delete [] Temp; + delete [] Dcpx; + delete [] Omega_HB; + } diff --git a/SU2_CFD/src/python_wrapper_structure.cpp b/SU2_CFD/src/python_wrapper_structure.cpp index 2f85546f4d3..ba6a563c5b0 100644 --- a/SU2_CFD/src/python_wrapper_structure.cpp +++ b/SU2_CFD/src/python_wrapper_structure.cpp @@ -31,32 +31,32 @@ #include "../../Common/include/toolboxes/geometry_toolbox.hpp" void CDriver::PythonInterface_Preprocessing(CConfig **config, CGeometry ****geometry, CSolver *****solver){ - - int rank = MASTER_NODE; - SU2_MPI::Comm_rank(SU2_MPI::GetComm(), &rank); - - /* --- Initialize boundary conditions customization, this is achieve through the Python wrapper --- */ - for(iZone=0; iZone < nZone; iZone++){ - - if (config[iZone]->GetnMarker_PyCustom() > 0){ - - if (rank == MASTER_NODE) cout << endl << "----------------- Python Interface Preprocessing ( Zone "<< iZone <<" ) -----------------" << endl; - - if (rank == MASTER_NODE) cout << "Setting customized boundary conditions for zone " << iZone << endl; - for (iMesh = 0; iMesh <= config[iZone]->GetnMGLevels(); iMesh++) { - geometry[iZone][INST_0][iMesh]->SetCustomBoundary(config[iZone]); - } - geometry[iZone][INST_0][MESH_0]->UpdateCustomBoundaryConditions(geometry[iZone][INST_0], config[iZone]); - - if ((config[iZone]->GetKind_Solver() == MAIN_SOLVER::EULER) || - (config[iZone]->GetKind_Solver() == MAIN_SOLVER::NAVIER_STOKES) || - (config[iZone]->GetKind_Solver() == MAIN_SOLVER::RANS)) { - - solver[iZone][INST_0][MESH_0][FLOW_SOL]->UpdateCustomBoundaryConditions(geometry[iZone][INST_0], config[iZone]); - } + + int rank = MASTER_NODE; + SU2_MPI::Comm_rank(SU2_MPI::GetComm(), &rank); + + /* --- Initialize boundary conditions customization, this is achieve through the Python wrapper --- */ + for(iZone=0; iZone < nZone; iZone++){ + + if (config[iZone]->GetnMarker_PyCustom() > 0){ + + if (rank == MASTER_NODE) cout << endl << "----------------- Python Interface Preprocessing ( Zone "<< iZone <<" ) -----------------" << endl; + + if (rank == MASTER_NODE) cout << "Setting customized boundary conditions for zone " << iZone << endl; + for (iMesh = 0; iMesh <= config[iZone]->GetnMGLevels(); iMesh++) { + geometry[iZone][INST_0][iMesh]->SetCustomBoundary(config[iZone]); + } + geometry[iZone][INST_0][MESH_0]->UpdateCustomBoundaryConditions(geometry[iZone][INST_0], config[iZone]); + + if ((config[iZone]->GetKind_Solver() == MAIN_SOLVER::EULER) || + (config[iZone]->GetKind_Solver() == MAIN_SOLVER::NAVIER_STOKES) || + (config[iZone]->GetKind_Solver() == MAIN_SOLVER::RANS)) { + + solver[iZone][INST_0][MESH_0][FLOW_SOL]->UpdateCustomBoundaryConditions(geometry[iZone][INST_0], config[iZone]); + } + } } - } - + } ///////////////////////////////////////////////////////////////////////////// @@ -64,106 +64,106 @@ void CDriver::PythonInterface_Preprocessing(CConfig **config, CGeometry ****geom ///////////////////////////////////////////////////////////////////////////// passivedouble CDriver::Get_Drag() const { - - unsigned short val_iZone = ZONE_0; - unsigned short FinestMesh = config_container[val_iZone]->GetFinestMesh(); - su2double CDrag, factor, val_Drag; - - /*--- Calculate drag force based on drag coefficient ---*/ - factor = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetAeroCoeffsReferenceForce(); - CDrag = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetTotal_CD(); - - val_Drag = CDrag*factor; - - return SU2_TYPE::GetValue(val_Drag); + + unsigned short val_iZone = ZONE_0; + unsigned short FinestMesh = config_container[val_iZone]->GetFinestMesh(); + su2double CDrag, factor, val_Drag; + + /*--- Calculate drag force based on drag coefficient ---*/ + factor = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetAeroCoeffsReferenceForce(); + CDrag = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetTotal_CD(); + + val_Drag = CDrag*factor; + + return SU2_TYPE::GetValue(val_Drag); } passivedouble CDriver::Get_Lift() const { - - unsigned short val_iZone = ZONE_0; - unsigned short FinestMesh = config_container[val_iZone]->GetFinestMesh(); - su2double CLift, factor, val_Lift; - - /*--- Calculate drag force based on drag coefficient ---*/ - factor = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetAeroCoeffsReferenceForce(); - CLift = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetTotal_CL(); - - val_Lift = CLift*factor; - - return SU2_TYPE::GetValue(val_Lift); + + unsigned short val_iZone = ZONE_0; + unsigned short FinestMesh = config_container[val_iZone]->GetFinestMesh(); + su2double CLift, factor, val_Lift; + + /*--- Calculate drag force based on drag coefficient ---*/ + factor = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetAeroCoeffsReferenceForce(); + CLift = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetTotal_CL(); + + val_Lift = CLift*factor; + + return SU2_TYPE::GetValue(val_Lift); } passivedouble CDriver::Get_Mx() const { - - unsigned short val_iZone = ZONE_0; - unsigned short FinestMesh = config_container[val_iZone]->GetFinestMesh(); - su2double CMx, RefLengthCoeff, factor, val_Mx; - - RefLengthCoeff = config_container[val_iZone]->GetRefLength(); - - /*--- Calculate moment around x-axis based on coefficients ---*/ - factor = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetAeroCoeffsReferenceForce(); - CMx = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetTotal_CMx(); - - val_Mx = CMx*factor*RefLengthCoeff; - - return SU2_TYPE::GetValue(val_Mx); + + unsigned short val_iZone = ZONE_0; + unsigned short FinestMesh = config_container[val_iZone]->GetFinestMesh(); + su2double CMx, RefLengthCoeff, factor, val_Mx; + + RefLengthCoeff = config_container[val_iZone]->GetRefLength(); + + /*--- Calculate moment around x-axis based on coefficients ---*/ + factor = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetAeroCoeffsReferenceForce(); + CMx = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetTotal_CMx(); + + val_Mx = CMx*factor*RefLengthCoeff; + + return SU2_TYPE::GetValue(val_Mx); } passivedouble CDriver::Get_My() const { - - unsigned short val_iZone = ZONE_0; - unsigned short FinestMesh = config_container[val_iZone]->GetFinestMesh(); - su2double CMy, RefLengthCoeff, factor, val_My; - - RefLengthCoeff = config_container[val_iZone]->GetRefLength(); - - /*--- Calculate moment around x-axis based on coefficients ---*/ - factor = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetAeroCoeffsReferenceForce(); - CMy = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetTotal_CMy(); - - val_My = CMy*factor*RefLengthCoeff; - - return SU2_TYPE::GetValue(val_My); + + unsigned short val_iZone = ZONE_0; + unsigned short FinestMesh = config_container[val_iZone]->GetFinestMesh(); + su2double CMy, RefLengthCoeff, factor, val_My; + + RefLengthCoeff = config_container[val_iZone]->GetRefLength(); + + /*--- Calculate moment around x-axis based on coefficients ---*/ + factor = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetAeroCoeffsReferenceForce(); + CMy = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetTotal_CMy(); + + val_My = CMy*factor*RefLengthCoeff; + + return SU2_TYPE::GetValue(val_My); } passivedouble CDriver::Get_Mz() const { - - unsigned short val_iZone = ZONE_0; - unsigned short FinestMesh = config_container[val_iZone]->GetFinestMesh(); - su2double CMz, RefLengthCoeff, factor, val_Mz; - - RefLengthCoeff = config_container[val_iZone]->GetRefLength(); - - /*--- Calculate moment around z-axis based on coefficients ---*/ - factor = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetAeroCoeffsReferenceForce(); - CMz = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetTotal_CMz(); - - val_Mz = CMz*factor*RefLengthCoeff; - - return SU2_TYPE::GetValue(val_Mz); + + unsigned short val_iZone = ZONE_0; + unsigned short FinestMesh = config_container[val_iZone]->GetFinestMesh(); + su2double CMz, RefLengthCoeff, factor, val_Mz; + + RefLengthCoeff = config_container[val_iZone]->GetRefLength(); + + /*--- Calculate moment around z-axis based on coefficients ---*/ + factor = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetAeroCoeffsReferenceForce(); + CMz = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetTotal_CMz(); + + val_Mz = CMz*factor*RefLengthCoeff; + + return SU2_TYPE::GetValue(val_Mz); } passivedouble CDriver::Get_DragCoeff() const { - - unsigned short val_iZone = ZONE_0; - unsigned short FinestMesh = config_container[val_iZone]->GetFinestMesh(); - su2double CDrag; - - CDrag = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetTotal_CD(); - - return SU2_TYPE::GetValue(CDrag); + + unsigned short val_iZone = ZONE_0; + unsigned short FinestMesh = config_container[val_iZone]->GetFinestMesh(); + su2double CDrag; + + CDrag = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetTotal_CD(); + + return SU2_TYPE::GetValue(CDrag); } passivedouble CDriver::Get_LiftCoeff() const { - - unsigned short val_iZone = ZONE_0; - unsigned short FinestMesh = config_container[val_iZone]->GetFinestMesh(); - su2double CLift; - - CLift = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetTotal_CL(); - - return SU2_TYPE::GetValue(CLift); + + unsigned short val_iZone = ZONE_0; + unsigned short FinestMesh = config_container[val_iZone]->GetFinestMesh(); + su2double CLift; + + CLift = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetTotal_CL(); + + return SU2_TYPE::GetValue(CLift); } ////////////////////////////////////////////////////////////////////////////////// @@ -171,23 +171,23 @@ passivedouble CDriver::Get_LiftCoeff() const { ////////////////////////////////////////////////////////////////////////////////// unsigned long CDriver::GetnTimeIter() const { - - return config_container[ZONE_0]->GetnTime_Iter(); + + return config_container[ZONE_0]->GetnTime_Iter(); } unsigned long CDriver::GetTime_Iter() const{ - - return TimeIter; + + return TimeIter; } passivedouble CDriver::GetUnsteady_TimeStep() const { - - return SU2_TYPE::GetValue(config_container[ZONE_0]->GetTime_Step()); + + return SU2_TYPE::GetValue(config_container[ZONE_0]->GetTime_Step()); } string CDriver::GetSurfaceFileName() const { - - return config_container[ZONE_0]->GetSurfCoeff_FileName(); + + return config_container[ZONE_0]->GetSurfCoeff_FileName(); } /////////////////////////////////////////////////////////////////////////////// @@ -195,125 +195,125 @@ string CDriver::GetSurfaceFileName() const { /////////////////////////////////////////////////////////////////////////////// passivedouble CDriver::GetVertexTemperature(unsigned short iMarker, unsigned long iVertex) const { - - unsigned long iPoint; - su2double vertexWallTemp(0.0); - - bool compressible = (config_container[ZONE_0]->GetKind_Regime() == ENUM_REGIME::COMPRESSIBLE); - - iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); - - if(geometry_container[ZONE_0][INST_0][MESH_0]->nodes->GetDomain(iPoint) && compressible){ - vertexWallTemp = solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]->GetNodes()->GetTemperature(iPoint); - } - - return SU2_TYPE::GetValue(vertexWallTemp); - + + unsigned long iPoint; + su2double vertexWallTemp(0.0); + + bool compressible = (config_container[ZONE_0]->GetKind_Regime() == ENUM_REGIME::COMPRESSIBLE); + + iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); + + if(geometry_container[ZONE_0][INST_0][MESH_0]->nodes->GetDomain(iPoint) && compressible){ + vertexWallTemp = solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]->GetNodes()->GetTemperature(iPoint); + } + + return SU2_TYPE::GetValue(vertexWallTemp); + } void CDriver::SetVertexTemperature(unsigned short iMarker, unsigned long iVertex, passivedouble val_WallTemp){ - - geometry_container[ZONE_0][INST_0][MESH_0]->SetCustomBoundaryTemperature(iMarker, iVertex, val_WallTemp); + + geometry_container[ZONE_0][INST_0][MESH_0]->SetCustomBoundaryTemperature(iMarker, iVertex, val_WallTemp); } vector CDriver::GetVertexHeatFluxes(unsigned short iMarker, unsigned long iVertex) const { - - unsigned long iPoint; - unsigned short iDim; - su2double Prandtl_Lam = config_container[ZONE_0]->GetPrandtl_Lam(); - su2double Gas_Constant = config_container[ZONE_0]->GetGas_ConstantND(); - su2double Gamma = config_container[ZONE_0]->GetGamma(); - su2double Gamma_Minus_One = Gamma - 1.0; - su2double Cp = (Gamma / Gamma_Minus_One) * Gas_Constant; - su2double laminar_viscosity, thermal_conductivity; - vector GradT (3,0.0); - vector HeatFlux (3,0.0); - vector HeatFluxPassive (3,0.0); - - bool compressible = (config_container[ZONE_0]->GetKind_Regime() == ENUM_REGIME::COMPRESSIBLE); - - iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); - - if(compressible){ - laminar_viscosity = solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]->GetNodes()->GetLaminarViscosity(iPoint); - thermal_conductivity = Cp * (laminar_viscosity/Prandtl_Lam); - for(iDim=0; iDim < nDim; iDim++){ - GradT[iDim] = solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]->GetNodes()->GetGradient_Primitive(iPoint, 0, iDim); - HeatFlux[iDim] = -thermal_conductivity*GradT[iDim]; + + unsigned long iPoint; + unsigned short iDim; + su2double Prandtl_Lam = config_container[ZONE_0]->GetPrandtl_Lam(); + su2double Gas_Constant = config_container[ZONE_0]->GetGas_ConstantND(); + su2double Gamma = config_container[ZONE_0]->GetGamma(); + su2double Gamma_Minus_One = Gamma - 1.0; + su2double Cp = (Gamma / Gamma_Minus_One) * Gas_Constant; + su2double laminar_viscosity, thermal_conductivity; + vector GradT (3,0.0); + vector HeatFlux (3,0.0); + vector HeatFluxPassive (3,0.0); + + bool compressible = (config_container[ZONE_0]->GetKind_Regime() == ENUM_REGIME::COMPRESSIBLE); + + iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); + + if(compressible){ + laminar_viscosity = solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]->GetNodes()->GetLaminarViscosity(iPoint); + thermal_conductivity = Cp * (laminar_viscosity/Prandtl_Lam); + for(iDim=0; iDim < nDim; iDim++){ + GradT[iDim] = solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]->GetNodes()->GetGradient_Primitive(iPoint, 0, iDim); + HeatFlux[iDim] = -thermal_conductivity*GradT[iDim]; + } } - } - - HeatFluxPassive[0] = SU2_TYPE::GetValue(HeatFlux[0]); - HeatFluxPassive[1] = SU2_TYPE::GetValue(HeatFlux[1]); - HeatFluxPassive[2] = SU2_TYPE::GetValue(HeatFlux[2]); - - return HeatFluxPassive; + + HeatFluxPassive[0] = SU2_TYPE::GetValue(HeatFlux[0]); + HeatFluxPassive[1] = SU2_TYPE::GetValue(HeatFlux[1]); + HeatFluxPassive[2] = SU2_TYPE::GetValue(HeatFlux[2]); + + return HeatFluxPassive; } passivedouble CDriver::GetVertexNormalHeatFlux(unsigned short iMarker, unsigned long iVertex) const{ - - unsigned long iPoint; - unsigned short iDim; - su2double vertexWallHeatFlux; - su2double Prandtl_Lam = config_container[ZONE_0]->GetPrandtl_Lam(); - su2double Gas_Constant = config_container[ZONE_0]->GetGas_ConstantND(); - su2double Gamma = config_container[ZONE_0]->GetGamma(); - su2double Gamma_Minus_One = Gamma - 1.0; - su2double Cp = (Gamma / Gamma_Minus_One) * Gas_Constant; - su2double Area; - su2double laminar_viscosity, thermal_conductivity, dTdn; - su2double *Normal, GradT[3] = {0.0,0.0,0.0}, UnitNormal[3] = {0.0,0.0,0.0}; - - bool compressible = (config_container[ZONE_0]->GetKind_Regime() == ENUM_REGIME::COMPRESSIBLE); - - vertexWallHeatFlux = 0.0; - dTdn = 0.0; - - iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); - - if(geometry_container[ZONE_0][INST_0][MESH_0]->nodes->GetDomain(iPoint) && compressible){ - Normal = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNormal(); - - Area = GeometryToolbox::Norm(nDim, Normal); - - for (iDim = 0; iDim < nDim; iDim++) - UnitNormal[iDim] = Normal[iDim]/Area; - - laminar_viscosity = solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]->GetNodes()->GetLaminarViscosity(iPoint); - thermal_conductivity = Cp * (laminar_viscosity/Prandtl_Lam); - /*Compute wall heat flux (normal to the wall) based on computed temperature gradient*/ - for(iDim=0; iDim < nDim; iDim++){ - GradT[iDim] = solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]->GetNodes()->GetGradient_Primitive(iPoint, 0, iDim); - dTdn += GradT[iDim]*UnitNormal[iDim]; + + unsigned long iPoint; + unsigned short iDim; + su2double vertexWallHeatFlux; + su2double Prandtl_Lam = config_container[ZONE_0]->GetPrandtl_Lam(); + su2double Gas_Constant = config_container[ZONE_0]->GetGas_ConstantND(); + su2double Gamma = config_container[ZONE_0]->GetGamma(); + su2double Gamma_Minus_One = Gamma - 1.0; + su2double Cp = (Gamma / Gamma_Minus_One) * Gas_Constant; + su2double Area; + su2double laminar_viscosity, thermal_conductivity, dTdn; + su2double *Normal, GradT[3] = {0.0,0.0,0.0}, UnitNormal[3] = {0.0,0.0,0.0}; + + bool compressible = (config_container[ZONE_0]->GetKind_Regime() == ENUM_REGIME::COMPRESSIBLE); + + vertexWallHeatFlux = 0.0; + dTdn = 0.0; + + iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); + + if(geometry_container[ZONE_0][INST_0][MESH_0]->nodes->GetDomain(iPoint) && compressible){ + Normal = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNormal(); + + Area = GeometryToolbox::Norm(nDim, Normal); + + for (iDim = 0; iDim < nDim; iDim++) + UnitNormal[iDim] = Normal[iDim]/Area; + + laminar_viscosity = solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]->GetNodes()->GetLaminarViscosity(iPoint); + thermal_conductivity = Cp * (laminar_viscosity/Prandtl_Lam); + /*Compute wall heat flux (normal to the wall) based on computed temperature gradient*/ + for(iDim=0; iDim < nDim; iDim++){ + GradT[iDim] = solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]->GetNodes()->GetGradient_Primitive(iPoint, 0, iDim); + dTdn += GradT[iDim]*UnitNormal[iDim]; + } + + vertexWallHeatFlux = -thermal_conductivity*dTdn; } - - vertexWallHeatFlux = -thermal_conductivity*dTdn; - } - - return SU2_TYPE::GetValue(vertexWallHeatFlux); + + return SU2_TYPE::GetValue(vertexWallHeatFlux); } void CDriver::SetVertexNormalHeatFlux(unsigned short iMarker, unsigned long iVertex, passivedouble val_WallHeatFlux){ - - geometry_container[ZONE_0][INST_0][MESH_0]->SetCustomBoundaryHeatFlux(iMarker, iVertex, val_WallHeatFlux); + + geometry_container[ZONE_0][INST_0][MESH_0]->SetCustomBoundaryHeatFlux(iMarker, iVertex, val_WallHeatFlux); } passivedouble CDriver::GetThermalConductivity(unsigned short iMarker, unsigned long iVertex) const { - - unsigned long iPoint; - su2double Prandtl_Lam = config_container[ZONE_0]->GetPrandtl_Lam(); - su2double Gas_Constant = config_container[ZONE_0]->GetGas_ConstantND(); - su2double Gamma = config_container[ZONE_0]->GetGamma(); - su2double Gamma_Minus_One = Gamma - 1.0; - su2double Cp = (Gamma / Gamma_Minus_One) * Gas_Constant; - su2double laminar_viscosity, thermal_conductivity; - - iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); - laminar_viscosity = solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]->GetNodes()->GetLaminarViscosity(iPoint); - thermal_conductivity = Cp * (laminar_viscosity/Prandtl_Lam); - - return SU2_TYPE::GetValue(thermal_conductivity); - + + unsigned long iPoint; + su2double Prandtl_Lam = config_container[ZONE_0]->GetPrandtl_Lam(); + su2double Gas_Constant = config_container[ZONE_0]->GetGas_ConstantND(); + su2double Gamma = config_container[ZONE_0]->GetGamma(); + su2double Gamma_Minus_One = Gamma - 1.0; + su2double Cp = (Gamma / Gamma_Minus_One) * Gas_Constant; + su2double laminar_viscosity, thermal_conductivity; + + iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); + laminar_viscosity = solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]->GetNodes()->GetLaminarViscosity(iPoint); + thermal_conductivity = Cp * (laminar_viscosity/Prandtl_Lam); + + return SU2_TYPE::GetValue(thermal_conductivity); + } //////////////////////////////////////////////////////////////////////////////// @@ -321,83 +321,83 @@ passivedouble CDriver::GetThermalConductivity(unsigned short iMarker, unsigned l //////////////////////////////////////////////////////////////////////////////// vector CDriver::GetAllBoundaryMarkersTag() const { - - vector boundariesTagList; - unsigned short iMarker,nBoundariesMarkers; - string Marker_Tag; - - nBoundariesMarkers = config_container[ZONE_0]->GetnMarker_All(); - boundariesTagList.resize(nBoundariesMarkers); - - for(iMarker=0; iMarker < nBoundariesMarkers; iMarker++){ - Marker_Tag = config_container[ZONE_0]->GetMarker_All_TagBound(iMarker); - boundariesTagList[iMarker] = Marker_Tag; - } - - return boundariesTagList; + + vector boundariesTagList; + unsigned short iMarker,nBoundariesMarkers; + string Marker_Tag; + + nBoundariesMarkers = config_container[ZONE_0]->GetnMarker_All(); + boundariesTagList.resize(nBoundariesMarkers); + + for(iMarker=0; iMarker < nBoundariesMarkers; iMarker++){ + Marker_Tag = config_container[ZONE_0]->GetMarker_All_TagBound(iMarker); + boundariesTagList[iMarker] = Marker_Tag; + } + + return boundariesTagList; } vector CDriver::GetAllCHTMarkersTag() const { - - vector CHTBoundariesTagList; - unsigned short iMarker, nBoundariesMarker; - string Marker_Tag; - - nBoundariesMarker = config_container[ZONE_0]->GetnMarker_All(); - - //The CHT markers can be identified as the markers that are customizable with a BC type HEAT_FLUX or ISOTHERMAL. - for(iMarker=0; iMarkerGetMarker_All_KindBC(iMarker) == HEAT_FLUX || config_container[ZONE_0]->GetMarker_All_KindBC(iMarker) == ISOTHERMAL) && config_container[ZONE_0]->GetMarker_All_PyCustom(iMarker)){ - Marker_Tag = config_container[ZONE_0]->GetMarker_All_TagBound(iMarker); - CHTBoundariesTagList.push_back(Marker_Tag); + + vector CHTBoundariesTagList; + unsigned short iMarker, nBoundariesMarker; + string Marker_Tag; + + nBoundariesMarker = config_container[ZONE_0]->GetnMarker_All(); + + //The CHT markers can be identified as the markers that are customizable with a BC type HEAT_FLUX or ISOTHERMAL. + for(iMarker=0; iMarkerGetMarker_All_KindBC(iMarker) == HEAT_FLUX || config_container[ZONE_0]->GetMarker_All_KindBC(iMarker) == ISOTHERMAL) && config_container[ZONE_0]->GetMarker_All_PyCustom(iMarker)){ + Marker_Tag = config_container[ZONE_0]->GetMarker_All_TagBound(iMarker); + CHTBoundariesTagList.push_back(Marker_Tag); + } } - } - - return CHTBoundariesTagList; + + return CHTBoundariesTagList; } vector CDriver::GetAllInletMarkersTag() const { - - vector BoundariesTagList; - unsigned short iMarker, nBoundariesMarker; - string Marker_Tag; - - nBoundariesMarker = config_container[ZONE_0]->GetnMarker_All(); - - for(iMarker=0; iMarkerGetMarker_All_PyCustom(iMarker); - bool isInlet = (config_container[ZONE_0]->GetMarker_All_KindBC(iMarker) == INLET_FLOW); - if(isCustomizable && isInlet) { - Marker_Tag = config_container[ZONE_0]->GetMarker_All_TagBound(iMarker); - BoundariesTagList.push_back(Marker_Tag); + + vector BoundariesTagList; + unsigned short iMarker, nBoundariesMarker; + string Marker_Tag; + + nBoundariesMarker = config_container[ZONE_0]->GetnMarker_All(); + + for(iMarker=0; iMarkerGetMarker_All_PyCustom(iMarker); + bool isInlet = (config_container[ZONE_0]->GetMarker_All_KindBC(iMarker) == INLET_FLOW); + if(isCustomizable && isInlet) { + Marker_Tag = config_container[ZONE_0]->GetMarker_All_TagBound(iMarker); + BoundariesTagList.push_back(Marker_Tag); + } } - } - - return BoundariesTagList; + + return BoundariesTagList; } void CDriver::SetHeatSource_Position(passivedouble alpha, passivedouble pos_x, passivedouble pos_y, passivedouble pos_z){ - - CSolver *solver = solver_container[ZONE_0][INST_0][MESH_0][RAD_SOL]; - - config_container[ZONE_0]->SetHeatSource_Rot_Z(alpha); - config_container[ZONE_0]->SetHeatSource_Center(pos_x, pos_y, pos_z); - - solver->SetVolumetricHeatSource(geometry_container[ZONE_0][INST_0][MESH_0], config_container[ZONE_0]); - + + CSolver *solver = solver_container[ZONE_0][INST_0][MESH_0][RAD_SOL]; + + config_container[ZONE_0]->SetHeatSource_Rot_Z(alpha); + config_container[ZONE_0]->SetHeatSource_Center(pos_x, pos_y, pos_z); + + solver->SetVolumetricHeatSource(geometry_container[ZONE_0][INST_0][MESH_0], config_container[ZONE_0]); + } void CDriver::SetInlet_Angle(unsigned short iMarker, passivedouble alpha){ - - su2double alpha_rad = alpha * PI_NUMBER/180.0; - - unsigned long iVertex; - - for (iVertex = 0; iVertex < geometry_container[ZONE_0][INST_0][MESH_0]->nVertex[iMarker]; iVertex++){ - solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]->SetInlet_FlowDir(iMarker, iVertex, 0, cos(alpha_rad)); - solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]->SetInlet_FlowDir(iMarker, iVertex, 1, sin(alpha_rad)); - } - + + su2double alpha_rad = alpha * PI_NUMBER/180.0; + + unsigned long iVertex; + + for (iVertex = 0; iVertex < geometry_container[ZONE_0][INST_0][MESH_0]->nVertex[iMarker]; iVertex++){ + solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]->SetInlet_FlowDir(iMarker, iVertex, 0, cos(alpha_rad)); + solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]->SetInlet_FlowDir(iMarker, iVertex, 1, sin(alpha_rad)); + } + } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -405,74 +405,74 @@ void CDriver::SetInlet_Angle(unsigned short iMarker, passivedouble alpha){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// void CDriver::ResetConvergence() { - - for(iZone = 0; iZone < nZone; iZone++) { - switch (config_container[iZone]->GetKind_Solver()) { - - case MAIN_SOLVER::EULER: case MAIN_SOLVER::NAVIER_STOKES: case MAIN_SOLVER::RANS: - case MAIN_SOLVER::INC_EULER: case MAIN_SOLVER::INC_NAVIER_STOKES: case MAIN_SOLVER::INC_RANS: - integration_container[iZone][INST_0][FLOW_SOL]->SetConvergence(false); - if (config_container[iZone]->GetKind_Solver() == MAIN_SOLVER::RANS) integration_container[iZone][INST_0][TURB_SOL]->SetConvergence(false); - if(config_container[iZone]->GetKind_Trans_Model() == TURB_TRANS_MODEL::LM) integration_container[iZone][INST_0][TRANS_SOL]->SetConvergence(false); - break; - - case MAIN_SOLVER::FEM_ELASTICITY: - integration_container[iZone][INST_0][FEA_SOL]->SetConvergence(false); - break; - - case MAIN_SOLVER::ADJ_EULER: case MAIN_SOLVER::ADJ_NAVIER_STOKES: case MAIN_SOLVER::ADJ_RANS: case MAIN_SOLVER::DISC_ADJ_EULER: case MAIN_SOLVER::DISC_ADJ_NAVIER_STOKES: case MAIN_SOLVER::DISC_ADJ_RANS: - case MAIN_SOLVER::DISC_ADJ_INC_EULER: case MAIN_SOLVER::DISC_ADJ_INC_NAVIER_STOKES: case MAIN_SOLVER::DISC_ADJ_INC_RANS: - integration_container[iZone][INST_0][ADJFLOW_SOL]->SetConvergence(false); - if( (config_container[iZone]->GetKind_Solver() == MAIN_SOLVER::ADJ_RANS) || (config_container[iZone]->GetKind_Solver() == MAIN_SOLVER::DISC_ADJ_RANS) ) - integration_container[iZone][INST_0][ADJTURB_SOL]->SetConvergence(false); - break; - - default: - break; + + for(iZone = 0; iZone < nZone; iZone++) { + switch (config_container[iZone]->GetKind_Solver()) { + + case MAIN_SOLVER::EULER: case MAIN_SOLVER::NAVIER_STOKES: case MAIN_SOLVER::RANS: + case MAIN_SOLVER::INC_EULER: case MAIN_SOLVER::INC_NAVIER_STOKES: case MAIN_SOLVER::INC_RANS: + integration_container[iZone][INST_0][FLOW_SOL]->SetConvergence(false); + if (config_container[iZone]->GetKind_Solver() == MAIN_SOLVER::RANS) integration_container[iZone][INST_0][TURB_SOL]->SetConvergence(false); + if(config_container[iZone]->GetKind_Trans_Model() == TURB_TRANS_MODEL::LM) integration_container[iZone][INST_0][TRANS_SOL]->SetConvergence(false); + break; + + case MAIN_SOLVER::FEM_ELASTICITY: + integration_container[iZone][INST_0][FEA_SOL]->SetConvergence(false); + break; + + case MAIN_SOLVER::ADJ_EULER: case MAIN_SOLVER::ADJ_NAVIER_STOKES: case MAIN_SOLVER::ADJ_RANS: case MAIN_SOLVER::DISC_ADJ_EULER: case MAIN_SOLVER::DISC_ADJ_NAVIER_STOKES: case MAIN_SOLVER::DISC_ADJ_RANS: + case MAIN_SOLVER::DISC_ADJ_INC_EULER: case MAIN_SOLVER::DISC_ADJ_INC_NAVIER_STOKES: case MAIN_SOLVER::DISC_ADJ_INC_RANS: + integration_container[iZone][INST_0][ADJFLOW_SOL]->SetConvergence(false); + if( (config_container[iZone]->GetKind_Solver() == MAIN_SOLVER::ADJ_RANS) || (config_container[iZone]->GetKind_Solver() == MAIN_SOLVER::DISC_ADJ_RANS) ) + integration_container[iZone][INST_0][ADJTURB_SOL]->SetConvergence(false); + break; + + default: + break; + } } - } - + } void CSinglezoneDriver::SetInitialMesh() { - - DynamicMeshUpdate(0); - - SU2_OMP_PARALLEL { - // Overwrite fictious velocities - for (iMesh = 0u; iMesh <= config_container[ZONE_0]->GetnMGLevels(); iMesh++) { - SU2_OMP_FOR_STAT(roundUpDiv(geometry_container[ZONE_0][INST_0][iMesh]->GetnPoint(),omp_get_max_threads())) - for (unsigned long iPoint = 0; iPoint < geometry_container[ZONE_0][INST_0][iMesh]->GetnPoint(); iPoint++) { - - /*--- Overwrite fictitious velocities ---*/ - su2double Grid_Vel[3] = {0.0, 0.0, 0.0}; - - /*--- Set the grid velocity for this coarse node. ---*/ - geometry_container[ZONE_0][INST_0][iMesh]->nodes->SetGridVel(iPoint, Grid_Vel); - } - END_SU2_OMP_FOR - /*--- Push back the volume. ---*/ - geometry_container[ZONE_0][INST_0][iMesh]->nodes->SetVolume_n(); - geometry_container[ZONE_0][INST_0][iMesh]->nodes->SetVolume_nM1(); + + DynamicMeshUpdate(0); + + SU2_OMP_PARALLEL { + // Overwrite fictious velocities + for (iMesh = 0u; iMesh <= config_container[ZONE_0]->GetnMGLevels(); iMesh++) { + SU2_OMP_FOR_STAT(roundUpDiv(geometry_container[ZONE_0][INST_0][iMesh]->GetnPoint(),omp_get_max_threads())) + for (unsigned long iPoint = 0; iPoint < geometry_container[ZONE_0][INST_0][iMesh]->GetnPoint(); iPoint++) { + + /*--- Overwrite fictitious velocities ---*/ + su2double Grid_Vel[3] = {0.0, 0.0, 0.0}; + + /*--- Set the grid velocity for this coarse node. ---*/ + geometry_container[ZONE_0][INST_0][iMesh]->nodes->SetGridVel(iPoint, Grid_Vel); + } + END_SU2_OMP_FOR + /*--- Push back the volume. ---*/ + geometry_container[ZONE_0][INST_0][iMesh]->nodes->SetVolume_n(); + geometry_container[ZONE_0][INST_0][iMesh]->nodes->SetVolume_nM1(); + } + /*--- Push back the solution so that there is no fictious velocity at the next step. ---*/ + solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->Set_Solution_time_n(); + solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->Set_Solution_time_n1(); } - /*--- Push back the solution so that there is no fictious velocity at the next step. ---*/ - solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->Set_Solution_time_n(); - solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->Set_Solution_time_n1(); - } - END_SU2_OMP_PARALLEL + END_SU2_OMP_PARALLEL } void CDriver::BoundaryConditionsUpdate(){ - - int rank = MASTER_NODE; - unsigned short iZone; - - SU2_MPI::Comm_rank(SU2_MPI::GetComm(), &rank); - - if(rank == MASTER_NODE) cout << "Updating boundary conditions." << endl; - for(iZone = 0; iZone < nZone; iZone++){ - geometry_container[iZone][INST_0][MESH_0]->UpdateCustomBoundaryConditions(geometry_container[iZone][INST_0], config_container[iZone]); - } + + int rank = MASTER_NODE; + unsigned short iZone; + + SU2_MPI::Comm_rank(SU2_MPI::GetComm(), &rank); + + if(rank == MASTER_NODE) cout << "Updating boundary conditions." << endl; + for(iZone = 0; iZone < nZone; iZone++){ + geometry_container[iZone][INST_0][MESH_0]->UpdateCustomBoundaryConditions(geometry_container[iZone][INST_0], config_container[iZone]); + } } //////////////////////////////////////////////////////////////////////////////// @@ -480,95 +480,95 @@ void CDriver::BoundaryConditionsUpdate(){ //////////////////////////////////////////////////////////////////////////////// void CDriver::SetFEA_Loads(unsigned short iMarker, unsigned long iVertex, passivedouble LoadX, - passivedouble LoadY, passivedouble LoadZ) { - - unsigned long iPoint; - su2double NodalForce[3] = {0.0,0.0,0.0}; - NodalForce[0] = LoadX; - NodalForce[1] = LoadY; - NodalForce[2] = LoadZ; - - iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); - solver_container[ZONE_0][INST_0][MESH_0][FEA_SOL]->GetNodes()->Set_FlowTraction(iPoint,NodalForce); - + passivedouble LoadY, passivedouble LoadZ) { + + unsigned long iPoint; + su2double NodalForce[3] = {0.0,0.0,0.0}; + NodalForce[0] = LoadX; + NodalForce[1] = LoadY; + NodalForce[2] = LoadZ; + + iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); + solver_container[ZONE_0][INST_0][MESH_0][FEA_SOL]->GetNodes()->Set_FlowTraction(iPoint,NodalForce); + } vector CDriver::GetFEA_Displacements(unsigned short iMarker, unsigned long iVertex) const { - - unsigned long iPoint; - vector Displacements(3, 0.0); - vector Displacements_passive(3, 0.0); - - iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); - CSolver *solver = solver_container[ZONE_0][INST_0][MESH_0][FEA_SOL]; - CGeometry *geometry = geometry_container[ZONE_0][INST_0][MESH_0]; - - Displacements[0] = solver->GetNodes()->GetSolution(iPoint, 0); - Displacements[1] = solver->GetNodes()->GetSolution(iPoint, 1); - if (geometry->GetnDim() == 3) - Displacements[2] = solver->GetNodes()->GetSolution(iPoint, 2); - else - Displacements[2] = 0.0; - - Displacements_passive[0] = SU2_TYPE::GetValue(Displacements[0]); - Displacements_passive[1] = SU2_TYPE::GetValue(Displacements[1]); - Displacements_passive[2] = SU2_TYPE::GetValue(Displacements[2]); - - return Displacements_passive; -} - - -vector CDriver::GetFEA_Velocity(unsigned short iMarker, unsigned long iVertex) const { - - unsigned long iPoint; - vector Velocity(3, 0.0); - vector Velocity_passive(3,0.0); - - iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); - CSolver *solver = solver_container[ZONE_0][INST_0][MESH_0][FEA_SOL]; - CGeometry *geometry = geometry_container[ZONE_0][INST_0][MESH_0]; - - if (config_container[ZONE_0]->GetDynamic_Analysis() == DYNAMIC){ - Velocity[0] = solver->GetNodes()->GetSolution_Vel(iPoint, 0); - Velocity[1] = solver->GetNodes()->GetSolution_Vel(iPoint, 1); + + unsigned long iPoint; + vector Displacements(3, 0.0); + vector Displacements_passive(3, 0.0); + + iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); + CSolver *solver = solver_container[ZONE_0][INST_0][MESH_0][FEA_SOL]; + CGeometry *geometry = geometry_container[ZONE_0][INST_0][MESH_0]; + + Displacements[0] = solver->GetNodes()->GetSolution(iPoint, 0); + Displacements[1] = solver->GetNodes()->GetSolution(iPoint, 1); if (geometry->GetnDim() == 3) - Velocity[2] = solver->GetNodes()->GetSolution_Vel(iPoint, 2); + Displacements[2] = solver->GetNodes()->GetSolution(iPoint, 2); else - Velocity[2] = 0.0; - } + Displacements[2] = 0.0; + + Displacements_passive[0] = SU2_TYPE::GetValue(Displacements[0]); + Displacements_passive[1] = SU2_TYPE::GetValue(Displacements[1]); + Displacements_passive[2] = SU2_TYPE::GetValue(Displacements[2]); + + return Displacements_passive; +} - Velocity_passive[0] = SU2_TYPE::GetValue(Velocity[0]); - Velocity_passive[1] = SU2_TYPE::GetValue(Velocity[1]); - Velocity_passive[2] = SU2_TYPE::GetValue(Velocity[2]); - return Velocity_passive; +vector CDriver::GetFEA_Velocity(unsigned short iMarker, unsigned long iVertex) const { + + unsigned long iPoint; + vector Velocity(3, 0.0); + vector Velocity_passive(3,0.0); + + iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); + CSolver *solver = solver_container[ZONE_0][INST_0][MESH_0][FEA_SOL]; + CGeometry *geometry = geometry_container[ZONE_0][INST_0][MESH_0]; + + if (config_container[ZONE_0]->GetDynamic_Analysis() == DYNAMIC){ + Velocity[0] = solver->GetNodes()->GetSolution_Vel(iPoint, 0); + Velocity[1] = solver->GetNodes()->GetSolution_Vel(iPoint, 1); + if (geometry->GetnDim() == 3) + Velocity[2] = solver->GetNodes()->GetSolution_Vel(iPoint, 2); + else + Velocity[2] = 0.0; + } + + Velocity_passive[0] = SU2_TYPE::GetValue(Velocity[0]); + Velocity_passive[1] = SU2_TYPE::GetValue(Velocity[1]); + Velocity_passive[2] = SU2_TYPE::GetValue(Velocity[2]); + + return Velocity_passive; } vector CDriver::GetFEA_Velocity_n(unsigned short iMarker, unsigned long iVertex) const { - - unsigned long iPoint; - vector Velocity_n(3, 0.0); - vector Velocity_n_passive(3, 0.0); - - iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); - CSolver *solver = solver_container[ZONE_0][INST_0][MESH_0][FEA_SOL]; - CGeometry *geometry = geometry_container[ZONE_0][INST_0][MESH_0]; - - if (config_container[ZONE_0]->GetDynamic_Analysis() == DYNAMIC){ - Velocity_n[0] = solver->GetNodes()->GetSolution_Vel_time_n(iPoint, 0); - Velocity_n[1] = solver->GetNodes()->GetSolution_Vel_time_n(iPoint, 1); - if (geometry->GetnDim() == 3) - Velocity_n[2] = solver->GetNodes()->GetSolution_Vel_time_n(iPoint, 2); - else - Velocity_n[2] = 0.0; - } - - Velocity_n_passive[0] = SU2_TYPE::GetValue(Velocity_n[0]); - Velocity_n_passive[1] = SU2_TYPE::GetValue(Velocity_n[1]); - Velocity_n_passive[2] = SU2_TYPE::GetValue(Velocity_n[2]); - - return Velocity_n_passive; - + + unsigned long iPoint; + vector Velocity_n(3, 0.0); + vector Velocity_n_passive(3, 0.0); + + iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); + CSolver *solver = solver_container[ZONE_0][INST_0][MESH_0][FEA_SOL]; + CGeometry *geometry = geometry_container[ZONE_0][INST_0][MESH_0]; + + if (config_container[ZONE_0]->GetDynamic_Analysis() == DYNAMIC){ + Velocity_n[0] = solver->GetNodes()->GetSolution_Vel_time_n(iPoint, 0); + Velocity_n[1] = solver->GetNodes()->GetSolution_Vel_time_n(iPoint, 1); + if (geometry->GetnDim() == 3) + Velocity_n[2] = solver->GetNodes()->GetSolution_Vel_time_n(iPoint, 2); + else + Velocity_n[2] = 0.0; + } + + Velocity_n_passive[0] = SU2_TYPE::GetValue(Velocity_n[0]); + Velocity_n_passive[1] = SU2_TYPE::GetValue(Velocity_n[1]); + Velocity_n_passive[2] = SU2_TYPE::GetValue(Velocity_n[2]); + + return Velocity_n_passive; + } //////////////////////////////////////////////////////////////////////////////// @@ -576,96 +576,96 @@ vector CDriver::GetFEA_Velocity_n(unsigned short iMarker, unsigne //////////////////////////////////////////////////////////////////////////////// vector CDriver::GetMeshDisp_Sensitivity(unsigned short iMarker, unsigned long iVertex) const { - - unsigned long iPoint; - vector Disp_Sens(3, 0.0); - vector Disp_Sens_passive(3, 0.0); - - iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); - CSolver *solver = solver_container[ZONE_0][INST_0][MESH_0][ADJMESH_SOL]; - CGeometry *geometry = geometry_container[ZONE_0][INST_0][MESH_0]; - - Disp_Sens[0] = solver->GetNodes()->GetBoundDisp_Sens(iPoint, 0); - Disp_Sens[1] = solver->GetNodes()->GetBoundDisp_Sens(iPoint, 1); - if (geometry->GetnDim() == 3) - Disp_Sens[2] = solver->GetNodes()->GetBoundDisp_Sens(iPoint, 2); - else - Disp_Sens[2] = 0.0; - - Disp_Sens_passive[0] = SU2_TYPE::GetValue(Disp_Sens[0]); - Disp_Sens_passive[1] = SU2_TYPE::GetValue(Disp_Sens[1]); - Disp_Sens_passive[2] = SU2_TYPE::GetValue(Disp_Sens[2]); - - return Disp_Sens_passive; - + + unsigned long iPoint; + vector Disp_Sens(3, 0.0); + vector Disp_Sens_passive(3, 0.0); + + iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); + CSolver *solver = solver_container[ZONE_0][INST_0][MESH_0][ADJMESH_SOL]; + CGeometry *geometry = geometry_container[ZONE_0][INST_0][MESH_0]; + + Disp_Sens[0] = solver->GetNodes()->GetBoundDisp_Sens(iPoint, 0); + Disp_Sens[1] = solver->GetNodes()->GetBoundDisp_Sens(iPoint, 1); + if (geometry->GetnDim() == 3) + Disp_Sens[2] = solver->GetNodes()->GetBoundDisp_Sens(iPoint, 2); + else + Disp_Sens[2] = 0.0; + + Disp_Sens_passive[0] = SU2_TYPE::GetValue(Disp_Sens[0]); + Disp_Sens_passive[1] = SU2_TYPE::GetValue(Disp_Sens[1]); + Disp_Sens_passive[2] = SU2_TYPE::GetValue(Disp_Sens[2]); + + return Disp_Sens_passive; + } vector CDriver::GetFlowLoad_Sensitivity(unsigned short iMarker, unsigned long iVertex) const { - - unsigned long iPoint; - vector FlowLoad_Sens(3, 0.0); - vector FlowLoad_Sens_passive(3, 0.0); - - iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); - CSolver *solver = solver_container[ZONE_0][INST_0][MESH_0][ADJFEA_SOL]; - CGeometry *geometry = geometry_container[ZONE_0][INST_0][MESH_0]; - - FlowLoad_Sens[0] = solver->GetNodes()->GetFlowTractionSensitivity(iPoint, 0); - FlowLoad_Sens[1] = solver->GetNodes()->GetFlowTractionSensitivity(iPoint, 1); - if (geometry->GetnDim() == 3) - FlowLoad_Sens[2] = solver->GetNodes()->GetFlowTractionSensitivity(iPoint, 2); - else - FlowLoad_Sens[2] = 0.0; - - FlowLoad_Sens_passive[0] = SU2_TYPE::GetValue(FlowLoad_Sens[0]); - FlowLoad_Sens_passive[1] = SU2_TYPE::GetValue(FlowLoad_Sens[1]); - FlowLoad_Sens_passive[2] = SU2_TYPE::GetValue(FlowLoad_Sens[2]); - - return FlowLoad_Sens_passive; - + + unsigned long iPoint; + vector FlowLoad_Sens(3, 0.0); + vector FlowLoad_Sens_passive(3, 0.0); + + iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); + CSolver *solver = solver_container[ZONE_0][INST_0][MESH_0][ADJFEA_SOL]; + CGeometry *geometry = geometry_container[ZONE_0][INST_0][MESH_0]; + + FlowLoad_Sens[0] = solver->GetNodes()->GetFlowTractionSensitivity(iPoint, 0); + FlowLoad_Sens[1] = solver->GetNodes()->GetFlowTractionSensitivity(iPoint, 1); + if (geometry->GetnDim() == 3) + FlowLoad_Sens[2] = solver->GetNodes()->GetFlowTractionSensitivity(iPoint, 2); + else + FlowLoad_Sens[2] = 0.0; + + FlowLoad_Sens_passive[0] = SU2_TYPE::GetValue(FlowLoad_Sens[0]); + FlowLoad_Sens_passive[1] = SU2_TYPE::GetValue(FlowLoad_Sens[1]); + FlowLoad_Sens_passive[2] = SU2_TYPE::GetValue(FlowLoad_Sens[2]); + + return FlowLoad_Sens_passive; + } void CDriver::SetFlowLoad_Adjoint(unsigned short iMarker, unsigned long iVertex, passivedouble val_AdjointX, passivedouble val_AdjointY, passivedouble val_AdjointZ) { - - CSolver *solver = solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]; - CGeometry *geometry = geometry_container[ZONE_0][INST_0][MESH_0]; - - solver->StoreVertexTractionsAdjoint(iMarker, iVertex, 0, val_AdjointX); - solver->StoreVertexTractionsAdjoint(iMarker, iVertex, 1, val_AdjointY); - if (geometry->GetnDim() == 3) - solver->StoreVertexTractionsAdjoint(iMarker, iVertex, 2, val_AdjointZ); - + + CSolver *solver = solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]; + CGeometry *geometry = geometry_container[ZONE_0][INST_0][MESH_0]; + + solver->StoreVertexTractionsAdjoint(iMarker, iVertex, 0, val_AdjointX); + solver->StoreVertexTractionsAdjoint(iMarker, iVertex, 1, val_AdjointY); + if (geometry->GetnDim() == 3) + solver->StoreVertexTractionsAdjoint(iMarker, iVertex, 2, val_AdjointZ); + } void CDriver::SetSourceTerm_DispAdjoint(unsigned short iMarker, unsigned long iVertex, passivedouble val_AdjointX, passivedouble val_AdjointY, passivedouble val_AdjointZ) { - - unsigned long iPoint; - - CSolver *solver = solver_container[ZONE_0][INST_0][MESH_0][ADJFEA_SOL]; - CGeometry *geometry = geometry_container[ZONE_0][INST_0][MESH_0]; - iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); - - solver->GetNodes()->SetSourceTerm_DispAdjoint(iPoint, 0, val_AdjointX); - solver->GetNodes()->SetSourceTerm_DispAdjoint(iPoint, 1, val_AdjointY); - if (geometry->GetnDim() == 3) - solver->GetNodes()->SetSourceTerm_DispAdjoint(iPoint, 2, val_AdjointZ); - + + unsigned long iPoint; + + CSolver *solver = solver_container[ZONE_0][INST_0][MESH_0][ADJFEA_SOL]; + CGeometry *geometry = geometry_container[ZONE_0][INST_0][MESH_0]; + iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); + + solver->GetNodes()->SetSourceTerm_DispAdjoint(iPoint, 0, val_AdjointX); + solver->GetNodes()->SetSourceTerm_DispAdjoint(iPoint, 1, val_AdjointY); + if (geometry->GetnDim() == 3) + solver->GetNodes()->SetSourceTerm_DispAdjoint(iPoint, 2, val_AdjointZ); + } void CDriver::SetSourceTerm_VelAdjoint(unsigned short iMarker, unsigned long iVertex, passivedouble val_AdjointX, - passivedouble val_AdjointY, passivedouble val_AdjointZ) { - - CSolver *solver = solver_container[ZONE_0][INST_0][MESH_0][ADJFEA_SOL]; - CGeometry *geometry = geometry_container[ZONE_0][INST_0][MESH_0]; - const auto iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); - - solver->GetNodes()->SetSourceTerm_VelAdjoint(iPoint, 0, val_AdjointX); - solver->GetNodes()->SetSourceTerm_VelAdjoint(iPoint, 1, val_AdjointY); - if (geometry->GetnDim() == 3) - solver->GetNodes()->SetSourceTerm_VelAdjoint(iPoint, 2, val_AdjointZ); - + passivedouble val_AdjointY, passivedouble val_AdjointZ) { + + CSolver *solver = solver_container[ZONE_0][INST_0][MESH_0][ADJFEA_SOL]; + CGeometry *geometry = geometry_container[ZONE_0][INST_0][MESH_0]; + const auto iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); + + solver->GetNodes()->SetSourceTerm_VelAdjoint(iPoint, 0, val_AdjointX); + solver->GetNodes()->SetSourceTerm_VelAdjoint(iPoint, 1, val_AdjointY); + if (geometry->GetnDim() == 3) + solver->GetNodes()->SetSourceTerm_VelAdjoint(iPoint, 2, val_AdjointZ); + } //////////////////////////////////////////////////////////////////////////////// @@ -673,26 +673,26 @@ void CDriver::SetSourceTerm_VelAdjoint(unsigned short iMarker, unsigned long iVe //////////////////////////////////////////////////////////////////////////////// vector CDriver::GetFlowLoad(unsigned short iMarker, unsigned long iVertex) const { - - vector FlowLoad(3, 0.0); - vector FlowLoad_passive(3, 0.0); - - CSolver *solver = solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]; - CGeometry *geometry = geometry_container[ZONE_0][INST_0][MESH_0]; - - if (config_container[ZONE_0]->GetSolid_Wall(iMarker)) { - FlowLoad[0] = solver->GetVertexTractions(iMarker, iVertex, 0); - FlowLoad[1] = solver->GetVertexTractions(iMarker, iVertex, 1); - if (geometry->GetnDim() == 3) - FlowLoad[2] = solver->GetVertexTractions(iMarker, iVertex, 2); - else - FlowLoad[2] = 0.0; - } - - FlowLoad_passive[0] = SU2_TYPE::GetValue(FlowLoad[0]); - FlowLoad_passive[1] = SU2_TYPE::GetValue(FlowLoad[1]); - FlowLoad_passive[2] = SU2_TYPE::GetValue(FlowLoad[2]); - - return FlowLoad_passive; - + + vector FlowLoad(3, 0.0); + vector FlowLoad_passive(3, 0.0); + + CSolver *solver = solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]; + CGeometry *geometry = geometry_container[ZONE_0][INST_0][MESH_0]; + + if (config_container[ZONE_0]->GetSolid_Wall(iMarker)) { + FlowLoad[0] = solver->GetVertexTractions(iMarker, iVertex, 0); + FlowLoad[1] = solver->GetVertexTractions(iMarker, iVertex, 1); + if (geometry->GetnDim() == 3) + FlowLoad[2] = solver->GetVertexTractions(iMarker, iVertex, 2); + else + FlowLoad[2] = 0.0; + } + + FlowLoad_passive[0] = SU2_TYPE::GetValue(FlowLoad[0]); + FlowLoad_passive[1] = SU2_TYPE::GetValue(FlowLoad[1]); + FlowLoad_passive[2] = SU2_TYPE::GetValue(FlowLoad[2]); + + return FlowLoad_passive; + } diff --git a/SU2_DEF/include/SU2_DEF.hpp b/SU2_DEF/include/SU2_DEF.hpp index b0f7ab26fc2..ea076540340 100644 --- a/SU2_DEF/include/SU2_DEF.hpp +++ b/SU2_DEF/include/SU2_DEF.hpp @@ -26,7 +26,6 @@ * License along with SU2. If not, see . */ - #pragma once #include "../../Common/include/parallelization/mpi_structure.hpp" diff --git a/SU2_DEF/include/drivers/CDeformationDriver.hpp b/SU2_DEF/include/drivers/CDeformationDriver.hpp index 329c660bb4c..507978d77e7 100644 --- a/SU2_DEF/include/drivers/CDeformationDriver.hpp +++ b/SU2_DEF/include/drivers/CDeformationDriver.hpp @@ -41,74 +41,74 @@ #include "../../../Common/include/drivers/CDriverBase.hpp" class CDeformationDriver : public CDriverBase { - + protected: - bool haveSurfaceDeformation = false; // flag used to determine whether surface deformation is available for output - + bool haveSurfaceDeformation = false; // flag used to determine whether surface deformation is available for output + public: - /*! - * \brief Constructor of the class. - * \param[in] confFile - Configuration file name. - * \param[in] MPICommunicator - MPI communicator for SU2. - */ - CDeformationDriver(char* confFile, SU2_Comm MPICommunicator); - - /*! - * \brief Destructor of the class. - */ - ~CDeformationDriver(void); - - /*! - * \brief [Overload] Launch the computation for single-zone problems. - */ - void Run(); - - /*! - * \brief Output the mesh. - */ - void Output(); - - /*! - * \brief Deallocation routine - */ - void Postprocessing(); - - void CommunicateMeshDisplacements(void); - + /*! + * \brief Constructor of the class. + * \param[in] confFile - Configuration file name. + * \param[in] MPICommunicator - MPI communicator for SU2. + */ + CDeformationDriver(char* confFile, SU2_Comm MPICommunicator); + + /*! + * \brief Destructor of the class. + */ + ~CDeformationDriver(void); + + /*! + * \brief [Overload] Launch the computation for single-zone problems. + */ + void Run(); + + /*! + * \brief Output the mesh. + */ + void Output(); + + /*! + * \brief Deallocation routine + */ + void Postprocessing(); + + void CommunicateMeshDisplacements(void); + protected: - /*! - * \brief Read in the config and mesh files. - */ - void Input_Preprocessing(); - - /*! - * \brief Construction of the edge-based data structure. - */ - void Geometrical_Preprocessing(); - - /*! - * \brief Preprocess the output container. - */ - void Output_Preprocessing(); - - /*! - * \brief Preprocess the mesh solver container. - */ - void Solver_Preprocessing(); - - /*! - * \brief Preprocess the numerics container. - */ - void Numerics_Preprocessing(); - - /*! - * \brief Mesh deformation based on linear elasticity solver (CMeshSolver). - */ - void Update(); - - /*! - * \brief Mesh deformation based on legacy implementation. - */ - void Update_Legacy(); - + /*! + * \brief Read in the config and mesh files. + */ + void Input_Preprocessing(); + + /*! + * \brief Construction of the edge-based data structure. + */ + void Geometrical_Preprocessing(); + + /*! + * \brief Preprocess the output container. + */ + void Output_Preprocessing(); + + /*! + * \brief Preprocess the mesh solver container. + */ + void Solver_Preprocessing(); + + /*! + * \brief Preprocess the numerics container. + */ + void Numerics_Preprocessing(); + + /*! + * \brief Mesh deformation based on linear elasticity solver (CMeshSolver). + */ + void Update(); + + /*! + * \brief Mesh deformation based on legacy implementation. + */ + void Update_Legacy(); + }; diff --git a/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp b/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp index 1f1f79b76c1..176f89b93f9 100644 --- a/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp +++ b/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp @@ -51,7 +51,7 @@ * \version 7.3.0 "Blackbird" */ class CDiscAdjDeformationDriver : public CDriverBase { - + protected: su2double** Gradient; ofstream Gradient_file; diff --git a/SU2_DEF/src/SU2_DEF.cpp b/SU2_DEF/src/SU2_DEF.cpp index 4cf24b8b5d1..3c5d4db9273 100644 --- a/SU2_DEF/src/SU2_DEF.cpp +++ b/SU2_DEF/src/SU2_DEF.cpp @@ -25,52 +25,51 @@ * License along with SU2. If not, see . */ - #include "../include/SU2_DEF.hpp" using namespace std; int main(int argc, char *argv[]) { - - char config_file_name[MAX_STRING_SIZE]; - - /*--- Create a pointer to the main SU2_DEF Driver ---*/ - - CDeformationDriver* driver = nullptr; - - /*--- MPI initialization ---*/ - + + char config_file_name[MAX_STRING_SIZE]; + + /*--- Create a pointer to the main SU2_DEF Driver ---*/ + + CDeformationDriver* driver = nullptr; + + /*--- MPI initialization ---*/ + #if defined(HAVE_OMP) && defined(HAVE_MPI) - int provided; - SU2_MPI::Init_thread(&argc, &argv, MPI_THREAD_FUNNELED, &provided); + int provided; + SU2_MPI::Init_thread(&argc, &argv, MPI_THREAD_FUNNELED, &provided); #else - SU2_MPI::Init(&argc, &argv); + SU2_MPI::Init(&argc, &argv); #endif - SU2_MPI::Comm comm = SU2_MPI::GetComm(); - - /*--- 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"); } - - /*--- Initialize the mesh deformation driver ---*/ - - driver = new CDeformationDriver(config_file_name, comm); - - /*--- Launch the main external loop of the solver. ---*/ - - driver->Run(); - - /*--- Postprocess all the containers, close history file, exit SU2. ---*/ - - driver->Postprocessing(); - - delete driver; - - /*--- Finalize MPI parallelization ---*/ - SU2_MPI::Finalize(); - - return EXIT_SUCCESS; - + SU2_MPI::Comm comm = SU2_MPI::GetComm(); + + /*--- 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"); } + + /*--- Initialize the mesh deformation driver ---*/ + + driver = new CDeformationDriver(config_file_name, comm); + + /*--- Launch the main external loop of the solver. ---*/ + + driver->Run(); + + /*--- Postprocess all the containers, close history file, exit SU2. ---*/ + + driver->Postprocessing(); + + delete driver; + + /*--- Finalize MPI parallelization ---*/ + SU2_MPI::Finalize(); + + return EXIT_SUCCESS; + } diff --git a/SU2_DEF/src/drivers/CDeformationDriver.cpp b/SU2_DEF/src/drivers/CDeformationDriver.cpp index 8bf4b8b9e98..ecca754838a 100644 --- a/SU2_DEF/src/drivers/CDeformationDriver.cpp +++ b/SU2_DEF/src/drivers/CDeformationDriver.cpp @@ -36,7 +36,7 @@ using namespace std; CDeformationDriver::CDeformationDriver(char* confFile, SU2_Comm MPICommunicator): - CDriverBase(confFile, 1, MPICommunicator) +CDriverBase(confFile, 1, MPICommunicator) { /*--- Initialize Medipack (must also be here so it is initialized from python) ---*/ @@ -107,7 +107,7 @@ void CDeformationDriver::Input_Preprocessing() { /*--- Initialize the configuration of the driver ---*/ driver_config = new CConfig(config_file_name, SU2_COMPONENT::SU2_DEF); - nZone = driver_config->GetnZone(); + nZone = driver_config->GetnZone(); /*--- Loop over all zones to initialize the various classes. In most cases, nZone is equal to one. This represents the solution of a partial @@ -162,7 +162,7 @@ void CDeformationDriver::Geometrical_Preprocessing() { unsigned short nInst_Zone = nInst[iZone]; unsigned short nMesh = 1; - + geometry_container[iZone] = new CGeometry**[nInst_Zone] (); geometry_container[iZone][INST_0] = new CGeometry*[nMesh] (); geometry_container[iZone][INST_0][MESH_0] = new CPhysicalGeometry(geometry_aux, config_container[iZone]); @@ -217,7 +217,7 @@ void CDeformationDriver::Geometrical_Preprocessing() { geometry_container[iZone][INST_0][MESH_0]->PreprocessP2PComms(geometry_container[iZone][INST_0][MESH_0], config_container[iZone]); } - + /*--- Get the number of dimensions ---*/ nDim = geometry_container[ZONE_0][INST_0][MESH_0]->GetnDim(); } @@ -247,13 +247,13 @@ void CDeformationDriver::Solver_Preprocessing() { unsigned short nInst_Zone = nInst[iZone]; unsigned short nMesh = 1; unsigned short nSols = MAX_SOLS; - - + + solver_container[iZone] = new CSolver*** [nInst_Zone] (); solver_container[iZone][INST_0] = new CSolver** [nMesh] (); solver_container[iZone][INST_0][MESH_0] = new CSolver* [nSols] (); solver_container[iZone][INST_0][MESH_0][MESH_SOL] = new CMeshSolver(geometry_container[iZone][INST_0][MESH_0], config_container[iZone]); - } + } } void CDeformationDriver::Numerics_Preprocessing() { @@ -263,7 +263,7 @@ void CDeformationDriver::Numerics_Preprocessing() { unsigned short nMesh = 1; unsigned short nSols = MAX_SOLS; unsigned int nTerm = omp_get_num_threads() * MAX_TERMS; - + numerics_container[iZone] = new CNumerics**** [nInst_Zone] (); numerics_container[iZone][INST_0] = new CNumerics*** [nMesh] (); numerics_container[iZone][INST_0][MESH_0] = new CNumerics** [nSols] (); @@ -328,7 +328,7 @@ void CDeformationDriver::Update() { } void CDeformationDriver::Update_Legacy() { - + for (iZone = 0; iZone < nZone; iZone++){ if (config_container[iZone]->GetDesign_Variable(0) != NO_DEFORMATION) { @@ -510,7 +510,7 @@ void CDeformationDriver::Output() { /*--- Load the data --- */ output_container[iZone]->Load_Data(geometry_container[iZone][INST_0][MESH_0], config_container[iZone], nullptr); - + output_container[iZone]->WriteToFile(config_container[iZone], geometry_container[iZone][INST_0][MESH_0], OUTPUT_TYPE::MESH, driver_config->GetMesh_Out_FileName()); /*--- Set the file names for the visualization files ---*/ @@ -539,9 +539,9 @@ void CDeformationDriver::Output() { } else { if (rank == MASTER_NODE) cout << "Adding any FFD information to the SU2 file." << endl; - + surface_movement[ZONE_0]->WriteFFDInfo(surface_movement, geometry_container, config_container); - } + } } } } diff --git a/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp b/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp index fea679b6f55..bab02b385ca 100644 --- a/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp +++ b/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp @@ -32,7 +32,7 @@ using namespace std; CDiscAdjDeformationDriver::CDiscAdjDeformationDriver(char* confFile, SU2_Comm MPICommunicator): - CDriverBase(confFile, 1, MPICommunicator) +CDriverBase(confFile, 1, MPICommunicator) { /*--- Initialize Medipack (must also be here so it is initialized from python) ---*/ #ifdef HAVE_MPI @@ -83,14 +83,14 @@ CDiscAdjDeformationDriver::~CDiscAdjDeformationDriver(void) { } void CDiscAdjDeformationDriver::Input_Preprocessing() { - + /*--- Initialize a char to store the zone filename ---*/ char zone_file_name[MAX_STRING_SIZE]; /*--- Initialize the configuration of the driver ---*/ driver_config = new CConfig(config_file_name, SU2_COMPONENT::SU2_DEF); - nZone = driver_config->GetnZone(); + nZone = driver_config->GetnZone(); /*--- Loop over all zones to initialize the various classes. In most cases, nZone is equal to one. This represents the solution of a partial @@ -110,11 +110,11 @@ void CDiscAdjDeformationDriver::Input_Preprocessing() { } config_container[iZone]->SetMPICommunicator(SU2_MPI::GetComm()); - + if (!config_container[iZone]->GetDiscrete_Adjoint()) { SU2_MPI::Error("The discrete adjoint solver was not specified in the configuration file.", CURRENT_FUNCTION); } - + } /*--- Set the multizone part of the problem. ---*/ @@ -265,7 +265,7 @@ void CDiscAdjDeformationDriver::Run() { for (iZone = 0; iZone < nZone; iZone++) { if (rank == MASTER_NODE) cout << "Reading volume sensitivities at each node from file." << endl; unsigned short nInst_Zone = nInst[iZone]; - + grid_movement[iZone] = new CVolumetricMovement* [nInst_Zone] (); grid_movement[iZone][INST_0] = new CVolumetricMovement(geometry_container[iZone][INST_0][MESH_0], config_container[iZone]); @@ -366,7 +366,7 @@ void CDiscAdjDeformationDriver::Postprocessing() { } delete [] solver_container; if (rank == MASTER_NODE) cout << "Deleted CSolver container." << endl; - + if (geometry_container != nullptr) { for (iZone = 0; iZone < nZone; iZone++) { if (geometry_container[iZone] != nullptr) { @@ -425,7 +425,7 @@ void CDiscAdjDeformationDriver::Postprocessing() { if (rank == MASTER_NODE) cout << "Deleted COutput class." << endl; if (nInst != nullptr) delete [] nInst; - + /*--- Exit the solver cleanly ---*/ if (rank == MASTER_NODE) From 976408cfbc3a97e4a43a0954f5add106028a4157 Mon Sep 17 00:00:00 2001 From: aa-g Date: Mon, 21 Feb 2022 16:23:49 +0100 Subject: [PATCH 20/68] Fix dangling if statement in CDiscAdjDeformationDriver --- SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp b/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp index bab02b385ca..a91ade80097 100644 --- a/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp +++ b/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp @@ -312,18 +312,19 @@ void CDiscAdjDeformationDriver::Run() { /*--- Copy coordinates to the surface structure ---*/ surface_movement[iZone]->CopyBoundary(geometry_container[iZone][INST_0][MESH_0], config_container[iZone]); - + /*--- If AD mode is enabled we can use it to compute the projection, * otherwise we use finite differences. ---*/ - if (config_container[iZone]->GetAD_Mode()) + if (config_container[iZone]->GetAD_Mode()) { if (config_container[iZone]->GetSmoothGradient()) { DerivativeTreatment_Gradient(geometry_container[iZone][INST_0][MESH_0], config_container[iZone], grid_movement[iZone][INST_0], surface_movement[iZone] , Gradient); } else { SetProjection_AD(geometry_container[iZone][INST_0][MESH_0], config_container[iZone], surface_movement[iZone] , Gradient); } - } else { - SetProjection_FD(geometry_container[iZone][INST_0][MESH_0], config_container[iZone], surface_movement[iZone] , Gradient); + } else { + SetProjection_FD(geometry_container[iZone][INST_0][MESH_0], config_container[iZone], surface_movement[iZone] , Gradient); + } } } // for iZone From 1b4ba30126576d9141d7b76c4ed72115d8ca2250 Mon Sep 17 00:00:00 2001 From: aa-g Date: Thu, 3 Mar 2022 22:58:57 +0100 Subject: [PATCH 21/68] Fix py_wrapper tests broken by new Python interface --- .../py_wrapper/disc_adj_fea/flow_load_sens/run_adjoint.py | 2 +- .../py_wrapper/disc_adj_flow/mesh_disp_sens/run_adjoint.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/TestCases/py_wrapper/disc_adj_fea/flow_load_sens/run_adjoint.py b/TestCases/py_wrapper/disc_adj_fea/flow_load_sens/run_adjoint.py index 1f994db4118..89006b9a53a 100755 --- a/TestCases/py_wrapper/disc_adj_fea/flow_load_sens/run_adjoint.py +++ b/TestCases/py_wrapper/disc_adj_fea/flow_load_sens/run_adjoint.py @@ -71,7 +71,7 @@ def main(): MarkerList = SU2Driver.GetAllBoundaryMarkersTag() # Get all the markers defined on this rank and their associated indices. - allMarkerIDs = SU2Driver.GetAllBoundaryMarkers() + allMarkerIDs = SU2Driver.GetBoundaryMarkerIndices() #Check if the specified marker exists and if it belongs to this rank. if MarkerName in MarkerList and MarkerName in allMarkerIDs.keys(): diff --git a/TestCases/py_wrapper/disc_adj_flow/mesh_disp_sens/run_adjoint.py b/TestCases/py_wrapper/disc_adj_flow/mesh_disp_sens/run_adjoint.py index f4ee6ed5b68..2229ad8ce5c 100755 --- a/TestCases/py_wrapper/disc_adj_flow/mesh_disp_sens/run_adjoint.py +++ b/TestCases/py_wrapper/disc_adj_flow/mesh_disp_sens/run_adjoint.py @@ -70,7 +70,7 @@ def main(): MarkerList = SU2Driver.GetAllBoundaryMarkersTag() # Get all the markers defined on this rank and their associated indices. - allMarkerIDs = SU2Driver.GetAllBoundaryMarkers() + allMarkerIDs = SU2Driver.GetBoundaryMarkerIndices() #Check if the specified marker exists and if it belongs to this rank. if MarkerName in MarkerList and MarkerName in allMarkerIDs.keys(): @@ -80,7 +80,7 @@ def main(): nVertex_Marker = 0 #total number of vertices (physical + halo) if MarkerID != None: - nVertex_Marker = SU2Driver.GetNumberVertices(MarkerID) + nVertex_Marker = SU2Driver.GetNumberVerticesMarker(MarkerID) # Time loop is defined in Python so that we have acces to SU2 functionalities at each time step if rank == 0: From 4a79c133f4fe29405961451de71c7e4a5fe9dbfd Mon Sep 17 00:00:00 2001 From: aa-g Date: Mon, 7 Mar 2022 20:12:46 +0100 Subject: [PATCH 22/68] Implement overleaded getters/setter --- Common/include/drivers/CDriverBase.hpp | 376 ++++++++-- Common/src/drivers/CDriverBase.cpp | 688 ++++++++++++------ SU2_CFD/include/drivers/CDriver.hpp | 16 +- SU2_CFD/src/python_wrapper_structure.cpp | 58 +- .../flow_load_sens/run_adjoint.py | 4 +- .../mesh_disp_sens/run_adjoint.py | 8 +- .../launch_flatPlate_rigidMotion.py | 17 +- .../launch_unsteady_CHT_FlatPlate.py | 15 +- 8 files changed, 832 insertions(+), 350 deletions(-) diff --git a/Common/include/drivers/CDriverBase.hpp b/Common/include/drivers/CDriverBase.hpp index 28619eab44e..6b9590fdd22 100644 --- a/Common/include/drivers/CDriverBase.hpp +++ b/Common/include/drivers/CDriverBase.hpp @@ -111,19 +111,30 @@ class CDriverBase { * \brief A virtual member. */ virtual void Postprocessing() {}; + /*! + * \brief Get the number of markers in the mesh. + * \return Number of markers. + */ + unsigned short GetNumberMarkers() const; /*! * \brief Get all the boundary markers tags with their associated indices. * \return List of boundary markers tags with their indices. */ - map GetBoundaryMarkerIndices() const; + map GetMarkerIndices() const; /*! * \brief Get all the boundary markers tags with their associated types. * \return List of boundary markers tags with their types. */ - map GetBoundaryMarkerTypes() const; + map GetMarkerTypes() const; + /*! + * \brief Get all the boundary marker tags. + * \return List of boundary markers tags. + */ + vector GetMarkerTags() const; + /*! * \brief Get all the deformable boundary marker tags. * \return List of deformable boundary markers tags. @@ -131,170 +142,393 @@ class CDriverBase { vector GetDeformableMarkerTags() const; /*! - * \brief Get the number of mesh dimensions. + * \brief Get the number of dimensions of the mesh. * \return Number of dimensions. */ unsigned long GetNumberDimensions() const; /*! - * \brief Get the number of mesh elements. + * \brief Get the number of elements in the mesh. * \return Number of elements. */ unsigned long GetNumberElements() const; /*! - * \brief Get the number of mesh elements from a specified marker. - * \param[in] iMarker - Marker identifier. + * \brief Get the number of elements in the marker. + * \param[in] iMarker - Marker index. * \return Number of elements. */ - unsigned long GetNumberElementsMarker(unsigned short iMarker) const; + unsigned long GetNumberMarkerElements(unsigned short iMarker) const; + + /*! + * \brief Get the global IDs of the mesh elements. + * \return Global element IDs. + */ + vector GetElementIDs() const; /*! - * \brief Get the number of mesh vertices. + * \brief Get the global ID of a mesh element. + * \param[in] iElem - Mesh element index. + * \return Global element ID. + */ + unsigned long GetElementIDs(unsigned long iElem) const; + + /*! + * \brief Get the global IDs of the marker elements. + * \param[in] iMarker - Marker index. + * \return Global element IDs. + */ + vector GetMarkerElementIDs(unsigned short iMarker) const; + + /*! + * \brief Get the global IDs of a marker element. + * \param[in] iMarker - Marker index. + * \param[in] iBound - Marker element index. + * \return Global element ID. + */ + unsigned long GetMarkerElementIDs(unsigned short iMarker, unsigned long iBound) const; + + /*! + * \brief Get the MPI colors for mesh elements. + * \return Element colors. + */ + vector GetElementColors() const; + + /*! + * \brief Get the MPI color for a mesh element. + * \param[in] iElem - Mesh element index. + * \return Element color. + */ + unsigned long GetElementColors(unsigned long iElem) const; + + /*! + * \brief Get the MPI colors for marker elements. + * \param[in] iMarker - Marker index. + * \return Element colors. + */ + vector GetMarkerElementColors(unsigned short iMarker) const; + + /*! + * \brief Get the MPI color for a marker element. + * \param[in] iMarker - Marker index. + * \param[in] iBound - Marker element index. + * \return Element color. + */ + unsigned long GetMarkerElementColors(unsigned short iMarker, unsigned long iBound) const; + + /*! + * \brief Get the table of vertex IDs belonging to the mesh elements. + * \return Element connectivities (nElem, nNode) + */ + vector> GetElementConnectivities() const; + + /*! + * \brief Get the row of vertex IDs belonging to a mesh element. + * \param[in] iElem - Mesh element index. + * \return Element connectivity (nNode) + */ + vector GetElementConnectivities(unsigned long iElem) const; + + /*! + * \brief Get the table of vertex IDs belonging to the marker elements. + * \param[in] iMarker - Marker index. + * \return Element connectivities (nBound, nNode). + */ + vector> GetMarkerElementConnectivities(unsigned short iMarker) const; + + /*! + * \brief Get the row of vertex IDs belonging to a marker element. + * \param[in] iMarker - Marker index. + * \param[in] iBound - Marker element index. + * \return Element connectivity (nNode). + */ + vector GetMarkerElementConnectivities(unsigned short iMarker, unsigned long iBound) const; + + /*! + * \brief Get the number of vertices in the mesh. * \return Number of vertices. */ unsigned long GetNumberVertices() const; /*! - * \brief Get the number of mesh vertices from a specified marker. - * \param[in] iMarker - Marker identifier. + * \brief Get the number of vertices in the marker. + * \param[in] iMarker - Marker index. * \return Number of vertices. */ - unsigned long GetNumberVerticesMarker(unsigned short iMarker) const; + unsigned long GetNumberMarkerVertices(unsigned short iMarker) const; /*! - * \brief Get the number of halo mesh vertices. + * \brief Get the number of halo vertices in the mesh. * \return Number of vertices. */ unsigned long GetNumberHaloVertices() const; /*! - * \brief Get the number of halo mesh vertices from a specified marker. - * \param[in] iMarker - Marker identifier. + * \brief Get the number of halo vertices in the marker. + * \param[in] iMarker - Marker index. * \return Number of vertices. */ - unsigned long GetNumberHaloVerticesMarker(unsigned short iMarker) const; + unsigned long GetNumberMarkerHaloVertices(unsigned short iMarker) const; /*! - * \brief Get global IDs of mesh vertices. + * \brief Get the mesh vertex indices of the marker vertices. + * \param[in] iMarker - Marker index. + * \return Mesh vertex indices. + */ + vector GetMarkerVertexIndex(unsigned short iMarker) const; + + /*! + * \brief Get the mesh vertex index of a marker vertex. + * \param[in] iMarker - Marker index. + * \param[in] iVertex - Marker vertex index. + * \return Mesh vertex index. + */ + unsigned long GetMarkerVertexIndex(unsigned short iMarker, unsigned long iVertex) const; + + /*! + * \brief Get the global IDs of the mesh vertices. * \return Global vertex IDs. */ vector GetVertexIDs() const; + + /*! + * \brief Get the global ID of a mesh vertex. + * \param[in] iPoint - Mesh vertex index. + * \return Global vertex ID. + */ + unsigned long GetVertexIDs(unsigned long iPoint) const; /*! - * \brief Get global IDs of mesh vertices. - * \param[in] iMarker - Marker identifier. + * \brief Get the global IDs of the marker vertices. + * \param[in] iMarker - Marker index. * \return Global vertex IDs. */ - vector GetVertexIDsMarker(unsigned short iMarker) const; + vector GetMarkerVertexIDs(unsigned short iMarker) const; /*! - * \brief Get global IDs of mesh elements. - * \return Global element IDs. + * \brief Get the global ID of a marker vertex. + * \param[in] iMarker - Marker index. + * \param[in] iVertex - Marker vertex index. + * \return Global vertex ID. */ - vector GetElementIDs() const; + unsigned long GetMarkerVertexIDs(unsigned short iMarker, unsigned long iVertex) const; /*! - * \brief Get global IDs of mesh elements. - * \param[in] iMarker - Marker identifier. - * \return Global element IDs. + * \brief Get the MPI colors of the mesh vertices. + * \return Vertex colors. */ - vector GetElementIDsMarker(unsigned short iMarker) const; + vector GetVertexColors() const; /*! - * \brief Get the connected point IDs of mesh elements. - * \return Element connectivities (nElem, nNode) + * \brief Get the MPI color of a mesh vertex. + * \param[in] iPoint - Mesh vertex index. + * \return Vertex color. */ - vector> GetConnectivity() const; + unsigned long GetVertexColors(unsigned long iPoint) const; /*! - * \brief Get the connected point IDs of mesh elements on a specified marker. - * \param[in] iMarker - Marker identifier. - * \return Element connectivities (nBound, nNode). + * \brief Get the MPI colors of the marker vertices. + * \param[in] iMarker - Marker index. + * \return Vertex colors. */ - vector> GetConnectivityMarker(unsigned short iMarker) const; + vector GetMarkerVertexColors(unsigned short iMarker) const; /*! - * \brief Get halo node stauts of mesh vertices. - * \return Point domain status. + * \brief Get the MPI color of a marker vertex. + * \param[in] iMarker - Marker index. + * \param[in] iVertex - Marker vertex index. + * \return Vertex color. + */ + unsigned long GetMarkerVertexColors(unsigned short iMarker, unsigned long iVertex) const; + + /*! + * \brief Get the halo flags of the mesh vertices. + * \return Vertex domain flags. */ vector GetDomain() const; /*! - * \brief Get halo node stauts of mesh marker vertices. - * \param[in] iMarker - Marker identifier. - * \return Point domain status. + * \brief Get the halo flag of a mesh vertex. + * \param[in] iPoint - Mesh vertex index. + * \return Vertex domain flag. + */ + bool GetDomain(unsigned long iPoint) const; + + /*! + * \brief Get the halo flags of the marker vertices. + * \param[in] iMarker - Marker index. + * \return Vertex domain flags. + */ + vector GetMarkerDomain(unsigned short iMarker) const; + + /*! + * \brief Get the halo flag of a marker vertex. + * \param[in] iMarker - Marker index. + * \param[in] iVertex - Marker vertex index. + * \return Vertex domain flag. + */ + bool GetMarkerDomain(unsigned short iMarker, unsigned long iVertex) const; + + /*! + * \brief Get the initial (un-deformed) coordinates of the mesh vertices. + * \return Initial vertex coordinates (nPoint*nDim). + */ + vector GetInitialCoordinates() const; + + /*! + * \brief Get the initial (un-deformed) coordinates of a mesh vertex. + * \param[in] iPoint - Mesh vertex index. + * \return Initial vertex coordinates (nDim). + */ + vector GetInitialCoordinates(unsigned long iPoint) const; + + /*! + * \brief Get the initial (un-deformed) coordinates of the marker vertices. + * \param[in] iMarker - Marker index. + * \return Initial vertex coordinates (nVertex*nDim). + */ + vector GetMarkerInitialCoordinates(unsigned short iMarker) const; + + /*! + * \brief Get the initial (un-deformed) coordinates of a marker vertex. + * \param[in] iMarker - Marker index. + * \param[in] iVertex - Marker vertex index. + * \return Initial vertex coordinates (nDim). */ - vector GetDomainMarker(unsigned short iMarker) const; + vector GetMarkerInitialCoordinates(unsigned short iMarker, unsigned long iVertex) const; /*! - * \brief Get the coordinates of the mesh points. - * \return Point coordinates (nPoint*nDim). + * \brief Get the coordinates of the mesh vertices. + * \return Vertex coordinates (nPoint*nDim). */ vector GetCoordinates() const; + + /*! + * \brief Get the coordinates of a mesh vertex. + * \param[in] iPoint - Mesh vertex index. + * \return Vertex coordinates (nDim). + */ + vector GetCoordinates(unsigned long iPoint) const; + + /*! + * \brief Get the coordinates of the marker vertices. + * \param[in] iMarker - Marker index. + * \return Vertex coordinates (nVertex*nDim). + */ + vector GetMarkerCoordinates(unsigned short iMarker) const; /*! - * \brief Get the coordinates of the mesh points on the specified marker. - * \param[in] iMarker - Marker identifier. - * \return Point coordinates (nVertex*nDim). + * \brief Get the coordinates of a marker vertex. + * \param[in] iMarker - Marker index. + * \param[in] iVertex - Marker vertex index. + * \return Vertex coordinates (nDim). */ - vector GetCoordinatesMarker(unsigned short iMarker) const; + vector GetMarkerCoordinates(unsigned short iMarker, unsigned long iVertex) const; /*! - * \brief Set the coordinates of the mesh points. - * \param[in] values - Point coordinates (nPoint*nDim). + * \brief Set the coordinates of the mesh vertices. + * \param[in] values - Vertex coordinates (nPoint*nDim). */ void SetCoordinates(vector values); /*! - * \brief Set the coordinates of the mesh points on the specified marker. - * \param[in] iMarker - Marker identifier. - * \param[in] values - Point coordinates (nVertex*nDim). + * \brief Set the coordinates of a mesh vertex. + * \param[in] iPoint - Mesh vertex index. + * \param[in] values - Vertex coordinates (nDim). + */ + void SetCoordinates(unsigned long iPoint, vector values); + + /*! + * \brief Set the coordinates of the marker vertices. + * \param[in] iMarker - Marker index. + * \param[in] values - Vertex coordinates (nVertex*nDim). + */ + void SetMarkerCoordinates(unsigned short iMarker, vector values); + + /*! + * \brief Set the coordinates of a marker vertex. + * \param[in] iMarker - Marker index. + * \param[in] iVertex - Marker vertex index. + * \param[in] values - Vertex coordinates (nDim). */ - void SetCoordinatesMarker(unsigned short iMarker, vector values); + void SetMarkerCoordinates(unsigned short iMarker, unsigned long iVertex, vector values); /*! - * \brief Get the vertex displacements on the specified marker. - * \param[in] iMarker - Marker identifier. + * \brief Get the displacements of the marker vertices. + * \param[in] iMarker - Marker index. * \return Vertex displacements (nVertex*nDim). */ - vector GetDisplacementsMarker(unsigned short iMarker) const; + vector GetMarkerDisplacements(unsigned short iMarker) const; /*! - * \brief Set the vertex displacements on the specified marker. - * \param[in] iMarker - Marker identifier. + * \brief Get the displacements of a marker vertex. + * \param[in] iMarker - Marker index. + * \param[in] iVertex - Marker vertex index. + * \return Vertex displacements (nDim). + */ + vector GetMarkerDisplacements(unsigned short iMarker, unsigned long iVertex) const; + + /*! + * \brief Set the displacements of the marker vertices. + * \param[in] iMarker - Marker index. * \param[in] values - Vertex displacements (nVertex*nDim). */ - void SetDisplacementsMarker(unsigned short iMarker, vector values); + void SetMarkerDisplacements(unsigned short iMarker, vector values); /*! - * \brief Get the vertex velocities on the specified marker. - * \param[in] iMarker - Marker identifier. + * \brief Set the displacements of a marker vertex. + * \param[in] iMarker - Marker index. + * \param[in] iVertex - Marker vertex index. + * \param[in] values - Vertex displacements (nDim). + */ + void SetMarkerDisplacements(unsigned short iMarker, unsigned long iVertex, vector values); + + /*! + * \brief Get the velocities of the marker vertices. + * \param[in] iMarker - Marker index. * \return Vertex velocities (nVertex*nDim). */ - vector GetVelocitiesMarker(unsigned short iMarker) const; + vector GetMarkerVelocities(unsigned short iMarker) const; + + /*! + * \brief Get the velocities of a marker vertex. + * \param[in] iMarker - Marker index. + * \param[in] iVertex - Marker vertex index. + * \return Vertex velocities (nVertex*nDim). + */ + vector GetMarkerVelocities(unsigned short iMarker, unsigned long iVertex) const; /*! - * \brief Set the vertex velocities on the specified marker. - * \param[in] iMarker - Marker identifier. + * \brief Set the velocities of the marker vertices. + * \param[in] iMarker - Marker index. * \param[in] values - Vertex velocities (nVertex*nDim). */ - void SetVelocitiesMarker(unsigned short iMarker, vector values); + void SetMarkerVelocities(unsigned short iMarker, vector values); /*! - * \brief Get undeformed coordinates from mesh solver on the specified marker. - * \param[in] iMarker - Marker identifier. - * \return Initial point coordinates (nVertex*nDim). + * \brief Set the velocities of a marker vertex. + * \param[in] iMarker - Marker index. + * \param[in] iVertex - Marker vertex index. + * \param[in] values - Vertex velocities (nDim). */ - vector GetInitialCoordinatesMarker(unsigned short iMarker) const; + void SetMarkerVelocities(unsigned short iMarker, unsigned long iVertex, vector values); /*! - * \brief Get the vertex normal vectors on the specified marker. - * \param[in] iMarker - Marker identifier. - * \param[in] UnitNormal - Boolean to indicate if unit normal vector should be returned. + * \brief Get the normal vectors at the marker vertices. + * \param[in] iMarker - Marker index. + * \param[in] normalize - If true, the unit (i.e. normalized) normal vector is returned. * \return Normal vector at the vertex (nVertex*nDim). */ - vector GetVertexNormalsMarker(unsigned short iMarker, bool UnitNormal = false) const; + vector GetMarkerVertexNormals(unsigned short iMarker, bool normalize = false) const; + + /*! + * \brief Get the normal vectors at a marker vertex. + * \param[in] iMarker - Marker index. + * \param[in] iVertex - Marker vertex index. + * \param[in] normalize - If true, the unit (i.e. normalized) normal vector is returned. + * \return Normal vector at the vertex (nDim). + */ + vector GetMarkerVertexNormals(unsigned short iMarker, unsigned long iVertex, bool normalize = false) const; /*! * \brief Communicate the boundary mesh displacements in a python call diff --git a/Common/src/drivers/CDriverBase.cpp b/Common/src/drivers/CDriverBase.cpp index 98d05d65305..9a3ee6ba686 100644 --- a/Common/src/drivers/CDriverBase.cpp +++ b/Common/src/drivers/CDriverBase.cpp @@ -82,78 +82,85 @@ void CDriverBase::SetContainers_Null() { driver_output = nullptr; } -map CDriverBase::GetBoundaryMarkerIndices() const { - CConfig* config = config_container[ZONE_0]; - - const auto nBoundaryMarkers = config->GetnMarker_All(); - map allBoundariesMap; +unsigned short CDriverBase::GetNumberMarkers() const { + return config_container[ZONE_0]->GetnMarker_All(); +} + +map CDriverBase::GetMarkerIndices() const { + const auto nMarker = config_container[ZONE_0]->GetnMarker_All(); + map indexMap; - for (auto iMarker = 0u; iMarker < nBoundaryMarkers; iMarker++) { - auto Marker_Tag = config->GetMarker_All_TagBound(iMarker); - allBoundariesMap[Marker_Tag] = iMarker; + for (auto iMarker = 0u; iMarker < nMarker; iMarker++) { + auto tag = config_container[ZONE_0]->GetMarker_All_TagBound(iMarker); + + indexMap[tag] = iMarker; } - return allBoundariesMap; + return indexMap; } -map CDriverBase::GetBoundaryMarkerTypes() const { - CConfig* config = config_container[ZONE_0]; +map CDriverBase::GetMarkerTypes() const { + map typeMap; + string type; - map allBoundariesTypeMap; - string Marker_Type; - - for (auto iMarker = 0u; iMarker < config->GetnMarker_All(); iMarker++) { - auto Marker_Tag = config->GetMarker_All_TagBound(iMarker); - auto KindBC = config->GetMarker_All_KindBC(iMarker); + for (auto iMarker = 0u; iMarker < config_container[ZONE_0]->GetnMarker_All(); iMarker++) { + auto tag = config_container[ZONE_0]->GetMarker_All_TagBound(iMarker); + auto kindBC = config_container[ZONE_0]->GetMarker_All_KindBC(iMarker); - switch(KindBC) { + switch(kindBC) { case EULER_WALL: - Marker_Type = "EULER_WALL"; + type = "EULER_WALL"; break; case FAR_FIELD: - Marker_Type = "FARFIELD"; + type = "FARFIELD"; break; case ISOTHERMAL: - Marker_Type = "ISOTHERMAL"; + type = "ISOTHERMAL"; break; case HEAT_FLUX: - Marker_Type = "HEATFLUX"; + type = "HEATFLUX"; break; case INLET_FLOW: - Marker_Type = "INLET_FLOW"; + type = "INLET_FLOW"; break; case OUTLET_FLOW: - Marker_Type = "OUTLET_FLOW"; + type = "OUTLET_FLOW"; break; case SYMMETRY_PLANE: - Marker_Type = "SYMMETRY"; + type = "SYMMETRY"; break; case SEND_RECEIVE: - Marker_Type = "SEND_RECEIVE"; + type = "SEND_RECEIVE"; break; default: - Marker_Type = "UNKNOWN_TYPE"; + type = "UNKNOWN_TYPE"; } - allBoundariesTypeMap[Marker_Tag] = Marker_Type; + typeMap[tag] = type; } - return allBoundariesTypeMap; + return typeMap; } -vector CDriverBase::GetDeformableMarkerTags() const { - CConfig* config = config_container[ZONE_0]; +vector CDriverBase::GetMarkerTags() const { + vector tags; + const auto nMarker = config_container[ZONE_0]->GetnMarker_All(); - const auto nBoundariesMarker = config->GetnMarker_Deform_Mesh(); - vector interfaceBoundariesTagList; + for(auto iMarker = 0u; iMarker < nMarker; iMarker++){ + tags.push_back(config_container[ZONE_0]->GetMarker_All_TagBound(iMarker)); + } - interfaceBoundariesTagList.resize(nBoundariesMarker); + return tags; +} + +vector CDriverBase::GetDeformableMarkerTags() const { + vector tags; + const auto nMarker = config_container[ZONE_0]->GetnMarker_All(); - for (auto iMarker = 0u; iMarker < nBoundariesMarker; iMarker++) { - auto Marker_Tag = config->GetMarker_Deform_Mesh_TagBound(iMarker); - interfaceBoundariesTagList[iMarker] = Marker_Tag; + for (auto iMarker = 0u; iMarker < nMarker; iMarker++) { + tags.push_back(config_container[ZONE_0]->GetMarker_Deform_Mesh_TagBound(iMarker)); } - return interfaceBoundariesTagList; + return tags; } unsigned long CDriverBase::GetNumberDimensions() const { @@ -164,26 +171,160 @@ unsigned long CDriverBase::GetNumberElements() const { return geometry_container[ZONE_0][INST_0][MESH_0]->GetnElem(); } -unsigned long CDriverBase::GetNumberElementsMarker(unsigned short iMarker) const { +unsigned long CDriverBase::GetNumberMarkerElements(unsigned short iMarker) const { + if (iMarker >= GetNumberMarkers()) { + SU2_MPI::Error("Marker index exceeds size.", CURRENT_FUNCTION); + } + return geometry_container[ZONE_0][INST_0][MESH_0]->GetnElem_Bound(iMarker); } +vector CDriverBase::GetElementIDs() const { + vector values; + const auto nElem = GetNumberElements(); + + for (auto iElem = 0ul; iElem < nElem; iElem++) { + values.push_back(GetElementIDs(iElem)); + } + + return values; +} + +unsigned long CDriverBase::GetElementIDs(unsigned long iElem) const { + if (iElem >= GetNumberElements()) { + SU2_MPI::Error("Element index exceeds size.", CURRENT_FUNCTION); + } + + return geometry_container[ZONE_0][INST_0][MESH_0]->elem[iElem]->GetGlobalIndex(); +} + +vector CDriverBase::GetMarkerElementIDs(unsigned short iMarker) const { + vector values; + const auto nBound = GetNumberMarkerElements(iMarker); + + for (auto iBound = 0ul; iBound < nBound; iBound++) { + values.push_back(GetMarkerElementIDs(iMarker, iBound)); + } + + return values; +} + +unsigned long CDriverBase::GetMarkerElementIDs(unsigned short iMarker, unsigned long iBound) const { + if (iBound >= GetNumberMarkerElements(iMarker)) { + SU2_MPI::Error("Marker element index exceeds size.", CURRENT_FUNCTION); + } + + return geometry_container[ZONE_0][INST_0][MESH_0]->bound[iMarker][iBound]->GetGlobalIndex(); +} + +vector CDriverBase::GetElementColors() const { + vector values; + const auto nElem = GetNumberElements(); + + for (auto iElem = 0ul; iElem < nElem; iElem++) { + values.push_back(GetElementColors(iElem)); + } + + return values; +} + +unsigned long CDriverBase::GetElementColors(unsigned long iElem) const { + if (iElem >= GetNumberElements()) { + SU2_MPI::Error("Element index exceeds size.", CURRENT_FUNCTION); + } + + return geometry_container[ZONE_0][INST_0][MESH_0]->elem[iElem]->GetColor(); +} + +vector CDriverBase::GetMarkerElementColors(unsigned short iMarker) const { + vector values; + const auto nBound = GetNumberMarkerElements(iMarker); + + for (auto iBound = 0ul; iBound < nBound; iBound++) { + values.push_back(GetMarkerElementColors(iMarker, iBound)); + } + + return values; +} + +unsigned long CDriverBase::GetMarkerElementColors(unsigned short iMarker, unsigned long iBound) const { + if (iBound >= GetNumberMarkerElements(iMarker)) { + SU2_MPI::Error("Marker element index exceeds size.", CURRENT_FUNCTION); + } + + return geometry_container[ZONE_0][INST_0][MESH_0]->bound[iMarker][iBound]->GetColor(); +} + +vector> CDriverBase::GetElementConnectivities() const { + vector> values; + const auto nElem = GetNumberElements(); + + for (auto iElem = 0ul; iElem < nElem; iElem++) { + values.push_back(GetElementConnectivities(iElem)); + } + + return values; +} + +vector CDriverBase::GetElementConnectivities(unsigned long iElem) const { + if (iElem >= GetNumberElements()) { + SU2_MPI::Error("Element index exceeds size.", CURRENT_FUNCTION); + } + + vector values; + unsigned short nNode = geometry_container[ZONE_0][INST_0][MESH_0]->elem[iElem]->GetnNodes(); + + for (auto iNode = 0u; iNode < nNode; iNode++) { + values.push_back(geometry_container[ZONE_0][INST_0][MESH_0]->elem[iElem]->GetNode(iNode)); + } + + return values; +} + +vector> CDriverBase::GetMarkerElementConnectivities(unsigned short iMarker) const { + vector> values; + const auto nBound = GetNumberMarkerElements(iMarker); + + for (auto iBound = 0ul; iBound < nBound; iBound++) { + values.push_back(GetMarkerElementConnectivities(iMarker, iBound)); + } + + return values; +} + +vector CDriverBase::GetMarkerElementConnectivities(unsigned short iMarker, unsigned long iBound) const { + if (iBound >= GetNumberMarkerElements(iMarker)) { + SU2_MPI::Error("Marker element index exceeds size.", CURRENT_FUNCTION); + } + + vector values; + unsigned short nNode = geometry_container[ZONE_0][INST_0][MESH_0]->bound[iMarker][iBound]->GetnNodes(); + + for (auto iNode = 0u; iNode < nNode; iNode++) { + values.push_back(geometry_container[ZONE_0][INST_0][MESH_0]->bound[iMarker][iBound]->GetNode(iNode)); + } + + return values; +} + unsigned long CDriverBase::GetNumberVertices() const { return geometry_container[ZONE_0][INST_0][MESH_0]->GetnPoint(); } -unsigned long CDriverBase::GetNumberVerticesMarker(unsigned short iMarker) const { +unsigned long CDriverBase::GetNumberMarkerVertices(unsigned short iMarker) const { + if (iMarker >= GetNumberMarkers()) { + SU2_MPI::Error("Marker index exceeds size.", CURRENT_FUNCTION); + } + return geometry_container[ZONE_0][INST_0][MESH_0]->GetnVertex(iMarker); } unsigned long CDriverBase::GetNumberHaloVertices() const { - CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; - - const auto nPoint = geometry->GetnPoint(); + const auto nPoint = GetNumberVertices(); unsigned long nHaloVertices = 0; for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { - if (!(geometry->nodes->GetDomain(iPoint))) { + if (!(geometry_container[ZONE_0][INST_0][MESH_0]->nodes->GetDomain(iPoint))) { nHaloVertices += 1; } } @@ -191,15 +332,14 @@ unsigned long CDriverBase::GetNumberHaloVertices() const { return nHaloVertices; } -unsigned long CDriverBase::GetNumberHaloVerticesMarker(unsigned short iMarker) const { - CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; - - const auto nVertex = geometry->GetnVertex(iMarker); +unsigned long CDriverBase::GetNumberMarkerHaloVertices(unsigned short iMarker) const { + const auto nVertex = GetNumberMarkerVertices(iMarker); // error-checking included unsigned long nHaloVertices = 0; for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - auto iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); - if (!(geometry->nodes->GetDomain(iPoint))) { + auto iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); + + if (!(geometry_container[ZONE_0][INST_0][MESH_0]->nodes->GetDomain(iPoint))) { nHaloVertices += 1; } } @@ -207,338 +347,474 @@ unsigned long CDriverBase::GetNumberHaloVerticesMarker(unsigned short iMarker) c return nHaloVertices; } -vector CDriverBase::GetVertexIDs() const { - CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; +vector CDriverBase::GetMarkerVertexIndex(unsigned short iMarker) const { + vector values; + const auto nVertex = GetNumberMarkerVertices(iMarker); + + for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { + values.push_back(GetMarkerVertexIndex(iMarker, iVertex)); + } + + return values; +} + +unsigned long CDriverBase::GetMarkerVertexIndex(unsigned short iMarker, unsigned long iVertex) const { + if (iVertex >= GetNumberMarkerVertices(iMarker)) { + SU2_MPI::Error("Marker vertex index exceeds size.", CURRENT_FUNCTION); + } - const auto nPoint = geometry->GetnPoint(); + return geometry_container[MESH_0][INST_0][ZONE_0]->vertex[iMarker][iVertex]->GetNode(); +} + +vector CDriverBase::GetVertexIDs() const { vector values; + const auto nPoint = GetNumberVertices(); for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { - values.push_back(geometry->nodes->GetGlobalIndex(iPoint)); + values.push_back(GetVertexIDs(iPoint)); } return values; } -vector CDriverBase::GetVertexIDsMarker(unsigned short iMarker) const { - CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; - - const auto nVertex = geometry->GetnVertex(iMarker); +unsigned long CDriverBase::GetVertexIDs(unsigned long iPoint) const { + if (iPoint >= GetNumberVertices()) { + SU2_MPI::Error("Vertex index exceeds size.", CURRENT_FUNCTION); + } + + return geometry_container[ZONE_0][INST_0][MESH_0]->nodes->GetGlobalIndex(iPoint); +} + +vector CDriverBase::GetMarkerVertexIDs(unsigned short iMarker) const { vector values; + const auto nVertex = GetNumberMarkerVertices(iMarker); for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - auto iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); - - values.push_back(geometry->nodes->GetGlobalIndex(iPoint)); + values.push_back(GetMarkerVertexIDs(iMarker, iVertex)); } return values; } -vector CDriverBase::GetElementIDs() const { - CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; - - const auto nElem = geometry->GetnElem(); +unsigned long CDriverBase::GetMarkerVertexIDs(unsigned short iMarker, unsigned long iVertex) const { + auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); // includes error-checking + + return geometry_container[ZONE_0][INST_0][MESH_0]->nodes->GetGlobalIndex(iPoint); +} + +vector CDriverBase::GetVertexColors() const { vector values; + const auto nPoint = GetNumberVertices(); - for (auto iElem = 0ul; iElem < nElem; iElem++) { - values.push_back(geometry->elem[iElem]->GetGlobalIndex()); + for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { + values.push_back(GetVertexColors(iPoint)); } return values; } -vector CDriverBase::GetElementIDsMarker(unsigned short iMarker) const { - CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; - - const auto nBound = geometry->GetnElem_Bound(iMarker); +unsigned long CDriverBase::GetVertexColors(unsigned long iPoint) const { + if (iPoint >= GetNumberVertices()) { + SU2_MPI::Error("Vertex index exceeds size.", CURRENT_FUNCTION); + } + + return geometry_container[ZONE_0][INST_0][MESH_0]->nodes->GetColor(iPoint); +} + +vector CDriverBase::GetMarkerVertexColors(unsigned short iMarker) const { vector values; + const auto nVertex = GetNumberMarkerVertices(iMarker); - for (auto iBound = 0ul; iBound < nBound; iBound++) { - values.push_back(geometry->bound[iMarker][iBound]->GetGlobalIndex()); + for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { + values.push_back(GetMarkerVertexColors(iMarker, iVertex)); } return values; } -vector> CDriverBase::GetConnectivity() const { - CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; +unsigned long CDriverBase::GetMarkerVertexColors(unsigned short iMarker, unsigned long iVertex) const { + auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); // includes error-checking - const auto nElem = geometry->GetnElem(); - vector> values(nElem); + return geometry_container[ZONE_0][INST_0][MESH_0]->nodes->GetColor(iPoint); +} + +vector CDriverBase::GetDomain() const { + vector values; + const auto nPoint = GetNumberVertices(); - for (auto iElem = 0ul; iElem < nElem; iElem++) { - unsigned short nNode = geometry->elem[iElem]->GetnNodes(); - - for (auto iNode = 0u; iNode < nNode; iNode++) { - values[iElem].push_back(geometry->elem[iElem]->GetNode(iNode)); - } + for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { + values.push_back(GetDomain(iPoint)); } return values; } -vector> CDriverBase::GetConnectivityMarker(unsigned short iMarker) const { - CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; +bool CDriverBase::GetDomain(unsigned long iPoint) const { + if (iPoint >= GetNumberVertices()) { + SU2_MPI::Error("Vertex index exceeds size.", CURRENT_FUNCTION); + } - const auto nBound = geometry->GetnElem_Bound(iMarker); - vector> values(nBound); + return geometry_container[ZONE_0][INST_0][MESH_0]->nodes->GetDomain(iPoint); +} + +vector CDriverBase::GetMarkerDomain(unsigned short iMarker) const { + vector values; + const auto nVertex = GetNumberMarkerVertices(iMarker); - for (auto iBound = 0ul; iBound < nBound; iBound++) { - unsigned short nNode = geometry->bound[iMarker][iBound]->GetnNodes(); - - for (auto iNode = 0u; iNode < nNode; iNode++) { - values[iBound].push_back(geometry->bound[iMarker][iBound]->GetNode(iNode)); - } + for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { + values.push_back(GetMarkerDomain(iMarker, iVertex)); } return values; } -vector CDriverBase::GetDomain() const { - CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; +bool CDriverBase::GetMarkerDomain(unsigned short iMarker, unsigned long iVertex) const { + auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); - const auto nPoint = geometry->GetnPoint(); - vector values; + return geometry_container[ZONE_0][INST_0][MESH_0]->nodes->GetDomain(iPoint); +} + +vector CDriverBase::GetInitialCoordinates() const { + const auto nPoint = GetNumberVertices(); + vector values; for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { - values.push_back(geometry->nodes->GetDomain(iPoint)); + const auto value = GetInitialCoordinates(iPoint); + + for (auto iDim = 0u; iDim < nDim; iDim++) { + values.push_back(value[iDim]); + } } return values; } -vector CDriverBase::GetDomainMarker(unsigned short iMarker) const { - CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; +vector CDriverBase::GetInitialCoordinates(unsigned long iPoint) const { + if (iPoint >= GetNumberVertices()) { + SU2_MPI::Error("Vertex index exceeds size.", CURRENT_FUNCTION); + } + + vector values; + + for (auto iDim = 0u; iDim < nDim; iDim++) { + const su2double value = solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->GetMesh_Coord(iPoint, iDim); + + if (!config_container[ZONE_0]->GetDeform_Mesh()) { + values.push_back(0.0); // mesh solver is not defined ! + } + else { + values.push_back(SU2_TYPE::GetValue(value)); + } + } - const auto nVertex = geometry->GetnVertex(iMarker); - vector values; + return values; +} + +vector CDriverBase::GetMarkerInitialCoordinates(unsigned short iMarker) const { + const auto nVertex = GetNumberMarkerVertices(iMarker); + vector values; for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - auto iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + const auto value = GetMarkerInitialCoordinates(iVertex); - values.push_back(geometry->nodes->GetDomain(iPoint)); + for (auto iDim = 0u; iDim < nDim; iDim++) { + values.push_back(value[iDim]); + } } return values; } -vector CDriverBase::GetCoordinates() const { - CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; +vector CDriverBase::GetMarkerInitialCoordinates(unsigned short iMarker, unsigned long iVertex) const { + auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); + vector values; + + for (auto iDim = 0u; iDim < nDim; iDim++) { + const su2double value = solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->GetMesh_Coord(iPoint, iDim); + + if (!config_container[ZONE_0]->GetDeform_Mesh()) { + values.push_back(0.0); // mesh solver is not defined ! + } + else { + values.push_back(SU2_TYPE::GetValue(value)); + } + } - const auto nPoint = geometry->GetnPoint(); - vector values(nPoint*nDim, 0.0); - su2double value; + return values; +} + +vector CDriverBase::GetCoordinates() const { + const auto nPoint = GetNumberVertices(); + vector values; for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { + const auto value = GetCoordinates(iPoint); + for (auto iDim = 0u; iDim < nDim; iDim++) { - value = geometry->nodes->GetCoord(iPoint, iDim); - values[iPoint*nDim + iDim] = SU2_TYPE::GetValue(value); + values.push_back(value[iDim]); } } return values; } -vector CDriverBase::GetCoordinatesMarker(unsigned short iMarker) const { - CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; +vector CDriverBase::GetCoordinates(unsigned long iPoint) const { + const auto nPoint = GetNumberVertices(); + vector values; + + for (auto iDim = 0u; iDim < nDim; iDim++) { + const su2double value = geometry_container[ZONE_0][INST_0][MESH_0]->nodes->GetCoord(iPoint, iDim); + + values.push_back(SU2_TYPE::GetValue(value)); + } - const auto nVertex = geometry->GetnVertex(iMarker); - vector values(nVertex*nDim, 0.0); - su2double value; + return values; +} + +vector CDriverBase::GetMarkerCoordinates(unsigned short iMarker) const { + const auto nVertex = GetNumberMarkerVertices(iMarker); + vector values; for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - auto iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + const auto value = GetMarkerCoordinates(iVertex); for (auto iDim = 0u; iDim < nDim; iDim++) { - value = geometry->nodes->GetCoord(iPoint, iDim); - values[iVertex*nDim + iDim] = SU2_TYPE::GetValue(value); + values.push_back(value[iDim]); } } return values; } +vector CDriverBase::GetMarkerCoordinates(unsigned short iMarker, unsigned long iVertex) const { + auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); + vector values; + + for (auto iDim = 0u; iDim < nDim; iDim++) { + const su2double value = geometry_container[ZONE_0][INST_0][MESH_0]->nodes->GetCoord(iPoint, iDim); + + values.push_back(SU2_TYPE::GetValue(value)); + } + + return values; +} + void CDriverBase::SetCoordinates(vector values) { - CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; + const auto nPoint = GetNumberVertices(); - const auto nPoint = geometry->GetnPoint(); if (values.size() != nPoint*nDim) { SU2_MPI::Error("Size does not match nPoint * nDim!", CURRENT_FUNCTION); } for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { for (auto iDim = 0u; iDim < nDim; iDim++) { - geometry->nodes->SetCoord(iPoint, iDim, values[iPoint*nDim + iDim]); + geometry_container[ZONE_0][INST_0][MESH_0]->nodes->SetCoord(iPoint, iDim, values[iPoint*nDim + iDim]); } } } -void CDriverBase::SetCoordinatesMarker(unsigned short iMarker, vector values) { - CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; +void CDriverBase::SetCoordinates(unsigned long iPoint, vector values) { + if (values.size() != nDim) { + SU2_MPI::Error("Size does not match nDim!", CURRENT_FUNCTION); + } - const auto nVertex = geometry->GetnVertex(iMarker); + for (auto iDim = 0u; iDim < nDim; iDim++) { + geometry_container[ZONE_0][INST_0][MESH_0]->nodes->SetCoord(iPoint, iDim, values[iDim]); + } +} + +void CDriverBase::SetMarkerCoordinates(unsigned short iMarker, vector values) { + const auto nVertex = GetNumberMarkerVertices(iMarker); + if (values.size() != nVertex*nDim) { SU2_MPI::Error("Size does not match nVertex * nDim!", CURRENT_FUNCTION); } for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - auto iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); for (auto iDim = 0u; iDim < nDim; iDim++) { - geometry->nodes->SetCoord(iPoint, iDim, values[iVertex*nDim + iDim]); + geometry_container[ZONE_0][INST_0][MESH_0]->nodes->SetCoord(iPoint, iDim, values[iVertex*nDim + iDim]); } } } -vector CDriverBase::GetDisplacementsMarker(unsigned short iMarker) const { - CConfig* config = config_container[ZONE_0]; - CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; - CSolver* solver = solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]; - - if (!config->GetDeform_Mesh()) { - return {}; +void CDriverBase::SetMarkerCoordinates(unsigned short iMarker, unsigned long iVertex, vector values) { + if (values.size() != nDim) { + SU2_MPI::Error("Size does not match nDim!", CURRENT_FUNCTION); } - const auto nVertex = geometry->GetnVertex(iMarker); - vector values(nVertex*nDim, 0.0); - su2double value; + auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); + + for (auto iDim = 0u; iDim < nDim; iDim++) { + geometry_container[ZONE_0][INST_0][MESH_0]->nodes->SetCoord(iPoint, iDim, values[iDim]); + } +} + +vector CDriverBase::GetMarkerDisplacements(unsigned short iMarker) const { + const auto nVertex = GetNumberMarkerVertices(iMarker); + vector values; for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - auto iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + const auto value = GetMarkerDisplacements(iMarker, iVertex); for (auto iDim = 0u; iDim < nDim; iDim++) { - value = solver->GetNodes()->GetBound_Disp(iPoint, iDim); - values[iVertex*nDim + iDim] = SU2_TYPE::GetValue(value); + values.push_back(values[iDim]); } } return values; } -void CDriverBase::SetDisplacementsMarker(unsigned short iMarker, vector values) { - CConfig* config = config_container[ZONE_0]; - CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; - CSolver* solver = solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]; +vector CDriverBase::GetMarkerDisplacements(unsigned short iMarker, unsigned long iVertex) const { + auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); + vector values; - if (!config->GetDeform_Mesh()) { - SU2_MPI::Error("Mesh solver is not defined!", CURRENT_FUNCTION); + for (auto iDim = 0u; iDim < nDim; iDim++) { + const su2double value = solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->GetBound_Disp(iPoint, iDim); + + values.push_back(SU2_TYPE::GetValue(value)); } - const auto nVertex = geometry->GetnVertex(iMarker); + return values; +} + +void CDriverBase::SetMarkerDisplacements(unsigned short iMarker, vector values) { + if (!config_container[ZONE_0]->GetDeform_Mesh()) { + SU2_MPI::Error("Mesh solver is not defined!", CURRENT_FUNCTION); + } + + const auto nVertex = GetNumberMarkerVertices(iMarker); + if (values.size() != nVertex*nDim) { SU2_MPI::Error("Size does not match nVertex * nDim!", CURRENT_FUNCTION); } for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - auto iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); for (auto iDim = 0u; iDim < nDim; iDim++) { - solver->GetNodes()->SetBound_Disp(iPoint, iDim, values[iVertex*nDim + iDim]); + solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->SetBound_Disp(iPoint, iDim, values[iVertex*nDim + iDim]); } } } -vector CDriverBase::GetVelocitiesMarker(unsigned short iMarker) const { - CConfig* config = config_container[ZONE_0]; - CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; - CSolver* solver = solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]; - - if (!config->GetDeform_Mesh()) { - return {}; +void CDriverBase::SetMarkerDisplacements(unsigned short iMarker, unsigned long iVertex, vector values) { + if (!config_container[ZONE_0]->GetDeform_Mesh()) { + SU2_MPI::Error("Mesh solver is not defined!", CURRENT_FUNCTION); + } + if (values.size() != nDim) { + SU2_MPI::Error("Size does not match nDim!", CURRENT_FUNCTION); } - const auto nVertex = geometry->GetnVertex(iMarker); - vector values(nVertex*nDim, 0.0); - su2double value; + auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); + + for (auto iDim = 0u; iDim < nDim; iDim++) { + solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->SetBound_Disp(iPoint, iDim, values[iDim]); + } +} + +vector CDriverBase::GetMarkerVelocities(unsigned short iMarker) const { + const auto nVertex = GetNumberMarkerVertices(iMarker); + vector values; for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - auto iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + const auto value = GetMarkerVelocities(iMarker, iVertex); for (auto iDim = 0u; iDim < nDim; iDim++) { - value = solver->GetNodes()->GetBound_Vel(iPoint, iDim); - values[iVertex*nDim + iDim] = SU2_TYPE::GetValue(value); + values.push_back(values[iDim]); } } return values; } -void CDriverBase::SetVelocitiesMarker(unsigned short iMarker, vector values) { - CConfig* config = config_container[ZONE_0]; - CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; - CSolver* solver = solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]; +vector CDriverBase::GetMarkerVelocities(unsigned short iMarker, unsigned long iVertex) const { + auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); + vector values; - if (!config->GetDeform_Mesh()) { - SU2_MPI::Error("Mesh solver is not defined!", CURRENT_FUNCTION); + for (auto iDim = 0u; iDim < nDim; iDim++) { + const su2double value = solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->GetBound_Vel(iPoint, iDim); + + values.push_back(SU2_TYPE::GetValue(value)); } - const auto nVertex = geometry->GetnVertex(iMarker); + return values; +} + +void CDriverBase::SetMarkerVelocities(unsigned short iMarker, vector values) { + if (!config_container[ZONE_0]->GetDeform_Mesh()) { + SU2_MPI::Error("Mesh solver is not defined!", CURRENT_FUNCTION); + } + + const auto nVertex = GetNumberMarkerVertices(iMarker); + if (values.size() != nVertex*nDim) { SU2_MPI::Error("Size does not match nVertex * nDim!", CURRENT_FUNCTION); } for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - auto iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); for (auto iDim = 0u; iDim < nDim; iDim++) { - solver->GetNodes()->SetBound_Vel(iPoint, iDim, values[iVertex*nDim + iDim]); + solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->SetBound_Disp(iPoint, iDim, values[iVertex*nDim + iDim]); } } } -vector CDriverBase::GetInitialCoordinatesMarker(unsigned short iMarker) const { - CConfig* config = config_container[ZONE_0]; - CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; - CSolver* solver = solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]; - - if (!config->GetDeform_Mesh()) { - return {}; +void CDriverBase::SetMarkerVelocities(unsigned short iMarker, unsigned long iVertex, vector values) { + if (!config_container[ZONE_0]->GetDeform_Mesh()) { + SU2_MPI::Error("Mesh solver is not defined!", CURRENT_FUNCTION); + } + if (values.size() != nDim) { + SU2_MPI::Error("Size does not match nDim!", CURRENT_FUNCTION); } - const auto nVertex = geometry->GetnVertex(iMarker); - vector values(nVertex*nDim, 0.0); - su2double value; + auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); + + for (auto iDim = 0u; iDim < nDim; iDim++) { + solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->SetBound_Disp(iPoint, iDim, values[iDim]); + } +} + +vector CDriverBase::GetMarkerVertexNormals(unsigned short iMarker, bool normalize) const { + const auto nVertex = GetNumberMarkerVertices(iMarker); + vector values; for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - auto iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + const auto value = GetMarkerVertexNormals(iMarker, normalize=normalize); for (auto iDim = 0u; iDim < nDim; iDim++) { - value = solver->GetNodes()->GetMesh_Coord(iPoint, iDim); - values[iVertex*nDim + iDim] = SU2_TYPE::GetValue(value); + values.push_back(value[iDim]); } } return values; } -vector CDriverBase::GetVertexNormalsMarker(unsigned short iMarker, bool UnitNormal) const { - CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; - - const auto nVertex = geometry->GetnVertex(iMarker); - vector values(nVertex*nDim, 0.0); +vector CDriverBase::GetMarkerVertexNormals(unsigned short iMarker, unsigned long iVertex, bool normalize) const { + if (iVertex >= GetNumberMarkerVertices(iMarker)) { + SU2_MPI::Error("Marker vertex index exceeds size.", CURRENT_FUNCTION); + } + + vector values; + + auto normal = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNormal(); + auto area = GeometryToolbox::Norm(nDim, normal); - for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - auto Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); - auto Area = GeometryToolbox::Norm(nDim, Normal); - - for (auto iDim = 0u; iDim < nDim; iDim++) { - if (!UnitNormal) { - values[iVertex*nDim + iDim] = SU2_TYPE::GetValue(Normal[iDim]); - } else { - values[iVertex*nDim + iDim] = SU2_TYPE::GetValue(Normal[iDim]/Area); - } + for (auto iDim = 0u; iDim < nDim; iDim++) { + if (normalize) { + values[iDim] = SU2_TYPE::GetValue(normal[iDim]/area); + } else { + values[iDim] = SU2_TYPE::GetValue(normal[iDim]); } } - + return values; } + void CDriverBase::CommunicateMeshDisplacements(void) { - CConfig* config = config_container[ZONE_0]; - CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; - CSolver* solver = solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]; - - solver->InitiateComms(geometry, config, MESH_DISPLACEMENTS); - solver->CompleteComms(geometry, config, MESH_DISPLACEMENTS); + solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->InitiateComms(geometry_container[ZONE_0][INST_0][MESH_0], config_container[ZONE_0], MESH_DISPLACEMENTS); + solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->CompleteComms(geometry_container[ZONE_0][INST_0][MESH_0], config_container[ZONE_0], MESH_DISPLACEMENTS); } diff --git a/SU2_CFD/include/drivers/CDriver.hpp b/SU2_CFD/include/drivers/CDriver.hpp index 32843db8c50..d15a510cae4 100644 --- a/SU2_CFD/include/drivers/CDriver.hpp +++ b/SU2_CFD/include/drivers/CDriver.hpp @@ -490,22 +490,16 @@ class CDriver : public CDriverBase { void Inlet_Preprocessing(CSolver ***solver, CGeometry **geometry, CConfig *config) const; /*! - * \brief Get all the boundary markers tags. - * \return List of boundary markers tags. + * \brief Get all the CHT boundary marker tags. + * \return List of CHT boundary markers tags. */ - vector GetAllBoundaryMarkersTag() const; + vector GetCHTMarkerTags() const; /*! - * \brief Get all the heat transfer boundary markers tags. - * \return List of heat transfer boundary markers tags. - */ - vector GetAllCHTMarkersTag() const; - - /*! - * \brief Get all the (subsonic) inlet boundary markers tags. + * \brief Get all the inlet boundary marker tags. * \return List of inlet boundary markers tags. */ - vector GetAllInletMarkersTag() const; + vector GetInletMarkerTags() const; /*! * \brief Return the sensitivities of the mesh boundary vertices. diff --git a/SU2_CFD/src/python_wrapper_structure.cpp b/SU2_CFD/src/python_wrapper_structure.cpp index ba6a563c5b0..2f7e35a1247 100644 --- a/SU2_CFD/src/python_wrapper_structure.cpp +++ b/SU2_CFD/src/python_wrapper_structure.cpp @@ -320,60 +320,36 @@ passivedouble CDriver::GetThermalConductivity(unsigned short iMarker, unsigned l /* Functions related to the management of markers */ //////////////////////////////////////////////////////////////////////////////// -vector CDriver::GetAllBoundaryMarkersTag() const { - - vector boundariesTagList; - unsigned short iMarker,nBoundariesMarkers; - string Marker_Tag; - - nBoundariesMarkers = config_container[ZONE_0]->GetnMarker_All(); - boundariesTagList.resize(nBoundariesMarkers); - - for(iMarker=0; iMarker < nBoundariesMarkers; iMarker++){ - Marker_Tag = config_container[ZONE_0]->GetMarker_All_TagBound(iMarker); - boundariesTagList[iMarker] = Marker_Tag; - } - - return boundariesTagList; -} - -vector CDriver::GetAllCHTMarkersTag() const { - - vector CHTBoundariesTagList; - unsigned short iMarker, nBoundariesMarker; - string Marker_Tag; - - nBoundariesMarker = config_container[ZONE_0]->GetnMarker_All(); +vector CDriver::GetCHTMarkerTags() const { + vector tags; + const auto nMarker = config_container[ZONE_0]->GetnMarker_All(); //The CHT markers can be identified as the markers that are customizable with a BC type HEAT_FLUX or ISOTHERMAL. - for(iMarker=0; iMarkerGetMarker_All_KindBC(iMarker) == HEAT_FLUX || config_container[ZONE_0]->GetMarker_All_KindBC(iMarker) == ISOTHERMAL) && config_container[ZONE_0]->GetMarker_All_PyCustom(iMarker)){ - Marker_Tag = config_container[ZONE_0]->GetMarker_All_TagBound(iMarker); - CHTBoundariesTagList.push_back(Marker_Tag); + for (auto iMarker = 0u; iMarker < nMarker; iMarker++) { + if ((config_container[ZONE_0]->GetMarker_All_KindBC(iMarker) == HEAT_FLUX || + config_container[ZONE_0]->GetMarker_All_KindBC(iMarker) == ISOTHERMAL) && config_container[ZONE_0]->GetMarker_All_PyCustom(iMarker)){ + + tags.push_back(config_container[ZONE_0]->GetMarker_All_TagBound(iMarker)); } } - return CHTBoundariesTagList; + return tags; } -vector CDriver::GetAllInletMarkersTag() const { +vector CDriver::GetInletMarkerTags() const { + vector tags; + const auto nMarker = config_container[ZONE_0]->GetnMarker_All(); - vector BoundariesTagList; - unsigned short iMarker, nBoundariesMarker; - string Marker_Tag; - - nBoundariesMarker = config_container[ZONE_0]->GetnMarker_All(); - - for(iMarker=0; iMarkerGetMarker_All_PyCustom(iMarker); bool isInlet = (config_container[ZONE_0]->GetMarker_All_KindBC(iMarker) == INLET_FLOW); - if(isCustomizable && isInlet) { - Marker_Tag = config_container[ZONE_0]->GetMarker_All_TagBound(iMarker); - BoundariesTagList.push_back(Marker_Tag); + + if (isCustomizable && isInlet) { + tags.push_back(config_container[ZONE_0]->GetMarker_All_TagBound(iMarker)); } } - return BoundariesTagList; + return tags; } void CDriver::SetHeatSource_Position(passivedouble alpha, passivedouble pos_x, passivedouble pos_y, passivedouble pos_z){ diff --git a/TestCases/py_wrapper/disc_adj_fea/flow_load_sens/run_adjoint.py b/TestCases/py_wrapper/disc_adj_fea/flow_load_sens/run_adjoint.py index 89006b9a53a..a962558d0d6 100755 --- a/TestCases/py_wrapper/disc_adj_fea/flow_load_sens/run_adjoint.py +++ b/TestCases/py_wrapper/disc_adj_fea/flow_load_sens/run_adjoint.py @@ -68,10 +68,10 @@ def main(): MarkerName = 'RightBeamS' # Specified by the user # Get all the boundary tags - MarkerList = SU2Driver.GetAllBoundaryMarkersTag() + MarkerList = SU2Driver.GetMarkerTags() # Get all the markers defined on this rank and their associated indices. - allMarkerIDs = SU2Driver.GetBoundaryMarkerIndices() + allMarkerIDs = SU2Driver.GetMarkerIndices() #Check if the specified marker exists and if it belongs to this rank. if MarkerName in MarkerList and MarkerName in allMarkerIDs.keys(): diff --git a/TestCases/py_wrapper/disc_adj_flow/mesh_disp_sens/run_adjoint.py b/TestCases/py_wrapper/disc_adj_flow/mesh_disp_sens/run_adjoint.py index 2229ad8ce5c..d174d13da12 100755 --- a/TestCases/py_wrapper/disc_adj_flow/mesh_disp_sens/run_adjoint.py +++ b/TestCases/py_wrapper/disc_adj_flow/mesh_disp_sens/run_adjoint.py @@ -67,12 +67,12 @@ def main(): MarkerName = 'wallF' # Specified by the user # Get all the boundary tags - MarkerList = SU2Driver.GetAllBoundaryMarkersTag() + MarkerList = SU2Driver.GetMarkerTags() # Get all the markers defined on this rank and their associated indices. - allMarkerIDs = SU2Driver.GetBoundaryMarkerIndices() + allMarkerIDs = SU2Driver.GetMarkerIndices() - #Check if the specified marker exists and if it belongs to this rank. + # Check if the specified marker exists and if it belongs to this rank. if MarkerName in MarkerList and MarkerName in allMarkerIDs.keys(): MarkerID = allMarkerIDs[MarkerName] @@ -80,7 +80,7 @@ def main(): nVertex_Marker = 0 #total number of vertices (physical + halo) if MarkerID != None: - nVertex_Marker = SU2Driver.GetNumberVerticesMarker(MarkerID) + nVertex_Marker = SU2Driver.GetNumberMarkerVertices(MarkerID) # Time loop is defined in Python so that we have acces to SU2 functionalities at each time step if rank == 0: diff --git a/TestCases/py_wrapper/flatPlate_rigidMotion/launch_flatPlate_rigidMotion.py b/TestCases/py_wrapper/flatPlate_rigidMotion/launch_flatPlate_rigidMotion.py index ea7983e2156..691f5b134c5 100755 --- a/TestCases/py_wrapper/flatPlate_rigidMotion/launch_flatPlate_rigidMotion.py +++ b/TestCases/py_wrapper/flatPlate_rigidMotion/launch_flatPlate_rigidMotion.py @@ -76,10 +76,10 @@ def main(): MovingMarker = 'plate' #specified by the user # Get all the tags with the moving option - MovingMarkerList = SU2Driver.GetAllDeformMeshMarkersTag() + MovingMarkerList = SU2Driver.GetMarkerTags() # Get all the markers defined on this rank and their associated indices. - allMarkerIDs = SU2Driver.GetAllBoundaryMarkers() + allMarkerIDs = SU2Driver.GetMarkerIndices() # Check if the specified marker has a moving option and if it exists on this rank. if MovingMarker in MovingMarkerList and MovingMarker in allMarkerIDs.keys(): @@ -91,8 +91,8 @@ def main(): nVertex_MovingMarker_PHYS = 0 #number of physical vertices if MovingMarkerID != None: - nVertex_MovingMarker = SU2Driver.GetNumberVertices(MovingMarkerID) - nVertex_MovingMarker_HALO = SU2Driver.GetNumberHaloVertices(MovingMarkerID) + nVertex_MovingMarker = SU2Driver.GetNumberMarkerVertices(MovingMarkerID) + nVertex_MovingMarker_HALO = SU2Driver.GetNumberMarkerHaloVertices(MovingMarkerID) nVertex_MovingMarker_PHYS = nVertex_MovingMarker - nVertex_MovingMarker_HALO # Retrieve some control parameters from the driver @@ -104,9 +104,8 @@ def main(): # Extract the initial position of each node on the moving marker CoordX = np.zeros(nVertex_MovingMarker) CoordY = np.zeros(nVertex_MovingMarker) - CoordZ = np.zeros(nVertex_MovingMarker) for iVertex in range(nVertex_MovingMarker): - CoordX[iVertex], CoordY[iVertex], CoordZ[iVertex] = SU2Driver.GetInitialMeshCoord(MovingMarkerID, iVertex) + CoordX[iVertex], CoordY[iVertex] = SU2Driver.GetMarkerInitialCoordinates(MovingMarkerID, iVertex) # Time loop is defined in Python so that we have acces to SU2 functionalities at each time step if rank == 0: @@ -117,9 +116,11 @@ def main(): while (TimeIter < nTimeIter): # Define the rigid body displacement and set the new coords of each node on the marker - d_y = 0.0175*sin(2*pi*time) + value = 0.0, 0.0175*sin(2*pi*time) + for iVertex in range(nVertex_MovingMarker): - SU2Driver.SetMeshDisplacement(MovingMarkerID, int(iVertex), 0.0, d_y, 0.0) + SU2Driver.SetMarkerDisplacements(MovingMarkerID, int(iVertex), value) + # Time iteration preprocessing SU2Driver.Preprocess(TimeIter) # Run one time iteration (e.g. dual-time) diff --git a/TestCases/py_wrapper/flatPlate_unsteady_CHT/launch_unsteady_CHT_FlatPlate.py b/TestCases/py_wrapper/flatPlate_unsteady_CHT/launch_unsteady_CHT_FlatPlate.py index dfde1d6b2c8..d63bb335442 100755 --- a/TestCases/py_wrapper/flatPlate_unsteady_CHT/launch_unsteady_CHT_FlatPlate.py +++ b/TestCases/py_wrapper/flatPlate_unsteady_CHT/launch_unsteady_CHT_FlatPlate.py @@ -75,23 +75,23 @@ def main(): CHTMarker = 'plate' # Specified by the user # Get all the tags with the CHT option - CHTMarkerList = SU2Driver.GetAllCHTMarkersTag() + CHTMarkerList = SU2Driver.GetCHTMarkerTags() # Get all the markers defined on this rank and their associated indices. - allMarkerIDs = SU2Driver.GetAllBoundaryMarkers() + allMarkerIDs = SU2Driver.GetMarkerIndices() #Check if the specified marker has a CHT option and if it exists on this rank. if CHTMarker in CHTMarkerList and CHTMarker in allMarkerIDs.keys(): CHTMarkerID = allMarkerIDs[CHTMarker] # Number of vertices on the specified marker (per rank) - nVertex_CHTMarker = 0 #total number of vertices (physical + halo) - nVertex_CHTMarker_HALO = 0 #number of halo vertices - nVertex_CHTMarker_PHYS = 0 #number of physical vertices + nVertex_CHTMarker = 0 # total number of vertices (physical + halo) + nVertex_CHTMarker_HALO = 0 # number of halo vertices + nVertex_CHTMarker_PHYS = 0 # number of physical vertices if CHTMarkerID != None: - nVertex_CHTMarker = SU2Driver.GetNumberVertices(CHTMarkerID) - nVertex_CHTMarker_HALO = SU2Driver.GetNumberHaloVertices(CHTMarkerID) + nVertex_CHTMarker = SU2Driver.GetNumberMarkerVertices(CHTMarkerID) + nVertex_CHTMarker_HALO = SU2Driver.GetNumberMarkerHaloVertices(CHTMarkerID) nVertex_CHTMarker_PHYS = nVertex_CHTMarker - nVertex_CHTMarker_HALO # Retrieve some control parameters from the driver @@ -115,6 +115,7 @@ def main(): # Set this temperature to all the vertices on the specified CHT marker for iVertex in range(nVertex_CHTMarker): SU2Driver.SetVertexTemperature(CHTMarkerID, iVertex, WallTemp) + # Tell the SU2 drive to update the boundary conditions SU2Driver.BoundaryConditionsUpdate() # Run one time iteration (e.g. dual-time) From fad776d390fea1ef7f6e3f28ca7c9c3eeb462885 Mon Sep 17 00:00:00 2001 From: aa-g Date: Mon, 7 Mar 2022 21:20:05 +0100 Subject: [PATCH 23/68] Adapt Python API to get/set from multi-dimensional arrays --- Common/include/drivers/CDriverBase.hpp | 48 +++--- Common/src/drivers/CDriverBase.cpp | 229 +++++++++++++------------ SU2_PY/pySU2/pySU2.i | 4 +- SU2_PY/pySU2/pySU2ad.i | 4 +- 4 files changed, 144 insertions(+), 141 deletions(-) diff --git a/Common/include/drivers/CDriverBase.hpp b/Common/include/drivers/CDriverBase.hpp index 6b9590fdd22..68aa0bd5956 100644 --- a/Common/include/drivers/CDriverBase.hpp +++ b/Common/include/drivers/CDriverBase.hpp @@ -121,7 +121,7 @@ class CDriverBase { * \brief Get all the boundary markers tags with their associated indices. * \return List of boundary markers tags with their indices. */ - map GetMarkerIndices() const; + map GetMarkerIndices() const; /*! * \brief Get all the boundary markers tags with their associated types. @@ -371,9 +371,9 @@ class CDriverBase { /*! * \brief Get the initial (un-deformed) coordinates of the mesh vertices. - * \return Initial vertex coordinates (nPoint*nDim). + * \return Initial vertex coordinates (nPoint, nDim). */ - vector GetInitialCoordinates() const; + vector> GetInitialCoordinates() const; /*! * \brief Get the initial (un-deformed) coordinates of a mesh vertex. @@ -385,9 +385,9 @@ class CDriverBase { /*! * \brief Get the initial (un-deformed) coordinates of the marker vertices. * \param[in] iMarker - Marker index. - * \return Initial vertex coordinates (nVertex*nDim). + * \return Initial vertex coordinates (nVertex, nDim). */ - vector GetMarkerInitialCoordinates(unsigned short iMarker) const; + vector> GetMarkerInitialCoordinates(unsigned short iMarker) const; /*! * \brief Get the initial (un-deformed) coordinates of a marker vertex. @@ -399,9 +399,9 @@ class CDriverBase { /*! * \brief Get the coordinates of the mesh vertices. - * \return Vertex coordinates (nPoint*nDim). + * \return Vertex coordinates (nPoint, nDim). */ - vector GetCoordinates() const; + vector> GetCoordinates() const; /*! * \brief Get the coordinates of a mesh vertex. @@ -413,9 +413,9 @@ class CDriverBase { /*! * \brief Get the coordinates of the marker vertices. * \param[in] iMarker - Marker index. - * \return Vertex coordinates (nVertex*nDim). + * \return Vertex coordinates (nVertex, nDim). */ - vector GetMarkerCoordinates(unsigned short iMarker) const; + vector> GetMarkerCoordinates(unsigned short iMarker) const; /*! * \brief Get the coordinates of a marker vertex. @@ -427,9 +427,9 @@ class CDriverBase { /*! * \brief Set the coordinates of the mesh vertices. - * \param[in] values - Vertex coordinates (nPoint*nDim). + * \param[in] values - Vertex coordinates (nPoint, nDim). */ - void SetCoordinates(vector values); + void SetCoordinates(vector> values); /*! * \brief Set the coordinates of a mesh vertex. @@ -441,9 +441,9 @@ class CDriverBase { /*! * \brief Set the coordinates of the marker vertices. * \param[in] iMarker - Marker index. - * \param[in] values - Vertex coordinates (nVertex*nDim). + * \param[in] values - Vertex coordinates (nVertex, nDim). */ - void SetMarkerCoordinates(unsigned short iMarker, vector values); + void SetMarkerCoordinates(unsigned short iMarker, vector> values); /*! * \brief Set the coordinates of a marker vertex. @@ -456,9 +456,9 @@ class CDriverBase { /*! * \brief Get the displacements of the marker vertices. * \param[in] iMarker - Marker index. - * \return Vertex displacements (nVertex*nDim). + * \return Vertex displacements (nVertex, nDim). */ - vector GetMarkerDisplacements(unsigned short iMarker) const; + vector> GetMarkerDisplacements(unsigned short iMarker) const; /*! * \brief Get the displacements of a marker vertex. @@ -471,9 +471,9 @@ class CDriverBase { /*! * \brief Set the displacements of the marker vertices. * \param[in] iMarker - Marker index. - * \param[in] values - Vertex displacements (nVertex*nDim). + * \param[in] values - Vertex displacements (nVertex, nDim). */ - void SetMarkerDisplacements(unsigned short iMarker, vector values); + void SetMarkerDisplacements(unsigned short iMarker, vector> values); /*! * \brief Set the displacements of a marker vertex. @@ -486,24 +486,24 @@ class CDriverBase { /*! * \brief Get the velocities of the marker vertices. * \param[in] iMarker - Marker index. - * \return Vertex velocities (nVertex*nDim). + * \return Vertex velocities (nVertex, nDim). */ - vector GetMarkerVelocities(unsigned short iMarker) const; + vector> GetMarkerVelocities(unsigned short iMarker) const; /*! * \brief Get the velocities of a marker vertex. * \param[in] iMarker - Marker index. * \param[in] iVertex - Marker vertex index. - * \return Vertex velocities (nVertex*nDim). + * \return Vertex velocities (nDim). */ vector GetMarkerVelocities(unsigned short iMarker, unsigned long iVertex) const; /*! * \brief Set the velocities of the marker vertices. * \param[in] iMarker - Marker index. - * \param[in] values - Vertex velocities (nVertex*nDim). + * \param[in] values - Vertex velocities (nVertex, nDim). */ - void SetMarkerVelocities(unsigned short iMarker, vector values); + void SetMarkerVelocities(unsigned short iMarker, vector> values); /*! * \brief Set the velocities of a marker vertex. @@ -517,9 +517,9 @@ class CDriverBase { * \brief Get the normal vectors at the marker vertices. * \param[in] iMarker - Marker index. * \param[in] normalize - If true, the unit (i.e. normalized) normal vector is returned. - * \return Normal vector at the vertex (nVertex*nDim). + * \return Normal vector at the vertex (nVertex, nDim). */ - vector GetMarkerVertexNormals(unsigned short iMarker, bool normalize = false) const; + vector> GetMarkerVertexNormals(unsigned short iMarker, bool normalize = false) const; /*! * \brief Get the normal vectors at a marker vertex. diff --git a/Common/src/drivers/CDriverBase.cpp b/Common/src/drivers/CDriverBase.cpp index 9a3ee6ba686..8f2f74d0a99 100644 --- a/Common/src/drivers/CDriverBase.cpp +++ b/Common/src/drivers/CDriverBase.cpp @@ -86,9 +86,9 @@ unsigned short CDriverBase::GetNumberMarkers() const { return config_container[ZONE_0]->GetnMarker_All(); } -map CDriverBase::GetMarkerIndices() const { +map CDriverBase::GetMarkerIndices() const { const auto nMarker = config_container[ZONE_0]->GetnMarker_All(); - map indexMap; + map indexMap; for (auto iMarker = 0u; iMarker < nMarker; iMarker++) { auto tag = config_container[ZONE_0]->GetMarker_All_TagBound(iMarker); @@ -154,7 +154,7 @@ vector CDriverBase::GetMarkerTags() const { vector CDriverBase::GetDeformableMarkerTags() const { vector tags; - const auto nMarker = config_container[ZONE_0]->GetnMarker_All(); + const auto nMarker = config_container[ZONE_0]->GetnMarker_Deform_Mesh(); for (auto iMarker = 0u; iMarker < nMarker; iMarker++) { tags.push_back(config_container[ZONE_0]->GetMarker_Deform_Mesh_TagBound(iMarker)); @@ -180,9 +180,10 @@ unsigned long CDriverBase::GetNumberMarkerElements(unsigned short iMarker) const } vector CDriverBase::GetElementIDs() const { - vector values; const auto nElem = GetNumberElements(); + vector values; + for (auto iElem = 0ul; iElem < nElem; iElem++) { values.push_back(GetElementIDs(iElem)); } @@ -199,9 +200,10 @@ unsigned long CDriverBase::GetElementIDs(unsigned long iElem) const { } vector CDriverBase::GetMarkerElementIDs(unsigned short iMarker) const { - vector values; const auto nBound = GetNumberMarkerElements(iMarker); + vector values; + for (auto iBound = 0ul; iBound < nBound; iBound++) { values.push_back(GetMarkerElementIDs(iMarker, iBound)); } @@ -218,9 +220,10 @@ unsigned long CDriverBase::GetMarkerElementIDs(unsigned short iMarker, unsigned } vector CDriverBase::GetElementColors() const { - vector values; const auto nElem = GetNumberElements(); + vector values; + for (auto iElem = 0ul; iElem < nElem; iElem++) { values.push_back(GetElementColors(iElem)); } @@ -237,9 +240,10 @@ unsigned long CDriverBase::GetElementColors(unsigned long iElem) const { } vector CDriverBase::GetMarkerElementColors(unsigned short iMarker) const { - vector values; const auto nBound = GetNumberMarkerElements(iMarker); + vector values; + for (auto iBound = 0ul; iBound < nBound; iBound++) { values.push_back(GetMarkerElementColors(iMarker, iBound)); } @@ -256,9 +260,10 @@ unsigned long CDriverBase::GetMarkerElementColors(unsigned short iMarker, unsign } vector> CDriverBase::GetElementConnectivities() const { - vector> values; const auto nElem = GetNumberElements(); + vector> values; + for (auto iElem = 0ul; iElem < nElem; iElem++) { values.push_back(GetElementConnectivities(iElem)); } @@ -271,9 +276,10 @@ vector CDriverBase::GetElementConnectivities(unsigned long iElem) SU2_MPI::Error("Element index exceeds size.", CURRENT_FUNCTION); } - vector values; unsigned short nNode = geometry_container[ZONE_0][INST_0][MESH_0]->elem[iElem]->GetnNodes(); + vector values; + for (auto iNode = 0u; iNode < nNode; iNode++) { values.push_back(geometry_container[ZONE_0][INST_0][MESH_0]->elem[iElem]->GetNode(iNode)); } @@ -282,9 +288,10 @@ vector CDriverBase::GetElementConnectivities(unsigned long iElem) } vector> CDriverBase::GetMarkerElementConnectivities(unsigned short iMarker) const { - vector> values; const auto nBound = GetNumberMarkerElements(iMarker); + vector> values; + for (auto iBound = 0ul; iBound < nBound; iBound++) { values.push_back(GetMarkerElementConnectivities(iMarker, iBound)); } @@ -297,9 +304,10 @@ vector CDriverBase::GetMarkerElementConnectivities(unsigned short SU2_MPI::Error("Marker element index exceeds size.", CURRENT_FUNCTION); } - vector values; unsigned short nNode = geometry_container[ZONE_0][INST_0][MESH_0]->bound[iMarker][iBound]->GetnNodes(); + vector values; + for (auto iNode = 0u; iNode < nNode; iNode++) { values.push_back(geometry_container[ZONE_0][INST_0][MESH_0]->bound[iMarker][iBound]->GetNode(iNode)); } @@ -348,9 +356,10 @@ unsigned long CDriverBase::GetNumberMarkerHaloVertices(unsigned short iMarker) c } vector CDriverBase::GetMarkerVertexIndex(unsigned short iMarker) const { - vector values; const auto nVertex = GetNumberMarkerVertices(iMarker); + vector values; + for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { values.push_back(GetMarkerVertexIndex(iMarker, iVertex)); } @@ -367,9 +376,10 @@ unsigned long CDriverBase::GetMarkerVertexIndex(unsigned short iMarker, unsigned } vector CDriverBase::GetVertexIDs() const { - vector values; const auto nPoint = GetNumberVertices(); + vector values; + for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { values.push_back(GetVertexIDs(iPoint)); } @@ -386,9 +396,10 @@ unsigned long CDriverBase::GetVertexIDs(unsigned long iPoint) const { } vector CDriverBase::GetMarkerVertexIDs(unsigned short iMarker) const { - vector values; const auto nVertex = GetNumberMarkerVertices(iMarker); + vector values; + for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { values.push_back(GetMarkerVertexIDs(iMarker, iVertex)); } @@ -403,9 +414,10 @@ unsigned long CDriverBase::GetMarkerVertexIDs(unsigned short iMarker, unsigned l } vector CDriverBase::GetVertexColors() const { - vector values; const auto nPoint = GetNumberVertices(); + vector values; + for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { values.push_back(GetVertexColors(iPoint)); } @@ -422,9 +434,10 @@ unsigned long CDriverBase::GetVertexColors(unsigned long iPoint) const { } vector CDriverBase::GetMarkerVertexColors(unsigned short iMarker) const { - vector values; const auto nVertex = GetNumberMarkerVertices(iMarker); + vector values; + for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { values.push_back(GetMarkerVertexColors(iMarker, iVertex)); } @@ -439,8 +452,9 @@ unsigned long CDriverBase::GetMarkerVertexColors(unsigned short iMarker, unsigne } vector CDriverBase::GetDomain() const { - vector values; const auto nPoint = GetNumberVertices(); + + vector values; for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { values.push_back(GetDomain(iPoint)); @@ -458,8 +472,9 @@ bool CDriverBase::GetDomain(unsigned long iPoint) const { } vector CDriverBase::GetMarkerDomain(unsigned short iMarker) const { - vector values; const auto nVertex = GetNumberMarkerVertices(iMarker); + + vector values; for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { values.push_back(GetMarkerDomain(iMarker, iVertex)); @@ -474,16 +489,13 @@ bool CDriverBase::GetMarkerDomain(unsigned short iMarker, unsigned long iVertex) return geometry_container[ZONE_0][INST_0][MESH_0]->nodes->GetDomain(iPoint); } -vector CDriverBase::GetInitialCoordinates() const { +vector> CDriverBase::GetInitialCoordinates() const { const auto nPoint = GetNumberVertices(); - vector values; + + vector> values; for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { - const auto value = GetInitialCoordinates(iPoint); - - for (auto iDim = 0u; iDim < nDim; iDim++) { - values.push_back(value[iDim]); - } + values.push_back(GetInitialCoordinates(iPoint)); } return values; @@ -510,9 +522,10 @@ vector CDriverBase::GetInitialCoordinates(unsigned long iPoint) c return values; } -vector CDriverBase::GetMarkerInitialCoordinates(unsigned short iMarker) const { +vector> CDriverBase::GetMarkerInitialCoordinates(unsigned short iMarker) const { const auto nVertex = GetNumberMarkerVertices(iMarker); - vector values; + + vector> values; for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { const auto value = GetMarkerInitialCoordinates(iVertex); @@ -527,6 +540,7 @@ vector CDriverBase::GetMarkerInitialCoordinates(unsigned short iM vector CDriverBase::GetMarkerInitialCoordinates(unsigned short iMarker, unsigned long iVertex) const { auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); + vector values; for (auto iDim = 0u; iDim < nDim; iDim++) { @@ -543,23 +557,23 @@ vector CDriverBase::GetMarkerInitialCoordinates(unsigned short iM return values; } -vector CDriverBase::GetCoordinates() const { +vector> CDriverBase::GetCoordinates() const { const auto nPoint = GetNumberVertices(); - vector values; + + vector> values; for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { - const auto value = GetCoordinates(iPoint); - - for (auto iDim = 0u; iDim < nDim; iDim++) { - values.push_back(value[iDim]); - } + values.push_back(GetCoordinates(iPoint)); } return values; } vector CDriverBase::GetCoordinates(unsigned long iPoint) const { - const auto nPoint = GetNumberVertices(); + if (iPoint >= GetNumberVertices()) { + SU2_MPI::Error("Vertex index exceeds size.", CURRENT_FUNCTION); + } + vector values; for (auto iDim = 0u; iDim < nDim; iDim++) { @@ -571,16 +585,13 @@ vector CDriverBase::GetCoordinates(unsigned long iPoint) const { return values; } -vector CDriverBase::GetMarkerCoordinates(unsigned short iMarker) const { +vector> CDriverBase::GetMarkerCoordinates(unsigned short iMarker) const { const auto nVertex = GetNumberMarkerVertices(iMarker); - vector values; + + vector> values; for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - const auto value = GetMarkerCoordinates(iVertex); - - for (auto iDim = 0u; iDim < nDim; iDim++) { - values.push_back(value[iDim]); - } + values.push_back(GetMarkerCoordinates(iMarker, iVertex)); } return values; @@ -588,6 +599,7 @@ vector CDriverBase::GetMarkerCoordinates(unsigned short iMarker) vector CDriverBase::GetMarkerCoordinates(unsigned short iMarker, unsigned long iVertex) const { auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); + vector values; for (auto iDim = 0u; iDim < nDim; iDim++) { @@ -599,23 +611,25 @@ vector CDriverBase::GetMarkerCoordinates(unsigned short iMarker, return values; } -void CDriverBase::SetCoordinates(vector values) { +void CDriverBase::SetCoordinates(vector> values) { const auto nPoint = GetNumberVertices(); - if (values.size() != nPoint*nDim) { - SU2_MPI::Error("Size does not match nPoint * nDim!", CURRENT_FUNCTION); + if (values.size() != nPoint) { + SU2_MPI::Error("Invalid number of vertices !", CURRENT_FUNCTION); } for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { - for (auto iDim = 0u; iDim < nDim; iDim++) { - geometry_container[ZONE_0][INST_0][MESH_0]->nodes->SetCoord(iPoint, iDim, values[iPoint*nDim + iDim]); - } + SetCoordinates(iPoint, values[iPoint]); } } void CDriverBase::SetCoordinates(unsigned long iPoint, vector values) { + if (iPoint >= GetNumberVertices()) { + SU2_MPI::Error("Vertex index exceeds size.", CURRENT_FUNCTION); + } + if (values.size() != nDim) { - SU2_MPI::Error("Size does not match nDim!", CURRENT_FUNCTION); + SU2_MPI::Error("Invalid number of dimensions !", CURRENT_FUNCTION); } for (auto iDim = 0u; iDim < nDim; iDim++) { @@ -623,44 +637,37 @@ void CDriverBase::SetCoordinates(unsigned long iPoint, vector val } } -void CDriverBase::SetMarkerCoordinates(unsigned short iMarker, vector values) { +void CDriverBase::SetMarkerCoordinates(unsigned short iMarker, vector> values) { const auto nVertex = GetNumberMarkerVertices(iMarker); - if (values.size() != nVertex*nDim) { - SU2_MPI::Error("Size does not match nVertex * nDim!", CURRENT_FUNCTION); + if (values.size() != nVertex) { + SU2_MPI::Error("Invalid number of marker vertices !", CURRENT_FUNCTION); } for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); - - for (auto iDim = 0u; iDim < nDim; iDim++) { - geometry_container[ZONE_0][INST_0][MESH_0]->nodes->SetCoord(iPoint, iDim, values[iVertex*nDim + iDim]); - } + SetMarkerCoordinates(iMarker, iVertex, values[iVertex]); } } void CDriverBase::SetMarkerCoordinates(unsigned short iMarker, unsigned long iVertex, vector values) { + auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); + if (values.size() != nDim) { - SU2_MPI::Error("Size does not match nDim!", CURRENT_FUNCTION); + SU2_MPI::Error("Invalid number of dimensions !", CURRENT_FUNCTION); } - auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); - for (auto iDim = 0u; iDim < nDim; iDim++) { geometry_container[ZONE_0][INST_0][MESH_0]->nodes->SetCoord(iPoint, iDim, values[iDim]); } } -vector CDriverBase::GetMarkerDisplacements(unsigned short iMarker) const { +vector> CDriverBase::GetMarkerDisplacements(unsigned short iMarker) const { const auto nVertex = GetNumberMarkerVertices(iMarker); - vector values; + + vector> values; for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - const auto value = GetMarkerDisplacements(iMarker, iVertex); - - for (auto iDim = 0u; iDim < nDim; iDim++) { - values.push_back(values[iDim]); - } + values.push_back(GetMarkerDisplacements(iMarker, iVertex)); } return values; @@ -668,62 +675,60 @@ vector CDriverBase::GetMarkerDisplacements(unsigned short iMarker vector CDriverBase::GetMarkerDisplacements(unsigned short iMarker, unsigned long iVertex) const { auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); + vector values; for (auto iDim = 0u; iDim < nDim; iDim++) { - const su2double value = solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->GetBound_Disp(iPoint, iDim); - - values.push_back(SU2_TYPE::GetValue(value)); + if (config_container[ZONE_0]->GetDeform_Mesh()) { + values.push_back(SU2_TYPE::GetValue(solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->GetBound_Disp(iPoint, iDim))); + } + else { + values.push_back(0.0); + } } return values; } -void CDriverBase::SetMarkerDisplacements(unsigned short iMarker, vector values) { +void CDriverBase::SetMarkerDisplacements(unsigned short iMarker, vector> values) { if (!config_container[ZONE_0]->GetDeform_Mesh()) { - SU2_MPI::Error("Mesh solver is not defined!", CURRENT_FUNCTION); + SU2_MPI::Error("Mesh solver is not defined !", CURRENT_FUNCTION); } const auto nVertex = GetNumberMarkerVertices(iMarker); - if (values.size() != nVertex*nDim) { - SU2_MPI::Error("Size does not match nVertex * nDim!", CURRENT_FUNCTION); + if (values.size() != nVertex) { + SU2_MPI::Error("Invalid number of marker vertices !", CURRENT_FUNCTION); } for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); - - for (auto iDim = 0u; iDim < nDim; iDim++) { - solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->SetBound_Disp(iPoint, iDim, values[iVertex*nDim + iDim]); - } + SetMarkerDisplacements(iMarker, iVertex, values[iVertex]); } } void CDriverBase::SetMarkerDisplacements(unsigned short iMarker, unsigned long iVertex, vector values) { if (!config_container[ZONE_0]->GetDeform_Mesh()) { - SU2_MPI::Error("Mesh solver is not defined!", CURRENT_FUNCTION); + SU2_MPI::Error("Mesh solver is not defined !", CURRENT_FUNCTION); } + + auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); + if (values.size() != nDim) { - SU2_MPI::Error("Size does not match nDim!", CURRENT_FUNCTION); + SU2_MPI::Error("Invalid number of dimensions !", CURRENT_FUNCTION); } - auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); - for (auto iDim = 0u; iDim < nDim; iDim++) { solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->SetBound_Disp(iPoint, iDim, values[iDim]); } } -vector CDriverBase::GetMarkerVelocities(unsigned short iMarker) const { +vector> CDriverBase::GetMarkerVelocities(unsigned short iMarker) const { const auto nVertex = GetNumberMarkerVertices(iMarker); - vector values; + + vector> values; for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - const auto value = GetMarkerVelocities(iMarker, iVertex); - - for (auto iDim = 0u; iDim < nDim; iDim++) { - values.push_back(values[iDim]); - } + values.push_back(GetMarkerVelocities(iMarker, iVertex)); } return values; @@ -731,62 +736,60 @@ vector CDriverBase::GetMarkerVelocities(unsigned short iMarker) c vector CDriverBase::GetMarkerVelocities(unsigned short iMarker, unsigned long iVertex) const { auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); + vector values; for (auto iDim = 0u; iDim < nDim; iDim++) { - const su2double value = solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->GetBound_Vel(iPoint, iDim); - - values.push_back(SU2_TYPE::GetValue(value)); + if (config_container[ZONE_0]->GetDeform_Mesh()) { + values.push_back(SU2_TYPE::GetValue(solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->GetBound_Vel(iPoint, iDim))); + } + else { + values.push_back(0.0); + } } return values; } -void CDriverBase::SetMarkerVelocities(unsigned short iMarker, vector values) { +void CDriverBase::SetMarkerVelocities(unsigned short iMarker, vector> values) { if (!config_container[ZONE_0]->GetDeform_Mesh()) { - SU2_MPI::Error("Mesh solver is not defined!", CURRENT_FUNCTION); + SU2_MPI::Error("Mesh solver is not defined !", CURRENT_FUNCTION); } const auto nVertex = GetNumberMarkerVertices(iMarker); - if (values.size() != nVertex*nDim) { - SU2_MPI::Error("Size does not match nVertex * nDim!", CURRENT_FUNCTION); + if (values.size() != nVertex) { + SU2_MPI::Error("Invalid number of marker vertices !", CURRENT_FUNCTION); } for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); - - for (auto iDim = 0u; iDim < nDim; iDim++) { - solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->SetBound_Disp(iPoint, iDim, values[iVertex*nDim + iDim]); - } + SetMarkerVelocities(iMarker, iVertex, values[iVertex]); } } void CDriverBase::SetMarkerVelocities(unsigned short iMarker, unsigned long iVertex, vector values) { if (!config_container[ZONE_0]->GetDeform_Mesh()) { - SU2_MPI::Error("Mesh solver is not defined!", CURRENT_FUNCTION); + SU2_MPI::Error("Mesh solver is not defined !", CURRENT_FUNCTION); } + + auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); + if (values.size() != nDim) { - SU2_MPI::Error("Size does not match nDim!", CURRENT_FUNCTION); + SU2_MPI::Error("Invalid number of dimensions !", CURRENT_FUNCTION); } - auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); - for (auto iDim = 0u; iDim < nDim; iDim++) { solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->SetBound_Disp(iPoint, iDim, values[iDim]); } } -vector CDriverBase::GetMarkerVertexNormals(unsigned short iMarker, bool normalize) const { +vector> CDriverBase::GetMarkerVertexNormals(unsigned short iMarker, bool normalize) const { const auto nVertex = GetNumberMarkerVertices(iMarker); - vector values; + + vector> values; for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - const auto value = GetMarkerVertexNormals(iMarker, normalize=normalize); - - for (auto iDim = 0u; iDim < nDim; iDim++) { - values.push_back(value[iDim]); - } + values.push_back(GetMarkerVertexNormals(iMarker, iVertex, normalize=normalize)); } return values; diff --git a/SU2_PY/pySU2/pySU2.i b/SU2_PY/pySU2/pySU2.i index 0125ffd1e6b..08cf47042fb 100644 --- a/SU2_PY/pySU2/pySU2.i +++ b/SU2_PY/pySU2/pySU2.i @@ -66,10 +66,10 @@ namespace std { %template() vector; %template() vector; %template() vector>; - %template() vector; %template() vector; + %template() vector>; %template() vector; - %template() map; + %template() map; %template() map; } diff --git a/SU2_PY/pySU2/pySU2ad.i b/SU2_PY/pySU2/pySU2ad.i index a1f47b6bf2b..5f0ce8412eb 100644 --- a/SU2_PY/pySU2/pySU2ad.i +++ b/SU2_PY/pySU2/pySU2ad.i @@ -66,10 +66,10 @@ namespace std { %template() vector; %template() vector; %template() vector>; - %template() vector; %template() vector; + %template() vector>; %template() vector; - %template() map; + %template() map; %template() map; } From 5891d3e16e15bac721051788c3e069941f7fbd6a Mon Sep 17 00:00:00 2001 From: aa-g Date: Mon, 7 Mar 2022 21:43:26 +0100 Subject: [PATCH 24/68] Fix small inconsistencies in previous commit --- Common/src/drivers/CDriverBase.cpp | 84 ++++++++++++++---------------- 1 file changed, 40 insertions(+), 44 deletions(-) diff --git a/Common/src/drivers/CDriverBase.cpp b/Common/src/drivers/CDriverBase.cpp index 8f2f74d0a99..e07a40652a9 100644 --- a/Common/src/drivers/CDriverBase.cpp +++ b/Common/src/drivers/CDriverBase.cpp @@ -329,30 +329,30 @@ unsigned long CDriverBase::GetNumberMarkerVertices(unsigned short iMarker) const unsigned long CDriverBase::GetNumberHaloVertices() const { const auto nPoint = GetNumberVertices(); - unsigned long nHaloVertices = 0; + unsigned long nHalo = 0; for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { if (!(geometry_container[ZONE_0][INST_0][MESH_0]->nodes->GetDomain(iPoint))) { - nHaloVertices += 1; + nHalo += 1; } } - return nHaloVertices; + return nHalo; } unsigned long CDriverBase::GetNumberMarkerHaloVertices(unsigned short iMarker) const { - const auto nVertex = GetNumberMarkerVertices(iMarker); // error-checking included - unsigned long nHaloVertices = 0; + const auto nVertex = GetNumberMarkerVertices(iMarker); + unsigned long nHalo = 0; for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - auto iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); + auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); if (!(geometry_container[ZONE_0][INST_0][MESH_0]->nodes->GetDomain(iPoint))) { - nHaloVertices += 1; + nHalo += 1; } } - return nHaloVertices; + return nHalo; } vector CDriverBase::GetMarkerVertexIndex(unsigned short iMarker) const { @@ -408,7 +408,7 @@ vector CDriverBase::GetMarkerVertexIDs(unsigned short iMarker) co } unsigned long CDriverBase::GetMarkerVertexIDs(unsigned short iMarker, unsigned long iVertex) const { - auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); // includes error-checking + auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); return geometry_container[ZONE_0][INST_0][MESH_0]->nodes->GetGlobalIndex(iPoint); } @@ -446,7 +446,7 @@ vector CDriverBase::GetMarkerVertexColors(unsigned short iMarker) } unsigned long CDriverBase::GetMarkerVertexColors(unsigned short iMarker, unsigned long iVertex) const { - auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); // includes error-checking + auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); return geometry_container[ZONE_0][INST_0][MESH_0]->nodes->GetColor(iPoint); } @@ -506,17 +506,16 @@ vector CDriverBase::GetInitialCoordinates(unsigned long iPoint) c SU2_MPI::Error("Vertex index exceeds size.", CURRENT_FUNCTION); } - vector values; + vector values (nDim, 0.0); + + if (!config_container[ZONE_0]->GetDeform_Mesh()) { + return values; + } for (auto iDim = 0u; iDim < nDim; iDim++) { const su2double value = solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->GetMesh_Coord(iPoint, iDim); - - if (!config_container[ZONE_0]->GetDeform_Mesh()) { - values.push_back(0.0); // mesh solver is not defined ! - } - else { - values.push_back(SU2_TYPE::GetValue(value)); - } + + values[iDim] = SU2_TYPE::GetValue(value); } return values; @@ -528,11 +527,7 @@ vector> CDriverBase::GetMarkerInitialCoordinates(unsigned vector> values; for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - const auto value = GetMarkerInitialCoordinates(iVertex); - - for (auto iDim = 0u; iDim < nDim; iDim++) { - values.push_back(value[iDim]); - } + values.push_back(GetMarkerInitialCoordinates(iMarker, iVertex)); } return values; @@ -541,17 +536,16 @@ vector> CDriverBase::GetMarkerInitialCoordinates(unsigned vector CDriverBase::GetMarkerInitialCoordinates(unsigned short iMarker, unsigned long iVertex) const { auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); - vector values; + vector values(nDim, 0.0); + + if (!config_container[ZONE_0]->GetDeform_Mesh()) { + return values; + } for (auto iDim = 0u; iDim < nDim; iDim++) { const su2double value = solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->GetMesh_Coord(iPoint, iDim); - if (!config_container[ZONE_0]->GetDeform_Mesh()) { - values.push_back(0.0); // mesh solver is not defined ! - } - else { - values.push_back(SU2_TYPE::GetValue(value)); - } + values[iDim] = SU2_TYPE::GetValue(value); } return values; @@ -676,15 +670,16 @@ vector> CDriverBase::GetMarkerDisplacements(unsigned short vector CDriverBase::GetMarkerDisplacements(unsigned short iMarker, unsigned long iVertex) const { auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); - vector values; + vector values (nDim, 0.0); + + if (!config_container[ZONE_0]->GetDeform_Mesh()) { + return values; + } for (auto iDim = 0u; iDim < nDim; iDim++) { - if (config_container[ZONE_0]->GetDeform_Mesh()) { - values.push_back(SU2_TYPE::GetValue(solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->GetBound_Disp(iPoint, iDim))); - } - else { - values.push_back(0.0); - } + const su2double value = solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->GetBound_Disp(iPoint, iDim); + + values[iDim] = SU2_TYPE::GetValue(value); } return values; @@ -737,15 +732,16 @@ vector> CDriverBase::GetMarkerVelocities(unsigned short iM vector CDriverBase::GetMarkerVelocities(unsigned short iMarker, unsigned long iVertex) const { auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); - vector values; + vector values (nDim, 0.0); + + if (!config_container[ZONE_0]->GetDeform_Mesh()) { + return values; + } for (auto iDim = 0u; iDim < nDim; iDim++) { - if (config_container[ZONE_0]->GetDeform_Mesh()) { - values.push_back(SU2_TYPE::GetValue(solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->GetBound_Vel(iPoint, iDim))); - } - else { - values.push_back(0.0); - } + const su2double value = solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->GetBound_Vel(iPoint, iDim); + + values[iDim] = SU2_TYPE::GetValue(value); } return values; From 59fdd2e86d14f264d92d6b610ee3331a0fe82140 Mon Sep 17 00:00:00 2001 From: aa-g Date: Mon, 7 Mar 2022 22:22:25 +0100 Subject: [PATCH 25/68] Fix conditional output of FFD information --- SU2_DEF/src/drivers/CDeformationDriver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SU2_DEF/src/drivers/CDeformationDriver.cpp b/SU2_DEF/src/drivers/CDeformationDriver.cpp index ecca754838a..309e65377d2 100644 --- a/SU2_DEF/src/drivers/CDeformationDriver.cpp +++ b/SU2_DEF/src/drivers/CDeformationDriver.cpp @@ -534,7 +534,7 @@ void CDeformationDriver::Output() { (config_container[ZONE_0]->GetDesign_Variable(0) != ROTATE_GRID)) { /*--- Write the the free-form deformation boxes after deformation (if defined). ---*/ - if (true) { + if (!haveSurfaceDeformation) { if (rank == MASTER_NODE) cout << "No FFD information available." << endl; } else { From 4873aa2f46c76e744c482c3c0e655addc6fc608f Mon Sep 17 00:00:00 2001 From: aa-g Date: Mon, 7 Mar 2022 23:25:20 +0100 Subject: [PATCH 26/68] Introduce 'main' Config and Geometry for Python API --- Common/include/drivers/CDriverBase.hpp | 8 +- Common/src/drivers/CDriverBase.cpp | 99 ++++++++++--------- SU2_CFD/src/drivers/CDriver.cpp | 10 +- SU2_DEF/src/drivers/CDeformationDriver.cpp | 7 ++ .../src/drivers/CDiscAdjDeformationDriver.cpp | 7 ++ 5 files changed, 79 insertions(+), 52 deletions(-) diff --git a/Common/include/drivers/CDriverBase.hpp b/Common/include/drivers/CDriverBase.hpp index 68aa0bd5956..19f0923e4b2 100644 --- a/Common/include/drivers/CDriverBase.hpp +++ b/Common/include/drivers/CDriverBase.hpp @@ -56,10 +56,11 @@ class CDriverBase { *nInst, /*!< \brief Total number of instances in the problem (per zone). */ **interface_types; /*!< \brief Type of coupling between the distinct (physical) zones.*/ - CConfig **config_container; /*!< \brief Definition of the particular problem. */ CConfig *driver_config; /*!< \brief Definition of the driver configuration. */ - COutput **output_container; /*!< \brief Pointer to the COutput class. */ COutput *driver_output; /*!< \brief Definition of the driver output. */ + + CConfig **config_container; /*!< \brief Definition of the particular problem. */ + COutput **output_container; /*!< \brief Pointer to the COutput class. */ CGeometry ****geometry_container; /*!< \brief Geometrical definition of the problem. */ CSolver *****solver_container; /*!< \brief Container vector with all the solutions. */ CNumerics ******numerics_container; /*!< \brief Description of the numerical method (the way in which the equations are solved). */ @@ -67,6 +68,9 @@ class CDriverBase { CVolumetricMovement ***grid_movement; /*!< \brief Volume grid movement classes of the problem. */ CFreeFormDefBox*** FFDBox; /*!< \brief FFD FFDBoxes of the problem. */ + CConfig *main_config; /*!< \brief Reference to the base (i.e. ZONE 0) configuration (used in the driver API). */ + CGeometry *main_geometry; /*!< \brief Reference to the base (i.E. ZONE, INST, MESH 0) geometry (used in the driver API). */ + public: /*! diff --git a/Common/src/drivers/CDriverBase.cpp b/Common/src/drivers/CDriverBase.cpp index e07a40652a9..01eccb23448 100644 --- a/Common/src/drivers/CDriverBase.cpp +++ b/Common/src/drivers/CDriverBase.cpp @@ -78,20 +78,23 @@ void CDriverBase::SetContainers_Null() { nInst[iZone] = 1; } - driver_config = nullptr; - driver_output = nullptr; + driver_config = nullptr; + driver_output = nullptr; + + main_config = nullptr; + main_geometry = nullptr; } unsigned short CDriverBase::GetNumberMarkers() const { - return config_container[ZONE_0]->GetnMarker_All(); + return main_config->GetnMarker_All(); } map CDriverBase::GetMarkerIndices() const { - const auto nMarker = config_container[ZONE_0]->GetnMarker_All(); + const auto nMarker = main_config->GetnMarker_All(); map indexMap; for (auto iMarker = 0u; iMarker < nMarker; iMarker++) { - auto tag = config_container[ZONE_0]->GetMarker_All_TagBound(iMarker); + auto tag = main_config->GetMarker_All_TagBound(iMarker); indexMap[tag] = iMarker; } @@ -103,9 +106,9 @@ map CDriverBase::GetMarkerTypes() const { map typeMap; string type; - for (auto iMarker = 0u; iMarker < config_container[ZONE_0]->GetnMarker_All(); iMarker++) { - auto tag = config_container[ZONE_0]->GetMarker_All_TagBound(iMarker); - auto kindBC = config_container[ZONE_0]->GetMarker_All_KindBC(iMarker); + for (auto iMarker = 0u; iMarker < main_config->GetnMarker_All(); iMarker++) { + auto tag = main_config->GetMarker_All_TagBound(iMarker); + auto kindBC = main_config->GetMarker_All_KindBC(iMarker); switch(kindBC) { case EULER_WALL: @@ -143,10 +146,10 @@ map CDriverBase::GetMarkerTypes() const { vector CDriverBase::GetMarkerTags() const { vector tags; - const auto nMarker = config_container[ZONE_0]->GetnMarker_All(); + const auto nMarker = main_config->GetnMarker_All(); for(auto iMarker = 0u; iMarker < nMarker; iMarker++){ - tags.push_back(config_container[ZONE_0]->GetMarker_All_TagBound(iMarker)); + tags.push_back(main_config->GetMarker_All_TagBound(iMarker)); } return tags; @@ -154,21 +157,21 @@ vector CDriverBase::GetMarkerTags() const { vector CDriverBase::GetDeformableMarkerTags() const { vector tags; - const auto nMarker = config_container[ZONE_0]->GetnMarker_Deform_Mesh(); + const auto nMarker = main_config->GetnMarker_Deform_Mesh(); for (auto iMarker = 0u; iMarker < nMarker; iMarker++) { - tags.push_back(config_container[ZONE_0]->GetMarker_Deform_Mesh_TagBound(iMarker)); + tags.push_back(main_config->GetMarker_Deform_Mesh_TagBound(iMarker)); } return tags; } unsigned long CDriverBase::GetNumberDimensions() const { - return geometry_container[ZONE_0][INST_0][MESH_0]->GetnDim(); + return main_geometry->GetnDim(); } unsigned long CDriverBase::GetNumberElements() const { - return geometry_container[ZONE_0][INST_0][MESH_0]->GetnElem(); + return main_geometry->GetnElem(); } unsigned long CDriverBase::GetNumberMarkerElements(unsigned short iMarker) const { @@ -176,7 +179,7 @@ unsigned long CDriverBase::GetNumberMarkerElements(unsigned short iMarker) const SU2_MPI::Error("Marker index exceeds size.", CURRENT_FUNCTION); } - return geometry_container[ZONE_0][INST_0][MESH_0]->GetnElem_Bound(iMarker); + return main_geometry->GetnElem_Bound(iMarker); } vector CDriverBase::GetElementIDs() const { @@ -196,7 +199,7 @@ unsigned long CDriverBase::GetElementIDs(unsigned long iElem) const { SU2_MPI::Error("Element index exceeds size.", CURRENT_FUNCTION); } - return geometry_container[ZONE_0][INST_0][MESH_0]->elem[iElem]->GetGlobalIndex(); + return main_geometry->elem[iElem]->GetGlobalIndex(); } vector CDriverBase::GetMarkerElementIDs(unsigned short iMarker) const { @@ -216,7 +219,7 @@ unsigned long CDriverBase::GetMarkerElementIDs(unsigned short iMarker, unsigned SU2_MPI::Error("Marker element index exceeds size.", CURRENT_FUNCTION); } - return geometry_container[ZONE_0][INST_0][MESH_0]->bound[iMarker][iBound]->GetGlobalIndex(); + return main_geometry->bound[iMarker][iBound]->GetGlobalIndex(); } vector CDriverBase::GetElementColors() const { @@ -236,7 +239,7 @@ unsigned long CDriverBase::GetElementColors(unsigned long iElem) const { SU2_MPI::Error("Element index exceeds size.", CURRENT_FUNCTION); } - return geometry_container[ZONE_0][INST_0][MESH_0]->elem[iElem]->GetColor(); + return main_geometry->elem[iElem]->GetColor(); } vector CDriverBase::GetMarkerElementColors(unsigned short iMarker) const { @@ -256,7 +259,7 @@ unsigned long CDriverBase::GetMarkerElementColors(unsigned short iMarker, unsign SU2_MPI::Error("Marker element index exceeds size.", CURRENT_FUNCTION); } - return geometry_container[ZONE_0][INST_0][MESH_0]->bound[iMarker][iBound]->GetColor(); + return main_geometry->bound[iMarker][iBound]->GetColor(); } vector> CDriverBase::GetElementConnectivities() const { @@ -276,12 +279,12 @@ vector CDriverBase::GetElementConnectivities(unsigned long iElem) SU2_MPI::Error("Element index exceeds size.", CURRENT_FUNCTION); } - unsigned short nNode = geometry_container[ZONE_0][INST_0][MESH_0]->elem[iElem]->GetnNodes(); + unsigned short nNode = main_geometry->elem[iElem]->GetnNodes(); vector values; for (auto iNode = 0u; iNode < nNode; iNode++) { - values.push_back(geometry_container[ZONE_0][INST_0][MESH_0]->elem[iElem]->GetNode(iNode)); + values.push_back(main_geometry->elem[iElem]->GetNode(iNode)); } return values; @@ -304,19 +307,19 @@ vector CDriverBase::GetMarkerElementConnectivities(unsigned short SU2_MPI::Error("Marker element index exceeds size.", CURRENT_FUNCTION); } - unsigned short nNode = geometry_container[ZONE_0][INST_0][MESH_0]->bound[iMarker][iBound]->GetnNodes(); + unsigned short nNode = main_geometry->bound[iMarker][iBound]->GetnNodes(); vector values; for (auto iNode = 0u; iNode < nNode; iNode++) { - values.push_back(geometry_container[ZONE_0][INST_0][MESH_0]->bound[iMarker][iBound]->GetNode(iNode)); + values.push_back(main_geometry->bound[iMarker][iBound]->GetNode(iNode)); } return values; } unsigned long CDriverBase::GetNumberVertices() const { - return geometry_container[ZONE_0][INST_0][MESH_0]->GetnPoint(); + return main_geometry->GetnPoint(); } unsigned long CDriverBase::GetNumberMarkerVertices(unsigned short iMarker) const { @@ -324,7 +327,7 @@ unsigned long CDriverBase::GetNumberMarkerVertices(unsigned short iMarker) const SU2_MPI::Error("Marker index exceeds size.", CURRENT_FUNCTION); } - return geometry_container[ZONE_0][INST_0][MESH_0]->GetnVertex(iMarker); + return main_geometry->GetnVertex(iMarker); } unsigned long CDriverBase::GetNumberHaloVertices() const { @@ -332,7 +335,7 @@ unsigned long CDriverBase::GetNumberHaloVertices() const { unsigned long nHalo = 0; for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { - if (!(geometry_container[ZONE_0][INST_0][MESH_0]->nodes->GetDomain(iPoint))) { + if (!(main_geometry->nodes->GetDomain(iPoint))) { nHalo += 1; } } @@ -347,7 +350,7 @@ unsigned long CDriverBase::GetNumberMarkerHaloVertices(unsigned short iMarker) c for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); - if (!(geometry_container[ZONE_0][INST_0][MESH_0]->nodes->GetDomain(iPoint))) { + if (!(main_geometry->nodes->GetDomain(iPoint))) { nHalo += 1; } } @@ -392,7 +395,7 @@ unsigned long CDriverBase::GetVertexIDs(unsigned long iPoint) const { SU2_MPI::Error("Vertex index exceeds size.", CURRENT_FUNCTION); } - return geometry_container[ZONE_0][INST_0][MESH_0]->nodes->GetGlobalIndex(iPoint); + return main_geometry->nodes->GetGlobalIndex(iPoint); } vector CDriverBase::GetMarkerVertexIDs(unsigned short iMarker) const { @@ -410,7 +413,7 @@ vector CDriverBase::GetMarkerVertexIDs(unsigned short iMarker) co unsigned long CDriverBase::GetMarkerVertexIDs(unsigned short iMarker, unsigned long iVertex) const { auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); - return geometry_container[ZONE_0][INST_0][MESH_0]->nodes->GetGlobalIndex(iPoint); + return main_geometry->nodes->GetGlobalIndex(iPoint); } vector CDriverBase::GetVertexColors() const { @@ -430,7 +433,7 @@ unsigned long CDriverBase::GetVertexColors(unsigned long iPoint) const { SU2_MPI::Error("Vertex index exceeds size.", CURRENT_FUNCTION); } - return geometry_container[ZONE_0][INST_0][MESH_0]->nodes->GetColor(iPoint); + return main_geometry->nodes->GetColor(iPoint); } vector CDriverBase::GetMarkerVertexColors(unsigned short iMarker) const { @@ -448,7 +451,7 @@ vector CDriverBase::GetMarkerVertexColors(unsigned short iMarker) unsigned long CDriverBase::GetMarkerVertexColors(unsigned short iMarker, unsigned long iVertex) const { auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); - return geometry_container[ZONE_0][INST_0][MESH_0]->nodes->GetColor(iPoint); + return main_geometry->nodes->GetColor(iPoint); } vector CDriverBase::GetDomain() const { @@ -468,7 +471,7 @@ bool CDriverBase::GetDomain(unsigned long iPoint) const { SU2_MPI::Error("Vertex index exceeds size.", CURRENT_FUNCTION); } - return geometry_container[ZONE_0][INST_0][MESH_0]->nodes->GetDomain(iPoint); + return main_geometry->nodes->GetDomain(iPoint); } vector CDriverBase::GetMarkerDomain(unsigned short iMarker) const { @@ -486,7 +489,7 @@ vector CDriverBase::GetMarkerDomain(unsigned short iMarker) const { bool CDriverBase::GetMarkerDomain(unsigned short iMarker, unsigned long iVertex) const { auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); - return geometry_container[ZONE_0][INST_0][MESH_0]->nodes->GetDomain(iPoint); + return main_geometry->nodes->GetDomain(iPoint); } vector> CDriverBase::GetInitialCoordinates() const { @@ -508,7 +511,7 @@ vector CDriverBase::GetInitialCoordinates(unsigned long iPoint) c vector values (nDim, 0.0); - if (!config_container[ZONE_0]->GetDeform_Mesh()) { + if (!main_config->GetDeform_Mesh()) { return values; } @@ -538,7 +541,7 @@ vector CDriverBase::GetMarkerInitialCoordinates(unsigned short iM vector values(nDim, 0.0); - if (!config_container[ZONE_0]->GetDeform_Mesh()) { + if (!main_config->GetDeform_Mesh()) { return values; } @@ -571,7 +574,7 @@ vector CDriverBase::GetCoordinates(unsigned long iPoint) const { vector values; for (auto iDim = 0u; iDim < nDim; iDim++) { - const su2double value = geometry_container[ZONE_0][INST_0][MESH_0]->nodes->GetCoord(iPoint, iDim); + const su2double value = main_geometry->nodes->GetCoord(iPoint, iDim); values.push_back(SU2_TYPE::GetValue(value)); } @@ -597,7 +600,7 @@ vector CDriverBase::GetMarkerCoordinates(unsigned short iMarker, vector values; for (auto iDim = 0u; iDim < nDim; iDim++) { - const su2double value = geometry_container[ZONE_0][INST_0][MESH_0]->nodes->GetCoord(iPoint, iDim); + const su2double value = main_geometry->nodes->GetCoord(iPoint, iDim); values.push_back(SU2_TYPE::GetValue(value)); } @@ -627,7 +630,7 @@ void CDriverBase::SetCoordinates(unsigned long iPoint, vector val } for (auto iDim = 0u; iDim < nDim; iDim++) { - geometry_container[ZONE_0][INST_0][MESH_0]->nodes->SetCoord(iPoint, iDim, values[iDim]); + main_geometry->nodes->SetCoord(iPoint, iDim, values[iDim]); } } @@ -651,7 +654,7 @@ void CDriverBase::SetMarkerCoordinates(unsigned short iMarker, unsigned long iVe } for (auto iDim = 0u; iDim < nDim; iDim++) { - geometry_container[ZONE_0][INST_0][MESH_0]->nodes->SetCoord(iPoint, iDim, values[iDim]); + main_geometry->nodes->SetCoord(iPoint, iDim, values[iDim]); } } @@ -672,7 +675,7 @@ vector CDriverBase::GetMarkerDisplacements(unsigned short iMarker vector values (nDim, 0.0); - if (!config_container[ZONE_0]->GetDeform_Mesh()) { + if (!main_config->GetDeform_Mesh()) { return values; } @@ -686,7 +689,7 @@ vector CDriverBase::GetMarkerDisplacements(unsigned short iMarker } void CDriverBase::SetMarkerDisplacements(unsigned short iMarker, vector> values) { - if (!config_container[ZONE_0]->GetDeform_Mesh()) { + if (!main_config->GetDeform_Mesh()) { SU2_MPI::Error("Mesh solver is not defined !", CURRENT_FUNCTION); } @@ -702,7 +705,7 @@ void CDriverBase::SetMarkerDisplacements(unsigned short iMarker, vector values) { - if (!config_container[ZONE_0]->GetDeform_Mesh()) { + if (!main_config->GetDeform_Mesh()) { SU2_MPI::Error("Mesh solver is not defined !", CURRENT_FUNCTION); } @@ -734,7 +737,7 @@ vector CDriverBase::GetMarkerVelocities(unsigned short iMarker, u vector values (nDim, 0.0); - if (!config_container[ZONE_0]->GetDeform_Mesh()) { + if (!main_config->GetDeform_Mesh()) { return values; } @@ -748,7 +751,7 @@ vector CDriverBase::GetMarkerVelocities(unsigned short iMarker, u } void CDriverBase::SetMarkerVelocities(unsigned short iMarker, vector> values) { - if (!config_container[ZONE_0]->GetDeform_Mesh()) { + if (!main_config->GetDeform_Mesh()) { SU2_MPI::Error("Mesh solver is not defined !", CURRENT_FUNCTION); } @@ -764,7 +767,7 @@ void CDriverBase::SetMarkerVelocities(unsigned short iMarker, vector values) { - if (!config_container[ZONE_0]->GetDeform_Mesh()) { + if (!main_config->GetDeform_Mesh()) { SU2_MPI::Error("Mesh solver is not defined !", CURRENT_FUNCTION); } @@ -798,7 +801,7 @@ vector CDriverBase::GetMarkerVertexNormals(unsigned short iMarker vector values; - auto normal = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNormal(); + auto normal = main_geometry->vertex[iMarker][iVertex]->GetNormal(); auto area = GeometryToolbox::Norm(nDim, normal); for (auto iDim = 0u; iDim < nDim; iDim++) { @@ -814,6 +817,6 @@ vector CDriverBase::GetMarkerVertexNormals(unsigned short iMarker void CDriverBase::CommunicateMeshDisplacements(void) { - solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->InitiateComms(geometry_container[ZONE_0][INST_0][MESH_0], config_container[ZONE_0], MESH_DISPLACEMENTS); - solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->CompleteComms(geometry_container[ZONE_0][INST_0][MESH_0], config_container[ZONE_0], MESH_DISPLACEMENTS); + solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->InitiateComms(main_geometry, main_config, MESH_DISPLACEMENTS); + solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->CompleteComms(main_geometry, main_config, MESH_DISPLACEMENTS); } diff --git a/SU2_CFD/src/drivers/CDriver.cpp b/SU2_CFD/src/drivers/CDriver.cpp index 4bb2a8a7071..b649ddc751d 100644 --- a/SU2_CFD/src/drivers/CDriver.cpp +++ b/SU2_CFD/src/drivers/CDriver.cpp @@ -589,6 +589,7 @@ void CDriver::Input_Preprocessing(CConfig **&config, CConfig *&driver_config) { /*--- Set the MPI communicator ---*/ config[iZone]->SetMPICommunicator(SU2_MPI::GetComm()); + } @@ -599,7 +600,10 @@ void CDriver::Input_Preprocessing(CConfig **&config, CConfig *&driver_config) { config_container[iZone]->SetMultizone(driver_config, config_container); } } - + + /*--- Keep a reference to the main (ZONE 0) config ---*/ + main_config = config_container[ZONE_0]; + /*--- Determine whether or not the FEM solver is used, which decides the type of * geometry classes that are instantiated. Only adapted for single-zone problems ---*/ @@ -703,7 +707,9 @@ void CDriver::Geometrical_Preprocessing(CConfig* config, CGeometry **&geometry, geometry_container[iZone][iInst][iMesh]->ComputeSurf_Straightness(config_container[iZone], (iMesh==MESH_0) ); } - + + /*--- Keep a reference to the main (ZONE_0, INST_0, MESH_0) geometry ---*/ + main_geometry = geometry_container[ZONE_0][INST_0][MESH_0]; } void CDriver::Geometrical_Preprocessing_FVM(CConfig *config, CGeometry **&geometry) { diff --git a/SU2_DEF/src/drivers/CDeformationDriver.cpp b/SU2_DEF/src/drivers/CDeformationDriver.cpp index 309e65377d2..2c577ed2c7f 100644 --- a/SU2_DEF/src/drivers/CDeformationDriver.cpp +++ b/SU2_DEF/src/drivers/CDeformationDriver.cpp @@ -140,6 +140,9 @@ void CDeformationDriver::Input_Preprocessing() { config_container[iZone]->SetMultizone(driver_config, config_container); } } + + /*--- Keep a reference to the main (ZONE 0) config ---*/ + main_config = config_container[ZONE_0]; } void CDeformationDriver::Geometrical_Preprocessing() { @@ -220,6 +223,10 @@ void CDeformationDriver::Geometrical_Preprocessing() { /*--- Get the number of dimensions ---*/ nDim = geometry_container[ZONE_0][INST_0][MESH_0]->GetnDim(); + + /*--- Keep a reference to the main (ZONE_0, INST_0, MESH_0) geometry ---*/ + main_geometry = geometry_container[ZONE_0][INST_0][MESH_0]; + } void CDeformationDriver::Output_Preprocessing() { diff --git a/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp b/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp index a91ade80097..94768b3c0e4 100644 --- a/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp +++ b/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp @@ -124,6 +124,9 @@ void CDiscAdjDeformationDriver::Input_Preprocessing() { config_container[iZone]->SetMultizone(driver_config, config_container); } } + + /*--- Keep a reference to the main (ZONE 0) config ---*/ + main_config = config_container[ZONE_0]; } void CDiscAdjDeformationDriver::Geometrical_Preprocessing() { @@ -254,6 +257,10 @@ void CDiscAdjDeformationDriver::Geometrical_Preprocessing() { geometry_container[iZone][INST_0][MESH_0]->PreprocessP2PComms(geometry_container[iZone][INST_0][MESH_0], config_container[iZone]); } + + /*--- Keep a reference to the main (ZONE_0, INST_0, MESH_0) geometry ---*/ + main_geometry = geometry_container[ZONE_0][INST_0][MESH_0]; + } void CDiscAdjDeformationDriver::Output_Preprocessing() { From 6aa8018695d37f754cbcd435685263855d334d69 Mon Sep 17 00:00:00 2001 From: aa-g Date: Mon, 4 Apr 2022 22:23:32 +0200 Subject: [PATCH 27/68] Remove some functions and fix IDs in Get(Marker)?ElementConnectivities --- Common/include/drivers/CDriverBase.hpp | 56 --------------- Common/src/drivers/CDriverBase.cpp | 98 ++------------------------ SU2_CFD/src/drivers/CDriver.cpp | 20 ------ 3 files changed, 6 insertions(+), 168 deletions(-) diff --git a/Common/include/drivers/CDriverBase.hpp b/Common/include/drivers/CDriverBase.hpp index 19f0923e4b2..5a78918ec67 100644 --- a/Common/include/drivers/CDriverBase.hpp +++ b/Common/include/drivers/CDriverBase.hpp @@ -192,34 +192,6 @@ class CDriverBase { */ unsigned long GetMarkerElementIDs(unsigned short iMarker, unsigned long iBound) const; - /*! - * \brief Get the MPI colors for mesh elements. - * \return Element colors. - */ - vector GetElementColors() const; - - /*! - * \brief Get the MPI color for a mesh element. - * \param[in] iElem - Mesh element index. - * \return Element color. - */ - unsigned long GetElementColors(unsigned long iElem) const; - - /*! - * \brief Get the MPI colors for marker elements. - * \param[in] iMarker - Marker index. - * \return Element colors. - */ - vector GetMarkerElementColors(unsigned short iMarker) const; - - /*! - * \brief Get the MPI color for a marker element. - * \param[in] iMarker - Marker index. - * \param[in] iBound - Marker element index. - * \return Element color. - */ - unsigned long GetMarkerElementColors(unsigned short iMarker, unsigned long iBound) const; - /*! * \brief Get the table of vertex IDs belonging to the mesh elements. * \return Element connectivities (nElem, nNode) @@ -317,34 +289,6 @@ class CDriverBase { */ unsigned long GetMarkerVertexIDs(unsigned short iMarker, unsigned long iVertex) const; - /*! - * \brief Get the MPI colors of the mesh vertices. - * \return Vertex colors. - */ - vector GetVertexColors() const; - - /*! - * \brief Get the MPI color of a mesh vertex. - * \param[in] iPoint - Mesh vertex index. - * \return Vertex color. - */ - unsigned long GetVertexColors(unsigned long iPoint) const; - - /*! - * \brief Get the MPI colors of the marker vertices. - * \param[in] iMarker - Marker index. - * \return Vertex colors. - */ - vector GetMarkerVertexColors(unsigned short iMarker) const; - - /*! - * \brief Get the MPI color of a marker vertex. - * \param[in] iMarker - Marker index. - * \param[in] iVertex - Marker vertex index. - * \return Vertex color. - */ - unsigned long GetMarkerVertexColors(unsigned short iMarker, unsigned long iVertex) const; - /*! * \brief Get the halo flags of the mesh vertices. * \return Vertex domain flags. diff --git a/Common/src/drivers/CDriverBase.cpp b/Common/src/drivers/CDriverBase.cpp index 01eccb23448..5702cf51513 100644 --- a/Common/src/drivers/CDriverBase.cpp +++ b/Common/src/drivers/CDriverBase.cpp @@ -222,58 +222,6 @@ unsigned long CDriverBase::GetMarkerElementIDs(unsigned short iMarker, unsigned return main_geometry->bound[iMarker][iBound]->GetGlobalIndex(); } -vector CDriverBase::GetElementColors() const { - const auto nElem = GetNumberElements(); - - vector values; - - for (auto iElem = 0ul; iElem < nElem; iElem++) { - values.push_back(GetElementColors(iElem)); - } - - return values; -} - -unsigned long CDriverBase::GetElementColors(unsigned long iElem) const { - if (iElem >= GetNumberElements()) { - SU2_MPI::Error("Element index exceeds size.", CURRENT_FUNCTION); - } - - return main_geometry->elem[iElem]->GetColor(); -} - -vector CDriverBase::GetMarkerElementColors(unsigned short iMarker) const { - const auto nBound = GetNumberMarkerElements(iMarker); - - vector values; - - for (auto iBound = 0ul; iBound < nBound; iBound++) { - values.push_back(GetMarkerElementColors(iMarker, iBound)); - } - - return values; -} - -unsigned long CDriverBase::GetMarkerElementColors(unsigned short iMarker, unsigned long iBound) const { - if (iBound >= GetNumberMarkerElements(iMarker)) { - SU2_MPI::Error("Marker element index exceeds size.", CURRENT_FUNCTION); - } - - return main_geometry->bound[iMarker][iBound]->GetColor(); -} - -vector> CDriverBase::GetElementConnectivities() const { - const auto nElem = GetNumberElements(); - - vector> values; - - for (auto iElem = 0ul; iElem < nElem; iElem++) { - values.push_back(GetElementConnectivities(iElem)); - } - - return values; -} - vector CDriverBase::GetElementConnectivities(unsigned long iElem) const { if (iElem >= GetNumberElements()) { SU2_MPI::Error("Element index exceeds size.", CURRENT_FUNCTION); @@ -284,7 +232,9 @@ vector CDriverBase::GetElementConnectivities(unsigned long iElem) vector values; for (auto iNode = 0u; iNode < nNode; iNode++) { - values.push_back(main_geometry->elem[iElem]->GetNode(iNode)); + unsigned long iPoint = main_geometry->elem[iElem]->GetNode(iNode); + + values.push_back(main_geometry->nodes->GetGlobalIndex(iPoint)); } return values; @@ -312,7 +262,9 @@ vector CDriverBase::GetMarkerElementConnectivities(unsigned short vector values; for (auto iNode = 0u; iNode < nNode; iNode++) { - values.push_back(main_geometry->bound[iMarker][iBound]->GetNode(iNode)); + unsigned long iPoint = main_geometry->bound[iMarker][iBound]->GetNode(iNode); + + values.push_back(main_geometry->nodes->GetGlobalIndex(iPoint)); } return values; @@ -416,44 +368,6 @@ unsigned long CDriverBase::GetMarkerVertexIDs(unsigned short iMarker, unsigned l return main_geometry->nodes->GetGlobalIndex(iPoint); } -vector CDriverBase::GetVertexColors() const { - const auto nPoint = GetNumberVertices(); - - vector values; - - for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { - values.push_back(GetVertexColors(iPoint)); - } - - return values; -} - -unsigned long CDriverBase::GetVertexColors(unsigned long iPoint) const { - if (iPoint >= GetNumberVertices()) { - SU2_MPI::Error("Vertex index exceeds size.", CURRENT_FUNCTION); - } - - return main_geometry->nodes->GetColor(iPoint); -} - -vector CDriverBase::GetMarkerVertexColors(unsigned short iMarker) const { - const auto nVertex = GetNumberMarkerVertices(iMarker); - - vector values; - - for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - values.push_back(GetMarkerVertexColors(iMarker, iVertex)); - } - - return values; -} - -unsigned long CDriverBase::GetMarkerVertexColors(unsigned short iMarker, unsigned long iVertex) const { - auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); - - return main_geometry->nodes->GetColor(iPoint); -} - vector CDriverBase::GetDomain() const { const auto nPoint = GetNumberVertices(); diff --git a/SU2_CFD/src/drivers/CDriver.cpp b/SU2_CFD/src/drivers/CDriver.cpp index e44a0e6781b..279470e0fcf 100644 --- a/SU2_CFD/src/drivers/CDriver.cpp +++ b/SU2_CFD/src/drivers/CDriver.cpp @@ -1139,26 +1139,6 @@ void CDriver::Inlet_Preprocessing(CSolver ***solver, CGeometry **geometry, string("Please set SPECIFIED_INLET_PROFILE= NO and try again."), CURRENT_FUNCTION); } - } else { - - /*--- Uniform inlets or python-customized inlets ---*/ - - /* --- Initialize quantities for inlet boundary - * This routine does not check if the python wrapper is being used to - * set custom boundary conditions. This is intentional; the - * default values for python custom BCs are initialized with the default - * values specified in the config (avoiding non physical values) --- */ - - for (unsigned short iMesh = 0; iMesh <= config->GetnMGLevels(); iMesh++) { - for(unsigned short iMarker=0; iMarker < config->GetnMarker_All(); iMarker++) { - if (solver[iMesh][FLOW_SOL]) solver[iMesh][FLOW_SOL]->SetUniformInlet(config, iMarker); - if (solver[iMesh][TURB_SOL]) solver[iMesh][TURB_SOL]->SetUniformInlet(config, iMarker); - if (solver[iMesh][SPECIES_SOL]) solver[iMesh][SPECIES_SOL]->SetUniformInlet(config, iMarker); - } - } - - } - } void CDriver::Solver_Restart(CSolver ***solver, CGeometry **geometry, From 3f0247625a9510232edf439297d7295888c6a3ed Mon Sep 17 00:00:00 2001 From: aa-g Date: Mon, 11 Apr 2022 20:15:52 +0200 Subject: [PATCH 28/68] Fix small inconsistency in naming of Getters/Setters --- Common/include/drivers/CDriverBase.hpp | 4 +-- Common/src/drivers/CDriverBase.cpp | 38 +++++++++++++++++--------- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/Common/include/drivers/CDriverBase.hpp b/Common/include/drivers/CDriverBase.hpp index 5a78918ec67..1fa0d011ca2 100644 --- a/Common/include/drivers/CDriverBase.hpp +++ b/Common/include/drivers/CDriverBase.hpp @@ -251,7 +251,7 @@ class CDriverBase { * \param[in] iMarker - Marker index. * \return Mesh vertex indices. */ - vector GetMarkerVertexIndex(unsigned short iMarker) const; + vector GetMarkerVertexIndices(unsigned short iMarker) const; /*! * \brief Get the mesh vertex index of a marker vertex. @@ -259,7 +259,7 @@ class CDriverBase { * \param[in] iVertex - Marker vertex index. * \return Mesh vertex index. */ - unsigned long GetMarkerVertexIndex(unsigned short iMarker, unsigned long iVertex) const; + unsigned long GetMarkerVertexIndices(unsigned short iMarker, unsigned long iVertex) const; /*! * \brief Get the global IDs of the mesh vertices. diff --git a/Common/src/drivers/CDriverBase.cpp b/Common/src/drivers/CDriverBase.cpp index 5702cf51513..b778a6ab99b 100644 --- a/Common/src/drivers/CDriverBase.cpp +++ b/Common/src/drivers/CDriverBase.cpp @@ -222,6 +222,18 @@ unsigned long CDriverBase::GetMarkerElementIDs(unsigned short iMarker, unsigned return main_geometry->bound[iMarker][iBound]->GetGlobalIndex(); } +vector> CDriverBase::GetElementConnectivities() const { + const auto nElem = GetNumberElements(); + + vector> values; + + for (auto iElem = 0ul; iElem < nElem; iElem++) { + values.push_back(GetElementConnectivities(iElem)); + } + + return values; +} + vector CDriverBase::GetElementConnectivities(unsigned long iElem) const { if (iElem >= GetNumberElements()) { SU2_MPI::Error("Element index exceeds size.", CURRENT_FUNCTION); @@ -300,7 +312,7 @@ unsigned long CDriverBase::GetNumberMarkerHaloVertices(unsigned short iMarker) c unsigned long nHalo = 0; for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); + auto iPoint = GetMarkerVertexIndices(iMarker, iVertex); if (!(main_geometry->nodes->GetDomain(iPoint))) { nHalo += 1; @@ -310,19 +322,19 @@ unsigned long CDriverBase::GetNumberMarkerHaloVertices(unsigned short iMarker) c return nHalo; } -vector CDriverBase::GetMarkerVertexIndex(unsigned short iMarker) const { +vector CDriverBase::GetMarkerVertexIndices(unsigned short iMarker) const { const auto nVertex = GetNumberMarkerVertices(iMarker); vector values; for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - values.push_back(GetMarkerVertexIndex(iMarker, iVertex)); + values.push_back(GetMarkerVertexIndices(iMarker, iVertex)); } return values; } -unsigned long CDriverBase::GetMarkerVertexIndex(unsigned short iMarker, unsigned long iVertex) const { +unsigned long CDriverBase::GetMarkerVertexIndices(unsigned short iMarker, unsigned long iVertex) const { if (iVertex >= GetNumberMarkerVertices(iMarker)) { SU2_MPI::Error("Marker vertex index exceeds size.", CURRENT_FUNCTION); } @@ -363,7 +375,7 @@ vector CDriverBase::GetMarkerVertexIDs(unsigned short iMarker) co } unsigned long CDriverBase::GetMarkerVertexIDs(unsigned short iMarker, unsigned long iVertex) const { - auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); + auto iPoint = GetMarkerVertexIndices(iMarker, iVertex); return main_geometry->nodes->GetGlobalIndex(iPoint); } @@ -401,7 +413,7 @@ vector CDriverBase::GetMarkerDomain(unsigned short iMarker) const { } bool CDriverBase::GetMarkerDomain(unsigned short iMarker, unsigned long iVertex) const { - auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); + auto iPoint = GetMarkerVertexIndices(iMarker, iVertex); return main_geometry->nodes->GetDomain(iPoint); } @@ -451,7 +463,7 @@ vector> CDriverBase::GetMarkerInitialCoordinates(unsigned } vector CDriverBase::GetMarkerInitialCoordinates(unsigned short iMarker, unsigned long iVertex) const { - auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); + auto iPoint = GetMarkerVertexIndices(iMarker, iVertex); vector values(nDim, 0.0); @@ -509,7 +521,7 @@ vector> CDriverBase::GetMarkerCoordinates(unsigned short i } vector CDriverBase::GetMarkerCoordinates(unsigned short iMarker, unsigned long iVertex) const { - auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); + auto iPoint = GetMarkerVertexIndices(iMarker, iVertex); vector values; @@ -561,7 +573,7 @@ void CDriverBase::SetMarkerCoordinates(unsigned short iMarker, vector values) { - auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); + auto iPoint = GetMarkerVertexIndices(iMarker, iVertex); if (values.size() != nDim) { SU2_MPI::Error("Invalid number of dimensions !", CURRENT_FUNCTION); @@ -585,7 +597,7 @@ vector> CDriverBase::GetMarkerDisplacements(unsigned short } vector CDriverBase::GetMarkerDisplacements(unsigned short iMarker, unsigned long iVertex) const { - auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); + auto iPoint = GetMarkerVertexIndices(iMarker, iVertex); vector values (nDim, 0.0); @@ -623,7 +635,7 @@ void CDriverBase::SetMarkerDisplacements(unsigned short iMarker, unsigned long i SU2_MPI::Error("Mesh solver is not defined !", CURRENT_FUNCTION); } - auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); + auto iPoint = GetMarkerVertexIndices(iMarker, iVertex); if (values.size() != nDim) { SU2_MPI::Error("Invalid number of dimensions !", CURRENT_FUNCTION); @@ -647,7 +659,7 @@ vector> CDriverBase::GetMarkerVelocities(unsigned short iM } vector CDriverBase::GetMarkerVelocities(unsigned short iMarker, unsigned long iVertex) const { - auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); + auto iPoint = GetMarkerVertexIndices(iMarker, iVertex); vector values (nDim, 0.0); @@ -685,7 +697,7 @@ void CDriverBase::SetMarkerVelocities(unsigned short iMarker, unsigned long iVer SU2_MPI::Error("Mesh solver is not defined !", CURRENT_FUNCTION); } - auto iPoint = GetMarkerVertexIndex(iMarker, iVertex); + auto iPoint = GetMarkerVertexIndices(iMarker, iVertex); if (values.size() != nDim) { SU2_MPI::Error("Invalid number of dimensions !", CURRENT_FUNCTION); From 259cf1c6afaf475f18f1fb7d19c9546535aec242 Mon Sep 17 00:00:00 2001 From: patelha57 Date: Thu, 8 Dec 2022 20:05:47 -0800 Subject: [PATCH 29/68] Update CDeformationDriver --- .../include/drivers/CDeformationDriver.hpp | 155 +-- SU2_DEF/src/drivers/CDeformationDriver.cpp | 1077 ++++++++--------- 2 files changed, 600 insertions(+), 632 deletions(-) diff --git a/SU2_DEF/include/drivers/CDeformationDriver.hpp b/SU2_DEF/include/drivers/CDeformationDriver.hpp index 507978d77e7..b0d08f21836 100644 --- a/SU2_DEF/include/drivers/CDeformationDriver.hpp +++ b/SU2_DEF/include/drivers/CDeformationDriver.hpp @@ -31,84 +31,89 @@ #include "../../../Common/include/CConfig.hpp" #undef ENABLE_MAPS -#include "../../../Common/include/parallelization/mpi_structure.hpp" - +#include "../../../Common/include/drivers/CDriverBase.hpp" +#include "../../../Common/include/geometry/CGeometry.hpp" #include "../../../Common/include/grid_movement/CSurfaceMovement.hpp" #include "../../../Common/include/grid_movement/CVolumetricMovement.hpp" -#include "../../../SU2_CFD/include/output/COutput.hpp" +#include "../../../Common/include/parallelization/mpi_structure.hpp" #include "../../../SU2_CFD/include/numerics/CNumerics.hpp" -#include "../../../Common/include/geometry/CGeometry.hpp" -#include "../../../Common/include/drivers/CDriverBase.hpp" +#include "../../../SU2_CFD/include/output/COutput.hpp" class CDeformationDriver : public CDriverBase { - -protected: - bool haveSurfaceDeformation = false; // flag used to determine whether surface deformation is available for output - -public: - /*! - * \brief Constructor of the class. - * \param[in] confFile - Configuration file name. - * \param[in] MPICommunicator - MPI communicator for SU2. - */ - CDeformationDriver(char* confFile, SU2_Comm MPICommunicator); - - /*! - * \brief Destructor of the class. - */ - ~CDeformationDriver(void); - - /*! - * \brief [Overload] Launch the computation for single-zone problems. - */ - void Run(); - - /*! - * \brief Output the mesh. - */ - void Output(); - - /*! - * \brief Deallocation routine - */ - void Postprocessing(); - - void CommunicateMeshDisplacements(void); - -protected: - /*! - * \brief Read in the config and mesh files. - */ - void Input_Preprocessing(); - - /*! - * \brief Construction of the edge-based data structure. - */ - void Geometrical_Preprocessing(); - - /*! - * \brief Preprocess the output container. - */ - void Output_Preprocessing(); - - /*! - * \brief Preprocess the mesh solver container. - */ - void Solver_Preprocessing(); - - /*! - * \brief Preprocess the numerics container. - */ - void Numerics_Preprocessing(); - - /*! - * \brief Mesh deformation based on linear elasticity solver (CMeshSolver). - */ - void Update(); - - /*! - * \brief Mesh deformation based on legacy implementation. - */ - void Update_Legacy(); - + protected: + bool haveSurfaceDeformation = false; // flag used to determine whether surface deformation is available for output + + public: + /*! + * \brief Constructor of the class. + * \param[in] confFile - Configuration file name. + * \param[in] MPICommunicator - MPI communicator for SU2. + */ + CDeformationDriver(char* confFile, SU2_Comm MPICommunicator); + + /*! + * \brief Destructor of the class. + */ + ~CDeformationDriver(void); + + /*! + * \brief Preprocess the driver data. + */ + void Preprocess(); + + /*! + * \brief Launch the driver computation. + */ + void Run(); + + /*! + * \brief Output the mesh. + */ + void Output(); + + /*! + * \brief Deallocation routine. + */ + void Postprocessing(); + + /*! + * \brief Communicate boundary mesh displacements. + */ + void CommunicateMeshDisplacements(void); + + protected: + /*! + * \brief Read in the config and mesh files. + */ + void Input_Preprocessing(); + + /*! + * \brief Construction of the edge-based data structure. + */ + void Geometrical_Preprocessing(); + + /*! + * \brief Preprocess the output container. + */ + void Output_Preprocessing(); + + /*! + * \brief Preprocess the mesh solver container. + */ + void Solver_Preprocessing(); + + /*! + * \brief Preprocess the numerics container. + */ + void Numerics_Preprocessing(); + + /*! + * \brief Mesh deformation based on linear elasticity solver (CMeshSolver). + */ + void Update(); + + /*! + * \brief Mesh deformation based on legacy implementation. + */ + void Update_Legacy(); }; diff --git a/SU2_DEF/src/drivers/CDeformationDriver.cpp b/SU2_DEF/src/drivers/CDeformationDriver.cpp index 2c577ed2c7f..4a5e0febd32 100644 --- a/SU2_DEF/src/drivers/CDeformationDriver.cpp +++ b/SU2_DEF/src/drivers/CDeformationDriver.cpp @@ -28,624 +28,587 @@ #include "../../include/drivers/CDeformationDriver.hpp" #include "../../../Common/include/geometry/CPhysicalGeometry.hpp" -#include "../../../Common/include/toolboxes/geometry_toolbox.hpp" -#include "../../../SU2_CFD/include/solvers/CMeshSolver.hpp" -#include "../../../SU2_CFD/include/output/CMeshOutput.hpp" #include "../../../SU2_CFD/include/numerics/elasticity/CFEALinearElasticity.hpp" +#include "../../../SU2_CFD/include/output/CMeshOutput.hpp" +#include "../../../SU2_CFD/include/solvers/CMeshSolver.hpp" using namespace std; -CDeformationDriver::CDeformationDriver(char* confFile, SU2_Comm MPICommunicator): -CDriverBase(confFile, 1, MPICommunicator) -{ - - /*--- Initialize Medipack (must also be here so it is initialized from python) ---*/ +CDeformationDriver::CDeformationDriver(char* confFile, SU2_Comm MPICommunicator) + : CDriverBase(confFile, 1, MPICommunicator) { + +/*--- Initialize MeDiPack (must also be here to initialize it from Python) ---*/ #ifdef HAVE_MPI #if defined(CODI_REVERSE_TYPE) || defined(CODI_FORWARD_TYPE) - SU2_MPI::Init_AMPI(); + SU2_MPI::Init_AMPI(); #endif #endif - - SU2_MPI::SetComm(MPICommunicator); - - rank = SU2_MPI::GetRank(); - size = SU2_MPI::GetSize(); - - /*--- Initialize containers --- */ - - SetContainers_Null(); - - /*--- Preprocessing of the config files. ---*/ - - Input_Preprocessing(); - - /*--- Set up a timer for performance benchmarking ---*/ - - StartTime = SU2_MPI::Wtime(); - - /*--- Preprocessing of the geometry for all zones. ---*/ - - Geometrical_Preprocessing(); - - /*--- Preprocessing of the output for all zones. ---*/ - - Output_Preprocessing(); - - if (driver_config->GetDeform_Mesh()){ - - /*--- Preprocessing of the mesh solver for all zones. ---*/ - - Solver_Preprocessing(); - - /*--- Preprocessing of the mesh solver for all zones. ---*/ - - Numerics_Preprocessing(); - - } - - /*--- Preprocessing time is reported now, but not included in the next compute portion. ---*/ - - StopTime = SU2_MPI::Wtime(); - - /*--- Compute/print the total time for performance benchmarking. ---*/ - - UsedTime = StopTime-StartTime; - UsedTimePreproc = UsedTime; - UsedTimeCompute = 0.0; - -} -CDeformationDriver::~CDeformationDriver(void) { - + SU2_MPI::SetComm(MPICommunicator); + + rank = SU2_MPI::GetRank(); + size = SU2_MPI::GetSize(); + + /*--- Initialize containers. --- */ + + SetContainers_Null(); + + /*--- Preprocessing of the config files. ---*/ + + Input_Preprocessing(); + + /*--- Set up a timer for performance benchmarking. ---*/ + + StartTime = SU2_MPI::Wtime(); + + /*--- Preprocessing of the geometry for all zones. ---*/ + + Geometrical_Preprocessing(); + + /*--- Preprocessing of the output for all zones. ---*/ + + Output_Preprocessing(); + + if (driver_config->GetDeform_Mesh()) { + /*--- Preprocessing of the mesh solver for all zones. ---*/ + + Solver_Preprocessing(); + + /*--- Preprocessing of the mesh solver for all zones. ---*/ + + Numerics_Preprocessing(); + + } + + /*--- Preprocessing time is reported now, but not included in the next compute portion. ---*/ + + StopTime = SU2_MPI::Wtime(); + + /*--- Compute the total time for performance benchmarking. ---*/ + + UsedTime = StopTime - StartTime; + UsedTimePreproc = UsedTime; + UsedTimeCompute = 0.0; } +CDeformationDriver::~CDeformationDriver(void) {} + void CDeformationDriver::Input_Preprocessing() { - - /*--- Initialize a char to store the zone filename ---*/ - char zone_file_name[MAX_STRING_SIZE]; - - /*--- Initialize the configuration of the driver ---*/ - driver_config = new CConfig(config_file_name, SU2_COMPONENT::SU2_DEF); - - nZone = driver_config->GetnZone(); - - /*--- 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. ---*/ - - if (driver_config->GetnConfigFiles() > 0){ - strcpy(zone_file_name, driver_config->GetConfigFilename(iZone).c_str()); - - config_container[iZone] = new CConfig(driver_config, zone_file_name, SU2_COMPONENT::SU2_DEF, iZone, nZone, true); - } else { - config_container[iZone] = new CConfig(driver_config, config_file_name, SU2_COMPONENT::SU2_DEF, iZone, nZone, true); - } - - config_container[iZone]->SetMPICommunicator(SU2_MPI::GetComm()); + /*--- Initialize a char to store the zone filename. ---*/ + + char zone_file_name[MAX_STRING_SIZE]; + + /*--- Initialize the configuration of the driver. ---*/ + + driver_config = new CConfig(config_file_name, SU2_COMPONENT::SU2_DEF); + + nZone = driver_config->GetnZone(); + + /*--- 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. ---*/ + + if (driver_config->GetnConfigFiles() > 0) { + strcpy(zone_file_name, driver_config->GetConfigFilename(iZone).c_str()); + config_container[iZone] = new CConfig(driver_config, zone_file_name, SU2_COMPONENT::SU2_DEF, iZone, nZone, true); + } else { + config_container[iZone] = new CConfig(driver_config, config_file_name, SU2_COMPONENT::SU2_DEF, iZone, nZone, true); } - - /*--- Set the multizone part of the problem. ---*/ - - if (driver_config->GetMultizone_Problem()){ - for (iZone = 0; iZone < nZone; iZone++) { - - /*--- Set the interface markers for multizone ---*/ - - config_container[iZone]->SetMultizone(driver_config, config_container); - } + + config_container[iZone]->SetMPICommunicator(SU2_MPI::GetComm()); + } + + /*--- Set the multi-zone part of the problem. ---*/ + + if (driver_config->GetMultizone_Problem()) { + for (iZone = 0; iZone < nZone; iZone++) { + /*--- Set the interface markers for multi-zone. ---*/ + + config_container[iZone]->SetMultizone(driver_config, config_container); } + } - /*--- Keep a reference to the main (ZONE 0) config ---*/ - main_config = config_container[ZONE_0]; + /*--- Keep a reference to the main (ZONE 0) config. ---*/ + + main_config = config_container[ZONE_0]; } void CDeformationDriver::Geometrical_Preprocessing() { - - for (iZone = 0; iZone < nZone; iZone++) { - - /*--- Definition of the geometry class to store the primal grid in the partitioning process. ---*/ - - CGeometry *geometry_aux = nullptr; - - /*--- 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]); - - /*--- Build the grid data structures using the ParMETIS coloring. ---*/ - - unsigned short nInst_Zone = nInst[iZone]; - unsigned short nMesh = 1; - - geometry_container[iZone] = new CGeometry**[nInst_Zone] (); - geometry_container[iZone][INST_0] = new CGeometry*[nMesh] (); - geometry_container[iZone][INST_0][MESH_0] = new CPhysicalGeometry(geometry_aux, config_container[iZone]); - - /*--- Deallocate the memory of geometry_aux ---*/ - - delete geometry_aux; - - /*--- Add the Send/Receive boundaries ---*/ - - geometry_container[iZone][INST_0][MESH_0]->SetSendReceive(config_container[iZone]); - - /*--- Add the Send/Receive boundaries ---*/ - - geometry_container[iZone][INST_0][MESH_0]->SetBoundaries(config_container[iZone]); - - /*--- Computational grid preprocesing ---*/ - - if (rank == MASTER_NODE) cout << endl << "----------------------- Preprocessing computations ----------------------" << endl; - - /*--- Compute elements surrounding points, points surrounding points ---*/ - - if (rank == MASTER_NODE) cout << "Setting local point connectivity." <SetPoint_Connectivity(); - - /*--- Check the orientation before computing geometrical quantities ---*/ - - geometry_container[iZone][INST_0][MESH_0]->SetBoundVolume(); - if (config_container[iZone]->GetReorientElements()) { - if (rank == MASTER_NODE) cout << "Checking the numerical grid orientation of the interior elements." <Check_IntElem_Orientation(config_container[iZone]); - geometry_container[iZone][INST_0][MESH_0]->Check_BoundElem_Orientation(config_container[iZone]); - } - - /*--- Create the edge structure ---*/ - - if (rank == MASTER_NODE) cout << "Identify edges and vertices." <SetEdges(); - geometry_container[iZone][INST_0][MESH_0]->SetVertex(config_container[iZone]); - - if (config_container[iZone]->GetDesign_Variable(0) != NO_DEFORMATION) { - - /*--- Create the dual control volume structures ---*/ - - if (rank == MASTER_NODE) cout << "Setting the bound control volume structure." << endl; - geometry_container[iZone][INST_0][MESH_0]->SetControlVolume(config_container[iZone], ALLOCATE); - geometry_container[iZone][INST_0][MESH_0]->SetBoundControlVolume(config_container[iZone], ALLOCATE); - } - - /*--- Create the point-to-point MPI communication structures. ---*/ - - geometry_container[iZone][INST_0][MESH_0]->PreprocessP2PComms(geometry_container[iZone][INST_0][MESH_0], config_container[iZone]); - + for (iZone = 0; iZone < nZone; iZone++) { + /*--- Definition of the geometry class to store the primal grid in the partitioning process. ---*/ + + CGeometry* geometry_aux = nullptr; + + /*--- 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]); + + /*--- Build the grid data structures using the ParMETIS coloring. ---*/ + + unsigned short nInst_Zone = nInst[iZone]; + unsigned short nMesh = 1; + + geometry_container[iZone] = new CGeometry**[nInst_Zone](); + geometry_container[iZone][INST_0] = new CGeometry*[nMesh](); + geometry_container[iZone][INST_0][MESH_0] = new CPhysicalGeometry(geometry_aux, config_container[iZone]); + + /*--- Deallocate the memory of geometry_aux. ---*/ + + delete geometry_aux; + + /*--- Add the Send/Receive boundaries. ---*/ + + geometry_container[iZone][INST_0][MESH_0]->SetSendReceive(config_container[iZone]); + + /*--- Add the Send/Receive boundaries. ---*/ + + geometry_container[iZone][INST_0][MESH_0]->SetBoundaries(config_container[iZone]); + + /*--- Computational grid preprocessing. ---*/ + + if (rank == MASTER_NODE) cout << endl << "----------------------- Preprocessing computations ----------------------" << endl; + + /*--- Compute elements surrounding points, points surrounding points. ---*/ + + if (rank == MASTER_NODE) cout << "Setting local point connectivity." << endl; + geometry_container[iZone][INST_0][MESH_0]->SetPoint_Connectivity(); + + /*--- Check the orientation before computing geometrical quantities. ---*/ + + geometry_container[iZone][INST_0][MESH_0]->SetBoundVolume(); + if (config_container[iZone]->GetReorientElements()) { + if (rank == MASTER_NODE) cout << "Checking the numerical grid orientation of the interior elements." << endl; + geometry_container[iZone][INST_0][MESH_0]->Check_IntElem_Orientation(config_container[iZone]); + geometry_container[iZone][INST_0][MESH_0]->Check_BoundElem_Orientation(config_container[iZone]); + } + + /*--- Create the edge structure. ---*/ + + if (rank == MASTER_NODE) cout << "Identify edges and vertices." << endl; + geometry_container[iZone][INST_0][MESH_0]->SetEdges(); + geometry_container[iZone][INST_0][MESH_0]->SetVertex(config_container[iZone]); + + if (config_container[iZone]->GetDesign_Variable(0) != NO_DEFORMATION) { + /*--- Create the dual control volume structures. ---*/ + + if (rank == MASTER_NODE) cout << "Setting the bound control volume structure." << endl; + geometry_container[iZone][INST_0][MESH_0]->SetControlVolume(config_container[iZone], ALLOCATE); + geometry_container[iZone][INST_0][MESH_0]->SetBoundControlVolume(config_container[iZone], ALLOCATE); } - - /*--- Get the number of dimensions ---*/ - nDim = geometry_container[ZONE_0][INST_0][MESH_0]->GetnDim(); - /*--- Keep a reference to the main (ZONE_0, INST_0, MESH_0) geometry ---*/ - main_geometry = geometry_container[ZONE_0][INST_0][MESH_0]; + /*--- Create the point-to-point MPI communication structures. ---*/ + + geometry_container[iZone][INST_0][MESH_0]->PreprocessP2PComms(geometry_container[iZone][INST_0][MESH_0],config_container[iZone]); + } + + /*--- Get the number of dimensions. ---*/ + nDim = geometry_container[ZONE_0][INST_0][MESH_0]->GetnDim(); + + /*--- Keep a reference to the main (ZONE_0, INST_0, MESH_0) geometry. ---*/ + + main_geometry = geometry_container[ZONE_0][INST_0][MESH_0]; } void CDeformationDriver::Output_Preprocessing() { - - for (iZone = 0; iZone < nZone; iZone++) { - - /*--- Allocate the mesh output ---*/ - - output_container[iZone] = new CMeshOutput(config_container[iZone], geometry_container[iZone][INST_0][MESH_0]->GetnDim()); - - /*--- Preprocess the volume output ---*/ - - output_container[iZone]->PreprocessVolumeOutput(config_container[iZone]); - - /*--- Preprocess history --- */ - - output_container[iZone]->PreprocessHistoryOutput(config_container[iZone], false); - - } + for (iZone = 0; iZone < nZone; iZone++) { + /*--- Allocate the mesh output. ---*/ + + output_container[iZone] = new CMeshOutput(config_container[iZone], geometry_container[iZone][INST_0][MESH_0]->GetnDim()); + + /*--- Preprocess the volume output. ---*/ + + output_container[iZone]->PreprocessVolumeOutput(config_container[iZone]); + + /*--- Preprocess history. --- */ + + output_container[iZone]->PreprocessHistoryOutput(config_container[iZone], false); + } } void CDeformationDriver::Solver_Preprocessing() { - - for (iZone = 0; iZone < nZone; iZone++) { - unsigned short nInst_Zone = nInst[iZone]; - unsigned short nMesh = 1; - unsigned short nSols = MAX_SOLS; - - - solver_container[iZone] = new CSolver*** [nInst_Zone] (); - solver_container[iZone][INST_0] = new CSolver** [nMesh] (); - solver_container[iZone][INST_0][MESH_0] = new CSolver* [nSols] (); - solver_container[iZone][INST_0][MESH_0][MESH_SOL] = new CMeshSolver(geometry_container[iZone][INST_0][MESH_0], config_container[iZone]); - } + for (iZone = 0; iZone < nZone; iZone++) { + unsigned short nInst_Zone = nInst[iZone]; + unsigned short nMesh = 1; + unsigned short nSols = MAX_SOLS; + + solver_container[iZone] = new CSolver***[nInst_Zone](); + solver_container[iZone][INST_0] = new CSolver**[nMesh](); + solver_container[iZone][INST_0][MESH_0] = new CSolver*[nSols](); + solver_container[iZone][INST_0][MESH_0][MESH_SOL] = + new CMeshSolver(geometry_container[iZone][INST_0][MESH_0], config_container[iZone]); + } } void CDeformationDriver::Numerics_Preprocessing() { - - for (iZone = 0; iZone < nZone; iZone++) { - unsigned short nInst_Zone = nInst[iZone]; - unsigned short nMesh = 1; - unsigned short nSols = MAX_SOLS; - unsigned int nTerm = omp_get_num_threads() * MAX_TERMS; - - numerics_container[iZone] = new CNumerics**** [nInst_Zone] (); - numerics_container[iZone][INST_0] = new CNumerics*** [nMesh] (); - numerics_container[iZone][INST_0][MESH_0] = new CNumerics** [nSols] (); - numerics_container[iZone][INST_0][MESH_0][MESH_SOL] = new CNumerics* [nTerm] (); - - for (int thread = 0; thread < omp_get_max_threads(); ++thread) { - const int iTerm = FEA_TERM + thread * MAX_TERMS; - const int nDim = geometry_container[iZone][INST_0][MESH_0]->GetnDim(); - - numerics_container[iZone][INST_0][MESH_0][MESH_SOL][iTerm] = new CFEAMeshElasticity(nDim, nDim, geometry_container[iZone][INST_0][MESH_0]->GetnElem(), config_container[iZone]); - } - + for (iZone = 0; iZone < nZone; iZone++) { + unsigned short nInst_Zone = nInst[iZone]; + unsigned short nMesh = 1; + unsigned short nSols = MAX_SOLS; + unsigned int nTerm = omp_get_num_threads() * MAX_TERMS; + + numerics_container[iZone] = new CNumerics****[nInst_Zone](); + numerics_container[iZone][INST_0] = new CNumerics***[nMesh](); + numerics_container[iZone][INST_0][MESH_0] = new CNumerics**[nSols](); + numerics_container[iZone][INST_0][MESH_0][MESH_SOL] = new CNumerics*[nTerm](); + + for (int thread = 0; thread < omp_get_max_threads(); ++thread) { + const int iTerm = FEA_TERM + thread * MAX_TERMS; + const int nDim = geometry_container[iZone][INST_0][MESH_0]->GetnDim(); + + numerics_container[iZone][INST_0][MESH_0][MESH_SOL][iTerm] = new CFEAMeshElasticity( + nDim, nDim, geometry_container[iZone][INST_0][MESH_0]->GetnElem(), config_container[iZone]); } - + } } +void CDeformationDriver::Preprocess() {} + void CDeformationDriver::Run() { - - /* --- Start measuring computation time ---*/ - - StartTime = SU2_MPI::Wtime(); - - /*--- Surface grid deformation using design variables ---*/ - - if (driver_config->GetDeform_Mesh()) { - Update(); - } - else { - Update_Legacy(); - } - - /*--- Synchronization point after a single solver iteration. Compute the - wall clock time required. ---*/ - - StopTime = SU2_MPI::Wtime(); - - UsedTimeCompute = StopTime-StartTime; - if (rank == MASTER_NODE) { - cout << "\nCompleted in " << fixed << UsedTimeCompute << " seconds on "<< size; - - if (size == 1) cout << " core." << endl; else cout << " cores." << endl; - } - - /*--- Output the deformed mesh ---*/ - Output(); - + /* --- Start measuring computation time. ---*/ + + StartTime = SU2_MPI::Wtime(); + + /*--- Surface grid deformation using design variables. ---*/ + + if (driver_config->GetDeform_Mesh()) { + Update(); + } else { + Update_Legacy(); + } + + /*--- Synchronization point after a single solver iteration. Compute the wall clock time required. ---*/ + + StopTime = SU2_MPI::Wtime(); + + UsedTimeCompute = StopTime - StartTime; + if (rank == MASTER_NODE) { + cout << "\nCompleted in " << fixed << UsedTimeCompute << " seconds on " << size; + + if (size == 1) cout << " core." << endl; else cout << " cores." << endl; + } + + /*--- Output the deformed mesh. ---*/ + + Output(); } void CDeformationDriver::Update() { - - for (iZone = 0; iZone < nZone; iZone++){ - - /*--- Set the stiffness of each element mesh into the mesh numerics ---*/ - - solver_container[iZone][INST_0][MESH_0][MESH_SOL]->SetMesh_Stiffness(numerics_container[iZone][INST_0][MESH_0][MESH_SOL], config_container[iZone]); - - /*--- Deform the volume grid around the new boundary locations ---*/ - - solver_container[iZone][INST_0][MESH_0][MESH_SOL]->DeformMesh(geometry_container[iZone][INST_0][MESH_0], numerics_container[iZone][INST_0][MESH_0][MESH_SOL], config_container[iZone]); - - } + for (iZone = 0; iZone < nZone; iZone++) { + /*--- Set the stiffness of each element mesh into the mesh numerics. ---*/ + + solver_container[iZone][INST_0][MESH_0][MESH_SOL]->SetMesh_Stiffness(numerics_container[iZone][INST_0][MESH_0][MESH_SOL], config_container[iZone]); + + /*--- Deform the volume grid around the new boundary locations. ---*/ + + solver_container[iZone][INST_0][MESH_0][MESH_SOL]->DeformMesh(geometry_container[iZone][INST_0][MESH_0], + numerics_container[iZone][INST_0][MESH_0][MESH_SOL], + config_container[iZone]); + } } void CDeformationDriver::Update_Legacy() { - - for (iZone = 0; iZone < nZone; iZone++){ - - if (config_container[iZone]->GetDesign_Variable(0) != NO_DEFORMATION) { - unsigned short nInst_Zone = nInst[iZone]; - - /*--- Definition of the Class for grid movement ---*/ - grid_movement[iZone] = new CVolumetricMovement* [nInst_Zone] (); - grid_movement[iZone][INST_0] = new CVolumetricMovement(geometry_container[iZone][INST_0][MESH_0], config_container[iZone]); - - /*--- Save original coordinates to be reused in convexity checking procedure ---*/ - auto OriginalCoordinates = geometry_container[iZone][INST_0][MESH_0]->nodes->GetCoord(); - - /*--- First check for volumetric grid deformation/transformations ---*/ - - if (config_container[iZone]->GetDesign_Variable(0) == SCALE_GRID) { - - if (rank == MASTER_NODE) - cout << endl << "--------------------- Volumetric grid scaling (ZONE " << iZone <<") ------------------" << endl; - grid_movement[iZone][INST_0]->SetVolume_Scaling(geometry_container[iZone][INST_0][MESH_0], config_container[iZone], false); - - } else if (config_container[iZone]->GetDesign_Variable(0) == TRANSLATE_GRID) { - - if (rank == MASTER_NODE) - cout << endl << "------------------- Volumetric grid translation (ZONE " << iZone <<") ----------------" << endl; - grid_movement[iZone][INST_0]->SetVolume_Translation(geometry_container[iZone][INST_0][MESH_0], config_container[iZone], false); - - } else if (config_container[iZone]->GetDesign_Variable(0) == ROTATE_GRID) { - - if (rank == MASTER_NODE) - cout << endl << "--------------------- Volumetric grid rotation (ZONE " << iZone <<") -----------------" << endl; - grid_movement[iZone][INST_0]->SetVolume_Rotation(geometry_container[iZone][INST_0][MESH_0], config_container[iZone], false); - - } else { - - /*--- If no volume-type deformations are requested, then this is a - surface-based deformation or FFD set up. ---*/ - - if (rank == MASTER_NODE) - cout << endl << "--------------------- Surface grid deformation (ZONE " << iZone <<") -----------------" << endl; - - /*--- Definition and initialization of the surface deformation class ---*/ - - surface_movement[iZone] = new CSurfaceMovement(); - haveSurfaceDeformation = true; - - /*--- Copy coordinates to the surface structure ---*/ - - surface_movement[iZone]->CopyBoundary(geometry_container[iZone][INST_0][MESH_0], config_container[iZone]); - - /*--- Surface grid deformation ---*/ - - if (rank == MASTER_NODE) cout << "Performing the deformation of the surface grid." << endl; - auto TotalDeformation = surface_movement[iZone]->SetSurface_Deformation(geometry_container[iZone][INST_0][MESH_0], config_container[iZone]); - - if (config_container[iZone]->GetDesign_Variable(0) != FFD_SETTING) { - - if (rank == MASTER_NODE) - cout << endl << "------------------- Volumetric grid deformation (ZONE " << iZone <<") ----------------" << endl; - - if (rank == MASTER_NODE) - cout << "Performing the deformation of the volumetric grid." << endl; - grid_movement[iZone][INST_0]->SetVolume_Deformation(geometry_container[iZone][INST_0][MESH_0], config_container[iZone], false); - - /*--- Get parameters for convexity check ---*/ - bool ConvexityCheck; - unsigned short ConvexityCheck_MaxIter, ConvexityCheck_MaxDepth; - - tie(ConvexityCheck, ConvexityCheck_MaxIter, ConvexityCheck_MaxDepth) = config_container[iZone]->GetConvexityCheck(); - - /*--- Recursively change deformations if there are nonconvex elements. ---*/ - - if (ConvexityCheck && geometry_container[iZone][INST_0][MESH_0]->GetnNonconvexElements() > 0) { - if (rank == MASTER_NODE) { - cout << "Nonconvex elements present after deformation. " << endl; - cout << "Recursively lowering deformation magnitude." << endl; - } - - /*--- Load initial deformation values ---*/ - auto InitialDeformation = TotalDeformation; - - unsigned short ConvexityCheckIter, RecursionDepth = 0; - su2double DeformationFactor = 1.0, DeformationDifference = 1.0; - for (ConvexityCheckIter = 1; ConvexityCheckIter <= ConvexityCheck_MaxIter; ConvexityCheckIter++) { - - /*--- Recursively change deformation magnitude: - decrease if there are nonconvex elements, increase otherwise ---*/ - DeformationDifference /= 2.0; - - if (geometry_container[iZone][INST_0][MESH_0]->GetnNonconvexElements() > 0) { - DeformationFactor -= DeformationDifference; - } else { - RecursionDepth += 1; - - if (RecursionDepth == ConvexityCheck_MaxDepth) { - if (rank == MASTER_NODE) { - cout << "Maximum recursion depth reached." << endl; - cout << "Remaining amount of original deformation: "; - cout << DeformationFactor*100.0 << " percent. " << endl; - } - break; - } - - DeformationFactor += DeformationDifference; - } - - /*--- Load mesh to start every iteration with an undeformed grid ---*/ - for (auto iPoint = 0ul; iPoint < OriginalCoordinates.rows(); iPoint++) { - for (auto iDim = 0ul; iDim < OriginalCoordinates.cols(); iDim++) { - geometry_container[iZone][INST_0][MESH_0]->nodes->SetCoord(iPoint, iDim, OriginalCoordinates(iPoint,iDim)); - } - } - - /*--- Set deformation magnitude as percentage of initial deformation ---*/ - for (auto iDV = 0u; iDV < driver_config->GetnDV(); iDV++) { - for (auto iDV_Value = 0u; iDV_Value < driver_config->GetnDV_Value(iDV); iDV_Value++) { - config_container[iZone]->SetDV_Value(iDV, iDV_Value, InitialDeformation[iDV][iDV_Value]*DeformationFactor); - } - } - - /*--- Surface grid deformation ---*/ - if (rank == MASTER_NODE) cout << "Performing the deformation of the surface grid." << endl; - - TotalDeformation = surface_movement[iZone]->SetSurface_Deformation(geometry_container[iZone][INST_0][MESH_0], config_container[iZone]); - - if (rank == MASTER_NODE) - cout << endl << "------------------- Volumetric grid deformation (ZONE " << iZone <<") ----------------" << endl; - - if (rank == MASTER_NODE) - cout << "Performing the deformation of the volumetric grid." << endl; - grid_movement[iZone][INST_0]->SetVolume_Deformation(geometry_container[iZone][INST_0][MESH_0], config_container[iZone], false); - - if (rank == MASTER_NODE) { - cout << "Number of nonconvex elements for iteration " << ConvexityCheckIter << ": "; - cout << geometry_container[iZone][INST_0][MESH_0]->GetnNonconvexElements() << endl; - cout << "Remaining amount of original deformation: "; - cout << DeformationFactor*100.0 << " percent. " << endl; - } - - } - - } - + for (iZone = 0; iZone < nZone; iZone++) { + if (config_container[iZone]->GetDesign_Variable(0) != NO_DEFORMATION) { + unsigned short nInst_Zone = nInst[iZone]; + + /*--- Definition of the Class for grid movement. ---*/ + + grid_movement[iZone] = new CVolumetricMovement*[nInst_Zone](); + grid_movement[iZone][INST_0] = new CVolumetricMovement(geometry_container[iZone][INST_0][MESH_0], config_container[iZone]); + + /*--- Save original coordinates to be reused in convexity checking procedure. ---*/ + + auto OriginalCoordinates = geometry_container[iZone][INST_0][MESH_0]->nodes->GetCoord(); + + /*--- First check for volumetric grid deformation/transformations. ---*/ + + if (config_container[iZone]->GetDesign_Variable(0) == SCALE_GRID) { + if (rank == MASTER_NODE) + cout << endl << "--------------------- Volumetric grid scaling (ZONE " << iZone << ") ------------------" << endl; + grid_movement[iZone][INST_0]->SetVolume_Scaling(geometry_container[iZone][INST_0][MESH_0], config_container[iZone], false); + + } else if (config_container[iZone]->GetDesign_Variable(0) == TRANSLATE_GRID) { + if (rank == MASTER_NODE) + cout << endl << "------------------- Volumetric grid translation (ZONE " << iZone << ") ----------------" << endl; + grid_movement[iZone][INST_0]->SetVolume_Translation(geometry_container[iZone][INST_0][MESH_0], config_container[iZone], false); + + } else if (config_container[iZone]->GetDesign_Variable(0) == ROTATE_GRID) { + if (rank == MASTER_NODE) + cout << endl << "--------------------- Volumetric grid rotation (ZONE " << iZone << ") -----------------" << endl; + grid_movement[iZone][INST_0]->SetVolume_Rotation(geometry_container[iZone][INST_0][MESH_0], config_container[iZone], false); + + } else { + /*--- If no volume-type deformations are requested, then this is a + * surface-based deformation or FFD set up. ---*/ + + if (rank == MASTER_NODE) + cout << endl << "--------------------- Surface grid deformation (ZONE " << iZone << ") -----------------" << endl; + + /*--- Definition and initialization of the surface deformation class. ---*/ + + surface_movement[iZone] = new CSurfaceMovement(); + haveSurfaceDeformation = true; + + /*--- Copy coordinates to the surface structure. ---*/ + + surface_movement[iZone]->CopyBoundary(geometry_container[iZone][INST_0][MESH_0], config_container[iZone]); + + /*--- Surface grid deformation. ---*/ + + if (rank == MASTER_NODE) cout << "Performing the deformation of the surface grid." << endl; + auto TotalDeformation = surface_movement[iZone]->SetSurface_Deformation(geometry_container[iZone][INST_0][MESH_0], config_container[iZone]); + + if (config_container[iZone]->GetDesign_Variable(0) != FFD_SETTING) { + if (rank == MASTER_NODE) + cout << endl << "------------------- Volumetric grid deformation (ZONE " << iZone << ") ----------------" << endl; + + if (rank == MASTER_NODE) cout << "Performing the deformation of the volumetric grid." << endl; + grid_movement[iZone][INST_0]->SetVolume_Deformation(geometry_container[iZone][INST_0][MESH_0],config_container[iZone], false); + + /*--- Get parameters for convexity check. ---*/ + bool ConvexityCheck; + unsigned short ConvexityCheck_MaxIter, ConvexityCheck_MaxDepth; + + tie(ConvexityCheck, ConvexityCheck_MaxIter, ConvexityCheck_MaxDepth) = config_container[iZone]->GetConvexityCheck(); + + /*--- Recursively change deformations if there are non-convex elements. ---*/ + + if (ConvexityCheck && geometry_container[iZone][INST_0][MESH_0]->GetnNonconvexElements() > 0) { + if (rank == MASTER_NODE) { + cout << "Non-convex elements present after deformation." << endl; + cout << "Recursively lowering deformation magnitude." << endl; + } + + /*--- Load initial deformation values. ---*/ + + auto InitialDeformation = TotalDeformation; + + unsigned short ConvexityCheckIter, RecursionDepth = 0; + su2double DeformationFactor = 1.0, DeformationDifference = 1.0; + for (ConvexityCheckIter = 1; ConvexityCheckIter <= ConvexityCheck_MaxIter; ConvexityCheckIter++) { + /*--- Recursively change deformation magnitude (decrease for non-convex elements, increase otherwise). ---*/ + + DeformationDifference /= 2.0; + + if (geometry_container[iZone][INST_0][MESH_0]->GetnNonconvexElements() > 0) { + DeformationFactor -= DeformationDifference; + } else { + RecursionDepth += 1; + + if (RecursionDepth == ConvexityCheck_MaxDepth) { + if (rank == MASTER_NODE) { + cout << "Maximum recursion depth reached." << endl; + cout << "Remaining amount of original deformation: "; + cout << DeformationFactor * 100.0 << " percent. " << endl; + } + break; + } + + DeformationFactor += DeformationDifference; + } + + /*--- Load mesh to start every iteration with an undeformed grid. ---*/ + + for (auto iPoint = 0ul; iPoint < OriginalCoordinates.rows(); iPoint++) { + for (auto iDim = 0ul; iDim < OriginalCoordinates.cols(); iDim++) { + geometry_container[iZone][INST_0][MESH_0]->nodes->SetCoord(iPoint, iDim, OriginalCoordinates(iPoint, iDim)); } - + } + + /*--- Set deformation magnitude as percentage of initial deformation. ---*/ + + for (auto iDV = 0u; iDV < driver_config->GetnDV(); iDV++) { + for (auto iDV_Value = 0u; iDV_Value < driver_config->GetnDV_Value(iDV); iDV_Value++) { + config_container[iZone]->SetDV_Value(iDV, iDV_Value,InitialDeformation[iDV][iDV_Value] * DeformationFactor); + } + } + + /*--- Surface grid deformation. ---*/ + + if (rank == MASTER_NODE) cout << "Performing the deformation of the surface grid." << endl; + + TotalDeformation = surface_movement[iZone]->SetSurface_Deformation(geometry_container[iZone][INST_0][MESH_0], config_container[iZone]); + + if (rank == MASTER_NODE) + cout << endl << "------------------- Volumetric grid deformation (ZONE " << iZone << ") ----------------" << endl; + + if (rank == MASTER_NODE) cout << "Performing the deformation of the volumetric grid." << endl; + grid_movement[iZone][INST_0]->SetVolume_Deformation(geometry_container[iZone][INST_0][MESH_0], config_container[iZone], false); + + if (rank == MASTER_NODE) { + cout << "Number of non-convex elements for iteration " << ConvexityCheckIter << ": "; + cout << geometry_container[iZone][INST_0][MESH_0]->GetnNonconvexElements() << endl; + cout << "Remaining amount of original deformation: "; + cout << DeformationFactor * 100.0 << " percent. " << endl; + } } - + } } - + } } - + } } void CDeformationDriver::Output() { - - /*--- Output deformed grid for visualization, if requested (surface and volumetric), in parallel - requires to move all the data to the master node---*/ - - if (rank == MASTER_NODE) cout << endl << "----------------------- Write deformed grid files -----------------------" << endl; - - for (iZone = 0; iZone < nZone; iZone++){ - - /*--- Compute Mesh Quality if requested. Necessary geometry preprocessing re-done beforehand. ---*/ - - if (config_container[iZone]->GetWrt_MeshQuality() && !driver_config->GetStructuralProblem()) { - - if (rank == MASTER_NODE) cout << "Recompute geometry properties necessary to evaluate mesh quality statistics.\n"; - - geometry_container[iZone][INST_0][MESH_0]->SetPoint_Connectivity(); - geometry_container[iZone][INST_0][MESH_0]->SetBoundVolume(); - geometry_container[iZone][INST_0][MESH_0]->SetEdges(); - geometry_container[iZone][INST_0][MESH_0]->SetVertex(config_container[iZone]); - geometry_container[iZone][INST_0][MESH_0]->SetControlVolume(config_container[iZone], ALLOCATE); - geometry_container[iZone][INST_0][MESH_0]->SetBoundControlVolume(config_container[iZone], ALLOCATE); - - if (rank == MASTER_NODE) cout << "Computing mesh quality statistics for the dual control volumes.\n"; - geometry_container[iZone][INST_0][MESH_0]->ComputeMeshQualityStatistics(config_container[iZone]); - }// Mesh Quality Output - - /*--- Load the data --- */ - - output_container[iZone]->Load_Data(geometry_container[iZone][INST_0][MESH_0], config_container[iZone], nullptr); - - output_container[iZone]->WriteToFile(config_container[iZone], geometry_container[iZone][INST_0][MESH_0], OUTPUT_TYPE::MESH, driver_config->GetMesh_Out_FileName()); - - /*--- Set the file names for the visualization files ---*/ - - output_container[iZone]->SetVolume_Filename("volume_deformed"); - output_container[iZone]->SetSurface_Filename("surface_deformed"); - - for (unsigned short iFile = 0; iFile < config_container[iZone]->GetnVolumeOutputFiles(); iFile++){ - auto FileFormat = config_container[iZone]->GetVolumeOutputFiles(); - if (FileFormat[iFile] != OUTPUT_TYPE::RESTART_ASCII && - FileFormat[iFile] != OUTPUT_TYPE::RESTART_BINARY && - FileFormat[iFile] != OUTPUT_TYPE::CSV) - output_container[iZone]->WriteToFile(config_container[iZone], geometry_container[iZone][INST_0][MESH_0], FileFormat[iFile]); - } + /*--- Output deformed grid for visualization, if requested (surface and volumetric), in parallel + requires to move all the data to the master node. ---*/ + + if (rank == MASTER_NODE) + cout << endl << "----------------------- Write deformed grid files -----------------------" << endl; + + for (iZone = 0; iZone < nZone; iZone++) { + /*--- Compute Mesh Quality if requested. Necessary geometry preprocessing re-done beforehand. ---*/ + + if (config_container[iZone]->GetWrt_MeshQuality() && !driver_config->GetStructuralProblem()) { + if (rank == MASTER_NODE) cout << "Recompute geometry properties necessary to evaluate mesh quality statistics.\n"; + + geometry_container[iZone][INST_0][MESH_0]->SetPoint_Connectivity(); + geometry_container[iZone][INST_0][MESH_0]->SetBoundVolume(); + geometry_container[iZone][INST_0][MESH_0]->SetEdges(); + geometry_container[iZone][INST_0][MESH_0]->SetVertex(config_container[iZone]); + geometry_container[iZone][INST_0][MESH_0]->SetControlVolume(config_container[iZone], ALLOCATE); + geometry_container[iZone][INST_0][MESH_0]->SetBoundControlVolume(config_container[iZone], ALLOCATE); + + if (rank == MASTER_NODE) cout << "Computing mesh quality statistics for the dual control volumes.\n"; + geometry_container[iZone][INST_0][MESH_0]->ComputeMeshQualityStatistics(config_container[iZone]); } - - if (!driver_config->GetDeform_Mesh()) { - if ((config_container[ZONE_0]->GetDesign_Variable(0) != NO_DEFORMATION) && - (config_container[ZONE_0]->GetDesign_Variable(0) != SCALE_GRID) && - (config_container[ZONE_0]->GetDesign_Variable(0) != TRANSLATE_GRID) && - (config_container[ZONE_0]->GetDesign_Variable(0) != ROTATE_GRID)) { - - /*--- Write the the free-form deformation boxes after deformation (if defined). ---*/ - if (!haveSurfaceDeformation) { - if (rank == MASTER_NODE) cout << "No FFD information available." << endl; - } - else { - if (rank == MASTER_NODE) cout << "Adding any FFD information to the SU2 file." << endl; - - surface_movement[ZONE_0]->WriteFFDInfo(surface_movement, geometry_container, config_container); - } - } + + /*--- Load the data. --- */ + + output_container[iZone]->Load_Data(geometry_container[iZone][INST_0][MESH_0], config_container[iZone], nullptr); + + output_container[iZone]->WriteToFile(config_container[iZone], geometry_container[iZone][INST_0][MESH_0],OUTPUT_TYPE::MESH, driver_config->GetMesh_Out_FileName()); + + /*--- Set the file names for the visualization files. ---*/ + + output_container[iZone]->SetVolume_Filename("volume_deformed"); + output_container[iZone]->SetSurface_Filename("surface_deformed"); + + for (unsigned short iFile = 0; iFile < config_container[iZone]->GetnVolumeOutputFiles(); iFile++) { + auto FileFormat = config_container[iZone]->GetVolumeOutputFiles(); + if (FileFormat[iFile] != OUTPUT_TYPE::RESTART_ASCII && FileFormat[iFile] != OUTPUT_TYPE::RESTART_BINARY && + FileFormat[iFile] != OUTPUT_TYPE::CSV) + output_container[iZone]->WriteToFile(config_container[iZone], geometry_container[iZone][INST_0][MESH_0],FileFormat[iFile]); + } + } + + if (!driver_config->GetDeform_Mesh()) { + if ((config_container[ZONE_0]->GetDesign_Variable(0) != NO_DEFORMATION) && + (config_container[ZONE_0]->GetDesign_Variable(0) != SCALE_GRID) && + (config_container[ZONE_0]->GetDesign_Variable(0) != TRANSLATE_GRID) && + (config_container[ZONE_0]->GetDesign_Variable(0) != ROTATE_GRID)) { + + /*--- Write the free form deformation boxes after deformation if defined. ---*/ + if (!haveSurfaceDeformation) { + if (rank == MASTER_NODE) cout << "No FFD information available." << endl; + } else { + if (rank == MASTER_NODE) cout << "Adding any FFD information to the SU2 file." << endl; + + surface_movement[ZONE_0]->WriteFFDInfo(surface_movement, geometry_container, config_container); + } } + } } void CDeformationDriver::Postprocessing() { - - if (rank == MASTER_NODE) - cout << endl <<"------------------------- Solver Postprocessing -------------------------" << endl; - - delete driver_config; - driver_config = nullptr; - - for (iZone = 0; iZone < nZone; iZone++) { - if (numerics_container[iZone] != nullptr) { - for (unsigned int iTerm = 0; iTerm < MAX_TERMS*omp_get_max_threads(); iTerm++) { - delete numerics_container[iZone][INST_0][MESH_0][MESH_SOL][iTerm]; - delete [] numerics_container[iZone][INST_0][MESH_0][MESH_SOL]; - delete [] numerics_container[iZone][INST_0][MESH_0]; - delete [] numerics_container[iZone][INST_0]; - } - delete [] numerics_container[iZone]; - } - } - delete [] numerics_container; - if (rank == MASTER_NODE) cout << "Deleted CNumerics container." << endl; - - for (iZone = 0; iZone < nZone; iZone++) { - if (solver_container[iZone] != nullptr) { - delete solver_container[iZone][INST_0][MESH_0][MESH_SOL]; - delete [] solver_container[iZone][INST_0][MESH_0]; - delete [] solver_container[iZone][INST_0]; - delete [] solver_container[iZone]; - } + if (rank == MASTER_NODE) + cout << endl << "------------------------- Solver Postprocessing -------------------------" << endl; + + if (driver_config != nullptr) delete[] driver_config; + + for (iZone = 0; iZone < nZone; iZone++) { + if (numerics_container[iZone] != nullptr) { + for (unsigned int iTerm = 0; iTerm < MAX_TERMS * omp_get_max_threads(); iTerm++) { + delete numerics_container[iZone][INST_0][MESH_0][MESH_SOL][iTerm]; + delete[] numerics_container[iZone][INST_0][MESH_0][MESH_SOL]; + delete[] numerics_container[iZone][INST_0][MESH_0]; + delete[] numerics_container[iZone][INST_0]; + } + delete[] numerics_container[iZone]; } - delete [] solver_container; - if (rank == MASTER_NODE) cout << "Deleted CSolver container." << endl; - - if (geometry_container != nullptr) { - for (iZone = 0; iZone < nZone; iZone++) { - delete geometry_container[iZone][INST_0][MESH_0]; - delete [] geometry_container[iZone][INST_0]; - delete [] geometry_container[iZone]; - } - delete [] geometry_container; + } + delete[] numerics_container; + if (rank == MASTER_NODE) cout << "Deleted CNumerics container." << endl; + + for (iZone = 0; iZone < nZone; iZone++) { + if (solver_container[iZone] != nullptr) { + delete solver_container[iZone][INST_0][MESH_0][MESH_SOL]; + delete[] solver_container[iZone][INST_0][MESH_0]; + delete[] solver_container[iZone][INST_0]; + delete[] solver_container[iZone]; } - if (rank == MASTER_NODE) cout << "Deleted CGeometry container." << endl; - + } + delete[] solver_container; + if (rank == MASTER_NODE) cout << "Deleted CSolver container." << endl; + + if (geometry_container != nullptr) { for (iZone = 0; iZone < nZone; iZone++) { - delete [] FFDBox[iZone]; + delete geometry_container[iZone][INST_0][MESH_0]; + delete[] geometry_container[iZone][INST_0]; + delete[] geometry_container[iZone]; } - delete [] FFDBox; - if (rank == MASTER_NODE) cout << "Deleted CFreeFormDefBox class." << endl; - - if (surface_movement != nullptr) { - for (iZone = 0; iZone < nZone; iZone++) { - delete surface_movement[iZone]; - } - delete [] surface_movement; + delete[] geometry_container; + } + if (rank == MASTER_NODE) cout << "Deleted CGeometry container." << endl; + + for (iZone = 0; iZone < nZone; iZone++) { + delete[] FFDBox[iZone]; + } + delete[] FFDBox; + if (rank == MASTER_NODE) cout << "Deleted CFreeFormDefBox class." << endl; + + if (surface_movement != nullptr) { + for (iZone = 0; iZone < nZone; iZone++) { + delete surface_movement[iZone]; } - if (rank == MASTER_NODE) cout << "Deleted CSurfaceMovement class." << endl; - - if (grid_movement != nullptr) { - for (iZone = 0; iZone < nZone; iZone++) { - delete grid_movement[iZone][INST_0]; - delete [] grid_movement[iZone]; - } - delete [] grid_movement; + delete[] surface_movement; + } + if (rank == MASTER_NODE) cout << "Deleted CSurfaceMovement class." << endl; + + if (grid_movement != nullptr) { + for (iZone = 0; iZone < nZone; iZone++) { + delete grid_movement[iZone][INST_0]; + delete[] grid_movement[iZone]; } - if (rank == MASTER_NODE) cout << "Deleted CVolumetricMovement class." << endl; - - if (config_container != nullptr) { - for (iZone = 0; iZone < nZone; iZone++) { - delete config_container[iZone]; - } - delete [] config_container; + delete[] grid_movement; + } + if (rank == MASTER_NODE) cout << "Deleted CVolumetricMovement class." << endl; + + if (config_container != nullptr) { + for (iZone = 0; iZone < nZone; iZone++) { + delete config_container[iZone]; } - if (rank == MASTER_NODE) cout << "Deleted CConfig container." << endl; - - if (output_container != nullptr) { - for (iZone = 0; iZone < nZone; iZone++) { - delete output_container[iZone]; - } - delete [] output_container; + delete[] config_container; + } + if (rank == MASTER_NODE) cout << "Deleted CConfig container." << endl; + + if (output_container != nullptr) { + for (iZone = 0; iZone < nZone; iZone++) { + delete output_container[iZone]; } - if (rank == MASTER_NODE) cout << "Deleted COutput class." << endl; - - if (nInst != nullptr) delete [] nInst; - - /*--- Exit the solver cleanly ---*/ - - if (rank == MASTER_NODE) - cout << endl << "------------------------- Exit Success (SU2_DEF) ------------------------" << endl << endl; + delete[] output_container; + } + if (rank == MASTER_NODE) cout << "Deleted COutput class." << endl; + + if (nInst != nullptr) delete[] nInst; + + /*--- Exit the solver cleanly. ---*/ + + if (rank == MASTER_NODE) + cout << endl << "------------------------- Exit Success (SU2_DEF) ------------------------" << endl << endl; } void CDeformationDriver::CommunicateMeshDisplacements(void) { - - solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->InitiateComms(geometry_container[ZONE_0][INST_0][MESH_0], config_container[ZONE_0], MESH_DISPLACEMENTS); - solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->CompleteComms(geometry_container[ZONE_0][INST_0][MESH_0], config_container[ZONE_0], MESH_DISPLACEMENTS); - + solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->InitiateComms(geometry_container[ZONE_0][INST_0][MESH_0],config_container[ZONE_0], MESH_DISPLACEMENTS); + solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->CompleteComms(geometry_container[ZONE_0][INST_0][MESH_0],config_container[ZONE_0], MESH_DISPLACEMENTS); } From 44c24a53f5b1f7ed6d4267199ae7cd12fc9fc7a9 Mon Sep 17 00:00:00 2001 From: patelha57 Date: Thu, 8 Dec 2022 20:19:31 -0800 Subject: [PATCH 30/68] Update CDiscAdjDeformationDriver --- .../drivers/CDiscAdjDeformationDriver.hpp | 218 +- .../src/drivers/CDiscAdjDeformationDriver.cpp | 1898 +++++++++-------- 2 files changed, 1057 insertions(+), 1059 deletions(-) diff --git a/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp b/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp index 176f89b93f9..d7857dbf5dc 100644 --- a/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp +++ b/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp @@ -1,7 +1,7 @@ /*! * \file CDiscAdjDeformationDriver.cpp * \brief Headers of the main subroutines for driving the projection of sensitivities. - * \author T. Economon, H. Kline, R. Sanchez + * \author T. Economon, H. Kline, R. Sanchez, A. Gastaldi, H. Patel * \version 7.3.0 "Blackbird" * * SU2 Project Website: https://su2code.github.io @@ -31,128 +31,118 @@ #include "../../../Common/include/CConfig.hpp" #undef ENABLE_MAPS -#include "../../../Common/include/parallelization/mpi_structure.hpp" -#include "../../../Common/include/geometry/CGeometry.hpp" +#include "../../../Common/include/drivers/CDriverBase.hpp" #include "../../../Common/include/fem/fem_geometry_structure.hpp" +#include "../../../Common/include/geometry/CGeometry.hpp" #include "../../../Common/include/grid_movement/CSurfaceMovement.hpp" #include "../../../Common/include/grid_movement/CVolumetricMovement.hpp" -#include "../../../SU2_CFD/include/output/COutput.hpp" +#include "../../../Common/include/parallelization/mpi_structure.hpp" +#include "../../../SU2_CFD/include/numerics/CGradSmoothing.hpp" #include "../../../SU2_CFD/include/output/CBaselineOutput.hpp" +#include "../../../SU2_CFD/include/output/COutput.hpp" #include "../../../SU2_CFD/include/solvers/CBaselineSolver.hpp" - -#include "../../../Common/include/drivers/CDriverBase.hpp" #include "../../../SU2_CFD/include/solvers/CGradientSmoothingSolver.hpp" -#include "../../../SU2_CFD/include/numerics/CGradSmoothing.hpp" -/*! - * \class CDiscAdjDeformationDriver - * \brief Class for driving sensitivity projections. - * \author A. Gastaldi, H. Patel - * \version 7.3.0 "Blackbird" - */ class CDiscAdjDeformationDriver : public CDriverBase { - protected: - su2double** Gradient; - ofstream Gradient_file; - + su2double** Gradient; + ofstream Gradient_file; + public: - /*! - * \brief Constructor of the class. - * \param[in] confFile - Configuration file name. - * \param[in] MPICommunicator - MPI communicator for SU2. - */ - CDiscAdjDeformationDriver(char* confFile, SU2_Comm MPICommunicator); - - /*! - * \brief Destructor of the class. - */ - ~CDiscAdjDeformationDriver(void); - - /*! - * \brief [Overload] Launch the computation for single-zone problems. - */ - void Run(); - - /*! - * \brief Deallocation routine - */ - void Postprocessing(); - + /*! + * \brief Constructor of the class. + * \param[in] confFile - Configuration file name. + * \param[in] MPICommunicator - MPI communicator for SU2. + */ + CDiscAdjDeformationDriver(char* confFile, SU2_Comm MPICommunicator); + + /*! + * \brief Destructor of the class. + */ + ~CDiscAdjDeformationDriver(void); + + /*! + * \brief Preprocess the driver data (includes solution allocation and initialization). + */ + void Preprocess(); + + /*! + * \brief Launch the driver computation. + */ + void Run(); + + /*! + * \brief Deallocation routine. + */ + void Postprocessing(); + protected: - - /*! - * \brief Read in the config and mesh files. - */ - void Input_Preprocessing(); - - /*! - * \brief Construction of the edge-based data structure. - */ - void Geometrical_Preprocessing(); - - /*! - * \brief Preprocess the output container. - */ - void Output_Preprocessing(); - - /*! - * \brief Projection of the surface sensitivity using finite differences (FD). - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] surface_movement - Surface movement class of the problem. - * \param[in] Gradient_file - Output file to store the gradient data. - */ - - void SetProjection_FD(CGeometry *geometry, CConfig *config, CSurfaceMovement *surface_movement, su2double **Gradient); - - /*! - * \brief Projection of the surface sensitivity using algorithmic differentiation (AD). - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] surface_movement - Surface movement class of the problem. - * \param[in] Gradient_file - Output file to store the gradient data. - */ - - void SetProjection_AD(CGeometry *geometry, CConfig *config, CSurfaceMovement *surface_movement, su2double **Gradient); - - /*! - * \brief Prints the gradient information to a file. - * \param[in] Gradient - The gradient data. - * \param[in] config - Definition of the particular problem. - * \param[in] Gradient_file - Output file to store the gradient data. - */ - - void OutputGradient(su2double** Gradient, CConfig* config, ofstream& Gradient_file); - - /*! - * \brief Write the sensitivity (including mesh sensitivity) computed with the discrete adjoint method - * on the surface and in the volume to a file. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] val_nZone - Number of Zones. - */ - - void SetSensitivity_Files(CGeometry ****geometry, CConfig **config, unsigned short val_nZone); - - /*! - * \brief Treatment of derivatives with the Sobolev smoothing solver. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] grid_movement - Volumetric movement class of the problem. - */ - - void DerivativeTreatment_MeshSensitivity(CGeometry *geometry, CConfig *config, CVolumetricMovement *grid_movement); - - /*! - * \brief Treatment of derivatives with the Sobolev smoothing solver. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] grid_movement - Volumetric movement class of the problem. - * \param[in] surface_movement - Surface movement class of the problem. - * \param[in] Gradient - Output array to store the gradient data. - */ - - void DerivativeTreatment_Gradient(CGeometry *geometry, CConfig *config, CVolumetricMovement *grid_movement, CSurfaceMovement *surface_movement, su2double **Gradient); - + /*! + * \brief Read in the config and mesh files. + */ + void Input_Preprocessing(); + + /*! + * \brief Construction of the edge-based data structure. + */ + void Geometrical_Preprocessing(); + + /*! + * \brief Preprocess the output container. + */ + void Output_Preprocessing(); + + /*! + * \brief Projection of the surface sensitivity using finite differences (FD). + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] surface_movement - Surface movement class of the problem. + * \param[in] Gradient_file - Output file to store the gradient data. + */ + void SetProjection_FD(CGeometry* geometry, CConfig* config, CSurfaceMovement* surface_movement, su2double** Gradient); + + /*! + * \brief Projection of the surface sensitivity using algorithmic differentiation (AD). + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] surface_movement - Surface movement class of the problem. + * \param[in] Gradient_file - Output file to store the gradient data. + */ + void SetProjection_AD(CGeometry* geometry, CConfig* config, CSurfaceMovement* surface_movement, su2double** Gradient); + + /*! + * \brief Prints the gradient information to a file. + * \param[in] Gradient - The gradient data. + * \param[in] config - Definition of the particular problem. + * \param[in] Gradient_file - Output file to store the gradient data. + */ + void OutputGradient(su2double** Gradient, CConfig* config, ofstream& Gradient_file); + + /*! + * \brief Write the sensitivity (including mesh sensitivity) computed with the discrete adjoint method + * on the surface and in the volume to a file. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] val_nZone - Number of Zones. + */ + void SetSensitivity_Files(CGeometry**** geometry, CConfig** config, unsigned short val_nZone); + + /*! + * \brief Treatment of derivatives with the Sobolev smoothing solver. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] grid_movement - Volumetric movement class of the problem. + */ + void DerivativeTreatment_MeshSensitivity(CGeometry* geometry, CConfig* config, CVolumetricMovement* grid_movement); + + /*! + * \brief Treatment of derivatives with the Sobolev smoothing solver. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] grid_movement - Volumetric movement class of the problem. + * \param[in] surface_movement - Surface movement class of the problem. + * \param[in] Gradient - Output array to store the gradient data. + */ + void DerivativeTreatment_Gradient(CGeometry* geometry, CConfig* config, CVolumetricMovement* grid_movement, + CSurfaceMovement* surface_movement, su2double** Gradient); }; diff --git a/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp b/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp index 94768b3c0e4..5390c366322 100644 --- a/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp +++ b/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp @@ -31,1027 +31,1035 @@ using namespace std; -CDiscAdjDeformationDriver::CDiscAdjDeformationDriver(char* confFile, SU2_Comm MPICommunicator): -CDriverBase(confFile, 1, MPICommunicator) -{ - /*--- Initialize Medipack (must also be here so it is initialized from python) ---*/ +CDiscAdjDeformationDriver::CDiscAdjDeformationDriver(char* confFile, SU2_Comm MPICommunicator) + : CDriverBase(confFile, 1, MPICommunicator) { + +/*--- Initialize MeDiPack (must also be here to initialize it from Python). ---*/ #ifdef HAVE_MPI #if defined(CODI_REVERSE_TYPE) || defined(CODI_FORWARD_TYPE) - SU2_MPI::Init_AMPI(); + SU2_MPI::Init_AMPI(); #endif #endif - - SU2_MPI::SetComm(MPICommunicator); - - rank = SU2_MPI::GetRank(); - size = SU2_MPI::GetSize(); - - /*--- Initialize containers --- */ - - SetContainers_Null(); - - /*--- Preprocessing of the config files. ---*/ - - Input_Preprocessing(); - - /*--- Set up a timer for performance benchmarking ---*/ - - StartTime = SU2_MPI::Wtime(); - - /*--- Preprocessing of the geometry for all zones. ---*/ - - Geometrical_Preprocessing(); - - /*--- Preprocessing of the outputs for all zones. ---*/ - - Output_Preprocessing(); - - /*--- Preprocessing time is reported now, but not included in the next compute portion. ---*/ - - StopTime = SU2_MPI::Wtime(); - - /*--- Compute/print the total time for performance benchmarking. ---*/ - - UsedTime = StopTime-StartTime; - UsedTimePreproc = UsedTime; - UsedTimeCompute = 0.0; - -} -CDiscAdjDeformationDriver::~CDiscAdjDeformationDriver(void) { - + SU2_MPI::SetComm(MPICommunicator); + + rank = SU2_MPI::GetRank(); + size = SU2_MPI::GetSize(); + + /*--- Initialize containers. --- */ + + SetContainers_Null(); + + /*--- Preprocessing of the config files. ---*/ + + Input_Preprocessing(); + + /*--- Initialize structure to store the gradient. ---*/ + + unsigned short nDV = config_container[ZONE_0]->GetnDV(); + Gradient = new su2double*[nDV]; + + for (auto iDV = 0u; iDV < nDV; iDV++) { + /*--- Initialize to zero ---*/ + unsigned short nValue = config_container[ZONE_0]->GetnDV_Value(iDV); + + Gradient[iDV] = new su2double[nValue]; + } + + /*--- Set up a timer for performance benchmarking. ---*/ + + StartTime = SU2_MPI::Wtime(); + + /*--- Preprocessing of the geometry for all zones. ---*/ + + Geometrical_Preprocessing(); + + /*--- Preprocessing of the outputs for all zones. ---*/ + + Output_Preprocessing(); + + /*--- Preprocessing time is reported now, but not included in the next compute portion. ---*/ + + StopTime = SU2_MPI::Wtime(); + + /*--- Compute the total time for performance benchmarking. ---*/ + + UsedTime = StopTime - StartTime; + UsedTimePreproc = UsedTime; + UsedTimeCompute = 0.0; } +CDiscAdjDeformationDriver::~CDiscAdjDeformationDriver(void) {} + void CDiscAdjDeformationDriver::Input_Preprocessing() { - - /*--- Initialize a char to store the zone filename ---*/ - char zone_file_name[MAX_STRING_SIZE]; - - /*--- Initialize the configuration of the driver ---*/ - driver_config = new CConfig(config_file_name, SU2_COMPONENT::SU2_DEF); - - nZone = driver_config->GetnZone(); - - /*--- 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. ---*/ - - if (driver_config->GetnConfigFiles() > 0){ - strcpy(zone_file_name, driver_config->GetConfigFilename(iZone).c_str()); - config_container[iZone] = new CConfig(driver_config, zone_file_name, SU2_COMPONENT::SU2_DOT, iZone, nZone, true); - } else { - config_container[iZone] = new CConfig(driver_config, config_file_name, SU2_COMPONENT::SU2_DOT, iZone, nZone, true); - } - - config_container[iZone]->SetMPICommunicator(SU2_MPI::GetComm()); - - if (!config_container[iZone]->GetDiscrete_Adjoint()) { - SU2_MPI::Error("The discrete adjoint solver was not specified in the configuration file.", CURRENT_FUNCTION); - } - + /*--- Initialize a char to store the zone filename. ---*/ + + char zone_file_name[MAX_STRING_SIZE]; + + /*--- Initialize the configuration of the driver. ---*/ + + driver_config = new CConfig(config_file_name, SU2_COMPONENT::SU2_DEF); + + nZone = driver_config->GetnZone(); + + /*--- 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. ---*/ + + if (driver_config->GetnConfigFiles() > 0) { + strcpy(zone_file_name, driver_config->GetConfigFilename(iZone).c_str()); + config_container[iZone] = new CConfig(driver_config, zone_file_name, SU2_COMPONENT::SU2_DOT, iZone, nZone, true); + } else { + config_container[iZone] = new CConfig(driver_config, config_file_name, SU2_COMPONENT::SU2_DOT, iZone, nZone, true); } - - /*--- Set the multizone part of the problem. ---*/ - if (driver_config->GetMultizone_Problem()){ - for (iZone = 0; iZone < nZone; iZone++) { - /*--- Set the interface markers for multizone ---*/ - config_container[iZone]->SetMultizone(driver_config, config_container); - } + + config_container[iZone]->SetMPICommunicator(SU2_MPI::GetComm()); + + if (!config_container[iZone]->GetDiscrete_Adjoint()) { + SU2_MPI::Error("The discrete adjoint solver was not specified in the configuration file.", CURRENT_FUNCTION); + } + } + + /*--- Set the multi-zone part of the problem. ---*/ + + if (driver_config->GetMultizone_Problem()) { + for (iZone = 0; iZone < nZone; iZone++) { + /*--- Set the interface markers for multi-zone. ---*/ + + config_container[iZone]->SetMultizone(driver_config, config_container); } + } - /*--- Keep a reference to the main (ZONE 0) config ---*/ - main_config = config_container[ZONE_0]; + /*--- Keep a reference to the main (ZONE 0) config. ---*/ + + main_config = config_container[ZONE_0]; } void CDiscAdjDeformationDriver::Geometrical_Preprocessing() { - - /*--- 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. ---*/ - unsigned short nMesh = 1; - - for (iZone = 0; iZone < nZone; iZone++) { - - /*--- Determine whether or not the FEM solver is used, which decides the - type of geometry classes that are instantiated. ---*/ - const bool fem_solver = config_container[iZone]->GetFEMSolver(); - - /*--- Read the number of instances for each zone ---*/ - - nInst[iZone] = config_container[iZone]->GetnTimeInstances(); - - geometry_container[iZone] = new CGeometry**[nInst[iZone]]; - - for (iInst = 0; iInst < nInst[iZone]; iInst++){ - - /*--- Definition of the geometry class to store the primal grid in the partitioning process. ---*/ - - CGeometry *geometry_aux = nullptr; - - /*--- 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) ---*/ - - if ( fem_solver ) geometry_aux->SetColorFEMGrid_Parallel(config_container[iZone]); - else geometry_aux->SetColorGrid_Parallel(config_container[iZone]); - - /*--- Build the grid data structures using the ParMETIS coloring. ---*/ - - if( fem_solver ) { - switch( config_container[iZone]->GetKind_FEM_Flow() ) { - case DG: { - geometry_container[iZone][iInst] = new CGeometry*[nMesh]; - geometry_container[iZone][iInst][MESH_0] = new CMeshFEM_DG(geometry_aux, config_container[iZone]); - break; - } - } - } - else { - geometry_container[iZone][iInst] = new CGeometry*[nMesh]; - geometry_container[iZone][iInst][MESH_0] = new CPhysicalGeometry(geometry_aux, config_container[iZone]); - } - - /*--- Deallocate the memory of geometry_aux ---*/ - - delete geometry_aux; - - /*--- Add the Send/Receive boundaries ---*/ - - geometry_container[iZone][iInst][MESH_0]->SetSendReceive(config_container[iZone]); - - /*--- Add the Send/Receive boundaries ---*/ - - geometry_container[iZone][iInst][MESH_0]->SetBoundaries(config_container[iZone]); - - /*--- Create the vertex structure (required for MPI) ---*/ - - if (rank == MASTER_NODE) cout << "Identify vertices." << endl; - geometry_container[iZone][iInst][MESH_0]->SetVertex(config_container[iZone]); - - /*--- Store the global to local mapping after preprocessing. ---*/ - - if (rank == MASTER_NODE) cout << "Storing a mapping from global to local point index." << endl; - geometry_container[iZone][iInst][MESH_0]->SetGlobal_to_Local_Point(); - - /* Test for a fem solver, because some more work must be done. */ - - if (fem_solver) { - - /*--- Carry out a dynamic cast to CMeshFEM_DG, such that it is not needed to - define all virtual functions in the base class CGeometry. ---*/ - CMeshFEM_DG *DGMesh = dynamic_cast(geometry_container[iZone][iInst][MESH_0]); - - /*--- Determine the standard elements for the volume elements. ---*/ - if (rank == MASTER_NODE) cout << "Creating standard volume elements." << endl; - DGMesh->CreateStandardVolumeElements(config_container[iZone]); - - /*--- Create the face information needed to compute the contour integral - for the elements in the Discontinuous Galerkin formulation. ---*/ - if (rank == MASTER_NODE) cout << "Creating face information." << endl; - DGMesh->CreateFaces(config_container[iZone]); - } - } - - if (rank == MASTER_NODE) - cout << "\n----------------------- Preprocessing computations ----------------------" << endl; - - /*--- Compute elements surrounding points, points surrounding points ---*/ - - if (rank == MASTER_NODE) cout << "Setting local point connectivity." << endl; - geometry_container[iZone][INST_0][MESH_0]->SetPoint_Connectivity(); - - /*--- Check the orientation before computing geometrical quantities ---*/ - - geometry_container[iZone][INST_0][MESH_0]->SetBoundVolume(); - if (config_container[iZone]->GetReorientElements()) { - if (rank == MASTER_NODE) cout << "Checking the numerical grid orientation of the elements." << endl; - geometry_container[iZone][INST_0][MESH_0]->Check_IntElem_Orientation(config_container[iZone]); - geometry_container[iZone][INST_0][MESH_0]->Check_BoundElem_Orientation(config_container[iZone]); + /*--- 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. ---*/ + + unsigned short nMesh = 1; + + for (iZone = 0; iZone < nZone; iZone++) { + /*--- Determine if the FEM solver is used, which decides the type of geometry classes that are instantiated. ---*/ + + const bool fem_solver = config_container[iZone]->GetFEMSolver(); + + /*--- Read the number of instances for each zone. ---*/ + + nInst[iZone] = config_container[iZone]->GetnTimeInstances(); + + geometry_container[iZone] = new CGeometry**[nInst[iZone]]; + + for (iInst = 0; iInst < nInst[iZone]; iInst++) { + /*--- Definition of the geometry class to store the primal grid in the partitioning process. ---*/ + + CGeometry* geometry_aux = nullptr; + + /*--- 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). ---*/ + + if (fem_solver) { + geometry_aux->SetColorFEMGrid_Parallel(config_container[iZone]); + } else { + geometry_aux->SetColorGrid_Parallel(config_container[iZone]); + } + + /*--- Build the grid data structures using the ParMETIS coloring. ---*/ + + if (fem_solver) { + switch (config_container[iZone]->GetKind_FEM_Flow()) { + case DG: + geometry_container[iZone][iInst] = new CGeometry*[nMesh]; + geometry_container[iZone][iInst][MESH_0] = new CMeshFEM_DG(geometry_aux, config_container[iZone]); + break; } - - /*--- Create the edge structure ---*/ - - if (rank == MASTER_NODE) cout << "Identify edges and vertices." << endl; - geometry_container[iZone][INST_0][MESH_0]->SetEdges(); geometry_container[iZone][INST_0][MESH_0]->SetVertex(config_container[iZone]); - - /*--- Create the dual control volume structures ---*/ - - if (rank == MASTER_NODE) cout << "Setting the bound control volume structure." << endl; - geometry_container[iZone][INST_0][MESH_0]->SetBoundControlVolume(config_container[ZONE_0], ALLOCATE); - - /*--- Store the global to local mapping after preprocessing. ---*/ - - if (rank == MASTER_NODE) cout << "Storing a mapping from global to local point index." << endl; - geometry_container[iZone][INST_0][MESH_0]->SetGlobal_to_Local_Point(); - - /*--- Create the point-to-point MPI communication structures. ---*/ - - geometry_container[iZone][INST_0][MESH_0]->PreprocessP2PComms(geometry_container[iZone][INST_0][MESH_0], config_container[iZone]); - + } else { + geometry_container[iZone][iInst] = new CGeometry*[nMesh]; + geometry_container[iZone][iInst][MESH_0] = new CPhysicalGeometry(geometry_aux, config_container[iZone]); + } + + /*--- Deallocate the memory of geometry_aux. ---*/ + + delete geometry_aux; + + /*--- Add the Send/Receive boundaries. ---*/ + + geometry_container[iZone][iInst][MESH_0]->SetSendReceive(config_container[iZone]); + + /*--- Add the Send/Receive boundaries. ---*/ + + geometry_container[iZone][iInst][MESH_0]->SetBoundaries(config_container[iZone]); + + /*--- Create the vertex structure (required for MPI). ---*/ + + if (rank == MASTER_NODE) cout << "Identify vertices." << endl; + geometry_container[iZone][iInst][MESH_0]->SetVertex(config_container[iZone]); + + /*--- Store the global to local mapping after preprocessing. ---*/ + + if (rank == MASTER_NODE) cout << "Storing a mapping from global to local point index." << endl; + geometry_container[iZone][iInst][MESH_0]->SetGlobal_to_Local_Point(); + + /*--- Test for a fem solver, because some more work must be done. ---*/ + + if (fem_solver) { + /*--- Carry out a dynamic cast to CMeshFEM_DG, such that it is not needed to + * define all virtual functions in the base class CGeometry. ---*/ + + CMeshFEM_DG* DGMesh = dynamic_cast(geometry_container[iZone][iInst][MESH_0]); + + /*--- Determine the standard elements for the volume elements. ---*/ + + if (rank == MASTER_NODE) cout << "Creating standard volume elements." << endl; + DGMesh->CreateStandardVolumeElements(config_container[iZone]); + + /*--- Create the face information needed to compute the contour integral + * for the elements in the Discontinuous Galerkin formulation. ---*/ + + if (rank == MASTER_NODE) cout << "Creating face information." << endl; + DGMesh->CreateFaces(config_container[iZone]); + } } - /*--- Keep a reference to the main (ZONE_0, INST_0, MESH_0) geometry ---*/ - main_geometry = geometry_container[ZONE_0][INST_0][MESH_0]; + if (rank == MASTER_NODE) + cout << "\n----------------------- Preprocessing computations ----------------------" << endl; + + /*--- Compute elements surrounding points, points surrounding points. ---*/ + + if (rank == MASTER_NODE) cout << "Setting local point connectivity." << endl; + geometry_container[iZone][INST_0][MESH_0]->SetPoint_Connectivity(); + + /*--- Check the orientation before computing geometrical quantities. ---*/ + + geometry_container[iZone][INST_0][MESH_0]->SetBoundVolume(); + if (config_container[iZone]->GetReorientElements()) { + if (rank == MASTER_NODE) cout << "Checking the numerical grid orientation of the elements." << endl; + geometry_container[iZone][INST_0][MESH_0]->Check_IntElem_Orientation(config_container[iZone]); + geometry_container[iZone][INST_0][MESH_0]->Check_BoundElem_Orientation(config_container[iZone]); + } + + /*--- Create the edge structure. ---*/ + + if (rank == MASTER_NODE) cout << "Identify edges and vertices." << endl; + geometry_container[iZone][INST_0][MESH_0]->SetEdges(); + geometry_container[iZone][INST_0][MESH_0]->SetVertex(config_container[iZone]); + + /*--- Create the dual control volume structures. ---*/ + + if (rank == MASTER_NODE) cout << "Setting the bound control volume structure." << endl; + geometry_container[iZone][INST_0][MESH_0]->SetBoundControlVolume(config_container[ZONE_0], ALLOCATE); + + /*--- Store the global to local mapping after preprocessing. ---*/ + + if (rank == MASTER_NODE) cout << "Storing a mapping from global to local point index." << endl; + geometry_container[iZone][INST_0][MESH_0]->SetGlobal_to_Local_Point(); + /*--- Create the point-to-point MPI communication structures. ---*/ + + geometry_container[iZone][INST_0][MESH_0]->PreprocessP2PComms(geometry_container[iZone][INST_0][MESH_0], + config_container[iZone]); + } + + /*--- Keep a reference to the main (ZONE_0, INST_0, MESH_0) geometry. ---*/ + + main_geometry = geometry_container[ZONE_0][INST_0][MESH_0]; } -void CDiscAdjDeformationDriver::Output_Preprocessing() { - +void CDiscAdjDeformationDriver::Output_Preprocessing() {} + +void CDiscAdjDeformationDriver::Preprocess() { + for (iZone = 0; iZone < nZone; iZone++) { + if (rank == MASTER_NODE) cout << "Reading volume sensitivities at each node from file." << endl; + unsigned short nInst_Zone = nInst[iZone]; + + grid_movement[iZone] = new CVolumetricMovement*[nInst_Zone](); + grid_movement[iZone][INST_0] = new CVolumetricMovement(geometry_container[iZone][INST_0][MESH_0], config_container[iZone]); + + /*--- Read in sensitivities from file. ---*/ + + if (config_container[ZONE_0]->GetSensitivity_Format() == UNORDERED_ASCII) + geometry_container[iZone][INST_0][MESH_0]->ReadUnorderedSensitivity(config_container[iZone]); + else + geometry_container[iZone][INST_0][MESH_0]->SetSensitivity(config_container[iZone]); + } } void CDiscAdjDeformationDriver::Run() { - - for (iZone = 0; iZone < nZone; iZone++) { - if (rank == MASTER_NODE) cout << "Reading volume sensitivities at each node from file." << endl; - unsigned short nInst_Zone = nInst[iZone]; - - grid_movement[iZone] = new CVolumetricMovement* [nInst_Zone] (); - grid_movement[iZone][INST_0] = new CVolumetricMovement(geometry_container[iZone][INST_0][MESH_0], config_container[iZone]); - - /*--- Read in sensitivities from file. ---*/ - if (config_container[ZONE_0]->GetSensitivity_Format() == UNORDERED_ASCII) - geometry_container[iZone][INST_0][MESH_0]->ReadUnorderedSensitivity(config_container[iZone]); - else - geometry_container[iZone][INST_0][MESH_0]->SetSensitivity(config_container[iZone]); - - if (rank == MASTER_NODE) cout << "\n---------------------- Mesh sensitivity computation ---------------------" << endl; - if (config_container[iZone]->GetDiscrete_Adjoint() && config_container[iZone]->GetSmoothGradient() && - config_container[iZone]->GetSobMode() == ENUM_SOBOLEV_MODUS::MESH_LEVEL) { - DerivativeTreatment_MeshSensitivity(geometry_container[iZone][INST_0][MESH_0], config_container[iZone], grid_movement[iZone][INST_0]); + for (iZone = 0; iZone < nZone; iZone++) { + if (rank == MASTER_NODE) + cout << "\n---------------------- Mesh sensitivity computation ---------------------" << endl; + if (config_container[iZone]->GetDiscrete_Adjoint() && config_container[iZone]->GetSmoothGradient() && + config_container[iZone]->GetSobMode() == ENUM_SOBOLEV_MODUS::MESH_LEVEL) { + DerivativeTreatment_MeshSensitivity(geometry_container[iZone][INST_0][MESH_0], config_container[iZone], grid_movement[iZone][INST_0]); + } else { + grid_movement[iZone][INST_0]->SetVolume_Deformation(geometry_container[iZone][INST_0][MESH_0], + config_container[iZone], false, true); + } + } + + if (rank == MASTER_NODE) + cout << "\n------------------------ Mesh sensitivity Output ------------------------" << endl; + + SetSensitivity_Files(geometry_container, config_container, nZone); + + Gradient_file.precision(driver_config->OptionIsSet("OUTPUT_PRECISION") ? driver_config->GetOutput_Precision() : 6); + + /*--- For multi-zone computations the gradient contributions are summed up and written into one file. ---*/ + + for (iZone = 0; iZone < nZone; iZone++) { + if ((config_container[iZone]->GetDesign_Variable(0) != NONE) && + (config_container[iZone]->GetDesign_Variable(0) != SURFACE_FILE)) { + if (rank == MASTER_NODE) + cout << "\n---------- Start gradient evaluation using sensitivity information ----------" << endl; + + /*--- Definition of the Class for surface deformation. ---*/ + + surface_movement[iZone] = new CSurfaceMovement(); + + /*--- Copy coordinates to the surface structure. ---*/ + + surface_movement[iZone]->CopyBoundary(geometry_container[iZone][INST_0][MESH_0], config_container[iZone]); + + /*--- If AD mode is enabled we can use it to compute the projection, otherwise we use finite differences. ---*/ + + if (config_container[iZone]->GetAD_Mode()) { + if (config_container[iZone]->GetSmoothGradient()) { + DerivativeTreatment_Gradient(geometry_container[iZone][INST_0][MESH_0], config_container[iZone], + grid_movement[iZone][INST_0], surface_movement[iZone], Gradient); } else { - grid_movement[iZone][INST_0]->SetVolume_Deformation(geometry_container[iZone][INST_0][MESH_0], config_container[iZone], false, true); + SetProjection_AD(geometry_container[iZone][INST_0][MESH_0], config_container[iZone], surface_movement[iZone], Gradient); } + } else { + SetProjection_FD(geometry_container[iZone][INST_0][MESH_0], config_container[iZone], surface_movement[iZone], Gradient); + } } - - if (rank == MASTER_NODE) cout << "\n------------------------ Mesh sensitivity Output ------------------------" << endl; - SetSensitivity_Files(geometry_container, config_container, nZone); - - /*--- Initialize structure to store the gradient ---*/ - Gradient = new su2double*[config_container[ZONE_0]->GetnDV()]; - - for (auto iDV = 0u; iDV < config_container[ZONE_0]->GetnDV(); iDV++) { - /*--- Initialize to zero ---*/ - Gradient[iDV] = new su2double[config_container[ZONE_0]->GetnDV_Value(iDV)](); - } - - Gradient_file.precision(driver_config->OptionIsSet("OUTPUT_PRECISION") ? driver_config->GetOutput_Precision() : 6); - - /*--- For multizone computations the gradient contributions are summed up and written into one file. ---*/ - for (iZone = 0; iZone < nZone; iZone++){ - if ((config_container[iZone]->GetDesign_Variable(0) != NONE) && - (config_container[iZone]->GetDesign_Variable(0) != SURFACE_FILE)) { - - if (rank == MASTER_NODE) - cout << "\n---------- Start gradient evaluation using sensitivity information ----------" << endl; - - /*--- Definition of the Class for surface deformation ---*/ - - surface_movement[iZone] = new CSurfaceMovement(); - - /*--- Copy coordinates to the surface structure ---*/ - - surface_movement[iZone]->CopyBoundary(geometry_container[iZone][INST_0][MESH_0], config_container[iZone]); - - /*--- If AD mode is enabled we can use it to compute the projection, - * otherwise we use finite differences. ---*/ - - if (config_container[iZone]->GetAD_Mode()) { - if (config_container[iZone]->GetSmoothGradient()) { - DerivativeTreatment_Gradient(geometry_container[iZone][INST_0][MESH_0], config_container[iZone], grid_movement[iZone][INST_0], surface_movement[iZone] , Gradient); - } else { - SetProjection_AD(geometry_container[iZone][INST_0][MESH_0], config_container[iZone], surface_movement[iZone] , Gradient); - } - } else { - SetProjection_FD(geometry_container[iZone][INST_0][MESH_0], config_container[iZone], surface_movement[iZone] , Gradient); - } - } - } // for iZone - - /*--- Write the gradient to a file ---*/ - - if (rank == MASTER_NODE) - Gradient_file.open(config_container[ZONE_0]->GetObjFunc_Grad_FileName().c_str(), ios::out); - - /*--- Print gradients to screen and writes to file ---*/ - - OutputGradient(Gradient, config_container[ZONE_0], Gradient_file); - + } + + /*--- Write the gradient to a file. ---*/ + + if (rank == MASTER_NODE) Gradient_file.open(config_container[ZONE_0]->GetObjFunc_Grad_FileName().c_str(), ios::out); + + /*--- Print gradients to screen and writes to file. ---*/ + + OutputGradient(Gradient, config_container[ZONE_0], Gradient_file); } void CDiscAdjDeformationDriver::Postprocessing() { - - for (auto iDV = 0u; iDV < config_container[ZONE_0]->GetnDV(); iDV++){ - delete [] Gradient[iDV]; + for (auto iDV = 0u; iDV < config_container[ZONE_0]->GetnDV(); iDV++) { + delete[] Gradient[iDV]; + } + delete[] Gradient; + + delete driver_config; + driver_config = nullptr; + + if (rank == MASTER_NODE) + cout << "\n------------------------- Solver Postprocessing -------------------------" << endl; + + for (iZone = 0; iZone < nZone; iZone++) { + if (numerics_container[iZone] != nullptr) { + delete[] numerics_container[iZone]; } - delete [] Gradient; - - delete driver_config; - driver_config = nullptr; - - if (rank == MASTER_NODE) - cout << "\n------------------------- Solver Postprocessing -------------------------" << endl; - - for (iZone = 0; iZone < nZone; iZone++) { - if (numerics_container[iZone] != nullptr) { - delete [] numerics_container[iZone]; - } + } + delete[] numerics_container; + if (rank == MASTER_NODE) cout << "Deleted CNumerics container." << endl; + + for (iZone = 0; iZone < nZone; iZone++) { + if (solver_container[iZone] != nullptr) { + delete[] solver_container[iZone]; } - delete [] numerics_container; - if (rank == MASTER_NODE) cout << "Deleted CNumerics container." << endl; - + } + delete[] solver_container; + if (rank == MASTER_NODE) cout << "Deleted CSolver container." << endl; + + if (geometry_container != nullptr) { for (iZone = 0; iZone < nZone; iZone++) { - if (solver_container[iZone] != nullptr) { - delete [] solver_container[iZone]; + if (geometry_container[iZone] != nullptr) { + for (iInst = 0; iInst < nInst[iZone]; iInst++) { + delete geometry_container[iZone][iInst][MESH_0]; + delete[] geometry_container[iZone][iInst]; } + delete[] geometry_container[iZone]; + } } - delete [] solver_container; - if (rank == MASTER_NODE) cout << "Deleted CSolver container." << endl; - - if (geometry_container != nullptr) { - for (iZone = 0; iZone < nZone; iZone++) { - if (geometry_container[iZone] != nullptr) { - for (iInst = 0; iInst < nInst[iZone]; iInst++){ - delete geometry_container[iZone][iInst][MESH_0]; - delete [] geometry_container[iZone][iInst]; - } - delete [] geometry_container[iZone]; - } - } - delete [] geometry_container; - } - if (rank == MASTER_NODE) cout << "Deleted CGeometry container." << endl; - + delete[] geometry_container; + } + if (rank == MASTER_NODE) cout << "Deleted CGeometry container." << endl; + + for (iZone = 0; iZone < nZone; iZone++) { + delete[] FFDBox[iZone]; + } + delete[] FFDBox; + if (rank == MASTER_NODE) cout << "Deleted CFreeFormDefBox class." << endl; + + if (surface_movement != nullptr) { for (iZone = 0; iZone < nZone; iZone++) { - delete [] FFDBox[iZone]; + delete surface_movement[iZone]; } - delete [] FFDBox; - if (rank == MASTER_NODE) cout << "Deleted CFreeFormDefBox class." << endl; - - if (surface_movement != nullptr) { - for (iZone = 0; iZone < nZone; iZone++) { - delete surface_movement[iZone]; - } - delete [] surface_movement; - } - if (rank == MASTER_NODE) cout << "Deleted CSurfaceMovement class." << endl; - - if (grid_movement != nullptr) { - for (iZone = 0; iZone < nZone; iZone++) { - if (grid_movement[iZone] != nullptr) { - for (iInst = 0; iInst < nInst[iZone]; iInst++){ - delete grid_movement[iZone][iInst]; - } - delete [] grid_movement[iZone]; - } + delete[] surface_movement; + } + if (rank == MASTER_NODE) cout << "Deleted CSurfaceMovement class." << endl; + + if (grid_movement != nullptr) { + for (iZone = 0; iZone < nZone; iZone++) { + if (grid_movement[iZone] != nullptr) { + for (iInst = 0; iInst < nInst[iZone]; iInst++) { + delete grid_movement[iZone][iInst]; } - delete [] grid_movement; + delete[] grid_movement[iZone]; + } } - if (rank == MASTER_NODE) cout << "Deleted CVolumetricMovement class." << endl; - - if (config_container != nullptr) { - for (iZone = 0; iZone < nZone; iZone++) { - delete config_container[iZone]; - } - delete [] config_container; + delete[] grid_movement; + } + if (rank == MASTER_NODE) cout << "Deleted CVolumetricMovement class." << endl; + + if (config_container != nullptr) { + for (iZone = 0; iZone < nZone; iZone++) { + delete config_container[iZone]; } - if (rank == MASTER_NODE) cout << "Deleted CConfig container." << endl; - - if (output_container != nullptr) { - for (iZone = 0; iZone < nZone; iZone++) { - delete output_container[iZone]; - } - delete [] output_container; + delete[] config_container; + } + if (rank == MASTER_NODE) cout << "Deleted CConfig container." << endl; + + if (output_container != nullptr) { + for (iZone = 0; iZone < nZone; iZone++) { + delete output_container[iZone]; } - if (rank == MASTER_NODE) cout << "Deleted COutput class." << endl; - - if (nInst != nullptr) delete [] nInst; - - /*--- Exit the solver cleanly ---*/ - - if (rank == MASTER_NODE) - cout << endl << "------------------------- Exit Success (SU2_DEF_AD) ------------------------" << endl << endl; - + delete[] output_container; + } + if (rank == MASTER_NODE) cout << "Deleted COutput class." << endl; + + if (nInst != nullptr) delete[] nInst; + + /*--- Exit the solver cleanly. ---*/ + + if (rank == MASTER_NODE) + cout << endl << "------------------------- Exit Success (SU2_DEF_AD) ------------------------" << endl << endl; } -void CDiscAdjDeformationDriver::SetProjection_FD(CGeometry *geometry, CConfig *config, CSurfaceMovement *surface_movement, su2double** Gradient){ - - unsigned short iDV, nDV, iFFDBox, nDV_Value, iMarker, iDim; - unsigned long iVertex, iPoint; - su2double delta_eps, my_Gradient, localGradient, *Normal, dS, *VarCoord, Sensitivity, - dalpha[3], deps[3], dalpha_deps; - bool *UpdatePoint, MoveSurface, Local_MoveSurface; - CFreeFormDefBox **FFDBox; - - int rank = SU2_MPI::GetRank(); - - nDV = config->GetnDV(); - - /*--- Boolean controlling points to be updated ---*/ - - UpdatePoint = new bool[geometry->GetnPoint()]; - - /*--- Definition of the FFD deformation class ---*/ - - unsigned short nFFDBox = MAX_NUMBER_FFD; - FFDBox = new CFreeFormDefBox*[nFFDBox]; - for (iFFDBox = 0; iFFDBox < MAX_NUMBER_FFD; iFFDBox++) FFDBox[iFFDBox] = nullptr; - - for (iDV = 0; iDV < nDV; iDV++){ - nDV_Value = config->GetnDV_Value(iDV); - if (nDV_Value != 1){ - SU2_MPI::Error("The projection using finite differences currently only supports a fixed direction of movement for FFD points.", CURRENT_FUNCTION); - } +void CDiscAdjDeformationDriver::SetProjection_FD(CGeometry* geometry, CConfig* config, + CSurfaceMovement* surface_movement, su2double** Gradient) { + unsigned short iDV, nDV, iFFDBox, nDV_Value, iMarker, iDim; + unsigned long iVertex, iPoint; + su2double delta_eps, my_Gradient, localGradient, *Normal, dS, *VarCoord, Sensitivity, dalpha[3], deps[3], dalpha_deps; + bool *UpdatePoint, MoveSurface, Local_MoveSurface; + CFreeFormDefBox** FFDBox; + + int rank = SU2_MPI::GetRank(); + + nDV = config->GetnDV(); + + /*--- Boolean controlling points to be updated. ---*/ + + UpdatePoint = new bool[geometry->GetnPoint()]; + + /*--- Definition of the FFD deformation class. ---*/ + + unsigned short nFFDBox = MAX_NUMBER_FFD; + FFDBox = new CFreeFormDefBox*[nFFDBox]; + for (iFFDBox = 0; iFFDBox < MAX_NUMBER_FFD; iFFDBox++) FFDBox[iFFDBox] = nullptr; + + for (iDV = 0; iDV < nDV; iDV++) { + nDV_Value = config->GetnDV_Value(iDV); + if (nDV_Value != 1) { + SU2_MPI::Error("The projection using finite differences currently only supports a fixed direction of movement for FFD points.", CURRENT_FUNCTION); } - - /*--- Continuous adjoint gradient computation ---*/ - - if (rank == MASTER_NODE) - cout << "Evaluate functional gradient using Finite Differences." << endl; - - for (iDV = 0; iDV < nDV; iDV++) { - - MoveSurface = true; - Local_MoveSurface = true; - - /*--- 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_TWIST_2D) || - (config->GetDesign_Variable(iDV) == FFD_CONTROL_POINT) || - (config->GetDesign_Variable(iDV) == FFD_NACELLE) || - (config->GetDesign_Variable(iDV) == FFD_GULL) || - (config->GetDesign_Variable(iDV) == FFD_TWIST) || - (config->GetDesign_Variable(iDV) == FFD_ROTATION) || - (config->GetDesign_Variable(iDV) == FFD_CAMBER) || - (config->GetDesign_Variable(iDV) == FFD_THICKNESS) || - (config->GetDesign_Variable(iDV) == FFD_ANGLE_OF_ATTACK)) { - - /*--- 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_movement->ReadFFDInfo(geometry, config, FFDBox, config->GetMesh_FileName()); - - /*--- If the FFDBox was not defined in the input file ---*/ - if (!surface_movement->GetFFDBoxDefinition()) { - SU2_MPI::Error("The input grid doesn't have the entire FFD information!", CURRENT_FUNCTION); - } - - for (iFFDBox = 0; iFFDBox < surface_movement->GetnFFDBox(); iFFDBox++) { - - if (rank == MASTER_NODE) cout << "Checking FFD box dimension." << endl; - surface_movement->CheckFFDDimension(geometry, config, FFDBox[iFFDBox], iFFDBox); - - if (rank == MASTER_NODE) cout << "Check the FFD box intersections with the solid surfaces." << endl; - surface_movement->CheckFFDIntersections(geometry, config, FFDBox[iFFDBox], iFFDBox); - - } - - if (rank == MASTER_NODE) - cout <<"-------------------------------------------------------------------------" << endl; - - } - - if (rank == MASTER_NODE) { - cout << endl << "Design variable number "<< iDV <<"." << endl; - cout << "Performing 3D deformation of the surface." << endl; - } - - /*--- Apply the control point change ---*/ - - MoveSurface = false; - - for (iFFDBox = 0; iFFDBox < surface_movement->GetnFFDBox(); iFFDBox++) { - - /*--- Reset FFD box ---*/ - - switch (config->GetDesign_Variable(iDV) ) { - case FFD_CONTROL_POINT_2D : Local_MoveSurface = surface_movement->SetFFDCPChange_2D(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; - case FFD_CAMBER_2D : Local_MoveSurface = surface_movement->SetFFDCamber_2D(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; - case FFD_THICKNESS_2D : Local_MoveSurface = surface_movement->SetFFDThickness_2D(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; - case FFD_TWIST_2D : Local_MoveSurface = surface_movement->SetFFDTwist_2D(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; - case FFD_CONTROL_POINT : Local_MoveSurface = surface_movement->SetFFDCPChange(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; - case FFD_NACELLE : Local_MoveSurface = surface_movement->SetFFDNacelle(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; - case FFD_GULL : Local_MoveSurface = surface_movement->SetFFDGull(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; - case FFD_TWIST : Local_MoveSurface = surface_movement->SetFFDTwist(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; - case FFD_ROTATION : Local_MoveSurface = surface_movement->SetFFDRotation(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; - case FFD_CAMBER : Local_MoveSurface = surface_movement->SetFFDCamber(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; - case FFD_THICKNESS : Local_MoveSurface = surface_movement->SetFFDThickness(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; - case FFD_CONTROL_SURFACE : Local_MoveSurface = surface_movement->SetFFDControl_Surface(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); break; - case FFD_ANGLE_OF_ATTACK : Gradient[iDV][0] = config->GetAoA_Sens(); break; - } - - /*--- Recompute cartesian coordinates using the new control points position ---*/ - - if (Local_MoveSurface) { - MoveSurface = true; - surface_movement->SetCartesianCoord(geometry, config, FFDBox[iFFDBox], iFFDBox, true); - } - - } - - } - - /*--- Hicks Henne design variable ---*/ - - else if (config->GetDesign_Variable(iDV) == HICKS_HENNE) { - surface_movement->SetHicksHenne(geometry, config, iDV, true); - } - - /*--- Surface bump design variable ---*/ - - else if (config->GetDesign_Variable(iDV) == SURFACE_BUMP) { - surface_movement->SetSurface_Bump(geometry, config, iDV, true); - } - - /*--- Kulfan (CST) design variable ---*/ - - else if (config->GetDesign_Variable(iDV) == CST) { - surface_movement->SetCST(geometry, config, iDV, true); + } + + /*--- Continuous adjoint gradient computation. ---*/ + + if (rank == MASTER_NODE) cout << "Evaluate functional gradient using Finite Differences." << endl; + + for (iDV = 0; iDV < nDV; iDV++) { + MoveSurface = true; + Local_MoveSurface = true; + + /*--- 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_TWIST_2D) || (config->GetDesign_Variable(iDV) == FFD_CONTROL_POINT) || + (config->GetDesign_Variable(iDV) == FFD_NACELLE) || (config->GetDesign_Variable(iDV) == FFD_GULL) || + (config->GetDesign_Variable(iDV) == FFD_TWIST) || (config->GetDesign_Variable(iDV) == FFD_ROTATION) || + (config->GetDesign_Variable(iDV) == FFD_CAMBER) || (config->GetDesign_Variable(iDV) == FFD_THICKNESS) || + (config->GetDesign_Variable(iDV) == FFD_ANGLE_OF_ATTACK)) { + /*--- 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_movement->ReadFFDInfo(geometry, config, FFDBox, config->GetMesh_FileName()); + + /*--- If the FFDBox was not defined in the input file. ---*/ + + if (!surface_movement->GetFFDBoxDefinition()) { + SU2_MPI::Error("The input grid doesn't have the entire FFD information!", CURRENT_FUNCTION); } - - /*--- Displacement design variable ---*/ - - else if (config->GetDesign_Variable(iDV) == TRANSLATION) { - surface_movement->SetTranslation(geometry, config, iDV, true); + + for (iFFDBox = 0; iFFDBox < surface_movement->GetnFFDBox(); iFFDBox++) { + if (rank == MASTER_NODE) cout << "Checking FFD box dimension." << endl; + surface_movement->CheckFFDDimension(geometry, config, FFDBox[iFFDBox], iFFDBox); + + if (rank == MASTER_NODE) cout << "Check the FFD box intersections with the solid surfaces." << endl; + surface_movement->CheckFFDIntersections(geometry, config, FFDBox[iFFDBox], iFFDBox); } - - /*--- Angle of Attack design variable ---*/ - - else if (config->GetDesign_Variable(iDV) == ANGLE_OF_ATTACK) { + + if (rank == MASTER_NODE) + cout << "-------------------------------------------------------------------------" << endl; + } + + if (rank == MASTER_NODE) { + cout << endl << "Design variable number " << iDV << "." << endl; + cout << "Performing 3D deformation of the surface." << endl; + } + + /*--- Apply the control point change. ---*/ + + MoveSurface = false; + + for (iFFDBox = 0; iFFDBox < surface_movement->GetnFFDBox(); iFFDBox++) { + /*--- Reset FFD box. ---*/ + + switch (config->GetDesign_Variable(iDV)) { + case FFD_CONTROL_POINT_2D: + Local_MoveSurface = + surface_movement->SetFFDCPChange_2D(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); + break; + case FFD_CAMBER_2D: + Local_MoveSurface = surface_movement->SetFFDCamber_2D(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); + break; + case FFD_THICKNESS_2D: + Local_MoveSurface = + surface_movement->SetFFDThickness_2D(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); + break; + case FFD_TWIST_2D: + Local_MoveSurface = surface_movement->SetFFDTwist_2D(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); + break; + case FFD_CONTROL_POINT: + Local_MoveSurface = surface_movement->SetFFDCPChange(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); + break; + case FFD_NACELLE: + Local_MoveSurface = surface_movement->SetFFDNacelle(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); + break; + case FFD_GULL: + Local_MoveSurface = surface_movement->SetFFDGull(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); + break; + case FFD_TWIST: + Local_MoveSurface = surface_movement->SetFFDTwist(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); + break; + case FFD_ROTATION: + Local_MoveSurface = surface_movement->SetFFDRotation(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); + break; + case FFD_CAMBER: + Local_MoveSurface = surface_movement->SetFFDCamber(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); + break; + case FFD_THICKNESS: + Local_MoveSurface = surface_movement->SetFFDThickness(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); + break; + case FFD_CONTROL_SURFACE: + Local_MoveSurface = + surface_movement->SetFFDControl_Surface(geometry, config, FFDBox[iFFDBox], FFDBox, iDV, true); + break; + case FFD_ANGLE_OF_ATTACK: Gradient[iDV][0] = config->GetAoA_Sens(); + break; } - - /*--- Scale design variable ---*/ - - else if (config->GetDesign_Variable(iDV) == SCALE) { - surface_movement->SetScale(geometry, config, iDV, true); - } - - /*--- Rotation design variable ---*/ - - else if (config->GetDesign_Variable(iDV) == ROTATION) { - surface_movement->SetRotation(geometry, config, iDV, true); - } - - /*--- NACA_4Digits design variable ---*/ - - else if (config->GetDesign_Variable(iDV) == NACA_4DIGITS) { - surface_movement->SetNACA_4Digits(geometry, config); - } - - /*--- Parabolic design variable ---*/ - - else if (config->GetDesign_Variable(iDV) == PARABOLIC) { - surface_movement->SetParabolic(geometry, config); - } - - /*--- Design variable not implemented ---*/ - - else { - if (rank == MASTER_NODE) - cout << "Design Variable not implemented yet" << endl; - } - - /*--- Load the delta change in the design variable (finite difference step). ---*/ - - if ((config->GetDesign_Variable(iDV) != ANGLE_OF_ATTACK) && - (config->GetDesign_Variable(iDV) != FFD_ANGLE_OF_ATTACK)) { - - /*--- If the Angle of attack is not involved, reset the value of the gradient ---*/ - - my_Gradient = 0.0; Gradient[iDV][0] = 0.0; - - if (MoveSurface) { - - delta_eps = config->GetDV_Value(iDV); - - for (iPoint = 0; iPoint < geometry->GetnPoint(); iPoint++) - UpdatePoint[iPoint] = true; - - for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { - if (config->GetMarker_All_DV(iMarker) == YES) { - for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - - iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); - if ((iPoint < geometry->GetnPointDomain()) && UpdatePoint[iPoint]) { - - Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); - VarCoord = geometry->vertex[iMarker][iVertex]->GetVarCoord(); - Sensitivity = geometry->vertex[iMarker][iVertex]->GetAuxVar(); - - dS = 0.0; - for (iDim = 0; iDim < geometry->GetnDim(); iDim++) { - dS += Normal[iDim]*Normal[iDim]; - deps[iDim] = VarCoord[iDim] / delta_eps; - } - dS = sqrt(dS); - - dalpha_deps = 0.0; - for (iDim = 0; iDim < geometry->GetnDim(); iDim++) { - dalpha[iDim] = Normal[iDim] / dS; - dalpha_deps -= dalpha[iDim]*deps[iDim]; - } - - my_Gradient += Sensitivity*dalpha_deps; - UpdatePoint[iPoint] = false; - } - } - } - } - } - - SU2_MPI::Allreduce(&my_Gradient, &localGradient, 1, MPI_DOUBLE, MPI_SUM, SU2_MPI::GetComm()); - Gradient[iDV][0] += localGradient; + + /*--- Recompute cartesian coordinates using the new control points position. ---*/ + + if (Local_MoveSurface) { + MoveSurface = true; + surface_movement->SetCartesianCoord(geometry, config, FFDBox[iFFDBox], iFFDBox, true); } + } } - - /*--- Delete memory for parameterization. ---*/ - - if (FFDBox != nullptr) { - for (iFFDBox = 0; iFFDBox < MAX_NUMBER_FFD; iFFDBox++) { - if (FFDBox[iFFDBox] != nullptr) { - delete FFDBox[iFFDBox]; - } - } - delete [] FFDBox; + + /*--- Hicks-Henne design variable. ---*/ + + else if (config->GetDesign_Variable(iDV) == HICKS_HENNE) { + surface_movement->SetHicksHenne(geometry, config, iDV, true); } - - delete [] UpdatePoint; - -} + /*--- Surface bump design variable. ---*/ -void CDiscAdjDeformationDriver::SetProjection_AD(CGeometry *geometry, CConfig *config, CSurfaceMovement *surface_movement, su2double** Gradient){ - - su2double *VarCoord = nullptr, Sensitivity, my_Gradient, localGradient, *Normal, Area = 0.0; - unsigned short iDV_Value = 0, iMarker, nMarker, iDim, nDim, iDV, nDV; - unsigned long iVertex, nVertex, iPoint; - - const int rank = SU2_MPI::GetRank(); - - nMarker = config->GetnMarker_All(); - nDim = geometry->GetnDim(); - nDV = config->GetnDV(); - - /*--- Discrete adjoint gradient computation ---*/ - - if (rank == MASTER_NODE) - cout << endl << "Evaluate functional gradient using Algorithmic Differentiation (ZONE " << config->GetiZone() << ")." << endl; - - /*--- Start recording of operations ---*/ - - AD::StartRecording(); - - /*--- Register design variables as input and set them to zero - * (since we want to have the derivative at alpha = 0, i.e. for the current design) ---*/ - - for (iDV = 0; iDV < nDV; iDV++){ - - for (iDV_Value = 0; iDV_Value < config->GetnDV_Value(iDV); iDV_Value++){ - - config->SetDV_Value(iDV, iDV_Value, 0.0); - - AD::RegisterInput(config->GetDV_Value(iDV, iDV_Value)); - } + else if (config->GetDesign_Variable(iDV) == SURFACE_BUMP) { + surface_movement->SetSurface_Bump(geometry, config, iDV, true); } - - /*--- Call the surface deformation routine ---*/ - - surface_movement->SetSurface_Deformation(geometry, config); - - /*--- Stop the recording --- */ - - AD::StopRecording(); - - /*--- Create a structure to identify points that have been already visited. - * We need that to make sure to set the sensitivity of surface points only once - * (Markers share points, so we would visit them more than once in the loop over the markers below) ---*/ - - vector visited(geometry->GetnPoint(), false); - - /*--- Initialize the derivatives of the output of the surface deformation routine - * with the discrete adjoints from the CFD solution ---*/ - - for (iMarker = 0; iMarker < nMarker; iMarker++) { - if (config->GetMarker_All_DV(iMarker) == YES) { - nVertex = geometry->nVertex[iMarker]; - for (iVertex = 0; iVertex vertex[iMarker][iVertex]->GetNode(); - if (!visited[iPoint]){ - VarCoord = geometry->vertex[iMarker][iVertex]->GetVarCoord(); - Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); - - Area = 0.0; - for (iDim = 0; iDim < nDim; iDim++){ - Area += Normal[iDim]*Normal[iDim]; - } - Area = sqrt(Area); - - for (iDim = 0; iDim < nDim; iDim++){ - if (config->GetDiscrete_Adjoint()){ - Sensitivity = geometry->GetSensitivity(iPoint, iDim); - } else { - Sensitivity = -Normal[iDim]*geometry->vertex[iMarker][iVertex]->GetAuxVar()/Area; - } - SU2_TYPE::SetDerivative(VarCoord[iDim], SU2_TYPE::GetValue(Sensitivity)); - } - visited[iPoint] = true; + + /*--- Kulfan (CST) design variable. ---*/ + + else if (config->GetDesign_Variable(iDV) == CST) { + surface_movement->SetCST(geometry, config, iDV, true); + } + + /*--- Displacement design variable. ---*/ + + else if (config->GetDesign_Variable(iDV) == TRANSLATION) { + surface_movement->SetTranslation(geometry, config, iDV, true); + } + + /*--- Angle of Attack design variable. ---*/ + + else if (config->GetDesign_Variable(iDV) == ANGLE_OF_ATTACK) { + Gradient[iDV][0] = config->GetAoA_Sens(); + } + + /*--- Scale design variable. ---*/ + + else if (config->GetDesign_Variable(iDV) == SCALE) { + surface_movement->SetScale(geometry, config, iDV, true); + } + + /*--- Rotation design variable. ---*/ + + else if (config->GetDesign_Variable(iDV) == ROTATION) { + surface_movement->SetRotation(geometry, config, iDV, true); + } + + /*--- NACA_4Digits design variable. ---*/ + + else if (config->GetDesign_Variable(iDV) == NACA_4DIGITS) { + surface_movement->SetNACA_4Digits(geometry, config); + } + + /*--- Parabolic design variable. ---*/ + + else if (config->GetDesign_Variable(iDV) == PARABOLIC) { + surface_movement->SetParabolic(geometry, config); + } + + /*--- Design variable not implemented. ---*/ + + else { + if (rank == MASTER_NODE) cout << "Design Variable not implemented yet" << endl; + } + + /*--- Load the delta change in the design variable (finite difference step). ---*/ + + if ((config->GetDesign_Variable(iDV) != ANGLE_OF_ATTACK) && + (config->GetDesign_Variable(iDV) != FFD_ANGLE_OF_ATTACK)) { + /*--- If the Angle of attack is not involved, reset the value of the gradient. ---*/ + + my_Gradient = 0.0; + Gradient[iDV][0] = 0.0; + + if (MoveSurface) { + delta_eps = config->GetDV_Value(iDV); + + for (iPoint = 0; iPoint < geometry->GetnPoint(); iPoint++) UpdatePoint[iPoint] = true; + + for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { + if (config->GetMarker_All_DV(iMarker) == YES) { + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { + iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + if ((iPoint < geometry->GetnPointDomain()) && UpdatePoint[iPoint]) { + Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); + VarCoord = geometry->vertex[iMarker][iVertex]->GetVarCoord(); + Sensitivity = geometry->vertex[iMarker][iVertex]->GetAuxVar(); + + dS = 0.0; + for (iDim = 0; iDim < geometry->GetnDim(); iDim++) { + dS += Normal[iDim] * Normal[iDim]; + deps[iDim] = VarCoord[iDim] / delta_eps; + } + dS = sqrt(dS); + + dalpha_deps = 0.0; + for (iDim = 0; iDim < geometry->GetnDim(); iDim++) { + dalpha[iDim] = Normal[iDim] / dS; + dalpha_deps -= dalpha[iDim] * deps[iDim]; } + + my_Gradient += Sensitivity * dalpha_deps; + UpdatePoint[iPoint] = false; + } } + } } + } + + SU2_MPI::Allreduce(&my_Gradient, &localGradient, 1, MPI_DOUBLE, MPI_SUM, SU2_MPI::GetComm()); + Gradient[iDV][0] += localGradient; } - - /*--- Compute derivatives and extract gradient ---*/ - - AD::ComputeAdjoint(); - - for (iDV = 0; iDV < nDV; iDV++){ - - for (iDV_Value = 0; iDV_Value < config->GetnDV_Value(iDV); iDV_Value++) { - - my_Gradient = SU2_TYPE::GetDerivative(config->GetDV_Value(iDV, iDV_Value)); - - SU2_MPI::Allreduce(&my_Gradient, &localGradient, 1, MPI_DOUBLE, MPI_SUM, SU2_MPI::GetComm()); - - /*--- Angle of Attack design variable (this is different, - the value comes form the input file) ---*/ - - if ((config->GetDesign_Variable(iDV) == ANGLE_OF_ATTACK) || - (config->GetDesign_Variable(iDV) == FFD_ANGLE_OF_ATTACK)) { - Gradient[iDV][iDV_Value] = config->GetAoA_Sens(); - } - - Gradient[iDV][iDV_Value] += localGradient; - } + } + + /*--- Delete memory for parameterization. ---*/ + + if (FFDBox != nullptr) { + for (iFFDBox = 0; iFFDBox < MAX_NUMBER_FFD; iFFDBox++) { + if (FFDBox[iFFDBox] != nullptr) { + delete FFDBox[iFFDBox]; + } } - - AD::Reset(); - + delete[] FFDBox; + } + + delete[] UpdatePoint; } -void CDiscAdjDeformationDriver::OutputGradient(su2double** Gradient, CConfig* config, ofstream& Gradient_file){ - - unsigned short nDV, iDV, iDV_Value, nDV_Value; - - int rank = SU2_MPI::GetRank(); - - nDV = config->GetnDV(); - - /*--- Loop through all design variables and their gradients ---*/ - - for (iDV = 0; iDV < nDV; iDV++){ - nDV_Value = config->GetnDV_Value(iDV); - if (rank == MASTER_NODE){ - - /*--- Print the kind of design variable on screen ---*/ - - cout << endl << "Design variable ("; - for (std::map::const_iterator it = Param_Map.begin(); it != Param_Map.end(); ++it ){ - if (it->second == config->GetDesign_Variable(iDV)){ - cout << it->first << ") number "<< iDV << "." << endl; - } - } - - /*--- Print the kind of objective function to screen ---*/ - - for (std::map::const_iterator it = Objective_Map.begin(); it != Objective_Map.end(); ++it ){ - if (it->second == config->GetKind_ObjFunc()){ - cout << it->first << " gradient : "; - if (iDV == 0) Gradient_file << it->first << " gradient " << endl; - } - } - - /*--- Print the gradient to file and screen ---*/ - - for (iDV_Value = 0; iDV_Value < nDV_Value; iDV_Value++){ - cout << Gradient[iDV][iDV_Value]; - if (iDV_Value != nDV_Value-1 ){ - cout << ", "; - } - Gradient_file << Gradient[iDV][iDV_Value] << endl; +void CDiscAdjDeformationDriver::SetProjection_AD(CGeometry* geometry, CConfig* config, + CSurfaceMovement* surface_movement, su2double** Gradient) { + su2double *VarCoord = nullptr, Sensitivity, my_Gradient, localGradient, *Normal, Area = 0.0; + unsigned short iDV_Value = 0, iMarker, nMarker, iDim, nDim, iDV, nDV; + unsigned long iVertex, nVertex, iPoint; + + const int rank = SU2_MPI::GetRank(); + + nMarker = config->GetnMarker_All(); + nDim = geometry->GetnDim(); + nDV = config->GetnDV(); + + /*--- Discrete adjoint gradient computation. ---*/ + + if (rank == MASTER_NODE) + cout << endl + << "Evaluate functional gradient using Algorithmic Differentiation (ZONE " << config->GetiZone() << ")." + << endl; + + /*--- Start recording of operations. ---*/ + + AD::StartRecording(); + + /*--- Register design variables as input and set them to zero + * (since we want to have the derivative at alpha = 0, i.e. for the current design). ---*/ + + for (iDV = 0; iDV < nDV; iDV++) { + for (iDV_Value = 0; iDV_Value < config->GetnDV_Value(iDV); iDV_Value++) { + config->SetDV_Value(iDV, iDV_Value, 0.0); + + AD::RegisterInput(config->GetDV_Value(iDV, iDV_Value)); + } + } + + /*--- Call the surface deformation routine. ---*/ + + surface_movement->SetSurface_Deformation(geometry, config); + + /*--- Stop the recording. --- */ + + AD::StopRecording(); + + /*--- Create a structure to identify points that have been already visited. + * We need that to make sure to set the sensitivity of surface points only once. + * Markers share points, so we would visit them more than once in the loop over the markers below). ---*/ + + vector visited(geometry->GetnPoint(), false); + + /*--- Initialize the derivatives of the output of the surface deformation routine + * with the discrete adjoints from the CFD solution. ---*/ + + for (iMarker = 0; iMarker < nMarker; iMarker++) { + if (config->GetMarker_All_DV(iMarker) == YES) { + nVertex = geometry->nVertex[iMarker]; + for (iVertex = 0; iVertex < nVertex; iVertex++) { + iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + if (!visited[iPoint]) { + VarCoord = geometry->vertex[iMarker][iVertex]->GetVarCoord(); + Normal = geometry->vertex[iMarker][iVertex]->GetNormal(); + + Area = 0.0; + for (iDim = 0; iDim < nDim; iDim++) { + Area += Normal[iDim] * Normal[iDim]; + } + Area = sqrt(Area); + + for (iDim = 0; iDim < nDim; iDim++) { + if (config->GetDiscrete_Adjoint()) { + Sensitivity = geometry->GetSensitivity(iPoint, iDim); + } else { + Sensitivity = -Normal[iDim] * geometry->vertex[iMarker][iVertex]->GetAuxVar() / Area; } - cout << endl; - cout <<"-------------------------------------------------------------------------" << endl; + SU2_TYPE::SetDerivative(VarCoord[iDim], SU2_TYPE::GetValue(Sensitivity)); + } + visited[iPoint] = true; } + } } + } + + /*--- Compute derivatives and extract gradient. ---*/ + + AD::ComputeAdjoint(); + + for (iDV = 0; iDV < nDV; iDV++) { + for (iDV_Value = 0; iDV_Value < config->GetnDV_Value(iDV); iDV_Value++) { + my_Gradient = SU2_TYPE::GetDerivative(config->GetDV_Value(iDV, iDV_Value)); + + SU2_MPI::Allreduce(&my_Gradient, &localGradient, 1, MPI_DOUBLE, MPI_SUM, SU2_MPI::GetComm()); + + /*--- Angle of Attack design variable (this is different, the value comes form the input file). ---*/ + + if ((config->GetDesign_Variable(iDV) == ANGLE_OF_ATTACK) || + (config->GetDesign_Variable(iDV) == FFD_ANGLE_OF_ATTACK)) { + Gradient[iDV][iDV_Value] = config->GetAoA_Sens(); + } + + Gradient[iDV][iDV_Value] += localGradient; + } + } + + AD::Reset(); } +void CDiscAdjDeformationDriver::OutputGradient(su2double** Gradient, CConfig* config, ofstream& Gradient_file) { -void CDiscAdjDeformationDriver::SetSensitivity_Files(CGeometry ****geometry, CConfig **config, unsigned short val_nZone) { - - unsigned short iMarker,iDim, nDim, nMarker, nVar; - unsigned long iVertex, iPoint, nPoint, nVertex; - su2double *Normal, Prod, Sens = 0.0, SensDim, Area; - - unsigned short iZone; - - CSolver *solver = nullptr; - COutput *output = nullptr; - - for (iZone = 0; iZone < val_nZone; iZone++) { - - nPoint = geometry[iZone][INST_0][MESH_0]->GetnPoint(); - nDim = geometry[iZone][INST_0][MESH_0]->GetnDim(); - nMarker = config[iZone]->GetnMarker_All(); - nVar = nDim + 1; - - /*--- We create a baseline solver to easily merge the sensitivity information ---*/ - - vector fieldnames; - fieldnames.push_back("\"Point\""); - fieldnames.push_back("\"x\""); - fieldnames.push_back("\"y\""); - if (nDim == 3) { - fieldnames.push_back("\"z\""); - } - fieldnames.push_back("\"Sensitivity_x\""); - fieldnames.push_back("\"Sensitivity_y\""); - if (nDim == 3) { - fieldnames.push_back("\"Sensitivity_z\""); - } - fieldnames.push_back("\"Surface_Sensitivity\""); - - solver = new CBaselineSolver(geometry[iZone][INST_0][MESH_0], config[iZone], nVar+nDim, fieldnames); - - for (iPoint = 0; iPoint < nPoint; iPoint++) { - for (iDim = 0; iDim < nDim; iDim++) { - solver->GetNodes()->SetSolution(iPoint, iDim, geometry[iZone][INST_0][MESH_0]->nodes->GetCoord(iPoint, iDim)); - solver->GetNodes()->SetSolution(iPoint, iDim+nDim, geometry[iZone][INST_0][MESH_0]->GetSensitivity(iPoint, iDim)); - } + unsigned short nDV, iDV, iDV_Value, nDV_Value; + + int rank = SU2_MPI::GetRank(); + + nDV = config->GetnDV(); + + /*--- Loop through all design variables and their gradients. ---*/ + + for (iDV = 0; iDV < nDV; iDV++) { + nDV_Value = config->GetnDV_Value(iDV); + if (rank == MASTER_NODE) { + /*--- Print the kind of design variable on screen. ---*/ + + cout << endl << "Design variable ("; + for (std::map::const_iterator it = Param_Map.begin(); it != Param_Map.end(); ++it) { + if (it->second == config->GetDesign_Variable(iDV)) { + cout << it->first << ") number " << iDV << "." << endl; } - - /*--- Compute the sensitivity in normal direction ---*/ - - for (iMarker = 0; iMarker < nMarker; iMarker++) { - - if(config[iZone]->GetSolid_Wall(iMarker) || (config[iZone]->GetMarker_All_DV(iMarker) == YES )) { - - nVertex = geometry[iZone][INST_0][MESH_0]->GetnVertex(iMarker); - - for (iVertex = 0; iVertex < nVertex; iVertex++) { - iPoint = geometry[iZone][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); - Normal = geometry[iZone][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNormal(); - Prod = 0.0; - Area = 0.0; - for (iDim = 0; iDim < nDim; iDim++) { - - /*--- Retrieve the gradient calculated with discrete adjoint method ---*/ - - SensDim = geometry[iZone][INST_0][MESH_0]->GetSensitivity(iPoint, iDim); - - /*--- Calculate scalar product for projection onto the normal vector ---*/ - - Prod += Normal[iDim]*SensDim; - - Area += Normal[iDim]*Normal[iDim]; - } - - Area = sqrt(Area); - - /*--- Projection of the gradient onto the normal vector of the surface ---*/ - - Sens = Prod/Area; - - solver->GetNodes()->SetSolution(iPoint, 2*nDim, Sens); - - } - } + } + + /*--- Print the kind of objective function to screen. ---*/ + + for (std::map::const_iterator it = Objective_Map.begin(); it != Objective_Map.end(); ++it) { + if (it->second == config->GetKind_ObjFunc()) { + cout << it->first << " gradient : "; + if (iDV == 0) Gradient_file << it->first << " gradient " << endl; } - - output = new CBaselineOutput(config[iZone], nDim, solver); - output->PreprocessVolumeOutput(config[iZone]); - output->PreprocessHistoryOutput(config[iZone], false); - - /*--- Load the data --- */ - - output->Load_Data(geometry[iZone][INST_0][MESH_0], config[iZone], &solver); - - /*--- Set the surface filename ---*/ - - output->SetSurface_Filename(config[iZone]->GetSurfSens_FileName()); - - /*--- Set the volume filename ---*/ - - output->SetVolume_Filename(config[iZone]->GetVolSens_FileName()); - - /*--- Write to file ---*/ - - for (unsigned short iFile = 0; iFile < config[iZone]->GetnVolumeOutputFiles(); iFile++){ - auto FileFormat = config[iZone]->GetVolumeOutputFiles(); - if (FileFormat[iFile] != OUTPUT_TYPE::RESTART_ASCII && - FileFormat[iFile] != OUTPUT_TYPE::RESTART_BINARY && - FileFormat[iFile] != OUTPUT_TYPE::CSV) - output->WriteToFile(config[iZone], geometry[iZone][INST_0][MESH_0], FileFormat[iFile]); + } + + /*--- Print the gradient to file and screen. ---*/ + + for (iDV_Value = 0; iDV_Value < nDV_Value; iDV_Value++) { + cout << Gradient[iDV][iDV_Value]; + if (iDV_Value != nDV_Value - 1) { + cout << ", "; } - - /*--- Free memory ---*/ - - delete output; - delete solver; - + Gradient_file << Gradient[iDV][iDV_Value] << endl; + } + cout << endl; + cout << "-------------------------------------------------------------------------" << endl; } - + } } -void CDiscAdjDeformationDriver::DerivativeTreatment_MeshSensitivity(CGeometry *geometry, CConfig *config, CVolumetricMovement *grid_movement) { - - int rank = SU2_MPI::GetRank(); - - /*--- Warning if choosen smoothing mode is unsupported. - * This is the default option if the user has not specified a mode in the config file. ---*/ - if (config->GetSobMode() == ENUM_SOBOLEV_MODUS::NONE) { - SU2_MPI::Error("Unsupported operation modus for the Sobolev Smoothing Solver.", CURRENT_FUNCTION); +void CDiscAdjDeformationDriver::SetSensitivity_Files(CGeometry**** geometry, CConfig** config, + unsigned short val_nZone) { + unsigned short iMarker, iDim, nDim, nMarker, nVar; + unsigned long iVertex, iPoint, nPoint, nVertex; + su2double *Normal, Prod, Sens = 0.0, SensDim, Area; + + unsigned short iZone; + + CSolver* solver = nullptr; + COutput* output = nullptr; + + for (iZone = 0; iZone < val_nZone; iZone++) { + nPoint = geometry[iZone][INST_0][MESH_0]->GetnPoint(); + nDim = geometry[iZone][INST_0][MESH_0]->GetnDim(); + nMarker = config[iZone]->GetnMarker_All(); + nVar = nDim + 1; + + /*--- We create a baseline solver to easily merge the sensitivity information. ---*/ + + vector fieldnames; + fieldnames.push_back("\"Point\""); + fieldnames.push_back("\"x\""); + fieldnames.push_back("\"y\""); + if (nDim == 3) { + fieldnames.push_back("\"z\""); } - - /*-- Construct the smoothing solver and numerics ---*/ - std::unique_ptr solver(new CGradientSmoothingSolver(geometry, config)); - unsigned dim = (config->GetSmoothOnSurface() ? geometry->GetnDim() - 1 : geometry->GetnDim()); - std::unique_ptr numerics(new CGradSmoothing(dim, config)); - - if (rank == MASTER_NODE) cout << "Sobolev Smoothing of derivatives is active." << endl; - - /*--- Apply the smoothing procedure on the mesh level. ---*/ - if (config->GetSobMode() == ENUM_SOBOLEV_MODUS::MESH_LEVEL) { - if (rank == MASTER_NODE) cout << " working on mesh level" << endl; - - /*--- Work with the surface derivatives. ---*/ - if (config->GetSmoothOnSurface()) { - - /*--- Project to surface and then smooth on surface. ---*/ - grid_movement->SetVolume_Deformation(geometry, config, false, true); - - /*--- Get the sensitivities from the geometry class to work with. ---*/ - solver->ReadSensFromGeometry(geometry); - - /*--- Perform the smoothing procedure on all boundaries marked as DV marker. ---*/ - solver->ApplyGradientSmoothingSurface(geometry, numerics.get(), config); - - /*--- After appling the solver write the results back ---*/ - solver->WriteSensToGeometry(geometry); - - /*--- Work with the volume derivatives. ---*/ - } else { - - /*--- Get the sensitivities from the geometry class to work with. ---*/ - solver->ReadSensFromGeometry(geometry); - - solver->ApplyGradientSmoothingVolume(geometry, numerics.get(), config); - - /*--- After appling the solver write the results back ---*/ - solver->WriteSensToGeometry(geometry); - - /*--- Projection is applied after smoothing. ---*/ - grid_movement->SetVolume_Deformation(geometry, config, false, true); + fieldnames.push_back("\"Sensitivity_x\""); + fieldnames.push_back("\"Sensitivity_y\""); + if (nDim == 3) { + fieldnames.push_back("\"Sensitivity_z\""); + } + fieldnames.push_back("\"Surface_Sensitivity\""); + + solver = new CBaselineSolver(geometry[iZone][INST_0][MESH_0], config[iZone], nVar + nDim, fieldnames); + + for (iPoint = 0; iPoint < nPoint; iPoint++) { + for (iDim = 0; iDim < nDim; iDim++) { + solver->GetNodes()->SetSolution(iPoint, iDim, geometry[iZone][INST_0][MESH_0]->nodes->GetCoord(iPoint, iDim)); + solver->GetNodes()->SetSolution(iPoint, iDim + nDim, geometry[iZone][INST_0][MESH_0]->GetSensitivity(iPoint, iDim)); + } + } + + /*--- Compute the sensitivity in normal direction. ---*/ + + for (iMarker = 0; iMarker < nMarker; iMarker++) { + if (config[iZone]->GetSolid_Wall(iMarker) || (config[iZone]->GetMarker_All_DV(iMarker) == YES)) { + nVertex = geometry[iZone][INST_0][MESH_0]->GetnVertex(iMarker); + + for (iVertex = 0; iVertex < nVertex; iVertex++) { + iPoint = geometry[iZone][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); + Normal = geometry[iZone][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNormal(); + Prod = 0.0; + Area = 0.0; + for (iDim = 0; iDim < nDim; iDim++) { + /*--- Retrieve the gradient calculated with discrete adjoint method. ---*/ + + SensDim = geometry[iZone][INST_0][MESH_0]->GetSensitivity(iPoint, iDim); + + /*--- Calculate scalar product for projection onto the normal vector. ---*/ + + Prod += Normal[iDim] * SensDim; + + Area += Normal[iDim] * Normal[iDim]; + } + + Area = sqrt(Area); + + /*--- Projection of the gradient onto the normal vector of the surface. ---*/ + + Sens = Prod / Area; + + solver->GetNodes()->SetSolution(iPoint, 2 * nDim, Sens); } - + } } - -} -void CDiscAdjDeformationDriver::DerivativeTreatment_Gradient(CGeometry *geometry, CConfig *config, CVolumetricMovement* grid_movement, CSurfaceMovement *surface_movement, su2double** Gradient) { - - int rank = SU2_MPI::GetRank(); - - /*--- Error if choosen smoothing mode is unsupported. - * This is the default option if the user has not specified a mode in the config file. ---*/ - if (config->GetSobMode() == ENUM_SOBOLEV_MODUS::NONE) { - SU2_MPI::Error("Unsupported operation modus for the Sobolev Smoothing Solver.", CURRENT_FUNCTION); + output = new CBaselineOutput(config[iZone], nDim, solver); + output->PreprocessVolumeOutput(config[iZone]); + output->PreprocessHistoryOutput(config[iZone], false); + + /*--- Load the data. --- */ + + output->Load_Data(geometry[iZone][INST_0][MESH_0], config[iZone], &solver); + + /*--- Set the surface filename. ---*/ + + output->SetSurface_Filename(config[iZone]->GetSurfSens_FileName()); + + /*--- Set the volume filename. ---*/ + + output->SetVolume_Filename(config[iZone]->GetVolSens_FileName()); + + /*--- Write to file. ---*/ + + for (unsigned short iFile = 0; iFile < config[iZone]->GetnVolumeOutputFiles(); iFile++) { + auto FileFormat = config[iZone]->GetVolumeOutputFiles(); + if (FileFormat[iFile] != OUTPUT_TYPE::RESTART_ASCII && FileFormat[iFile] != OUTPUT_TYPE::RESTART_BINARY && + FileFormat[iFile] != OUTPUT_TYPE::CSV) + output->WriteToFile(config[iZone], geometry[iZone][INST_0][MESH_0], FileFormat[iFile]); } - - /*-- Construct the smoothing solver and numerics ---*/ - std::unique_ptr solver(new CGradientSmoothingSolver(geometry, config)); - unsigned dim = (config->GetSmoothOnSurface() ? geometry->GetnDim() - 1 : geometry->GetnDim()); - std::unique_ptr numerics(new CGradSmoothing(dim, config)); - - if (rank == MASTER_NODE) cout << "Sobolev Smoothing of derivatives is active." << endl; - - /*--- Get the sensitivities from the geometry class to work with. ---*/ - solver->ReadSensFromGeometry(geometry); - - /*--- Apply the smoothing procedure on the DV level. ---*/ - if (config->GetSobMode() == ENUM_SOBOLEV_MODUS::PARAM_LEVEL_COMPLETE) { - solver->ApplyGradientSmoothingDV(geometry, numerics.get(), surface_movement, grid_movement, config, Gradient); - - /*--- If smoothing already took place on the mesh level, or none is requested, just do standard projection. ---*/ - } else if (config->GetSobMode() == ENUM_SOBOLEV_MODUS::ONLY_GRAD || - config->GetSobMode() == ENUM_SOBOLEV_MODUS::MESH_LEVEL) { - solver->RecordTapeAndCalculateOriginalGradient(geometry, surface_movement, grid_movement, config, Gradient); + + /*--- Free memory. ---*/ + + delete output; + delete solver; + } +} + +void CDiscAdjDeformationDriver::DerivativeTreatment_MeshSensitivity(CGeometry* geometry, CConfig* config, + CVolumetricMovement* grid_movement) { + int rank = SU2_MPI::GetRank(); + + /*--- Warning if chosen smoothing mode is unsupported. + * This is the default option if the user has not specified a mode in the config file. ---*/ + + if (config->GetSobMode() == ENUM_SOBOLEV_MODUS::NONE) { + SU2_MPI::Error("Unsupported operation modus for the Sobolev Smoothing Solver.", CURRENT_FUNCTION); + } + + /*-- Construct the smoothing solver and numerics. ---*/ + + std::unique_ptr solver(new CGradientSmoothingSolver(geometry, config)); + unsigned dim = (config->GetSmoothOnSurface() ? geometry->GetnDim() - 1 : geometry->GetnDim()); + std::unique_ptr numerics(new CGradSmoothing(dim, config)); + + if (rank == MASTER_NODE) cout << "Sobolev Smoothing of derivatives is active." << endl; + + /*--- Apply the smoothing procedure on the mesh level. ---*/ + + if (config->GetSobMode() == ENUM_SOBOLEV_MODUS::MESH_LEVEL) { + if (rank == MASTER_NODE) cout << " working on mesh level" << endl; + + /*--- Work with the surface derivatives. ---*/ + if (config->GetSmoothOnSurface()) { + /*--- Project to surface and then smooth on surface. ---*/ + + grid_movement->SetVolume_Deformation(geometry, config, false, true); + + /*--- Get the sensitivities from the geometry class to work with. ---*/ + + solver->ReadSensFromGeometry(geometry); + + /*--- Perform the smoothing procedure on all boundaries marked as DV marker. ---*/ + + solver->ApplyGradientSmoothingSurface(geometry, numerics.get(), config); + + /*--- After applying the solver write the results back. ---*/ + + solver->WriteSensToGeometry(geometry); + + /*--- Work with the volume derivatives. ---*/ + } else { + /*--- Get the sensitivities from the geometry class to work with. ---*/ + + solver->ReadSensFromGeometry(geometry); + + solver->ApplyGradientSmoothingVolume(geometry, numerics.get(), config); + + /*--- After applying the solver write the results back. ---*/ + + solver->WriteSensToGeometry(geometry); + + /*--- Projection is applied after smoothing. ---*/ + + grid_movement->SetVolume_Deformation(geometry, config, false, true); } - + } +} + +void CDiscAdjDeformationDriver::DerivativeTreatment_Gradient(CGeometry* geometry, CConfig* config, + CVolumetricMovement* grid_movement, + CSurfaceMovement* surface_movement, su2double** Gradient) { + int rank = SU2_MPI::GetRank(); + + /*--- Error if chosen smoothing mode is unsupported. + * This is the default option if the user has not specified a mode in the config file. ---*/ + + if (config->GetSobMode() == ENUM_SOBOLEV_MODUS::NONE) { + SU2_MPI::Error("Unsupported operation modus for the Sobolev Smoothing Solver.", CURRENT_FUNCTION); + } + + /*-- Construct the smoothing solver and numerics. ---*/ + + std::unique_ptr solver(new CGradientSmoothingSolver(geometry, config)); + unsigned dim = (config->GetSmoothOnSurface() ? geometry->GetnDim() - 1 : geometry->GetnDim()); + std::unique_ptr numerics(new CGradSmoothing(dim, config)); + + if (rank == MASTER_NODE) cout << "Sobolev Smoothing of derivatives is active." << endl; + + /*--- Get the sensitivities from the geometry class to work with. ---*/ + + solver->ReadSensFromGeometry(geometry); + + /*--- Apply the smoothing procedure on the DV level. ---*/ + if (config->GetSobMode() == ENUM_SOBOLEV_MODUS::PARAM_LEVEL_COMPLETE) { + solver->ApplyGradientSmoothingDV(geometry, numerics.get(), surface_movement, grid_movement, config, Gradient); + + /*--- If smoothing already took place on the mesh level, or none is requested, just do standard projection. ---*/ + } else if (config->GetSobMode() == ENUM_SOBOLEV_MODUS::ONLY_GRAD || + config->GetSobMode() == ENUM_SOBOLEV_MODUS::MESH_LEVEL) { + solver->RecordTapeAndCalculateOriginalGradient(geometry, surface_movement, grid_movement, config, Gradient); + } } From 30ea6c4de6e9a4faf22f37bd3c9f7ed2e7f2a6d5 Mon Sep 17 00:00:00 2001 From: patelha57 Date: Thu, 8 Dec 2022 20:31:42 -0800 Subject: [PATCH 31/68] Update CDriverBase --- Common/include/drivers/CDriverBase.hpp | 1097 +++++++++-------- Common/src/drivers/CDriverBase.cpp | 1537 ++++++++++++++++-------- 2 files changed, 1645 insertions(+), 989 deletions(-) diff --git a/Common/include/drivers/CDriverBase.hpp b/Common/include/drivers/CDriverBase.hpp index 1fa0d011ca2..b5804091ce3 100644 --- a/Common/include/drivers/CDriverBase.hpp +++ b/Common/include/drivers/CDriverBase.hpp @@ -27,499 +27,614 @@ #pragma once -#include "../CConfig.hpp" #include "../../../SU2_CFD/include/numerics/CNumerics.hpp" -#include "../../../SU2_CFD/include/solvers/CSolver.hpp" #include "../../../SU2_CFD/include/output/COutput.hpp" +#include "../../../SU2_CFD/include/solvers/CSolver.hpp" +#include "../CConfig.hpp" class CDriverBase { - -protected: - - int rank, /*!< \brief MPI Rank. */ - size; /*!< \brief MPI Size. */ - char* config_file_name; /*!< \brief Configuration file name of the problem.*/ - - su2double StartTime, /*!< \brief Start point of the timer for performance benchmarking.*/ - StopTime, /*!< \brief Stop point of the timer for performance benchmarking.*/ - UsedTimePreproc, /*!< \brief Elapsed time between Start and Stop point of the timer for tracking preprocessing phase.*/ - UsedTimeCompute, /*!< \brief Elapsed time between Start and Stop point of the timer for tracking compute phase.*/ - UsedTime; /*!< \brief Elapsed time between Start and Stop point of the timer.*/ - - unsigned long TimeIter; - - unsigned short iMesh, /*!< \brief Iterator on mesh levels.*/ - iZone, /*!< \brief Iterator on zones.*/ - nZone, /*!< \brief Total number of zones in the problem. */ - nDim, /*!< \brief Number of dimensions.*/ - iInst, /*!< \brief Iterator on instance levels.*/ - *nInst, /*!< \brief Total number of instances in the problem (per zone). */ - **interface_types; /*!< \brief Type of coupling between the distinct (physical) zones.*/ - - CConfig *driver_config; /*!< \brief Definition of the driver configuration. */ - COutput *driver_output; /*!< \brief Definition of the driver output. */ - - CConfig **config_container; /*!< \brief Definition of the particular problem. */ - COutput **output_container; /*!< \brief Pointer to the COutput class. */ - CGeometry ****geometry_container; /*!< \brief Geometrical definition of the problem. */ - CSolver *****solver_container; /*!< \brief Container vector with all the solutions. */ - CNumerics ******numerics_container; /*!< \brief Description of the numerical method (the way in which the equations are solved). */ - CSurfaceMovement **surface_movement; /*!< \brief Surface movement classes of the problem. */ - CVolumetricMovement ***grid_movement; /*!< \brief Volume grid movement classes of the problem. */ - CFreeFormDefBox*** FFDBox; /*!< \brief FFD FFDBoxes of the problem. */ - - CConfig *main_config; /*!< \brief Reference to the base (i.e. ZONE 0) configuration (used in the driver API). */ - CGeometry *main_geometry; /*!< \brief Reference to the base (i.E. ZONE, INST, MESH 0) geometry (used in the driver API). */ - -public: - - /*! - * \brief Constructor of the class. - * \param[in] confFile - Configuration file name. - * \param[in] val_nZone - Total number of zones. - * \param[in] MPICommunicator - MPI communicator for SU2. - */ - CDriverBase(char* confFile, unsigned short val_nZone, SU2_Comm MPICommunicator); - - /*! - * \brief Destructor of the class. - */ - virtual ~CDriverBase(void); - - /*! - * \brief A virtual member. - */ - virtual void Preprocessing() {}; - - /*! - * \brief A virtual member. - */ - virtual void Run() {}; - - /*! - * \brief A virtual member. - */ - virtual void Update() {}; - - /*! - * \brief A virtual member. - */ - virtual void Update_Legacy() {}; - - /*! - * \brief A virtual member. - */ - virtual void Output() {}; - - /*! - * \brief A virtual member. - */ - virtual void Postprocessing() {}; - /*! - * \brief Get the number of markers in the mesh. - * \return Number of markers. - */ - unsigned short GetNumberMarkers() const; - - /*! - * \brief Get all the boundary markers tags with their associated indices. - * \return List of boundary markers tags with their indices. - */ - map GetMarkerIndices() const; - - /*! - * \brief Get all the boundary markers tags with their associated types. - * \return List of boundary markers tags with their types. - */ - map GetMarkerTypes() const; - - /*! - * \brief Get all the boundary marker tags. - * \return List of boundary markers tags. - */ - vector GetMarkerTags() const; - - /*! - * \brief Get all the deformable boundary marker tags. - * \return List of deformable boundary markers tags. - */ - vector GetDeformableMarkerTags() const; - - /*! - * \brief Get the number of dimensions of the mesh. - * \return Number of dimensions. - */ - unsigned long GetNumberDimensions() const; - - /*! - * \brief Get the number of elements in the mesh. - * \return Number of elements. - */ - unsigned long GetNumberElements() const; - - /*! - * \brief Get the number of elements in the marker. - * \param[in] iMarker - Marker index. - * \return Number of elements. - */ - unsigned long GetNumberMarkerElements(unsigned short iMarker) const; - - /*! - * \brief Get the global IDs of the mesh elements. - * \return Global element IDs. - */ - vector GetElementIDs() const; - - /*! - * \brief Get the global ID of a mesh element. - * \param[in] iElem - Mesh element index. - * \return Global element ID. - */ - unsigned long GetElementIDs(unsigned long iElem) const; - - /*! - * \brief Get the global IDs of the marker elements. - * \param[in] iMarker - Marker index. - * \return Global element IDs. - */ - vector GetMarkerElementIDs(unsigned short iMarker) const; - - /*! - * \brief Get the global IDs of a marker element. - * \param[in] iMarker - Marker index. - * \param[in] iBound - Marker element index. - * \return Global element ID. - */ - unsigned long GetMarkerElementIDs(unsigned short iMarker, unsigned long iBound) const; - - /*! - * \brief Get the table of vertex IDs belonging to the mesh elements. - * \return Element connectivities (nElem, nNode) - */ - vector> GetElementConnectivities() const; - - /*! - * \brief Get the row of vertex IDs belonging to a mesh element. - * \param[in] iElem - Mesh element index. - * \return Element connectivity (nNode) - */ - vector GetElementConnectivities(unsigned long iElem) const; - - /*! - * \brief Get the table of vertex IDs belonging to the marker elements. - * \param[in] iMarker - Marker index. - * \return Element connectivities (nBound, nNode). - */ - vector> GetMarkerElementConnectivities(unsigned short iMarker) const; - - /*! - * \brief Get the row of vertex IDs belonging to a marker element. - * \param[in] iMarker - Marker index. - * \param[in] iBound - Marker element index. - * \return Element connectivity (nNode). - */ - vector GetMarkerElementConnectivities(unsigned short iMarker, unsigned long iBound) const; - - /*! - * \brief Get the number of vertices in the mesh. - * \return Number of vertices. - */ - unsigned long GetNumberVertices() const; - - /*! - * \brief Get the number of vertices in the marker. - * \param[in] iMarker - Marker index. - * \return Number of vertices. - */ - unsigned long GetNumberMarkerVertices(unsigned short iMarker) const; - - /*! - * \brief Get the number of halo vertices in the mesh. - * \return Number of vertices. - */ - unsigned long GetNumberHaloVertices() const; - - /*! - * \brief Get the number of halo vertices in the marker. - * \param[in] iMarker - Marker index. - * \return Number of vertices. - */ - unsigned long GetNumberMarkerHaloVertices(unsigned short iMarker) const; - - /*! - * \brief Get the mesh vertex indices of the marker vertices. - * \param[in] iMarker - Marker index. - * \return Mesh vertex indices. - */ - vector GetMarkerVertexIndices(unsigned short iMarker) const; - - /*! - * \brief Get the mesh vertex index of a marker vertex. - * \param[in] iMarker - Marker index. - * \param[in] iVertex - Marker vertex index. - * \return Mesh vertex index. - */ - unsigned long GetMarkerVertexIndices(unsigned short iMarker, unsigned long iVertex) const; - - /*! - * \brief Get the global IDs of the mesh vertices. - * \return Global vertex IDs. - */ - vector GetVertexIDs() const; - - /*! - * \brief Get the global ID of a mesh vertex. - * \param[in] iPoint - Mesh vertex index. - * \return Global vertex ID. - */ - unsigned long GetVertexIDs(unsigned long iPoint) const; - - /*! - * \brief Get the global IDs of the marker vertices. - * \param[in] iMarker - Marker index. - * \return Global vertex IDs. - */ - vector GetMarkerVertexIDs(unsigned short iMarker) const; - - /*! - * \brief Get the global ID of a marker vertex. - * \param[in] iMarker - Marker index. - * \param[in] iVertex - Marker vertex index. - * \return Global vertex ID. - */ - unsigned long GetMarkerVertexIDs(unsigned short iMarker, unsigned long iVertex) const; - - /*! - * \brief Get the halo flags of the mesh vertices. - * \return Vertex domain flags. - */ - vector GetDomain() const; - - /*! - * \brief Get the halo flag of a mesh vertex. - * \param[in] iPoint - Mesh vertex index. - * \return Vertex domain flag. - */ - bool GetDomain(unsigned long iPoint) const; - - /*! - * \brief Get the halo flags of the marker vertices. - * \param[in] iMarker - Marker index. - * \return Vertex domain flags. - */ - vector GetMarkerDomain(unsigned short iMarker) const; - - /*! - * \brief Get the halo flag of a marker vertex. - * \param[in] iMarker - Marker index. - * \param[in] iVertex - Marker vertex index. - * \return Vertex domain flag. - */ - bool GetMarkerDomain(unsigned short iMarker, unsigned long iVertex) const; - - /*! - * \brief Get the initial (un-deformed) coordinates of the mesh vertices. - * \return Initial vertex coordinates (nPoint, nDim). - */ - vector> GetInitialCoordinates() const; - - /*! - * \brief Get the initial (un-deformed) coordinates of a mesh vertex. - * \param[in] iPoint - Mesh vertex index. - * \return Initial vertex coordinates (nDim). - */ - vector GetInitialCoordinates(unsigned long iPoint) const; - - /*! - * \brief Get the initial (un-deformed) coordinates of the marker vertices. - * \param[in] iMarker - Marker index. - * \return Initial vertex coordinates (nVertex, nDim). - */ - vector> GetMarkerInitialCoordinates(unsigned short iMarker) const; - - /*! - * \brief Get the initial (un-deformed) coordinates of a marker vertex. - * \param[in] iMarker - Marker index. - * \param[in] iVertex - Marker vertex index. - * \return Initial vertex coordinates (nDim). - */ - vector GetMarkerInitialCoordinates(unsigned short iMarker, unsigned long iVertex) const; - - /*! - * \brief Get the coordinates of the mesh vertices. - * \return Vertex coordinates (nPoint, nDim). - */ - vector> GetCoordinates() const; - - /*! - * \brief Get the coordinates of a mesh vertex. - * \param[in] iPoint - Mesh vertex index. - * \return Vertex coordinates (nDim). - */ - vector GetCoordinates(unsigned long iPoint) const; - - /*! - * \brief Get the coordinates of the marker vertices. - * \param[in] iMarker - Marker index. - * \return Vertex coordinates (nVertex, nDim). - */ - vector> GetMarkerCoordinates(unsigned short iMarker) const; - - /*! - * \brief Get the coordinates of a marker vertex. - * \param[in] iMarker - Marker index. - * \param[in] iVertex - Marker vertex index. - * \return Vertex coordinates (nDim). - */ - vector GetMarkerCoordinates(unsigned short iMarker, unsigned long iVertex) const; - - /*! - * \brief Set the coordinates of the mesh vertices. - * \param[in] values - Vertex coordinates (nPoint, nDim). - */ - void SetCoordinates(vector> values); - - /*! - * \brief Set the coordinates of a mesh vertex. - * \param[in] iPoint - Mesh vertex index. - * \param[in] values - Vertex coordinates (nDim). - */ - void SetCoordinates(unsigned long iPoint, vector values); - - /*! - * \brief Set the coordinates of the marker vertices. - * \param[in] iMarker - Marker index. - * \param[in] values - Vertex coordinates (nVertex, nDim). - */ - void SetMarkerCoordinates(unsigned short iMarker, vector> values); - - /*! - * \brief Set the coordinates of a marker vertex. - * \param[in] iMarker - Marker index. - * \param[in] iVertex - Marker vertex index. - * \param[in] values - Vertex coordinates (nDim). - */ - void SetMarkerCoordinates(unsigned short iMarker, unsigned long iVertex, vector values); - - /*! - * \brief Get the displacements of the marker vertices. - * \param[in] iMarker - Marker index. - * \return Vertex displacements (nVertex, nDim). - */ - vector> GetMarkerDisplacements(unsigned short iMarker) const; - - /*! - * \brief Get the displacements of a marker vertex. - * \param[in] iMarker - Marker index. - * \param[in] iVertex - Marker vertex index. - * \return Vertex displacements (nDim). - */ - vector GetMarkerDisplacements(unsigned short iMarker, unsigned long iVertex) const; - - /*! - * \brief Set the displacements of the marker vertices. - * \param[in] iMarker - Marker index. - * \param[in] values - Vertex displacements (nVertex, nDim). - */ - void SetMarkerDisplacements(unsigned short iMarker, vector> values); - - /*! - * \brief Set the displacements of a marker vertex. - * \param[in] iMarker - Marker index. - * \param[in] iVertex - Marker vertex index. - * \param[in] values - Vertex displacements (nDim). - */ - void SetMarkerDisplacements(unsigned short iMarker, unsigned long iVertex, vector values); - - /*! - * \brief Get the velocities of the marker vertices. - * \param[in] iMarker - Marker index. - * \return Vertex velocities (nVertex, nDim). - */ - vector> GetMarkerVelocities(unsigned short iMarker) const; - - /*! - * \brief Get the velocities of a marker vertex. - * \param[in] iMarker - Marker index. - * \param[in] iVertex - Marker vertex index. - * \return Vertex velocities (nDim). - */ - vector GetMarkerVelocities(unsigned short iMarker, unsigned long iVertex) const; - - /*! - * \brief Set the velocities of the marker vertices. - * \param[in] iMarker - Marker index. - * \param[in] values - Vertex velocities (nVertex, nDim). - */ - void SetMarkerVelocities(unsigned short iMarker, vector> values); - - /*! - * \brief Set the velocities of a marker vertex. - * \param[in] iMarker - Marker index. - * \param[in] iVertex - Marker vertex index. - * \param[in] values - Vertex velocities (nDim). - */ - void SetMarkerVelocities(unsigned short iMarker, unsigned long iVertex, vector values); - - /*! - * \brief Get the normal vectors at the marker vertices. - * \param[in] iMarker - Marker index. - * \param[in] normalize - If true, the unit (i.e. normalized) normal vector is returned. - * \return Normal vector at the vertex (nVertex, nDim). - */ - vector> GetMarkerVertexNormals(unsigned short iMarker, bool normalize = false) const; - - /*! - * \brief Get the normal vectors at a marker vertex. - * \param[in] iMarker - Marker index. - * \param[in] iVertex - Marker vertex index. - * \param[in] normalize - If true, the unit (i.e. normalized) normal vector is returned. - * \return Normal vector at the vertex (nDim). - */ - vector GetMarkerVertexNormals(unsigned short iMarker, unsigned long iVertex, bool normalize = false) const; - - /*! - * \brief Communicate the boundary mesh displacements in a python call - */ - void CommunicateMeshDisplacements(void); - -protected: - - /*! - * \brief Initialize Containers - */ - void SetContainers_Null(); - - /*! - * \brief Read in the config and mesh files. - */ - void Input_Preprocessing(CConfig **&config, CConfig *&driver_config); - - /*! - * \brief Construction of the edge-based data structure and the multigrid structure. - */ - void Geometrical_Preprocessing(CConfig *config, CGeometry **&geometry, bool dummy); - - /*! - * \brief Definition and allocation of all solution classes. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void Solver_Preprocessing(CConfig *config, CGeometry **geometry, CSolver ***&solver); - - /*! - * \brief Definition and allocation of all solver classes. - * \param[in] numerics_container - Description of the numerical method (the way in which the equations are solved). - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - void Numerics_Preprocessing(CConfig *config, CGeometry **geometry, CSolver ***solver, CNumerics ****&numerics) const; - - /*! - * \brief Preprocess the output container. - */ - void Output_Preprocessing(CConfig **config, CConfig *driver_config, COutput **&output_container, COutput *&driver_output); - + protected: + int rank, /*!< \brief MPI Rank. */ + size; /*!< \brief MPI Size. */ + char* config_file_name; /*!< \brief Configuration file name of the problem. */ + + su2double StartTime, /*!< \brief Start point of the timer for performance benchmarking. */ + StopTime, /*!< \brief Stop point of the timer for performance benchmarking. */ + UsedTimePreproc, /*!< \brief Elapsed time between Start and Stop point of the timer for tracking preprocessing + phase. */ + UsedTimeCompute, /*!< \brief Elapsed time between Start and Stop point of the timer for tracking compute phase. */ + UsedTime; /*!< \brief Elapsed time between Start and Stop point of the timer. */ + + unsigned long TimeIter; + + unsigned short iMesh, /*!< \brief Iterator on mesh levels. */ + iZone, /*!< \brief Iterator on zones. */ + nZone, /*!< \brief Total number of zones in the problem. */ + nDim, /*!< \brief Number of dimensions. */ + iInst, /*!< \brief Iterator on instance levels. */ + *nInst, /*!< \brief Total number of instances in the problem (per zone). */ + **interface_types; /*!< \brief Type of coupling between the distinct (physical) zones. */ + + CConfig* driver_config; /*!< \brief Definition of the driver configuration. */ + COutput* driver_output; /*!< \brief Definition of the driver output. */ + + CConfig** config_container; /*!< \brief Definition of the particular problem. */ + COutput** output_container; /*!< \brief Pointer to the COutput class. */ + CGeometry**** geometry_container; /*!< \brief Geometrical definition of the problem. */ + CSolver***** solver_container; /*!< \brief Container vector with all the solutions. */ + CNumerics****** numerics_container; /*!< \brief Description of the numerical method (the way in which the equations + are solved). */ + CSurfaceMovement** surface_movement; /*!< \brief Surface movement classes of the problem. */ + CVolumetricMovement*** grid_movement; /*!< \brief Volume grid movement classes of the problem. */ + CFreeFormDefBox*** FFDBox; /*!< \brief FFD FFDBoxes of the problem. */ + + CConfig* main_config; /*!< \brief Reference to base (i.e. ZONE 0) configuration (used in driver API). */ + CGeometry* main_geometry; /*!< \brief Reference to base (i.e. ZONE, INST, MESH 0) geometry (used in driver API). */ + + public: + /*! + * \brief Constructor of the class. + * \param[in] confFile - Configuration file name. + * \param[in] val_nZone - Total number of zones. + * \param[in] MPICommunicator - MPI communicator for SU2. + */ + CDriverBase(char* confFile, unsigned short val_nZone, SU2_Comm MPICommunicator); + + /*! + * \brief Destructor of the class. + */ + virtual ~CDriverBase(void); + + /*! + * \brief A virtual member. + */ + virtual void Preprocessing(){}; + + /*! + * \brief A virtual member. + */ + virtual void Run(){}; + + /*! + * \brief A virtual member. + */ + virtual void Update(){}; + + /*! + * \brief A virtual member. + */ + virtual void Update_Legacy(){}; + + /*! + * \brief A virtual member. + */ + virtual void Output(){}; + + /*! + * \brief A virtual member. + */ + virtual void Postprocessing(){}; + + /*! + * \brief Get the number of design variables. + * \return Number of design variables. + */ + unsigned short GetNumberDesignVariables() const; + + /*! + * \brief Get the number of FFD boxes. + * \return Number of FFD boxes. + */ + unsigned short GetNumberFFDBoxes() const; + + /*! + * \brief Get the number of FFD box corner points. + * \param[in] iFFDBox - FFD box index. + * \return Number of FFD box corner points. + */ + unsigned short GetNumberFFDBoxCornerPoints(unsigned short iFFDBox) const; + + /*! + * \brief Get the number of FFD box control points. + * \param[in] iFFDBox - FFD box index. + * \return Number of FFD box control points. + */ + unsigned short GetNumberFFDBoxControlPoints(unsigned short iFFDBox) const; + + /*! + * \brief Get the number of FFD box surface points. + * \param[in] iFFDBox - FFD box index. + * \return Number of FFD box surface points. + */ + unsigned long GetNumberFFDBoxSurfacePoints(unsigned short iFFDBox) const; + + /*! + * \brief Get the FFD box marker IDs. + * \param[in] iFFDBox - FFD box index. + * \return FFD box marker IDs. + */ + vector GetFFDBoxMarkerIDs(unsigned short iFFDBox) const; + + /*! + * \brief Get the FFD box vertex IDs. + * \param[in] iFFDBox - FFD box index. + * \return FFD box vertex IDs. + */ + vector GetFFDBoxVertexIDs(unsigned short iFFDBox) const; + + /*! + * \brief Get the FFD box grid point IDs. + * \param[in] iFFDBox - FFD box index. + * \return FFD box grid point IDs. + */ + vector GetFFDBoxPointIDs(unsigned short iFFDBox) const; + + /*! + * \brief Get the FFD box corner coordinates. + * \param[in] iFFDBox - FFD box index. + * \return FFD box corner coordinates. + */ + vector> GetFFDBoxCornerCoordinates(unsigned short iFFDBox) const; + + /*! + * \brief Get the FFD box control point coordinates. + * \param[in] iFFDBox - FFD box index. + * \return FFD box control point coordinates. + */ + vector> GetFFDBoxControlPointCoordinates(unsigned short iFFDBox) const; + + /*! + * \brief Get the FFD box control point coordinates. + * \param[in] iFFDBox - FFD box index. + * \param[in] iOrder - Local i-index of the control point. + * \param[in] jOrder - Local j-index of the control point. + * \param[in] kOrder - Local k-index of the control point. + * \return FFD box control point coordinates. + */ + vector GetFFDBoxControlPointCoordinates(unsigned short iFFDBox, unsigned int iOrder, + unsigned int jOrder, unsigned int kOrder) const; + + /*! + * \brief Get the FFD box surface coordinates. + * \param[in] iFFDBox - FFD box index. + * \param[in] parametric - Boolean to indicate if parametric coordinates should be returned. + * \return FFD box surface coordinates. + */ + vector> GetFFDBoxSurfaceCoordinates(unsigned short iFFDBox, bool parametric = false) const; + + /*! + * \brief Get the FFD box surface coordinates. + * \param[in] iFFDBox - FFD box index. + * \param[in] iPoint - FFD surface point index. + * \param[in] parametric - Boolean to indicate if parametric coordinates should be returned. + * \return FFD box surface coordinates. + */ + vector GetFFDBoxSurfaceCoordinates(unsigned short iFFDBox, unsigned long iPoint, + bool parametric = false) const; + + /*! + * \brief Get the number of markers in the mesh. + * \return Number of markers. + */ + unsigned short GetNumberMarkers() const; + + /*! + * \brief Get all the boundary markers tags with their associated indices. + * \return List of boundary markers tags with their indices. + */ + map GetMarkerIndices() const; + + /*! + * \brief Get all the boundary markers tags with their associated types. + * \return List of boundary markers tags with their types. + */ + map GetMarkerTypes() const; + + /*! + * \brief Get all the boundary marker tags. + * \return List of boundary markers tags. + */ + vector GetMarkerTags() const; + + /*! + * \brief Get all the deformable boundary marker tags. + * \return List of deformable boundary markers tags. + */ + vector GetDeformableMarkerTags() const; + + /*! + * \brief Get the number of dimensions of the mesh. + * \return Number of dimensions. + */ + unsigned long GetNumberDimensions() const; + + /*! + * \brief Get the number of elements in the mesh. + * \return Number of elements. + */ + unsigned long GetNumberElements() const; + + /*! + * \brief Get the number of elements in the marker. + * \param[in] iMarker - Marker index. + * \return Number of elements. + */ + unsigned long GetNumberMarkerElements(unsigned short iMarker) const; + + /*! + * \brief Get the global IDs of the mesh elements. + * \return Global element IDs. + */ + vector GetElementIDs() const; + + /*! + * \brief Get the global ID of a mesh element. + * \param[in] iElem - Mesh element index. + * \return Global element ID. + */ + unsigned long GetElementIDs(unsigned long iElem) const; + + /*! + * \brief Get the global IDs of the marker elements. + * \param[in] iMarker - Marker index. + * \return Global element IDs. + */ + vector GetMarkerElementIDs(unsigned short iMarker) const; + + /*! + * \brief Get the global IDs of a marker element. + * \param[in] iMarker - Marker index. + * \param[in] iBound - Marker element index. + * \return Global element ID. + */ + unsigned long GetMarkerElementIDs(unsigned short iMarker, unsigned long iBound) const; + + /*! + * \brief Get the table of vertex IDs belonging to the mesh elements. + * \return Element connectivities (nElem, nNode) + */ + vector> GetElementConnectivities() const; + + /*! + * \brief Get the row of vertex IDs belonging to a mesh element. + * \param[in] iElem - Mesh element index. + * \return Element connectivity (nNode) + */ + vector GetElementConnectivities(unsigned long iElem) const; + + /*! + * \brief Get the table of vertex IDs belonging to the marker elements. + * \param[in] iMarker - Marker index. + * \return Element connectivities (nBound, nNode). + */ + vector> GetMarkerElementConnectivities(unsigned short iMarker) const; + + /*! + * \brief Get the row of vertex IDs belonging to a marker element. + * \param[in] iMarker - Marker index. + * \param[in] iBound - Marker element index. + * \return Element connectivity (nNode). + */ + vector GetMarkerElementConnectivities(unsigned short iMarker, unsigned long iBound) const; + + /*! + * \brief Get the number of vertices in the mesh. + * \return Number of vertices. + */ + unsigned long GetNumberVertices() const; + + /*! + * \brief Get the number of vertices in the marker. + * \param[in] iMarker - Marker index. + * \return Number of vertices. + */ + unsigned long GetNumberMarkerVertices(unsigned short iMarker) const; + + /*! + * \brief Get the number of halo vertices in the mesh. + * \return Number of vertices. + */ + unsigned long GetNumberHaloVertices() const; + + /*! + * \brief Get the number of halo vertices in the marker. + * \param[in] iMarker - Marker index. + * \return Number of vertices. + */ + unsigned long GetNumberMarkerHaloVertices(unsigned short iMarker) const; + + /*! + * \brief Get the mesh vertex indices of the marker vertices. + * \param[in] iMarker - Marker index. + * \return Mesh vertex indices. + */ + vector GetMarkerVertexIndices(unsigned short iMarker) const; + + /*! + * \brief Get the mesh vertex index of a marker vertex. + * \param[in] iMarker - Marker index. + * \param[in] iVertex - Marker vertex index. + * \return Mesh vertex index. + */ + unsigned long GetMarkerVertexIndices(unsigned short iMarker, unsigned long iVertex) const; + + /*! + * \brief Get the global IDs of the mesh vertices. + * \return Global vertex IDs. + */ + vector GetVertexIDs() const; + + /*! + * \brief Get the global ID of a mesh vertex. + * \param[in] iPoint - Mesh vertex index. + * \return Global vertex ID. + */ + unsigned long GetVertexIDs(unsigned long iPoint) const; + + /*! + * \brief Get the global IDs of the marker vertices. + * \param[in] iMarker - Marker index. + * \return Global vertex IDs. + */ + vector GetMarkerVertexIDs(unsigned short iMarker) const; + + /*! + * \brief Get the global ID of a marker vertex. + * \param[in] iMarker - Marker index. + * \param[in] iVertex - Marker vertex index. + * \return Global vertex ID. + */ + unsigned long GetMarkerVertexIDs(unsigned short iMarker, unsigned long iVertex) const; + + /*! + * \brief Get the halo flags of the mesh vertices. + * \return Vertex domain flags. + */ + vector GetDomain() const; + + /*! + * \brief Get the halo flag of a mesh vertex. + * \param[in] iPoint - Mesh vertex index. + * \return Vertex domain flag. + */ + bool GetDomain(unsigned long iPoint) const; + + /*! + * \brief Get the halo flags of the marker vertices. + * \param[in] iMarker - Marker index. + * \return Vertex domain flags. + */ + vector GetMarkerDomain(unsigned short iMarker) const; + + /*! + * \brief Get the halo flag of a marker vertex. + * \param[in] iMarker - Marker index. + * \param[in] iVertex - Marker vertex index. + * \return Vertex domain flag. + */ + bool GetMarkerDomain(unsigned short iMarker, unsigned long iVertex) const; + + /*! + * \brief Get the initial (un-deformed) coordinates of the mesh vertices. + * \return Initial vertex coordinates (nPoint, nDim). + */ + vector> GetInitialCoordinates() const; + + /*! + * \brief Get the initial (un-deformed) coordinates of a mesh vertex. + * \param[in] iPoint - Mesh vertex index. + * \return Initial vertex coordinates (nDim). + */ + vector GetInitialCoordinates(unsigned long iPoint) const; + + /*! + * \brief Get the initial (un-deformed) coordinates of the marker vertices. + * \param[in] iMarker - Marker index. + * \return Initial vertex coordinates (nVertex, nDim). + */ + vector> GetMarkerInitialCoordinates(unsigned short iMarker) const; + + /*! + * \brief Get the initial (un-deformed) coordinates of a marker vertex. + * \param[in] iMarker - Marker index. + * \param[in] iVertex - Marker vertex index. + * \return Initial vertex coordinates (nDim). + */ + vector GetMarkerInitialCoordinates(unsigned short iMarker, unsigned long iVertex) const; + + /*! + * \brief Get the coordinates of the mesh vertices. + * \return Vertex coordinates (nPoint, nDim). + */ + vector> GetCoordinates() const; + + /*! + * \brief Get the coordinates of a mesh vertex. + * \param[in] iPoint - Mesh vertex index. + * \return Vertex coordinates (nDim). + */ + vector GetCoordinates(unsigned long iPoint) const; + + /*! + * \brief Get the coordinates of the marker vertices. + * \param[in] iMarker - Marker index. + * \return Vertex coordinates (nVertex, nDim). + */ + vector> GetMarkerCoordinates(unsigned short iMarker) const; + + /*! + * \brief Get the coordinates of a marker vertex. + * \param[in] iMarker - Marker index. + * \param[in] iVertex - Marker vertex index. + * \return Vertex coordinates (nDim). + */ + vector GetMarkerCoordinates(unsigned short iMarker, unsigned long iVertex) const; + + /*! + * \brief Set the coordinates of the mesh vertices. + * \param[in] values - Vertex coordinates (nPoint, nDim). + */ + void SetCoordinates(vector> values); + + /*! + * \brief Set the coordinates of a mesh vertex. + * \param[in] iPoint - Mesh vertex index. + * \param[in] values - Vertex coordinates (nDim). + */ + void SetCoordinates(unsigned long iPoint, vector values); + + /*! + * \brief Set the coordinates of the marker vertices. + * \param[in] iMarker - Marker index. + * \param[in] values - Vertex coordinates (nVertex, nDim). + */ + void SetMarkerCoordinates(unsigned short iMarker, vector> values); + + /*! + * \brief Set the coordinates of a marker vertex. + * \param[in] iMarker - Marker index. + * \param[in] iVertex - Marker vertex index. + * \param[in] values - Vertex coordinates (nDim). + */ + void SetMarkerCoordinates(unsigned short iMarker, unsigned long iVertex, vector values); + + /*! + * \brief Get the displacements of the marker vertices. + * \param[in] iMarker - Marker index. + * \return Vertex displacements (nVertex, nDim). + */ + vector> GetMarkerDisplacements(unsigned short iMarker) const; + + /*! + * \brief Get the displacements of a marker vertex. + * \param[in] iMarker - Marker index. + * \param[in] iVertex - Marker vertex index. + * \return Vertex displacements (nDim). + */ + vector GetMarkerDisplacements(unsigned short iMarker, unsigned long iVertex) const; + + /*! + * \brief Set the displacements of the marker vertices. + * \param[in] iMarker - Marker index. + * \param[in] values - Vertex displacements (nVertex, nDim). + */ + void SetMarkerDisplacements(unsigned short iMarker, vector> values); + + /*! + * \brief Set the displacements of a marker vertex. + * \param[in] iMarker - Marker index. + * \param[in] iVertex - Marker vertex index. + * \param[in] values - Vertex displacements (nDim). + */ + void SetMarkerDisplacements(unsigned short iMarker, unsigned long iVertex, vector values); + + /*! + * \brief Get the velocities of the marker vertices. + * \param[in] iMarker - Marker index. + * \return Vertex velocities (nVertex, nDim). + */ + vector> GetMarkerVelocities(unsigned short iMarker) const; + + /*! + * \brief Get the velocities of a marker vertex. + * \param[in] iMarker - Marker index. + * \param[in] iVertex - Marker vertex index. + * \return Vertex velocities (nDim). + */ + vector GetMarkerVelocities(unsigned short iMarker, unsigned long iVertex) const; + + /*! + * \brief Set the velocities of the marker vertices. + * \param[in] iMarker - Marker index. + * \param[in] values - Vertex velocities (nVertex, nDim). + */ + void SetMarkerVelocities(unsigned short iMarker, vector> values); + + /*! + * \brief Set the velocities of a marker vertex. + * \param[in] iMarker - Marker index. + * \param[in] iVertex - Marker vertex index. + * \param[in] values - Vertex velocities (nDim). + */ + void SetMarkerVelocities(unsigned short iMarker, unsigned long iVertex, vector values); + + /*! + * \brief Get the normal vectors at the marker vertices. + * \param[in] iMarker - Marker index. + * \param[in] normalize - If true, the unit (i.e. normalized) normal vector is returned. + * \return Normal vector at the vertex (nVertex, nDim). + */ + vector> GetMarkerVertexNormals(unsigned short iMarker, bool normalize = false) const; + + /*! + * \brief Get the normal vectors at a marker vertex. + * \param[in] iMarker - Marker index. + * \param[in] iVertex - Marker vertex index. + * \param[in] normalize - If true, the unit (i.e. normalized) normal vector is returned. + * \return Normal vector at the vertex (nDim). + */ + vector GetMarkerVertexNormals(unsigned short iMarker, unsigned long iVertex, + bool normalize = false) const; + + /*! + * \brief Communicate the boundary mesh displacements. + */ + void CommunicateMeshDisplacements(void); + + protected: + /*! + * \brief Initialize Containers + */ + void SetContainers_Null(); + + /*! + * \brief Read in the config and mesh files. + * \param[in] config - Definition of the particular problem. + * \param[in] driver_config - Definition of the driver configuration. + */ + void Input_Preprocessing(CConfig**& config, CConfig*& driver_config); + + /*! + * \brief Construction of the edge-based data structure and the multi-grid structure. + * \param[in] config - Definition of the particular problem. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] dummy - Definition of the dummy driver. + */ + void Geometrical_Preprocessing(CConfig* config, CGeometry**& geometry, bool dummy); + + /*! + * \brief Definition and allocation of all solution classes. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void Solver_Preprocessing(CConfig* config, CGeometry** geometry, CSolver***& solver); + + /*! + * \brief Definition and allocation of all solver classes. + * \param[in] numerics_container - Description of the numerical method (the way in which the equations are solved). + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + void Numerics_Preprocessing(CConfig* config, CGeometry** geometry, CSolver*** solver, CNumerics****& numerics) const; + + /*! + * \brief Preprocess the output container. + * \param[in] config - Definition of the particular problem. + * \param[in] driver_config - Definition of the driver configuration. + * \param[in] output_container - Container vector with all the outputs. + * \param[in] driver_output - Definition of the driver output. + */ + void Output_Preprocessing(CConfig** config, CConfig* driver_config, COutput**& output_container, + COutput*& driver_output); + + /*! + * \brief Read the free form deformation box information from the input mesh file. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + * \param[in] FFDBox - Definition of the FFD boxes of the problem. + * \param[in] val_mesh_filename - Name of the input mesh file. + */ + void ReadFFDInfo(CGeometry* geometry, CConfig* config, CFreeFormDefBox** FFDBox, string val_mesh_filename); }; diff --git a/Common/src/drivers/CDriverBase.cpp b/Common/src/drivers/CDriverBase.cpp index b778a6ab99b..f0b75542b0b 100644 --- a/Common/src/drivers/CDriverBase.cpp +++ b/Common/src/drivers/CDriverBase.cpp @@ -32,717 +32,1258 @@ using namespace std; -CDriverBase::CDriverBase(char* confFile, unsigned short val_nZone, SU2_Comm MPICommunicator): -config_file_name(confFile), -StartTime(0.0), -StopTime(0.0), -UsedTime(0.0), -TimeIter(0), -nZone(val_nZone) -{ - +CDriverBase::CDriverBase(char* confFile, unsigned short val_nZone, SU2_Comm MPICommunicator) + : config_file_name(confFile), StartTime(0.0), StopTime(0.0), UsedTime(0.0), TimeIter(0), nZone(val_nZone) {} + +CDriverBase::~CDriverBase(void) {} + +void CDriverBase::SetContainers_Null() { + /*--- Create pointers to all the classes that may be used by drivers. In general, the pointers are instantiated + * down a hierarchy over all zones, multi-grid levels, equation sets, and equation terms as described in the comments + * below. ---*/ + + config_container = nullptr; + output_container = nullptr; + geometry_container = nullptr; + solver_container = nullptr; + numerics_container = nullptr; + + surface_movement = nullptr; + grid_movement = nullptr; + FFDBox = nullptr; + + config_container = new CConfig*[nZone](); + output_container = new COutput*[nZone](); + geometry_container = new CGeometry***[nZone](); + solver_container = new CSolver****[nZone](); + numerics_container = new CNumerics*****[nZone](); + surface_movement = new CSurfaceMovement*[nZone](); + grid_movement = new CVolumetricMovement**[nZone](); + FFDBox = new CFreeFormDefBox**[nZone](); + + nInst = new unsigned short[nZone]; + + for (iZone = 0; iZone < nZone; iZone++) { + nInst[iZone] = 1; + FFDBox[iZone] = new CFreeFormDefBox*[MAX_NUMBER_FFD]; + } + + driver_config = nullptr; + driver_output = nullptr; + + main_config = nullptr; + main_geometry = nullptr; +} + +unsigned short CDriverBase::GetNumberDesignVariables() const { return main_config->GetnDV(); } + +unsigned short CDriverBase::GetNumberFFDBoxes() const { return main_config->GetnFFDBox(); } + +unsigned short CDriverBase::GetNumberFFDBoxCornerPoints(unsigned short iFFDBox) const { + return FFDBox[ZONE_0][iFFDBox]->GetnCornerPoints(); } -CDriverBase::~CDriverBase(void) { - +unsigned short CDriverBase::GetNumberFFDBoxControlPoints(unsigned short iFFDBox) const { + return FFDBox[ZONE_0][iFFDBox]->GetnControlPoints(); } -void CDriverBase::SetContainers_Null() { - - /*--- Create pointers to all of the classes that may be used by drivers. In general, the pointers are instantiated down a - hierarchy over all zones, multigrid levels, equation sets, and equation - terms as described in the comments below. ---*/ - - config_container = nullptr; - output_container = nullptr; - geometry_container = nullptr; - solver_container = nullptr; - numerics_container = nullptr; - - surface_movement = nullptr; - grid_movement = nullptr; - FFDBox = nullptr; - - config_container = new CConfig*[nZone] (); - output_container = new COutput*[nZone] (); - geometry_container = new CGeometry***[nZone] (); - solver_container = new CSolver****[nZone] (); - numerics_container = new CNumerics*****[nZone] (); - surface_movement = new CSurfaceMovement*[nZone] (); - grid_movement = new CVolumetricMovement**[nZone] (); - FFDBox = new CFreeFormDefBox**[nZone] (); - - nInst = new unsigned short[nZone]; - - for (iZone = 0; iZone < nZone; iZone++) { - nInst[iZone] = 1; +unsigned long CDriverBase::GetNumberFFDBoxSurfacePoints(unsigned short iFFDBox) const { + return FFDBox[ZONE_0][iFFDBox]->GetnSurfacePoint(); +} + +vector CDriverBase::GetFFDBoxMarkerIDs(unsigned short iFFDBox) const { + vector values; + + for (auto iPoint = 0ul; iPoint < GetNumberFFDBoxSurfacePoints(iFFDBox); iPoint++) { + values.push_back(FFDBox[ZONE_0][iFFDBox]->Get_MarkerIndex(iPoint)); + } + return values; +} + +vector CDriverBase::GetFFDBoxVertexIDs(unsigned short iFFDBox) const { + vector values; + + for (auto iPoint = 0ul; iPoint < GetNumberFFDBoxSurfacePoints(iFFDBox); iPoint++) { + values.push_back(FFDBox[ZONE_0][iFFDBox]->Get_VertexIndex(iPoint)); + } + return values; +} + +vector CDriverBase::GetFFDBoxPointIDs(unsigned short iFFDBox) const { + vector values; + + for (auto iPoint = 0ul; iPoint < GetNumberFFDBoxSurfacePoints(iFFDBox); iPoint++) { + values.push_back(FFDBox[ZONE_0][iFFDBox]->Get_PointIndex(iPoint)); + } + return values; +} + +vector> CDriverBase::GetFFDBoxCornerCoordinates(unsigned short iFFDBox) const { + vector> values; + + for (auto iPoint = 0u; iPoint < GetNumberFFDBoxCornerPoints(iFFDBox); iPoint++) { + vector coords; + + const su2double* coord = FFDBox[ZONE_0][iFFDBox]->GetCoordCornerPoints(iPoint); + + for (auto iDim = 0u; iDim < nDim; iDim++) { + coords.push_back(SU2_TYPE::GetValue(coord[iDim])); + } + + values.push_back(coords); + } + + return values; +} + +vector> CDriverBase::GetFFDBoxControlPointCoordinates(unsigned short iFFDBox) const { + vector> values; + + for (auto iOrder = 0u; iOrder < FFDBox[ZONE_0][iFFDBox]->GetlOrder(); iOrder++) { + for (auto jOrder = 0u; jOrder < FFDBox[ZONE_0][iFFDBox]->GetmOrder(); jOrder++) { + for (auto kOrder = 0u; kOrder < FFDBox[ZONE_0][iFFDBox]->GetnOrder(); kOrder++) { + values.push_back(GetFFDBoxControlPointCoordinates(iFFDBox, iOrder, jOrder, kOrder)); + } } - - driver_config = nullptr; - driver_output = nullptr; + } - main_config = nullptr; - main_geometry = nullptr; + return values; } -unsigned short CDriverBase::GetNumberMarkers() const { - return main_config->GetnMarker_All(); +vector CDriverBase::GetFFDBoxControlPointCoordinates(unsigned short iFFDBox, unsigned int iOrder, + unsigned int jOrder, unsigned int kOrder) const { + vector values; + + const su2double* coord = FFDBox[ZONE_0][iFFDBox]->GetCoordControlPoints(iOrder, jOrder, kOrder); + + for (auto iDim = 0u; iDim < nDim; iDim++) { + values.push_back(SU2_TYPE::GetValue(coord[iDim])); + } + + return values; } +vector> CDriverBase::GetFFDBoxSurfaceCoordinates(unsigned short iFFDBox, bool parametric) const { + vector> values; + + for (auto iPoint = 0ul; iPoint < GetNumberFFDBoxSurfacePoints(iFFDBox); iPoint++) { + values.push_back(GetFFDBoxSurfaceCoordinates(iFFDBox, iPoint, parametric)); + } + + return values; +} + +vector CDriverBase::GetFFDBoxSurfaceCoordinates(unsigned short iFFDBox, unsigned long iPoint, + bool parametric) const { + vector values; + const su2double* coord; + + if (parametric) { + coord = FFDBox[ZONE_0][iFFDBox]->Get_ParametricCoord(iPoint); + } else { + coord = FFDBox[ZONE_0][iFFDBox]->Get_CartesianCoord(iPoint); + } + + for (auto iDim = 0u; iDim < nDim; iDim++) { + values.push_back(SU2_TYPE::GetValue(coord[iDim])); + } + + return values; +} + +unsigned short CDriverBase::GetNumberMarkers() const { return main_config->GetnMarker_All(); } + map CDriverBase::GetMarkerIndices() const { - const auto nMarker = main_config->GetnMarker_All(); - map indexMap; - - for (auto iMarker = 0u; iMarker < nMarker; iMarker++) { - auto tag = main_config->GetMarker_All_TagBound(iMarker); + const auto nMarker = main_config->GetnMarker_All(); + map indexMap; - indexMap[tag] = iMarker; - } - - return indexMap; + for (auto iMarker = 0u; iMarker < nMarker; iMarker++) { + auto tag = main_config->GetMarker_All_TagBound(iMarker); + + indexMap[tag] = iMarker; + } + + return indexMap; } map CDriverBase::GetMarkerTypes() const { - map typeMap; - string type; - - for (auto iMarker = 0u; iMarker < main_config->GetnMarker_All(); iMarker++) { - auto tag = main_config->GetMarker_All_TagBound(iMarker); - auto kindBC = main_config->GetMarker_All_KindBC(iMarker); - - switch(kindBC) { - case EULER_WALL: - type = "EULER_WALL"; - break; - case FAR_FIELD: - type = "FARFIELD"; - break; - case ISOTHERMAL: - type = "ISOTHERMAL"; - break; - case HEAT_FLUX: - type = "HEATFLUX"; - break; - case INLET_FLOW: - type = "INLET_FLOW"; - break; - case OUTLET_FLOW: - type = "OUTLET_FLOW"; - break; - case SYMMETRY_PLANE: - type = "SYMMETRY"; - break; - case SEND_RECEIVE: - type = "SEND_RECEIVE"; - break; - default: - type = "UNKNOWN_TYPE"; - } - typeMap[tag] = type; - } - - return typeMap; + map typeMap; + string type; + + for (auto iMarker = 0u; iMarker < main_config->GetnMarker_All(); iMarker++) { + auto tag = main_config->GetMarker_All_TagBound(iMarker); + auto kindBC = main_config->GetMarker_All_KindBC(iMarker); + + switch (kindBC) { + case EULER_WALL: + type = "EULER_WALL"; + break; + case FAR_FIELD: + type = "FARFIELD"; + break; + case ISOTHERMAL: + type = "ISOTHERMAL"; + break; + case HEAT_FLUX: + type = "HEATFLUX"; + break; + case INLET_FLOW: + type = "INLET_FLOW"; + break; + case OUTLET_FLOW: + type = "OUTLET_FLOW"; + break; + case SYMMETRY_PLANE: + type = "SYMMETRY"; + break; + case SEND_RECEIVE: + type = "SEND_RECEIVE"; + break; + default: + type = "UNKNOWN_TYPE"; + } + typeMap[tag] = type; + } + + return typeMap; } vector CDriverBase::GetMarkerTags() const { - vector tags; - const auto nMarker = main_config->GetnMarker_All(); - - for(auto iMarker = 0u; iMarker < nMarker; iMarker++){ - tags.push_back(main_config->GetMarker_All_TagBound(iMarker)); - } - - return tags; + vector tags; + const auto nMarker = main_config->GetnMarker_All(); + + for (auto iMarker = 0u; iMarker < nMarker; iMarker++) { + tags.push_back(main_config->GetMarker_All_TagBound(iMarker)); + } + + return tags; } vector CDriverBase::GetDeformableMarkerTags() const { - vector tags; - const auto nMarker = main_config->GetnMarker_Deform_Mesh(); - - for (auto iMarker = 0u; iMarker < nMarker; iMarker++) { - tags.push_back(main_config->GetMarker_Deform_Mesh_TagBound(iMarker)); - } - - return tags; -} + vector tags; + const auto nMarker = main_config->GetnMarker_Deform_Mesh(); -unsigned long CDriverBase::GetNumberDimensions() const { - return main_geometry->GetnDim(); -} + for (auto iMarker = 0u; iMarker < nMarker; iMarker++) { + tags.push_back(main_config->GetMarker_Deform_Mesh_TagBound(iMarker)); + } -unsigned long CDriverBase::GetNumberElements() const { - return main_geometry->GetnElem(); + return tags; } +unsigned long CDriverBase::GetNumberDimensions() const { return main_geometry->GetnDim(); } + +unsigned long CDriverBase::GetNumberElements() const { return main_geometry->GetnElem(); } + unsigned long CDriverBase::GetNumberMarkerElements(unsigned short iMarker) const { - if (iMarker >= GetNumberMarkers()) { - SU2_MPI::Error("Marker index exceeds size.", CURRENT_FUNCTION); - } + if (iMarker >= GetNumberMarkers()) { + SU2_MPI::Error("Marker index exceeds size.", CURRENT_FUNCTION); + } - return main_geometry->GetnElem_Bound(iMarker); + return main_geometry->GetnElem_Bound(iMarker); } vector CDriverBase::GetElementIDs() const { - const auto nElem = GetNumberElements(); + const auto nElem = GetNumberElements(); - vector values; + vector values; - for (auto iElem = 0ul; iElem < nElem; iElem++) { - values.push_back(GetElementIDs(iElem)); - } - - return values; + for (auto iElem = 0ul; iElem < nElem; iElem++) { + values.push_back(GetElementIDs(iElem)); + } + + return values; } unsigned long CDriverBase::GetElementIDs(unsigned long iElem) const { - if (iElem >= GetNumberElements()) { - SU2_MPI::Error("Element index exceeds size.", CURRENT_FUNCTION); - } + if (iElem >= GetNumberElements()) { + SU2_MPI::Error("Element index exceeds size.", CURRENT_FUNCTION); + } - return main_geometry->elem[iElem]->GetGlobalIndex(); + return main_geometry->elem[iElem]->GetGlobalIndex(); } -vector CDriverBase::GetMarkerElementIDs(unsigned short iMarker) const { - const auto nBound = GetNumberMarkerElements(iMarker); +vector CDriverBase::GetMarkerElementIDs(unsigned short iMarker) const { + const auto nBound = GetNumberMarkerElements(iMarker); - vector values; - - for (auto iBound = 0ul; iBound < nBound; iBound++) { - values.push_back(GetMarkerElementIDs(iMarker, iBound)); - } - - return values; + vector values; + + for (auto iBound = 0ul; iBound < nBound; iBound++) { + values.push_back(GetMarkerElementIDs(iMarker, iBound)); + } + + return values; } unsigned long CDriverBase::GetMarkerElementIDs(unsigned short iMarker, unsigned long iBound) const { - if (iBound >= GetNumberMarkerElements(iMarker)) { - SU2_MPI::Error("Marker element index exceeds size.", CURRENT_FUNCTION); - } + if (iBound >= GetNumberMarkerElements(iMarker)) { + SU2_MPI::Error("Marker element index exceeds size.", CURRENT_FUNCTION); + } - return main_geometry->bound[iMarker][iBound]->GetGlobalIndex(); + return main_geometry->bound[iMarker][iBound]->GetGlobalIndex(); } vector> CDriverBase::GetElementConnectivities() const { - const auto nElem = GetNumberElements(); - - vector> values; + const auto nElem = GetNumberElements(); - for (auto iElem = 0ul; iElem < nElem; iElem++) { - values.push_back(GetElementConnectivities(iElem)); - } - - return values; + vector> values; + + for (auto iElem = 0ul; iElem < nElem; iElem++) { + values.push_back(GetElementConnectivities(iElem)); + } + + return values; } vector CDriverBase::GetElementConnectivities(unsigned long iElem) const { - if (iElem >= GetNumberElements()) { - SU2_MPI::Error("Element index exceeds size.", CURRENT_FUNCTION); - } - - unsigned short nNode = main_geometry->elem[iElem]->GetnNodes(); - - vector values; + if (iElem >= GetNumberElements()) { + SU2_MPI::Error("Element index exceeds size.", CURRENT_FUNCTION); + } - for (auto iNode = 0u; iNode < nNode; iNode++) { - unsigned long iPoint = main_geometry->elem[iElem]->GetNode(iNode); + unsigned short nNode = main_geometry->elem[iElem]->GetnNodes(); - values.push_back(main_geometry->nodes->GetGlobalIndex(iPoint)); - } - - return values; + vector values; + + for (auto iNode = 0u; iNode < nNode; iNode++) { + unsigned long iPoint = main_geometry->elem[iElem]->GetNode(iNode); + + values.push_back(main_geometry->nodes->GetGlobalIndex(iPoint)); + } + + return values; } vector> CDriverBase::GetMarkerElementConnectivities(unsigned short iMarker) const { - const auto nBound = GetNumberMarkerElements(iMarker); - - vector> values; + const auto nBound = GetNumberMarkerElements(iMarker); - for (auto iBound = 0ul; iBound < nBound; iBound++) { - values.push_back(GetMarkerElementConnectivities(iMarker, iBound)); - } - - return values; + vector> values; + + for (auto iBound = 0ul; iBound < nBound; iBound++) { + values.push_back(GetMarkerElementConnectivities(iMarker, iBound)); + } + + return values; } vector CDriverBase::GetMarkerElementConnectivities(unsigned short iMarker, unsigned long iBound) const { - if (iBound >= GetNumberMarkerElements(iMarker)) { - SU2_MPI::Error("Marker element index exceeds size.", CURRENT_FUNCTION); - } - - unsigned short nNode = main_geometry->bound[iMarker][iBound]->GetnNodes(); - - vector values; + if (iBound >= GetNumberMarkerElements(iMarker)) { + SU2_MPI::Error("Marker element index exceeds size.", CURRENT_FUNCTION); + } - for (auto iNode = 0u; iNode < nNode; iNode++) { - unsigned long iPoint = main_geometry->bound[iMarker][iBound]->GetNode(iNode); + unsigned short nNode = main_geometry->bound[iMarker][iBound]->GetnNodes(); - values.push_back(main_geometry->nodes->GetGlobalIndex(iPoint)); - } - - return values; -} + vector values; + + for (auto iNode = 0u; iNode < nNode; iNode++) { + unsigned long iPoint = main_geometry->bound[iMarker][iBound]->GetNode(iNode); + + values.push_back(main_geometry->nodes->GetGlobalIndex(iPoint)); + } -unsigned long CDriverBase::GetNumberVertices() const { - return main_geometry->GetnPoint(); + return values; } +unsigned long CDriverBase::GetNumberVertices() const { return main_geometry->GetnPoint(); } + unsigned long CDriverBase::GetNumberMarkerVertices(unsigned short iMarker) const { - if (iMarker >= GetNumberMarkers()) { - SU2_MPI::Error("Marker index exceeds size.", CURRENT_FUNCTION); - } + if (iMarker >= GetNumberMarkers()) { + SU2_MPI::Error("Marker index exceeds size.", CURRENT_FUNCTION); + } - return main_geometry->GetnVertex(iMarker); + return main_geometry->GetnVertex(iMarker); } unsigned long CDriverBase::GetNumberHaloVertices() const { - const auto nPoint = GetNumberVertices(); - unsigned long nHalo = 0; - - for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { - if (!(main_geometry->nodes->GetDomain(iPoint))) { - nHalo += 1; - } + const auto nPoint = GetNumberVertices(); + unsigned long nHalo = 0; + + for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { + if (!(main_geometry->nodes->GetDomain(iPoint))) { + nHalo += 1; } - - return nHalo; + } + + return nHalo; } unsigned long CDriverBase::GetNumberMarkerHaloVertices(unsigned short iMarker) const { - const auto nVertex = GetNumberMarkerVertices(iMarker); - unsigned long nHalo = 0; - - for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - auto iPoint = GetMarkerVertexIndices(iMarker, iVertex); - - if (!(main_geometry->nodes->GetDomain(iPoint))) { - nHalo += 1; - } + const auto nVertex = GetNumberMarkerVertices(iMarker); + unsigned long nHalo = 0; + + for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { + auto iPoint = GetMarkerVertexIndices(iMarker, iVertex); + + if (!(main_geometry->nodes->GetDomain(iPoint))) { + nHalo += 1; } - - return nHalo; + } + + return nHalo; } vector CDriverBase::GetMarkerVertexIndices(unsigned short iMarker) const { - const auto nVertex = GetNumberMarkerVertices(iMarker); - - vector values; + const auto nVertex = GetNumberMarkerVertices(iMarker); - for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - values.push_back(GetMarkerVertexIndices(iMarker, iVertex)); - } - - return values; + vector values; + + for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { + values.push_back(GetMarkerVertexIndices(iMarker, iVertex)); + } + + return values; } unsigned long CDriverBase::GetMarkerVertexIndices(unsigned short iMarker, unsigned long iVertex) const { - if (iVertex >= GetNumberMarkerVertices(iMarker)) { - SU2_MPI::Error("Marker vertex index exceeds size.", CURRENT_FUNCTION); - } - - return geometry_container[MESH_0][INST_0][ZONE_0]->vertex[iMarker][iVertex]->GetNode(); + if (iVertex >= GetNumberMarkerVertices(iMarker)) { + SU2_MPI::Error("Vertex index exceeds marker size.", CURRENT_FUNCTION); + } + + return geometry_container[MESH_0][INST_0][ZONE_0]->vertex[iMarker][iVertex]->GetNode(); } vector CDriverBase::GetVertexIDs() const { - const auto nPoint = GetNumberVertices(); - - vector values; + const auto nPoint = GetNumberVertices(); - for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { - values.push_back(GetVertexIDs(iPoint)); - } - - return values; + vector values; + + for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { + values.push_back(GetVertexIDs(iPoint)); + } + + return values; } unsigned long CDriverBase::GetVertexIDs(unsigned long iPoint) const { - if (iPoint >= GetNumberVertices()) { - SU2_MPI::Error("Vertex index exceeds size.", CURRENT_FUNCTION); - } + if (iPoint >= GetNumberVertices()) { + SU2_MPI::Error("Vertex index exceeds mesh size.", CURRENT_FUNCTION); + } - return main_geometry->nodes->GetGlobalIndex(iPoint); + return main_geometry->nodes->GetGlobalIndex(iPoint); } vector CDriverBase::GetMarkerVertexIDs(unsigned short iMarker) const { - const auto nVertex = GetNumberMarkerVertices(iMarker); - - vector values; + const auto nVertex = GetNumberMarkerVertices(iMarker); - for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - values.push_back(GetMarkerVertexIDs(iMarker, iVertex)); - } - - return values; + vector values; + + for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { + values.push_back(GetMarkerVertexIDs(iMarker, iVertex)); + } + + return values; } unsigned long CDriverBase::GetMarkerVertexIDs(unsigned short iMarker, unsigned long iVertex) const { - auto iPoint = GetMarkerVertexIndices(iMarker, iVertex); + auto iPoint = GetMarkerVertexIndices(iMarker, iVertex); - return main_geometry->nodes->GetGlobalIndex(iPoint); + return main_geometry->nodes->GetGlobalIndex(iPoint); } vector CDriverBase::GetDomain() const { - const auto nPoint = GetNumberVertices(); + const auto nPoint = GetNumberVertices(); - vector values; - - for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { - values.push_back(GetDomain(iPoint)); - } - - return values; + vector values; + + for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { + values.push_back(GetDomain(iPoint)); + } + + return values; } bool CDriverBase::GetDomain(unsigned long iPoint) const { - if (iPoint >= GetNumberVertices()) { - SU2_MPI::Error("Vertex index exceeds size.", CURRENT_FUNCTION); - } - - return main_geometry->nodes->GetDomain(iPoint); + if (iPoint >= GetNumberVertices()) { + SU2_MPI::Error("Vertex index exceeds mesh size.", CURRENT_FUNCTION); + } + + return main_geometry->nodes->GetDomain(iPoint); } vector CDriverBase::GetMarkerDomain(unsigned short iMarker) const { - const auto nVertex = GetNumberMarkerVertices(iMarker); + const auto nVertex = GetNumberMarkerVertices(iMarker); - vector values; - - for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - values.push_back(GetMarkerDomain(iMarker, iVertex)); - } - - return values; + vector values; + + for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { + values.push_back(GetMarkerDomain(iMarker, iVertex)); + } + + return values; } bool CDriverBase::GetMarkerDomain(unsigned short iMarker, unsigned long iVertex) const { - auto iPoint = GetMarkerVertexIndices(iMarker, iVertex); - - return main_geometry->nodes->GetDomain(iPoint); + auto iPoint = GetMarkerVertexIndices(iMarker, iVertex); + + return main_geometry->nodes->GetDomain(iPoint); } vector> CDriverBase::GetInitialCoordinates() const { - const auto nPoint = GetNumberVertices(); + const auto nPoint = GetNumberVertices(); - vector> values; - - for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { - values.push_back(GetInitialCoordinates(iPoint)); - } - - return values; + vector> values; + + for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { + values.push_back(GetInitialCoordinates(iPoint)); + } + + return values; } vector CDriverBase::GetInitialCoordinates(unsigned long iPoint) const { - if (iPoint >= GetNumberVertices()) { - SU2_MPI::Error("Vertex index exceeds size.", CURRENT_FUNCTION); - } + if (iPoint >= GetNumberVertices()) { + SU2_MPI::Error("Vertex index exceeds mesh size.", CURRENT_FUNCTION); + } - vector values (nDim, 0.0); - - if (!main_config->GetDeform_Mesh()) { - return values; - } + vector values(nDim, 0.0); - for (auto iDim = 0u; iDim < nDim; iDim++) { - const su2double value = solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->GetMesh_Coord(iPoint, iDim); - - values[iDim] = SU2_TYPE::GetValue(value); - } - + if (!main_config->GetDeform_Mesh()) { return values; + } + + for (auto iDim = 0u; iDim < nDim; iDim++) { + const su2double value = solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->GetMesh_Coord(iPoint, iDim); + + values[iDim] = SU2_TYPE::GetValue(value); + } + + return values; } vector> CDriverBase::GetMarkerInitialCoordinates(unsigned short iMarker) const { - const auto nVertex = GetNumberMarkerVertices(iMarker); + const auto nVertex = GetNumberMarkerVertices(iMarker); - vector> values; - - for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - values.push_back(GetMarkerInitialCoordinates(iMarker, iVertex)); - } - - return values; + vector> values; + + for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { + values.push_back(GetMarkerInitialCoordinates(iMarker, iVertex)); + } + + return values; } vector CDriverBase::GetMarkerInitialCoordinates(unsigned short iMarker, unsigned long iVertex) const { - auto iPoint = GetMarkerVertexIndices(iMarker, iVertex); + auto iPoint = GetMarkerVertexIndices(iMarker, iVertex); - vector values(nDim, 0.0); + vector values(nDim, 0.0); - if (!main_config->GetDeform_Mesh()) { - return values; - } + if (!main_config->GetDeform_Mesh()) { + return values; + } - for (auto iDim = 0u; iDim < nDim; iDim++) { - const su2double value = solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->GetMesh_Coord(iPoint, iDim); + for (auto iDim = 0u; iDim < nDim; iDim++) { + const su2double value = solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->GetMesh_Coord(iPoint, iDim); - values[iDim] = SU2_TYPE::GetValue(value); - } - - return values; + values[iDim] = SU2_TYPE::GetValue(value); + } + + return values; } vector> CDriverBase::GetCoordinates() const { - const auto nPoint = GetNumberVertices(); + const auto nPoint = GetNumberVertices(); - vector> values; - - for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { - values.push_back(GetCoordinates(iPoint)); - } - - return values; + vector> values; + + for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { + values.push_back(GetCoordinates(iPoint)); + } + + return values; } vector CDriverBase::GetCoordinates(unsigned long iPoint) const { - if (iPoint >= GetNumberVertices()) { - SU2_MPI::Error("Vertex index exceeds size.", CURRENT_FUNCTION); - } + if (iPoint >= GetNumberVertices()) { + SU2_MPI::Error("Vertex index exceeds mesh size.", CURRENT_FUNCTION); + } - vector values; - - for (auto iDim = 0u; iDim < nDim; iDim++) { - const su2double value = main_geometry->nodes->GetCoord(iPoint, iDim); - - values.push_back(SU2_TYPE::GetValue(value)); - } - - return values; + vector values; + + for (auto iDim = 0u; iDim < nDim; iDim++) { + const su2double value = main_geometry->nodes->GetCoord(iPoint, iDim); + + values.push_back(SU2_TYPE::GetValue(value)); + } + + return values; } vector> CDriverBase::GetMarkerCoordinates(unsigned short iMarker) const { - const auto nVertex = GetNumberMarkerVertices(iMarker); + const auto nVertex = GetNumberMarkerVertices(iMarker); - vector> values; - - for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - values.push_back(GetMarkerCoordinates(iMarker, iVertex)); - } - - return values; + vector> values; + + for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { + values.push_back(GetMarkerCoordinates(iMarker, iVertex)); + } + + return values; } vector CDriverBase::GetMarkerCoordinates(unsigned short iMarker, unsigned long iVertex) const { - auto iPoint = GetMarkerVertexIndices(iMarker, iVertex); + auto iPoint = GetMarkerVertexIndices(iMarker, iVertex); - vector values; - - for (auto iDim = 0u; iDim < nDim; iDim++) { - const su2double value = main_geometry->nodes->GetCoord(iPoint, iDim); - - values.push_back(SU2_TYPE::GetValue(value)); - } - - return values; + vector values; + + for (auto iDim = 0u; iDim < nDim; iDim++) { + const su2double value = main_geometry->nodes->GetCoord(iPoint, iDim); + + values.push_back(SU2_TYPE::GetValue(value)); + } + + return values; } void CDriverBase::SetCoordinates(vector> values) { - const auto nPoint = GetNumberVertices(); - - if (values.size() != nPoint) { - SU2_MPI::Error("Invalid number of vertices !", CURRENT_FUNCTION); - } - - for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { - SetCoordinates(iPoint, values[iPoint]); - } + const auto nPoint = GetNumberVertices(); + + if (values.size() != nPoint) { + SU2_MPI::Error("Invalid number of vertices!", CURRENT_FUNCTION); + } + + for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { + SetCoordinates(iPoint, values[iPoint]); + } } void CDriverBase::SetCoordinates(unsigned long iPoint, vector values) { - if (iPoint >= GetNumberVertices()) { - SU2_MPI::Error("Vertex index exceeds size.", CURRENT_FUNCTION); - } - - if (values.size() != nDim) { - SU2_MPI::Error("Invalid number of dimensions !", CURRENT_FUNCTION); - } - - for (auto iDim = 0u; iDim < nDim; iDim++) { - main_geometry->nodes->SetCoord(iPoint, iDim, values[iDim]); - } + if (iPoint >= GetNumberVertices()) { + SU2_MPI::Error("Vertex index exceeds mesh size.", CURRENT_FUNCTION); + } + if (values.size() != nDim) { + SU2_MPI::Error("Invalid number of dimensions!", CURRENT_FUNCTION); + } + + for (auto iDim = 0u; iDim < nDim; iDim++) { + main_geometry->nodes->SetCoord(iPoint, iDim, values[iDim]); + } } void CDriverBase::SetMarkerCoordinates(unsigned short iMarker, vector> values) { - const auto nVertex = GetNumberMarkerVertices(iMarker); + const auto nVertex = GetNumberMarkerVertices(iMarker); - if (values.size() != nVertex) { - SU2_MPI::Error("Invalid number of marker vertices !", CURRENT_FUNCTION); - } - - for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - SetMarkerCoordinates(iMarker, iVertex, values[iVertex]); - } + if (values.size() != nVertex) { + SU2_MPI::Error("Invalid number of marker vertices!", CURRENT_FUNCTION); + } + + for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { + SetMarkerCoordinates(iMarker, iVertex, values[iVertex]); + } } void CDriverBase::SetMarkerCoordinates(unsigned short iMarker, unsigned long iVertex, vector values) { - auto iPoint = GetMarkerVertexIndices(iMarker, iVertex); + auto iPoint = GetMarkerVertexIndices(iMarker, iVertex); - if (values.size() != nDim) { - SU2_MPI::Error("Invalid number of dimensions !", CURRENT_FUNCTION); - } - - for (auto iDim = 0u; iDim < nDim; iDim++) { - main_geometry->nodes->SetCoord(iPoint, iDim, values[iDim]); - } + if (values.size() != nDim) { + SU2_MPI::Error("Invalid number of dimensions!", CURRENT_FUNCTION); + } + + for (auto iDim = 0u; iDim < nDim; iDim++) { + main_geometry->nodes->SetCoord(iPoint, iDim, values[iDim]); + } } vector> CDriverBase::GetMarkerDisplacements(unsigned short iMarker) const { - const auto nVertex = GetNumberMarkerVertices(iMarker); + const auto nVertex = GetNumberMarkerVertices(iMarker); - vector> values; - - for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - values.push_back(GetMarkerDisplacements(iMarker, iVertex)); - } - - return values; + vector> values; + + for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { + values.push_back(GetMarkerDisplacements(iMarker, iVertex)); + } + + return values; } vector CDriverBase::GetMarkerDisplacements(unsigned short iMarker, unsigned long iVertex) const { - auto iPoint = GetMarkerVertexIndices(iMarker, iVertex); + auto iPoint = GetMarkerVertexIndices(iMarker, iVertex); - vector values (nDim, 0.0); - - if (!main_config->GetDeform_Mesh()) { - return values; - } - - for (auto iDim = 0u; iDim < nDim; iDim++) { - const su2double value = solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->GetBound_Disp(iPoint, iDim); - - values[iDim] = SU2_TYPE::GetValue(value); - } - + vector values(nDim, 0.0); + + if (!main_config->GetDeform_Mesh()) { return values; + } + + for (auto iDim = 0u; iDim < nDim; iDim++) { + const su2double value = solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->GetBound_Disp(iPoint, iDim); + + values[iDim] = SU2_TYPE::GetValue(value); + } + + return values; } void CDriverBase::SetMarkerDisplacements(unsigned short iMarker, vector> values) { - if (!main_config->GetDeform_Mesh()) { - SU2_MPI::Error("Mesh solver is not defined !", CURRENT_FUNCTION); - } + if (!main_config->GetDeform_Mesh()) { + SU2_MPI::Error("Mesh solver is not defined!", CURRENT_FUNCTION); + } - const auto nVertex = GetNumberMarkerVertices(iMarker); + const auto nVertex = GetNumberMarkerVertices(iMarker); - if (values.size() != nVertex) { - SU2_MPI::Error("Invalid number of marker vertices !", CURRENT_FUNCTION); - } - - for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - SetMarkerDisplacements(iMarker, iVertex, values[iVertex]); - } + if (values.size() != nVertex) { + SU2_MPI::Error("Invalid number of marker vertices!", CURRENT_FUNCTION); + } + + for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { + SetMarkerDisplacements(iMarker, iVertex, values[iVertex]); + } } void CDriverBase::SetMarkerDisplacements(unsigned short iMarker, unsigned long iVertex, vector values) { - if (!main_config->GetDeform_Mesh()) { - SU2_MPI::Error("Mesh solver is not defined !", CURRENT_FUNCTION); - } + if (!main_config->GetDeform_Mesh()) { + SU2_MPI::Error("Mesh solver is not defined!", CURRENT_FUNCTION); + } - auto iPoint = GetMarkerVertexIndices(iMarker, iVertex); + auto iPoint = GetMarkerVertexIndices(iMarker, iVertex); - if (values.size() != nDim) { - SU2_MPI::Error("Invalid number of dimensions !", CURRENT_FUNCTION); - } - - for (auto iDim = 0u; iDim < nDim; iDim++) { - solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->SetBound_Disp(iPoint, iDim, values[iDim]); - } + if (values.size() != nDim) { + SU2_MPI::Error("Invalid number of dimensions!", CURRENT_FUNCTION); + } + + for (auto iDim = 0u; iDim < nDim; iDim++) { + solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->SetBound_Disp(iPoint, iDim, values[iDim]); + } } vector> CDriverBase::GetMarkerVelocities(unsigned short iMarker) const { - const auto nVertex = GetNumberMarkerVertices(iMarker); + const auto nVertex = GetNumberMarkerVertices(iMarker); - vector> values; - - for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - values.push_back(GetMarkerVelocities(iMarker, iVertex)); - } - - return values; + vector> values; + + for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { + values.push_back(GetMarkerVelocities(iMarker, iVertex)); + } + + return values; } vector CDriverBase::GetMarkerVelocities(unsigned short iMarker, unsigned long iVertex) const { - auto iPoint = GetMarkerVertexIndices(iMarker, iVertex); + auto iPoint = GetMarkerVertexIndices(iMarker, iVertex); - vector values (nDim, 0.0); - - if (!main_config->GetDeform_Mesh()) { - return values; - } - - for (auto iDim = 0u; iDim < nDim; iDim++) { - const su2double value = solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->GetBound_Vel(iPoint, iDim); - - values[iDim] = SU2_TYPE::GetValue(value); - } - + vector values(nDim, 0.0); + + if (!main_config->GetDeform_Mesh()) { return values; + } + + for (auto iDim = 0u; iDim < nDim; iDim++) { + const su2double value = solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->GetBound_Vel(iPoint, iDim); + + values[iDim] = SU2_TYPE::GetValue(value); + } + + return values; } void CDriverBase::SetMarkerVelocities(unsigned short iMarker, vector> values) { - if (!main_config->GetDeform_Mesh()) { - SU2_MPI::Error("Mesh solver is not defined !", CURRENT_FUNCTION); - } + if (!main_config->GetDeform_Mesh()) { + SU2_MPI::Error("Mesh solver is not defined!", CURRENT_FUNCTION); + } - const auto nVertex = GetNumberMarkerVertices(iMarker); + const auto nVertex = GetNumberMarkerVertices(iMarker); - if (values.size() != nVertex) { - SU2_MPI::Error("Invalid number of marker vertices !", CURRENT_FUNCTION); - } - - for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - SetMarkerVelocities(iMarker, iVertex, values[iVertex]); - } + if (values.size() != nVertex) { + SU2_MPI::Error("Invalid number of marker vertices!", CURRENT_FUNCTION); + } + + for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { + SetMarkerVelocities(iMarker, iVertex, values[iVertex]); + } } void CDriverBase::SetMarkerVelocities(unsigned short iMarker, unsigned long iVertex, vector values) { - if (!main_config->GetDeform_Mesh()) { - SU2_MPI::Error("Mesh solver is not defined !", CURRENT_FUNCTION); - } + if (!main_config->GetDeform_Mesh()) { + SU2_MPI::Error("Mesh solver is not defined!", CURRENT_FUNCTION); + } - auto iPoint = GetMarkerVertexIndices(iMarker, iVertex); + auto iPoint = GetMarkerVertexIndices(iMarker, iVertex); - if (values.size() != nDim) { - SU2_MPI::Error("Invalid number of dimensions !", CURRENT_FUNCTION); - } - - for (auto iDim = 0u; iDim < nDim; iDim++) { - solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->SetBound_Disp(iPoint, iDim, values[iDim]); - } + if (values.size() != nDim) { + SU2_MPI::Error("Invalid number of dimensions!", CURRENT_FUNCTION); + } + + for (auto iDim = 0u; iDim < nDim; iDim++) { + solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->SetBound_Disp(iPoint, iDim, values[iDim]); + } } vector> CDriverBase::GetMarkerVertexNormals(unsigned short iMarker, bool normalize) const { - const auto nVertex = GetNumberMarkerVertices(iMarker); + const auto nVertex = GetNumberMarkerVertices(iMarker); + + vector> values; + + for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { + values.push_back(GetMarkerVertexNormals(iMarker, iVertex, normalize = normalize)); + } + + return values; +} - vector> values; - - for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - values.push_back(GetMarkerVertexNormals(iMarker, iVertex, normalize=normalize)); +vector CDriverBase::GetMarkerVertexNormals(unsigned short iMarker, unsigned long iVertex, + bool normalize) const { + if (iVertex >= GetNumberMarkerVertices(iMarker)) { + SU2_MPI::Error("Vertex index exceeds marker size.", CURRENT_FUNCTION); + } + + vector values(nDim, 0.0); + + auto normal = main_geometry->vertex[iMarker][iVertex]->GetNormal(); + auto area = GeometryToolbox::Norm(nDim, normal); + + for (auto iDim = 0u; iDim < nDim; iDim++) { + if (normalize) { + values[iDim] = SU2_TYPE::GetValue(normal[iDim] / area); + } else { + values[iDim] = SU2_TYPE::GetValue(normal[iDim]); } - - return values; + } + + return values; } -vector CDriverBase::GetMarkerVertexNormals(unsigned short iMarker, unsigned long iVertex, bool normalize) const { - if (iVertex >= GetNumberMarkerVertices(iMarker)) { - SU2_MPI::Error("Marker vertex index exceeds size.", CURRENT_FUNCTION); +void CDriverBase::CommunicateMeshDisplacements(void) { + solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->InitiateComms(main_geometry, main_config, MESH_DISPLACEMENTS); + solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->CompleteComms(main_geometry, main_config, MESH_DISPLACEMENTS); +} + +void CDriverBase::ReadFFDInfo(CGeometry* geometry, CConfig* config, CFreeFormDefBox** FFDBox, string val_mesh_filename) { + string text_line, iTag; + ifstream mesh_file; + su2double CPcoord[3], coord[] = {0, 0, 0}; + unsigned short degree[3], iFFDBox, iCornerPoints, iControlPoints, iMarker, iDegree, jDegree, kDegree, iChar, + LevelFFDBox, nParentFFDBox, iParentFFDBox, nChildFFDBox, iChildFFDBox, nMarker, *nCornerPoints, *nControlPoints; + unsigned long iSurfacePoints, iPoint, jPoint, iVertex, nVertex, nPoint, iElem = 0, nElem, my_nSurfPoints, nSurfPoints, + *nSurfacePoints; + su2double XCoord, YCoord; + + bool polar = (config->GetFFD_CoordSystem() == POLAR); + unsigned short nDim = geometry->GetnDim(), iDim; + unsigned short SplineOrder[3]; + unsigned short Blending = 0; + + unsigned short nFFDBox = 0; + unsigned short nLevel = 0; + bool FFDBoxDefinition = false; + + mesh_file.open(val_mesh_filename); + if (mesh_file.fail()) { + SU2_MPI::Error("There is no geometry file (ReadFFDInfo)!!", CURRENT_FUNCTION); + } + + while (getline(mesh_file, text_line)) { + /*--- Read the inner elements. ---*/ + + string::size_type position = text_line.find("NELEM=", 0); + if (position != string::npos) { + text_line.erase(0, 6); + nElem = atoi(text_line.c_str()); + for (iElem = 0; iElem < nElem; iElem++) { + getline(mesh_file, text_line); + } + } + + /*--- Read the inner points. ---*/ + + position = text_line.find("NPOIN=", 0); + if (position != string::npos) { + text_line.erase(0, 6); + nPoint = atoi(text_line.c_str()); + for (iPoint = 0; iPoint < nPoint; iPoint++) { + getline(mesh_file, text_line); + } + } + + /*--- Read the boundaries. ---*/ + + position = text_line.find("NMARK=", 0); + if (position != string::npos) { + text_line.erase(0, 6); + nMarker = atoi(text_line.c_str()); + for (iMarker = 0; iMarker < nMarker; iMarker++) { + getline(mesh_file, text_line); + getline(mesh_file, text_line); + text_line.erase(0, 13); + nVertex = atoi(text_line.c_str()); + for (iVertex = 0; iVertex < nVertex; iVertex++) { + getline(mesh_file, text_line); + } + } } - vector values; + /*--- Read the FFDBox information. ---*/ - auto normal = main_geometry->vertex[iMarker][iVertex]->GetNormal(); - auto area = GeometryToolbox::Norm(nDim, normal); - - for (auto iDim = 0u; iDim < nDim; iDim++) { - if (normalize) { - values[iDim] = SU2_TYPE::GetValue(normal[iDim]/area); + position = text_line.find("FFD_NBOX=", 0); + if (position != string::npos) { + text_line.erase(0, 9); + nFFDBox = atoi(text_line.c_str()); + + if (rank == MASTER_NODE) cout << nFFDBox << " Free Form Deformation boxes." << endl; + + nCornerPoints = new unsigned short[nFFDBox]; + nControlPoints = new unsigned short[nFFDBox]; + nSurfacePoints = new unsigned long[nFFDBox]; + + getline(mesh_file, text_line); + text_line.erase(0, 11); + nLevel = atoi(text_line.c_str()); + + if (rank == MASTER_NODE) cout << nLevel << " Free Form Deformation nested levels." << endl; + + for (iFFDBox = 0; iFFDBox < nFFDBox; iFFDBox++) { + /*--- Read the name of the FFD box. ---*/ + + getline(mesh_file, text_line); + text_line.erase(0, 8); + + /*--- Remove extra data from the FFDBox name. ---*/ + + string::size_type position; + for (iChar = 0; iChar < 20; iChar++) { + position = text_line.find(" ", 0); + if (position != string::npos) text_line.erase(position, 1); + position = text_line.find("\r", 0); + if (position != string::npos) text_line.erase(position, 1); + position = text_line.find("\n", 0); + if (position != string::npos) text_line.erase(position, 1); + } + + string TagFFDBox = text_line.c_str(); + + if (rank == MASTER_NODE) cout << "FFD box tag: " << TagFFDBox << ". "; + + /*--- Read the level of the FFD box. ---*/ + + getline(mesh_file, text_line); + text_line.erase(0, 10); + LevelFFDBox = atoi(text_line.c_str()); + + if (rank == MASTER_NODE) cout << "FFD box level: " << LevelFFDBox << ". "; + + /*--- Read the degree of the FFD box. ---*/ + + if (nDim == 2) { + if (polar) { + getline(mesh_file, text_line); + text_line.erase(0, 13); + degree[0] = atoi(text_line.c_str()); + degree[1] = 1; + getline(mesh_file, text_line); + text_line.erase(0, 13); + degree[2] = atoi(text_line.c_str()); + } else { + getline(mesh_file, text_line); + text_line.erase(0, 13); + degree[0] = atoi(text_line.c_str()); + getline(mesh_file, text_line); + text_line.erase(0, 13); + degree[1] = atoi(text_line.c_str()); + degree[2] = 1; + } } else { - values[iDim] = SU2_TYPE::GetValue(normal[iDim]); + getline(mesh_file, text_line); + text_line.erase(0, 13); + degree[0] = atoi(text_line.c_str()); + getline(mesh_file, text_line); + text_line.erase(0, 13); + degree[1] = atoi(text_line.c_str()); + getline(mesh_file, text_line); + text_line.erase(0, 13); + degree[2] = atoi(text_line.c_str()); } - } - return values; -} + if (rank == MASTER_NODE) { + if (nDim == 2) { + if (polar) + cout << "Degrees: " << degree[0] << ", " << degree[2] << "." << endl; + else + cout << "Degrees: " << degree[0] << ", " << degree[1] << "." << endl; + } else + cout << "Degrees: " << degree[0] << ", " << degree[1] << ", " << degree[2] << "." << endl; + } + getline(mesh_file, text_line); + if (text_line.substr(0, 12) != "FFD_BLENDING") { + SU2_MPI::Error( + string("Deprecated FFD information found in mesh file.\n") + + string( + "FFD information generated with SU2 version <= 4.3 is incompatible with the current version.") + + string("Run SU2_DEF again with DV_KIND= FFD_SETTING."), + CURRENT_FUNCTION); + } + text_line.erase(0, 14); + if (text_line == "BEZIER") { + Blending = BEZIER; + } + if (text_line == "BSPLINE_UNIFORM") { + Blending = BSPLINE_UNIFORM; + } -void CDriverBase::CommunicateMeshDisplacements(void) { - solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->InitiateComms(main_geometry, main_config, MESH_DISPLACEMENTS); - solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->CompleteComms(main_geometry, main_config, MESH_DISPLACEMENTS); + if (Blending == BSPLINE_UNIFORM) { + getline(mesh_file, text_line); + text_line.erase(0, 17); + SplineOrder[0] = atoi(text_line.c_str()); + getline(mesh_file, text_line); + text_line.erase(0, 17); + SplineOrder[1] = atoi(text_line.c_str()); + if (nDim == 3) { + getline(mesh_file, text_line); + text_line.erase(0, 17); + SplineOrder[2] = atoi(text_line.c_str()); + } else { + SplineOrder[2] = 2; + } + } + if (rank == MASTER_NODE) { + if (Blending == BSPLINE_UNIFORM) { + cout << "FFD Blending using B-Splines. "; + cout << "Order: " << SplineOrder[0] << ", " << SplineOrder[1]; + if (nDim == 3) cout << ", " << SplineOrder[2]; + cout << ". " << endl; + } + if (Blending == BEZIER) { + cout << "FFD Blending using Bezier Curves." << endl; + } + } + + FFDBox[iFFDBox] = new CFreeFormDefBox(degree, SplineOrder, Blending); + FFDBox[iFFDBox]->SetTag(TagFFDBox); + FFDBox[iFFDBox]->SetLevel(LevelFFDBox); + + /*--- Read the number of parents boxes. ---*/ + + getline(mesh_file, text_line); + text_line.erase(0, 12); + nParentFFDBox = atoi(text_line.c_str()); + if (rank == MASTER_NODE) cout << "Number of parent boxes: " << nParentFFDBox << ". "; + for (iParentFFDBox = 0; iParentFFDBox < nParentFFDBox; iParentFFDBox++) { + getline(mesh_file, text_line); + + /*--- Remove extra data from the FFDBox name. ---*/ + + string::size_type position; + for (iChar = 0; iChar < 20; iChar++) { + position = text_line.find(" ", 0); + if (position != string::npos) text_line.erase(position, 1); + position = text_line.find("\r", 0); + if (position != string::npos) text_line.erase(position, 1); + position = text_line.find("\n", 0); + if (position != string::npos) text_line.erase(position, 1); + } + + string ParentFFDBox = text_line.c_str(); + FFDBox[iFFDBox]->SetParentFFDBox(ParentFFDBox); + } + + /*--- Read the number of children boxes. ---*/ + + getline(mesh_file, text_line); + text_line.erase(0, 13); + nChildFFDBox = atoi(text_line.c_str()); + if (rank == MASTER_NODE) cout << "Number of child boxes: " << nChildFFDBox << "." << endl; + + for (iChildFFDBox = 0; iChildFFDBox < nChildFFDBox; iChildFFDBox++) { + getline(mesh_file, text_line); + + /*--- Remove extra data from the FFDBox name. ---*/ + + string::size_type position; + for (iChar = 0; iChar < 20; iChar++) { + position = text_line.find(" ", 0); + if (position != string::npos) text_line.erase(position, 1); + position = text_line.find("\r", 0); + if (position != string::npos) text_line.erase(position, 1); + position = text_line.find("\n", 0); + if (position != string::npos) text_line.erase(position, 1); + } + + string ChildFFDBox = text_line.c_str(); + FFDBox[iFFDBox]->SetChildFFDBox(ChildFFDBox); + } + + /*--- Read the number of the corner points. ---*/ + + getline(mesh_file, text_line); + text_line.erase(0, 18); + nCornerPoints[iFFDBox] = atoi(text_line.c_str()); + if (rank == MASTER_NODE) cout << "Corner points: " << nCornerPoints[iFFDBox] << ". "; + if (nDim == 2) nCornerPoints[iFFDBox] = nCornerPoints[iFFDBox] * SU2_TYPE::Int(2); + + /*--- Read the coordinates of the corner points. ---*/ + + if (nDim == 2) { + if (polar) { + getline(mesh_file, text_line); + istringstream FFDBox_line_1(text_line); + FFDBox_line_1 >> XCoord; + FFDBox_line_1 >> YCoord; + + CPcoord[0] = XCoord; + CPcoord[1] = cos(0.1) * YCoord; + CPcoord[2] = -sin(0.1) * YCoord; + FFDBox[iFFDBox]->SetCoordCornerPoints(coord, 4); + + CPcoord[0] = XCoord; + CPcoord[1] = cos(0.1) * YCoord; + CPcoord[2] = sin(0.1) * YCoord; + FFDBox[iFFDBox]->SetCoordCornerPoints(coord, 7); + + getline(mesh_file, text_line); + istringstream FFDBox_line_2(text_line); + FFDBox_line_2 >> XCoord; + FFDBox_line_2 >> YCoord; + + CPcoord[0] = XCoord; + CPcoord[1] = cos(0.1) * YCoord; + CPcoord[2] = -sin(0.1) * YCoord; + FFDBox[iFFDBox]->SetCoordCornerPoints(CPcoord, 0); + + CPcoord[0] = XCoord; + CPcoord[1] = cos(0.1) * YCoord; + CPcoord[2] = sin(0.1) * YCoord; + FFDBox[iFFDBox]->SetCoordCornerPoints(CPcoord, 3); + + getline(mesh_file, text_line); + istringstream FFDBox_line_3(text_line); + FFDBox_line_3 >> XCoord; + FFDBox_line_3 >> YCoord; + + CPcoord[0] = XCoord; + CPcoord[1] = cos(0.1) * YCoord; + CPcoord[2] = -sin(0.1) * YCoord; + FFDBox[iFFDBox]->SetCoordCornerPoints(CPcoord, 1); + + CPcoord[0] = XCoord; + CPcoord[1] = cos(0.1) * YCoord; + CPcoord[2] = sin(0.1) * YCoord; + FFDBox[iFFDBox]->SetCoordCornerPoints(CPcoord, 2); + + getline(mesh_file, text_line); + istringstream FFDBox_line_4(text_line); + FFDBox_line_4 >> XCoord; + FFDBox_line_4 >> YCoord; + + CPcoord[0] = XCoord; + CPcoord[1] = cos(0.1) * YCoord; + CPcoord[2] = -sin(0.1) * YCoord; + FFDBox[iFFDBox]->SetCoordCornerPoints(CPcoord, 5); + + CPcoord[0] = XCoord; + CPcoord[1] = cos(0.1) * YCoord; + CPcoord[2] = sin(0.1) * YCoord; + FFDBox[iFFDBox]->SetCoordCornerPoints(CPcoord, 6); + + } else { + for (iCornerPoints = 0; iCornerPoints < nCornerPoints[iFFDBox]; iCornerPoints++) { + if (iCornerPoints < nCornerPoints[iFFDBox] / SU2_TYPE::Int(2)) { + getline(mesh_file, text_line); + istringstream FFDBox_line(text_line); + FFDBox_line >> CPcoord[0]; + FFDBox_line >> CPcoord[1]; + CPcoord[2] = -0.5; + } else { + CPcoord[0] = + FFDBox[iFFDBox]->GetCoordCornerPoints(0, iCornerPoints - nCornerPoints[iFFDBox] / SU2_TYPE::Int(2)); + CPcoord[1] = + FFDBox[iFFDBox]->GetCoordCornerPoints(1, iCornerPoints - nCornerPoints[iFFDBox] / SU2_TYPE::Int(2)); + CPcoord[2] = 0.5; + } + FFDBox[iFFDBox]->SetCoordCornerPoints(CPcoord, iCornerPoints); + } + } + + } else { + for (iCornerPoints = 0; iCornerPoints < nCornerPoints[iFFDBox]; iCornerPoints++) { + getline(mesh_file, text_line); + istringstream FFDBox_line(text_line); + FFDBox_line >> CPcoord[0]; + FFDBox_line >> CPcoord[1]; + FFDBox_line >> CPcoord[2]; + FFDBox[iFFDBox]->SetCoordCornerPoints(CPcoord, iCornerPoints); + } + } + + /*--- Read the number of the control points. ---*/ + + getline(mesh_file, text_line); + text_line.erase(0, 19); + nControlPoints[iFFDBox] = atoi(text_line.c_str()); + + if (rank == MASTER_NODE) cout << "Control points: " << nControlPoints[iFFDBox] << ". "; + + /*--- Method to identify if there is a FFDBox definition. ---*/ + + if (nControlPoints[iFFDBox] != 0) FFDBoxDefinition = true; + + /*--- Read the coordinates of the control points. ---*/ + + for (iControlPoints = 0; iControlPoints < nControlPoints[iFFDBox]; iControlPoints++) { + getline(mesh_file, text_line); + istringstream FFDBox_line(text_line); + FFDBox_line >> iDegree; + FFDBox_line >> jDegree; + FFDBox_line >> kDegree; + FFDBox_line >> CPcoord[0]; + FFDBox_line >> CPcoord[1]; + FFDBox_line >> CPcoord[2]; + FFDBox[iFFDBox]->SetCoordControlPoints(CPcoord, iDegree, jDegree, kDegree); + FFDBox[iFFDBox]->SetCoordControlPoints_Copy(CPcoord, iDegree, jDegree, kDegree); + } + + getline(mesh_file, text_line); + text_line.erase(0, 19); + nSurfacePoints[iFFDBox] = atoi(text_line.c_str()); + + /*--- The surface points parametric coordinates (all the nodes read the FFD + * information but they only store their part). ---*/ + + my_nSurfPoints = 0; + for (iSurfacePoints = 0; iSurfacePoints < nSurfacePoints[iFFDBox]; iSurfacePoints++) { + getline(mesh_file, text_line); + istringstream FFDBox_line(text_line); + FFDBox_line >> iTag; + FFDBox_line >> iPoint; + + if (config->GetMarker_All_TagBound(iTag) != -1) { + iMarker = config->GetMarker_All_TagBound(iTag); + FFDBox_line >> CPcoord[0]; + FFDBox_line >> CPcoord[1]; + FFDBox_line >> CPcoord[2]; + + for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { + jPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + if (iPoint == geometry->nodes->GetGlobalIndex(jPoint)) { + for (iDim = 0; iDim < nDim; iDim++) { + coord[iDim] = geometry->nodes->GetCoord(jPoint, iDim); + } + FFDBox[iFFDBox]->Set_MarkerIndex(iMarker); + FFDBox[iFFDBox]->Set_VertexIndex(iVertex); + FFDBox[iFFDBox]->Set_PointIndex(jPoint); + FFDBox[iFFDBox]->Set_ParametricCoord(CPcoord); + FFDBox[iFFDBox]->Set_CartesianCoord(coord); + my_nSurfPoints++; + } + } + } + } + + nSurfacePoints[iFFDBox] = my_nSurfPoints; + +#ifdef HAVE_MPI + nSurfPoints = 0; + SU2_MPI::Allreduce(&my_nSurfPoints, &nSurfPoints, 1, MPI_UNSIGNED_LONG, MPI_SUM, SU2_MPI::GetComm()); + if (rank == MASTER_NODE) cout << "Surface points: " << nSurfPoints << "." << endl; +#else + nSurfPoints = my_nSurfPoints; + if (rank == MASTER_NODE) cout << "Surface points: " << nSurfPoints << "." << endl; +#endif + } + + delete[] nCornerPoints; + delete[] nControlPoints; + delete[] nSurfacePoints; + } + } + mesh_file.close(); + + if (nFFDBox == 0) { + if (rank == MASTER_NODE) cout << "There is no FFD box definition. Just in case, check the .su2 file" << endl; + } } From bb19bd0346016fb2b3c6957e375e4233533bcb17 Mon Sep 17 00:00:00 2001 From: patelha57 Date: Thu, 8 Dec 2022 20:43:38 -0800 Subject: [PATCH 32/68] Update SU2_DEF and SU2_DOT --- SU2_DEF/include/SU2_DEF.hpp | 9 ++-- SU2_DEF/src/SU2_DEF.cpp | 87 +++++++++++++++++++----------------- SU2_DOT/include/SU2_DOT.hpp | 10 ++--- SU2_DOT/src/SU2_DOT.cpp | 88 ++++++++++++++++++++----------------- 4 files changed, 102 insertions(+), 92 deletions(-) diff --git a/SU2_DEF/include/SU2_DEF.hpp b/SU2_DEF/include/SU2_DEF.hpp index 4825094fae2..645e6e29768 100644 --- a/SU2_DEF/include/SU2_DEF.hpp +++ b/SU2_DEF/include/SU2_DEF.hpp @@ -1,7 +1,6 @@ /*! * \file SU2_DEF.hpp * \brief Headers of the main subroutines of the code SU2_DEF. - * The subroutines and functions are in the SU2_DEF.cpp file. * \author F. Palacios, T. Economon * \version 7.3.1 "Blackbird" * @@ -35,11 +34,11 @@ #include "../../Common/include/CConfig.hpp" #undef ENABLE_MAPS -#include "drivers/CDeformationDriver.hpp" - +#include #include -#include #include -#include +#include + +#include "drivers/CDeformationDriver.hpp" using namespace std; diff --git a/SU2_DEF/src/SU2_DEF.cpp b/SU2_DEF/src/SU2_DEF.cpp index 515bd8d6cfb..d15fce2e60e 100644 --- a/SU2_DEF/src/SU2_DEF.cpp +++ b/SU2_DEF/src/SU2_DEF.cpp @@ -29,47 +29,54 @@ using namespace std; -int main(int argc, char *argv[]) { - - char config_file_name[MAX_STRING_SIZE]; - - /*--- Create a pointer to the main SU2_DEF Driver ---*/ - - CDeformationDriver* driver = nullptr; - - /*--- MPI initialization ---*/ - +int main(int argc, char* argv[]) { + + char config_file_name[MAX_STRING_SIZE]; + + /*--- Create a pointer to the main SU2_DEF Driver ---*/ + + CDeformationDriver* driver = nullptr; + + /*--- MPI initialization ---*/ + #if defined(HAVE_OMP) && defined(HAVE_MPI) - int provided; - SU2_MPI::Init_thread(&argc, &argv, MPI_THREAD_FUNNELED, &provided); + int provided; + SU2_MPI::Init_thread(&argc, &argv, MPI_THREAD_FUNNELED, &provided); #else - SU2_MPI::Init(&argc, &argv); + SU2_MPI::Init(&argc, &argv); #endif - SU2_MPI::Comm comm = SU2_MPI::GetComm(); - - /*--- 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"); } - - /*--- Initialize the mesh deformation driver ---*/ - - driver = new CDeformationDriver(config_file_name, comm); - - /*--- Launch the main external loop of the solver. ---*/ - - driver->Run(); - - /*--- Postprocess all the containers, close history file, exit SU2. ---*/ - - driver->Postprocessing(); - - delete driver; - - /*--- Finalize MPI parallelization ---*/ - SU2_MPI::Finalize(); - - return EXIT_SUCCESS; - + SU2_MPI::Comm comm = SU2_MPI::GetComm(); + + /*--- 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"); + } + + /*--- Initialize the mesh deformation driver. ---*/ + + driver = new CDeformationDriver(config_file_name, comm); + + /*--- Preprocess the solver data. ---*/ + + driver->Preprocess(); + + /*--- Launch the main external loop of the solver. ---*/ + + driver->Run(); + + /*--- Postprocess all the containers, close history file, and exit SU2. ---*/ + + driver->Postprocessing(); + + delete driver; + + /*--- Finalize MPI parallelization. ---*/ + + SU2_MPI::Finalize(); + + return EXIT_SUCCESS; } diff --git a/SU2_DOT/include/SU2_DOT.hpp b/SU2_DOT/include/SU2_DOT.hpp index d087a9eb1b2..cc201e1d50b 100644 --- a/SU2_DOT/include/SU2_DOT.hpp +++ b/SU2_DOT/include/SU2_DOT.hpp @@ -1,7 +1,6 @@ /*! * \file SU2_DOT.hpp * \brief Headers of the main subroutines of the code SU2_DOT. - * The subroutines and functions are in the SU2_DOT.cpp file. * \author F. Palacios, T. Economon * \version 7.3.1 "Blackbird" * @@ -32,14 +31,13 @@ #include "../../Common/include/CConfig.hpp" #undef ENABLE_MAPS -#include "../../Common/include/parallelization/mpi_structure.hpp" -#include "../../Common/include/parallelization/omp_structure.hpp" - +#include #include -#include #include -#include +#include +#include "../../Common/include/parallelization/mpi_structure.hpp" +#include "../../Common/include/parallelization/omp_structure.hpp" #include "../../SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp" using namespace std; diff --git a/SU2_DOT/src/SU2_DOT.cpp b/SU2_DOT/src/SU2_DOT.cpp index cb362511793..4d01c6e4793 100644 --- a/SU2_DOT/src/SU2_DOT.cpp +++ b/SU2_DOT/src/SU2_DOT.cpp @@ -25,52 +25,58 @@ * License along with SU2. If not, see . */ - #include "../include/SU2_DOT.hpp" using namespace std; -int main(int argc, char *argv[]) { - - char config_file_name[MAX_STRING_SIZE]; - - /*--- Create a pointer to the main SU2_DEF Driver ---*/ - - CDiscAdjDeformationDriver* driver = nullptr; - - /*--- MPI initialization ---*/ - +int main(int argc, char* argv[]) { + + char config_file_name[MAX_STRING_SIZE]; + + /*--- Create a pointer to the main SU2_DEF Driver. ---*/ + + CDiscAdjDeformationDriver* driver = nullptr; + + /*--- MPI initialization. ---*/ + #if defined(HAVE_OMP) && defined(HAVE_MPI) - int provided; - SU2_MPI::Init_thread(&argc, &argv, MPI_THREAD_FUNNELED, &provided); + int provided; + SU2_MPI::Init_thread(&argc, &argv, MPI_THREAD_FUNNELED, &provided); #else - SU2_MPI::Init(&argc, &argv); + SU2_MPI::Init(&argc, &argv); #endif - SU2_MPI::Comm comm = SU2_MPI::GetComm(); - - /*--- 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"); } - - /*--- Initialize the mesh deformation driver ---*/ - - driver = new CDiscAdjDeformationDriver(config_file_name, comm); - - /*--- Launch the main external loop of the solver. ---*/ - - driver->Run(); - - /*--- Postprocess all the containers, close history file, exit SU2. ---*/ - - driver->Postprocessing(); - - delete driver; - - /*--- Finalize MPI parallelization ---*/ - SU2_MPI::Finalize(); - - return EXIT_SUCCESS; - + SU2_MPI::Comm comm = SU2_MPI::GetComm(); + + /*--- 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"); + } + + /*--- Initialize the mesh deformation driver. ---*/ + + driver = new CDiscAdjDeformationDriver(config_file_name, comm); + + /*--- Preprocess the solver data. ---*/ + + driver->Preprocess(); + + /*--- Launch the main external loop of the solver. ---*/ + + driver->Run(); + + /*--- Postprocess all the containers, close history file, and exit SU2. ---*/ + + driver->Postprocessing(); + + delete driver; + + /*--- Finalize MPI parallelization. ---*/ + + SU2_MPI::Finalize(); + + return EXIT_SUCCESS; } From 7b545bc581df6c1f4390bb330fc432b0c23c8507 Mon Sep 17 00:00:00 2001 From: patelha57 Date: Thu, 8 Dec 2022 21:01:41 -0800 Subject: [PATCH 33/68] Add vector template for Python wrapper --- SU2_PY/pySU2/pySU2.i | 1 + 1 file changed, 1 insertion(+) diff --git a/SU2_PY/pySU2/pySU2.i b/SU2_PY/pySU2/pySU2.i index 0aa3dddc212..56da2437af2 100644 --- a/SU2_PY/pySU2/pySU2.i +++ b/SU2_PY/pySU2/pySU2.i @@ -64,6 +64,7 @@ threads="1" namespace std { %template() vector; + %template() vector; %template() vector; %template() vector>; %template() vector; From 8d4974fd6907b9853ef37a116e90480bb4ae7e7b Mon Sep 17 00:00:00 2001 From: patelha57 Date: Thu, 8 Dec 2022 23:28:28 -0800 Subject: [PATCH 34/68] Fix compilation error caused by hdf5 static library --- externals/cgns/hdf5/meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/externals/cgns/hdf5/meson.build b/externals/cgns/hdf5/meson.build index f85d5ba86d9..7b558a49c4e 100644 --- a/externals/cgns/hdf5/meson.build +++ b/externals/cgns/hdf5/meson.build @@ -25,7 +25,7 @@ hdf5_conf_data.set('version', '1.12.1') ext_deps = [] -opt_zlib = dependency('zlib', required: false, static: true) +opt_zlib = dependency('zlib', required: false, static: false) opt_szip = dependency('szip', required: false, static: true) if opt_zlib.found() and cc.has_header('zlib.h') From 23d03ca9b38a3cbae3f29f4f9259c08cf5bfc040 Mon Sep 17 00:00:00 2001 From: Harsh Patel Date: Fri, 9 Dec 2022 16:06:52 -0800 Subject: [PATCH 35/68] Update submodule versions --- externals/meson | 2 +- externals/opdi | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/externals/meson b/externals/meson index 29ef4478df6..41c650a040d 160000 --- a/externals/meson +++ b/externals/meson @@ -1 +1 @@ -Subproject commit 29ef4478df6d3aaca40c7993f125b29409be1de2 +Subproject commit 41c650a040d50e0912d268af7a903a9ce1456dfa diff --git a/externals/opdi b/externals/opdi index e56f79cada2..1aabf5bd1ed 160000 --- a/externals/opdi +++ b/externals/opdi @@ -1 +1 @@ -Subproject commit e56f79cada202d21e7425f5d5cfd5b1153f2465e +Subproject commit 1aabf5bd1ed77611742eb655002f2ac7a3dddef9 From df160c0f3345092830ca3936275c89a07b9d73ca Mon Sep 17 00:00:00 2001 From: patelha57 Date: Sat, 10 Dec 2022 11:48:23 -0800 Subject: [PATCH 36/68] Update CoDiPack submodule version --- externals/codi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/externals/codi b/externals/codi index 6a67202a388..96ac78ec5bc 160000 --- a/externals/codi +++ b/externals/codi @@ -1 +1 @@ -Subproject commit 6a67202a3887c8da490fdfde82bc46507de68692 +Subproject commit 96ac78ec5bcc5ac25b785e79b16ed76fca22d736 From 3a8ddae427e038e0e71d22dc49e5fc02ad262ee7 Mon Sep 17 00:00:00 2001 From: patelha57 Date: Sat, 10 Dec 2022 15:40:14 -0800 Subject: [PATCH 37/68] Apply clang format to CDriver.hpp --- SU2_CFD/include/drivers/CDriver.hpp | 1567 +++++++++++++-------------- 1 file changed, 778 insertions(+), 789 deletions(-) diff --git a/SU2_CFD/include/drivers/CDriver.hpp b/SU2_CFD/include/drivers/CDriver.hpp index aeb1467980b..50366afd833 100644 --- a/SU2_CFD/include/drivers/CDriver.hpp +++ b/SU2_CFD/include/drivers/CDriver.hpp @@ -28,14 +28,12 @@ #pragma once +#include "../../../Common/include/drivers/CDriverBase.hpp" +#include "../../../Common/include/geometry/CGeometry.hpp" #include "../../../Common/include/parallelization/mpi_structure.hpp" - #include "../integration/CIntegration.hpp" -#include "../solvers/CSolver.hpp" #include "../interfaces/CInterface.hpp" - -#include "../../../Common/include/geometry/CGeometry.hpp" -#include "../../../Common/include/drivers/CDriverBase.hpp" +#include "../solvers/CSolver.hpp" using namespace std; @@ -52,627 +50,633 @@ class COutput; */ class CDriver : public CDriverBase { - -protected: - - char runtime_file_name[MAX_STRING_SIZE]; - su2double UsedTimeOutput; /*!< \brief Elapsed time between Start and Stop point of the timer for tracking output phase.*/ - - su2double BandwidthSum = 0.0; /*!< \brief Aggregate value of the bandwidth for writing restarts (to be average later).*/ - unsigned long IterCount, /*!< \brief Iteration count stored for performance benchmarking.*/ - OutputCount; /*!< \brief Output count stored for performance benchmarking.*/ - unsigned long DOFsPerPoint; /*!< \brief Number of unknowns at each vertex, i.e., number of equations solved. */ - su2double Mpoints; /*!< \brief Total number of grid points in millions in the calculation (including ghost points).*/ - su2double MpointsDomain; /*!< \brief Total number of grid points in millions in the calculation (excluding ghost points).*/ - su2double MDOFs; /*!< \brief Total number of DOFs in millions in the calculation (including ghost points).*/ - su2double MDOFsDomain; /*!< \brief Total number of DOFs in millions in the calculation (excluding ghost points).*/ - - ofstream **ConvHist_file; /*!< \brief Convergence history file.*/ - ofstream FSIHist_file; /*!< \brief FSI convergence history file.*/ - - bool StopCalc, /*!< \brief Stop computation flag.*/ - mixingplane, /*!< \brief mixing-plane simulation flag.*/ - fsi, /*!< \brief FSI simulation flag.*/ - fem_solver; /*!< \brief FEM fluid solver simulation flag. */ - - CIteration ***iteration_container; /*!< \brief Container vector with all the iteration methods. */ - CIntegration ****integration_container; /*!< \brief Container vector with all the integration methods. */ - vector > > - interpolator_container; /*!< \brief Definition of the interpolation method between non-matching discretizations of the interface. */ - CInterface ***interface_container; /*!< \brief Definition of the interface of information and physics. */ - bool dry_run; /*!< \brief Flag if SU2_CFD was started as dry-run via "SU2_CFD -d .cfg" */ - -public: - - /*! - * \brief Constructor of the class. - * \param[in] confFile - Configuration file name. - * \param[in] val_nZone - Total number of zones. - * \param[in] val_nDim - Number of dimensions. - * \param[in] MPICommunicator - MPI communicator for SU2. - */ - CDriver(char* confFile, - unsigned short val_nZone, - SU2_Comm MPICommunicator, bool dummy_geo); - - /*! - * \brief Destructor of the class. - */ - virtual ~CDriver(void); - - /*! - * \brief A virtual member. - */ - virtual void Run() { }; - -protected: - - /*! - * \brief Init_Containers - */ - void SetContainers_Null(); - - /*! - * \brief Read in the config and mesh files. - */ - void Input_Preprocessing(CConfig **&config, CConfig *&driver_config); - - /*! - * \brief Construction of the edge-based data structure and the multigrid structure. - */ - void Geometrical_Preprocessing(CConfig *config, CGeometry **&geometry, bool dummy); - - /*! - * \brief Do the geometrical preprocessing for the DG FEM solver. - */ - void Geometrical_Preprocessing_DGFEM(CConfig *config, CGeometry **&geometry); - - /*! - * \brief Geometrical_Preprocessing_FVM - */ - void Geometrical_Preprocessing_FVM(CConfig *config, CGeometry **&geometry); - - /*! - * \brief Definition of the physics iteration class or within a single zone. - * \param[in] iteration_container - Pointer to the iteration container to be instantiated. - * \param[in] config - Definition of the particular problem. - * \param[in] iZone - Index of the zone. - */ - void Iteration_Preprocessing(CConfig *config, CIteration *&iteration) const; - - /*! - * \brief Definition and allocation of all solution classes. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void Solver_Preprocessing(CConfig *config, CGeometry **geometry, CSolver ***&solver); - - /*! - * \brief Restart of the solvers from the restart files. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void Solver_Restart(CSolver ***solver, CGeometry **geometry, CConfig *config, bool update_geo); - - /*! - * \brief Definition and allocation of all solution classes. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void Solver_Postprocessing(CSolver ****solver, CGeometry **geometry, CConfig *config, unsigned short val_iInst); - - /*! - * \brief Definition and allocation of all integration classes. - * \param[in] config - Definition of the particular problem. - * \param[in] solver - Container vector with all the solutions. - * \param[out] integration - Container vector with all the integration methods. - */ - void Integration_Preprocessing(CConfig *config, CSolver **solver, CIntegration **&integration) const; - - /*! - * \brief Definition and allocation of all integration classes. - * \param[in] integration_container - Container vector with all the integration methods. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void Integration_Postprocessing(CIntegration ***integration, CGeometry **geometry, CConfig *config, unsigned short val_iInst); - - /*! - * \brief Definition and allocation of all interface classes. - */ - void Interface_Preprocessing(CConfig **config, CSolver *****solver, CGeometry ****geometry, - unsigned short **interface_types, CInterface ***interface, - vector > > &interpolation); - - /*! - * \brief Definition and allocation of all solver classes. - * \param[in] numerics_container - Description of the numerical method (the way in which the equations are solved). - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] config - Definition of the particular problem. - */ - void Numerics_Preprocessing(CConfig *config, CGeometry **geometry, CSolver ***solver, CNumerics ****&numerics) const; - - /*! - * \brief Helper to instantiate turbulence numerics specialized for different flow solvers. - */ - template - void InstantiateTurbulentNumerics(unsigned short nVar_Turb, int offset, const CConfig *config, - const CSolver* turb_solver, CNumerics ****&numerics) const; - - /*! - * \brief Helper to instantiate transition numerics specialized for different flow solvers. - */ - template - void InstantiateTransitionNumerics(unsigned short nVar_Trans, int offset, const CConfig *config, - const CSolver* trans_solver, CNumerics ****&numerics) const; - /*! - * \brief Helper to instantiate species transport numerics specialized for different flow solvers. - */ - template - void InstantiateSpeciesNumerics(unsigned short nVar_Species, int offset, const CConfig *config, - const CSolver* species_solver, CNumerics ****&numerics) const; - - /*! - * \brief Definition and allocation of all solver classes. - * \param[in] numerics_container - Description of the numerical method (the way in which the equations are solved). - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void Numerics_Postprocessing(CNumerics *****numerics, CSolver ***solver, CGeometry **geometry, CConfig *config, unsigned short val_iInst); - - /*! - * \brief GridMovement_Preprocessing - * \param config - * \param geometry - * \param solver - * \param iteration - * \param grid_movement - * \param surface_movement - */ - void DynamicMesh_Preprocessing(CConfig *config, CGeometry **geometry, CSolver ***solver, CIteration *iteration, CVolumetricMovement *&grid_movement, CSurfaceMovement *&surface_movement) const; - - /*! - * \brief Initialize Python interface functionalities - */ - void PythonInterface_Preprocessing(CConfig** config, CGeometry**** geometry, CSolver***** solver); - - /*! - * \brief Preprocess the output container. - */ - void Output_Preprocessing(CConfig **config, CConfig *driver_config, COutput **&output_container, COutput *&driver_output); - - /*! - * \brief Initiate value for static mesh movement such as the gridVel for the ROTATING frame. - */ - void StaticMesh_Preprocessing(const CConfig *config, CGeometry **geometry); - - /*! - * \brief Initiate value for static mesh movement such as the gridVel for the ROTATING frame. - */ - void Turbomachinery_Preprocessing(CConfig** config, CGeometry**** geometry, CSolver***** solver, - CInterface*** interface); - - /*! - * \brief A virtual member. - * \param[in] donorZone - zone in which the displacements will be predicted. - * \param[in] targetZone - zone which receives the predicted displacements. - */ - virtual void Predict_Displacements(unsigned short donorZone, unsigned short targetZone) {} - - /*! - * \brief A virtual member. - * \param[in] donorZone - zone in which the tractions will be predicted. - * \param[in] targetZone - zone which receives the predicted traction. - */ - virtual void Predict_Tractions(unsigned short donorZone, unsigned short targetZone) {} - - /*! - * \brief A virtual member. - * \param[in] donorZone - zone in which the displacements will be transferred. - * \param[in] targetZone - zone which receives the tractions transferred. - */ - virtual void Transfer_Displacements(unsigned short donorZone, unsigned short targetZone) {} - - /*! - * \brief A virtual member. - * \param[in] donorZone - zone from which the tractions will be transferred. - * \param[in] targetZone - zone which receives the tractions transferred. - */ - virtual void Transfer_Tractions(unsigned short donorZone, unsigned short targetZone) {} - - /*! - * \brief A virtual member. - * \param[in] donorZone - origin of the information. - * \param[in] targetZone - destination of the information. - * \param[in] iOuterIter - Fluid-Structure Interaction subiteration. - */ - virtual void Relaxation_Displacements(unsigned short donorZone, unsigned short targetZone, unsigned long iOuterIter) {} - - /*! - * \brief A virtual member. - * \param[in] donorZone - origin of the information. - * \param[in] targetZone - destination of the information. - * \param[in] iOuterIter - Fluid-Structure Interaction subiteration. - */ - virtual void Relaxation_Tractions(unsigned short donorZone, unsigned short targetZone, unsigned long iOuterIter) {} - - /*! - * \brief A virtual member to run a Block Gauss-Seidel iteration in multizone problems. - */ - virtual void Run_GaussSeidel(){} - - /*! - * \brief A virtual member to run a Block-Jacobi iteration in multizone problems. - */ - virtual void Run_Jacobi(){} - - /*! - * \brief A virtual member. - */ - virtual void Update() {} - - /*! - * \brief Print out the direct residuals. - * \param[in] kind_recording - Type of recording (full list in ENUM_RECORDING, option_structure.hpp) - */ - void Print_DirectResidual(RECORDING kind_recording); - -public: - - /*! - * \brief Launch the computation for all zones and all physics. - */ - virtual void StartSolver() {} - - /*! - * \brief Deallocation routine - */ - void Postprocessing(); - - /*! - * \brief A virtual member. - */ - virtual void ResetConvergence(); - - /*! - * \brief Perform some pre-processing before an iteration of the physics. - */ - virtual void Preprocess(unsigned long TimeIter){ } - - /*! - * \brief Monitor the computation. - */ - virtual bool Monitor(unsigned long TimeIter){ return false; } - - /*! - * \brief Output the solution in solution file. - */ - virtual void Output(unsigned long TimeIter){ } - - /*! - * \brief Perform a dynamic mesh deformation, including grid velocity computation and update of the multigrid structure. - */ - virtual void DynamicMeshUpdate(unsigned long TimeIter) { } - - /*! - * \brief Perform a dynamic mesh deformation, including grid velocity computation and update of the multigrid structure. - */ - virtual void DynamicMeshUpdate(unsigned short val_iZone, unsigned long TimeIter) { } - - /*! - * \brief Perform a mesh deformation as initial condition. - */ - virtual void SetInitialMesh() { } - - /*! - * \brief Process the boundary conditions and update the multigrid structure. - */ - void BoundaryConditionsUpdate(); - - /*! - * \brief Get the total drag. - * \return Total drag. - */ - passivedouble Get_Drag() const; - - /*! - * \brief Get the total lift. - * \return Total lift. - */ - passivedouble Get_Lift() const; - - /*! - * \brief Get the total x moment. - * \return Total x moment. - */ - passivedouble Get_Mx() const; - - /*! - * \brief Get the total y moment. - * \return Total y moment. - */ - passivedouble Get_My() const; - - /*! - * \brief Get the total z moment. - * \return Total z moment. - */ - passivedouble Get_Mz() const; - - /*! - * \brief Get the total drag coefficient. - * \return Total drag coefficient. - */ - passivedouble Get_DragCoeff() const; - - /*! - * \brief Get the total lift coefficient. - * \return Total lift coefficient. - */ - passivedouble Get_LiftCoeff() const; - - /*! - * \brief Get the number of external iterations. - * \return Number of external iterations. - */ - unsigned long GetnTimeIter() const; - - /*! - * \brief Get the current external iteration. - * \return Current external iteration. - */ - unsigned long GetTime_Iter() const; - - /*! - * \brief Get the unsteady time step. - * \return Unsteady time step. - */ - passivedouble GetUnsteady_TimeStep() const; - - /*! - * \brief Get the name of the output file for the surface. - * \return File name for the surface output. - */ - string GetSurfaceFileName() const; - - /*! - * \brief Get the temperature at a vertex on a specified marker. - * \param[in] iMarker - Marker identifier. - * \param[in] iVertex - Vertex identifier. - * \return Temperature of the vertex. - */ - passivedouble GetVertexTemperature(unsigned short iMarker, unsigned long iVertex) const; - - /*! - * \brief Set the temperature of a vertex on a specified marker. - * \param[in] iMarker - Marker identifier. - * \param[in] iVertex - Vertex identifier. - * \param[in] val_WallTemp - Value of the temperature. - */ - void SetVertexTemperature(unsigned short iMarker, unsigned long iVertex, passivedouble val_WallTemp); - - /*! - * \brief Get the heat flux at a vertex on a specified marker (3 components). - * \param[in] iMarker - Marker identifier. - * \param[in] iVertex - Vertex identifier. - * \return True if the vertex is a halo node. - */ - vector GetVertexHeatFluxes(unsigned short iMarker, unsigned long iVertex) const; - - /*! - * \brief Get the wall normal component of the heat flux at a vertex on a specified marker. - * \param[in] iMarker - Marker identifier. - * \param[in] iVertex - Vertex identifier. - * \return Wall normal component of the heat flux at the vertex. - */ - passivedouble GetVertexNormalHeatFlux(unsigned short iMarker, unsigned long iVertex) const; - - /*! - * \brief Set the wall normal component of the heat flux at a vertex on a specified marker. - * \param[in] iMarker - Marker identifier. - * \param[in] iVertex - Vertex identifier. - * \param[in] val_WallHeatFlux - Value of the normal heat flux. - */ - void SetVertexNormalHeatFlux(unsigned short iMarker, unsigned long iVertex, passivedouble val_WallHeatFlux); - - /*! - * \brief Get the thermal conductivity at a vertex on a specified marker. - * \param[in] iMarker - Marker identifier. - * \param[in] iVertex - Vertex identifier. - * \return Thermal conductivity at the vertex. - */ - passivedouble GetThermalConductivity(unsigned short iMarker, unsigned long iVertex) const; - - /*! - * \brief Preprocess the inlets via file input for all solvers. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void Inlet_Preprocessing(CSolver ***solver, CGeometry **geometry, CConfig *config) const; - - /*! - * \brief Get all the CHT boundary marker tags. - * \return List of CHT boundary markers tags. - */ - vector GetCHTMarkerTags() const; - - /*! - * \brief Get all the inlet boundary marker tags. - * \return List of inlet boundary markers tags. - */ - vector GetInletMarkerTags() const; - - /*! - * \brief Return the sensitivities of the mesh boundary vertices. - * \param[in] iMarker - Marker identifier. - * \param[in] iVertex - Vertex identifier. - * \return Vector of sensitivities. - */ - vector GetMeshDisp_Sensitivity(unsigned short iMarker, unsigned long iVertex) const; - - /*! - * \brief Set the load in X direction for the structural solver. - * \param[in] iMarker - Marker identifier. - * \param[in] iVertex - Vertex identifier. - * \param[in] LoadX - Value of the load in the direction X. - * \param[in] LoadX - Value of the load in the direction Y. - * \param[in] LoadX - Value of the load in the direction Z. - */ - void SetFEA_Loads(unsigned short iMarker, unsigned long iVertex, passivedouble LoadX, passivedouble LoadY, passivedouble LoadZ); - - /*! - * \brief Return the displacements from the FEA solver. - * \param[in] iMarker - Marker identifier. - * \param[in] iVertex - Vertex identifier. - * \return Vector of displacements. - */ - vector GetFEA_Displacements(unsigned short iMarker, unsigned long iVertex) const; - - /*! - * \brief Return the velocities from the FEA Solver. - * \param[in] iMarker - Marker identifier. - * \param[in] iVertex - Vertex identifier. - * \return Vector of velocities. - */ - vector GetFEA_Velocity(unsigned short iMarker, unsigned long iVertex) const; - - /*! - * \brief Return the velocities from the FEA Solver. - * \param[in] iMarker - Marker identifier. - * \param[in] iVertex - Vertex identifier. - * \return Vector of velocities at time n. - */ - vector GetFEA_Velocity_n(unsigned short iMarker, unsigned long iVertex) const; - - /*! - * \brief Get the sensitivity of the flow loads for the structural solver. - * \param[in] iMarker - Marker identifier. - * \param[in] iVertex - Vertex identifier. - * \param[in] LoadX - Value of the load in the direction X. - * \param[in] LoadX - Value of the load in the direction Y. - * \param[in] LoadX - Value of the load in the direction Z. - */ - vector GetFlowLoad_Sensitivity(unsigned short iMarker, unsigned long iVertex) const; - - /*! - * \brief Get the flow load (from the extra step - the repeated methods should be unified once the postprocessing - * strategy is in place). - * \param[in] iMarker - Marker identifier. - * \param[in] iVertex - Vertex identifier. - */ - vector GetFlowLoad(unsigned short iMarker, unsigned long iVertex) const; - - /*! - * \brief Set the adjoint of the flow tractions (from the extra step - - * the repeated methods should be unified once the postprocessing strategy is in place). - * \param[in] iMarker - Marker identifier. - * \param[in] iVertex - Vertex identifier. - * \param[in] val_AdjointX - Value of the adjoint in the direction X. - * \param[in] val_AdjointY - Value of the adjoint in the direction Y. - * \param[in] val_AdjointZ - Value of the adjoint in the direction Z. - */ - void SetFlowLoad_Adjoint(unsigned short iMarker, unsigned long iVertex, passivedouble val_AdjointX, - passivedouble val_AdjointY, passivedouble val_AdjointZ); - - /*! - * \brief Set the adjoint of the structural displacements (from an outside source) - * \param[in] iMarker - Marker identifier. - * \param[in] iVertex - Vertex identifier. - * \param[in] val_AdjointX - Value of the adjoint in the direction X. - * \param[in] val_AdjointY - Value of the adjoint in the direction Y. - * \param[in] val_AdjointZ - Value of the adjoint in the direction Z. - */ - void SetSourceTerm_DispAdjoint(unsigned short iMarker, unsigned long iVertex, passivedouble val_AdjointX, - passivedouble val_AdjointY, passivedouble val_AdjointZ); - void SetSourceTerm_VelAdjoint(unsigned short iMarker, unsigned long iVertex, passivedouble val_AdjointX, - passivedouble val_AdjointY, passivedouble val_AdjointZ); - - /*! - * \brief Set the position of the heat source. - * \param[in] alpha - Angle of rotation respect to Z axis. - * \param[in] pos_x - Position X. - * \param[in] pos_y - Position Y. - * \param[in] pos_z - Position Z. - */ - void SetHeatSource_Position(passivedouble alpha, passivedouble pos_x, passivedouble pos_y, passivedouble pos_z); - - /*! - * \brief Set the direction of the inlet. - * \param[in] iMarker - Marker index. - * \param[in] alpha - Angle (Zpos). - */ - void SetInlet_Angle(unsigned short iMarker, passivedouble alpha); - - /*! - * \brief Sum the number of primal or adjoint variables for all solvers in a given zone. - * \param[in] iZone - Index of the zone. - * \param[in] adjoint - True to consider adjoint solvers instead of primal. - * \return Total number of solution variables. - */ - unsigned short GetTotalNumberOfVariables(unsigned short iZone, bool adjoint) const { - unsigned short nVar = 0; - for (auto iSol = 0u; iSol < MAX_SOLS; iSol++) { - auto solver = solver_container[iZone][INST_0][MESH_0][iSol]; - if (solver && (solver->GetAdjoint() == adjoint)) nVar += solver->GetnVar(); - } - return nVar; - } - - /*! - * \brief Set the solution of all solvers (adjoint or primal) in a zone. - * \param[in] iZone - Index of the zone. - * \param[in] adjoint - True to consider adjoint solvers instead of primal. - * \param[in] solution - Solution object with interface (iPoint,iVar). - * \tparam Old - If true set "old solutions" instead. - */ - template - void SetAllSolutions(unsigned short iZone, bool adjoint, const Container& solution) { - const auto nPoint = geometry_container[iZone][INST_0][MESH_0]->GetnPoint(); - for (auto iSol = 0u, offset = 0u; iSol < MAX_SOLS; ++iSol) { - auto solver = solver_container[iZone][INST_0][MESH_0][iSol]; - if (!(solver && (solver->GetAdjoint() == adjoint))) continue; - for (auto iPoint = 0ul; iPoint < nPoint; ++iPoint) - for (auto iVar = 0ul; iVar < solver->GetnVar(); ++iVar) - if (!Old) solver->GetNodes()->SetSolution(iPoint, iVar, solution(iPoint,offset+iVar)); - else solver->GetNodes()->SetSolution_Old(iPoint, iVar, solution(iPoint,offset+iVar)); - offset += solver->GetnVar(); - } + protected: + char runtime_file_name[MAX_STRING_SIZE]; + su2double + UsedTimeOutput; /*!< \brief Elapsed time between Start and Stop point of the timer for tracking output phase.*/ + + su2double BandwidthSum = + 0.0; /*!< \brief Aggregate value of the bandwidth for writing restarts (to be average later).*/ + unsigned long IterCount, /*!< \brief Iteration count stored for performance benchmarking.*/ + OutputCount; /*!< \brief Output count stored for performance benchmarking.*/ + unsigned long DOFsPerPoint; /*!< \brief Number of unknowns at each vertex, i.e., number of equations solved. */ + su2double Mpoints; /*!< \brief Total number of grid points in millions in the calculation (including ghost points).*/ + su2double + MpointsDomain; /*!< \brief Total number of grid points in millions in the calculation (excluding ghost points).*/ + su2double MDOFs; /*!< \brief Total number of DOFs in millions in the calculation (including ghost points).*/ + su2double MDOFsDomain; /*!< \brief Total number of DOFs in millions in the calculation (excluding ghost points).*/ + + ofstream** ConvHist_file; /*!< \brief Convergence history file.*/ + ofstream FSIHist_file; /*!< \brief FSI convergence history file.*/ + + bool StopCalc, /*!< \brief Stop computation flag.*/ + mixingplane, /*!< \brief mixing-plane simulation flag.*/ + fsi, /*!< \brief FSI simulation flag.*/ + fem_solver; /*!< \brief FEM fluid solver simulation flag. */ + + CIteration*** iteration_container; /*!< \brief Container vector with all the iteration methods. */ + CIntegration**** integration_container; /*!< \brief Container vector with all the integration methods. */ + vector>> + interpolator_container; /*!< \brief Definition of the interpolation method between non-matching discretizations of + the interface. */ + CInterface*** interface_container; /*!< \brief Definition of the interface of information and physics. */ + bool dry_run; /*!< \brief Flag if SU2_CFD was started as dry-run via "SU2_CFD -d .cfg" */ + + public: + /*! + * \brief Constructor of the class. + * \param[in] confFile - Configuration file name. + * \param[in] val_nZone - Total number of zones. + * \param[in] val_nDim - Number of dimensions. + * \param[in] MPICommunicator - MPI communicator for SU2. + */ + CDriver(char* confFile, unsigned short val_nZone, SU2_Comm MPICommunicator, bool dummy_geo); + + /*! + * \brief Destructor of the class. + */ + virtual ~CDriver(void); + + /*! + * \brief A virtual member. + */ + virtual void Run(){}; + + protected: + /*! + * \brief Init_Containers + */ + void SetContainers_Null(); + + /*! + * \brief Read in the config and mesh files. + */ + void Input_Preprocessing(CConfig**& config, CConfig*& driver_config); + + /*! + * \brief Construction of the edge-based data structure and the multi-grid structure. + */ + void Geometrical_Preprocessing(CConfig* config, CGeometry**& geometry, bool dummy); + + /*! + * \brief Do the geometrical preprocessing for the DG FEM solver. + */ + void Geometrical_Preprocessing_DGFEM(CConfig* config, CGeometry**& geometry); + + /*! + * \brief Geometrical_Preprocessing_FVM + */ + void Geometrical_Preprocessing_FVM(CConfig* config, CGeometry**& geometry); + + /*! + * \brief Definition of the physics iteration class or within a single zone. + * \param[in] iteration_container - Pointer to the iteration container to be instantiated. + * \param[in] config - Definition of the particular problem. + * \param[in] iZone - Index of the zone. + */ + void Iteration_Preprocessing(CConfig* config, CIteration*& iteration) const; + + /*! + * \brief Definition and allocation of all solution classes. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void Solver_Preprocessing(CConfig* config, CGeometry** geometry, CSolver***& solver); + + /*! + * \brief Restart of the solvers from the restart files. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void Solver_Restart(CSolver*** solver, CGeometry** geometry, CConfig* config, bool update_geo); + + /*! + * \brief Definition and allocation of all solution classes. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void Solver_Postprocessing(CSolver**** solver, CGeometry** geometry, CConfig* config, unsigned short val_iInst); + + /*! + * \brief Definition and allocation of all integration classes. + * \param[in] config - Definition of the particular problem. + * \param[in] solver - Container vector with all the solutions. + * \param[out] integration - Container vector with all the integration methods. + */ + void Integration_Preprocessing(CConfig* config, CSolver** solver, CIntegration**& integration) const; + + /*! + * \brief Definition and allocation of all integration classes. + * \param[in] integration_container - Container vector with all the integration methods. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void Integration_Postprocessing(CIntegration*** integration, CGeometry** geometry, CConfig* config, + unsigned short val_iInst); + + /*! + * \brief Definition and allocation of all interface classes. + */ + void Interface_Preprocessing(CConfig** config, CSolver***** solver, CGeometry**** geometry, + unsigned short** interface_types, CInterface*** interface, + vector>>& interpolation); + + /*! + * \brief Definition and allocation of all solver classes. + * \param[in] numerics_container - Description of the numerical method (the way in which the equations are solved). + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] config - Definition of the particular problem. + */ + void Numerics_Preprocessing(CConfig* config, CGeometry** geometry, CSolver*** solver, CNumerics****& numerics) const; + + /*! + * \brief Helper to instantiate turbulence numerics specialized for different flow solvers. + */ + template + void InstantiateTurbulentNumerics(unsigned short nVar_Turb, int offset, const CConfig* config, + const CSolver* turb_solver, CNumerics****& numerics) const; + + /*! + * \brief Helper to instantiate transition numerics specialized for different flow solvers. + */ + template + void InstantiateTransitionNumerics(unsigned short nVar_Trans, int offset, const CConfig* config, + const CSolver* trans_solver, CNumerics****& numerics) const; + /*! + * \brief Helper to instantiate species transport numerics specialized for different flow solvers. + */ + template + void InstantiateSpeciesNumerics(unsigned short nVar_Species, int offset, const CConfig* config, + const CSolver* species_solver, CNumerics****& numerics) const; + + /*! + * \brief Definition and allocation of all solver classes. + * \param[in] numerics_container - Description of the numerical method (the way in which the equations are solved). + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void Numerics_Postprocessing(CNumerics***** numerics, CSolver*** solver, CGeometry** geometry, CConfig* config, + unsigned short val_iInst); + + /*! + * \brief GridMovement_Preprocessing + * \param config + * \param geometry + * \param solver + * \param iteration + * \param grid_movement + * \param surface_movement + */ + void DynamicMesh_Preprocessing(CConfig* config, CGeometry** geometry, CSolver*** solver, CIteration* iteration, + CVolumetricMovement*& grid_movement, CSurfaceMovement*& surface_movement) const; + + /*! + * \brief Initialize Python interface functionalities + */ + void PythonInterface_Preprocessing(CConfig** config, CGeometry**** geometry, CSolver***** solver); + + /*! + * \brief Preprocess the output container. + */ + void Output_Preprocessing(CConfig** config, CConfig* driver_config, COutput**& output_container, + COutput*& driver_output); + + /*! + * \brief Initiate value for static mesh movement such as the gridVel for the ROTATING frame. + */ + void StaticMesh_Preprocessing(const CConfig* config, CGeometry** geometry); + + /*! + * \brief Initiate value for static mesh movement such as the gridVel for the ROTATING frame. + */ + void Turbomachinery_Preprocessing(CConfig** config, CGeometry**** geometry, CSolver***** solver, + CInterface*** interface); + + /*! + * \brief A virtual member. + * \param[in] donorZone - zone in which the displacements will be predicted. + * \param[in] targetZone - zone which receives the predicted displacements. + */ + virtual void Predict_Displacements(unsigned short donorZone, unsigned short targetZone) {} + + /*! + * \brief A virtual member. + * \param[in] donorZone - zone in which the tractions will be predicted. + * \param[in] targetZone - zone which receives the predicted traction. + */ + virtual void Predict_Tractions(unsigned short donorZone, unsigned short targetZone) {} + + /*! + * \brief A virtual member. + * \param[in] donorZone - zone in which the displacements will be transferred. + * \param[in] targetZone - zone which receives the tractions transferred. + */ + virtual void Transfer_Displacements(unsigned short donorZone, unsigned short targetZone) {} + + /*! + * \brief A virtual member. + * \param[in] donorZone - zone from which the tractions will be transferred. + * \param[in] targetZone - zone which receives the tractions transferred. + */ + virtual void Transfer_Tractions(unsigned short donorZone, unsigned short targetZone) {} + + /*! + * \brief A virtual member. + * \param[in] donorZone - origin of the information. + * \param[in] targetZone - destination of the information. + * \param[in] iOuterIter - Fluid-Structure Interaction subiteration. + */ + virtual void Relaxation_Displacements(unsigned short donorZone, unsigned short targetZone, unsigned long iOuterIter) {} + + /*! + * \brief A virtual member. + * \param[in] donorZone - origin of the information. + * \param[in] targetZone - destination of the information. + * \param[in] iOuterIter - Fluid-Structure Interaction subiteration. + */ + virtual void Relaxation_Tractions(unsigned short donorZone, unsigned short targetZone, unsigned long iOuterIter) {} + + /*! + * \brief A virtual member to run a Block Gauss-Seidel iteration in multi-zone problems. + */ + virtual void Run_GaussSeidel() {} + + /*! + * \brief A virtual member to run a Block-Jacobi iteration in multi-zone problems. + */ + virtual void Run_Jacobi() {} + + /*! + * \brief A virtual member. + */ + virtual void Update() {} + + /*! + * \brief Print out the direct residuals. + * \param[in] kind_recording - Type of recording (full list in ENUM_RECORDING, option_structure.hpp) + */ + void Print_DirectResidual(RECORDING kind_recording); + + public: + /*! + * \brief Launch the computation for all zones and all physics. + */ + virtual void StartSolver() {} + + /*! + * \brief Deallocation routine + */ + void Postprocessing(); + + /*! + * \brief A virtual member. + */ + virtual void ResetConvergence(); + + /*! + * \brief Perform some pre-processing before an iteration of the physics. + */ + virtual void Preprocess(unsigned long TimeIter) {} + + /*! + * \brief Monitor the computation. + */ + virtual bool Monitor(unsigned long TimeIter) { return false; } + + /*! + * \brief Output the solution in solution file. + */ + virtual void Output(unsigned long TimeIter) {} + + /*! + * \brief Perform a dynamic mesh deformation, including grid velocity computation and update of the multi-grid + * structure. + */ + virtual void DynamicMeshUpdate(unsigned long TimeIter) {} + + /*! + * \brief Perform a dynamic mesh deformation, including grid velocity computation and update of the multi-grid + * structure. + */ + virtual void DynamicMeshUpdate(unsigned short val_iZone, unsigned long TimeIter) {} + + /*! + * \brief Perform a mesh deformation as initial condition. + */ + virtual void SetInitialMesh() {} + + /*! + * \brief Process the boundary conditions and update the multi-grid structure. + */ + void BoundaryConditionsUpdate(); + + /*! + * \brief Get the total drag. + * \return Total drag. + */ + passivedouble Get_Drag() const; + + /*! + * \brief Get the total lift. + * \return Total lift. + */ + passivedouble Get_Lift() const; + + /*! + * \brief Get the total x moment. + * \return Total x moment. + */ + passivedouble Get_Mx() const; + + /*! + * \brief Get the total y moment. + * \return Total y moment. + */ + passivedouble Get_My() const; + + /*! + * \brief Get the total z moment. + * \return Total z moment. + */ + passivedouble Get_Mz() const; + + /*! + * \brief Get the total drag coefficient. + * \return Total drag coefficient. + */ + passivedouble Get_DragCoeff() const; + + /*! + * \brief Get the total lift coefficient. + * \return Total lift coefficient. + */ + passivedouble Get_LiftCoeff() const; + + /*! + * \brief Get the number of external iterations. + * \return Number of external iterations. + */ + unsigned long GetnTimeIter() const; + + /*! + * \brief Get the current external iteration. + * \return Current external iteration. + */ + unsigned long GetTime_Iter() const; + + /*! + * \brief Get the unsteady time step. + * \return Unsteady time step. + */ + passivedouble GetUnsteady_TimeStep() const; + + /*! + * \brief Get the name of the output file for the surface. + * \return File name for the surface output. + */ + string GetSurfaceFileName() const; + + /*! + * \brief Get the temperature at a vertex on a specified marker. + * \param[in] iMarker - Marker identifier. + * \param[in] iVertex - Vertex identifier. + * \return Temperature of the vertex. + */ + passivedouble GetVertexTemperature(unsigned short iMarker, unsigned long iVertex) const; + + /*! + * \brief Set the temperature of a vertex on a specified marker. + * \param[in] iMarker - Marker identifier. + * \param[in] iVertex - Vertex identifier. + * \param[in] val_WallTemp - Value of the temperature. + */ + void SetVertexTemperature(unsigned short iMarker, unsigned long iVertex, passivedouble val_WallTemp); + + /*! + * \brief Get the heat flux at a vertex on a specified marker (3 components). + * \param[in] iMarker - Marker identifier. + * \param[in] iVertex - Vertex identifier. + * \return True if the vertex is a halo node. + */ + vector GetVertexHeatFluxes(unsigned short iMarker, unsigned long iVertex) const; + + /*! + * \brief Get the wall normal component of the heat flux at a vertex on a specified marker. + * \param[in] iMarker - Marker identifier. + * \param[in] iVertex - Vertex identifier. + * \return Wall normal component of the heat flux at the vertex. + */ + passivedouble GetVertexNormalHeatFlux(unsigned short iMarker, unsigned long iVertex) const; + + /*! + * \brief Set the wall normal component of the heat flux at a vertex on a specified marker. + * \param[in] iMarker - Marker identifier. + * \param[in] iVertex - Vertex identifier. + * \param[in] val_WallHeatFlux - Value of the normal heat flux. + */ + void SetVertexNormalHeatFlux(unsigned short iMarker, unsigned long iVertex, passivedouble val_WallHeatFlux); + + /*! + * \brief Get the thermal conductivity at a vertex on a specified marker. + * \param[in] iMarker - Marker identifier. + * \param[in] iVertex - Vertex identifier. + * \return Thermal conductivity at the vertex. + */ + passivedouble GetThermalConductivity(unsigned short iMarker, unsigned long iVertex) const; + + /*! + * \brief Preprocess the inlets via file input for all solvers. + * \param[in] solver_container - Container vector with all the solutions. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] config - Definition of the particular problem. + */ + void Inlet_Preprocessing(CSolver*** solver, CGeometry** geometry, CConfig* config) const; + + /*! + * \brief Get all the CHT boundary marker tags. + * \return List of CHT boundary markers tags. + */ + vector GetCHTMarkerTags() const; + + /*! + * \brief Get all the inlet boundary marker tags. + * \return List of inlet boundary markers tags. + */ + vector GetInletMarkerTags() const; + + /*! + * \brief Return the sensitivities of the mesh boundary vertices. + * \param[in] iMarker - Marker identifier. + * \param[in] iVertex - Vertex identifier. + * \return Vector of sensitivities. + */ + vector GetMeshDisp_Sensitivity(unsigned short iMarker, unsigned long iVertex) const; + + /*! + * \brief Set the load in X direction for the structural solver. + * \param[in] iMarker - Marker identifier. + * \param[in] iVertex - Vertex identifier. + * \param[in] LoadX - Value of the load in the direction X. + * \param[in] LoadX - Value of the load in the direction Y. + * \param[in] LoadX - Value of the load in the direction Z. + */ + void SetFEA_Loads(unsigned short iMarker, unsigned long iVertex, passivedouble LoadX, passivedouble LoadY, + passivedouble LoadZ); + + /*! + * \brief Return the displacements from the FEA solver. + * \param[in] iMarker - Marker identifier. + * \param[in] iVertex - Vertex identifier. + * \return Vector of displacements. + */ + vector GetFEA_Displacements(unsigned short iMarker, unsigned long iVertex) const; + + /*! + * \brief Return the velocities from the FEA Solver. + * \param[in] iMarker - Marker identifier. + * \param[in] iVertex - Vertex identifier. + * \return Vector of velocities. + */ + vector GetFEA_Velocity(unsigned short iMarker, unsigned long iVertex) const; + + /*! + * \brief Return the velocities from the FEA Solver. + * \param[in] iMarker - Marker identifier. + * \param[in] iVertex - Vertex identifier. + * \return Vector of velocities at time n. + */ + vector GetFEA_Velocity_n(unsigned short iMarker, unsigned long iVertex) const; + + /*! + * \brief Get the sensitivity of the flow loads for the structural solver. + * \param[in] iMarker - Marker identifier. + * \param[in] iVertex - Vertex identifier. + * \param[in] LoadX - Value of the load in the direction X. + * \param[in] LoadX - Value of the load in the direction Y. + * \param[in] LoadX - Value of the load in the direction Z. + */ + vector GetFlowLoad_Sensitivity(unsigned short iMarker, unsigned long iVertex) const; + + /*! + * \brief Get the flow load (from the extra step - the repeated methods should be unified once the postprocessing + * strategy is in place). + * \param[in] iMarker - Marker identifier. + * \param[in] iVertex - Vertex identifier. + */ + vector GetFlowLoad(unsigned short iMarker, unsigned long iVertex) const; + + /*! + * \brief Set the adjoint of the flow tractions (from the extra step - + * the repeated methods should be unified once the postprocessing strategy is in place). + * \param[in] iMarker - Marker identifier. + * \param[in] iVertex - Vertex identifier. + * \param[in] val_AdjointX - Value of the adjoint in the direction X. + * \param[in] val_AdjointY - Value of the adjoint in the direction Y. + * \param[in] val_AdjointZ - Value of the adjoint in the direction Z. + */ + void SetFlowLoad_Adjoint(unsigned short iMarker, unsigned long iVertex, passivedouble val_AdjointX, + passivedouble val_AdjointY, passivedouble val_AdjointZ); + + /*! + * \brief Set the adjoint of the structural displacements (from an outside source) + * \param[in] iMarker - Marker identifier. + * \param[in] iVertex - Vertex identifier. + * \param[in] val_AdjointX - Value of the adjoint in the direction X. + * \param[in] val_AdjointY - Value of the adjoint in the direction Y. + * \param[in] val_AdjointZ - Value of the adjoint in the direction Z. + */ + void SetSourceTerm_DispAdjoint(unsigned short iMarker, unsigned long iVertex, passivedouble val_AdjointX, + passivedouble val_AdjointY, passivedouble val_AdjointZ); + void SetSourceTerm_VelAdjoint(unsigned short iMarker, unsigned long iVertex, passivedouble val_AdjointX, + passivedouble val_AdjointY, passivedouble val_AdjointZ); + + /*! + * \brief Set the position of the heat source. + * \param[in] alpha - Angle of rotation respect to Z axis. + * \param[in] pos_x - Position X. + * \param[in] pos_y - Position Y. + * \param[in] pos_z - Position Z. + */ + void SetHeatSource_Position(passivedouble alpha, passivedouble pos_x, passivedouble pos_y, passivedouble pos_z); + + /*! + * \brief Set the direction of the inlet. + * \param[in] iMarker - Marker index. + * \param[in] alpha - Angle (Zpos). + */ + void SetInlet_Angle(unsigned short iMarker, passivedouble alpha); + + /*! + * \brief Sum the number of primal or adjoint variables for all solvers in a given zone. + * \param[in] iZone - Index of the zone. + * \param[in] adjoint - True to consider adjoint solvers instead of primal. + * \return Total number of solution variables. + */ + unsigned short GetTotalNumberOfVariables(unsigned short iZone, bool adjoint) const { + unsigned short nVar = 0; + for (auto iSol = 0u; iSol < MAX_SOLS; iSol++) { + auto solver = solver_container[iZone][INST_0][MESH_0][iSol]; + if (solver && (solver->GetAdjoint() == adjoint)) nVar += solver->GetnVar(); } - - /*! - * \brief Set the "old solution" of all solvers (adjoint or primal) in a zone. - */ - template - void SetAllSolutionsOld(unsigned short iZone, bool adjoint, const Container& solution) { - SetAllSolutions(iZone, adjoint, solution); + return nVar; + } + + /*! + * \brief Set the solution of all solvers (adjoint or primal) in a zone. + * \param[in] iZone - Index of the zone. + * \param[in] adjoint - True to consider adjoint solvers instead of primal. + * \param[in] solution - Solution object with interface (iPoint,iVar). + * \tparam Old - If true set "old solutions" instead. + */ + template + void SetAllSolutions(unsigned short iZone, bool adjoint, const Container& solution) { + const auto nPoint = geometry_container[iZone][INST_0][MESH_0]->GetnPoint(); + for (auto iSol = 0u, offset = 0u; iSol < MAX_SOLS; ++iSol) { + auto solver = solver_container[iZone][INST_0][MESH_0][iSol]; + if (!(solver && (solver->GetAdjoint() == adjoint))) continue; + for (auto iPoint = 0ul; iPoint < nPoint; ++iPoint) + for (auto iVar = 0ul; iVar < solver->GetnVar(); ++iVar) + if (!Old) { + solver->GetNodes()->SetSolution(iPoint, iVar, solution(iPoint, offset + iVar)); + } else { + solver->GetNodes()->SetSolution_Old(iPoint, iVar, solution(iPoint, offset + iVar)); + } + offset += solver->GetnVar(); } - - /*! - * \brief Get the solution of all solvers (adjoint or primal) in a zone. - * \param[in] iZone - Index of the zone. - * \param[in] adjoint - True to consider adjoint solvers instead of primal. - * \param[out] solution - Solution object with interface (iPoint,iVar). - */ - template - void GetAllSolutions(unsigned short iZone, bool adjoint, Container& solution) const { - const auto nPoint = geometry_container[iZone][INST_0][MESH_0]->GetnPoint(); - for (auto iSol = 0u, offset = 0u; iSol < MAX_SOLS; ++iSol) { - auto solver = solver_container[iZone][INST_0][MESH_0][iSol]; - if (!(solver && (solver->GetAdjoint() == adjoint))) continue; - const auto& sol = solver->GetNodes()->GetSolution(); - for (auto iPoint = 0ul; iPoint < nPoint; ++iPoint) - for (auto iVar = 0ul; iVar < solver->GetnVar(); ++iVar) - solution(iPoint,offset+iVar) = SU2_TYPE::GetValue(sol(iPoint,iVar)); - offset += solver->GetnVar(); - } + } + + /*! + * \brief Set the "old solution" of all solvers (adjoint or primal) in a zone. + */ + template + void SetAllSolutionsOld(unsigned short iZone, bool adjoint, const Container& solution) { + SetAllSolutions(iZone, adjoint, solution); + } + + /*! + * \brief Get the solution of all solvers (adjoint or primal) in a zone. + * \param[in] iZone - Index of the zone. + * \param[in] adjoint - True to consider adjoint solvers instead of primal. + * \param[out] solution - Solution object with interface (iPoint,iVar). + */ + template + void GetAllSolutions(unsigned short iZone, bool adjoint, Container& solution) const { + const auto nPoint = geometry_container[iZone][INST_0][MESH_0]->GetnPoint(); + for (auto iSol = 0u, offset = 0u; iSol < MAX_SOLS; ++iSol) { + auto solver = solver_container[iZone][INST_0][MESH_0][iSol]; + if (!(solver && (solver->GetAdjoint() == adjoint))) continue; + const auto& sol = solver->GetNodes()->GetSolution(); + for (auto iPoint = 0ul; iPoint < nPoint; ++iPoint) + for (auto iVar = 0ul; iVar < solver->GetnVar(); ++iVar) + solution(iPoint, offset + iVar) = SU2_TYPE::GetValue(sol(iPoint, iVar)); + offset += solver->GetnVar(); } - + } }; /*! @@ -682,71 +686,66 @@ class CDriver : public CDriverBase { * \author T. Economon, G. Gori */ class CFluidDriver : public CDriver { - -protected: - unsigned long Max_Iter; - -protected: - - /*! - * \brief Constructor of the class. - * \param[in] confFile - Configuration file name. - * \param[in] val_nZone - Total number of zones. - * \param[in] val_nDim - Number of dimensions. - * \param[in] MPICommunicator - MPI communicator for SU2. - */ - CFluidDriver(char* confFile, - unsigned short val_nZone, - SU2_Comm MPICommunicator); - -public: - /*! - * \brief Destructor of the class. - */ - ~CFluidDriver(void) override; - - /*! - * \brief Launch the computation for all zones and all physics. - */ - void StartSolver() override; - - /*! - * \brief Run a single iteration of the physics within multiple zones. - */ - void Run() override; - - /*! - * \brief Update the dual-time solution within multiple zones. - */ - void Update() override; - - /*! - * \brief Output the solution in solution file. - */ - void Output(unsigned long InnerIter) override; - - /*! - * \brief Monitor the computation. - */ - bool Monitor(unsigned long ExtIter) override; - - /*! - * \brief Perform some pre-processing before an iteration of the physics. - */ - void Preprocess(unsigned long Iter) override; - - /*! - * \brief Perform a dynamic mesh deformation, included grid velocity computation and the update of the multigrid structure (multiple zone). - */ - void DynamicMeshUpdate(unsigned long TimeIter) override; - - /*! - * \brief Transfer data among different zones (multiple zone). - */ - void Transfer_Data(unsigned short donorZone, unsigned short targetZone); - -}; + protected: + unsigned long Max_Iter; + + protected: + /*! + * \brief Constructor of the class. + * \param[in] confFile - Configuration file name. + * \param[in] val_nZone - Total number of zones. + * \param[in] val_nDim - Number of dimensions. + * \param[in] MPICommunicator - MPI communicator for SU2. + */ + CFluidDriver(char* confFile, unsigned short val_nZone, SU2_Comm MPICommunicator); + + public: + /*! + * \brief Destructor of the class. + */ + ~CFluidDriver(void) override; + + /*! + * \brief Launch the computation for all zones and all physics. + */ + void StartSolver() override; + + /*! + * \brief Run a single iteration of the physics within multiple zones. + */ + void Run() override; + /*! + * \brief Update the dual-time solution within multiple zones. + */ + void Update() override; + + /*! + * \brief Output the solution in solution file. + */ + void Output(unsigned long InnerIter) override; + + /*! + * \brief Monitor the computation. + */ + bool Monitor(unsigned long ExtIter) override; + + /*! + * \brief Perform some pre-processing before an iteration of the physics. + */ + void Preprocess(unsigned long Iter) override; + + /*! + * \brief Perform a dynamic mesh deformation, included grid velocity computation and the update of the multi-grid + * structure (multiple zone). + */ + void DynamicMeshUpdate(unsigned long TimeIter) override; + + /*! + * \brief Transfer data among different zones (multiple zone). + */ + void Transfer_Data(unsigned short donorZone, unsigned short targetZone); +}; /*! * \class CTurbomachineryDriver @@ -755,51 +754,45 @@ class CFluidDriver : public CDriver { * \author S. Vitale */ class CTurbomachineryDriver : public CFluidDriver { -private: - COutputLegacy* output_legacy; - -public: - - /*! - * \brief Constructor of the class. - * \param[in] confFile - Configuration file name. - * \param[in] val_nZone - Total number of zones. - * \param[in] val_nDim - Number of dimensions. - * \param[in] val_periodic - Bool for periodic BCs. - * \param[in] MPICommunicator - MPI communicator for SU2. - */ - CTurbomachineryDriver(char* confFile, - unsigned short val_nZone, - SU2_Comm MPICommunicator); - - /*! - * \brief Destructor of the class. - */ - ~CTurbomachineryDriver(void) override; - - /*! - * \brief Run a single iteration of the physics within multiple zones. - */ - - void Run() override; - - /*! - * \brief Set Mixing Plane interface within multiple zones. - */ - void SetMixingPlane(unsigned short iZone); - - /*! - * \brief Set Mixing Plane interface within multiple zones. - */ - void SetTurboPerformance(unsigned short targetZone); - - /*! - * \brief Monitor the computation. - */ - bool Monitor(unsigned long TimeIter) override; - - - + private: + COutputLegacy* output_legacy; + + public: + /*! + * \brief Constructor of the class. + * \param[in] confFile - Configuration file name. + * \param[in] val_nZone - Total number of zones. + * \param[in] val_nDim - Number of dimensions. + * \param[in] val_periodic - Bool for periodic BCs. + * \param[in] MPICommunicator - MPI communicator for SU2. + */ + CTurbomachineryDriver(char* confFile, unsigned short val_nZone, SU2_Comm MPICommunicator); + + /*! + * \brief Destructor of the class. + */ + ~CTurbomachineryDriver(void) override; + + /*! + * \brief Run a single iteration of the physics within multiple zones. + */ + + void Run() override; + + /*! + * \brief Set Mixing Plane interface within multiple zones. + */ + void SetMixingPlane(unsigned short iZone); + + /*! + * \brief Set Mixing Plane interface within multiple zones. + */ + void SetTurboPerformance(unsigned short targetZone); + + /*! + * \brief Monitor the computation. + */ + bool Monitor(unsigned long TimeIter) override; }; /*! @@ -809,61 +802,57 @@ class CTurbomachineryDriver : public CFluidDriver { * \author T. Economon */ class CHBDriver : public CFluidDriver { - -private: - COutputLegacy* output_legacy; - unsigned short nInstHB; - su2double **D; /*!< \brief Harmonic Balance operator. */ - -public: - - /*! - * \brief Constructor of the class. - * \param[in] confFile - Configuration file name. - * \param[in] val_nZone - Total number of zones. - * \param[in] val_nDim - Number of dimensions. - * \param[in] MPICommunicator - MPI communicator for SU2. - */ - CHBDriver(char* confFile, - unsigned short val_nZone, - SU2_Comm MPICommunicator); - - /*! - * \brief Destructor of the class. - */ - ~CHBDriver(void) override; - - /*! - * \brief Run a single iteration of a Harmonic Balance problem. - */ - void Run() override; - - /*! - * \brief Computation and storage of the Harmonic Balance method source terms. - * \author T. Economon, K. Naik - * \param[in] iZone - Current zone number. - */ - void SetHarmonicBalance(unsigned short iZone); - - /*! - * \brief Precondition Harmonic Balance source term for stability - * \author J. Howison - */ - void StabilizeHarmonicBalance(); - - /*! - * \brief Computation of the Harmonic Balance operator matrix for harmonic balance. - * \author A. Rubino, S. Nimmagadda - */ - void ComputeHB_Operator(); - - /*! - * \brief Update the solution for the Harmonic Balance. - */ - void Update() override; - - /*! - * \brief Reset the convergence flag (set to false) of the solver for the Harmonic Balance. - */ - void ResetConvergence() override; + private: + COutputLegacy* output_legacy; + unsigned short nInstHB; + su2double** D; /*!< \brief Harmonic Balance operator. */ + + public: + /*! + * \brief Constructor of the class. + * \param[in] confFile - Configuration file name. + * \param[in] val_nZone - Total number of zones. + * \param[in] val_nDim - Number of dimensions. + * \param[in] MPICommunicator - MPI communicator for SU2. + */ + CHBDriver(char* confFile, unsigned short val_nZone, SU2_Comm MPICommunicator); + + /*! + * \brief Destructor of the class. + */ + ~CHBDriver(void) override; + + /*! + * \brief Run a single iteration of a Harmonic Balance problem. + */ + void Run() override; + + /*! + * \brief Computation and storage of the Harmonic Balance method source terms. + * \author T. Economon, K. Naik + * \param[in] iZone - Current zone number. + */ + void SetHarmonicBalance(unsigned short iZone); + + /*! + * \brief Precondition Harmonic Balance source term for stability + * \author J. Howison + */ + void StabilizeHarmonicBalance(); + + /*! + * \brief Computation of the Harmonic Balance operator matrix for harmonic balance. + * \author A. Rubino, S. Nimmagadda + */ + void ComputeHB_Operator(); + + /*! + * \brief Update the solution for the Harmonic Balance. + */ + void Update() override; + + /*! + * \brief Reset the convergence flag (set to false) of the solver for the Harmonic Balance. + */ + void ResetConvergence() override; }; From 3c3b4a5d7b6c5e2c78bba3d56bb3b84a06ac4609 Mon Sep 17 00:00:00 2001 From: patelha57 Date: Sat, 10 Dec 2022 15:45:00 -0800 Subject: [PATCH 38/68] Fix copyright dates --- Common/include/drivers/CDriverBase.hpp | 2 +- Common/src/drivers/CDriverBase.cpp | 2 +- SU2_DEF/include/drivers/CDeformationDriver.hpp | 2 +- SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp | 2 +- SU2_DEF/src/drivers/CDeformationDriver.cpp | 2 +- SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Common/include/drivers/CDriverBase.hpp b/Common/include/drivers/CDriverBase.hpp index 09107b4d685..e3acace3892 100644 --- a/Common/include/drivers/CDriverBase.hpp +++ b/Common/include/drivers/CDriverBase.hpp @@ -9,7 +9,7 @@ * The SU2 Project is maintained by the SU2 Foundation * (http://su2foundation.org) * - * Copyright 2012-2021, SU2 Contributors (cf. AUTHORS.md) + * Copyright 2012-2022, SU2 Contributors (cf. AUTHORS.md) * * SU2 is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/Common/src/drivers/CDriverBase.cpp b/Common/src/drivers/CDriverBase.cpp index 9d5ec62f32d..9c7d69bbd5b 100644 --- a/Common/src/drivers/CDriverBase.cpp +++ b/Common/src/drivers/CDriverBase.cpp @@ -9,7 +9,7 @@ * The SU2 Project is maintained by the SU2 Foundation * (http://su2foundation.org) * - * Copyright 2012-2021, SU2 Contributors (cf. AUTHORS.md) + * Copyright 2012-2022, SU2 Contributors (cf. AUTHORS.md) * * SU2 is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser/ General Public diff --git a/SU2_DEF/include/drivers/CDeformationDriver.hpp b/SU2_DEF/include/drivers/CDeformationDriver.hpp index f27c0155a81..bded29a1f0d 100644 --- a/SU2_DEF/include/drivers/CDeformationDriver.hpp +++ b/SU2_DEF/include/drivers/CDeformationDriver.hpp @@ -9,7 +9,7 @@ * The SU2 Project is maintained by the SU2 Foundation * (http://su2foundation.org) * - * Copyright 2012-2021, SU2 Contributors (cf. AUTHORS.md) + * Copyright 2012-2022, SU2 Contributors (cf. AUTHORS.md) * * SU2 is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp b/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp index da663dcf022..783e21c98dd 100644 --- a/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp +++ b/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp @@ -9,7 +9,7 @@ * The SU2 Project is maintained by the SU2 Foundation * (http://su2foundation.org) * - * Copyright 2012-2021, SU2 Contributors (cf. AUTHORS.md) + * Copyright 2012-2022, SU2 Contributors (cf. AUTHORS.md) * * SU2 is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/SU2_DEF/src/drivers/CDeformationDriver.cpp b/SU2_DEF/src/drivers/CDeformationDriver.cpp index 51604c3c72e..6140f4526a9 100644 --- a/SU2_DEF/src/drivers/CDeformationDriver.cpp +++ b/SU2_DEF/src/drivers/CDeformationDriver.cpp @@ -9,7 +9,7 @@ * The SU2 Project is maintained by the SU2 Foundation * (http://su2foundation.org) * - * Copyright 2012-2021, SU2 Contributors (cf. AUTHORS.md) + * Copyright 2012-2022, SU2 Contributors (cf. AUTHORS.md) * * SU2 is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser/ General Public diff --git a/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp b/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp index a513081b338..f483eb0dabf 100644 --- a/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp +++ b/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp @@ -9,7 +9,7 @@ * The SU2 Project is maintained by the SU2 Foundation * (http://su2foundation.org) * - * Copyright 2012-2021, SU2 Contributors (cf. AUTHORS.md) + * Copyright 2012-2022, SU2 Contributors (cf. AUTHORS.md) * * SU2 is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public From 23716f32d1803d8068af6d86f4dd55f9c8753953 Mon Sep 17 00:00:00 2001 From: patelha57 Date: Sat, 10 Dec 2022 15:50:05 -0800 Subject: [PATCH 39/68] Add Python support for incompressible and NEMO solvers --- SU2_CFD/src/python_wrapper_structure.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/SU2_CFD/src/python_wrapper_structure.cpp b/SU2_CFD/src/python_wrapper_structure.cpp index 6ec8e594669..e3046eda5fd 100644 --- a/SU2_CFD/src/python_wrapper_structure.cpp +++ b/SU2_CFD/src/python_wrapper_structure.cpp @@ -50,7 +50,12 @@ void CDriver::PythonInterface_Preprocessing(CConfig **config, CGeometry ****geom if ((config[iZone]->GetKind_Solver() == MAIN_SOLVER::EULER) || (config[iZone]->GetKind_Solver() == MAIN_SOLVER::NAVIER_STOKES) || - (config[iZone]->GetKind_Solver() == MAIN_SOLVER::RANS)) { + (config[iZone]->GetKind_Solver() == MAIN_SOLVER::RANS) || + (config[iZone]->GetKind_Solver() == MAIN_SOLVER::INC_EULER) || + (config[iZone]->GetKind_Solver() == MAIN_SOLVER::INC_NAVIER_STOKES) || + (config[iZone]->GetKind_Solver() == MAIN_SOLVER::INC_RANS) || + (config[iZone]->GetKind_Solver() == MAIN_SOLVER::NEMO_EULER) || + (config[iZone]->GetKind_Solver() == MAIN_SOLVER::NEMO_NAVIER_STOKES)) { solver[iZone][INST_0][MESH_0][FLOW_SOL]->UpdateCustomBoundaryConditions(geometry[iZone][INST_0], config[iZone]); } @@ -387,6 +392,7 @@ void CDriver::ResetConvergence() { case MAIN_SOLVER::EULER: case MAIN_SOLVER::NAVIER_STOKES: case MAIN_SOLVER::RANS: case MAIN_SOLVER::INC_EULER: case MAIN_SOLVER::INC_NAVIER_STOKES: case MAIN_SOLVER::INC_RANS: + case MAIN_SOLVER::NEMO_EULER: case MAIN_SOLVER::NEMO_NAVIER_STOKES: integration_container[iZone][INST_0][FLOW_SOL]->SetConvergence(false); if (config_container[iZone]->GetKind_Solver() == MAIN_SOLVER::RANS) integration_container[iZone][INST_0][TURB_SOL]->SetConvergence(false); if(config_container[iZone]->GetKind_Trans_Model() == TURB_TRANS_MODEL::LM) integration_container[iZone][INST_0][TRANS_SOL]->SetConvergence(false); From cd523cdfb0385bcd65cf0a4d7fced133cbbdf54e Mon Sep 17 00:00:00 2001 From: patelha57 Date: Sat, 10 Dec 2022 15:54:26 -0800 Subject: [PATCH 40/68] Add more boundary conditions for GetMarkerTypes() --- Common/src/drivers/CDriverBase.cpp | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/Common/src/drivers/CDriverBase.cpp b/Common/src/drivers/CDriverBase.cpp index 9c7d69bbd5b..cc222d50e6c 100644 --- a/Common/src/drivers/CDriverBase.cpp +++ b/Common/src/drivers/CDriverBase.cpp @@ -225,7 +225,10 @@ map CDriverBase::GetMarkerTypes() const { type = "ISOTHERMAL"; break; case HEAT_FLUX: - type = "HEATFLUX"; + type = "HEAT_FLUX"; + break; + case HEAT_TRANSFER: + type = "HEAT_TRANSFER"; break; case INLET_FLOW: type = "INLET_FLOW"; @@ -233,6 +236,27 @@ map CDriverBase::GetMarkerTypes() const { case OUTLET_FLOW: type = "OUTLET_FLOW"; break; + case SUPERSONIC_INLET: + type = "SUPERSONIC_INLET"; + break; + case SUPERSONIC_OUTLET: + type = "SUPERSONIC_OUTLET"; + break; + case RIEMANN_BOUNDARY: + type = "RIEMANN"; + break; + case GILES_BOUNDARY: + type = "GILES"; + break; + case DISPLACEMENT_BOUNDARY: + type = "DISPLACEMENT"; + break; + case LOAD_BOUNDARY: + type = "LOAD"; + break; + case PERIODIC_BOUNDARY: + type = "PERIODIC"; + break; case SYMMETRY_PLANE: type = "SYMMETRY"; break; From 3ea9b55fb3f7e81a024e62ec4c4b84283adba04b Mon Sep 17 00:00:00 2001 From: patelha57 Date: Sat, 10 Dec 2022 16:35:31 -0800 Subject: [PATCH 41/68] Fix unused variable error in regression tests --- Common/src/drivers/CDriverBase.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Common/src/drivers/CDriverBase.cpp b/Common/src/drivers/CDriverBase.cpp index cc222d50e6c..dd1e3f9c88e 100644 --- a/Common/src/drivers/CDriverBase.cpp +++ b/Common/src/drivers/CDriverBase.cpp @@ -885,7 +885,6 @@ void CDriverBase::ReadFFDInfo(CGeometry* geometry, CConfig* config, CFreeFormDef unsigned short nFFDBox = 0; unsigned short nLevel = 0; - bool FFDBoxDefinition = false; mesh_file.open(val_mesh_filename); if (mesh_file.fail()) { @@ -1232,10 +1231,6 @@ void CDriverBase::ReadFFDInfo(CGeometry* geometry, CConfig* config, CFreeFormDef if (rank == MASTER_NODE) cout << "Control points: " << nControlPoints[iFFDBox] << ". "; - /*--- Method to identify if there is a FFDBox definition. ---*/ - - if (nControlPoints[iFFDBox] != 0) FFDBoxDefinition = true; - /*--- Read the coordinates of the control points. ---*/ for (iControlPoints = 0; iControlPoints < nControlPoints[iFFDBox]; iControlPoints++) { From 8aa6a58784a92fc137d16992771796f1d0c7ab4f Mon Sep 17 00:00:00 2001 From: patelha57 Date: Mon, 12 Dec 2022 11:13:50 -0800 Subject: [PATCH 42/68] Update code documentation blocks in CDriver.hpp --- SU2_CFD/include/drivers/CDriver.hpp | 75 ++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 24 deletions(-) diff --git a/SU2_CFD/include/drivers/CDriver.hpp b/SU2_CFD/include/drivers/CDriver.hpp index 50366afd833..b9f752b3bfb 100644 --- a/SU2_CFD/include/drivers/CDriver.hpp +++ b/SU2_CFD/include/drivers/CDriver.hpp @@ -87,8 +87,8 @@ class CDriver : public CDriverBase { * \brief Constructor of the class. * \param[in] confFile - Configuration file name. * \param[in] val_nZone - Total number of zones. - * \param[in] val_nDim - Number of dimensions. * \param[in] MPICommunicator - MPI communicator for SU2. + * \param[in] dummy_geo - Dummy geometric definition of the problem. */ CDriver(char* confFile, unsigned short val_nZone, SU2_Comm MPICommunicator, bool dummy_geo); @@ -110,53 +110,63 @@ class CDriver : public CDriverBase { /*! * \brief Read in the config and mesh files. + * \param[in] config - Definition of the particular problem. + * \param[in] driver_config - Definition of the driver configuration. */ void Input_Preprocessing(CConfig**& config, CConfig*& driver_config); /*! * \brief Construction of the edge-based data structure and the multi-grid structure. + * \param[in] config - Definition of the particular problem. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] dummy - Definition of the dummy driver. */ void Geometrical_Preprocessing(CConfig* config, CGeometry**& geometry, bool dummy); /*! * \brief Do the geometrical preprocessing for the DG FEM solver. + * \param[in] config - Definition of the particular problem. + * \param[in] geometry - Geometrical definition of the problem. */ void Geometrical_Preprocessing_DGFEM(CConfig* config, CGeometry**& geometry); /*! * \brief Geometrical_Preprocessing_FVM + * \param[in] config - Definition of the particular problem. + * \param[in] geometry - Geometrical definition of the problem. */ void Geometrical_Preprocessing_FVM(CConfig* config, CGeometry**& geometry); /*! * \brief Definition of the physics iteration class or within a single zone. - * \param[in] iteration_container - Pointer to the iteration container to be instantiated. * \param[in] config - Definition of the particular problem. - * \param[in] iZone - Index of the zone. + * \param[in] iteration - Pointer to the iteration container to be instantiated. */ void Iteration_Preprocessing(CConfig* config, CIteration*& iteration) const; /*! * \brief Definition and allocation of all solution classes. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] geometry - Geometrical definition of the problem. * \param[in] config - Definition of the particular problem. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver - Container vector with all the solutions. */ void Solver_Preprocessing(CConfig* config, CGeometry** geometry, CSolver***& solver); /*! * \brief Restart of the solvers from the restart files. - * \param[in] solver_container - Container vector with all the solutions. + * \param[in] solver - Container vector with all the solutions. * \param[in] geometry - Geometrical definition of the problem. * \param[in] config - Definition of the particular problem. + * \param[in] update_geo - Boolean to indicate if geometry should be updated. */ void Solver_Restart(CSolver*** solver, CGeometry** geometry, CConfig* config, bool update_geo); /*! * \brief Definition and allocation of all solution classes. - * \param[in] solver_container - Container vector with all the solutions. + * \param[in] solver - Container vector with all the solutions. * \param[in] geometry - Geometrical definition of the problem. * \param[in] config - Definition of the particular problem. + * \param[in] val_iInst - Current solver instance. */ void Solver_Postprocessing(CSolver**** solver, CGeometry** geometry, CConfig* config, unsigned short val_iInst); @@ -164,21 +174,28 @@ class CDriver : public CDriverBase { * \brief Definition and allocation of all integration classes. * \param[in] config - Definition of the particular problem. * \param[in] solver - Container vector with all the solutions. - * \param[out] integration - Container vector with all the integration methods. + * \param[in] integration - Container vector with all the integration methods. */ void Integration_Preprocessing(CConfig* config, CSolver** solver, CIntegration**& integration) const; /*! * \brief Definition and allocation of all integration classes. - * \param[in] integration_container - Container vector with all the integration methods. + * \param[in] integration - Container vector with all the integration methods. * \param[in] geometry - Geometrical definition of the problem. * \param[in] config - Definition of the particular problem. + * \param[in] val_iInst - Current solver instance. */ void Integration_Postprocessing(CIntegration*** integration, CGeometry** geometry, CConfig* config, unsigned short val_iInst); /*! * \brief Definition and allocation of all interface classes. + * \param[in] config - Definition of the particular problem. + * \param[in] solver - Container vector with all the solutions. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] interface_types - Type of coupling between the distinct (physical) zones. + * \param[in] interface - Class defining the physical transfer of information. + * \param[in] interpolation - Object defining the interpolation. */ void Interface_Preprocessing(CConfig** config, CSolver***** solver, CGeometry**** geometry, unsigned short** interface_types, CInterface*** interface, @@ -186,10 +203,10 @@ class CDriver : public CDriverBase { /*! * \brief Definition and allocation of all solver classes. - * \param[in] numerics_container - Description of the numerical method (the way in which the equations are solved). - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. * \param[in] config - Definition of the particular problem. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method (the way in which the equations are solved). */ void Numerics_Preprocessing(CConfig* config, CGeometry** geometry, CSolver*** solver, CNumerics****& numerics) const; @@ -215,44 +232,58 @@ class CDriver : public CDriverBase { /*! * \brief Definition and allocation of all solver classes. - * \param[in] numerics_container - Description of the numerical method (the way in which the equations are solved). - * \param[in] solver_container - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method (the way in which the equations are solved). + * \param[in] solver - Container vector with all the solutions. * \param[in] geometry - Geometrical definition of the problem. * \param[in] config - Definition of the particular problem. + * \param[in] val_iInst - Current solver instance. */ void Numerics_Postprocessing(CNumerics***** numerics, CSolver*** solver, CGeometry** geometry, CConfig* config, unsigned short val_iInst); /*! * \brief GridMovement_Preprocessing - * \param config - * \param geometry - * \param solver - * \param iteration - * \param grid_movement - * \param surface_movement + * \param[in] config - Definition of the particular problem. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver - Container vector with all the solutions. + * \param[in] iteration - Container vector with all the iteration methods. + * \param[in] grid_movement - Volume grid movement classes of the problem. + * \param[in] surface_movement - Surface movement classes of the problem. */ void DynamicMesh_Preprocessing(CConfig* config, CGeometry** geometry, CSolver*** solver, CIteration* iteration, CVolumetricMovement*& grid_movement, CSurfaceMovement*& surface_movement) const; /*! * \brief Initialize Python interface functionalities + * \param[in] config - Definition of the particular problem. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver - Container vector with all the solutions. */ void PythonInterface_Preprocessing(CConfig** config, CGeometry**** geometry, CSolver***** solver); /*! * \brief Preprocess the output container. + * \param[in] config - Definition of the particular problem. + * \param[in] driver_config - Definition of the driver configuration. + * \param[in] output_container - Container vector with all the outputs. + * \param[in] driver_output - Definition of the driver output. */ void Output_Preprocessing(CConfig** config, CConfig* driver_config, COutput**& output_container, COutput*& driver_output); /*! * \brief Initiate value for static mesh movement such as the gridVel for the ROTATING frame. + * \param[in] config - Definition of the particular problem. + * \param[in] geometry - Geometrical definition of the problem. */ void StaticMesh_Preprocessing(const CConfig* config, CGeometry** geometry); /*! * \brief Initiate value for static mesh movement such as the gridVel for the ROTATING frame. + * \param[in] config - Definition of the particular problem. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver - Container vector with all the solutions. + * \param[in] interface - Class defining the physical transfer of information. */ void Turbomachinery_Preprocessing(CConfig** config, CGeometry**** geometry, CSolver***** solver, CInterface*** interface); @@ -694,7 +725,6 @@ class CFluidDriver : public CDriver { * \brief Constructor of the class. * \param[in] confFile - Configuration file name. * \param[in] val_nZone - Total number of zones. - * \param[in] val_nDim - Number of dimensions. * \param[in] MPICommunicator - MPI communicator for SU2. */ CFluidDriver(char* confFile, unsigned short val_nZone, SU2_Comm MPICommunicator); @@ -762,8 +792,6 @@ class CTurbomachineryDriver : public CFluidDriver { * \brief Constructor of the class. * \param[in] confFile - Configuration file name. * \param[in] val_nZone - Total number of zones. - * \param[in] val_nDim - Number of dimensions. - * \param[in] val_periodic - Bool for periodic BCs. * \param[in] MPICommunicator - MPI communicator for SU2. */ CTurbomachineryDriver(char* confFile, unsigned short val_nZone, SU2_Comm MPICommunicator); @@ -812,7 +840,6 @@ class CHBDriver : public CFluidDriver { * \brief Constructor of the class. * \param[in] confFile - Configuration file name. * \param[in] val_nZone - Total number of zones. - * \param[in] val_nDim - Number of dimensions. * \param[in] MPICommunicator - MPI communicator for SU2. */ CHBDriver(char* confFile, unsigned short val_nZone, SU2_Comm MPICommunicator); From 4e5952d98772d52c13dbbeca735283edd560c106 Mon Sep 17 00:00:00 2001 From: patelha57 Date: Tue, 20 Dec 2022 14:18:42 -0800 Subject: [PATCH 43/68] Add error checks for FFD functions, fix FFD read segfault --- Common/src/drivers/CDriverBase.cpp | 80 ++++++++++++++++++++++++++++++ SU2_CFD/src/drivers/CDriver.cpp | 6 +-- 2 files changed, 82 insertions(+), 4 deletions(-) diff --git a/Common/src/drivers/CDriverBase.cpp b/Common/src/drivers/CDriverBase.cpp index dd1e3f9c88e..ab2e60049b6 100644 --- a/Common/src/drivers/CDriverBase.cpp +++ b/Common/src/drivers/CDriverBase.cpp @@ -80,18 +80,46 @@ unsigned short CDriverBase::GetNumberDesignVariables() const { return main_confi unsigned short CDriverBase::GetNumberFFDBoxes() const { return main_config->GetnFFDBox(); } unsigned short CDriverBase::GetNumberFFDBoxCornerPoints(unsigned short iFFDBox) const { + if (GetNumberFFDBoxes() == 0) { + SU2_MPI::Error("FFD Box definition not found in the mesh file.", CURRENT_FUNCTION); + } + if (iFFDBox >= GetNumberFFDBoxes()) { + SU2_MPI::Error("FFD Box index exceeds size.", CURRENT_FUNCTION); + } + return FFDBox[ZONE_0][iFFDBox]->GetnCornerPoints(); } unsigned short CDriverBase::GetNumberFFDBoxControlPoints(unsigned short iFFDBox) const { + if (GetNumberFFDBoxes() == 0) { + SU2_MPI::Error("FFD Box definition not found in the mesh file.", CURRENT_FUNCTION); + } + if (iFFDBox >= GetNumberFFDBoxes()) { + SU2_MPI::Error("FFD Box index exceeds size.", CURRENT_FUNCTION); + } + return FFDBox[ZONE_0][iFFDBox]->GetnControlPoints(); } unsigned long CDriverBase::GetNumberFFDBoxSurfacePoints(unsigned short iFFDBox) const { + if (GetNumberFFDBoxes() == 0) { + SU2_MPI::Error("FFD Box definition not found in the mesh file.", CURRENT_FUNCTION); + } + if (iFFDBox >= GetNumberFFDBoxes()) { + SU2_MPI::Error("FFD Box index exceeds size.", CURRENT_FUNCTION); + } + return FFDBox[ZONE_0][iFFDBox]->GetnSurfacePoint(); } vector CDriverBase::GetFFDBoxMarkerIDs(unsigned short iFFDBox) const { + if (GetNumberFFDBoxes() == 0) { + SU2_MPI::Error("FFD Box definition not found in the mesh file.", CURRENT_FUNCTION); + } + if (iFFDBox >= GetNumberFFDBoxes()) { + SU2_MPI::Error("FFD Box index exceeds size.", CURRENT_FUNCTION); + } + vector values; for (auto iPoint = 0ul; iPoint < GetNumberFFDBoxSurfacePoints(iFFDBox); iPoint++) { @@ -101,6 +129,13 @@ vector CDriverBase::GetFFDBoxMarkerIDs(unsigned short iFFDBox) c } vector CDriverBase::GetFFDBoxVertexIDs(unsigned short iFFDBox) const { + if (GetNumberFFDBoxes() == 0) { + SU2_MPI::Error("FFD Box definition not found in the mesh file.", CURRENT_FUNCTION); + } + if (iFFDBox >= GetNumberFFDBoxes()) { + SU2_MPI::Error("FFD Box index exceeds size.", CURRENT_FUNCTION); + } + vector values; for (auto iPoint = 0ul; iPoint < GetNumberFFDBoxSurfacePoints(iFFDBox); iPoint++) { @@ -110,6 +145,13 @@ vector CDriverBase::GetFFDBoxVertexIDs(unsigned short iFFDBox) co } vector CDriverBase::GetFFDBoxPointIDs(unsigned short iFFDBox) const { + if (GetNumberFFDBoxes() == 0) { + SU2_MPI::Error("FFD Box definition not found in the mesh file.", CURRENT_FUNCTION); + } + if (iFFDBox >= GetNumberFFDBoxes()) { + SU2_MPI::Error("FFD Box index exceeds size.", CURRENT_FUNCTION); + } + vector values; for (auto iPoint = 0ul; iPoint < GetNumberFFDBoxSurfacePoints(iFFDBox); iPoint++) { @@ -119,6 +161,13 @@ vector CDriverBase::GetFFDBoxPointIDs(unsigned short iFFDBox) con } vector> CDriverBase::GetFFDBoxCornerCoordinates(unsigned short iFFDBox) const { + if (GetNumberFFDBoxes() == 0) { + SU2_MPI::Error("FFD Box definition not found in the mesh file.", CURRENT_FUNCTION); + } + if (iFFDBox >= GetNumberFFDBoxes()) { + SU2_MPI::Error("FFD Box index exceeds size.", CURRENT_FUNCTION); + } + vector> values; for (auto iPoint = 0u; iPoint < GetNumberFFDBoxCornerPoints(iFFDBox); iPoint++) { @@ -137,6 +186,13 @@ vector> CDriverBase::GetFFDBoxCornerCoordinates(unsigned s } vector> CDriverBase::GetFFDBoxControlPointCoordinates(unsigned short iFFDBox) const { + if (GetNumberFFDBoxes() == 0) { + SU2_MPI::Error("FFD Box definition not found in the mesh file.", CURRENT_FUNCTION); + } + if (iFFDBox >= GetNumberFFDBoxes()) { + SU2_MPI::Error("FFD Box index exceeds size.", CURRENT_FUNCTION); + } + vector> values; for (auto iOrder = 0u; iOrder < FFDBox[ZONE_0][iFFDBox]->GetlOrder(); iOrder++) { @@ -152,6 +208,13 @@ vector> CDriverBase::GetFFDBoxControlPointCoordinates(unsi vector CDriverBase::GetFFDBoxControlPointCoordinates(unsigned short iFFDBox, unsigned int iOrder, unsigned int jOrder, unsigned int kOrder) const { + if (GetNumberFFDBoxes() == 0) { + SU2_MPI::Error("FFD Box definition not found in the mesh file.", CURRENT_FUNCTION); + } + if (iFFDBox >= GetNumberFFDBoxes()) { + SU2_MPI::Error("FFD Box index exceeds size.", CURRENT_FUNCTION); + } + vector values; const su2double* coord = FFDBox[ZONE_0][iFFDBox]->GetCoordControlPoints(iOrder, jOrder, kOrder); @@ -164,6 +227,13 @@ vector CDriverBase::GetFFDBoxControlPointCoordinates(unsigned sho } vector> CDriverBase::GetFFDBoxSurfaceCoordinates(unsigned short iFFDBox, bool parametric) const { + if (GetNumberFFDBoxes() == 0) { + SU2_MPI::Error("FFD Box definition not found in the mesh file.", CURRENT_FUNCTION); + } + if (iFFDBox >= GetNumberFFDBoxes()) { + SU2_MPI::Error("FFD Box index exceeds size.", CURRENT_FUNCTION); + } + vector> values; for (auto iPoint = 0ul; iPoint < GetNumberFFDBoxSurfacePoints(iFFDBox); iPoint++) { @@ -175,6 +245,16 @@ vector> CDriverBase::GetFFDBoxSurfaceCoordinates(unsigned vector CDriverBase::GetFFDBoxSurfaceCoordinates(unsigned short iFFDBox, unsigned long iPoint, bool parametric) const { + if (GetNumberFFDBoxes() == 0) { + SU2_MPI::Error("FFD Box definition not found in the mesh file.", CURRENT_FUNCTION); + } + if (iFFDBox >= GetNumberFFDBoxes()) { + SU2_MPI::Error("FFD Box index exceeds size.", CURRENT_FUNCTION); + } + if (iPoint >= GetNumberFFDBoxSurfacePoints()) { + SU2_MPI::Error("FFD Box vertex index exceeds mesh size.", CURRENT_FUNCTION); + } + vector values; const su2double* coord; diff --git a/SU2_CFD/src/drivers/CDriver.cpp b/SU2_CFD/src/drivers/CDriver.cpp index 331c50b1ee4..23fb0b70a00 100644 --- a/SU2_CFD/src/drivers/CDriver.cpp +++ b/SU2_CFD/src/drivers/CDriver.cpp @@ -177,10 +177,8 @@ CDriverBase(confFile, val_nZone, MPICommunicator), StopCalc(false), fsi(false), } } - /*--- Read free-form deformation design variables data. --- */ - if (main_config->GetnFFDBox() != 0) { - ReadFFDInfo(main_geometry, main_config, FFDBox[ZONE_0], main_config->GetMesh_FileName()); - } + /*--- Read free form deformation design variables data. --- */ + ReadFFDInfo(geometry_container[ZONE_0][INST_0][MESH_0], config_container[ZONE_0], FFDBox[ZONE_0], config_container[ZONE_0]->GetMesh_FileName()); /*--- Before we proceed with the zone loop we have to compute the wall distances. * This computation depends on all zones at once. ---*/ From 35eb6ada05949842bfe2c7dcc2b52a315727126c Mon Sep 17 00:00:00 2001 From: patelha57 Date: Tue, 20 Dec 2022 14:29:43 -0800 Subject: [PATCH 44/68] Fix missing input argument in CDriverBase.cpp --- Common/src/drivers/CDriverBase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Common/src/drivers/CDriverBase.cpp b/Common/src/drivers/CDriverBase.cpp index ab2e60049b6..20b65f9a974 100644 --- a/Common/src/drivers/CDriverBase.cpp +++ b/Common/src/drivers/CDriverBase.cpp @@ -251,7 +251,7 @@ vector CDriverBase::GetFFDBoxSurfaceCoordinates(unsigned short iF if (iFFDBox >= GetNumberFFDBoxes()) { SU2_MPI::Error("FFD Box index exceeds size.", CURRENT_FUNCTION); } - if (iPoint >= GetNumberFFDBoxSurfacePoints()) { + if (iPoint >= GetNumberFFDBoxSurfacePoints(iFFDBox)) { SU2_MPI::Error("FFD Box vertex index exceeds mesh size.", CURRENT_FUNCTION); } From 68edc822c01e02851960d7c997e918deb9235b15 Mon Sep 17 00:00:00 2001 From: patelha57 Date: Wed, 21 Dec 2022 20:59:21 -0800 Subject: [PATCH 45/68] Fix FFD read error when there is no geometry file --- Common/src/drivers/CDriverBase.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Common/src/drivers/CDriverBase.cpp b/Common/src/drivers/CDriverBase.cpp index 20b65f9a974..74dda47ce3b 100644 --- a/Common/src/drivers/CDriverBase.cpp +++ b/Common/src/drivers/CDriverBase.cpp @@ -966,6 +966,11 @@ void CDriverBase::ReadFFDInfo(CGeometry* geometry, CConfig* config, CFreeFormDef unsigned short nFFDBox = 0; unsigned short nLevel = 0; + if (config->GetMesh_FileFormat() != SU2) { + if (rank == MASTER_NODE) cout << "Mesh file format is not .su2 so FFD box information cannot be extracted." << endl; + return; + } + mesh_file.open(val_mesh_filename); if (mesh_file.fail()) { SU2_MPI::Error("There is no geometry file (ReadFFDInfo)!!", CURRENT_FUNCTION); From 9ad958c81af77eb05cdf87c09aac4155f70ec6da Mon Sep 17 00:00:00 2001 From: patelha57 Date: Thu, 22 Dec 2022 10:54:46 -0800 Subject: [PATCH 46/68] Update pysu2 function names in FSIInterface.py --- SU2_PY/FSI_tools/FSIInterface.py | 34 ++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/SU2_PY/FSI_tools/FSIInterface.py b/SU2_PY/FSI_tools/FSIInterface.py index e4e89dce7ce..616628162a8 100644 --- a/SU2_PY/FSI_tools/FSIInterface.py +++ b/SU2_PY/FSI_tools/FSIInterface.py @@ -227,15 +227,15 @@ def connect(self, FSI_config, FluidSolver, SolidSolver): if FluidSolver is not None: print('Fluid solver is initialized on process {}'.format(myid)) self.haveFluidSolver = True - allMovingMarkersTags = FluidSolver.GetAllDeformMeshMarkersTag() - allMarkersID = FluidSolver.GetAllBoundaryMarkers() + allMovingMarkersTags = FluidSolver.GetDeformableMarkerTags() + allMarkersID = FluidSolver.GetMarkerTags() if not allMovingMarkersTags: raise Exception('No interface for FSI was defined.') else: if allMovingMarkersTags[0] in allMarkersID.keys(): self.fluidInterfaceIdentifier = allMarkersID[allMovingMarkersTags[0]] if self.fluidInterfaceIdentifier is not None: - self.nLocalFluidInterfaceNodes = FluidSolver.GetNumberVertices(self.fluidInterfaceIdentifier) + self.nLocalFluidInterfaceNodes = FluidSolver.GetNumberMarkerVertices(self.fluidInterfaceIdentifier) if self.nLocalFluidInterfaceNodes != 0: self.haveFluidInterface = True print('Number of interface fluid nodes (halo nodes included) on proccess {} : {}'.format(myid,self.nLocalFluidInterfaceNodes)) @@ -300,8 +300,8 @@ def connect(self, FSI_config, FluidSolver, SolidSolver): # Calculate the number of halo nodes on each partition self.nLocalFluidInterfaceHaloNode = 0 for iVertex in range(self.nLocalFluidInterfaceNodes): - if FluidSolver.IsAHaloNode(self.fluidInterfaceIdentifier, iVertex): - GlobalIndex = FluidSolver.GetVertexGlobalIndex(self.fluidInterfaceIdentifier, iVertex) + if not FluidSolver.GetMarkerDomain(self.fluidInterfaceIdentifier, iVertex): + GlobalIndex = FluidSolver.GetMarkerVertexIDs(self.fluidInterfaceIdentifier, iVertex) self.FluidHaloNodeList[GlobalIndex] = iVertex self.nLocalFluidInterfaceHaloNode += 1 # Calculate the number of physical (= not halo) nodes on each partition @@ -565,8 +565,12 @@ def interfaceMapping(self,FluidSolver, SolidSolver, FSI_config): # Note that the fluid solver is separated in more processors outside the python script # thus when, from a core, we request for the vertices on the interface, we only obtain # those in that core - GlobalIndex = FluidSolver.GetVertexGlobalIndex(self.fluidInterfaceIdentifier, iVertex) - posx, posy, posz = FluidSolver.GetInitialMeshCoord(self.fluidInterfaceIdentifier, iVertex) + GlobalIndex = FluidSolver.GetMarkerVertexIDs(self.fluidInterfaceIdentifier, iVertex) + if self.nDim == 2: + posx, posy = FluidSolver.GetMarkerInitialCoordinates(self.fluidInterfaceIdentifier, iVertex) + posz = 0 + else: + posx, posy, posz = FluidSolver.GetMarkerInitialCoordinates(self.fluidInterfaceIdentifier, iVertex) if GlobalIndex not in self.FluidHaloNodeList[myid].keys(): fluidIndexing_temp[GlobalIndex] = self.__getGlobalIndex('fluid', myid, localIndex) self.localFluidInterface_array_X_init[localIndex] = posx @@ -1456,7 +1460,7 @@ def getFluidInterfaceNodalForce(self, FSI_config, FluidSolver): # --- Get the fluid interface loads from the fluid solver and directly fill the corresponding PETSc vector --- for iVertex in range(self.nLocalFluidInterfaceNodes): - GlobalIndex = FluidSolver.GetVertexGlobalIndex(self.fluidInterfaceIdentifier, iVertex) + GlobalIndex = FluidSolver.GetMarkerVertexIDs(self.fluidInterfaceIdentifier, iVertex) if GlobalIndex not in self.FluidHaloNodeList[myid].keys(): loadX, loadY, loadZ = FluidSolver.GetFlowLoad(self.fluidInterfaceIdentifier, iVertex) iGlobalVertex = self.__getGlobalIndex('fluid', myid, localIndex) @@ -1486,15 +1490,15 @@ def setFluidInterfaceVarCoord(self, FluidSolver): # --- Send the new fluid interface position to the fluid solver (on each partition, halo nodes included) --- localIndex = 0 for iVertex in range(self.nLocalFluidInterfaceNodes): - GlobalIndex = FluidSolver.GetVertexGlobalIndex(self.fluidInterfaceIdentifier, iVertex) + GlobalIndex = FluidSolver.GetMarkerVertexIDs(self.fluidInterfaceIdentifier, iVertex) if GlobalIndex in self.FluidHaloNodeList[myid].keys(): DispX, DispY, DispZ = self.haloNodesDisplacements[GlobalIndex] - FluidSolver.SetMeshDisplacement(self.fluidInterfaceIdentifier, int(iVertex), DispX, DispY, DispZ) + FluidSolver.SetMarkerDisplacements(self.fluidInterfaceIdentifier, int(iVertex), np.array([DispX, DispY, DispZ])) else: DispX = self.localFluidInterface_array_DispX[localIndex] DispY = self.localFluidInterface_array_DispY[localIndex] DispZ = self.localFluidInterface_array_DispZ[localIndex] - FluidSolver.SetMeshDisplacement(self.fluidInterfaceIdentifier, int(iVertex), DispX, DispY, DispZ) + FluidSolver.SetMarkerDisplacements(self.fluidInterfaceIdentifier, int(iVertex), np.array([DispX, DispY, DispZ])) localIndex += 1 @@ -2142,8 +2146,12 @@ def MapModes(self, FSI_config, FluidSolver, SolidSolver): nodeNormals = {} for iVertex in range(self.nLocalFluidInterfaceNodes): - nx, ny, nz = FluidSolver.GetVertexNormal(self.fluidInterfaceIdentifier, iVertex, False) - GlobalIndex = FluidSolver.GetVertexGlobalIndex(self.fluidInterfaceIdentifier, iVertex) + if self.nDim == 2: + nx, ny = FluidSolver.GetMarkerVertexNormals(self.fluidInterfaceIdentifier, iVertex, False) + nz = 0 + else: + nx, ny, nz = FluidSolver.GetMarkerVertexNormals(self.fluidInterfaceIdentifier, iVertex, False) + GlobalIndex = FluidSolver.GetMarkerVertexIDs(self.fluidInterfaceIdentifier, iVertex) nodeNormals[GlobalIndex] = [nx, ny, nz] nodeNormals = self.comm.gather(nodeNormals, root=self.rootProcess) From 3b46ee098bf7dea6eee8eba51a475435d0cdb2d2 Mon Sep 17 00:00:00 2001 From: patelha57 Date: Thu, 22 Dec 2022 16:22:06 -0800 Subject: [PATCH 47/68] Modify regression workflow --- .github/workflows/regression.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/regression.yml b/.github/workflows/regression.yml index 8e2d4414353..37c3dc637f9 100644 --- a/.github/workflows/regression.yml +++ b/.github/workflows/regression.yml @@ -128,7 +128,7 @@ jobs: uses: docker://ghcr.io/su2code/su2/test-su2:220614-1237 with: # -t -c - args: -b ${{github.ref}} -t develop -c develop -s ${{matrix.testscript}} + args: -b ${{github.ref}} -t develop -c feature_FFD -s ${{matrix.testscript}} - name: Cleanup uses: docker://ghcr.io/su2code/su2/test-su2:220614-1237 with: From a4450bbbd1f0170267476e4af7cc762a2f99d09d Mon Sep 17 00:00:00 2001 From: patelha57 Date: Thu, 22 Dec 2022 18:23:41 -0800 Subject: [PATCH 48/68] Update pysu2 function names in translating NACA0012 test case --- TestCases/py_wrapper/translating_NACA0012/run_su2.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/TestCases/py_wrapper/translating_NACA0012/run_su2.py b/TestCases/py_wrapper/translating_NACA0012/run_su2.py index 731c109184d..a4abfee0b6e 100644 --- a/TestCases/py_wrapper/translating_NACA0012/run_su2.py +++ b/TestCases/py_wrapper/translating_NACA0012/run_su2.py @@ -35,8 +35,8 @@ def run_solver(self): self.comm.barrier() def save_forces(self): - solver_all_moving_markers = np.array(self.FluidSolver.GetAllDeformMeshMarkersTag()) - solver_marker_ids = self.FluidSolver.GetAllBoundaryMarkers() + solver_all_moving_markers = np.array(self.FluidSolver.GetDeformableMarkerTags()) + solver_marker_ids = self.FluidSolver.GetMarkerTags() # The surface marker and the partitioning of the solver usually don't agree. # Thus, it is necessary to figure out if the partition of the current mpi process has # a node that belongs to a moving surface marker. @@ -46,10 +46,10 @@ def save_forces(self): for marker in solver_all_moving_markers[has_moving_marker]: solver_marker_id = solver_marker_ids[marker] - n_vertices = self.FluidSolver.GetNumberVertices(solver_marker_id) + n_vertices = self.FluidSolver.GetNumberMarkerVertices(solver_marker_id) for i_vertex in range(n_vertices): fxyz = self.FluidSolver.GetFlowLoad(solver_marker_id, i_vertex) - GlobalIndex = self.FluidSolver.GetVertexGlobalIndex(solver_marker_id, i_vertex) + GlobalIndex = self.FluidSolver.GetMarkerVertexIDs(solver_marker_id, i_vertex) f.write('{}, {:.2f}, {:.2f}, {:.2f}\n'.format(GlobalIndex, fxyz[0], fxyz[1], fxyz[2])) f.close() From 57a7faf38cb7306f262aeb66f9a10fbfc6d54ad8 Mon Sep 17 00:00:00 2001 From: patelha57 Date: Thu, 22 Dec 2022 18:28:21 -0800 Subject: [PATCH 49/68] Fix continuous adjoint solver error handling in CDiscAdjDeformationDriver --- SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp b/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp index f483eb0dabf..9e55a74c11a 100644 --- a/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp +++ b/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp @@ -120,8 +120,8 @@ void CDiscAdjDeformationDriver::Input_Preprocessing() { config_container[iZone]->SetMPICommunicator(SU2_MPI::GetComm()); - if (!config_container[iZone]->GetDiscrete_Adjoint()) { - SU2_MPI::Error("The discrete adjoint solver was not specified in the configuration file.", CURRENT_FUNCTION); + if (!config_container[iZone]->GetDiscrete_Adjoint() && !config_container[iZone]->GetContinuous_Adjoint()) { + SU2_MPI::Error("An adjoint solver (discrete or continuous) was not specified in the configuration file.", CURRENT_FUNCTION); } } From 5c1ec48ef8f712b67afe88faa8011ace8282cfc6 Mon Sep 17 00:00:00 2001 From: patelha57 Date: Wed, 28 Dec 2022 14:56:34 -0800 Subject: [PATCH 50/68] Move CDriverBase from Common to SU2_CFD --- Common/src/drivers/meson.build | 1 - SU2_CFD/include/drivers/CDriver.hpp | 2 +- {Common => SU2_CFD}/include/drivers/CDriverBase.hpp | 8 ++++---- {Common => SU2_CFD}/src/drivers/CDriverBase.cpp | 4 ++-- SU2_CFD/src/meson.build | 3 ++- SU2_DEF/include/drivers/CDeformationDriver.hpp | 2 +- SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp | 2 +- SU2_PY/pySU2/pySU2.i | 9 ++++----- SU2_PY/pySU2/pySU2ad.i | 9 ++++----- 9 files changed, 19 insertions(+), 21 deletions(-) delete mode 100644 Common/src/drivers/meson.build rename {Common => SU2_CFD}/include/drivers/CDriverBase.hpp (99%) rename {Common => SU2_CFD}/src/drivers/CDriverBase.cpp (99%) diff --git a/Common/src/drivers/meson.build b/Common/src/drivers/meson.build deleted file mode 100644 index bcee2ba35cb..00000000000 --- a/Common/src/drivers/meson.build +++ /dev/null @@ -1 +0,0 @@ -common_src += files(['CDriverBase.cpp']) diff --git a/SU2_CFD/include/drivers/CDriver.hpp b/SU2_CFD/include/drivers/CDriver.hpp index 1d4e6f913b8..c6fbde07c5a 100644 --- a/SU2_CFD/include/drivers/CDriver.hpp +++ b/SU2_CFD/include/drivers/CDriver.hpp @@ -28,12 +28,12 @@ #pragma once -#include "../../../Common/include/drivers/CDriverBase.hpp" #include "../../../Common/include/geometry/CGeometry.hpp" #include "../../../Common/include/parallelization/mpi_structure.hpp" #include "../integration/CIntegration.hpp" #include "../interfaces/CInterface.hpp" #include "../solvers/CSolver.hpp" +#include "CDriverBase.hpp" using namespace std; diff --git a/Common/include/drivers/CDriverBase.hpp b/SU2_CFD/include/drivers/CDriverBase.hpp similarity index 99% rename from Common/include/drivers/CDriverBase.hpp rename to SU2_CFD/include/drivers/CDriverBase.hpp index e3acace3892..4eb8490bb73 100644 --- a/Common/include/drivers/CDriverBase.hpp +++ b/SU2_CFD/include/drivers/CDriverBase.hpp @@ -27,10 +27,10 @@ #pragma once -#include "../../../SU2_CFD/include/numerics/CNumerics.hpp" -#include "../../../SU2_CFD/include/output/COutput.hpp" -#include "../../../SU2_CFD/include/solvers/CSolver.hpp" -#include "../CConfig.hpp" +#include "../../../Common/include/CConfig.hpp" +#include "../numerics/CNumerics.hpp" +#include "../output/COutput.hpp" +#include "../solvers/CSolver.hpp" class CDriverBase { protected: diff --git a/Common/src/drivers/CDriverBase.cpp b/SU2_CFD/src/drivers/CDriverBase.cpp similarity index 99% rename from Common/src/drivers/CDriverBase.cpp rename to SU2_CFD/src/drivers/CDriverBase.cpp index 74dda47ce3b..dba80d8b8db 100644 --- a/Common/src/drivers/CDriverBase.cpp +++ b/SU2_CFD/src/drivers/CDriverBase.cpp @@ -27,8 +27,8 @@ #include "../../include/drivers/CDriverBase.hpp" -#include "../../include/geometry/CPhysicalGeometry.hpp" -#include "../../include/toolboxes/geometry_toolbox.hpp" +#include "../../../Common/include/geometry/CPhysicalGeometry.hpp" +#include "../../../Common/include/toolboxes/geometry_toolbox.hpp" using namespace std; diff --git a/SU2_CFD/src/meson.build b/SU2_CFD/src/meson.build index d7c7d156c41..53b2081c660 100644 --- a/SU2_CFD/src/meson.build +++ b/SU2_CFD/src/meson.build @@ -165,7 +165,8 @@ su2_cfd_src += files(['drivers/CDriver.cpp', 'drivers/CSinglezoneDriver.cpp', 'drivers/CDiscAdjMultizoneDriver.cpp', 'drivers/CDiscAdjSinglezoneDriver.cpp', - 'drivers/CDummyDriver.cpp']) + 'drivers/CDummyDriver.cpp', + 'drivers/CDriverBase.cpp']) su2_cfd_src += files(['integration/CIntegration.cpp', 'integration/CIntegrationFactory.cpp', diff --git a/SU2_DEF/include/drivers/CDeformationDriver.hpp b/SU2_DEF/include/drivers/CDeformationDriver.hpp index bded29a1f0d..62954de5b73 100644 --- a/SU2_DEF/include/drivers/CDeformationDriver.hpp +++ b/SU2_DEF/include/drivers/CDeformationDriver.hpp @@ -31,11 +31,11 @@ #include "../../../Common/include/CConfig.hpp" #undef ENABLE_MAPS -#include "../../../Common/include/drivers/CDriverBase.hpp" #include "../../../Common/include/geometry/CGeometry.hpp" #include "../../../Common/include/grid_movement/CSurfaceMovement.hpp" #include "../../../Common/include/grid_movement/CVolumetricMovement.hpp" #include "../../../Common/include/parallelization/mpi_structure.hpp" +#include "../../../SU2_CFD/include/drivers/CDriverBase.hpp" #include "../../../SU2_CFD/include/numerics/CNumerics.hpp" #include "../../../SU2_CFD/include/output/COutput.hpp" diff --git a/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp b/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp index 783e21c98dd..d5b42b958e5 100644 --- a/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp +++ b/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp @@ -31,12 +31,12 @@ #include "../../../Common/include/CConfig.hpp" #undef ENABLE_MAPS -#include "../../../Common/include/drivers/CDriverBase.hpp" #include "../../../Common/include/fem/fem_geometry_structure.hpp" #include "../../../Common/include/geometry/CGeometry.hpp" #include "../../../Common/include/grid_movement/CSurfaceMovement.hpp" #include "../../../Common/include/grid_movement/CVolumetricMovement.hpp" #include "../../../Common/include/parallelization/mpi_structure.hpp" +#include "../../../SU2_CFD/include/drivers/CDriverBase.hpp" #include "../../../SU2_CFD/include/numerics/CGradSmoothing.hpp" #include "../../../SU2_CFD/include/output/CBaselineOutput.hpp" #include "../../../SU2_CFD/include/output/COutput.hpp" diff --git a/SU2_PY/pySU2/pySU2.i b/SU2_PY/pySU2/pySU2.i index 44a6c0c4f33..1d8c424cd28 100644 --- a/SU2_PY/pySU2/pySU2.i +++ b/SU2_PY/pySU2/pySU2.i @@ -37,12 +37,11 @@ directors="1", threads="1" ) pysu2 %{ - -#include "../../Common/include/drivers/CDriverBase.hpp" +#include "../../SU2_CFD/include/drivers/CDiscAdjSinglezoneDriver.hpp" #include "../../SU2_CFD/include/drivers/CDriver.hpp" -#include "../../SU2_CFD/include/drivers/CSinglezoneDriver.hpp" +#include "../../SU2_CFD/include/drivers/CDriverBase.hpp" #include "../../SU2_CFD/include/drivers/CMultizoneDriver.hpp" -#include "../../SU2_CFD/include/drivers/CDiscAdjSinglezoneDriver.hpp" +#include "../../SU2_CFD/include/drivers/CSinglezoneDriver.hpp" #include "../../SU2_DEF/include/drivers/CDeformationDriver.hpp" %} @@ -93,8 +92,8 @@ const unsigned int MESH_1 = 1; /*!< \brief Definition of the finest grid level. const unsigned int ZONE_0 = 0; /*!< \brief Definition of the first grid domain. */ const unsigned int ZONE_1 = 1; /*!< \brief Definition of the first grid domain. */ -%include "../../Common/include/drivers/CDriverBase.hpp" %include "../../SU2_CFD/include/drivers/CDriver.hpp" +%include "../../SU2_CFD/include/drivers/CDriverBase.hpp" %include "../../SU2_CFD/include/drivers/CSinglezoneDriver.hpp" %include "../../SU2_CFD/include/drivers/CMultizoneDriver.hpp" %include "../../SU2_CFD/include/drivers/CDiscAdjSinglezoneDriver.hpp" diff --git a/SU2_PY/pySU2/pySU2ad.i b/SU2_PY/pySU2/pySU2ad.i index b581fb86038..7b347f5cbe1 100644 --- a/SU2_PY/pySU2/pySU2ad.i +++ b/SU2_PY/pySU2/pySU2ad.i @@ -37,12 +37,11 @@ directors="1", threads="1" ) pysu2ad %{ - -#include "../../Common/include/drivers/CDriverBase.hpp" +#include "../../SU2_CFD/include/drivers/CDiscAdjSinglezoneDriver.hpp" #include "../../SU2_CFD/include/drivers/CDriver.hpp" -#include "../../SU2_CFD/include/drivers/CSinglezoneDriver.hpp" +#include "../../SU2_CFD/include/drivers/CDriverBase.hpp" #include "../../SU2_CFD/include/drivers/CMultizoneDriver.hpp" -#include "../../SU2_CFD/include/drivers/CDiscAdjSinglezoneDriver.hpp" +#include "../../SU2_CFD/include/drivers/CSinglezoneDriver.hpp" #include "../../SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp" %} @@ -92,8 +91,8 @@ const unsigned int MESH_1 = 1; /*!< \brief Definition of the finest grid level. const unsigned int ZONE_0 = 0; /*!< \brief Definition of the first grid domain. */ const unsigned int ZONE_1 = 1; /*!< \brief Definition of the first grid domain. */ -%include "../../Common/include/drivers/CDriverBase.hpp" %include "../../SU2_CFD/include/drivers/CDriver.hpp" +%include "../../SU2_CFD/include/drivers/CDriverBase.hpp" %include "../../SU2_CFD/include/drivers/CSinglezoneDriver.hpp" %include "../../SU2_CFD/include/drivers/CMultizoneDriver.hpp" %include "../../SU2_CFD/include/drivers/CDiscAdjSinglezoneDriver.hpp" From 50a2011969c742853b493b2fbe63846af6ecda07 Mon Sep 17 00:00:00 2001 From: patelha57 Date: Wed, 28 Dec 2022 15:06:00 -0800 Subject: [PATCH 51/68] Remove 'drivers' subdirectory from meson build file in Common --- Common/src/meson.build | 1 - 1 file changed, 1 deletion(-) diff --git a/Common/src/meson.build b/Common/src/meson.build index 332b61108bf..3d84e6ea17a 100644 --- a/Common/src/meson.build +++ b/Common/src/meson.build @@ -13,7 +13,6 @@ subdir('geometry/elements') subdir('geometry/dual_grid') subdir('geometry/primal_grid') subdir('geometry/meshreader') -subdir('drivers') subdir('containers') subdir('interface_interpolation') subdir('fem') From 3c8f5cd84eea3a870c6f3b0bf2b74fdbdfead498 Mon Sep 17 00:00:00 2001 From: patelha57 Date: Wed, 28 Dec 2022 16:02:53 -0800 Subject: [PATCH 52/68] Remove pysu2 FFD functions from CDriverBase --- SU2_CFD/include/drivers/CDriverBase.hpp | 106 +--- SU2_CFD/src/drivers/CDriver.cpp | 4 - SU2_CFD/src/drivers/CDriverBase.cpp | 636 ------------------------ 3 files changed, 6 insertions(+), 740 deletions(-) diff --git a/SU2_CFD/include/drivers/CDriverBase.hpp b/SU2_CFD/include/drivers/CDriverBase.hpp index 4eb8490bb73..cec1a78c58a 100644 --- a/SU2_CFD/include/drivers/CDriverBase.hpp +++ b/SU2_CFD/include/drivers/CDriverBase.hpp @@ -127,91 +127,6 @@ class CDriverBase { */ unsigned short GetNumberFFDBoxes() const; - /*! - * \brief Get the number of FFD box corner points. - * \param[in] iFFDBox - FFD box index. - * \return Number of FFD box corner points. - */ - unsigned short GetNumberFFDBoxCornerPoints(unsigned short iFFDBox) const; - - /*! - * \brief Get the number of FFD box control points. - * \param[in] iFFDBox - FFD box index. - * \return Number of FFD box control points. - */ - unsigned short GetNumberFFDBoxControlPoints(unsigned short iFFDBox) const; - - /*! - * \brief Get the number of FFD box surface points. - * \param[in] iFFDBox - FFD box index. - * \return Number of FFD box surface points. - */ - unsigned long GetNumberFFDBoxSurfacePoints(unsigned short iFFDBox) const; - - /*! - * \brief Get the FFD box marker IDs. - * \param[in] iFFDBox - FFD box index. - * \return FFD box marker IDs. - */ - vector GetFFDBoxMarkerIDs(unsigned short iFFDBox) const; - - /*! - * \brief Get the FFD box vertex IDs. - * \param[in] iFFDBox - FFD box index. - * \return FFD box vertex IDs. - */ - vector GetFFDBoxVertexIDs(unsigned short iFFDBox) const; - - /*! - * \brief Get the FFD box grid point IDs. - * \param[in] iFFDBox - FFD box index. - * \return FFD box grid point IDs. - */ - vector GetFFDBoxPointIDs(unsigned short iFFDBox) const; - - /*! - * \brief Get the FFD box corner coordinates. - * \param[in] iFFDBox - FFD box index. - * \return FFD box corner coordinates. - */ - vector> GetFFDBoxCornerCoordinates(unsigned short iFFDBox) const; - - /*! - * \brief Get the FFD box control point coordinates. - * \param[in] iFFDBox - FFD box index. - * \return FFD box control point coordinates. - */ - vector> GetFFDBoxControlPointCoordinates(unsigned short iFFDBox) const; - - /*! - * \brief Get the FFD box control point coordinates. - * \param[in] iFFDBox - FFD box index. - * \param[in] iOrder - Local i-index of the control point. - * \param[in] jOrder - Local j-index of the control point. - * \param[in] kOrder - Local k-index of the control point. - * \return FFD box control point coordinates. - */ - vector GetFFDBoxControlPointCoordinates(unsigned short iFFDBox, unsigned int iOrder, - unsigned int jOrder, unsigned int kOrder) const; - - /*! - * \brief Get the FFD box surface coordinates. - * \param[in] iFFDBox - FFD box index. - * \param[in] parametric - Boolean to indicate if parametric coordinates should be returned. - * \return FFD box surface coordinates. - */ - vector> GetFFDBoxSurfaceCoordinates(unsigned short iFFDBox, bool parametric = false) const; - - /*! - * \brief Get the FFD box surface coordinates. - * \param[in] iFFDBox - FFD box index. - * \param[in] iPoint - FFD surface point index. - * \param[in] parametric - Boolean to indicate if parametric coordinates should be returned. - * \return FFD box surface coordinates. - */ - vector GetFFDBoxSurfaceCoordinates(unsigned short iFFDBox, unsigned long iPoint, - bool parametric = false) const; - /*! * \brief Get the number of markers in the mesh. * \return Number of markers. @@ -583,7 +498,7 @@ class CDriverBase { protected: /*! - * \brief Initialize Containers + * \brief Initialize containers. */ void SetContainers_Null(); @@ -604,18 +519,18 @@ class CDriverBase { /*! * \brief Definition and allocation of all solution classes. - * \param[in] solver_container - Container vector with all the solutions. - * \param[in] geometry - Geometrical definition of the problem. * \param[in] config - Definition of the particular problem. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver - Container vector with all the solutions. */ void Solver_Preprocessing(CConfig* config, CGeometry** geometry, CSolver***& solver); /*! * \brief Definition and allocation of all solver classes. - * \param[in] numerics_container - Description of the numerical method (the way in which the equations are solved). - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] solver_container - Container vector with all the solutions. * \param[in] config - Definition of the particular problem. + * \param[in] geometry - Geometrical definition of the problem. + * \param[in] solver - Container vector with all the solutions. + * \param[in] numerics - Description of the numerical method (the way in which the equations are solved). */ void Numerics_Preprocessing(CConfig* config, CGeometry** geometry, CSolver*** solver, CNumerics****& numerics) const; @@ -628,13 +543,4 @@ class CDriverBase { */ void Output_Preprocessing(CConfig** config, CConfig* driver_config, COutput**& output_container, COutput*& driver_output); - - /*! - * \brief Read the free form deformation box information from the input mesh file. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - * \param[in] FFDBox - Definition of the FFD boxes of the problem. - * \param[in] val_mesh_filename - Name of the input mesh file. - */ - void ReadFFDInfo(CGeometry* geometry, CConfig* config, CFreeFormDefBox** FFDBox, string val_mesh_filename); }; diff --git a/SU2_CFD/src/drivers/CDriver.cpp b/SU2_CFD/src/drivers/CDriver.cpp index d7302267d35..c0a6c49f217 100644 --- a/SU2_CFD/src/drivers/CDriver.cpp +++ b/SU2_CFD/src/drivers/CDriver.cpp @@ -177,9 +177,6 @@ CDriverBase(confFile, val_nZone, MPICommunicator), StopCalc(false), fsi(false), } } - /*--- Read free form deformation design variables data. --- */ - ReadFFDInfo(geometry_container[ZONE_0][INST_0][MESH_0], config_container[ZONE_0], FFDBox[ZONE_0], config_container[ZONE_0]->GetMesh_FileName()); - /*--- Before we proceed with the zone loop we have to compute the wall distances. * This computation depends on all zones at once. ---*/ if (rank == MASTER_NODE) @@ -356,7 +353,6 @@ void CDriver::SetContainers_Null(){ for (iZone = 0; iZone < nZone; iZone++) { interface_types[iZone] = new unsigned short[nZone]; nInst[iZone] = 1; - FFDBox[iZone] = new CFreeFormDefBox*[MAX_NUMBER_FFD]; } strcpy(runtime_file_name, "runtime.dat"); diff --git a/SU2_CFD/src/drivers/CDriverBase.cpp b/SU2_CFD/src/drivers/CDriverBase.cpp index dba80d8b8db..4009c76fa26 100644 --- a/SU2_CFD/src/drivers/CDriverBase.cpp +++ b/SU2_CFD/src/drivers/CDriverBase.cpp @@ -79,198 +79,6 @@ unsigned short CDriverBase::GetNumberDesignVariables() const { return main_confi unsigned short CDriverBase::GetNumberFFDBoxes() const { return main_config->GetnFFDBox(); } -unsigned short CDriverBase::GetNumberFFDBoxCornerPoints(unsigned short iFFDBox) const { - if (GetNumberFFDBoxes() == 0) { - SU2_MPI::Error("FFD Box definition not found in the mesh file.", CURRENT_FUNCTION); - } - if (iFFDBox >= GetNumberFFDBoxes()) { - SU2_MPI::Error("FFD Box index exceeds size.", CURRENT_FUNCTION); - } - - return FFDBox[ZONE_0][iFFDBox]->GetnCornerPoints(); -} - -unsigned short CDriverBase::GetNumberFFDBoxControlPoints(unsigned short iFFDBox) const { - if (GetNumberFFDBoxes() == 0) { - SU2_MPI::Error("FFD Box definition not found in the mesh file.", CURRENT_FUNCTION); - } - if (iFFDBox >= GetNumberFFDBoxes()) { - SU2_MPI::Error("FFD Box index exceeds size.", CURRENT_FUNCTION); - } - - return FFDBox[ZONE_0][iFFDBox]->GetnControlPoints(); -} - -unsigned long CDriverBase::GetNumberFFDBoxSurfacePoints(unsigned short iFFDBox) const { - if (GetNumberFFDBoxes() == 0) { - SU2_MPI::Error("FFD Box definition not found in the mesh file.", CURRENT_FUNCTION); - } - if (iFFDBox >= GetNumberFFDBoxes()) { - SU2_MPI::Error("FFD Box index exceeds size.", CURRENT_FUNCTION); - } - - return FFDBox[ZONE_0][iFFDBox]->GetnSurfacePoint(); -} - -vector CDriverBase::GetFFDBoxMarkerIDs(unsigned short iFFDBox) const { - if (GetNumberFFDBoxes() == 0) { - SU2_MPI::Error("FFD Box definition not found in the mesh file.", CURRENT_FUNCTION); - } - if (iFFDBox >= GetNumberFFDBoxes()) { - SU2_MPI::Error("FFD Box index exceeds size.", CURRENT_FUNCTION); - } - - vector values; - - for (auto iPoint = 0ul; iPoint < GetNumberFFDBoxSurfacePoints(iFFDBox); iPoint++) { - values.push_back(FFDBox[ZONE_0][iFFDBox]->Get_MarkerIndex(iPoint)); - } - return values; -} - -vector CDriverBase::GetFFDBoxVertexIDs(unsigned short iFFDBox) const { - if (GetNumberFFDBoxes() == 0) { - SU2_MPI::Error("FFD Box definition not found in the mesh file.", CURRENT_FUNCTION); - } - if (iFFDBox >= GetNumberFFDBoxes()) { - SU2_MPI::Error("FFD Box index exceeds size.", CURRENT_FUNCTION); - } - - vector values; - - for (auto iPoint = 0ul; iPoint < GetNumberFFDBoxSurfacePoints(iFFDBox); iPoint++) { - values.push_back(FFDBox[ZONE_0][iFFDBox]->Get_VertexIndex(iPoint)); - } - return values; -} - -vector CDriverBase::GetFFDBoxPointIDs(unsigned short iFFDBox) const { - if (GetNumberFFDBoxes() == 0) { - SU2_MPI::Error("FFD Box definition not found in the mesh file.", CURRENT_FUNCTION); - } - if (iFFDBox >= GetNumberFFDBoxes()) { - SU2_MPI::Error("FFD Box index exceeds size.", CURRENT_FUNCTION); - } - - vector values; - - for (auto iPoint = 0ul; iPoint < GetNumberFFDBoxSurfacePoints(iFFDBox); iPoint++) { - values.push_back(FFDBox[ZONE_0][iFFDBox]->Get_PointIndex(iPoint)); - } - return values; -} - -vector> CDriverBase::GetFFDBoxCornerCoordinates(unsigned short iFFDBox) const { - if (GetNumberFFDBoxes() == 0) { - SU2_MPI::Error("FFD Box definition not found in the mesh file.", CURRENT_FUNCTION); - } - if (iFFDBox >= GetNumberFFDBoxes()) { - SU2_MPI::Error("FFD Box index exceeds size.", CURRENT_FUNCTION); - } - - vector> values; - - for (auto iPoint = 0u; iPoint < GetNumberFFDBoxCornerPoints(iFFDBox); iPoint++) { - vector coords; - - const su2double* coord = FFDBox[ZONE_0][iFFDBox]->GetCoordCornerPoints(iPoint); - - for (auto iDim = 0u; iDim < nDim; iDim++) { - coords.push_back(SU2_TYPE::GetValue(coord[iDim])); - } - - values.push_back(coords); - } - - return values; -} - -vector> CDriverBase::GetFFDBoxControlPointCoordinates(unsigned short iFFDBox) const { - if (GetNumberFFDBoxes() == 0) { - SU2_MPI::Error("FFD Box definition not found in the mesh file.", CURRENT_FUNCTION); - } - if (iFFDBox >= GetNumberFFDBoxes()) { - SU2_MPI::Error("FFD Box index exceeds size.", CURRENT_FUNCTION); - } - - vector> values; - - for (auto iOrder = 0u; iOrder < FFDBox[ZONE_0][iFFDBox]->GetlOrder(); iOrder++) { - for (auto jOrder = 0u; jOrder < FFDBox[ZONE_0][iFFDBox]->GetmOrder(); jOrder++) { - for (auto kOrder = 0u; kOrder < FFDBox[ZONE_0][iFFDBox]->GetnOrder(); kOrder++) { - values.push_back(GetFFDBoxControlPointCoordinates(iFFDBox, iOrder, jOrder, kOrder)); - } - } - } - - return values; -} - -vector CDriverBase::GetFFDBoxControlPointCoordinates(unsigned short iFFDBox, unsigned int iOrder, - unsigned int jOrder, unsigned int kOrder) const { - if (GetNumberFFDBoxes() == 0) { - SU2_MPI::Error("FFD Box definition not found in the mesh file.", CURRENT_FUNCTION); - } - if (iFFDBox >= GetNumberFFDBoxes()) { - SU2_MPI::Error("FFD Box index exceeds size.", CURRENT_FUNCTION); - } - - vector values; - - const su2double* coord = FFDBox[ZONE_0][iFFDBox]->GetCoordControlPoints(iOrder, jOrder, kOrder); - - for (auto iDim = 0u; iDim < nDim; iDim++) { - values.push_back(SU2_TYPE::GetValue(coord[iDim])); - } - - return values; -} - -vector> CDriverBase::GetFFDBoxSurfaceCoordinates(unsigned short iFFDBox, bool parametric) const { - if (GetNumberFFDBoxes() == 0) { - SU2_MPI::Error("FFD Box definition not found in the mesh file.", CURRENT_FUNCTION); - } - if (iFFDBox >= GetNumberFFDBoxes()) { - SU2_MPI::Error("FFD Box index exceeds size.", CURRENT_FUNCTION); - } - - vector> values; - - for (auto iPoint = 0ul; iPoint < GetNumberFFDBoxSurfacePoints(iFFDBox); iPoint++) { - values.push_back(GetFFDBoxSurfaceCoordinates(iFFDBox, iPoint, parametric)); - } - - return values; -} - -vector CDriverBase::GetFFDBoxSurfaceCoordinates(unsigned short iFFDBox, unsigned long iPoint, - bool parametric) const { - if (GetNumberFFDBoxes() == 0) { - SU2_MPI::Error("FFD Box definition not found in the mesh file.", CURRENT_FUNCTION); - } - if (iFFDBox >= GetNumberFFDBoxes()) { - SU2_MPI::Error("FFD Box index exceeds size.", CURRENT_FUNCTION); - } - if (iPoint >= GetNumberFFDBoxSurfacePoints(iFFDBox)) { - SU2_MPI::Error("FFD Box vertex index exceeds mesh size.", CURRENT_FUNCTION); - } - - vector values; - const su2double* coord; - - if (parametric) { - coord = FFDBox[ZONE_0][iFFDBox]->Get_ParametricCoord(iPoint); - } else { - coord = FFDBox[ZONE_0][iFFDBox]->Get_CartesianCoord(iPoint); - } - - for (auto iDim = 0u; iDim < nDim; iDim++) { - values.push_back(SU2_TYPE::GetValue(coord[iDim])); - } - - return values; -} - unsigned short CDriverBase::GetNumberMarkers() const { return main_config->GetnMarker_All(); } map CDriverBase::GetMarkerIndices() const { @@ -947,447 +755,3 @@ void CDriverBase::CommunicateMeshDisplacements(void) { solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->InitiateComms(main_geometry, main_config, MESH_DISPLACEMENTS); solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->CompleteComms(main_geometry, main_config, MESH_DISPLACEMENTS); } - -void CDriverBase::ReadFFDInfo(CGeometry* geometry, CConfig* config, CFreeFormDefBox** FFDBox, string val_mesh_filename) { - string text_line, iTag; - ifstream mesh_file; - su2double CPcoord[3], coord[] = {0, 0, 0}; - unsigned short degree[3], iFFDBox, iCornerPoints, iControlPoints, iMarker, iDegree, jDegree, kDegree, iChar, - LevelFFDBox, nParentFFDBox, iParentFFDBox, nChildFFDBox, iChildFFDBox, nMarker, *nCornerPoints, *nControlPoints; - unsigned long iSurfacePoints, iPoint, jPoint, iVertex, nVertex, nPoint, iElem = 0, nElem, my_nSurfPoints, nSurfPoints, - *nSurfacePoints; - su2double XCoord, YCoord; - - bool polar = (config->GetFFD_CoordSystem() == POLAR); - unsigned short nDim = geometry->GetnDim(), iDim; - unsigned short SplineOrder[3]; - unsigned short Blending = 0; - - unsigned short nFFDBox = 0; - unsigned short nLevel = 0; - - if (config->GetMesh_FileFormat() != SU2) { - if (rank == MASTER_NODE) cout << "Mesh file format is not .su2 so FFD box information cannot be extracted." << endl; - return; - } - - mesh_file.open(val_mesh_filename); - if (mesh_file.fail()) { - SU2_MPI::Error("There is no geometry file (ReadFFDInfo)!!", CURRENT_FUNCTION); - } - - while (getline(mesh_file, text_line)) { - /*--- Read the inner elements. ---*/ - - string::size_type position = text_line.find("NELEM=", 0); - if (position != string::npos) { - text_line.erase(0, 6); - nElem = atoi(text_line.c_str()); - for (iElem = 0; iElem < nElem; iElem++) { - getline(mesh_file, text_line); - } - } - - /*--- Read the inner points. ---*/ - - position = text_line.find("NPOIN=", 0); - if (position != string::npos) { - text_line.erase(0, 6); - nPoint = atoi(text_line.c_str()); - for (iPoint = 0; iPoint < nPoint; iPoint++) { - getline(mesh_file, text_line); - } - } - - /*--- Read the boundaries. ---*/ - - position = text_line.find("NMARK=", 0); - if (position != string::npos) { - text_line.erase(0, 6); - nMarker = atoi(text_line.c_str()); - for (iMarker = 0; iMarker < nMarker; iMarker++) { - getline(mesh_file, text_line); - getline(mesh_file, text_line); - text_line.erase(0, 13); - nVertex = atoi(text_line.c_str()); - for (iVertex = 0; iVertex < nVertex; iVertex++) { - getline(mesh_file, text_line); - } - } - } - - /*--- Read the FFDBox information. ---*/ - - position = text_line.find("FFD_NBOX=", 0); - if (position != string::npos) { - text_line.erase(0, 9); - nFFDBox = atoi(text_line.c_str()); - - if (rank == MASTER_NODE) cout << nFFDBox << " Free Form Deformation boxes." << endl; - - nCornerPoints = new unsigned short[nFFDBox]; - nControlPoints = new unsigned short[nFFDBox]; - nSurfacePoints = new unsigned long[nFFDBox]; - - getline(mesh_file, text_line); - text_line.erase(0, 11); - nLevel = atoi(text_line.c_str()); - - if (rank == MASTER_NODE) cout << nLevel << " Free Form Deformation nested levels." << endl; - - for (iFFDBox = 0; iFFDBox < nFFDBox; iFFDBox++) { - /*--- Read the name of the FFD box. ---*/ - - getline(mesh_file, text_line); - text_line.erase(0, 8); - - /*--- Remove extra data from the FFDBox name. ---*/ - - string::size_type position; - for (iChar = 0; iChar < 20; iChar++) { - position = text_line.find(" ", 0); - if (position != string::npos) text_line.erase(position, 1); - position = text_line.find("\r", 0); - if (position != string::npos) text_line.erase(position, 1); - position = text_line.find("\n", 0); - if (position != string::npos) text_line.erase(position, 1); - } - - string TagFFDBox = text_line.c_str(); - - if (rank == MASTER_NODE) cout << "FFD box tag: " << TagFFDBox << ". "; - - /*--- Read the level of the FFD box. ---*/ - - getline(mesh_file, text_line); - text_line.erase(0, 10); - LevelFFDBox = atoi(text_line.c_str()); - - if (rank == MASTER_NODE) cout << "FFD box level: " << LevelFFDBox << ". "; - - /*--- Read the degree of the FFD box. ---*/ - - if (nDim == 2) { - if (polar) { - getline(mesh_file, text_line); - text_line.erase(0, 13); - degree[0] = atoi(text_line.c_str()); - degree[1] = 1; - getline(mesh_file, text_line); - text_line.erase(0, 13); - degree[2] = atoi(text_line.c_str()); - } else { - getline(mesh_file, text_line); - text_line.erase(0, 13); - degree[0] = atoi(text_line.c_str()); - getline(mesh_file, text_line); - text_line.erase(0, 13); - degree[1] = atoi(text_line.c_str()); - degree[2] = 1; - } - } else { - getline(mesh_file, text_line); - text_line.erase(0, 13); - degree[0] = atoi(text_line.c_str()); - getline(mesh_file, text_line); - text_line.erase(0, 13); - degree[1] = atoi(text_line.c_str()); - getline(mesh_file, text_line); - text_line.erase(0, 13); - degree[2] = atoi(text_line.c_str()); - } - - if (rank == MASTER_NODE) { - if (nDim == 2) { - if (polar) - cout << "Degrees: " << degree[0] << ", " << degree[2] << "." << endl; - else - cout << "Degrees: " << degree[0] << ", " << degree[1] << "." << endl; - } else - cout << "Degrees: " << degree[0] << ", " << degree[1] << ", " << degree[2] << "." << endl; - } - - getline(mesh_file, text_line); - if (text_line.substr(0, 12) != "FFD_BLENDING") { - SU2_MPI::Error( - string("Deprecated FFD information found in mesh file.\n") + - string( - "FFD information generated with SU2 version <= 4.3 is incompatible with the current version.") + - string("Run SU2_DEF again with DV_KIND= FFD_SETTING."), - CURRENT_FUNCTION); - } - text_line.erase(0, 14); - if (text_line == "BEZIER") { - Blending = BEZIER; - } - if (text_line == "BSPLINE_UNIFORM") { - Blending = BSPLINE_UNIFORM; - } - - if (Blending == BSPLINE_UNIFORM) { - getline(mesh_file, text_line); - text_line.erase(0, 17); - SplineOrder[0] = atoi(text_line.c_str()); - getline(mesh_file, text_line); - text_line.erase(0, 17); - SplineOrder[1] = atoi(text_line.c_str()); - if (nDim == 3) { - getline(mesh_file, text_line); - text_line.erase(0, 17); - SplineOrder[2] = atoi(text_line.c_str()); - } else { - SplineOrder[2] = 2; - } - } - if (rank == MASTER_NODE) { - if (Blending == BSPLINE_UNIFORM) { - cout << "FFD Blending using B-Splines. "; - cout << "Order: " << SplineOrder[0] << ", " << SplineOrder[1]; - if (nDim == 3) cout << ", " << SplineOrder[2]; - cout << ". " << endl; - } - if (Blending == BEZIER) { - cout << "FFD Blending using Bezier Curves." << endl; - } - } - - FFDBox[iFFDBox] = new CFreeFormDefBox(degree, SplineOrder, Blending); - FFDBox[iFFDBox]->SetTag(TagFFDBox); - FFDBox[iFFDBox]->SetLevel(LevelFFDBox); - - /*--- Read the number of parents boxes. ---*/ - - getline(mesh_file, text_line); - text_line.erase(0, 12); - nParentFFDBox = atoi(text_line.c_str()); - if (rank == MASTER_NODE) cout << "Number of parent boxes: " << nParentFFDBox << ". "; - for (iParentFFDBox = 0; iParentFFDBox < nParentFFDBox; iParentFFDBox++) { - getline(mesh_file, text_line); - - /*--- Remove extra data from the FFDBox name. ---*/ - - string::size_type position; - for (iChar = 0; iChar < 20; iChar++) { - position = text_line.find(" ", 0); - if (position != string::npos) text_line.erase(position, 1); - position = text_line.find("\r", 0); - if (position != string::npos) text_line.erase(position, 1); - position = text_line.find("\n", 0); - if (position != string::npos) text_line.erase(position, 1); - } - - string ParentFFDBox = text_line.c_str(); - FFDBox[iFFDBox]->SetParentFFDBox(ParentFFDBox); - } - - /*--- Read the number of children boxes. ---*/ - - getline(mesh_file, text_line); - text_line.erase(0, 13); - nChildFFDBox = atoi(text_line.c_str()); - if (rank == MASTER_NODE) cout << "Number of child boxes: " << nChildFFDBox << "." << endl; - - for (iChildFFDBox = 0; iChildFFDBox < nChildFFDBox; iChildFFDBox++) { - getline(mesh_file, text_line); - - /*--- Remove extra data from the FFDBox name. ---*/ - - string::size_type position; - for (iChar = 0; iChar < 20; iChar++) { - position = text_line.find(" ", 0); - if (position != string::npos) text_line.erase(position, 1); - position = text_line.find("\r", 0); - if (position != string::npos) text_line.erase(position, 1); - position = text_line.find("\n", 0); - if (position != string::npos) text_line.erase(position, 1); - } - - string ChildFFDBox = text_line.c_str(); - FFDBox[iFFDBox]->SetChildFFDBox(ChildFFDBox); - } - - /*--- Read the number of the corner points. ---*/ - - getline(mesh_file, text_line); - text_line.erase(0, 18); - nCornerPoints[iFFDBox] = atoi(text_line.c_str()); - if (rank == MASTER_NODE) cout << "Corner points: " << nCornerPoints[iFFDBox] << ". "; - if (nDim == 2) nCornerPoints[iFFDBox] = nCornerPoints[iFFDBox] * SU2_TYPE::Int(2); - - /*--- Read the coordinates of the corner points. ---*/ - - if (nDim == 2) { - if (polar) { - getline(mesh_file, text_line); - istringstream FFDBox_line_1(text_line); - FFDBox_line_1 >> XCoord; - FFDBox_line_1 >> YCoord; - - CPcoord[0] = XCoord; - CPcoord[1] = cos(0.1) * YCoord; - CPcoord[2] = -sin(0.1) * YCoord; - FFDBox[iFFDBox]->SetCoordCornerPoints(coord, 4); - - CPcoord[0] = XCoord; - CPcoord[1] = cos(0.1) * YCoord; - CPcoord[2] = sin(0.1) * YCoord; - FFDBox[iFFDBox]->SetCoordCornerPoints(coord, 7); - - getline(mesh_file, text_line); - istringstream FFDBox_line_2(text_line); - FFDBox_line_2 >> XCoord; - FFDBox_line_2 >> YCoord; - - CPcoord[0] = XCoord; - CPcoord[1] = cos(0.1) * YCoord; - CPcoord[2] = -sin(0.1) * YCoord; - FFDBox[iFFDBox]->SetCoordCornerPoints(CPcoord, 0); - - CPcoord[0] = XCoord; - CPcoord[1] = cos(0.1) * YCoord; - CPcoord[2] = sin(0.1) * YCoord; - FFDBox[iFFDBox]->SetCoordCornerPoints(CPcoord, 3); - - getline(mesh_file, text_line); - istringstream FFDBox_line_3(text_line); - FFDBox_line_3 >> XCoord; - FFDBox_line_3 >> YCoord; - - CPcoord[0] = XCoord; - CPcoord[1] = cos(0.1) * YCoord; - CPcoord[2] = -sin(0.1) * YCoord; - FFDBox[iFFDBox]->SetCoordCornerPoints(CPcoord, 1); - - CPcoord[0] = XCoord; - CPcoord[1] = cos(0.1) * YCoord; - CPcoord[2] = sin(0.1) * YCoord; - FFDBox[iFFDBox]->SetCoordCornerPoints(CPcoord, 2); - - getline(mesh_file, text_line); - istringstream FFDBox_line_4(text_line); - FFDBox_line_4 >> XCoord; - FFDBox_line_4 >> YCoord; - - CPcoord[0] = XCoord; - CPcoord[1] = cos(0.1) * YCoord; - CPcoord[2] = -sin(0.1) * YCoord; - FFDBox[iFFDBox]->SetCoordCornerPoints(CPcoord, 5); - - CPcoord[0] = XCoord; - CPcoord[1] = cos(0.1) * YCoord; - CPcoord[2] = sin(0.1) * YCoord; - FFDBox[iFFDBox]->SetCoordCornerPoints(CPcoord, 6); - - } else { - for (iCornerPoints = 0; iCornerPoints < nCornerPoints[iFFDBox]; iCornerPoints++) { - if (iCornerPoints < nCornerPoints[iFFDBox] / SU2_TYPE::Int(2)) { - getline(mesh_file, text_line); - istringstream FFDBox_line(text_line); - FFDBox_line >> CPcoord[0]; - FFDBox_line >> CPcoord[1]; - CPcoord[2] = -0.5; - } else { - CPcoord[0] = - FFDBox[iFFDBox]->GetCoordCornerPoints(0, iCornerPoints - nCornerPoints[iFFDBox] / SU2_TYPE::Int(2)); - CPcoord[1] = - FFDBox[iFFDBox]->GetCoordCornerPoints(1, iCornerPoints - nCornerPoints[iFFDBox] / SU2_TYPE::Int(2)); - CPcoord[2] = 0.5; - } - FFDBox[iFFDBox]->SetCoordCornerPoints(CPcoord, iCornerPoints); - } - } - - } else { - for (iCornerPoints = 0; iCornerPoints < nCornerPoints[iFFDBox]; iCornerPoints++) { - getline(mesh_file, text_line); - istringstream FFDBox_line(text_line); - FFDBox_line >> CPcoord[0]; - FFDBox_line >> CPcoord[1]; - FFDBox_line >> CPcoord[2]; - FFDBox[iFFDBox]->SetCoordCornerPoints(CPcoord, iCornerPoints); - } - } - - /*--- Read the number of the control points. ---*/ - - getline(mesh_file, text_line); - text_line.erase(0, 19); - nControlPoints[iFFDBox] = atoi(text_line.c_str()); - - if (rank == MASTER_NODE) cout << "Control points: " << nControlPoints[iFFDBox] << ". "; - - /*--- Read the coordinates of the control points. ---*/ - - for (iControlPoints = 0; iControlPoints < nControlPoints[iFFDBox]; iControlPoints++) { - getline(mesh_file, text_line); - istringstream FFDBox_line(text_line); - FFDBox_line >> iDegree; - FFDBox_line >> jDegree; - FFDBox_line >> kDegree; - FFDBox_line >> CPcoord[0]; - FFDBox_line >> CPcoord[1]; - FFDBox_line >> CPcoord[2]; - FFDBox[iFFDBox]->SetCoordControlPoints(CPcoord, iDegree, jDegree, kDegree); - FFDBox[iFFDBox]->SetCoordControlPoints_Copy(CPcoord, iDegree, jDegree, kDegree); - } - - getline(mesh_file, text_line); - text_line.erase(0, 19); - nSurfacePoints[iFFDBox] = atoi(text_line.c_str()); - - /*--- The surface points parametric coordinates (all the nodes read the FFD - * information but they only store their part). ---*/ - - my_nSurfPoints = 0; - for (iSurfacePoints = 0; iSurfacePoints < nSurfacePoints[iFFDBox]; iSurfacePoints++) { - getline(mesh_file, text_line); - istringstream FFDBox_line(text_line); - FFDBox_line >> iTag; - FFDBox_line >> iPoint; - - if (config->GetMarker_All_TagBound(iTag) != -1) { - iMarker = config->GetMarker_All_TagBound(iTag); - FFDBox_line >> CPcoord[0]; - FFDBox_line >> CPcoord[1]; - FFDBox_line >> CPcoord[2]; - - for (iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { - jPoint = geometry->vertex[iMarker][iVertex]->GetNode(); - if (iPoint == geometry->nodes->GetGlobalIndex(jPoint)) { - for (iDim = 0; iDim < nDim; iDim++) { - coord[iDim] = geometry->nodes->GetCoord(jPoint, iDim); - } - FFDBox[iFFDBox]->Set_MarkerIndex(iMarker); - FFDBox[iFFDBox]->Set_VertexIndex(iVertex); - FFDBox[iFFDBox]->Set_PointIndex(jPoint); - FFDBox[iFFDBox]->Set_ParametricCoord(CPcoord); - FFDBox[iFFDBox]->Set_CartesianCoord(coord); - my_nSurfPoints++; - } - } - } - } - - nSurfacePoints[iFFDBox] = my_nSurfPoints; - -#ifdef HAVE_MPI - nSurfPoints = 0; - SU2_MPI::Allreduce(&my_nSurfPoints, &nSurfPoints, 1, MPI_UNSIGNED_LONG, MPI_SUM, SU2_MPI::GetComm()); - if (rank == MASTER_NODE) cout << "Surface points: " << nSurfPoints << "." << endl; -#else - nSurfPoints = my_nSurfPoints; - if (rank == MASTER_NODE) cout << "Surface points: " << nSurfPoints << "." << endl; -#endif - } - - delete[] nCornerPoints; - delete[] nControlPoints; - delete[] nSurfacePoints; - } - } - mesh_file.close(); - - if (nFFDBox == 0) { - if (rank == MASTER_NODE) cout << "There is no FFD box definition. Just in case, check the .su2 file" << endl; - } -} From 030030ad31dab0dd4eec27952ccfe43126751d58 Mon Sep 17 00:00:00 2001 From: patelha57 Date: Wed, 28 Dec 2022 16:51:48 -0800 Subject: [PATCH 53/68] Apply clang format to python_wrapper_structure.cpp --- SU2_CFD/src/python_wrapper_structure.cpp | 1058 +++++++++++----------- 1 file changed, 504 insertions(+), 554 deletions(-) diff --git a/SU2_CFD/src/python_wrapper_structure.cpp b/SU2_CFD/src/python_wrapper_structure.cpp index 9ee05047ee9..b3d8feed938 100644 --- a/SU2_CFD/src/python_wrapper_structure.cpp +++ b/SU2_CFD/src/python_wrapper_structure.cpp @@ -1,324 +1,292 @@ /*! - * \file python_wrapper_structure.cpp - * \brief Driver subroutines that are used by the Python wrapper. Those routines are usually called from an external Python environment. - * \author D. Thomas - * \version 7.5.0 "Blackbird" - * - * SU2 Project Website: https://su2code.github.io - * - * The SU2 Project is maintained by the SU2 Foundation - * (http://su2foundation.org) - * - * Copyright 2012-2022, SU2 Contributors (cf. AUTHORS.md) - * - * SU2 is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * SU2 is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with SU2. If not, see . - */ - +* \file python_wrapper_structure.cpp +* \brief Driver subroutines that are used by the Python wrapper (usually called from an external Python environment). +* \author D. Thomas +* \version 7.5.0 "Blackbird" +* +* SU2 Project Website: https://su2code.github.io +* +* The SU2 Project is maintained by the SU2 Foundation +* (http://su2foundation.org) +* +* Copyright 2012-2022, SU2 Contributors (cf. AUTHORS.md) +* +* SU2 is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2.1 of the License, or (at your option) any later version. +* +* SU2 is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with SU2. If not, see . +*/ +#include "../../Common/include/toolboxes/geometry_toolbox.hpp" #include "../include/drivers/CDriver.hpp" #include "../include/drivers/CSinglezoneDriver.hpp" -#include "../../Common/include/toolboxes/geometry_toolbox.hpp" -void CDriver::PythonInterface_Preprocessing(CConfig **config, CGeometry ****geometry, CSolver *****solver){ - - int rank = MASTER_NODE; - SU2_MPI::Comm_rank(SU2_MPI::GetComm(), &rank); - - /* --- Initialize boundary conditions customization, this is achieve through the Python wrapper --- */ - for(iZone=0; iZone < nZone; iZone++){ - - if (config[iZone]->GetnMarker_PyCustom() > 0){ - - if (rank == MASTER_NODE) cout << endl << "----------------- Python Interface Preprocessing ( Zone "<< iZone <<" ) -----------------" << endl; - - if (rank == MASTER_NODE) cout << "Setting customized boundary conditions for zone " << iZone << endl; - for (iMesh = 0; iMesh <= config[iZone]->GetnMGLevels(); iMesh++) { - geometry[iZone][INST_0][iMesh]->SetCustomBoundary(config[iZone]); - } - geometry[iZone][INST_0][MESH_0]->UpdateCustomBoundaryConditions(geometry[iZone][INST_0], config[iZone]); - - if ((config[iZone]->GetKind_Solver() == MAIN_SOLVER::EULER) || - (config[iZone]->GetKind_Solver() == MAIN_SOLVER::NAVIER_STOKES) || - (config[iZone]->GetKind_Solver() == MAIN_SOLVER::RANS) || - (config[iZone]->GetKind_Solver() == MAIN_SOLVER::INC_EULER) || - (config[iZone]->GetKind_Solver() == MAIN_SOLVER::INC_NAVIER_STOKES) || - (config[iZone]->GetKind_Solver() == MAIN_SOLVER::INC_RANS) || - (config[iZone]->GetKind_Solver() == MAIN_SOLVER::NEMO_EULER) || - (config[iZone]->GetKind_Solver() == MAIN_SOLVER::NEMO_NAVIER_STOKES)) { - - solver[iZone][INST_0][MESH_0][FLOW_SOL]->UpdateCustomBoundaryConditions(geometry[iZone][INST_0], config[iZone]); - } - } +void CDriver::PythonInterface_Preprocessing(CConfig** config, CGeometry**** geometry, CSolver***** solver) { + int rank = MASTER_NODE; + SU2_MPI::Comm_rank(SU2_MPI::GetComm(), &rank); + + /* --- Initialize boundary conditions customization, this is achieved through the Python wrapper. --- */ + for (iZone = 0; iZone < nZone; iZone++) { + if (config[iZone]->GetnMarker_PyCustom() > 0) { + if (rank == MASTER_NODE) cout << "----------------- Python Interface Preprocessing ( Zone " << iZone << " ) -----------------" << endl; + + if (rank == MASTER_NODE) cout << "Setting customized boundary conditions for zone " << iZone << endl; + for (iMesh = 0; iMesh <= config[iZone]->GetnMGLevels(); iMesh++) { + geometry[iZone][INST_0][iMesh]->SetCustomBoundary(config[iZone]); + } + geometry[iZone][INST_0][MESH_0]->UpdateCustomBoundaryConditions(geometry[iZone][INST_0], config[iZone]); + + if ((config[iZone]->GetKind_Solver() == MAIN_SOLVER::EULER) || + (config[iZone]->GetKind_Solver() == MAIN_SOLVER::NAVIER_STOKES) || + (config[iZone]->GetKind_Solver() == MAIN_SOLVER::RANS) || + (config[iZone]->GetKind_Solver() == MAIN_SOLVER::INC_EULER) || + (config[iZone]->GetKind_Solver() == MAIN_SOLVER::INC_NAVIER_STOKES) || + (config[iZone]->GetKind_Solver() == MAIN_SOLVER::INC_RANS) || + (config[iZone]->GetKind_Solver() == MAIN_SOLVER::NEMO_EULER) || + (config[iZone]->GetKind_Solver() == MAIN_SOLVER::NEMO_NAVIER_STOKES)) { + solver[iZone][INST_0][MESH_0][FLOW_SOL]->UpdateCustomBoundaryConditions(geometry[iZone][INST_0], config[iZone]); + } } - + } } ///////////////////////////////////////////////////////////////////////////// -/* Functions related to the global performance indices (Lift, Drag, ecc..) */ +/* Functions related to the global performance indices (Lift, Drag, etc.) */ ///////////////////////////////////////////////////////////////////////////// passivedouble CDriver::Get_Drag() const { - - unsigned short val_iZone = ZONE_0; - unsigned short FinestMesh = config_container[val_iZone]->GetFinestMesh(); - su2double CDrag, factor, val_Drag; - - /*--- Calculate drag force based on drag coefficient ---*/ - factor = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetAeroCoeffsReferenceForce(); - CDrag = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetTotal_CD(); - - val_Drag = CDrag*factor; - - return SU2_TYPE::GetValue(val_Drag); + unsigned short val_iZone = ZONE_0; + unsigned short FinestMesh = config_container[val_iZone]->GetFinestMesh(); + su2double CDrag, factor, val_Drag; + + /*--- Calculate drag force based on drag coefficient ---*/ + factor = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetAeroCoeffsReferenceForce(); + CDrag = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetTotal_CD(); + + val_Drag = CDrag * factor; + + return SU2_TYPE::GetValue(val_Drag); } passivedouble CDriver::Get_Lift() const { - - unsigned short val_iZone = ZONE_0; - unsigned short FinestMesh = config_container[val_iZone]->GetFinestMesh(); - su2double CLift, factor, val_Lift; - - /*--- Calculate drag force based on drag coefficient ---*/ - factor = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetAeroCoeffsReferenceForce(); - CLift = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetTotal_CL(); - - val_Lift = CLift*factor; - - return SU2_TYPE::GetValue(val_Lift); + unsigned short val_iZone = ZONE_0; + unsigned short FinestMesh = config_container[val_iZone]->GetFinestMesh(); + su2double CLift, factor, val_Lift; + + /*--- Calculate drag force based on drag coefficient ---*/ + factor = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetAeroCoeffsReferenceForce(); + CLift = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetTotal_CL(); + + val_Lift = CLift * factor; + + return SU2_TYPE::GetValue(val_Lift); } passivedouble CDriver::Get_Mx() const { - - unsigned short val_iZone = ZONE_0; - unsigned short FinestMesh = config_container[val_iZone]->GetFinestMesh(); - su2double CMx, RefLengthCoeff, factor, val_Mx; - - RefLengthCoeff = config_container[val_iZone]->GetRefLength(); - - /*--- Calculate moment around x-axis based on coefficients ---*/ - factor = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetAeroCoeffsReferenceForce(); - CMx = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetTotal_CMx(); - - val_Mx = CMx*factor*RefLengthCoeff; - - return SU2_TYPE::GetValue(val_Mx); + unsigned short val_iZone = ZONE_0; + unsigned short FinestMesh = config_container[val_iZone]->GetFinestMesh(); + su2double CMx, RefLengthCoeff, factor, val_Mx; + + RefLengthCoeff = config_container[val_iZone]->GetRefLength(); + + /*--- Calculate moment around x-axis based on coefficients ---*/ + factor = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetAeroCoeffsReferenceForce(); + CMx = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetTotal_CMx(); + + val_Mx = CMx * factor * RefLengthCoeff; + + return SU2_TYPE::GetValue(val_Mx); } passivedouble CDriver::Get_My() const { - - unsigned short val_iZone = ZONE_0; - unsigned short FinestMesh = config_container[val_iZone]->GetFinestMesh(); - su2double CMy, RefLengthCoeff, factor, val_My; - - RefLengthCoeff = config_container[val_iZone]->GetRefLength(); - - /*--- Calculate moment around x-axis based on coefficients ---*/ - factor = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetAeroCoeffsReferenceForce(); - CMy = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetTotal_CMy(); - - val_My = CMy*factor*RefLengthCoeff; - - return SU2_TYPE::GetValue(val_My); + unsigned short val_iZone = ZONE_0; + unsigned short FinestMesh = config_container[val_iZone]->GetFinestMesh(); + su2double CMy, RefLengthCoeff, factor, val_My; + + RefLengthCoeff = config_container[val_iZone]->GetRefLength(); + + /*--- Calculate moment around x-axis based on coefficients ---*/ + factor = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetAeroCoeffsReferenceForce(); + CMy = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetTotal_CMy(); + + val_My = CMy * factor * RefLengthCoeff; + + return SU2_TYPE::GetValue(val_My); } passivedouble CDriver::Get_Mz() const { - - unsigned short val_iZone = ZONE_0; - unsigned short FinestMesh = config_container[val_iZone]->GetFinestMesh(); - su2double CMz, RefLengthCoeff, factor, val_Mz; - - RefLengthCoeff = config_container[val_iZone]->GetRefLength(); - - /*--- Calculate moment around z-axis based on coefficients ---*/ - factor = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetAeroCoeffsReferenceForce(); - CMz = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetTotal_CMz(); - - val_Mz = CMz*factor*RefLengthCoeff; - - return SU2_TYPE::GetValue(val_Mz); + unsigned short val_iZone = ZONE_0; + unsigned short FinestMesh = config_container[val_iZone]->GetFinestMesh(); + su2double CMz, RefLengthCoeff, factor, val_Mz; + + RefLengthCoeff = config_container[val_iZone]->GetRefLength(); + + /*--- Calculate moment around z-axis based on coefficients ---*/ + factor = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetAeroCoeffsReferenceForce(); + CMz = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetTotal_CMz(); + + val_Mz = CMz * factor * RefLengthCoeff; + + return SU2_TYPE::GetValue(val_Mz); } passivedouble CDriver::Get_DragCoeff() const { - - unsigned short val_iZone = ZONE_0; - unsigned short FinestMesh = config_container[val_iZone]->GetFinestMesh(); - su2double CDrag; - - CDrag = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetTotal_CD(); - - return SU2_TYPE::GetValue(CDrag); + unsigned short val_iZone = ZONE_0; + unsigned short FinestMesh = config_container[val_iZone]->GetFinestMesh(); + su2double CDrag; + + CDrag = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetTotal_CD(); + + return SU2_TYPE::GetValue(CDrag); } passivedouble CDriver::Get_LiftCoeff() const { - - unsigned short val_iZone = ZONE_0; - unsigned short FinestMesh = config_container[val_iZone]->GetFinestMesh(); - su2double CLift; - - CLift = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetTotal_CL(); - - return SU2_TYPE::GetValue(CLift); + unsigned short val_iZone = ZONE_0; + unsigned short FinestMesh = config_container[val_iZone]->GetFinestMesh(); + su2double CLift; + + CLift = solver_container[val_iZone][INST_0][FinestMesh][FLOW_SOL]->GetTotal_CL(); + + return SU2_TYPE::GetValue(CLift); } ////////////////////////////////////////////////////////////////////////////////// -/* Functions to obtain global parameters from SU2 (time steps, delta t, ecc...) */ +/* Functions to obtain global parameters from SU2 (time steps, delta t, etc.) */ ////////////////////////////////////////////////////////////////////////////////// -unsigned long CDriver::GetnTimeIter() const { - - return config_container[ZONE_0]->GetnTime_Iter(); -} +unsigned long CDriver::GetnTimeIter() const { return config_container[ZONE_0]->GetnTime_Iter(); } -unsigned long CDriver::GetTime_Iter() const{ - - return TimeIter; -} +unsigned long CDriver::GetTime_Iter() const { return TimeIter; } passivedouble CDriver::GetUnsteady_TimeStep() const { - - return SU2_TYPE::GetValue(config_container[ZONE_0]->GetTime_Step()); + return SU2_TYPE::GetValue(config_container[ZONE_0]->GetTime_Step()); } -string CDriver::GetSurfaceFileName() const { - - return config_container[ZONE_0]->GetSurfCoeff_FileName(); -} +string CDriver::GetSurfaceFileName() const { return config_container[ZONE_0]->GetSurfCoeff_FileName(); } /////////////////////////////////////////////////////////////////////////////// /* Functions related to CHT solver */ /////////////////////////////////////////////////////////////////////////////// passivedouble CDriver::GetVertexTemperature(unsigned short iMarker, unsigned long iVertex) const { - - unsigned long iPoint; - su2double vertexWallTemp(0.0); - - bool compressible = (config_container[ZONE_0]->GetKind_Regime() == ENUM_REGIME::COMPRESSIBLE); - - iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); - - if(geometry_container[ZONE_0][INST_0][MESH_0]->nodes->GetDomain(iPoint) && compressible){ - vertexWallTemp = solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]->GetNodes()->GetTemperature(iPoint); - } - - return SU2_TYPE::GetValue(vertexWallTemp); - + unsigned long iPoint; + su2double vertexWallTemp(0.0); + + bool compressible = (config_container[ZONE_0]->GetKind_Regime() == ENUM_REGIME::COMPRESSIBLE); + + iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); + + if (geometry_container[ZONE_0][INST_0][MESH_0]->nodes->GetDomain(iPoint) && compressible) { + vertexWallTemp = solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]->GetNodes()->GetTemperature(iPoint); + } + + return SU2_TYPE::GetValue(vertexWallTemp); } -void CDriver::SetVertexTemperature(unsigned short iMarker, unsigned long iVertex, passivedouble val_WallTemp){ - - geometry_container[ZONE_0][INST_0][MESH_0]->SetCustomBoundaryTemperature(iMarker, iVertex, val_WallTemp); +void CDriver::SetVertexTemperature(unsigned short iMarker, unsigned long iVertex, passivedouble val_WallTemp) { + geometry_container[ZONE_0][INST_0][MESH_0]->SetCustomBoundaryTemperature(iMarker, iVertex, val_WallTemp); } vector CDriver::GetVertexHeatFluxes(unsigned short iMarker, unsigned long iVertex) const { - - unsigned long iPoint; - unsigned short iDim; - su2double Prandtl_Lam = config_container[ZONE_0]->GetPrandtl_Lam(); - su2double Gas_Constant = config_container[ZONE_0]->GetGas_ConstantND(); - su2double Gamma = config_container[ZONE_0]->GetGamma(); - su2double Gamma_Minus_One = Gamma - 1.0; - su2double Cp = (Gamma / Gamma_Minus_One) * Gas_Constant; - su2double laminar_viscosity, thermal_conductivity; - vector GradT (3,0.0); - vector HeatFlux (3,0.0); - vector HeatFluxPassive (3,0.0); - - bool compressible = (config_container[ZONE_0]->GetKind_Regime() == ENUM_REGIME::COMPRESSIBLE); - - iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); - - if(compressible){ - laminar_viscosity = solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]->GetNodes()->GetLaminarViscosity(iPoint); - thermal_conductivity = Cp * (laminar_viscosity/Prandtl_Lam); - for(iDim=0; iDim < nDim; iDim++){ - GradT[iDim] = solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]->GetNodes()->GetGradient_Primitive(iPoint, 0, iDim); - HeatFlux[iDim] = -thermal_conductivity*GradT[iDim]; - } + unsigned long iPoint; + unsigned short iDim; + su2double Prandtl_Lam = config_container[ZONE_0]->GetPrandtl_Lam(); + su2double Gas_Constant = config_container[ZONE_0]->GetGas_ConstantND(); + su2double Gamma = config_container[ZONE_0]->GetGamma(); + su2double Gamma_Minus_One = Gamma - 1.0; + su2double Cp = (Gamma / Gamma_Minus_One) * Gas_Constant; + su2double laminar_viscosity, thermal_conductivity; + vector GradT(3, 0.0); + vector HeatFlux(3, 0.0); + vector HeatFluxPassive(3, 0.0); + + bool compressible = (config_container[ZONE_0]->GetKind_Regime() == ENUM_REGIME::COMPRESSIBLE); + + iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); + + if (compressible) { + laminar_viscosity = solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]->GetNodes()->GetLaminarViscosity(iPoint); + thermal_conductivity = Cp * (laminar_viscosity / Prandtl_Lam); + for (iDim = 0; iDim < nDim; iDim++) { + GradT[iDim] = solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]->GetNodes()->GetGradient_Primitive(iPoint, 0, iDim); + HeatFlux[iDim] = -thermal_conductivity * GradT[iDim]; } - - HeatFluxPassive[0] = SU2_TYPE::GetValue(HeatFlux[0]); - HeatFluxPassive[1] = SU2_TYPE::GetValue(HeatFlux[1]); - HeatFluxPassive[2] = SU2_TYPE::GetValue(HeatFlux[2]); - - return HeatFluxPassive; -} - -passivedouble CDriver::GetVertexNormalHeatFlux(unsigned short iMarker, unsigned long iVertex) const{ - - unsigned long iPoint; - unsigned short iDim; - su2double vertexWallHeatFlux; - su2double Prandtl_Lam = config_container[ZONE_0]->GetPrandtl_Lam(); - su2double Gas_Constant = config_container[ZONE_0]->GetGas_ConstantND(); - su2double Gamma = config_container[ZONE_0]->GetGamma(); - su2double Gamma_Minus_One = Gamma - 1.0; - su2double Cp = (Gamma / Gamma_Minus_One) * Gas_Constant; - su2double Area; - su2double laminar_viscosity, thermal_conductivity, dTdn; - su2double *Normal, GradT[3] = {0.0,0.0,0.0}, UnitNormal[3] = {0.0,0.0,0.0}; - - bool compressible = (config_container[ZONE_0]->GetKind_Regime() == ENUM_REGIME::COMPRESSIBLE); - - vertexWallHeatFlux = 0.0; - dTdn = 0.0; - - iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); - - if(geometry_container[ZONE_0][INST_0][MESH_0]->nodes->GetDomain(iPoint) && compressible){ - Normal = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNormal(); - - Area = GeometryToolbox::Norm(nDim, Normal); - - for (iDim = 0; iDim < nDim; iDim++) - UnitNormal[iDim] = Normal[iDim]/Area; - - laminar_viscosity = solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]->GetNodes()->GetLaminarViscosity(iPoint); - thermal_conductivity = Cp * (laminar_viscosity/Prandtl_Lam); - /*Compute wall heat flux (normal to the wall) based on computed temperature gradient*/ - for(iDim=0; iDim < nDim; iDim++){ - GradT[iDim] = solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]->GetNodes()->GetGradient_Primitive(iPoint, 0, iDim); - dTdn += GradT[iDim]*UnitNormal[iDim]; - } - - vertexWallHeatFlux = -thermal_conductivity*dTdn; + } + + HeatFluxPassive[0] = SU2_TYPE::GetValue(HeatFlux[0]); + HeatFluxPassive[1] = SU2_TYPE::GetValue(HeatFlux[1]); + HeatFluxPassive[2] = SU2_TYPE::GetValue(HeatFlux[2]); + + return HeatFluxPassive; +} + +passivedouble CDriver::GetVertexNormalHeatFlux(unsigned short iMarker, unsigned long iVertex) const { + unsigned long iPoint; + unsigned short iDim; + su2double vertexWallHeatFlux; + su2double Prandtl_Lam = config_container[ZONE_0]->GetPrandtl_Lam(); + su2double Gas_Constant = config_container[ZONE_0]->GetGas_ConstantND(); + su2double Gamma = config_container[ZONE_0]->GetGamma(); + su2double Gamma_Minus_One = Gamma - 1.0; + su2double Cp = (Gamma / Gamma_Minus_One) * Gas_Constant; + su2double Area; + su2double laminar_viscosity, thermal_conductivity, dTdn; + su2double *Normal, GradT[3] = {0.0, 0.0, 0.0}, UnitNormal[3] = {0.0, 0.0, 0.0}; + + bool compressible = (config_container[ZONE_0]->GetKind_Regime() == ENUM_REGIME::COMPRESSIBLE); + + vertexWallHeatFlux = 0.0; + dTdn = 0.0; + + iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); + + if (geometry_container[ZONE_0][INST_0][MESH_0]->nodes->GetDomain(iPoint) && compressible) { + Normal = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNormal(); + + Area = GeometryToolbox::Norm(nDim, Normal); + + for (iDim = 0; iDim < nDim; iDim++) UnitNormal[iDim] = Normal[iDim] / Area; + + laminar_viscosity = solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]->GetNodes()->GetLaminarViscosity(iPoint); + thermal_conductivity = Cp * (laminar_viscosity / Prandtl_Lam); + /*Compute wall heat flux (normal to the wall) based on computed temperature gradient*/ + for (iDim = 0; iDim < nDim; iDim++) { + GradT[iDim] = solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]->GetNodes()->GetGradient_Primitive(iPoint, 0, iDim); + dTdn += GradT[iDim] * UnitNormal[iDim]; } - - return SU2_TYPE::GetValue(vertexWallHeatFlux); + + vertexWallHeatFlux = -thermal_conductivity * dTdn; + } + + return SU2_TYPE::GetValue(vertexWallHeatFlux); } -void CDriver::SetVertexNormalHeatFlux(unsigned short iMarker, unsigned long iVertex, passivedouble val_WallHeatFlux){ - - geometry_container[ZONE_0][INST_0][MESH_0]->SetCustomBoundaryHeatFlux(iMarker, iVertex, val_WallHeatFlux); +void CDriver::SetVertexNormalHeatFlux(unsigned short iMarker, unsigned long iVertex, passivedouble val_WallHeatFlux) { + geometry_container[ZONE_0][INST_0][MESH_0]->SetCustomBoundaryHeatFlux(iMarker, iVertex, val_WallHeatFlux); } passivedouble CDriver::GetThermalConductivity(unsigned short iMarker, unsigned long iVertex) const { - - unsigned long iPoint; - su2double Prandtl_Lam = config_container[ZONE_0]->GetPrandtl_Lam(); - su2double Gas_Constant = config_container[ZONE_0]->GetGas_ConstantND(); - su2double Gamma = config_container[ZONE_0]->GetGamma(); - su2double Gamma_Minus_One = Gamma - 1.0; - su2double Cp = (Gamma / Gamma_Minus_One) * Gas_Constant; - su2double laminar_viscosity, thermal_conductivity; - - iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); - laminar_viscosity = solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]->GetNodes()->GetLaminarViscosity(iPoint); - thermal_conductivity = Cp * (laminar_viscosity/Prandtl_Lam); - - return SU2_TYPE::GetValue(thermal_conductivity); - + unsigned long iPoint; + su2double Prandtl_Lam = config_container[ZONE_0]->GetPrandtl_Lam(); + su2double Gas_Constant = config_container[ZONE_0]->GetGas_ConstantND(); + su2double Gamma = config_container[ZONE_0]->GetGamma(); + su2double Gamma_Minus_One = Gamma - 1.0; + su2double Cp = (Gamma / Gamma_Minus_One) * Gas_Constant; + su2double laminar_viscosity, thermal_conductivity; + + iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); + laminar_viscosity = solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]->GetNodes()->GetLaminarViscosity(iPoint); + thermal_conductivity = Cp * (laminar_viscosity / Prandtl_Lam); + + return SU2_TYPE::GetValue(thermal_conductivity); } //////////////////////////////////////////////////////////////////////////////// @@ -326,231 +294,228 @@ passivedouble CDriver::GetThermalConductivity(unsigned short iMarker, unsigned l //////////////////////////////////////////////////////////////////////////////// vector CDriver::GetCHTMarkerTags() const { - vector tags; - const auto nMarker = config_container[ZONE_0]->GetnMarker_All(); - - //The CHT markers can be identified as the markers that are customizable with a BC type HEAT_FLUX or ISOTHERMAL. - for (auto iMarker = 0u; iMarker < nMarker; iMarker++) { - if ((config_container[ZONE_0]->GetMarker_All_KindBC(iMarker) == HEAT_FLUX || - config_container[ZONE_0]->GetMarker_All_KindBC(iMarker) == ISOTHERMAL) && config_container[ZONE_0]->GetMarker_All_PyCustom(iMarker)){ - - tags.push_back(config_container[ZONE_0]->GetMarker_All_TagBound(iMarker)); - } + vector tags; + const auto nMarker = config_container[ZONE_0]->GetnMarker_All(); + + // The CHT markers can be identified as the markers that are customizable with a BC type HEAT_FLUX or ISOTHERMAL. + for (auto iMarker = 0u; iMarker < nMarker; iMarker++) { + if ((config_container[ZONE_0]->GetMarker_All_KindBC(iMarker) == HEAT_FLUX || + config_container[ZONE_0]->GetMarker_All_KindBC(iMarker) == ISOTHERMAL) && + config_container[ZONE_0]->GetMarker_All_PyCustom(iMarker)) { + tags.push_back(config_container[ZONE_0]->GetMarker_All_TagBound(iMarker)); } - - return tags; + } + + return tags; } vector CDriver::GetInletMarkerTags() const { - vector tags; - const auto nMarker = config_container[ZONE_0]->GetnMarker_All(); - - for (auto iMarker = 0u; iMarker < nMarker; iMarker++) { - bool isCustomizable = config_container[ZONE_0]->GetMarker_All_PyCustom(iMarker); - bool isInlet = (config_container[ZONE_0]->GetMarker_All_KindBC(iMarker) == INLET_FLOW); - - if (isCustomizable && isInlet) { - tags.push_back(config_container[ZONE_0]->GetMarker_All_TagBound(iMarker)); - } - } - - return tags; -} - -void CDriver::SetHeatSource_Position(passivedouble alpha, passivedouble pos_x, passivedouble pos_y, passivedouble pos_z){ - - CSolver *solver = solver_container[ZONE_0][INST_0][MESH_0][RAD_SOL]; - - config_container[ZONE_0]->SetHeatSource_Rot_Z(alpha); - config_container[ZONE_0]->SetHeatSource_Center(pos_x, pos_y, pos_z); - - solver->SetVolumetricHeatSource(geometry_container[ZONE_0][INST_0][MESH_0], config_container[ZONE_0]); - -} - -void CDriver::SetInlet_Angle(unsigned short iMarker, passivedouble alpha){ - - su2double alpha_rad = alpha * PI_NUMBER/180.0; - - unsigned long iVertex; - - for (iVertex = 0; iVertex < geometry_container[ZONE_0][INST_0][MESH_0]->nVertex[iMarker]; iVertex++){ - solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]->SetInlet_FlowDir(iMarker, iVertex, 0, cos(alpha_rad)); - solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]->SetInlet_FlowDir(iMarker, iVertex, 1, sin(alpha_rad)); + vector tags; + const auto nMarker = config_container[ZONE_0]->GetnMarker_All(); + + for (auto iMarker = 0u; iMarker < nMarker; iMarker++) { + bool isCustomizable = config_container[ZONE_0]->GetMarker_All_PyCustom(iMarker); + bool isInlet = (config_container[ZONE_0]->GetMarker_All_KindBC(iMarker) == INLET_FLOW); + + if (isCustomizable && isInlet) { + tags.push_back(config_container[ZONE_0]->GetMarker_All_TagBound(iMarker)); } - + } + + return tags; +} + +void CDriver::SetHeatSource_Position(passivedouble alpha, passivedouble pos_x, passivedouble pos_y, + passivedouble pos_z) { + CSolver* solver = solver_container[ZONE_0][INST_0][MESH_0][RAD_SOL]; + + config_container[ZONE_0]->SetHeatSource_Rot_Z(alpha); + config_container[ZONE_0]->SetHeatSource_Center(pos_x, pos_y, pos_z); + + solver->SetVolumetricHeatSource(geometry_container[ZONE_0][INST_0][MESH_0], config_container[ZONE_0]); +} + +void CDriver::SetInlet_Angle(unsigned short iMarker, passivedouble alpha) { + su2double alpha_rad = alpha * PI_NUMBER / 180.0; + + unsigned long iVertex; + + for (iVertex = 0; iVertex < geometry_container[ZONE_0][INST_0][MESH_0]->nVertex[iMarker]; iVertex++) { + solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]->SetInlet_FlowDir(iMarker, iVertex, 0, cos(alpha_rad)); + solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]->SetInlet_FlowDir(iMarker, iVertex, 1, sin(alpha_rad)); + } } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/* Functions related to simulation control, high level functions (reset convergence, set initial mesh, ecc...) */ +/* Functions related to simulation control, high level functions (reset convergence, set initial mesh, etc.) */ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// void CDriver::ResetConvergence() { - - for(iZone = 0; iZone < nZone; iZone++) { - switch (config_container[iZone]->GetKind_Solver()) { - - case MAIN_SOLVER::EULER: case MAIN_SOLVER::NAVIER_STOKES: case MAIN_SOLVER::RANS: - case MAIN_SOLVER::INC_EULER: case MAIN_SOLVER::INC_NAVIER_STOKES: case MAIN_SOLVER::INC_RANS: - case MAIN_SOLVER::NEMO_EULER: case MAIN_SOLVER::NEMO_NAVIER_STOKES: - integration_container[iZone][INST_0][FLOW_SOL]->SetConvergence(false); - if (config_container[iZone]->GetKind_Solver() == MAIN_SOLVER::RANS) integration_container[iZone][INST_0][TURB_SOL]->SetConvergence(false); - if(config_container[iZone]->GetKind_Trans_Model() == TURB_TRANS_MODEL::LM) integration_container[iZone][INST_0][TRANS_SOL]->SetConvergence(false); - break; - - case MAIN_SOLVER::FEM_ELASTICITY: - integration_container[iZone][INST_0][FEA_SOL]->SetConvergence(false); - break; - - case MAIN_SOLVER::ADJ_EULER: case MAIN_SOLVER::ADJ_NAVIER_STOKES: case MAIN_SOLVER::ADJ_RANS: case MAIN_SOLVER::DISC_ADJ_EULER: case MAIN_SOLVER::DISC_ADJ_NAVIER_STOKES: case MAIN_SOLVER::DISC_ADJ_RANS: - case MAIN_SOLVER::DISC_ADJ_INC_EULER: case MAIN_SOLVER::DISC_ADJ_INC_NAVIER_STOKES: case MAIN_SOLVER::DISC_ADJ_INC_RANS: - integration_container[iZone][INST_0][ADJFLOW_SOL]->SetConvergence(false); - if( (config_container[iZone]->GetKind_Solver() == MAIN_SOLVER::ADJ_RANS) || (config_container[iZone]->GetKind_Solver() == MAIN_SOLVER::DISC_ADJ_RANS) ) - integration_container[iZone][INST_0][ADJTURB_SOL]->SetConvergence(false); - break; - - default: - break; - } + for (auto iZone = 0u; iZone < nZone; iZone++) { + switch (main_config->GetKind_Solver()) { + case MAIN_SOLVER::EULER: + case MAIN_SOLVER::NAVIER_STOKES: + case MAIN_SOLVER::RANS: + case MAIN_SOLVER::INC_EULER: + case MAIN_SOLVER::INC_NAVIER_STOKES: + case MAIN_SOLVER::INC_RANS: + case MAIN_SOLVER::NEMO_EULER: + case MAIN_SOLVER::NEMO_NAVIER_STOKES: + integration_container[iZone][INST_0][FLOW_SOL]->SetConvergence(false); + if (config_container[iZone]->GetKind_Solver() == MAIN_SOLVER::RANS) + integration_container[iZone][INST_0][TURB_SOL]->SetConvergence(false); + if (config_container[iZone]->GetKind_Trans_Model() == TURB_TRANS_MODEL::LM) + integration_container[iZone][INST_0][TRANS_SOL]->SetConvergence(false); + break; + + case MAIN_SOLVER::FEM_ELASTICITY: + integration_container[iZone][INST_0][FEA_SOL]->SetConvergence(false); + break; + + case MAIN_SOLVER::ADJ_EULER: + case MAIN_SOLVER::ADJ_NAVIER_STOKES: + case MAIN_SOLVER::ADJ_RANS: + case MAIN_SOLVER::DISC_ADJ_EULER: + case MAIN_SOLVER::DISC_ADJ_NAVIER_STOKES: + case MAIN_SOLVER::DISC_ADJ_RANS: + case MAIN_SOLVER::DISC_ADJ_INC_EULER: + case MAIN_SOLVER::DISC_ADJ_INC_NAVIER_STOKES: + case MAIN_SOLVER::DISC_ADJ_INC_RANS: + integration_container[iZone][INST_0][ADJFLOW_SOL]->SetConvergence(false); + if ((config_container[iZone]->GetKind_Solver() == MAIN_SOLVER::ADJ_RANS) || + (config_container[iZone]->GetKind_Solver() == MAIN_SOLVER::DISC_ADJ_RANS)) + integration_container[iZone][INST_0][ADJTURB_SOL]->SetConvergence(false); + break; + + default: + break; } - + } } void CSinglezoneDriver::SetInitialMesh() { - - DynamicMeshUpdate(0); - - SU2_OMP_PARALLEL { - // Overwrite fictious velocities - for (iMesh = 0u; iMesh <= config_container[ZONE_0]->GetnMGLevels(); iMesh++) { - SU2_OMP_FOR_STAT(roundUpDiv(geometry_container[ZONE_0][INST_0][iMesh]->GetnPoint(),omp_get_max_threads())) - for (unsigned long iPoint = 0; iPoint < geometry_container[ZONE_0][INST_0][iMesh]->GetnPoint(); iPoint++) { - - /*--- Overwrite fictitious velocities ---*/ - su2double Grid_Vel[3] = {0.0, 0.0, 0.0}; - - /*--- Set the grid velocity for this coarse node. ---*/ - geometry_container[ZONE_0][INST_0][iMesh]->nodes->SetGridVel(iPoint, Grid_Vel); - } - END_SU2_OMP_FOR - /*--- Push back the volume. ---*/ - geometry_container[ZONE_0][INST_0][iMesh]->nodes->SetVolume_n(); - geometry_container[ZONE_0][INST_0][iMesh]->nodes->SetVolume_nM1(); - } - /*--- Push back the solution so that there is no fictious velocity at the next step. ---*/ - solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->Set_Solution_time_n(); - solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->Set_Solution_time_n1(); - } - END_SU2_OMP_PARALLEL -} - -void CDriver::BoundaryConditionsUpdate(){ - - int rank = MASTER_NODE; - unsigned short iZone; - - SU2_MPI::Comm_rank(SU2_MPI::GetComm(), &rank); - - if(rank == MASTER_NODE) cout << "Updating boundary conditions." << endl; - for(iZone = 0; iZone < nZone; iZone++){ - geometry_container[iZone][INST_0][MESH_0]->UpdateCustomBoundaryConditions(geometry_container[iZone][INST_0], config_container[iZone]); + DynamicMeshUpdate(0); + + SU2_OMP_PARALLEL { + for (iMesh = 0u; iMesh <= main_config->GetnMGLevels(); iMesh++) { + SU2_OMP_FOR_STAT(roundUpDiv(geometry_container[ZONE_0][INST_0][iMesh]->GetnPoint(), omp_get_max_threads())) + for (auto iPoint = 0ul; iPoint < geometry_container[ZONE_0][INST_0][iMesh]->GetnPoint(); iPoint++) { + /*--- Overwrite fictitious velocities. ---*/ + su2double Grid_Vel[3] = {0.0, 0.0, 0.0}; + + /*--- Set the grid velocity for this coarse node. ---*/ + geometry_container[ZONE_0][INST_0][iMesh]->nodes->SetGridVel(iPoint, Grid_Vel); + } + END_SU2_OMP_FOR + /*--- Push back the volume. ---*/ + geometry_container[ZONE_0][INST_0][iMesh]->nodes->SetVolume_n(); + geometry_container[ZONE_0][INST_0][iMesh]->nodes->SetVolume_nM1(); } + /*--- Push back the solution so that there is no fictitious velocity at the next step. ---*/ + solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->Set_Solution_time_n(); + solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->Set_Solution_time_n1(); + } + END_SU2_OMP_PARALLEL +} + +void CDriver::BoundaryConditionsUpdate() { + int rank = MASTER_NODE; + + SU2_MPI::Comm_rank(SU2_MPI::GetComm(), &rank); + + if (rank == MASTER_NODE) cout << "Updating boundary conditions." << endl; + for (auto iZone = 0u; iZone < nZone; iZone++) { + geometry_container[iZone][INST_0][MESH_0]->UpdateCustomBoundaryConditions(geometry_container[iZone][INST_0],config_container[iZone]); + } } //////////////////////////////////////////////////////////////////////////////// /* Functions related to finite elements */ //////////////////////////////////////////////////////////////////////////////// -void CDriver::SetFEA_Loads(unsigned short iMarker, unsigned long iVertex, passivedouble LoadX, - passivedouble LoadY, passivedouble LoadZ) { - - unsigned long iPoint; - su2double NodalForce[3] = {0.0,0.0,0.0}; - NodalForce[0] = LoadX; - NodalForce[1] = LoadY; - NodalForce[2] = LoadZ; - - iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); - solver_container[ZONE_0][INST_0][MESH_0][FEA_SOL]->GetNodes()->Set_FlowTraction(iPoint,NodalForce); - +void CDriver::SetFEA_Loads(unsigned short iMarker, unsigned long iVertex, passivedouble LoadX, passivedouble LoadY, + passivedouble LoadZ) { + unsigned long iPoint; + su2double NodalForce[3] = {0.0, 0.0, 0.0}; + NodalForce[0] = LoadX; + NodalForce[1] = LoadY; + NodalForce[2] = LoadZ; + + iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); + solver_container[ZONE_0][INST_0][MESH_0][FEA_SOL]->GetNodes()->Set_FlowTraction(iPoint, NodalForce); } vector CDriver::GetFEA_Displacements(unsigned short iMarker, unsigned long iVertex) const { - - unsigned long iPoint; - vector Displacements(3, 0.0); - vector Displacements_passive(3, 0.0); - - iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); - CSolver *solver = solver_container[ZONE_0][INST_0][MESH_0][FEA_SOL]; - CGeometry *geometry = geometry_container[ZONE_0][INST_0][MESH_0]; - - Displacements[0] = solver->GetNodes()->GetSolution(iPoint, 0); - Displacements[1] = solver->GetNodes()->GetSolution(iPoint, 1); + unsigned long iPoint; + vector Displacements(3, 0.0); + vector Displacements_passive(3, 0.0); + + iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); + CSolver* solver = solver_container[ZONE_0][INST_0][MESH_0][FEA_SOL]; + CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; + + Displacements[0] = solver->GetNodes()->GetSolution(iPoint, 0); + Displacements[1] = solver->GetNodes()->GetSolution(iPoint, 1); + if (geometry->GetnDim() == 3) + Displacements[2] = solver->GetNodes()->GetSolution(iPoint, 2); + else + Displacements[2] = 0.0; + + Displacements_passive[0] = SU2_TYPE::GetValue(Displacements[0]); + Displacements_passive[1] = SU2_TYPE::GetValue(Displacements[1]); + Displacements_passive[2] = SU2_TYPE::GetValue(Displacements[2]); + + return Displacements_passive; +} + +vector CDriver::GetFEA_Velocity(unsigned short iMarker, unsigned long iVertex) const { + unsigned long iPoint; + vector Velocity(3, 0.0); + vector Velocity_passive(3, 0.0); + + iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); + CSolver* solver = solver_container[ZONE_0][INST_0][MESH_0][FEA_SOL]; + CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; + + if (config_container[ZONE_0]->GetDynamic_Analysis() == DYNAMIC) { + Velocity[0] = solver->GetNodes()->GetSolution_Vel(iPoint, 0); + Velocity[1] = solver->GetNodes()->GetSolution_Vel(iPoint, 1); if (geometry->GetnDim() == 3) - Displacements[2] = solver->GetNodes()->GetSolution(iPoint, 2); + Velocity[2] = solver->GetNodes()->GetSolution_Vel(iPoint, 2); else - Displacements[2] = 0.0; - - Displacements_passive[0] = SU2_TYPE::GetValue(Displacements[0]); - Displacements_passive[1] = SU2_TYPE::GetValue(Displacements[1]); - Displacements_passive[2] = SU2_TYPE::GetValue(Displacements[2]); - - return Displacements_passive; -} + Velocity[2] = 0.0; + } + Velocity_passive[0] = SU2_TYPE::GetValue(Velocity[0]); + Velocity_passive[1] = SU2_TYPE::GetValue(Velocity[1]); + Velocity_passive[2] = SU2_TYPE::GetValue(Velocity[2]); -vector CDriver::GetFEA_Velocity(unsigned short iMarker, unsigned long iVertex) const { - - unsigned long iPoint; - vector Velocity(3, 0.0); - vector Velocity_passive(3,0.0); - - iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); - CSolver *solver = solver_container[ZONE_0][INST_0][MESH_0][FEA_SOL]; - CGeometry *geometry = geometry_container[ZONE_0][INST_0][MESH_0]; - - if (config_container[ZONE_0]->GetDynamic_Analysis() == DYNAMIC){ - Velocity[0] = solver->GetNodes()->GetSolution_Vel(iPoint, 0); - Velocity[1] = solver->GetNodes()->GetSolution_Vel(iPoint, 1); - if (geometry->GetnDim() == 3) - Velocity[2] = solver->GetNodes()->GetSolution_Vel(iPoint, 2); - else - Velocity[2] = 0.0; - } - - Velocity_passive[0] = SU2_TYPE::GetValue(Velocity[0]); - Velocity_passive[1] = SU2_TYPE::GetValue(Velocity[1]); - Velocity_passive[2] = SU2_TYPE::GetValue(Velocity[2]); - - return Velocity_passive; + return Velocity_passive; } vector CDriver::GetFEA_Velocity_n(unsigned short iMarker, unsigned long iVertex) const { - - unsigned long iPoint; - vector Velocity_n(3, 0.0); - vector Velocity_n_passive(3, 0.0); - - iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); - CSolver *solver = solver_container[ZONE_0][INST_0][MESH_0][FEA_SOL]; - CGeometry *geometry = geometry_container[ZONE_0][INST_0][MESH_0]; - - if (config_container[ZONE_0]->GetDynamic_Analysis() == DYNAMIC){ - Velocity_n[0] = solver->GetNodes()->GetSolution_Vel_time_n(iPoint, 0); - Velocity_n[1] = solver->GetNodes()->GetSolution_Vel_time_n(iPoint, 1); - if (geometry->GetnDim() == 3) - Velocity_n[2] = solver->GetNodes()->GetSolution_Vel_time_n(iPoint, 2); - else - Velocity_n[2] = 0.0; - } - - Velocity_n_passive[0] = SU2_TYPE::GetValue(Velocity_n[0]); - Velocity_n_passive[1] = SU2_TYPE::GetValue(Velocity_n[1]); - Velocity_n_passive[2] = SU2_TYPE::GetValue(Velocity_n[2]); - - return Velocity_n_passive; - + unsigned long iPoint; + vector Velocity_n(3, 0.0); + vector Velocity_n_passive(3, 0.0); + + iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); + CSolver* solver = solver_container[ZONE_0][INST_0][MESH_0][FEA_SOL]; + CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; + + if (config_container[ZONE_0]->GetDynamic_Analysis() == DYNAMIC) { + Velocity_n[0] = solver->GetNodes()->GetSolution_Vel_time_n(iPoint, 0); + Velocity_n[1] = solver->GetNodes()->GetSolution_Vel_time_n(iPoint, 1); + if (geometry->GetnDim() == 3) + Velocity_n[2] = solver->GetNodes()->GetSolution_Vel_time_n(iPoint, 2); + else + Velocity_n[2] = 0.0; + } + + Velocity_n_passive[0] = SU2_TYPE::GetValue(Velocity_n[0]); + Velocity_n_passive[1] = SU2_TYPE::GetValue(Velocity_n[1]); + Velocity_n_passive[2] = SU2_TYPE::GetValue(Velocity_n[2]); + + return Velocity_n_passive; } //////////////////////////////////////////////////////////////////////////////// @@ -558,123 +523,108 @@ vector CDriver::GetFEA_Velocity_n(unsigned short iMarker, unsigne //////////////////////////////////////////////////////////////////////////////// vector CDriver::GetMeshDisp_Sensitivity(unsigned short iMarker, unsigned long iVertex) const { - - unsigned long iPoint; - vector Disp_Sens(3, 0.0); - vector Disp_Sens_passive(3, 0.0); - - iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); - CSolver *solver = solver_container[ZONE_0][INST_0][MESH_0][ADJMESH_SOL]; - CGeometry *geometry = geometry_container[ZONE_0][INST_0][MESH_0]; - - Disp_Sens[0] = solver->GetNodes()->GetBoundDisp_Sens(iPoint, 0); - Disp_Sens[1] = solver->GetNodes()->GetBoundDisp_Sens(iPoint, 1); - if (geometry->GetnDim() == 3) - Disp_Sens[2] = solver->GetNodes()->GetBoundDisp_Sens(iPoint, 2); - else - Disp_Sens[2] = 0.0; - - Disp_Sens_passive[0] = SU2_TYPE::GetValue(Disp_Sens[0]); - Disp_Sens_passive[1] = SU2_TYPE::GetValue(Disp_Sens[1]); - Disp_Sens_passive[2] = SU2_TYPE::GetValue(Disp_Sens[2]); - - return Disp_Sens_passive; - + unsigned long iPoint; + vector Disp_Sens(3, 0.0); + vector Disp_Sens_passive(3, 0.0); + + iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); + CSolver* solver = solver_container[ZONE_0][INST_0][MESH_0][ADJMESH_SOL]; + CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; + + Disp_Sens[0] = solver->GetNodes()->GetBoundDisp_Sens(iPoint, 0); + Disp_Sens[1] = solver->GetNodes()->GetBoundDisp_Sens(iPoint, 1); + if (geometry->GetnDim() == 3) + Disp_Sens[2] = solver->GetNodes()->GetBoundDisp_Sens(iPoint, 2); + else + Disp_Sens[2] = 0.0; + + Disp_Sens_passive[0] = SU2_TYPE::GetValue(Disp_Sens[0]); + Disp_Sens_passive[1] = SU2_TYPE::GetValue(Disp_Sens[1]); + Disp_Sens_passive[2] = SU2_TYPE::GetValue(Disp_Sens[2]); + + return Disp_Sens_passive; } vector CDriver::GetFlowLoad_Sensitivity(unsigned short iMarker, unsigned long iVertex) const { - - unsigned long iPoint; - vector FlowLoad_Sens(3, 0.0); - vector FlowLoad_Sens_passive(3, 0.0); - - iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); - CSolver *solver = solver_container[ZONE_0][INST_0][MESH_0][ADJFEA_SOL]; - CGeometry *geometry = geometry_container[ZONE_0][INST_0][MESH_0]; - - FlowLoad_Sens[0] = solver->GetNodes()->GetFlowTractionSensitivity(iPoint, 0); - FlowLoad_Sens[1] = solver->GetNodes()->GetFlowTractionSensitivity(iPoint, 1); - if (geometry->GetnDim() == 3) - FlowLoad_Sens[2] = solver->GetNodes()->GetFlowTractionSensitivity(iPoint, 2); - else - FlowLoad_Sens[2] = 0.0; - - FlowLoad_Sens_passive[0] = SU2_TYPE::GetValue(FlowLoad_Sens[0]); - FlowLoad_Sens_passive[1] = SU2_TYPE::GetValue(FlowLoad_Sens[1]); - FlowLoad_Sens_passive[2] = SU2_TYPE::GetValue(FlowLoad_Sens[2]); - - return FlowLoad_Sens_passive; - + unsigned long iPoint; + vector FlowLoad_Sens(3, 0.0); + vector FlowLoad_Sens_passive(3, 0.0); + + iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); + CSolver* solver = solver_container[ZONE_0][INST_0][MESH_0][ADJFEA_SOL]; + CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; + + FlowLoad_Sens[0] = solver->GetNodes()->GetFlowTractionSensitivity(iPoint, 0); + FlowLoad_Sens[1] = solver->GetNodes()->GetFlowTractionSensitivity(iPoint, 1); + if (geometry->GetnDim() == 3) + FlowLoad_Sens[2] = solver->GetNodes()->GetFlowTractionSensitivity(iPoint, 2); + else + FlowLoad_Sens[2] = 0.0; + + FlowLoad_Sens_passive[0] = SU2_TYPE::GetValue(FlowLoad_Sens[0]); + FlowLoad_Sens_passive[1] = SU2_TYPE::GetValue(FlowLoad_Sens[1]); + FlowLoad_Sens_passive[2] = SU2_TYPE::GetValue(FlowLoad_Sens[2]); + + return FlowLoad_Sens_passive; } void CDriver::SetFlowLoad_Adjoint(unsigned short iMarker, unsigned long iVertex, passivedouble val_AdjointX, passivedouble val_AdjointY, passivedouble val_AdjointZ) { - - CSolver *solver = solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]; - CGeometry *geometry = geometry_container[ZONE_0][INST_0][MESH_0]; - - solver->StoreVertexTractionsAdjoint(iMarker, iVertex, 0, val_AdjointX); - solver->StoreVertexTractionsAdjoint(iMarker, iVertex, 1, val_AdjointY); - if (geometry->GetnDim() == 3) - solver->StoreVertexTractionsAdjoint(iMarker, iVertex, 2, val_AdjointZ); - + CSolver* solver = solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]; + CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; + + solver->StoreVertexTractionsAdjoint(iMarker, iVertex, 0, val_AdjointX); + solver->StoreVertexTractionsAdjoint(iMarker, iVertex, 1, val_AdjointY); + if (geometry->GetnDim() == 3) solver->StoreVertexTractionsAdjoint(iMarker, iVertex, 2, val_AdjointZ); } void CDriver::SetSourceTerm_DispAdjoint(unsigned short iMarker, unsigned long iVertex, passivedouble val_AdjointX, passivedouble val_AdjointY, passivedouble val_AdjointZ) { - - unsigned long iPoint; - - CSolver *solver = solver_container[ZONE_0][INST_0][MESH_0][ADJFEA_SOL]; - CGeometry *geometry = geometry_container[ZONE_0][INST_0][MESH_0]; - iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); - - solver->GetNodes()->SetSourceTerm_DispAdjoint(iPoint, 0, val_AdjointX); - solver->GetNodes()->SetSourceTerm_DispAdjoint(iPoint, 1, val_AdjointY); - if (geometry->GetnDim() == 3) - solver->GetNodes()->SetSourceTerm_DispAdjoint(iPoint, 2, val_AdjointZ); - + unsigned long iPoint; + + CSolver* solver = solver_container[ZONE_0][INST_0][MESH_0][ADJFEA_SOL]; + CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; + iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); + + solver->GetNodes()->SetSourceTerm_DispAdjoint(iPoint, 0, val_AdjointX); + solver->GetNodes()->SetSourceTerm_DispAdjoint(iPoint, 1, val_AdjointY); + if (geometry->GetnDim() == 3) solver->GetNodes()->SetSourceTerm_DispAdjoint(iPoint, 2, val_AdjointZ); } void CDriver::SetSourceTerm_VelAdjoint(unsigned short iMarker, unsigned long iVertex, passivedouble val_AdjointX, passivedouble val_AdjointY, passivedouble val_AdjointZ) { - - CSolver *solver = solver_container[ZONE_0][INST_0][MESH_0][ADJFEA_SOL]; - CGeometry *geometry = geometry_container[ZONE_0][INST_0][MESH_0]; - const auto iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); - - solver->GetNodes()->SetSourceTerm_VelAdjoint(iPoint, 0, val_AdjointX); - solver->GetNodes()->SetSourceTerm_VelAdjoint(iPoint, 1, val_AdjointY); - if (geometry->GetnDim() == 3) - solver->GetNodes()->SetSourceTerm_VelAdjoint(iPoint, 2, val_AdjointZ); - + CSolver* solver = solver_container[ZONE_0][INST_0][MESH_0][ADJFEA_SOL]; + CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; + const auto iPoint = geometry_container[ZONE_0][INST_0][MESH_0]->vertex[iMarker][iVertex]->GetNode(); + + solver->GetNodes()->SetSourceTerm_VelAdjoint(iPoint, 0, val_AdjointX); + solver->GetNodes()->SetSourceTerm_VelAdjoint(iPoint, 1, val_AdjointY); + if (geometry->GetnDim() == 3) solver->GetNodes()->SetSourceTerm_VelAdjoint(iPoint, 2, val_AdjointZ); } //////////////////////////////////////////////////////////////////////////////// -/* Functions related to flow loads */ +/* Functions related to flow loads */ //////////////////////////////////////////////////////////////////////////////// vector CDriver::GetFlowLoad(unsigned short iMarker, unsigned long iVertex) const { - - vector FlowLoad(3, 0.0); - vector FlowLoad_passive(3, 0.0); - - CSolver *solver = solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]; - CGeometry *geometry = geometry_container[ZONE_0][INST_0][MESH_0]; - - if (config_container[ZONE_0]->GetSolid_Wall(iMarker)) { - FlowLoad[0] = solver->GetVertexTractions(iMarker, iVertex, 0); - FlowLoad[1] = solver->GetVertexTractions(iMarker, iVertex, 1); - if (geometry->GetnDim() == 3) - FlowLoad[2] = solver->GetVertexTractions(iMarker, iVertex, 2); - else - FlowLoad[2] = 0.0; - } - - FlowLoad_passive[0] = SU2_TYPE::GetValue(FlowLoad[0]); - FlowLoad_passive[1] = SU2_TYPE::GetValue(FlowLoad[1]); - FlowLoad_passive[2] = SU2_TYPE::GetValue(FlowLoad[2]); - - return FlowLoad_passive; - + vector FlowLoad(3, 0.0); + vector FlowLoad_passive(3, 0.0); + + CSolver* solver = solver_container[ZONE_0][INST_0][MESH_0][FLOW_SOL]; + CGeometry* geometry = geometry_container[ZONE_0][INST_0][MESH_0]; + + if (config_container[ZONE_0]->GetSolid_Wall(iMarker)) { + FlowLoad[0] = solver->GetVertexTractions(iMarker, iVertex, 0); + FlowLoad[1] = solver->GetVertexTractions(iMarker, iVertex, 1); + if (geometry->GetnDim() == 3) + FlowLoad[2] = solver->GetVertexTractions(iMarker, iVertex, 2); + else + FlowLoad[2] = 0.0; + } + + FlowLoad_passive[0] = SU2_TYPE::GetValue(FlowLoad[0]); + FlowLoad_passive[1] = SU2_TYPE::GetValue(FlowLoad[1]); + FlowLoad_passive[2] = SU2_TYPE::GetValue(FlowLoad[2]); + + return FlowLoad_passive; } From bf07e5b18fbfb0e2934f252eb205647d2f12b8e8 Mon Sep 17 00:00:00 2001 From: patelha57 Date: Wed, 28 Dec 2022 16:53:55 -0800 Subject: [PATCH 54/68] Update SU2 version number --- SU2_CFD/include/drivers/CDriverBase.hpp | 2 +- SU2_CFD/src/drivers/CDriverBase.cpp | 2 +- SU2_DEF/include/drivers/CDeformationDriver.hpp | 2 +- SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp | 2 +- SU2_DEF/src/drivers/CDeformationDriver.cpp | 2 +- SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp | 2 +- TestCases/nicf/coolprop/fluidModel.cfg | 2 +- TestCases/nicf/coolprop/transportModel.cfg | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/SU2_CFD/include/drivers/CDriverBase.hpp b/SU2_CFD/include/drivers/CDriverBase.hpp index cec1a78c58a..a2d138760ff 100644 --- a/SU2_CFD/include/drivers/CDriverBase.hpp +++ b/SU2_CFD/include/drivers/CDriverBase.hpp @@ -2,7 +2,7 @@ * \file CDriverBase.hpp * \brief Base class template for all drivers. * \author H. Patel, A. Gastaldi - * \version 7.4.0 "Blackbird" + * \version 7.5.0 "Blackbird" * * SU2 Project Website: https://su2code.github.io * diff --git a/SU2_CFD/src/drivers/CDriverBase.cpp b/SU2_CFD/src/drivers/CDriverBase.cpp index 4009c76fa26..fcac9907521 100644 --- a/SU2_CFD/src/drivers/CDriverBase.cpp +++ b/SU2_CFD/src/drivers/CDriverBase.cpp @@ -2,7 +2,7 @@ * \file CDriverBase.hpp * \brief Base class template for all drivers. * \author H. Patel, A. Gastaldi - * \version 7.4.0 "Blackbird" + * \version 7.5.0 "Blackbird" * * SU2 Project Website: https://su2code.github.io * diff --git a/SU2_DEF/include/drivers/CDeformationDriver.hpp b/SU2_DEF/include/drivers/CDeformationDriver.hpp index 62954de5b73..9e6fee12097 100644 --- a/SU2_DEF/include/drivers/CDeformationDriver.hpp +++ b/SU2_DEF/include/drivers/CDeformationDriver.hpp @@ -2,7 +2,7 @@ * \file CDeformationDriver.hpp * \brief Headers of the main subroutines for driving the mesh deformation. * \author A. Gastaldi, H. Patel - * \version 7.4.0 "Blackbird" + * \version 7.5.0 "Blackbird" * * SU2 Project Website: https://su2code.github.io * diff --git a/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp b/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp index d5b42b958e5..0760513ed05 100644 --- a/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp +++ b/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp @@ -2,7 +2,7 @@ * \file CDiscAdjDeformationDriver.cpp * \brief Headers of the main subroutines for driving the projection of sensitivities. * \author T. Economon, H. Kline, R. Sanchez, A. Gastaldi, H. Patel - * \version 7.4.0 "Blackbird" + * \version 7.5.0 "Blackbird" * * SU2 Project Website: https://su2code.github.io * diff --git a/SU2_DEF/src/drivers/CDeformationDriver.cpp b/SU2_DEF/src/drivers/CDeformationDriver.cpp index 6140f4526a9..99ed2dab30a 100644 --- a/SU2_DEF/src/drivers/CDeformationDriver.cpp +++ b/SU2_DEF/src/drivers/CDeformationDriver.cpp @@ -2,7 +2,7 @@ * \file CDeformationDriver.cpp * \brief Main subroutines for driving the mesh deformation. * \author A. Gastaldi, H. Patel - * \version 7.4.0 "Blackbird" + * \version 7.5.0 "Blackbird" * * SU2 Project Website: https://su2code.github.io * diff --git a/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp b/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp index 9e55a74c11a..0b01614eec5 100644 --- a/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp +++ b/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp @@ -2,7 +2,7 @@ * \file CDiscAdjDeformationDriver.cpp * \brief Main subroutines for driving the projection of sensitivities. * \author T. Economon, H. Kline, R. Sanchez, A. Gastaldi, H. Patel - * \version 7.4.0 "Blackbird" + * \version 7.5.0 "Blackbird" * * SU2 Project Website: https://su2code.github.io * diff --git a/TestCases/nicf/coolprop/fluidModel.cfg b/TestCases/nicf/coolprop/fluidModel.cfg index 6b2fb858bc6..44df7a39118 100644 --- a/TestCases/nicf/coolprop/fluidModel.cfg +++ b/TestCases/nicf/coolprop/fluidModel.cfg @@ -6,7 +6,7 @@ % Author: Peng Yan, Alberto Guardone % % Institution: Politecnico di Milano % % Date: 2022.10.8 % -% File Version 7.4.0 Blackbird % +% File Version 7.5.0 Blackbird % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/TestCases/nicf/coolprop/transportModel.cfg b/TestCases/nicf/coolprop/transportModel.cfg index b4b1d9c4906..491073a2734 100644 --- a/TestCases/nicf/coolprop/transportModel.cfg +++ b/TestCases/nicf/coolprop/transportModel.cfg @@ -6,7 +6,7 @@ % Author: Peng Yan, Alberto Guardone % % Institution: Politecnico di Milano % % Date: 2022.11.26 % -% File Version 7.4.0 Blackbird % +% File Version 7.5.0 Blackbird % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% From adecd156f32a2948832c6d962e56d494a0d0a052 Mon Sep 17 00:00:00 2001 From: patelha57 Date: Wed, 28 Dec 2022 18:27:25 -0800 Subject: [PATCH 55/68] Remove ENABLE_MAPS from header files --- SU2_DEF/include/SU2_DEF.hpp | 10 +++------- SU2_DEF/include/drivers/CDeformationDriver.hpp | 3 --- SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp | 3 --- SU2_DOT/include/SU2_DOT.hpp | 5 +---- 4 files changed, 4 insertions(+), 17 deletions(-) diff --git a/SU2_DEF/include/SU2_DEF.hpp b/SU2_DEF/include/SU2_DEF.hpp index a3aaada5218..c851b1d35d1 100644 --- a/SU2_DEF/include/SU2_DEF.hpp +++ b/SU2_DEF/include/SU2_DEF.hpp @@ -27,18 +27,14 @@ #pragma once -#include "../../Common/include/parallelization/mpi_structure.hpp" -#include "../../Common/include/parallelization/omp_structure.hpp" - -#define ENABLE_MAPS -#include "../../Common/include/CConfig.hpp" -#undef ENABLE_MAPS - #include #include #include #include +#include "../../Common/include/CConfig.hpp" +#include "../../Common/include/parallelization/mpi_structure.hpp" +#include "../../Common/include/parallelization/omp_structure.hpp" #include "drivers/CDeformationDriver.hpp" using namespace std; diff --git a/SU2_DEF/include/drivers/CDeformationDriver.hpp b/SU2_DEF/include/drivers/CDeformationDriver.hpp index 9e6fee12097..01eecee0df5 100644 --- a/SU2_DEF/include/drivers/CDeformationDriver.hpp +++ b/SU2_DEF/include/drivers/CDeformationDriver.hpp @@ -27,10 +27,7 @@ #pragma once -#define ENABLE_MAPS #include "../../../Common/include/CConfig.hpp" -#undef ENABLE_MAPS - #include "../../../Common/include/geometry/CGeometry.hpp" #include "../../../Common/include/grid_movement/CSurfaceMovement.hpp" #include "../../../Common/include/grid_movement/CVolumetricMovement.hpp" diff --git a/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp b/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp index 0760513ed05..998b89fbe1b 100644 --- a/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp +++ b/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp @@ -27,10 +27,7 @@ #pragma once -#define ENABLE_MAPS #include "../../../Common/include/CConfig.hpp" -#undef ENABLE_MAPS - #include "../../../Common/include/fem/fem_geometry_structure.hpp" #include "../../../Common/include/geometry/CGeometry.hpp" #include "../../../Common/include/grid_movement/CSurfaceMovement.hpp" diff --git a/SU2_DOT/include/SU2_DOT.hpp b/SU2_DOT/include/SU2_DOT.hpp index 8b918e52abd..77f39c7085e 100644 --- a/SU2_DOT/include/SU2_DOT.hpp +++ b/SU2_DOT/include/SU2_DOT.hpp @@ -27,15 +27,12 @@ #pragma once -#define ENABLE_MAPS -#include "../../Common/include/CConfig.hpp" -#undef ENABLE_MAPS - #include #include #include #include +#include "../../Common/include/CConfig.hpp" #include "../../Common/include/parallelization/mpi_structure.hpp" #include "../../Common/include/parallelization/omp_structure.hpp" #include "../../SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp" From 4353a260a68413ef1f3f2068120e5eb1768b1cbf Mon Sep 17 00:00:00 2001 From: patelha57 Date: Thu, 29 Dec 2022 18:44:14 -0800 Subject: [PATCH 56/68] Update function names in CDriverBase, fix variable designations --- SU2_CFD/include/drivers/CDriverBase.hpp | 203 ++++++++++++------------ SU2_CFD/src/drivers/CDriverBase.cpp | 150 ++++++++--------- 2 files changed, 180 insertions(+), 173 deletions(-) diff --git a/SU2_CFD/include/drivers/CDriverBase.hpp b/SU2_CFD/include/drivers/CDriverBase.hpp index a2d138760ff..6ff1781eb09 100644 --- a/SU2_CFD/include/drivers/CDriverBase.hpp +++ b/SU2_CFD/include/drivers/CDriverBase.hpp @@ -1,6 +1,6 @@ /*! * \file CDriverBase.hpp - * \brief Base class template for all drivers. + * \brief Base class for all drivers. * \author H. Patel, A. Gastaldi * \version 7.5.0 "Blackbird" * @@ -32,6 +32,13 @@ #include "../output/COutput.hpp" #include "../solvers/CSolver.hpp" +/*! + * \class CDriverBase + * \ingroup Drivers + * \brief Base class for all drivers. + * \author H. Patel, A. Gastaldi + */ + class CDriverBase { protected: int rank, /*!< \brief MPI Rank. */ @@ -177,147 +184,147 @@ class CDriverBase { unsigned long GetNumberMarkerElements(unsigned short iMarker) const; /*! - * \brief Get the global IDs of the mesh elements. - * \return Global element IDs. + * \brief Get the global indices of the mesh elements. + * \return Global element indices (nElem). */ - vector GetElementIDs() const; + vector GetElements() const; /*! - * \brief Get the global ID of a mesh element. + * \brief Get the global index of a mesh element. * \param[in] iElem - Mesh element index. - * \return Global element ID. + * \return Global element index. */ - unsigned long GetElementIDs(unsigned long iElem) const; + unsigned long GetElements(unsigned long iElem) const; /*! - * \brief Get the global IDs of the marker elements. + * \brief Get the global indices of the marker elements. * \param[in] iMarker - Marker index. - * \return Global element IDs. + * \return Global element indices (nElem). */ - vector GetMarkerElementIDs(unsigned short iMarker) const; + vector GetMarkerElements(unsigned short iMarker) const; /*! - * \brief Get the global IDs of a marker element. + * \brief Get the global index of a marker element. * \param[in] iMarker - Marker index. - * \param[in] iBound - Marker element index. - * \return Global element ID. + * \param[in] iElem - Marker element index. + * \return Global element index. */ - unsigned long GetMarkerElementIDs(unsigned short iMarker, unsigned long iBound) const; + unsigned long GetMarkerElements(unsigned short iMarker, unsigned long iElem) const; /*! - * \brief Get the table of vertex IDs belonging to the mesh elements. - * \return Element connectivities (nElem, nNode) + * \brief Get the global node indices of the mesh elements. + * \return Element global node indices (nElem, nNode). */ - vector> GetElementConnectivities() const; + vector> GetElementNodes() const; /*! - * \brief Get the row of vertex IDs belonging to a mesh element. + * \brief Get the global node indices of a mesh element. * \param[in] iElem - Mesh element index. - * \return Element connectivity (nNode) + * \return Element global node indices (nNode). */ - vector GetElementConnectivities(unsigned long iElem) const; + vector GetElementNodes(unsigned long iElem) const; /*! - * \brief Get the table of vertex IDs belonging to the marker elements. + * \brief Get the global node indices of the marker elements. * \param[in] iMarker - Marker index. - * \return Element connectivities (nBound, nNode). + * \return Element global node indices (nElem, nVertex). */ - vector> GetMarkerElementConnectivities(unsigned short iMarker) const; + vector> GetMarkerElementNodes(unsigned short iMarker) const; /*! - * \brief Get the row of vertex IDs belonging to a marker element. + * \brief Get the global node indices of a marker element. * \param[in] iMarker - Marker index. - * \param[in] iBound - Marker element index. - * \return Element connectivity (nNode). + * \param[in] iElem - Marker element index. + * \return Element global node indices (nVertex). */ - vector GetMarkerElementConnectivities(unsigned short iMarker, unsigned long iBound) const; + vector GetMarkerElementNodes(unsigned short iMarker, unsigned long iElem) const; /*! - * \brief Get the number of vertices in the mesh. - * \return Number of vertices. + * \brief Get the number of nodes in the mesh. + * \return Number of nodes. */ - unsigned long GetNumberVertices() const; + unsigned long GetNumberNodes() const; /*! - * \brief Get the number of vertices in the marker. + * \brief Get the number of nodes in the marker. * \param[in] iMarker - Marker index. - * \return Number of vertices. + * \return Number of nodes. */ - unsigned long GetNumberMarkerVertices(unsigned short iMarker) const; + unsigned long GetNumberMarkerNodes(unsigned short iMarker) const; /*! - * \brief Get the number of halo vertices in the mesh. - * \return Number of vertices. + * \brief Get the number of halo nodes in the mesh. + * \return Number of halo nodes. */ - unsigned long GetNumberHaloVertices() const; + unsigned long GetNumberHaloNodes() const; /*! - * \brief Get the number of halo vertices in the marker. + * \brief Get the number of halo nodes in the marker. * \param[in] iMarker - Marker index. - * \return Number of vertices. + * \return Number of halo nodes. */ - unsigned long GetNumberMarkerHaloVertices(unsigned short iMarker) const; + unsigned long GetNumberMarkerHaloNodes(unsigned short iMarker) const; /*! - * \brief Get the mesh vertex indices of the marker vertices. + * \brief Get the vertices of the marker. * \param[in] iMarker - Marker index. - * \return Mesh vertex indices. + * \return Marker vertices (nVertex). */ - vector GetMarkerVertexIndices(unsigned short iMarker) const; + vector GetMarkerVertices(unsigned short iMarker) const; /*! - * \brief Get the mesh vertex index of a marker vertex. + * \brief Get the vertex of a marker. * \param[in] iMarker - Marker index. * \param[in] iVertex - Marker vertex index. - * \return Mesh vertex index. + * \return Marker vertex. */ - unsigned long GetMarkerVertexIndices(unsigned short iMarker, unsigned long iVertex) const; + unsigned long GetMarkerVertices(unsigned short iMarker, unsigned long iVertex) const; /*! - * \brief Get the global IDs of the mesh vertices. - * \return Global vertex IDs. + * \brief Get the global node indices. + * \return Global node indices (nNode). */ - vector GetVertexIDs() const; + vector GetNodes() const; /*! - * \brief Get the global ID of a mesh vertex. - * \param[in] iPoint - Mesh vertex index. - * \return Global vertex ID. + * \brief Get the global node index. + * \param[in] iPoint - Mesh node index. + * \return Global node index. */ - unsigned long GetVertexIDs(unsigned long iPoint) const; + unsigned long GetNodes(unsigned long iPoint) const; /*! - * \brief Get the global IDs of the marker vertices. + * \brief Get the global node indices of the marker vertices. * \param[in] iMarker - Marker index. - * \return Global vertex IDs. + * \return Global node indices (nVertex). */ - vector GetMarkerVertexIDs(unsigned short iMarker) const; + vector GetMarkerNodes(unsigned short iMarker) const; /*! - * \brief Get the global ID of a marker vertex. + * \brief Get the global node index of a marker vertex. * \param[in] iMarker - Marker index. * \param[in] iVertex - Marker vertex index. - * \return Global vertex ID. + * \return Global node index. */ - unsigned long GetMarkerVertexIDs(unsigned short iMarker, unsigned long iVertex) const; + unsigned long GetMarkerNodes(unsigned short iMarker, unsigned long iVertex) const; /*! - * \brief Get the halo flags of the mesh vertices. - * \return Vertex domain flags. + * \brief Get the halo flags of the mesh nodes. + * \return Node domain flags (nNode). */ vector GetDomain() const; /*! - * \brief Get the halo flag of a mesh vertex. - * \param[in] iPoint - Mesh vertex index. - * \return Vertex domain flag. + * \brief Get the halo flag of a mesh node. + * \param[in] iPoint - Mesh node index. + * \return Node domain flag. */ bool GetDomain(unsigned long iPoint) const; /*! * \brief Get the halo flags of the marker vertices. * \param[in] iMarker - Marker index. - * \return Vertex domain flags. + * \return Domain flags (nVertex). */ vector GetMarkerDomain(unsigned short iMarker) const; @@ -325,27 +332,27 @@ class CDriverBase { * \brief Get the halo flag of a marker vertex. * \param[in] iMarker - Marker index. * \param[in] iVertex - Marker vertex index. - * \return Vertex domain flag. + * \return Domain flag. */ bool GetMarkerDomain(unsigned short iMarker, unsigned long iVertex) const; /*! - * \brief Get the initial (un-deformed) coordinates of the mesh vertices. - * \return Initial vertex coordinates (nPoint, nDim). + * \brief Get the initial (un-deformed) coordinates of the mesh nodes. + * \return Initial node coordinates (nNode, nDim). */ vector> GetInitialCoordinates() const; /*! - * \brief Get the initial (un-deformed) coordinates of a mesh vertex. - * \param[in] iPoint - Mesh vertex index. - * \return Initial vertex coordinates (nDim). + * \brief Get the initial (un-deformed) coordinates of a mesh node. + * \param[in] iPoint - Mesh node index. + * \return Initial node coordinates (nDim). */ vector GetInitialCoordinates(unsigned long iPoint) const; /*! * \brief Get the initial (un-deformed) coordinates of the marker vertices. * \param[in] iMarker - Marker index. - * \return Initial vertex coordinates (nVertex, nDim). + * \return Initial node coordinates (nVertex, nDim). */ vector> GetMarkerInitialCoordinates(unsigned short iMarker) const; @@ -353,27 +360,27 @@ class CDriverBase { * \brief Get the initial (un-deformed) coordinates of a marker vertex. * \param[in] iMarker - Marker index. * \param[in] iVertex - Marker vertex index. - * \return Initial vertex coordinates (nDim). + * \return Initial node coordinates (nDim). */ vector GetMarkerInitialCoordinates(unsigned short iMarker, unsigned long iVertex) const; /*! - * \brief Get the coordinates of the mesh vertices. - * \return Vertex coordinates (nPoint, nDim). + * \brief Get the coordinates of the mesh nodes. + * \return Node coordinates (nNode, nDim). */ vector> GetCoordinates() const; /*! - * \brief Get the coordinates of a mesh vertex. - * \param[in] iPoint - Mesh vertex index. - * \return Vertex coordinates (nDim). + * \brief Get the coordinates of a mesh node. + * \param[in] iPoint - Mesh node index. + * \return Node coordinates (nDim). */ vector GetCoordinates(unsigned long iPoint) const; /*! * \brief Get the coordinates of the marker vertices. * \param[in] iMarker - Marker index. - * \return Vertex coordinates (nVertex, nDim). + * \return Node coordinates (nVertex, nDim). */ vector> GetMarkerCoordinates(unsigned short iMarker) const; @@ -381,27 +388,27 @@ class CDriverBase { * \brief Get the coordinates of a marker vertex. * \param[in] iMarker - Marker index. * \param[in] iVertex - Marker vertex index. - * \return Vertex coordinates (nDim). + * \return Node coordinates (nDim). */ vector GetMarkerCoordinates(unsigned short iMarker, unsigned long iVertex) const; /*! - * \brief Set the coordinates of the mesh vertices. - * \param[in] values - Vertex coordinates (nPoint, nDim). + * \brief Set the coordinates of the mesh nodes. + * \param[in] values - Node coordinates (nNode, nDim). */ void SetCoordinates(vector> values); /*! - * \brief Set the coordinates of a mesh vertex. - * \param[in] iPoint - Mesh vertex index. - * \param[in] values - Vertex coordinates (nDim). + * \brief Set the coordinates of a mesh node. + * \param[in] iPoint - Mesh node index. + * \param[in] values - Node coordinates (nDim). */ void SetCoordinates(unsigned long iPoint, vector values); /*! * \brief Set the coordinates of the marker vertices. * \param[in] iMarker - Marker index. - * \param[in] values - Vertex coordinates (nVertex, nDim). + * \param[in] values - Node coordinates (nVertex, nDim). */ void SetMarkerCoordinates(unsigned short iMarker, vector> values); @@ -409,14 +416,14 @@ class CDriverBase { * \brief Set the coordinates of a marker vertex. * \param[in] iMarker - Marker index. * \param[in] iVertex - Marker vertex index. - * \param[in] values - Vertex coordinates (nDim). + * \param[in] values - Node coordinates (nDim). */ void SetMarkerCoordinates(unsigned short iMarker, unsigned long iVertex, vector values); /*! * \brief Get the displacements of the marker vertices. * \param[in] iMarker - Marker index. - * \return Vertex displacements (nVertex, nDim). + * \return Node displacements (nVertex, nDim). */ vector> GetMarkerDisplacements(unsigned short iMarker) const; @@ -424,14 +431,14 @@ class CDriverBase { * \brief Get the displacements of a marker vertex. * \param[in] iMarker - Marker index. * \param[in] iVertex - Marker vertex index. - * \return Vertex displacements (nDim). + * \return Node displacements (nDim). */ vector GetMarkerDisplacements(unsigned short iMarker, unsigned long iVertex) const; /*! * \brief Set the displacements of the marker vertices. * \param[in] iMarker - Marker index. - * \param[in] values - Vertex displacements (nVertex, nDim). + * \param[in] values - Node displacements (nVertex, nDim). */ void SetMarkerDisplacements(unsigned short iMarker, vector> values); @@ -439,14 +446,14 @@ class CDriverBase { * \brief Set the displacements of a marker vertex. * \param[in] iMarker - Marker index. * \param[in] iVertex - Marker vertex index. - * \param[in] values - Vertex displacements (nDim). + * \param[in] values - Node displacements (nDim). */ void SetMarkerDisplacements(unsigned short iMarker, unsigned long iVertex, vector values); /*! * \brief Get the velocities of the marker vertices. * \param[in] iMarker - Marker index. - * \return Vertex velocities (nVertex, nDim). + * \return Node velocities (nVertex, nDim). */ vector> GetMarkerVelocities(unsigned short iMarker) const; @@ -454,14 +461,14 @@ class CDriverBase { * \brief Get the velocities of a marker vertex. * \param[in] iMarker - Marker index. * \param[in] iVertex - Marker vertex index. - * \return Vertex velocities (nDim). + * \return Node velocities (nDim). */ vector GetMarkerVelocities(unsigned short iMarker, unsigned long iVertex) const; /*! * \brief Set the velocities of the marker vertices. * \param[in] iMarker - Marker index. - * \param[in] values - Vertex velocities (nVertex, nDim). + * \param[in] values - Node velocities (nVertex, nDim). */ void SetMarkerVelocities(unsigned short iMarker, vector> values); @@ -469,24 +476,24 @@ class CDriverBase { * \brief Set the velocities of a marker vertex. * \param[in] iMarker - Marker index. * \param[in] iVertex - Marker vertex index. - * \param[in] values - Vertex velocities (nDim). + * \param[in] values - Node velocities (nDim). */ void SetMarkerVelocities(unsigned short iMarker, unsigned long iVertex, vector values); /*! - * \brief Get the normal vectors at the marker vertices. + * \brief Get the normal vectors of the marker vertices. * \param[in] iMarker - Marker index. * \param[in] normalize - If true, the unit (i.e. normalized) normal vector is returned. - * \return Normal vector at the vertex (nVertex, nDim). + * \return Node normal vectors (nVertex, nDim). */ vector> GetMarkerVertexNormals(unsigned short iMarker, bool normalize = false) const; /*! - * \brief Get the normal vectors at a marker vertex. + * \brief Get the normal vector of a marker vertex. * \param[in] iMarker - Marker index. * \param[in] iVertex - Marker vertex index. * \param[in] normalize - If true, the unit (i.e. normalized) normal vector is returned. - * \return Normal vector at the vertex (nDim). + * \return Node normal vector (nDim). */ vector GetMarkerVertexNormals(unsigned short iMarker, unsigned long iVertex, bool normalize = false) const; diff --git a/SU2_CFD/src/drivers/CDriverBase.cpp b/SU2_CFD/src/drivers/CDriverBase.cpp index fcac9907521..726dabe44f9 100644 --- a/SU2_CFD/src/drivers/CDriverBase.cpp +++ b/SU2_CFD/src/drivers/CDriverBase.cpp @@ -194,19 +194,19 @@ unsigned long CDriverBase::GetNumberMarkerElements(unsigned short iMarker) const return main_geometry->GetnElem_Bound(iMarker); } -vector CDriverBase::GetElementIDs() const { +vector CDriverBase::GetElements() const { const auto nElem = GetNumberElements(); vector values; for (auto iElem = 0ul; iElem < nElem; iElem++) { - values.push_back(GetElementIDs(iElem)); + values.push_back(GetElements(iElem)); } return values; } -unsigned long CDriverBase::GetElementIDs(unsigned long iElem) const { +unsigned long CDriverBase::GetElements(unsigned long iElem) const { if (iElem >= GetNumberElements()) { SU2_MPI::Error("Element index exceeds size.", CURRENT_FUNCTION); } @@ -214,39 +214,39 @@ unsigned long CDriverBase::GetElementIDs(unsigned long iElem) const { return main_geometry->elem[iElem]->GetGlobalIndex(); } -vector CDriverBase::GetMarkerElementIDs(unsigned short iMarker) const { - const auto nBound = GetNumberMarkerElements(iMarker); +vector CDriverBase::GetMarkerElements(unsigned short iMarker) const { + const auto nElem = GetNumberMarkerElements(iMarker); vector values; - for (auto iBound = 0ul; iBound < nBound; iBound++) { - values.push_back(GetMarkerElementIDs(iMarker, iBound)); + for (auto iElem = 0ul; iElem < nElem; iElem++) { + values.push_back(GetMarkerElements(iMarker, iElem)); } return values; } -unsigned long CDriverBase::GetMarkerElementIDs(unsigned short iMarker, unsigned long iBound) const { - if (iBound >= GetNumberMarkerElements(iMarker)) { +unsigned long CDriverBase::GetMarkerElements(unsigned short iMarker, unsigned long iElem) const { + if (iElem >= GetNumberMarkerElements(iMarker)) { SU2_MPI::Error("Marker element index exceeds size.", CURRENT_FUNCTION); } - return main_geometry->bound[iMarker][iBound]->GetGlobalIndex(); + return main_geometry->bound[iMarker][iElem]->GetGlobalIndex(); } -vector> CDriverBase::GetElementConnectivities() const { +vector> CDriverBase::GetElementNodes() const { const auto nElem = GetNumberElements(); vector> values; for (auto iElem = 0ul; iElem < nElem; iElem++) { - values.push_back(GetElementConnectivities(iElem)); + values.push_back(GetElementNodes(iElem)); } return values; } -vector CDriverBase::GetElementConnectivities(unsigned long iElem) const { +vector CDriverBase::GetElementNodes(unsigned long iElem) const { if (iElem >= GetNumberElements()) { SU2_MPI::Error("Element index exceeds size.", CURRENT_FUNCTION); } @@ -264,29 +264,29 @@ vector CDriverBase::GetElementConnectivities(unsigned long iElem) return values; } -vector> CDriverBase::GetMarkerElementConnectivities(unsigned short iMarker) const { - const auto nBound = GetNumberMarkerElements(iMarker); +vector> CDriverBase::GetMarkerElementNodes(unsigned short iMarker) const { + const auto nElem = GetNumberMarkerElements(iMarker); vector> values; - for (auto iBound = 0ul; iBound < nBound; iBound++) { - values.push_back(GetMarkerElementConnectivities(iMarker, iBound)); + for (auto iElem = 0ul; iElem < nElem; iElem++) { + values.push_back(GetMarkerElementNodes(iMarker, iElem)); } return values; } -vector CDriverBase::GetMarkerElementConnectivities(unsigned short iMarker, unsigned long iBound) const { - if (iBound >= GetNumberMarkerElements(iMarker)) { +vector CDriverBase::GetMarkerElementNodes(unsigned short iMarker, unsigned long iElem) const { + if (iElem >= GetNumberMarkerElements(iMarker)) { SU2_MPI::Error("Marker element index exceeds size.", CURRENT_FUNCTION); } - unsigned short nNode = main_geometry->bound[iMarker][iBound]->GetnNodes(); + unsigned short nNode = main_geometry->bound[iMarker][iElem]->GetnNodes(); vector values; for (auto iNode = 0u; iNode < nNode; iNode++) { - unsigned long iPoint = main_geometry->bound[iMarker][iBound]->GetNode(iNode); + unsigned long iPoint = main_geometry->bound[iMarker][iElem]->GetNode(iNode); values.push_back(main_geometry->nodes->GetGlobalIndex(iPoint)); } @@ -294,9 +294,9 @@ vector CDriverBase::GetMarkerElementConnectivities(unsigned short return values; } -unsigned long CDriverBase::GetNumberVertices() const { return main_geometry->GetnPoint(); } +unsigned long CDriverBase::GetNumberNodes() const { return main_geometry->GetnPoint(); } -unsigned long CDriverBase::GetNumberMarkerVertices(unsigned short iMarker) const { +unsigned long CDriverBase::GetNumberMarkerNodes(unsigned short iMarker) const { if (iMarker >= GetNumberMarkers()) { SU2_MPI::Error("Marker index exceeds size.", CURRENT_FUNCTION); } @@ -304,8 +304,8 @@ unsigned long CDriverBase::GetNumberMarkerVertices(unsigned short iMarker) const return main_geometry->GetnVertex(iMarker); } -unsigned long CDriverBase::GetNumberHaloVertices() const { - const auto nPoint = GetNumberVertices(); +unsigned long CDriverBase::GetNumberHaloNodes() const { + const auto nPoint = GetNumberNodes(); unsigned long nHalo = 0; for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { @@ -317,12 +317,12 @@ unsigned long CDriverBase::GetNumberHaloVertices() const { return nHalo; } -unsigned long CDriverBase::GetNumberMarkerHaloVertices(unsigned short iMarker) const { - const auto nVertex = GetNumberMarkerVertices(iMarker); +unsigned long CDriverBase::GetNumberMarkerHaloNodes(unsigned short iMarker) const { + const auto nVertex = GetNumberMarkerNodes(iMarker); unsigned long nHalo = 0; for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - auto iPoint = GetMarkerVertexIndices(iMarker, iVertex); + auto iPoint = GetMarkerVertices(iMarker, iVertex); if (!(main_geometry->nodes->GetDomain(iPoint))) { nHalo += 1; @@ -332,66 +332,66 @@ unsigned long CDriverBase::GetNumberMarkerHaloVertices(unsigned short iMarker) c return nHalo; } -vector CDriverBase::GetMarkerVertexIndices(unsigned short iMarker) const { - const auto nVertex = GetNumberMarkerVertices(iMarker); +vector CDriverBase::GetMarkerVertices(unsigned short iMarker) const { + const auto nVertex = GetNumberMarkerNodes(iMarker); vector values; for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - values.push_back(GetMarkerVertexIndices(iMarker, iVertex)); + values.push_back(GetMarkerVertices(iMarker, iVertex)); } return values; } -unsigned long CDriverBase::GetMarkerVertexIndices(unsigned short iMarker, unsigned long iVertex) const { - if (iVertex >= GetNumberMarkerVertices(iMarker)) { +unsigned long CDriverBase::GetMarkerVertices(unsigned short iMarker, unsigned long iVertex) const { + if (iVertex >= GetNumberMarkerNodes(iMarker)) { SU2_MPI::Error("Vertex index exceeds marker size.", CURRENT_FUNCTION); } return geometry_container[MESH_0][INST_0][ZONE_0]->vertex[iMarker][iVertex]->GetNode(); } -vector CDriverBase::GetVertexIDs() const { - const auto nPoint = GetNumberVertices(); +vector CDriverBase::GetNodes() const { + const auto nPoint = GetNumberNodes(); vector values; for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { - values.push_back(GetVertexIDs(iPoint)); + values.push_back(GetNodes(iPoint)); } return values; } -unsigned long CDriverBase::GetVertexIDs(unsigned long iPoint) const { - if (iPoint >= GetNumberVertices()) { - SU2_MPI::Error("Vertex index exceeds mesh size.", CURRENT_FUNCTION); +unsigned long CDriverBase::GetNodes(unsigned long iPoint) const { + if (iPoint >= GetNumberNodes()) { + SU2_MPI::Error("Node index exceeds mesh size.", CURRENT_FUNCTION); } return main_geometry->nodes->GetGlobalIndex(iPoint); } -vector CDriverBase::GetMarkerVertexIDs(unsigned short iMarker) const { - const auto nVertex = GetNumberMarkerVertices(iMarker); +vector CDriverBase::GetMarkerNodes(unsigned short iMarker) const { + const auto nVertex = GetNumberMarkerNodes(iMarker); vector values; for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - values.push_back(GetMarkerVertexIDs(iMarker, iVertex)); + values.push_back(GetMarkerNodes(iMarker, iVertex)); } return values; } -unsigned long CDriverBase::GetMarkerVertexIDs(unsigned short iMarker, unsigned long iVertex) const { - auto iPoint = GetMarkerVertexIndices(iMarker, iVertex); +unsigned long CDriverBase::GetMarkerNodes(unsigned short iMarker, unsigned long iVertex) const { + auto iPoint = GetMarkerVertices(iMarker, iVertex); return main_geometry->nodes->GetGlobalIndex(iPoint); } vector CDriverBase::GetDomain() const { - const auto nPoint = GetNumberVertices(); + const auto nPoint = GetNumberNodes(); vector values; @@ -403,15 +403,15 @@ vector CDriverBase::GetDomain() const { } bool CDriverBase::GetDomain(unsigned long iPoint) const { - if (iPoint >= GetNumberVertices()) { - SU2_MPI::Error("Vertex index exceeds mesh size.", CURRENT_FUNCTION); + if (iPoint >= GetNumberNodes()) { + SU2_MPI::Error("Node index exceeds mesh size.", CURRENT_FUNCTION); } return main_geometry->nodes->GetDomain(iPoint); } vector CDriverBase::GetMarkerDomain(unsigned short iMarker) const { - const auto nVertex = GetNumberMarkerVertices(iMarker); + const auto nVertex = GetNumberMarkerNodes(iMarker); vector values; @@ -423,13 +423,13 @@ vector CDriverBase::GetMarkerDomain(unsigned short iMarker) const { } bool CDriverBase::GetMarkerDomain(unsigned short iMarker, unsigned long iVertex) const { - auto iPoint = GetMarkerVertexIndices(iMarker, iVertex); + auto iPoint = GetMarkerVertices(iMarker, iVertex); return main_geometry->nodes->GetDomain(iPoint); } vector> CDriverBase::GetInitialCoordinates() const { - const auto nPoint = GetNumberVertices(); + const auto nPoint = GetNumberNodes(); vector> values; @@ -441,8 +441,8 @@ vector> CDriverBase::GetInitialCoordinates() const { } vector CDriverBase::GetInitialCoordinates(unsigned long iPoint) const { - if (iPoint >= GetNumberVertices()) { - SU2_MPI::Error("Vertex index exceeds mesh size.", CURRENT_FUNCTION); + if (iPoint >= GetNumberNodes()) { + SU2_MPI::Error("Node index exceeds mesh size.", CURRENT_FUNCTION); } vector values(nDim, 0.0); @@ -461,7 +461,7 @@ vector CDriverBase::GetInitialCoordinates(unsigned long iPoint) c } vector> CDriverBase::GetMarkerInitialCoordinates(unsigned short iMarker) const { - const auto nVertex = GetNumberMarkerVertices(iMarker); + const auto nVertex = GetNumberMarkerNodes(iMarker); vector> values; @@ -473,7 +473,7 @@ vector> CDriverBase::GetMarkerInitialCoordinates(unsigned } vector CDriverBase::GetMarkerInitialCoordinates(unsigned short iMarker, unsigned long iVertex) const { - auto iPoint = GetMarkerVertexIndices(iMarker, iVertex); + auto iPoint = GetMarkerVertices(iMarker, iVertex); vector values(nDim, 0.0); @@ -491,7 +491,7 @@ vector CDriverBase::GetMarkerInitialCoordinates(unsigned short iM } vector> CDriverBase::GetCoordinates() const { - const auto nPoint = GetNumberVertices(); + const auto nPoint = GetNumberNodes(); vector> values; @@ -503,8 +503,8 @@ vector> CDriverBase::GetCoordinates() const { } vector CDriverBase::GetCoordinates(unsigned long iPoint) const { - if (iPoint >= GetNumberVertices()) { - SU2_MPI::Error("Vertex index exceeds mesh size.", CURRENT_FUNCTION); + if (iPoint >= GetNumberNodes()) { + SU2_MPI::Error("Node index exceeds mesh size.", CURRENT_FUNCTION); } vector values; @@ -519,7 +519,7 @@ vector CDriverBase::GetCoordinates(unsigned long iPoint) const { } vector> CDriverBase::GetMarkerCoordinates(unsigned short iMarker) const { - const auto nVertex = GetNumberMarkerVertices(iMarker); + const auto nVertex = GetNumberMarkerNodes(iMarker); vector> values; @@ -531,7 +531,7 @@ vector> CDriverBase::GetMarkerCoordinates(unsigned short i } vector CDriverBase::GetMarkerCoordinates(unsigned short iMarker, unsigned long iVertex) const { - auto iPoint = GetMarkerVertexIndices(iMarker, iVertex); + auto iPoint = GetMarkerVertices(iMarker, iVertex); vector values; @@ -545,10 +545,10 @@ vector CDriverBase::GetMarkerCoordinates(unsigned short iMarker, } void CDriverBase::SetCoordinates(vector> values) { - const auto nPoint = GetNumberVertices(); + const auto nPoint = GetNumberNodes(); if (values.size() != nPoint) { - SU2_MPI::Error("Invalid number of vertices!", CURRENT_FUNCTION); + SU2_MPI::Error("Invalid number of nodes!", CURRENT_FUNCTION); } for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { @@ -557,8 +557,8 @@ void CDriverBase::SetCoordinates(vector> values) { } void CDriverBase::SetCoordinates(unsigned long iPoint, vector values) { - if (iPoint >= GetNumberVertices()) { - SU2_MPI::Error("Vertex index exceeds mesh size.", CURRENT_FUNCTION); + if (iPoint >= GetNumberNodes()) { + SU2_MPI::Error("Node index exceeds mesh size.", CURRENT_FUNCTION); } if (values.size() != nDim) { SU2_MPI::Error("Invalid number of dimensions!", CURRENT_FUNCTION); @@ -570,7 +570,7 @@ void CDriverBase::SetCoordinates(unsigned long iPoint, vector val } void CDriverBase::SetMarkerCoordinates(unsigned short iMarker, vector> values) { - const auto nVertex = GetNumberMarkerVertices(iMarker); + const auto nVertex = GetNumberMarkerNodes(iMarker); if (values.size() != nVertex) { SU2_MPI::Error("Invalid number of marker vertices!", CURRENT_FUNCTION); @@ -582,7 +582,7 @@ void CDriverBase::SetMarkerCoordinates(unsigned short iMarker, vector values) { - auto iPoint = GetMarkerVertexIndices(iMarker, iVertex); + auto iPoint = GetMarkerVertices(iMarker, iVertex); if (values.size() != nDim) { SU2_MPI::Error("Invalid number of dimensions!", CURRENT_FUNCTION); @@ -594,7 +594,7 @@ void CDriverBase::SetMarkerCoordinates(unsigned short iMarker, unsigned long iVe } vector> CDriverBase::GetMarkerDisplacements(unsigned short iMarker) const { - const auto nVertex = GetNumberMarkerVertices(iMarker); + const auto nVertex = GetNumberMarkerNodes(iMarker); vector> values; @@ -606,7 +606,7 @@ vector> CDriverBase::GetMarkerDisplacements(unsigned short } vector CDriverBase::GetMarkerDisplacements(unsigned short iMarker, unsigned long iVertex) const { - auto iPoint = GetMarkerVertexIndices(iMarker, iVertex); + auto iPoint = GetMarkerVertices(iMarker, iVertex); vector values(nDim, 0.0); @@ -628,7 +628,7 @@ void CDriverBase::SetMarkerDisplacements(unsigned short iMarker, vector> CDriverBase::GetMarkerVelocities(unsigned short iMarker) const { - const auto nVertex = GetNumberMarkerVertices(iMarker); + const auto nVertex = GetNumberMarkerNodes(iMarker); vector> values; @@ -668,7 +668,7 @@ vector> CDriverBase::GetMarkerVelocities(unsigned short iM } vector CDriverBase::GetMarkerVelocities(unsigned short iMarker, unsigned long iVertex) const { - auto iPoint = GetMarkerVertexIndices(iMarker, iVertex); + auto iPoint = GetMarkerVertices(iMarker, iVertex); vector values(nDim, 0.0); @@ -690,7 +690,7 @@ void CDriverBase::SetMarkerVelocities(unsigned short iMarker, vector> CDriverBase::GetMarkerVertexNormals(unsigned short iMarker, bool normalize) const { - const auto nVertex = GetNumberMarkerVertices(iMarker); + const auto nVertex = GetNumberMarkerNodes(iMarker); vector> values; @@ -731,7 +731,7 @@ vector> CDriverBase::GetMarkerVertexNormals(unsigned short vector CDriverBase::GetMarkerVertexNormals(unsigned short iMarker, unsigned long iVertex, bool normalize) const { - if (iVertex >= GetNumberMarkerVertices(iMarker)) { + if (iVertex >= GetNumberMarkerNodes(iMarker)) { SU2_MPI::Error("Vertex index exceeds marker size.", CURRENT_FUNCTION); } From 0c61d0a2fe77119c3387fe663fb144f4902fa9dc Mon Sep 17 00:00:00 2001 From: patelha57 Date: Thu, 29 Dec 2022 21:55:34 -0800 Subject: [PATCH 57/68] Fix maps build error, fix pysu2 dependency --- SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp | 10 +--------- SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp | 11 ++++++++++- SU2_PY/pySU2/pySU2.i | 2 +- SU2_PY/pySU2/pySU2ad.i | 2 +- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp b/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp index 998b89fbe1b..534b0cddb16 100644 --- a/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp +++ b/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp @@ -27,18 +27,10 @@ #pragma once -#include "../../../Common/include/CConfig.hpp" #include "../../../Common/include/fem/fem_geometry_structure.hpp" -#include "../../../Common/include/geometry/CGeometry.hpp" -#include "../../../Common/include/grid_movement/CSurfaceMovement.hpp" -#include "../../../Common/include/grid_movement/CVolumetricMovement.hpp" #include "../../../Common/include/parallelization/mpi_structure.hpp" +#include "../../../Common/include/parallelization/omp_structure.hpp" #include "../../../SU2_CFD/include/drivers/CDriverBase.hpp" -#include "../../../SU2_CFD/include/numerics/CGradSmoothing.hpp" -#include "../../../SU2_CFD/include/output/CBaselineOutput.hpp" -#include "../../../SU2_CFD/include/output/COutput.hpp" -#include "../../../SU2_CFD/include/solvers/CBaselineSolver.hpp" -#include "../../../SU2_CFD/include/solvers/CGradientSmoothingSolver.hpp" class CDiscAdjDeformationDriver : public CDriverBase { protected: diff --git a/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp b/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp index 0b01614eec5..362c237e56a 100644 --- a/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp +++ b/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp @@ -25,9 +25,18 @@ * License along with SU2. If not, see . */ -#include "../../include/drivers/CDiscAdjDeformationDriver.hpp" +#define ENABLE_MAPS +#include "../../../Common/include/CConfig.hpp" +#undef ENABLE_MAPS #include "../../../Common/include/geometry/CPhysicalGeometry.hpp" +#include "../../../Common/include/grid_movement/CSurfaceMovement.hpp" +#include "../../../Common/include/grid_movement/CVolumetricMovement.hpp" +#include "../../../SU2_CFD/include/numerics/CGradSmoothing.hpp" +#include "../../../SU2_CFD/include/output/CBaselineOutput.hpp" +#include "../../../SU2_CFD/include/solvers/CBaselineSolver.hpp" +#include "../../../SU2_CFD/include/solvers/CGradientSmoothingSolver.hpp" +#include "../../include/drivers/CDiscAdjDeformationDriver.hpp" using namespace std; diff --git a/SU2_PY/pySU2/pySU2.i b/SU2_PY/pySU2/pySU2.i index 1d8c424cd28..7cf25ca6f09 100644 --- a/SU2_PY/pySU2/pySU2.i +++ b/SU2_PY/pySU2/pySU2.i @@ -92,8 +92,8 @@ const unsigned int MESH_1 = 1; /*!< \brief Definition of the finest grid level. const unsigned int ZONE_0 = 0; /*!< \brief Definition of the first grid domain. */ const unsigned int ZONE_1 = 1; /*!< \brief Definition of the first grid domain. */ -%include "../../SU2_CFD/include/drivers/CDriver.hpp" %include "../../SU2_CFD/include/drivers/CDriverBase.hpp" +%include "../../SU2_CFD/include/drivers/CDriver.hpp" %include "../../SU2_CFD/include/drivers/CSinglezoneDriver.hpp" %include "../../SU2_CFD/include/drivers/CMultizoneDriver.hpp" %include "../../SU2_CFD/include/drivers/CDiscAdjSinglezoneDriver.hpp" diff --git a/SU2_PY/pySU2/pySU2ad.i b/SU2_PY/pySU2/pySU2ad.i index 7b347f5cbe1..f8aec4044f3 100644 --- a/SU2_PY/pySU2/pySU2ad.i +++ b/SU2_PY/pySU2/pySU2ad.i @@ -91,8 +91,8 @@ const unsigned int MESH_1 = 1; /*!< \brief Definition of the finest grid level. const unsigned int ZONE_0 = 0; /*!< \brief Definition of the first grid domain. */ const unsigned int ZONE_1 = 1; /*!< \brief Definition of the first grid domain. */ -%include "../../SU2_CFD/include/drivers/CDriver.hpp" %include "../../SU2_CFD/include/drivers/CDriverBase.hpp" +%include "../../SU2_CFD/include/drivers/CDriver.hpp" %include "../../SU2_CFD/include/drivers/CSinglezoneDriver.hpp" %include "../../SU2_CFD/include/drivers/CMultizoneDriver.hpp" %include "../../SU2_CFD/include/drivers/CDiscAdjSinglezoneDriver.hpp" From a447ae3ae3447d69488d84b748b857a9dea9bf72 Mon Sep 17 00:00:00 2001 From: patelha57 Date: Fri, 30 Dec 2022 12:24:29 -0800 Subject: [PATCH 58/68] Update function names in FSIInterface.py and Python test cases --- SU2_PY/FSI_tools/FSIInterface.py | 12 ++++++------ .../disc_adj_flow/mesh_disp_sens/run_adjoint.py | 2 +- .../launch_flatPlate_rigidMotion.py | 4 ++-- .../launch_unsteady_CHT_FlatPlate.py | 4 ++-- TestCases/py_wrapper/translating_NACA0012/run_su2.py | 4 ++-- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/SU2_PY/FSI_tools/FSIInterface.py b/SU2_PY/FSI_tools/FSIInterface.py index 616628162a8..0ab227fde57 100644 --- a/SU2_PY/FSI_tools/FSIInterface.py +++ b/SU2_PY/FSI_tools/FSIInterface.py @@ -235,7 +235,7 @@ def connect(self, FSI_config, FluidSolver, SolidSolver): if allMovingMarkersTags[0] in allMarkersID.keys(): self.fluidInterfaceIdentifier = allMarkersID[allMovingMarkersTags[0]] if self.fluidInterfaceIdentifier is not None: - self.nLocalFluidInterfaceNodes = FluidSolver.GetNumberMarkerVertices(self.fluidInterfaceIdentifier) + self.nLocalFluidInterfaceNodes = FluidSolver.GetNumberMarkerNodes(self.fluidInterfaceIdentifier) if self.nLocalFluidInterfaceNodes != 0: self.haveFluidInterface = True print('Number of interface fluid nodes (halo nodes included) on proccess {} : {}'.format(myid,self.nLocalFluidInterfaceNodes)) @@ -301,7 +301,7 @@ def connect(self, FSI_config, FluidSolver, SolidSolver): self.nLocalFluidInterfaceHaloNode = 0 for iVertex in range(self.nLocalFluidInterfaceNodes): if not FluidSolver.GetMarkerDomain(self.fluidInterfaceIdentifier, iVertex): - GlobalIndex = FluidSolver.GetMarkerVertexIDs(self.fluidInterfaceIdentifier, iVertex) + GlobalIndex = FluidSolver.GetMarkerNodes(self.fluidInterfaceIdentifier, iVertex) self.FluidHaloNodeList[GlobalIndex] = iVertex self.nLocalFluidInterfaceHaloNode += 1 # Calculate the number of physical (= not halo) nodes on each partition @@ -565,7 +565,7 @@ def interfaceMapping(self,FluidSolver, SolidSolver, FSI_config): # Note that the fluid solver is separated in more processors outside the python script # thus when, from a core, we request for the vertices on the interface, we only obtain # those in that core - GlobalIndex = FluidSolver.GetMarkerVertexIDs(self.fluidInterfaceIdentifier, iVertex) + GlobalIndex = FluidSolver.GetMarkerNodes(self.fluidInterfaceIdentifier, iVertex) if self.nDim == 2: posx, posy = FluidSolver.GetMarkerInitialCoordinates(self.fluidInterfaceIdentifier, iVertex) posz = 0 @@ -1460,7 +1460,7 @@ def getFluidInterfaceNodalForce(self, FSI_config, FluidSolver): # --- Get the fluid interface loads from the fluid solver and directly fill the corresponding PETSc vector --- for iVertex in range(self.nLocalFluidInterfaceNodes): - GlobalIndex = FluidSolver.GetMarkerVertexIDs(self.fluidInterfaceIdentifier, iVertex) + GlobalIndex = FluidSolver.GetMarkerNodes(self.fluidInterfaceIdentifier, iVertex) if GlobalIndex not in self.FluidHaloNodeList[myid].keys(): loadX, loadY, loadZ = FluidSolver.GetFlowLoad(self.fluidInterfaceIdentifier, iVertex) iGlobalVertex = self.__getGlobalIndex('fluid', myid, localIndex) @@ -1490,7 +1490,7 @@ def setFluidInterfaceVarCoord(self, FluidSolver): # --- Send the new fluid interface position to the fluid solver (on each partition, halo nodes included) --- localIndex = 0 for iVertex in range(self.nLocalFluidInterfaceNodes): - GlobalIndex = FluidSolver.GetMarkerVertexIDs(self.fluidInterfaceIdentifier, iVertex) + GlobalIndex = FluidSolver.GetMarkerNodes(self.fluidInterfaceIdentifier, iVertex) if GlobalIndex in self.FluidHaloNodeList[myid].keys(): DispX, DispY, DispZ = self.haloNodesDisplacements[GlobalIndex] FluidSolver.SetMarkerDisplacements(self.fluidInterfaceIdentifier, int(iVertex), np.array([DispX, DispY, DispZ])) @@ -2151,7 +2151,7 @@ def MapModes(self, FSI_config, FluidSolver, SolidSolver): nz = 0 else: nx, ny, nz = FluidSolver.GetMarkerVertexNormals(self.fluidInterfaceIdentifier, iVertex, False) - GlobalIndex = FluidSolver.GetMarkerVertexIDs(self.fluidInterfaceIdentifier, iVertex) + GlobalIndex = FluidSolver.GetMarkerNodes(self.fluidInterfaceIdentifier, iVertex) nodeNormals[GlobalIndex] = [nx, ny, nz] nodeNormals = self.comm.gather(nodeNormals, root=self.rootProcess) diff --git a/TestCases/py_wrapper/disc_adj_flow/mesh_disp_sens/run_adjoint.py b/TestCases/py_wrapper/disc_adj_flow/mesh_disp_sens/run_adjoint.py index e098d06640b..905a43ddb56 100755 --- a/TestCases/py_wrapper/disc_adj_flow/mesh_disp_sens/run_adjoint.py +++ b/TestCases/py_wrapper/disc_adj_flow/mesh_disp_sens/run_adjoint.py @@ -80,7 +80,7 @@ def main(): nVertex_Marker = 0 #total number of vertices (physical + halo) if MarkerID != None: - nVertex_Marker = SU2Driver.GetNumberMarkerVertices(MarkerID) + nVertex_Marker = SU2Driver.GetNumberMarkerNodes(MarkerID) # Time loop is defined in Python so that we have acces to SU2 functionalities at each time step if rank == 0: diff --git a/TestCases/py_wrapper/flatPlate_rigidMotion/launch_flatPlate_rigidMotion.py b/TestCases/py_wrapper/flatPlate_rigidMotion/launch_flatPlate_rigidMotion.py index 88a8d2e3ece..85c9483fddd 100755 --- a/TestCases/py_wrapper/flatPlate_rigidMotion/launch_flatPlate_rigidMotion.py +++ b/TestCases/py_wrapper/flatPlate_rigidMotion/launch_flatPlate_rigidMotion.py @@ -91,8 +91,8 @@ def main(): nVertex_MovingMarker_PHYS = 0 #number of physical vertices if MovingMarkerID != None: - nVertex_MovingMarker = SU2Driver.GetNumberMarkerVertices(MovingMarkerID) - nVertex_MovingMarker_HALO = SU2Driver.GetNumberMarkerHaloVertices(MovingMarkerID) + nVertex_MovingMarker = SU2Driver.GetNumberMarkerNodes(MovingMarkerID) + nVertex_MovingMarker_HALO = SU2Driver.GetNumberMarkerHaloNodes(MovingMarkerID) nVertex_MovingMarker_PHYS = nVertex_MovingMarker - nVertex_MovingMarker_HALO # Retrieve some control parameters from the driver diff --git a/TestCases/py_wrapper/flatPlate_unsteady_CHT/launch_unsteady_CHT_FlatPlate.py b/TestCases/py_wrapper/flatPlate_unsteady_CHT/launch_unsteady_CHT_FlatPlate.py index 8e9b6ca9679..57aec6661fa 100755 --- a/TestCases/py_wrapper/flatPlate_unsteady_CHT/launch_unsteady_CHT_FlatPlate.py +++ b/TestCases/py_wrapper/flatPlate_unsteady_CHT/launch_unsteady_CHT_FlatPlate.py @@ -90,8 +90,8 @@ def main(): nVertex_CHTMarker_PHYS = 0 # number of physical vertices if CHTMarkerID != None: - nVertex_CHTMarker = SU2Driver.GetNumberMarkerVertices(CHTMarkerID) - nVertex_CHTMarker_HALO = SU2Driver.GetNumberMarkerHaloVertices(CHTMarkerID) + nVertex_CHTMarker = SU2Driver.GetNumberMarkerNodes(CHTMarkerID) + nVertex_CHTMarker_HALO = SU2Driver.GetNumberMarkerHaloNodes(CHTMarkerID) nVertex_CHTMarker_PHYS = nVertex_CHTMarker - nVertex_CHTMarker_HALO # Retrieve some control parameters from the driver diff --git a/TestCases/py_wrapper/translating_NACA0012/run_su2.py b/TestCases/py_wrapper/translating_NACA0012/run_su2.py index a4abfee0b6e..5cc7a679ab4 100644 --- a/TestCases/py_wrapper/translating_NACA0012/run_su2.py +++ b/TestCases/py_wrapper/translating_NACA0012/run_su2.py @@ -46,10 +46,10 @@ def save_forces(self): for marker in solver_all_moving_markers[has_moving_marker]: solver_marker_id = solver_marker_ids[marker] - n_vertices = self.FluidSolver.GetNumberMarkerVertices(solver_marker_id) + n_vertices = self.FluidSolver.GetNumberMarkerNodes(solver_marker_id) for i_vertex in range(n_vertices): fxyz = self.FluidSolver.GetFlowLoad(solver_marker_id, i_vertex) - GlobalIndex = self.FluidSolver.GetMarkerVertexIDs(solver_marker_id, i_vertex) + GlobalIndex = self.FluidSolver.GetMarkerNodes(solver_marker_id, i_vertex) f.write('{}, {:.2f}, {:.2f}, {:.2f}\n'.format(GlobalIndex, fxyz[0], fxyz[1], fxyz[2])) f.close() From 93b4ac00985172a4d8828fc3f1a662acea561b3b Mon Sep 17 00:00:00 2001 From: patelha57 Date: Fri, 30 Dec 2022 14:43:44 -0800 Subject: [PATCH 59/68] Fix segfault from accessing main_config and main_geometry --- SU2_CFD/src/drivers/CDriver.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/SU2_CFD/src/drivers/CDriver.cpp b/SU2_CFD/src/drivers/CDriver.cpp index c0a6c49f217..6d9321c8fdd 100644 --- a/SU2_CFD/src/drivers/CDriver.cpp +++ b/SU2_CFD/src/drivers/CDriver.cpp @@ -603,6 +603,10 @@ void CDriver::Input_Preprocessing(CConfig **&config, CConfig *&driver_config) { } } + /*--- Keep a reference to the main (ZONE 0) config. ---*/ + + main_config = config_container[ZONE_0]; + /*--- Determine whether or not the FEM solver is used, which decides the type of * geometry classes that are instantiated. Only adapted for single-zone problems ---*/ @@ -707,6 +711,9 @@ void CDriver::Geometrical_Preprocessing(CConfig* config, CGeometry **&geometry, } + /*--- Keep a reference to the main (ZONE_0, INST_0, MESH_0) geometry. ---*/ + + main_geometry = geometry_container[ZONE_0][INST_0][MESH_0]; } void CDriver::Geometrical_Preprocessing_FVM(CConfig *config, CGeometry **&geometry) { From bc9893cc44125bf61e25004d9e93075bd5294d8b Mon Sep 17 00:00:00 2001 From: patelha57 Date: Fri, 30 Dec 2022 15:40:03 -0800 Subject: [PATCH 60/68] Fix attribute error in translating NACA0012 pysu2 test case --- TestCases/py_wrapper/translating_NACA0012/run_su2.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/TestCases/py_wrapper/translating_NACA0012/run_su2.py b/TestCases/py_wrapper/translating_NACA0012/run_su2.py index 5cc7a679ab4..c8b114410ec 100644 --- a/TestCases/py_wrapper/translating_NACA0012/run_su2.py +++ b/TestCases/py_wrapper/translating_NACA0012/run_su2.py @@ -36,11 +36,12 @@ def run_solver(self): def save_forces(self): solver_all_moving_markers = np.array(self.FluidSolver.GetDeformableMarkerTags()) - solver_marker_ids = self.FluidSolver.GetMarkerTags() + solver_markers = self.FluidSolver.GetMarkerTags() + solver_marker_ids = self.FluidSolver.GetMarkerIndices() # The surface marker and the partitioning of the solver usually don't agree. # Thus, it is necessary to figure out if the partition of the current mpi process has # a node that belongs to a moving surface marker. - has_moving_marker = [marker in solver_marker_ids.keys() for marker in solver_all_moving_markers] + has_moving_marker = [marker in solver_markers for marker in solver_all_moving_markers] f = open('forces_'+str(self.myid)+'.csv','w') From c69ed9249a416606023ecbe7a84191678196292c Mon Sep 17 00:00:00 2001 From: patelha57 Date: Wed, 4 Jan 2023 13:24:58 -0800 Subject: [PATCH 61/68] Modify regression workflow --- .github/workflows/regression.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/regression.yml b/.github/workflows/regression.yml index b622d6c88af..e749e661e70 100644 --- a/.github/workflows/regression.yml +++ b/.github/workflows/regression.yml @@ -128,7 +128,7 @@ jobs: uses: docker://ghcr.io/su2code/su2/test-su2:221224-1158 with: # -t -c - args: -b ${{github.ref}} -t develop -c feature_FFD -s ${{matrix.testscript}} + args: -b ${{github.ref}} -t develop -c develop -s ${{matrix.testscript}} - name: Cleanup uses: docker://ghcr.io/su2code/su2/test-su2:221224-1158 with: From abe96dec521d9bbef68be8cfc7c2cc82a870bfd1 Mon Sep 17 00:00:00 2001 From: patelha57 Date: Tue, 10 Jan 2023 15:00:57 -0800 Subject: [PATCH 62/68] Fix memory deallocation error in CDeformationDriver --- SU2_CFD/src/drivers/CDriverBase.cpp | 1 - SU2_DEF/src/drivers/CDeformationDriver.cpp | 46 +++++++++++----------- 2 files changed, 22 insertions(+), 25 deletions(-) diff --git a/SU2_CFD/src/drivers/CDriverBase.cpp b/SU2_CFD/src/drivers/CDriverBase.cpp index 726dabe44f9..fd7b2948301 100644 --- a/SU2_CFD/src/drivers/CDriverBase.cpp +++ b/SU2_CFD/src/drivers/CDriverBase.cpp @@ -65,7 +65,6 @@ void CDriverBase::SetContainers_Null() { for (iZone = 0; iZone < nZone; iZone++) { nInst[iZone] = 1; - FFDBox[iZone] = new CFreeFormDefBox*[MAX_NUMBER_FFD]; } driver_config = nullptr; diff --git a/SU2_DEF/src/drivers/CDeformationDriver.cpp b/SU2_DEF/src/drivers/CDeformationDriver.cpp index 99ed2dab30a..712cd8e194d 100644 --- a/SU2_DEF/src/drivers/CDeformationDriver.cpp +++ b/SU2_DEF/src/drivers/CDeformationDriver.cpp @@ -524,32 +524,32 @@ void CDeformationDriver::Postprocessing() { if (rank == MASTER_NODE) cout << endl << "------------------------- Solver Postprocessing -------------------------" << endl; - if (driver_config != nullptr) delete[] driver_config; - - for (iZone = 0; iZone < nZone; iZone++) { - if (numerics_container[iZone] != nullptr) { - for (unsigned int iTerm = 0; iTerm < MAX_TERMS * omp_get_max_threads(); iTerm++) { - delete numerics_container[iZone][INST_0][MESH_0][MESH_SOL][iTerm]; - delete[] numerics_container[iZone][INST_0][MESH_0][MESH_SOL]; - delete[] numerics_container[iZone][INST_0][MESH_0]; - delete[] numerics_container[iZone][INST_0]; + if (driver_config->GetDeform_Mesh()) { + for (iZone = 0; iZone < nZone; iZone++) { + if (numerics_container[iZone] != nullptr) { + for (unsigned int iTerm = 0; iTerm < MAX_TERMS * omp_get_max_threads(); iTerm++) { + delete numerics_container[iZone][INST_0][MESH_0][MESH_SOL][iTerm]; + delete[] numerics_container[iZone][INST_0][MESH_0][MESH_SOL]; + delete[] numerics_container[iZone][INST_0][MESH_0]; + delete[] numerics_container[iZone][INST_0]; + } + delete[] numerics_container[iZone]; } - delete[] numerics_container[iZone]; } - } - delete[] numerics_container; - if (rank == MASTER_NODE) cout << "Deleted CNumerics container." << endl; + delete[] numerics_container; + if (rank == MASTER_NODE) cout << "Deleted CNumerics container." << endl; - for (iZone = 0; iZone < nZone; iZone++) { - if (solver_container[iZone] != nullptr) { - delete solver_container[iZone][INST_0][MESH_0][MESH_SOL]; - delete[] solver_container[iZone][INST_0][MESH_0]; - delete[] solver_container[iZone][INST_0]; - delete[] solver_container[iZone]; + for (iZone = 0; iZone < nZone; iZone++) { + if (solver_container[iZone] != nullptr) { + delete solver_container[iZone][INST_0][MESH_0][MESH_SOL]; + delete[] solver_container[iZone][INST_0][MESH_0]; + delete[] solver_container[iZone][INST_0]; + delete[] solver_container[iZone]; + } } + delete[] solver_container; + if (rank == MASTER_NODE) cout << "Deleted CSolver container." << endl; } - delete[] solver_container; - if (rank == MASTER_NODE) cout << "Deleted CSolver container." << endl; if (geometry_container != nullptr) { for (iZone = 0; iZone < nZone; iZone++) { @@ -561,9 +561,6 @@ void CDeformationDriver::Postprocessing() { } if (rank == MASTER_NODE) cout << "Deleted CGeometry container." << endl; - for (iZone = 0; iZone < nZone; iZone++) { - delete[] FFDBox[iZone]; - } delete[] FFDBox; if (rank == MASTER_NODE) cout << "Deleted CFreeFormDefBox class." << endl; @@ -590,6 +587,7 @@ void CDeformationDriver::Postprocessing() { } delete[] config_container; } + delete driver_config; if (rank == MASTER_NODE) cout << "Deleted CConfig container." << endl; if (output_container != nullptr) { From 47b1966ca1e62a88294665dc1223538f42468e79 Mon Sep 17 00:00:00 2001 From: patelha57 Date: Tue, 10 Jan 2023 17:17:38 -0800 Subject: [PATCH 63/68] Fix continuous adjoint solver errors in CDiscAdjDeformationDriver --- .../src/drivers/CDiscAdjDeformationDriver.cpp | 52 ++++++++++++------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp b/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp index 362c237e56a..d65f150d2a9 100644 --- a/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp +++ b/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp @@ -289,38 +289,50 @@ void CDiscAdjDeformationDriver::Output_Preprocessing() {} void CDiscAdjDeformationDriver::Preprocess() { for (iZone = 0; iZone < nZone; iZone++) { - if (rank == MASTER_NODE) cout << "Reading volume sensitivities at each node from file." << endl; - unsigned short nInst_Zone = nInst[iZone]; + if (!config_container[iZone]->GetDiscrete_Adjoint()) { + if (rank == MASTER_NODE) cout << "Reading surface sensitivities at each node from file." << endl; + geometry_container[iZone][INST_0][MESH_0]->SetBoundSensitivity(config_container[iZone]); - grid_movement[iZone] = new CVolumetricMovement*[nInst_Zone](); - grid_movement[iZone][INST_0] = new CVolumetricMovement(geometry_container[iZone][INST_0][MESH_0], config_container[iZone]); + } else { + if (rank == MASTER_NODE) cout << "Reading volume sensitivities at each node from file." << endl; + unsigned short nInst_Zone = nInst[iZone]; + + grid_movement[iZone] = new CVolumetricMovement*[nInst_Zone](); + grid_movement[iZone][INST_0] = new CVolumetricMovement(geometry_container[iZone][INST_0][MESH_0], config_container[iZone]); - /*--- Read in sensitivities from file. ---*/ + /*--- Read in sensitivities from file. ---*/ - if (config_container[ZONE_0]->GetSensitivity_Format() == UNORDERED_ASCII) - geometry_container[iZone][INST_0][MESH_0]->ReadUnorderedSensitivity(config_container[iZone]); - else - geometry_container[iZone][INST_0][MESH_0]->SetSensitivity(config_container[iZone]); + if (config_container[ZONE_0]->GetSensitivity_Format() == UNORDERED_ASCII) + geometry_container[iZone][INST_0][MESH_0]->ReadUnorderedSensitivity(config_container[iZone]); + else + geometry_container[iZone][INST_0][MESH_0]->SetSensitivity(config_container[iZone]); + } } } void CDiscAdjDeformationDriver::Run() { for (iZone = 0; iZone < nZone; iZone++) { - if (rank == MASTER_NODE) - cout << "\n---------------------- Mesh sensitivity computation ---------------------" << endl; - if (config_container[iZone]->GetDiscrete_Adjoint() && config_container[iZone]->GetSmoothGradient() && - config_container[iZone]->GetSobMode() == ENUM_SOBOLEV_MODUS::MESH_LEVEL) { - DerivativeTreatment_MeshSensitivity(geometry_container[iZone][INST_0][MESH_0], config_container[iZone], grid_movement[iZone][INST_0]); + if (!config_container[iZone]->GetDiscrete_Adjoint()) { + continue; } else { - grid_movement[iZone][INST_0]->SetVolume_Deformation(geometry_container[iZone][INST_0][MESH_0], - config_container[iZone], false, true); + if (rank == MASTER_NODE) + cout << "\n---------------------- Mesh sensitivity computation ---------------------" << endl; + if (config_container[iZone]->GetDiscrete_Adjoint() && config_container[iZone]->GetSmoothGradient() && + config_container[iZone]->GetSobMode() == ENUM_SOBOLEV_MODUS::MESH_LEVEL) { + DerivativeTreatment_MeshSensitivity(geometry_container[iZone][INST_0][MESH_0], config_container[iZone], + grid_movement[iZone][INST_0]); + } else { + grid_movement[iZone][INST_0]->SetVolume_Deformation(geometry_container[iZone][INST_0][MESH_0], + config_container[iZone], false, true); + } } } - if (rank == MASTER_NODE) - cout << "\n------------------------ Mesh sensitivity Output ------------------------" << endl; - - SetSensitivity_Files(geometry_container, config_container, nZone); + if (config_container[ZONE_0]->GetDiscrete_Adjoint()) { + if (rank == MASTER_NODE) + cout << "\n------------------------ Mesh sensitivity Output ------------------------" << endl; + SetSensitivity_Files(geometry_container, config_container, nZone); + } Gradient_file.precision(driver_config->OptionIsSet("OUTPUT_PRECISION") ? driver_config->GetOutput_Precision() : 6); From 3ebd12b9d5e5e479d05232278a33ce6e0b2ea9f5 Mon Sep 17 00:00:00 2001 From: Harsh Patel <51417692+patelha57@users.noreply.github.com> Date: Wed, 11 Jan 2023 11:35:17 -0800 Subject: [PATCH 64/68] Update CDriver.hpp Co-authored-by: Pedro Gomes <38071223+pcarruscag@users.noreply.github.com> --- SU2_CFD/include/drivers/CDriver.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SU2_CFD/include/drivers/CDriver.hpp b/SU2_CFD/include/drivers/CDriver.hpp index c6fbde07c5a..a2755337263 100644 --- a/SU2_CFD/include/drivers/CDriver.hpp +++ b/SU2_CFD/include/drivers/CDriver.hpp @@ -1,5 +1,5 @@ /*! - * \file driver_structure.hpp + * \file CDriver.hpp * \brief Headers of the main subroutines for driving single or multi-zone problems. * The subroutines and functions are in the driver_structure.cpp file. * \author T. Economon, H. Kline, R. Sanchez From 5f2e268f8da1cc211d12804de2d7dfd911b36f8f Mon Sep 17 00:00:00 2001 From: Pedro Gomes Date: Sun, 5 Feb 2023 15:15:02 -0800 Subject: [PATCH 65/68] address boiler plate and return of global indices --- SU2_CFD/include/drivers/CDriverBase.hpp | 295 +++--------- SU2_CFD/src/drivers/CDriverBase.cpp | 609 +++++------------------- 2 files changed, 172 insertions(+), 732 deletions(-) diff --git a/SU2_CFD/include/drivers/CDriverBase.hpp b/SU2_CFD/include/drivers/CDriverBase.hpp index 6ff1781eb09..cb1c27f340d 100644 --- a/SU2_CFD/include/drivers/CDriverBase.hpp +++ b/SU2_CFD/include/drivers/CDriverBase.hpp @@ -134,36 +134,6 @@ class CDriverBase { */ unsigned short GetNumberFFDBoxes() const; - /*! - * \brief Get the number of markers in the mesh. - * \return Number of markers. - */ - unsigned short GetNumberMarkers() const; - - /*! - * \brief Get all the boundary markers tags with their associated indices. - * \return List of boundary markers tags with their indices. - */ - map GetMarkerIndices() const; - - /*! - * \brief Get all the boundary markers tags with their associated types. - * \return List of boundary markers tags with their types. - */ - map GetMarkerTypes() const; - - /*! - * \brief Get all the boundary marker tags. - * \return List of boundary markers tags. - */ - vector GetMarkerTags() const; - - /*! - * \brief Get all the deformable boundary marker tags. - * \return List of deformable boundary markers tags. - */ - vector GetDeformableMarkerTags() const; - /*! * \brief Get the number of dimensions of the mesh. * \return Number of dimensions. @@ -176,256 +146,144 @@ class CDriverBase { */ unsigned long GetNumberElements() const; - /*! - * \brief Get the number of elements in the marker. - * \param[in] iMarker - Marker index. - * \return Number of elements. - */ - unsigned long GetNumberMarkerElements(unsigned short iMarker) const; - - /*! - * \brief Get the global indices of the mesh elements. - * \return Global element indices (nElem). - */ - vector GetElements() const; - /*! * \brief Get the global index of a mesh element. * \param[in] iElem - Mesh element index. * \return Global element index. */ - unsigned long GetElements(unsigned long iElem) const; - - /*! - * \brief Get the global indices of the marker elements. - * \param[in] iMarker - Marker index. - * \return Global element indices (nElem). - */ - vector GetMarkerElements(unsigned short iMarker) const; - - /*! - * \brief Get the global index of a marker element. - * \param[in] iMarker - Marker index. - * \param[in] iElem - Marker element index. - * \return Global element index. - */ - unsigned long GetMarkerElements(unsigned short iMarker, unsigned long iElem) const; + unsigned long GetElementGlobalIndex(unsigned long iElem) const; /*! - * \brief Get the global node indices of the mesh elements. - * \return Element global node indices (nElem, nNode). - */ - vector> GetElementNodes() const; - - /*! - * \brief Get the global node indices of a mesh element. + * \brief Get the node indices of a mesh element. * \param[in] iElem - Mesh element index. - * \return Element global node indices (nNode). + * \return Element node indices (nNode). */ vector GetElementNodes(unsigned long iElem) const; /*! - * \brief Get the global node indices of the marker elements. - * \param[in] iMarker - Marker index. - * \return Element global node indices (nElem, nVertex). - */ - vector> GetMarkerElementNodes(unsigned short iMarker) const; - - /*! - * \brief Get the global node indices of a marker element. - * \param[in] iMarker - Marker index. - * \param[in] iElem - Marker element index. - * \return Element global node indices (nVertex). - */ - vector GetMarkerElementNodes(unsigned short iMarker, unsigned long iElem) const; - - /*! - * \brief Get the number of nodes in the mesh. + * \brief Get the number of nodes in the mesh (including halos). * \return Number of nodes. */ unsigned long GetNumberNodes() const; - /*! - * \brief Get the number of nodes in the marker. - * \param[in] iMarker - Marker index. - * \return Number of nodes. - */ - unsigned long GetNumberMarkerNodes(unsigned short iMarker) const; - /*! * \brief Get the number of halo nodes in the mesh. * \return Number of halo nodes. */ unsigned long GetNumberHaloNodes() const; - /*! - * \brief Get the number of halo nodes in the marker. - * \param[in] iMarker - Marker index. - * \return Number of halo nodes. - */ - unsigned long GetNumberMarkerHaloNodes(unsigned short iMarker) const; - - /*! - * \brief Get the vertices of the marker. - * \param[in] iMarker - Marker index. - * \return Marker vertices (nVertex). - */ - vector GetMarkerVertices(unsigned short iMarker) const; - - /*! - * \brief Get the vertex of a marker. - * \param[in] iMarker - Marker index. - * \param[in] iVertex - Marker vertex index. - * \return Marker vertex. - */ - unsigned long GetMarkerVertices(unsigned short iMarker, unsigned long iVertex) const; - - /*! - * \brief Get the global node indices. - * \return Global node indices (nNode). - */ - vector GetNodes() const; - /*! * \brief Get the global node index. * \param[in] iPoint - Mesh node index. * \return Global node index. */ - unsigned long GetNodes(unsigned long iPoint) const; - - /*! - * \brief Get the global node indices of the marker vertices. - * \param[in] iMarker - Marker index. - * \return Global node indices (nVertex). - */ - vector GetMarkerNodes(unsigned short iMarker) const; - - /*! - * \brief Get the global node index of a marker vertex. - * \param[in] iMarker - Marker index. - * \param[in] iVertex - Marker vertex index. - * \return Global node index. - */ - unsigned long GetMarkerNodes(unsigned short iMarker, unsigned long iVertex) const; - - /*! - * \brief Get the halo flags of the mesh nodes. - * \return Node domain flags (nNode). - */ - vector GetDomain() const; + unsigned long GetNodeGlobalIndex(unsigned long iPoint) const; /*! * \brief Get the halo flag of a mesh node. * \param[in] iPoint - Mesh node index. * \return Node domain flag. */ - bool GetDomain(unsigned long iPoint) const; - - /*! - * \brief Get the halo flags of the marker vertices. - * \param[in] iMarker - Marker index. - * \return Domain flags (nVertex). - */ - vector GetMarkerDomain(unsigned short iMarker) const; + bool GetNodeDomain(unsigned long iPoint) const; /*! - * \brief Get the halo flag of a marker vertex. - * \param[in] iMarker - Marker index. - * \param[in] iVertex - Marker vertex index. - * \return Domain flag. + * \brief Get the initial (un-deformed) coordinates of a mesh node. + * \param[in] iPoint - Mesh node index. + * \return Initial node coordinates (nDim). */ - bool GetMarkerDomain(unsigned short iMarker, unsigned long iVertex) const; + vector GetInitialCoordinates(unsigned long iPoint) const; /*! - * \brief Get the initial (un-deformed) coordinates of the mesh nodes. - * \return Initial node coordinates (nNode, nDim). + * \brief Get the current coordinates of a mesh node. + * \param[in] iPoint - Mesh node index. + * \return Node coordinates (nDim). */ - vector> GetInitialCoordinates() const; + vector GetCoordinates(unsigned long iPoint) const; /*! - * \brief Get the initial (un-deformed) coordinates of a mesh node. + * \brief Set the coordinates of a mesh node. * \param[in] iPoint - Mesh node index. - * \return Initial node coordinates (nDim). + * \param[in] values - Node coordinates (nDim). */ - vector GetInitialCoordinates(unsigned long iPoint) const; + void SetCoordinates(unsigned long iPoint, vector values); /*! - * \brief Get the initial (un-deformed) coordinates of the marker vertices. - * \param[in] iMarker - Marker index. - * \return Initial node coordinates (nVertex, nDim). + * \brief Get the number of markers in the mesh. + * \return Number of markers. */ - vector> GetMarkerInitialCoordinates(unsigned short iMarker) const; + unsigned short GetNumberMarkers() const; /*! - * \brief Get the initial (un-deformed) coordinates of a marker vertex. - * \param[in] iMarker - Marker index. - * \param[in] iVertex - Marker vertex index. - * \return Initial node coordinates (nDim). + * \brief Get all the boundary markers tags with their associated indices. + * \return Map of boundary markers tags to their indices. */ - vector GetMarkerInitialCoordinates(unsigned short iMarker, unsigned long iVertex) const; + map GetMarkerIndices() const; /*! - * \brief Get the coordinates of the mesh nodes. - * \return Node coordinates (nNode, nDim). + * \brief Get all the boundary markers tags with their associated types. + * \return Map of boundary markers tags to their types. */ - vector> GetCoordinates() const; + map GetMarkerTypes() const; /*! - * \brief Get the coordinates of a mesh node. - * \param[in] iPoint - Mesh node index. - * \return Node coordinates (nDim). + * \brief Get all the boundary marker tags. + * \return List of boundary markers tags. */ - vector GetCoordinates(unsigned long iPoint) const; + vector GetMarkerTags() const; /*! - * \brief Get the coordinates of the marker vertices. - * \param[in] iMarker - Marker index. - * \return Node coordinates (nVertex, nDim). + * \brief Get all the deformable boundary marker tags. + * \return List of deformable boundary markers tags. */ - vector> GetMarkerCoordinates(unsigned short iMarker) const; + vector GetDeformableMarkerTags() const; /*! - * \brief Get the coordinates of a marker vertex. + * \brief Get the number of elements in the marker. * \param[in] iMarker - Marker index. - * \param[in] iVertex - Marker vertex index. - * \return Node coordinates (nDim). + * \return Number of elements. */ - vector GetMarkerCoordinates(unsigned short iMarker, unsigned long iVertex) const; + unsigned long GetNumberMarkerElements(unsigned short iMarker) const; /*! - * \brief Set the coordinates of the mesh nodes. - * \param[in] values - Node coordinates (nNode, nDim). + * \brief Get the global index of a marker element. + * \param[in] iMarker - Marker index. + * \param[in] iElem - Marker element index. + * \return Global element index. */ - void SetCoordinates(vector> values); + unsigned long GetMarkerElementGlobalIndex(unsigned short iMarker, unsigned long iElem) const; /*! - * \brief Set the coordinates of a mesh node. - * \param[in] iPoint - Mesh node index. - * \param[in] values - Node coordinates (nDim). + * \brief Get the node indices of a marker element. + * \param[in] iMarker - Marker index. + * \param[in] iElem - Marker element index. + * \return Element node indices. */ - void SetCoordinates(unsigned long iPoint, vector values); + vector GetMarkerElementNodes(unsigned short iMarker, unsigned long iElem) const; /*! - * \brief Set the coordinates of the marker vertices. + * \brief Get the number of nodes in the marker. * \param[in] iMarker - Marker index. - * \param[in] values - Node coordinates (nVertex, nDim). + * \return Number of nodes. */ - void SetMarkerCoordinates(unsigned short iMarker, vector> values); + unsigned long GetNumberMarkerNodes(unsigned short iMarker) const; /*! - * \brief Set the coordinates of a marker vertex. + * \brief Get the node index of a marker. * \param[in] iMarker - Marker index. * \param[in] iVertex - Marker vertex index. - * \param[in] values - Node coordinates (nDim). + * \return Marker vertex. */ - void SetMarkerCoordinates(unsigned short iMarker, unsigned long iVertex, vector values); + unsigned long GetMarkerNode(unsigned short iMarker, unsigned long iVertex) const; /*! - * \brief Get the displacements of the marker vertices. + * \brief Get the normal vector of a marker vertex. * \param[in] iMarker - Marker index. - * \return Node displacements (nVertex, nDim). + * \param[in] iVertex - Marker vertex index. + * \param[in] normalize - If true, the unit (i.e. normalized) normal vector is returned. + * \return Node normal vector (nDim). */ - vector> GetMarkerDisplacements(unsigned short iMarker) const; + vector GetMarkerVertexNormals(unsigned short iMarker, unsigned long iVertex, + bool normalize = false) const; /*! * \brief Get the displacements of a marker vertex. @@ -435,13 +293,6 @@ class CDriverBase { */ vector GetMarkerDisplacements(unsigned short iMarker, unsigned long iVertex) const; - /*! - * \brief Set the displacements of the marker vertices. - * \param[in] iMarker - Marker index. - * \param[in] values - Node displacements (nVertex, nDim). - */ - void SetMarkerDisplacements(unsigned short iMarker, vector> values); - /*! * \brief Set the displacements of a marker vertex. * \param[in] iMarker - Marker index. @@ -450,13 +301,6 @@ class CDriverBase { */ void SetMarkerDisplacements(unsigned short iMarker, unsigned long iVertex, vector values); - /*! - * \brief Get the velocities of the marker vertices. - * \param[in] iMarker - Marker index. - * \return Node velocities (nVertex, nDim). - */ - vector> GetMarkerVelocities(unsigned short iMarker) const; - /*! * \brief Get the velocities of a marker vertex. * \param[in] iMarker - Marker index. @@ -465,13 +309,6 @@ class CDriverBase { */ vector GetMarkerVelocities(unsigned short iMarker, unsigned long iVertex) const; - /*! - * \brief Set the velocities of the marker vertices. - * \param[in] iMarker - Marker index. - * \param[in] values - Node velocities (nVertex, nDim). - */ - void SetMarkerVelocities(unsigned short iMarker, vector> values); - /*! * \brief Set the velocities of a marker vertex. * \param[in] iMarker - Marker index. @@ -480,24 +317,6 @@ class CDriverBase { */ void SetMarkerVelocities(unsigned short iMarker, unsigned long iVertex, vector values); - /*! - * \brief Get the normal vectors of the marker vertices. - * \param[in] iMarker - Marker index. - * \param[in] normalize - If true, the unit (i.e. normalized) normal vector is returned. - * \return Node normal vectors (nVertex, nDim). - */ - vector> GetMarkerVertexNormals(unsigned short iMarker, bool normalize = false) const; - - /*! - * \brief Get the normal vector of a marker vertex. - * \param[in] iMarker - Marker index. - * \param[in] iVertex - Marker vertex index. - * \param[in] normalize - If true, the unit (i.e. normalized) normal vector is returned. - * \return Node normal vector (nDim). - */ - vector GetMarkerVertexNormals(unsigned short iMarker, unsigned long iVertex, - bool normalize = false) const; - /*! * \brief Communicate the boundary mesh displacements. */ diff --git a/SU2_CFD/src/drivers/CDriverBase.cpp b/SU2_CFD/src/drivers/CDriverBase.cpp index fd7b2948301..5097fe345ec 100644 --- a/SU2_CFD/src/drivers/CDriverBase.cpp +++ b/SU2_CFD/src/drivers/CDriverBase.cpp @@ -78,6 +78,90 @@ unsigned short CDriverBase::GetNumberDesignVariables() const { return main_confi unsigned short CDriverBase::GetNumberFFDBoxes() const { return main_config->GetnFFDBox(); } +unsigned long CDriverBase::GetNumberDimensions() const { return main_geometry->GetnDim(); } + +unsigned long CDriverBase::GetNumberElements() const { return main_geometry->GetnElem(); } + +unsigned long CDriverBase::GetElementGlobalIndex(unsigned long iElem) const { + if (iElem >= GetNumberElements()) { + SU2_MPI::Error("Element index exceeds size.", CURRENT_FUNCTION); + } + return main_geometry->elem[iElem]->GetGlobalIndex(); +} + +vector CDriverBase::GetElementNodes(unsigned long iElem) const { + if (iElem >= GetNumberElements()) { + SU2_MPI::Error("Element index exceeds size.", CURRENT_FUNCTION); + } + const auto nNode = main_geometry->elem[iElem]->GetnNodes(); + vector values(nNode); + + for (auto iNode = 0u; iNode < nNode; iNode++) { + values[iNode] = main_geometry->elem[iElem]->GetNode(iNode); + } + return values; +} + +unsigned long CDriverBase::GetNumberNodes() const { return main_geometry->GetnPoint(); } + +unsigned long CDriverBase::GetNumberHaloNodes() const { + return main_geometry->GetnPoint() - main_geometry->GetnPointDomain(); +} + +unsigned long CDriverBase::GetNodeGlobalIndex(unsigned long iPoint) const { + if (iPoint >= GetNumberNodes()) { + SU2_MPI::Error("Node index exceeds mesh size.", CURRENT_FUNCTION); + } + return main_geometry->nodes->GetGlobalIndex(iPoint); +} + +bool CDriverBase::GetNodeDomain(unsigned long iPoint) const { + if (iPoint >= GetNumberNodes()) { + SU2_MPI::Error("Node index exceeds mesh size.", CURRENT_FUNCTION); + } + return main_geometry->nodes->GetDomain(iPoint); +} + +vector CDriverBase::GetInitialCoordinates(unsigned long iPoint) const { + if (iPoint >= GetNumberNodes()) { + SU2_MPI::Error("Node index exceeds mesh size.", CURRENT_FUNCTION); + } + vector values(nDim, 0.0); + + if (main_config->GetDeform_Mesh()) { + for (auto iDim = 0u; iDim < nDim; iDim++) { + const su2double value = solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->GetMesh_Coord(iPoint, iDim); + values[iDim] = SU2_TYPE::GetValue(value); + } + } + return values; +} + +vector CDriverBase::GetCoordinates(unsigned long iPoint) const { + if (iPoint >= GetNumberNodes()) { + SU2_MPI::Error("Node index exceeds mesh size.", CURRENT_FUNCTION); + } + vector values; + + for (auto iDim = 0u; iDim < nDim; iDim++) { + const su2double value = main_geometry->nodes->GetCoord(iPoint, iDim); + values.push_back(SU2_TYPE::GetValue(value)); + } + return values; +} + +void CDriverBase::SetCoordinates(unsigned long iPoint, vector values) { + if (iPoint >= GetNumberNodes()) { + SU2_MPI::Error("Node index exceeds mesh size.", CURRENT_FUNCTION); + } + if (values.size() != nDim) { + SU2_MPI::Error("Invalid number of dimensions!", CURRENT_FUNCTION); + } + for (auto iDim = 0u; iDim < nDim; iDim++) { + main_geometry->nodes->SetCoord(iPoint, iDim, values[iDim]); + } +} + unsigned short CDriverBase::GetNumberMarkers() const { return main_config->GetnMarker_All(); } map CDriverBase::GetMarkerIndices() const { @@ -85,11 +169,8 @@ map CDriverBase::GetMarkerIndices() const { map indexMap; for (auto iMarker = 0u; iMarker < nMarker; iMarker++) { - auto tag = main_config->GetMarker_All_TagBound(iMarker); - - indexMap[tag] = iMarker; + indexMap[main_config->GetMarker_All_TagBound(iMarker)] = iMarker; } - return indexMap; } @@ -160,594 +241,134 @@ map CDriverBase::GetMarkerTypes() const { } vector CDriverBase::GetMarkerTags() const { - vector tags; const auto nMarker = main_config->GetnMarker_All(); + vector tags(nMarker); for (auto iMarker = 0u; iMarker < nMarker; iMarker++) { - tags.push_back(main_config->GetMarker_All_TagBound(iMarker)); + tags[iMarker] = main_config->GetMarker_All_TagBound(iMarker); } - return tags; } vector CDriverBase::GetDeformableMarkerTags() const { - vector tags; const auto nMarker = main_config->GetnMarker_Deform_Mesh(); + vector tags(nMarker); for (auto iMarker = 0u; iMarker < nMarker; iMarker++) { - tags.push_back(main_config->GetMarker_Deform_Mesh_TagBound(iMarker)); + tags[iMarker] = main_config->GetMarker_Deform_Mesh_TagBound(iMarker); } - return tags; } -unsigned long CDriverBase::GetNumberDimensions() const { return main_geometry->GetnDim(); } - -unsigned long CDriverBase::GetNumberElements() const { return main_geometry->GetnElem(); } - unsigned long CDriverBase::GetNumberMarkerElements(unsigned short iMarker) const { if (iMarker >= GetNumberMarkers()) { SU2_MPI::Error("Marker index exceeds size.", CURRENT_FUNCTION); } - return main_geometry->GetnElem_Bound(iMarker); } -vector CDriverBase::GetElements() const { - const auto nElem = GetNumberElements(); - - vector values; - - for (auto iElem = 0ul; iElem < nElem; iElem++) { - values.push_back(GetElements(iElem)); - } - - return values; -} - -unsigned long CDriverBase::GetElements(unsigned long iElem) const { - if (iElem >= GetNumberElements()) { - SU2_MPI::Error("Element index exceeds size.", CURRENT_FUNCTION); - } - - return main_geometry->elem[iElem]->GetGlobalIndex(); -} - -vector CDriverBase::GetMarkerElements(unsigned short iMarker) const { - const auto nElem = GetNumberMarkerElements(iMarker); - - vector values; - - for (auto iElem = 0ul; iElem < nElem; iElem++) { - values.push_back(GetMarkerElements(iMarker, iElem)); - } - - return values; -} - -unsigned long CDriverBase::GetMarkerElements(unsigned short iMarker, unsigned long iElem) const { +unsigned long CDriverBase::GetMarkerElementGlobalIndex(unsigned short iMarker, unsigned long iElem) const { if (iElem >= GetNumberMarkerElements(iMarker)) { SU2_MPI::Error("Marker element index exceeds size.", CURRENT_FUNCTION); } - return main_geometry->bound[iMarker][iElem]->GetGlobalIndex(); } -vector> CDriverBase::GetElementNodes() const { - const auto nElem = GetNumberElements(); - - vector> values; - - for (auto iElem = 0ul; iElem < nElem; iElem++) { - values.push_back(GetElementNodes(iElem)); - } - - return values; -} - -vector CDriverBase::GetElementNodes(unsigned long iElem) const { - if (iElem >= GetNumberElements()) { - SU2_MPI::Error("Element index exceeds size.", CURRENT_FUNCTION); - } - - unsigned short nNode = main_geometry->elem[iElem]->GetnNodes(); - - vector values; - - for (auto iNode = 0u; iNode < nNode; iNode++) { - unsigned long iPoint = main_geometry->elem[iElem]->GetNode(iNode); - - values.push_back(main_geometry->nodes->GetGlobalIndex(iPoint)); - } - - return values; -} - -vector> CDriverBase::GetMarkerElementNodes(unsigned short iMarker) const { - const auto nElem = GetNumberMarkerElements(iMarker); - - vector> values; - - for (auto iElem = 0ul; iElem < nElem; iElem++) { - values.push_back(GetMarkerElementNodes(iMarker, iElem)); - } - - return values; -} - vector CDriverBase::GetMarkerElementNodes(unsigned short iMarker, unsigned long iElem) const { if (iElem >= GetNumberMarkerElements(iMarker)) { SU2_MPI::Error("Marker element index exceeds size.", CURRENT_FUNCTION); } - unsigned short nNode = main_geometry->bound[iMarker][iElem]->GetnNodes(); - - vector values; + vector values(nNode); for (auto iNode = 0u; iNode < nNode; iNode++) { - unsigned long iPoint = main_geometry->bound[iMarker][iElem]->GetNode(iNode); - - values.push_back(main_geometry->nodes->GetGlobalIndex(iPoint)); + values[iNode] = main_geometry->bound[iMarker][iElem]->GetNode(iNode); } - return values; } -unsigned long CDriverBase::GetNumberNodes() const { return main_geometry->GetnPoint(); } - unsigned long CDriverBase::GetNumberMarkerNodes(unsigned short iMarker) const { if (iMarker >= GetNumberMarkers()) { SU2_MPI::Error("Marker index exceeds size.", CURRENT_FUNCTION); } - return main_geometry->GetnVertex(iMarker); } -unsigned long CDriverBase::GetNumberHaloNodes() const { - const auto nPoint = GetNumberNodes(); - unsigned long nHalo = 0; - - for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { - if (!(main_geometry->nodes->GetDomain(iPoint))) { - nHalo += 1; - } - } - - return nHalo; -} - -unsigned long CDriverBase::GetNumberMarkerHaloNodes(unsigned short iMarker) const { - const auto nVertex = GetNumberMarkerNodes(iMarker); - unsigned long nHalo = 0; - - for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - auto iPoint = GetMarkerVertices(iMarker, iVertex); - - if (!(main_geometry->nodes->GetDomain(iPoint))) { - nHalo += 1; - } - } - - return nHalo; -} - -vector CDriverBase::GetMarkerVertices(unsigned short iMarker) const { - const auto nVertex = GetNumberMarkerNodes(iMarker); - - vector values; - - for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - values.push_back(GetMarkerVertices(iMarker, iVertex)); - } - - return values; -} - -unsigned long CDriverBase::GetMarkerVertices(unsigned short iMarker, unsigned long iVertex) const { +unsigned long CDriverBase::GetMarkerNode(unsigned short iMarker, unsigned long iVertex) const { if (iVertex >= GetNumberMarkerNodes(iMarker)) { SU2_MPI::Error("Vertex index exceeds marker size.", CURRENT_FUNCTION); } - return geometry_container[MESH_0][INST_0][ZONE_0]->vertex[iMarker][iVertex]->GetNode(); } -vector CDriverBase::GetNodes() const { - const auto nPoint = GetNumberNodes(); - - vector values; - - for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { - values.push_back(GetNodes(iPoint)); - } - - return values; -} - -unsigned long CDriverBase::GetNodes(unsigned long iPoint) const { - if (iPoint >= GetNumberNodes()) { - SU2_MPI::Error("Node index exceeds mesh size.", CURRENT_FUNCTION); - } - - return main_geometry->nodes->GetGlobalIndex(iPoint); -} - -vector CDriverBase::GetMarkerNodes(unsigned short iMarker) const { - const auto nVertex = GetNumberMarkerNodes(iMarker); - - vector values; - - for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - values.push_back(GetMarkerNodes(iMarker, iVertex)); - } - - return values; -} - -unsigned long CDriverBase::GetMarkerNodes(unsigned short iMarker, unsigned long iVertex) const { - auto iPoint = GetMarkerVertices(iMarker, iVertex); - - return main_geometry->nodes->GetGlobalIndex(iPoint); -} - -vector CDriverBase::GetDomain() const { - const auto nPoint = GetNumberNodes(); - - vector values; - - for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { - values.push_back(GetDomain(iPoint)); - } - - return values; -} - -bool CDriverBase::GetDomain(unsigned long iPoint) const { - if (iPoint >= GetNumberNodes()) { - SU2_MPI::Error("Node index exceeds mesh size.", CURRENT_FUNCTION); - } - - return main_geometry->nodes->GetDomain(iPoint); -} - -vector CDriverBase::GetMarkerDomain(unsigned short iMarker) const { - const auto nVertex = GetNumberMarkerNodes(iMarker); - - vector values; - - for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - values.push_back(GetMarkerDomain(iMarker, iVertex)); - } - - return values; -} - -bool CDriverBase::GetMarkerDomain(unsigned short iMarker, unsigned long iVertex) const { - auto iPoint = GetMarkerVertices(iMarker, iVertex); - - return main_geometry->nodes->GetDomain(iPoint); -} - -vector> CDriverBase::GetInitialCoordinates() const { - const auto nPoint = GetNumberNodes(); - - vector> values; - - for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { - values.push_back(GetInitialCoordinates(iPoint)); - } - - return values; -} - -vector CDriverBase::GetInitialCoordinates(unsigned long iPoint) const { - if (iPoint >= GetNumberNodes()) { - SU2_MPI::Error("Node index exceeds mesh size.", CURRENT_FUNCTION); - } - - vector values(nDim, 0.0); - - if (!main_config->GetDeform_Mesh()) { - return values; - } - - for (auto iDim = 0u; iDim < nDim; iDim++) { - const su2double value = solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->GetMesh_Coord(iPoint, iDim); - - values[iDim] = SU2_TYPE::GetValue(value); - } - - return values; -} - -vector> CDriverBase::GetMarkerInitialCoordinates(unsigned short iMarker) const { - const auto nVertex = GetNumberMarkerNodes(iMarker); - - vector> values; - - for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - values.push_back(GetMarkerInitialCoordinates(iMarker, iVertex)); +vector CDriverBase::GetMarkerVertexNormals(unsigned short iMarker, unsigned long iVertex, + bool normalize) const { + if (iVertex >= GetNumberMarkerNodes(iMarker)) { + SU2_MPI::Error("Vertex index exceeds marker size.", CURRENT_FUNCTION); } - - return values; -} - -vector CDriverBase::GetMarkerInitialCoordinates(unsigned short iMarker, unsigned long iVertex) const { - auto iPoint = GetMarkerVertices(iMarker, iVertex); + const auto* normal = main_geometry->vertex[iMarker][iVertex]->GetNormal(); + const su2double area = normalize ? GeometryToolbox::Norm(nDim, normal) : 1.0; vector values(nDim, 0.0); - if (!main_config->GetDeform_Mesh()) { - return values; - } - - for (auto iDim = 0u; iDim < nDim; iDim++) { - const su2double value = solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->GetMesh_Coord(iPoint, iDim); - - values[iDim] = SU2_TYPE::GetValue(value); - } - - return values; -} - -vector> CDriverBase::GetCoordinates() const { - const auto nPoint = GetNumberNodes(); - - vector> values; - - for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { - values.push_back(GetCoordinates(iPoint)); - } - - return values; -} - -vector CDriverBase::GetCoordinates(unsigned long iPoint) const { - if (iPoint >= GetNumberNodes()) { - SU2_MPI::Error("Node index exceeds mesh size.", CURRENT_FUNCTION); - } - - vector values; - for (auto iDim = 0u; iDim < nDim; iDim++) { - const su2double value = main_geometry->nodes->GetCoord(iPoint, iDim); - - values.push_back(SU2_TYPE::GetValue(value)); + values[iDim] = SU2_TYPE::GetValue(normal[iDim] / area); } - - return values; -} - -vector> CDriverBase::GetMarkerCoordinates(unsigned short iMarker) const { - const auto nVertex = GetNumberMarkerNodes(iMarker); - - vector> values; - - for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - values.push_back(GetMarkerCoordinates(iMarker, iVertex)); - } - - return values; -} - -vector CDriverBase::GetMarkerCoordinates(unsigned short iMarker, unsigned long iVertex) const { - auto iPoint = GetMarkerVertices(iMarker, iVertex); - - vector values; - - for (auto iDim = 0u; iDim < nDim; iDim++) { - const su2double value = main_geometry->nodes->GetCoord(iPoint, iDim); - - values.push_back(SU2_TYPE::GetValue(value)); - } - - return values; -} - -void CDriverBase::SetCoordinates(vector> values) { - const auto nPoint = GetNumberNodes(); - - if (values.size() != nPoint) { - SU2_MPI::Error("Invalid number of nodes!", CURRENT_FUNCTION); - } - - for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { - SetCoordinates(iPoint, values[iPoint]); - } -} - -void CDriverBase::SetCoordinates(unsigned long iPoint, vector values) { - if (iPoint >= GetNumberNodes()) { - SU2_MPI::Error("Node index exceeds mesh size.", CURRENT_FUNCTION); - } - if (values.size() != nDim) { - SU2_MPI::Error("Invalid number of dimensions!", CURRENT_FUNCTION); - } - - for (auto iDim = 0u; iDim < nDim; iDim++) { - main_geometry->nodes->SetCoord(iPoint, iDim, values[iDim]); - } -} - -void CDriverBase::SetMarkerCoordinates(unsigned short iMarker, vector> values) { - const auto nVertex = GetNumberMarkerNodes(iMarker); - - if (values.size() != nVertex) { - SU2_MPI::Error("Invalid number of marker vertices!", CURRENT_FUNCTION); - } - - for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - SetMarkerCoordinates(iMarker, iVertex, values[iVertex]); - } -} - -void CDriverBase::SetMarkerCoordinates(unsigned short iMarker, unsigned long iVertex, vector values) { - auto iPoint = GetMarkerVertices(iMarker, iVertex); - - if (values.size() != nDim) { - SU2_MPI::Error("Invalid number of dimensions!", CURRENT_FUNCTION); - } - - for (auto iDim = 0u; iDim < nDim; iDim++) { - main_geometry->nodes->SetCoord(iPoint, iDim, values[iDim]); - } -} - -vector> CDriverBase::GetMarkerDisplacements(unsigned short iMarker) const { - const auto nVertex = GetNumberMarkerNodes(iMarker); - - vector> values; - - for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - values.push_back(GetMarkerDisplacements(iMarker, iVertex)); - } - return values; } vector CDriverBase::GetMarkerDisplacements(unsigned short iMarker, unsigned long iVertex) const { - auto iPoint = GetMarkerVertices(iMarker, iVertex); - vector values(nDim, 0.0); - if (!main_config->GetDeform_Mesh()) { - return values; - } - - for (auto iDim = 0u; iDim < nDim; iDim++) { - const su2double value = solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->GetBound_Disp(iPoint, iDim); - - values[iDim] = SU2_TYPE::GetValue(value); + if (main_config->GetDeform_Mesh()) { + const auto iPoint = GetMarkerNode(iMarker, iVertex); + for (auto iDim = 0u; iDim < nDim; iDim++) { + const su2double value = solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->GetBound_Disp(iPoint, iDim); + values[iDim] = SU2_TYPE::GetValue(value); + } } - return values; } -void CDriverBase::SetMarkerDisplacements(unsigned short iMarker, vector> values) { - if (!main_config->GetDeform_Mesh()) { - SU2_MPI::Error("Mesh solver is not defined!", CURRENT_FUNCTION); - } - - const auto nVertex = GetNumberMarkerNodes(iMarker); - - if (values.size() != nVertex) { - SU2_MPI::Error("Invalid number of marker vertices!", CURRENT_FUNCTION); - } - - for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - SetMarkerDisplacements(iMarker, iVertex, values[iVertex]); - } -} - void CDriverBase::SetMarkerDisplacements(unsigned short iMarker, unsigned long iVertex, vector values) { if (!main_config->GetDeform_Mesh()) { SU2_MPI::Error("Mesh solver is not defined!", CURRENT_FUNCTION); } - - auto iPoint = GetMarkerVertices(iMarker, iVertex); - if (values.size() != nDim) { SU2_MPI::Error("Invalid number of dimensions!", CURRENT_FUNCTION); } + const auto iPoint = GetMarkerNode(iMarker, iVertex); for (auto iDim = 0u; iDim < nDim; iDim++) { solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->SetBound_Disp(iPoint, iDim, values[iDim]); } } -vector> CDriverBase::GetMarkerVelocities(unsigned short iMarker) const { - const auto nVertex = GetNumberMarkerNodes(iMarker); - - vector> values; - - for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - values.push_back(GetMarkerVelocities(iMarker, iVertex)); - } - - return values; -} - vector CDriverBase::GetMarkerVelocities(unsigned short iMarker, unsigned long iVertex) const { - auto iPoint = GetMarkerVertices(iMarker, iVertex); - vector values(nDim, 0.0); - if (!main_config->GetDeform_Mesh()) { - return values; - } - - for (auto iDim = 0u; iDim < nDim; iDim++) { - const su2double value = solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->GetBound_Vel(iPoint, iDim); - - values[iDim] = SU2_TYPE::GetValue(value); + if (main_config->GetDeform_Mesh()) { + const auto iPoint = GetMarkerNode(iMarker, iVertex); + for (auto iDim = 0u; iDim < nDim; iDim++) { + const su2double value = solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->GetBound_Vel(iPoint, iDim); + values[iDim] = SU2_TYPE::GetValue(value); + } } - return values; } -void CDriverBase::SetMarkerVelocities(unsigned short iMarker, vector> values) { - if (!main_config->GetDeform_Mesh()) { - SU2_MPI::Error("Mesh solver is not defined!", CURRENT_FUNCTION); - } - - const auto nVertex = GetNumberMarkerNodes(iMarker); - - if (values.size() != nVertex) { - SU2_MPI::Error("Invalid number of marker vertices!", CURRENT_FUNCTION); - } - - for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - SetMarkerVelocities(iMarker, iVertex, values[iVertex]); - } -} - void CDriverBase::SetMarkerVelocities(unsigned short iMarker, unsigned long iVertex, vector values) { if (!main_config->GetDeform_Mesh()) { SU2_MPI::Error("Mesh solver is not defined!", CURRENT_FUNCTION); } - - auto iPoint = GetMarkerVertices(iMarker, iVertex); - if (values.size() != nDim) { SU2_MPI::Error("Invalid number of dimensions!", CURRENT_FUNCTION); } + const auto iPoint = GetMarkerNode(iMarker, iVertex); for (auto iDim = 0u; iDim < nDim; iDim++) { - solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->SetBound_Disp(iPoint, iDim, values[iDim]); - } -} - -vector> CDriverBase::GetMarkerVertexNormals(unsigned short iMarker, bool normalize) const { - const auto nVertex = GetNumberMarkerNodes(iMarker); - - vector> values; - - for (auto iVertex = 0ul; iVertex < nVertex; iVertex++) { - values.push_back(GetMarkerVertexNormals(iMarker, iVertex, normalize = normalize)); + solver_container[ZONE_0][INST_0][MESH_0][MESH_SOL]->GetNodes()->SetBound_Vel(iPoint, iDim, values[iDim]); } - - return values; -} - -vector CDriverBase::GetMarkerVertexNormals(unsigned short iMarker, unsigned long iVertex, - bool normalize) const { - if (iVertex >= GetNumberMarkerNodes(iMarker)) { - SU2_MPI::Error("Vertex index exceeds marker size.", CURRENT_FUNCTION); - } - - vector values(nDim, 0.0); - - auto normal = main_geometry->vertex[iMarker][iVertex]->GetNormal(); - auto area = GeometryToolbox::Norm(nDim, normal); - - for (auto iDim = 0u; iDim < nDim; iDim++) { - if (normalize) { - values[iDim] = SU2_TYPE::GetValue(normal[iDim] / area); - } else { - values[iDim] = SU2_TYPE::GetValue(normal[iDim]); - } - } - - return values; } void CDriverBase::CommunicateMeshDisplacements(void) { From cd1e820cde0068297a2fcb08a2917eb35e151fb4 Mon Sep 17 00:00:00 2001 From: Pedro Gomes Date: Sun, 5 Feb 2023 15:16:45 -0800 Subject: [PATCH 66/68] 2022 -> 2023 --- SU2_CFD/include/drivers/CDriverBase.hpp | 2 +- SU2_CFD/src/drivers/CDriverBase.cpp | 2 +- SU2_DEF/include/drivers/CDeformationDriver.hpp | 2 +- SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp | 2 +- SU2_DEF/src/drivers/CDeformationDriver.cpp | 2 +- SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/SU2_CFD/include/drivers/CDriverBase.hpp b/SU2_CFD/include/drivers/CDriverBase.hpp index cb1c27f340d..31e5385f802 100644 --- a/SU2_CFD/include/drivers/CDriverBase.hpp +++ b/SU2_CFD/include/drivers/CDriverBase.hpp @@ -9,7 +9,7 @@ * The SU2 Project is maintained by the SU2 Foundation * (http://su2foundation.org) * - * Copyright 2012-2022, SU2 Contributors (cf. AUTHORS.md) + * Copyright 2012-2023, SU2 Contributors (cf. AUTHORS.md) * * SU2 is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/SU2_CFD/src/drivers/CDriverBase.cpp b/SU2_CFD/src/drivers/CDriverBase.cpp index 5097fe345ec..63c6c974013 100644 --- a/SU2_CFD/src/drivers/CDriverBase.cpp +++ b/SU2_CFD/src/drivers/CDriverBase.cpp @@ -9,7 +9,7 @@ * The SU2 Project is maintained by the SU2 Foundation * (http://su2foundation.org) * - * Copyright 2012-2022, SU2 Contributors (cf. AUTHORS.md) + * Copyright 2012-2023, SU2 Contributors (cf. AUTHORS.md) * * SU2 is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser/ General Public diff --git a/SU2_DEF/include/drivers/CDeformationDriver.hpp b/SU2_DEF/include/drivers/CDeformationDriver.hpp index 01eecee0df5..ecc8b46c5cb 100644 --- a/SU2_DEF/include/drivers/CDeformationDriver.hpp +++ b/SU2_DEF/include/drivers/CDeformationDriver.hpp @@ -9,7 +9,7 @@ * The SU2 Project is maintained by the SU2 Foundation * (http://su2foundation.org) * - * Copyright 2012-2022, SU2 Contributors (cf. AUTHORS.md) + * Copyright 2012-2023, SU2 Contributors (cf. AUTHORS.md) * * SU2 is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp b/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp index 534b0cddb16..ce6ed37f4c5 100644 --- a/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp +++ b/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp @@ -9,7 +9,7 @@ * The SU2 Project is maintained by the SU2 Foundation * (http://su2foundation.org) * - * Copyright 2012-2022, SU2 Contributors (cf. AUTHORS.md) + * Copyright 2012-2023, SU2 Contributors (cf. AUTHORS.md) * * SU2 is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/SU2_DEF/src/drivers/CDeformationDriver.cpp b/SU2_DEF/src/drivers/CDeformationDriver.cpp index 712cd8e194d..88fa39afbff 100644 --- a/SU2_DEF/src/drivers/CDeformationDriver.cpp +++ b/SU2_DEF/src/drivers/CDeformationDriver.cpp @@ -9,7 +9,7 @@ * The SU2 Project is maintained by the SU2 Foundation * (http://su2foundation.org) * - * Copyright 2012-2022, SU2 Contributors (cf. AUTHORS.md) + * Copyright 2012-2023, SU2 Contributors (cf. AUTHORS.md) * * SU2 is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser/ General Public diff --git a/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp b/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp index d65f150d2a9..05d57465390 100644 --- a/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp +++ b/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp @@ -9,7 +9,7 @@ * The SU2 Project is maintained by the SU2 Foundation * (http://su2foundation.org) * - * Copyright 2012-2022, SU2 Contributors (cf. AUTHORS.md) + * Copyright 2012-2023, SU2 Contributors (cf. AUTHORS.md) * * SU2 is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public From 46fed4fc38699d1fc2a6d621eea4b53a6a6912ea Mon Sep 17 00:00:00 2001 From: Pedro Gomes Date: Sun, 5 Feb 2023 16:36:40 -0800 Subject: [PATCH 67/68] fix python scripts, remove mesh solver duplication --- SU2_CFD/include/drivers/CDriverBase.hpp | 12 ++-- SU2_CFD/include/solvers/CMeshSolver.hpp | 9 --- SU2_CFD/src/solvers/CMeshSolver.cpp | 57 ------------------- SU2_DEF/src/drivers/CDeformationDriver.cpp | 7 ++- SU2_PY/FSI_tools/FSIInterface.py | 18 +++--- .../launch_flatPlate_rigidMotion.py | 9 +-- .../launch_unsteady_CHT_FlatPlate.py | 4 -- .../translating_NACA0012/run_su2.py | 5 +- 8 files changed, 27 insertions(+), 94 deletions(-) diff --git a/SU2_CFD/include/drivers/CDriverBase.hpp b/SU2_CFD/include/drivers/CDriverBase.hpp index 31e5385f802..ad647f12be8 100644 --- a/SU2_CFD/include/drivers/CDriverBase.hpp +++ b/SU2_CFD/include/drivers/CDriverBase.hpp @@ -95,32 +95,32 @@ class CDriverBase { /*! * \brief A virtual member. */ - virtual void Preprocessing(){}; + virtual void Preprocessing(){} /*! * \brief A virtual member. */ - virtual void Run(){}; + virtual void Run(){} /*! * \brief A virtual member. */ - virtual void Update(){}; + virtual void Update(){} /*! * \brief A virtual member. */ - virtual void Update_Legacy(){}; + virtual void Update_Legacy(){} /*! * \brief A virtual member. */ - virtual void Output(){}; + virtual void Output(){} /*! * \brief A virtual member. */ - virtual void Postprocessing(){}; + virtual void Postprocessing(){} /*! * \brief Get the number of design variables. diff --git a/SU2_CFD/include/solvers/CMeshSolver.hpp b/SU2_CFD/include/solvers/CMeshSolver.hpp index 02152135276..713b6a086fa 100644 --- a/SU2_CFD/include/solvers/CMeshSolver.hpp +++ b/SU2_CFD/include/solvers/CMeshSolver.hpp @@ -132,15 +132,6 @@ class CMeshSolver final : public CFEASolver { CNumerics **numerics, CConfig *config) override; - /*! - * \brief Grid deformation using the linear elasticity equations (no multigrid). - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] numerics - Numerics used in the solution. - * \param[in] config - Definition of the particular problem. - */ - void DeformMesh(CGeometry *geometry, - CNumerics **numerics, - CConfig *config) override; /*! * \brief Set the stiffness of the mesh. * \param[in] numerics - Numerics used in the solution. diff --git a/SU2_CFD/src/solvers/CMeshSolver.cpp b/SU2_CFD/src/solvers/CMeshSolver.cpp index 970a41c7892..a4753df41cd 100644 --- a/SU2_CFD/src/solvers/CMeshSolver.cpp +++ b/SU2_CFD/src/solvers/CMeshSolver.cpp @@ -539,63 +539,6 @@ void CMeshSolver::DeformMesh(CGeometry **geometry, CNumerics **numerics, CConfig } -void CMeshSolver::DeformMesh(CGeometry *geometry, CNumerics **numerics, CConfig *config){ - - if (multizone) nodes->Set_BGSSolution_k(); - - /*--- Capture a few MPI dependencies for AD. ---*/ - geometry->InitiateComms(geometry, config, COORDINATES); - geometry->CompleteComms(geometry, config, COORDINATES); - - InitiateComms(geometry, config, SOLUTION); - CompleteComms(geometry, config, SOLUTION); - - InitiateComms(geometry, config, MESH_DISPLACEMENTS); - CompleteComms(geometry, config, MESH_DISPLACEMENTS); - - /*--- Compute the stiffness matrix, no point recording because we clear the residual. ---*/ - - const bool wasActive = AD::BeginPassive(); - - Compute_StiffMatrix(geometry, numerics, config); - - AD::EndPassive(wasActive); - - /*--- Clear residual (loses AD info), we do not want an incremental solution. ---*/ - SU2_OMP_PARALLEL { - LinSysRes.SetValZero(); - if (time_domain && config->GetFSI_Simulation()) LinSysSol.SetValZero(); - } - END_SU2_OMP_PARALLEL - - /*--- Impose boundary conditions (all of them are ESSENTIAL BC's - displacements). ---*/ - SetBoundaryDisplacements(geometry, config, false); - - /*--- Solve the linear system. ---*/ - Solve_System(geometry, config); - - SU2_OMP_PARALLEL { - - /*--- Update the grid coordinates and cell volumes using the solution - of the linear system (usol contains the x, y, z displacements). ---*/ - UpdateGridCoord(geometry, config); - - /*--- Update the dual grid (without multigrid). ---*/ - geometry->InitiateComms(geometry, config, COORDINATES); - geometry->CompleteComms(geometry, config, COORDINATES); - - geometry->SetControlVolume(config, UPDATE); - geometry->SetBoundControlVolume(config, UPDATE); - geometry->SetMaxLength(config); - - /*--- Check for failed deformation (negative volumes). ---*/ - SetMinMaxVolume(geometry, config, true); - - } - END_SU2_OMP_PARALLEL - -} - void CMeshSolver::UpdateGridCoord(CGeometry *geometry, const CConfig *config){ /*--- Update the grid coordinates using the solution of the linear system ---*/ diff --git a/SU2_DEF/src/drivers/CDeformationDriver.cpp b/SU2_DEF/src/drivers/CDeformationDriver.cpp index 88fa39afbff..b064aaf8d62 100644 --- a/SU2_DEF/src/drivers/CDeformationDriver.cpp +++ b/SU2_DEF/src/drivers/CDeformationDriver.cpp @@ -309,10 +309,13 @@ void CDeformationDriver::Update() { solver_container[iZone][INST_0][MESH_0][MESH_SOL]->SetMesh_Stiffness(numerics_container[iZone][INST_0][MESH_0][MESH_SOL], config_container[iZone]); /*--- Deform the volume grid around the new boundary locations. ---*/ - - solver_container[iZone][INST_0][MESH_0][MESH_SOL]->DeformMesh(geometry_container[iZone][INST_0][MESH_0], + /*--- Force the number of levels to be 0 because in this driver we do not build MG levels. ---*/ + const auto nMGLevels = config_container[iZone]->GetnMGLevels(); + config_container[iZone]->SetMGLevels(0); + solver_container[iZone][INST_0][MESH_0][MESH_SOL]->DeformMesh(geometry_container[iZone][INST_0], numerics_container[iZone][INST_0][MESH_0][MESH_SOL], config_container[iZone]); + config_container[iZone]->SetMGLevels(nMGLevels); } } diff --git a/SU2_PY/FSI_tools/FSIInterface.py b/SU2_PY/FSI_tools/FSIInterface.py index c8d3e6bd241..21f18882d13 100644 --- a/SU2_PY/FSI_tools/FSIInterface.py +++ b/SU2_PY/FSI_tools/FSIInterface.py @@ -300,8 +300,9 @@ def connect(self, FSI_config, FluidSolver, SolidSolver): # Calculate the number of halo nodes on each partition self.nLocalFluidInterfaceHaloNode = 0 for iVertex in range(self.nLocalFluidInterfaceNodes): - if not FluidSolver.GetMarkerDomain(self.fluidInterfaceIdentifier, iVertex): - GlobalIndex = FluidSolver.GetMarkerNodes(self.fluidInterfaceIdentifier, iVertex) + iPoint = FluidSolver.GetMarkerNode(self.fluidInterfaceIdentifier, iVertex) + if not FluidSolver.GetNodeDomain(iPoint): + GlobalIndex = FluidSolver.GetNodeGlobalIndex(iPoint) self.FluidHaloNodeList[GlobalIndex] = iVertex self.nLocalFluidInterfaceHaloNode += 1 # Calculate the number of physical (= not halo) nodes on each partition @@ -565,12 +566,13 @@ def interfaceMapping(self,FluidSolver, SolidSolver, FSI_config): # Note that the fluid solver is separated in more processors outside the python script # thus when, from a core, we request for the vertices on the interface, we only obtain # those in that core - GlobalIndex = FluidSolver.GetMarkerNodes(self.fluidInterfaceIdentifier, iVertex) + iPoint = FluidSolver.GetMarkerNode(self.fluidInterfaceIdentifier, iVertex) + GlobalIndex = FluidSolver.GetNodeGlobalIndex(iPoint) if self.nDim == 2: - posx, posy = FluidSolver.GetMarkerInitialCoordinates(self.fluidInterfaceIdentifier, iVertex) + posx, posy = FluidSolver.GetInitialCoordinates(iPoint) posz = 0 else: - posx, posy, posz = FluidSolver.GetMarkerInitialCoordinates(self.fluidInterfaceIdentifier, iVertex) + posx, posy, posz = FluidSolver.GetInitialCoordinates(iPoint) if GlobalIndex not in self.FluidHaloNodeList[myid].keys(): fluidIndexing_temp[GlobalIndex] = self.__getGlobalIndex('fluid', myid, localIndex) self.localFluidInterface_array_X_init[localIndex] = posx @@ -1460,7 +1462,7 @@ def getFluidInterfaceNodalForce(self, FSI_config, FluidSolver): # --- Get the fluid interface loads from the fluid solver and directly fill the corresponding PETSc vector --- for iVertex in range(self.nLocalFluidInterfaceNodes): - GlobalIndex = FluidSolver.GetMarkerNodes(self.fluidInterfaceIdentifier, iVertex) + GlobalIndex = FluidSolver.GetNodeGlobalIndex(FluidSolver.GetMarkerNode(self.fluidInterfaceIdentifier, iVertex)) if GlobalIndex not in self.FluidHaloNodeList[myid].keys(): loadX, loadY, loadZ = FluidSolver.GetFlowLoad(self.fluidInterfaceIdentifier, iVertex) iGlobalVertex = self.__getGlobalIndex('fluid', myid, localIndex) @@ -1490,7 +1492,7 @@ def setFluidInterfaceVarCoord(self, FluidSolver): # --- Send the new fluid interface position to the fluid solver (on each partition, halo nodes included) --- localIndex = 0 for iVertex in range(self.nLocalFluidInterfaceNodes): - GlobalIndex = FluidSolver.GetMarkerNodes(self.fluidInterfaceIdentifier, iVertex) + GlobalIndex = FluidSolver.GetNodeGlobalIndex(FluidSolver.GetMarkerNode(self.fluidInterfaceIdentifier, iVertex)) if GlobalIndex in self.FluidHaloNodeList[myid].keys(): DispX, DispY, DispZ = self.haloNodesDisplacements[GlobalIndex] FluidSolver.SetMarkerDisplacements(self.fluidInterfaceIdentifier, int(iVertex), np.array([DispX, DispY, DispZ])) @@ -2151,7 +2153,7 @@ def MapModes(self, FSI_config, FluidSolver, SolidSolver): nz = 0 else: nx, ny, nz = FluidSolver.GetMarkerVertexNormals(self.fluidInterfaceIdentifier, iVertex, False) - GlobalIndex = FluidSolver.GetMarkerNodes(self.fluidInterfaceIdentifier, iVertex) + GlobalIndex = FluidSolver.GetNodeGlobalIndex(FluidSolver.GetMarkerNode(self.fluidInterfaceIdentifier, iVertex)) nodeNormals[GlobalIndex] = [nx, ny, nz] nodeNormals = self.comm.gather(nodeNormals, root=self.rootProcess) diff --git a/TestCases/py_wrapper/flatPlate_rigidMotion/launch_flatPlate_rigidMotion.py b/TestCases/py_wrapper/flatPlate_rigidMotion/launch_flatPlate_rigidMotion.py index fe28b4ac8dd..e3e05f7dcc1 100755 --- a/TestCases/py_wrapper/flatPlate_rigidMotion/launch_flatPlate_rigidMotion.py +++ b/TestCases/py_wrapper/flatPlate_rigidMotion/launch_flatPlate_rigidMotion.py @@ -87,13 +87,9 @@ def main(): # Number of vertices on the specified marker (per rank) nVertex_MovingMarker = 0 #total number of vertices (physical + halo) - nVertex_MovingMarker_HALO = 0 #number of halo vertices - nVertex_MovingMarker_PHYS = 0 #number of physical vertices if MovingMarkerID != None: - nVertex_MovingMarker = SU2Driver.GetNumberMarkerNodes(MovingMarkerID) - nVertex_MovingMarker_HALO = SU2Driver.GetNumberMarkerHaloNodes(MovingMarkerID) - nVertex_MovingMarker_PHYS = nVertex_MovingMarker - nVertex_MovingMarker_HALO + nVertex_MovingMarker = SU2Driver.GetNumberMarkerNodes(MovingMarkerID)\ # Retrieve some control parameters from the driver deltaT = SU2Driver.GetUnsteady_TimeStep() @@ -105,7 +101,8 @@ def main(): CoordX = np.zeros(nVertex_MovingMarker) CoordY = np.zeros(nVertex_MovingMarker) for iVertex in range(nVertex_MovingMarker): - CoordX[iVertex], CoordY[iVertex] = SU2Driver.GetMarkerInitialCoordinates(MovingMarkerID, iVertex) + iPoint = SU2Driver.GetMarkerNode(MovingMarkerID, iVertex) + CoordX[iVertex], CoordY[iVertex] = SU2Driver.GetInitialCoordinates(iPoint) # Time loop is defined in Python so that we have acces to SU2 functionalities at each time step if rank == 0: diff --git a/TestCases/py_wrapper/flatPlate_unsteady_CHT/launch_unsteady_CHT_FlatPlate.py b/TestCases/py_wrapper/flatPlate_unsteady_CHT/launch_unsteady_CHT_FlatPlate.py index f0e692eea73..37b8ed66914 100755 --- a/TestCases/py_wrapper/flatPlate_unsteady_CHT/launch_unsteady_CHT_FlatPlate.py +++ b/TestCases/py_wrapper/flatPlate_unsteady_CHT/launch_unsteady_CHT_FlatPlate.py @@ -86,13 +86,9 @@ def main(): # Number of vertices on the specified marker (per rank) nVertex_CHTMarker = 0 # total number of vertices (physical + halo) - nVertex_CHTMarker_HALO = 0 # number of halo vertices - nVertex_CHTMarker_PHYS = 0 # number of physical vertices if CHTMarkerID != None: nVertex_CHTMarker = SU2Driver.GetNumberMarkerNodes(CHTMarkerID) - nVertex_CHTMarker_HALO = SU2Driver.GetNumberMarkerHaloNodes(CHTMarkerID) - nVertex_CHTMarker_PHYS = nVertex_CHTMarker - nVertex_CHTMarker_HALO # Retrieve some control parameters from the driver deltaT = SU2Driver.GetUnsteady_TimeStep() diff --git a/TestCases/py_wrapper/translating_NACA0012/run_su2.py b/TestCases/py_wrapper/translating_NACA0012/run_su2.py index c8b114410ec..7d638c92b08 100644 --- a/TestCases/py_wrapper/translating_NACA0012/run_su2.py +++ b/TestCases/py_wrapper/translating_NACA0012/run_su2.py @@ -30,7 +30,7 @@ def run_solver(self): self.FluidSolver.Run() self.FluidSolver.Postprocess() # write outputs - self.FluidSolver.Monitor(0) + self.FluidSolver.Monitor(0) self.FluidSolver.Output(0) self.comm.barrier() @@ -50,7 +50,8 @@ def save_forces(self): n_vertices = self.FluidSolver.GetNumberMarkerNodes(solver_marker_id) for i_vertex in range(n_vertices): fxyz = self.FluidSolver.GetFlowLoad(solver_marker_id, i_vertex) - GlobalIndex = self.FluidSolver.GetMarkerNodes(solver_marker_id, i_vertex) + iPoint = self.FluidSolver.GetMarkerNode(solver_marker_id, i_vertex) + GlobalIndex = self.FluidSolver.GetNodeGlobalIndex(iPoint) f.write('{}, {:.2f}, {:.2f}, {:.2f}\n'.format(GlobalIndex, fxyz[0], fxyz[1], fxyz[2])) f.close() From 9965ffbb2a561d92873d71b77ed0c164115abe6c Mon Sep 17 00:00:00 2001 From: Pedro Gomes Date: Tue, 7 Feb 2023 15:32:37 -0800 Subject: [PATCH 68/68] update version numbers --- SU2_CFD/include/drivers/CDriverBase.hpp | 2 +- SU2_CFD/src/drivers/CDriverBase.cpp | 2 +- SU2_DEF/include/drivers/CDeformationDriver.hpp | 2 +- SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp | 2 +- SU2_DEF/src/drivers/CDeformationDriver.cpp | 2 +- SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/SU2_CFD/include/drivers/CDriverBase.hpp b/SU2_CFD/include/drivers/CDriverBase.hpp index ad647f12be8..132ee87ca71 100644 --- a/SU2_CFD/include/drivers/CDriverBase.hpp +++ b/SU2_CFD/include/drivers/CDriverBase.hpp @@ -2,7 +2,7 @@ * \file CDriverBase.hpp * \brief Base class for all drivers. * \author H. Patel, A. Gastaldi - * \version 7.5.0 "Blackbird" + * \version 7.5.1 "Blackbird" * * SU2 Project Website: https://su2code.github.io * diff --git a/SU2_CFD/src/drivers/CDriverBase.cpp b/SU2_CFD/src/drivers/CDriverBase.cpp index 63c6c974013..95d755c1e59 100644 --- a/SU2_CFD/src/drivers/CDriverBase.cpp +++ b/SU2_CFD/src/drivers/CDriverBase.cpp @@ -2,7 +2,7 @@ * \file CDriverBase.hpp * \brief Base class template for all drivers. * \author H. Patel, A. Gastaldi - * \version 7.5.0 "Blackbird" + * \version 7.5.1 "Blackbird" * * SU2 Project Website: https://su2code.github.io * diff --git a/SU2_DEF/include/drivers/CDeformationDriver.hpp b/SU2_DEF/include/drivers/CDeformationDriver.hpp index ecc8b46c5cb..a562a07c1a5 100644 --- a/SU2_DEF/include/drivers/CDeformationDriver.hpp +++ b/SU2_DEF/include/drivers/CDeformationDriver.hpp @@ -2,7 +2,7 @@ * \file CDeformationDriver.hpp * \brief Headers of the main subroutines for driving the mesh deformation. * \author A. Gastaldi, H. Patel - * \version 7.5.0 "Blackbird" + * \version 7.5.1 "Blackbird" * * SU2 Project Website: https://su2code.github.io * diff --git a/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp b/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp index ce6ed37f4c5..6b28f072b98 100644 --- a/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp +++ b/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp @@ -2,7 +2,7 @@ * \file CDiscAdjDeformationDriver.cpp * \brief Headers of the main subroutines for driving the projection of sensitivities. * \author T. Economon, H. Kline, R. Sanchez, A. Gastaldi, H. Patel - * \version 7.5.0 "Blackbird" + * \version 7.5.1 "Blackbird" * * SU2 Project Website: https://su2code.github.io * diff --git a/SU2_DEF/src/drivers/CDeformationDriver.cpp b/SU2_DEF/src/drivers/CDeformationDriver.cpp index b064aaf8d62..856450217c2 100644 --- a/SU2_DEF/src/drivers/CDeformationDriver.cpp +++ b/SU2_DEF/src/drivers/CDeformationDriver.cpp @@ -2,7 +2,7 @@ * \file CDeformationDriver.cpp * \brief Main subroutines for driving the mesh deformation. * \author A. Gastaldi, H. Patel - * \version 7.5.0 "Blackbird" + * \version 7.5.1 "Blackbird" * * SU2 Project Website: https://su2code.github.io * diff --git a/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp b/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp index 05d57465390..25ae73f9abd 100644 --- a/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp +++ b/SU2_DEF/src/drivers/CDiscAdjDeformationDriver.cpp @@ -2,7 +2,7 @@ * \file CDiscAdjDeformationDriver.cpp * \brief Main subroutines for driving the projection of sensitivities. * \author T. Economon, H. Kline, R. Sanchez, A. Gastaldi, H. Patel - * \version 7.5.0 "Blackbird" + * \version 7.5.1 "Blackbird" * * SU2 Project Website: https://su2code.github.io *