diff --git a/Common/include/CConfig.hpp b/Common/include/CConfig.hpp index 717bb443a49d..b5a5556bf41f 100644 --- a/Common/include/CConfig.hpp +++ b/Common/include/CConfig.hpp @@ -716,6 +716,7 @@ class CConfig { unsigned short Geo_Description; /*!< \brief Description of the geometry. */ unsigned short Mesh_FileFormat; /*!< \brief Mesh input format. */ unsigned short Tab_FileFormat; /*!< \brief Format of the output files. */ + unsigned short output_precision; /*!< \brief .precision(value) for SU2_DOT and HISTORY output */ unsigned short ActDisk_Jump; /*!< \brief Format of the output files. */ unsigned long StartWindowIteration; /*!< \brief Starting Iteration for long time Windowing apporach . */ unsigned short nCFL_AdaptParam; /*!< \brief Number of CFL parameters provided in config. */ @@ -994,6 +995,13 @@ class CConfig { array mu_polycoeffs{{0.0}}; /*!< \brief Array for viscosity polynomial coefficients. */ array kt_polycoeffs{{0.0}}; /*!< \brief Array for thermal conductivity polynomial coefficients. */ bool Body_Force; /*!< \brief Flag to know if a body force is included in the formulation. */ + + unsigned short Kind_Streamwise_Periodic; /*!< \brief Kind of Streamwise periodic flow (pressure drop or massflow) */ + bool Streamwise_Periodic_Temperature; /*!< \brief Use real periodicity for Energy equation or otherwise outlet source term. */ + su2double Streamwise_Periodic_PressureDrop; /*!< \brief Value of prescribed pressure drop [Pa] which results in an artificial body force vector. */ + su2double Streamwise_Periodic_TargetMassFlow; /*!< \brief Value of prescribed massflow [kg/s] which results in an delta p and therefore an artificial body force vector. */ + su2double Streamwise_Periodic_OutletHeat; /*!< /brief Heatflux boundary [W/m^2] imposed at streamwise periodic outlet. */ + su2double *FreeStreamTurboNormal; /*!< \brief Direction to initialize the flow in turbomachinery computation */ su2double Restart_Bandwidth_Agg; /*!< \brief The aggregate of the bandwidth for writing binary restarts (to be averaged later). */ su2double Max_Vel2; /*!< \brief The maximum velocity^2 in the domain for the incompressible preconditioner. */ @@ -2786,7 +2794,7 @@ class CConfig { const su2double *GetWeightsIntegrationADER_DG(void) const { return WeightsIntegrationADER_DG; } /*! - * \brief Get the total number of boundary markers including send/receive domains. + * \brief Get the total number of boundary markers of the local process including send/receive domains. * \return Total number of boundary markers. */ unsigned short GetnMarker_All(void) const { return nMarker_All; } @@ -2810,7 +2818,7 @@ class CConfig { unsigned short GetnMarker_SymWall(void) const { return nMarker_SymWall; } /*! - * \brief Get the total number of boundary markers. + * \brief Get the total number of boundary markers in the cfg plus the possible send/receive domains. * \return Total number of boundary markers. */ unsigned short GetnMarker_Max(void) const { return nMarker_Max; } @@ -2906,7 +2914,7 @@ class CConfig { unsigned short GetnMarker_Periodic(void) const { return nMarker_PerBound; } /*! - * \brief Get the total number of heat flux markers. + * \brief Get the total (local) number of heat flux markers. * \return Total number of heat flux markers. */ unsigned short GetnMarker_HeatFlux(void) const { return nMarker_HeatFlux; } @@ -5170,6 +5178,12 @@ class CConfig { */ unsigned short GetTabular_FileFormat(void) const { return Tab_FileFormat; } + /*! + * \brief Get the output precision to be used in .precision(value) for history and SU2_DOT output. + * \return Output precision. + */ + unsigned short GetOutput_Precision(void) const { return output_precision; } + /*! * \brief Get the format of the output solution. * \return Format of the output solution. @@ -5729,6 +5743,36 @@ class CConfig { */ const su2double* GetBody_Force_Vector(void) const { return body_force; } + /*! + * \brief Get information about the streamwise periodicity (None, Pressure_Drop, Massflow). + * \return Driving force identification. + */ + unsigned short GetKind_Streamwise_Periodic(void) const { return Kind_Streamwise_Periodic; } + + /*! + * \brief Get information about the streamwise periodicity Energy equation handling. + * \return Real periodic treatment of energy equation. + */ + bool GetStreamwise_Periodic_Temperature(void) const { return Streamwise_Periodic_Temperature; } + + /*! + * \brief Get the value of the artificial periodic outlet heat. + * \return Heat value. + */ + su2double GetStreamwise_Periodic_OutletHeat(void) const { return Streamwise_Periodic_OutletHeat; } + + /*! + * \brief Get the value of the pressure delta from which body force vector is computed. + * \return Delta Pressure for body force computation. + */ + su2double GetStreamwise_Periodic_PressureDrop(void) const { return Streamwise_Periodic_PressureDrop; } + + /*! + * \brief Get the value of the massflow from which body force vector is computed. + * \return Massflow for body force computation. + */ + su2double GetStreamwise_Periodic_TargetMassFlow(void) const { return Streamwise_Periodic_TargetMassFlow; } + /*! * \brief Get information about the volumetric heat source. * \return TRUE if it uses a volumetric heat source; otherwise FALSE. @@ -6147,10 +6191,17 @@ class CConfig { const su2double *GetPeriodicRotAngles(string val_marker) const; /*! - * \brief Translation vector for a rotational periodic boundary. + * \brief Translation vector for a translational periodic boundary. */ const su2double *GetPeriodicTranslation(string val_marker) const; + /*! + * \brief Get the translation vector for a periodic transformation. + * \param[in] val_index - Index corresponding to the periodic transformation. + * \return The translation vector. + */ + const su2double* GetPeriodic_Translation(unsigned short val_index ) const { return Periodic_Translation[val_index]; } + /*! * \brief Get the rotationally periodic donor marker for boundary val_marker. * \return Periodic donor marker from the config information for the marker val_marker. diff --git a/Common/include/geometry/CGeometry.hpp b/Common/include/geometry/CGeometry.hpp index 8a4c89922856..a01e376deed3 100644 --- a/Common/include/geometry/CGeometry.hpp +++ b/Common/include/geometry/CGeometry.hpp @@ -1711,5 +1711,17 @@ class CGeometry { * \param[out] nNonconvexElements- amount of nonconvex elements in the mesh */ unsigned long GetnNonconvexElements() const {return nNonconvexElements;} + + /*! + * \brief For streamwise periodicity, find & store a unique reference node on the designated periodic inlet. + * \param[in] config - Definition of the particular problem. + */ + inline virtual void FindUniqueNode_PeriodicBound(const CConfig *config) {} + + /*! + * \brief Get a pointer to the reference node coordinate vector. + * \return A pointer to the reference node coordinate vector. + */ + inline virtual const su2double* GetStreamwise_Periodic_RefNode(void) const { return nullptr; } }; diff --git a/Common/include/geometry/CPhysicalGeometry.hpp b/Common/include/geometry/CPhysicalGeometry.hpp index 57bd79fba77d..55cbd8713025 100644 --- a/Common/include/geometry/CPhysicalGeometry.hpp +++ b/Common/include/geometry/CPhysicalGeometry.hpp @@ -107,6 +107,8 @@ class CPhysicalGeometry final : public CGeometry { vector GlobalMarkerStorageDispl; vector GlobalRoughness_Height; + su2double Streamwise_Periodic_RefNode[MAXNDIM] = {0}; /*!< \brief Coordinates of the reference node [m] on the receiving periodic marker, for recovered pressure/temperature computation only.*/ + public: /*--- This is to suppress Woverloaded-virtual, omitting it has no negative impact. ---*/ using CGeometry::SetVertex; @@ -784,4 +786,15 @@ class CPhysicalGeometry final : public CGeometry { */ void SetGlobalMarkerRoughness(const CConfig* config); + /*! + * \brief For streamwise periodicity, find & store a unique reference node on the designated periodic inlet. + * \param[in] config - Definition of the particular problem. + */ + void FindUniqueNode_PeriodicBound(const CConfig *config) final; + + /*! + * \brief Get a pointer to the reference node coordinate vector. + * \return A pointer to the reference node coordinate vector. + */ + inline const su2double* GetStreamwise_Periodic_RefNode(void) const final { return Streamwise_Periodic_RefNode;} }; diff --git a/Common/include/option_structure.hpp b/Common/include/option_structure.hpp index 1fdaa01b8b64..52aa9e2a0079 100644 --- a/Common/include/option_structure.hpp +++ b/Common/include/option_structure.hpp @@ -2256,6 +2256,30 @@ static const MapType Verification_Solution_ MakePair("USER_DEFINED_SOLUTION", USER_DEFINED_SOLUTION) }; +/*! + * \brief Types of streamwise periodicity. + */ +enum ENUM_STREAMWISE_PERIODIC { + NO_STREAMWISE_PERIODIC = 0, /*!< \brief No streamwise periodic flow. */ + PRESSURE_DROP = 1, /*!< \brief Prescribed pressure drop. */ + STREAMWISE_MASSFLOW = 2, /*!< \brief Prescribed massflow. */ +}; +static const MapType Streamwise_Periodic_Map = { + MakePair("NONE", NO_STREAMWISE_PERIODIC) + MakePair("PRESSURE_DROP", PRESSURE_DROP) + MakePair("MASSFLOW", STREAMWISE_MASSFLOW) +}; + +/*! + * \brief Container to hold Variables for streamwise Periodic flow as they are often used together in places. + */ +struct StreamwisePeriodicValues { + su2double Streamwise_Periodic_PressureDrop; /*!< \brief Value of prescribed pressure drop [Pa] which results in an artificial body force vector. */ + su2double Streamwise_Periodic_MassFlow; /*!< \brief Value of current massflow [kg/s] which results in a delta p and therefore an artificial body force vector. */ + su2double Streamwise_Periodic_IntegratedHeatFlow; /*!< \brief Value of of the net sum of heatflow [W] into the domain. */ + su2double Streamwise_Periodic_InletTemperature; /*!< \brief Area avg static Temp [K] at the periodic inlet. Used for adaptive outlet heatsink. */ +}; + #undef MakePair /* END_CONFIG_ENUMS */ diff --git a/Common/src/CConfig.cpp b/Common/src/CConfig.cpp index eddd0d68918f..5ae576f72d09 100644 --- a/Common/src/CConfig.cpp +++ b/Common/src/CConfig.cpp @@ -1104,6 +1104,18 @@ void CConfig::SetConfig_Options() { body_force[0] = 0.0; body_force[1] = 0.0; body_force[2] = 0.0; /* DESCRIPTION: Vector of body force values (BodyForce_X, BodyForce_Y, BodyForce_Z) */ addDoubleArrayOption("BODY_FORCE_VECTOR", 3, body_force); + + /* DESCRIPTION: Apply a body force as a source term for periodic boundary conditions \n Options: NONE, PRESSURE_DROP, MASSFLOW \n DEFAULT: NONE \ingroup Config */ + addEnumOption("KIND_STREAMWISE_PERIODIC", Kind_Streamwise_Periodic, Streamwise_Periodic_Map, NO_STREAMWISE_PERIODIC); + /* DESCRIPTION: Use real periodicity for temperature \n Options: NO, YES \n DEFAULT: NO \ingroup Config */ + addBoolOption("STREAMWISE_PERIODIC_TEMPERATURE", Streamwise_Periodic_Temperature, false); + /* DESCRIPTION: Heatflux boundary at streamwise periodic 'outlet', choose heat [W] such that net domain heatflux is zero. Only active if STREAMWISE_PERIODIC_TEMPERATURE is active. \n DEFAULT: 0.0 \ingroup Config */ + addDoubleOption("STREAMWISE_PERIODIC_OUTLET_HEAT", Streamwise_Periodic_OutletHeat, 0.0); + /* DESCRIPTION: Delta pressure [Pa] on which basis body force will be computed, serves as initial value if MASSFLOW is chosen. \n DEFAULT: 1.0 \ingroup Config */ + addDoubleOption("STREAMWISE_PERIODIC_PRESSURE_DROP", Streamwise_Periodic_PressureDrop, 1.0); + /* DESCRIPTION: Target Massflow [kg/s], Delta P will be adapted until m_dot is met. \n DEFAULT: 0.0 \ingroup Config */ + addDoubleOption("STREAMWISE_PERIODIC_MASSFLOW", Streamwise_Periodic_TargetMassFlow, 0.0); + /*!\brief RESTART_SOL \n DESCRIPTION: Restart solution from native solution file \n Options: NO, YES \ingroup Config */ addBoolOption("RESTART_SOL", Restart, false); /*!\brief BINARY_RESTART \n DESCRIPTION: Read binary SU2 native restart files. \n Options: YES, NO \ingroup Config */ @@ -1924,6 +1936,8 @@ void CConfig::SetConfig_Options() { /*!\brief OUTPUT_FORMAT \n DESCRIPTION: I/O format for output plots. \n OPTIONS: see \link TabOutput_Map \endlink \n DEFAULT: TECPLOT \ingroup Config */ addEnumOption("TABULAR_FORMAT", Tab_FileFormat, TabOutput_Map, TAB_CSV); + /*!\brief OUTPUT_PRECISION \n DESCRIPTION: Set .precision(value) to specified value for SU2_DOT and HISTORY output. Useful for exact gradient validation. \n DEFAULT: 6 \ingroup Config */ + addUnsignedShortOption("OUTPUT_PRECISION", output_precision, 10); /*!\brief ACTDISK_JUMP \n DESCRIPTION: The jump is given by the difference in values or a ratio */ addEnumOption("ACTDISK_JUMP", ActDisk_Jump, Jump_Map, DIFFERENCE); /*!\brief MESH_FORMAT \n DESCRIPTION: Mesh input file format \n OPTIONS: see \link Input_Map \endlink \n DEFAULT: SU2 \ingroup Config*/ @@ -2253,7 +2267,7 @@ void CConfig::SetConfig_Options() { addDoubleOption("REFERENCE_GEOMETRY_PENALTY", RefGeom_Penalty, 1E6); /*!\brief REFERENCE_GEOMETRY_FILENAME \n DESCRIPTION: Reference geometry filename \n Default: reference_geometry.dat \ingroup Config */ addStringOption("REFERENCE_GEOMETRY_FILENAME", RefGeom_FEMFileName, string("reference_geometry.dat")); - /*!\brief REFERENCE_GEOMETRY_FORMAT \n DESCRIPTION: Reference geometry format \n DEFAULT: SU2 \ingroup Config*/ + /*!\brief REFERENCE_GEOMETRY_FORMAT \n DESCRIPTION: Format of the reference geometry file \n OPTIONS: see \link Input_Ref_Map \endlink \n DEFAULT: SU2 \ingroup Config*/ addEnumOption("REFERENCE_GEOMETRY_FORMAT", RefGeom_FileFormat, Input_Ref_Map, SU2_REF); /*!\brief REFERENCE_GEOMETRY_SURFACE\n DESCRIPTION: If true consider only the surfaces where loads are applied. \ingroup Config*/ addBoolOption("REFERENCE_GEOMETRY_SURFACE", RefGeomSurf, false); @@ -4585,6 +4599,28 @@ void CConfig::SetPostprocessing(unsigned short val_software, unsigned short val_ SU2_MPI::Error("Must list two markers for the pressure drop objective function.\n Expected format: MARKER_ANALYZE= (outlet_name, inlet_name).", CURRENT_FUNCTION); } } + + /*--- Check feassbility for Streamwise Periodic flow ---*/ + if (Kind_Streamwise_Periodic != NONE) { + if (Kind_Regime != INCOMPRESSIBLE) + SU2_MPI::Error("Streamwise Periodic Flow currently only implemented for incompressible flow.", CURRENT_FUNCTION); + if (Kind_Solver == INC_EULER) + SU2_MPI::Error("Streamwise Periodic Flow + Incompressible Euler: Not tested yet.", CURRENT_FUNCTION); + if (nMarker_PerBound != 2) + SU2_MPI::Error("Streamwise Periodic Flow currently only implemented for one Periodic Marker pair. Combining Streamwise and Spanwise periodicity not possible in the moment.", CURRENT_FUNCTION); + if (Energy_Equation && Streamwise_Periodic_Temperature && nMarker_Isothermal != 0) + SU2_MPI::Error("No MARKER_ISOTHERMAL marker allowed with STREAMWISE_PERIODIC_TEMPERATURE= YES, only MARKER_HEATFLUX & MARKER_SYM.", CURRENT_FUNCTION); + if (DiscreteAdjoint && Kind_Streamwise_Periodic == MASSFLOW) + SU2_MPI::Error("Discrete Adjoint currently not validated for prescribed MASSFLOW.", CURRENT_FUNCTION); + if (Ref_Inc_NonDim != DIMENSIONAL) + SU2_MPI::Error("Streamwise Periodicity only works with \"INC_NONDIM= DIMENSIONAL\", the nondimensionalization with source terms doesn;t work in general.", CURRENT_FUNCTION); + if (Axisymmetric) + SU2_MPI::Error("Streamwise Periodicity terms does not not have axisymmetric corrections.", CURRENT_FUNCTION); + if (!Energy_Equation) Streamwise_Periodic_Temperature = false; + } else { + /*--- Safety measure ---*/ + Streamwise_Periodic_Temperature = false; + } /*--- Check that if the wall roughness array are compatible and set deafult values if needed. ---*/ if ((nMarker_HeatFlux > 0) || (nMarker_Isothermal > 0) || (nMarker_CHTInterface > 0)) { diff --git a/Common/src/geometry/CPhysicalGeometry.cpp b/Common/src/geometry/CPhysicalGeometry.cpp index 31a5ca91321b..c1021d38a142 100644 --- a/Common/src/geometry/CPhysicalGeometry.cpp +++ b/Common/src/geometry/CPhysicalGeometry.cpp @@ -7456,6 +7456,99 @@ void CPhysicalGeometry::MatchPeriodic(CConfig *config, delete [] Buffer_Recv_GlobalIndex; delete [] Buffer_Recv_Vertex; delete [] Buffer_Recv_Marker; +} + +void CPhysicalGeometry::FindUniqueNode_PeriodicBound(const CConfig *config) { + + /*-------------------------------------------------------------------------------------------*/ + /*--- Find reference node on the 'inlet' streamwise periodic marker for the computation ---*/ + /*--- of recovered pressure/temperature, such that this found node is independent of the ---*/ + /*--- number of ranks. This does not affect the 'correctness' of the solution as the ---*/ + /*--- absolute value is arbitrary anyway, but it assures that the solution does not change---*/ + /*--- with a higher number of ranks. If the periodic markers are a line\plane and the ---*/ + /*--- streamwise coordinate vector is perpendicular to that |--->|, the choice of the ---*/ + /*--- reference node is not relevant at all. This is probably true for most streamwise ---*/ + /*--- periodic cases. Other cases where it is relevant could look like this (--->( or ---*/ + /*--- \--->\ . The chosen metric is the minimal distance to the origin. ---*/ + /*-------------------------------------------------------------------------------------------*/ + + /*--- Initialize/Allocate variables. ---*/ + su2double min_norm = numeric_limits::max(); + + /*--- Communicate Coordinates plus the minimum distance, therefor the nDim+1 ---*/ + vector Buffer_Send_RefNode(nDim+1, numeric_limits::max()); + su2activematrix Buffer_Recv_RefNode(size,nDim+1); + unsigned long iPointMin = 0; // Initialisaton, otherwise 'may be uninitialized` warning' + + /*-------------------------------------------------------------------------------------------*/ + /*--- Step 1: Find a unique reference node on each rank and communicate them such that ---*/ + /*--- each process has the local ref-nodes from every process. Most processes ---*/ + /*--- won't have a boundary with the streamwise periodic 'inlet' marker, ---*/ + /*--- therefore the default value of the send value is set super high. ---*/ + /*-------------------------------------------------------------------------------------------*/ + + for (unsigned short iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { + if (config->GetMarker_All_KindBC(iMarker) == PERIODIC_BOUNDARY) { + + /*--- 1 is the receiver/'inlet', 2 is the donor/'outlet', 0 if no PBC at all. ---*/ + auto iPeriodic = config->GetMarker_All_PerBound(iMarker); + if (iPeriodic == 1) { + + for (auto iVertex = 0ul; iVertex < GetnVertex(iMarker); iVertex++) { + + auto iPoint = vertex[iMarker][iVertex]->GetNode(); + + /*--- Get the squared norm of the current point. sqrt is a monotonic function in [0,R+) so for comparison we dont need Norm. ---*/ + auto norm = GeometryToolbox::SquaredNorm(nDim, nodes->GetCoord(iPoint)); + + /*--- Check if new unique reference node is found and store Point ID. ---*/ + if (norm < min_norm) { + min_norm = norm; + iPointMin = iPoint; + } + /*--- The theoretical case, that multiple inlet points with the same distance to the origin exists, remains. ---*/ + } + break; // Actually no more than one streamwise periodic marker pair is allowed + } // receiver conditional + } // periodic conditional + } // marker loop + + /*--- Copy the Coordinates and norm into send buffer. ---*/ + for (unsigned short iDim = 0; iDim < nDim; iDim++) + Buffer_Send_RefNode[iDim] = nodes->GetCoord(iPointMin,iDim); + Buffer_Send_RefNode[nDim] = min_norm; + + /*--- Communicate unique nodes to all processes. In case of serial mode nothing happens. ---*/ + SU2_MPI::Allgather(Buffer_Send_RefNode.data(), nDim+1, MPI_DOUBLE, + Buffer_Recv_RefNode.data(), nDim+1, MPI_DOUBLE, SU2_MPI::GetComm()); + + /*-------------------------------------------------------------------------------------------*/ + /*--- Step 2: Amongst all local nodes with the smallest distance to the origin, find the ---*/ + /*--- globally closest to the origin. Store the found node coordinates in the ---*/ + /*--- geometry container. ---*/ + /*-------------------------------------------------------------------------------------------*/ + + min_norm = numeric_limits::max(); + + for (int iRank = 0; iRank < size; iRank++) { + + auto norm = Buffer_Recv_RefNode(iRank,nDim); + + /*--- Check if new unique reference node is found. ---*/ + if (norm < min_norm) { + min_norm = norm; + for (unsigned short iDim = 0; iDim < nDim; iDim++) + Streamwise_Periodic_RefNode[iDim] = Buffer_Recv_RefNode(iRank,iDim); + } + } + + /*--- Print the reference node to screen. ---*/ + if (rank == MASTER_NODE) { + cout << "Streamwise Periodic Reference Node: ["; + for (unsigned short iDim = 0; iDim < nDim; iDim++) + cout << " " << Streamwise_Periodic_RefNode[iDim]; + cout << " ]" << endl; + } } diff --git a/Common/src/grid_movement/CVolumetricMovement.cpp b/Common/src/grid_movement/CVolumetricMovement.cpp index e1790682b949..b0dd11cf8ec6 100644 --- a/Common/src/grid_movement/CVolumetricMovement.cpp +++ b/Common/src/grid_movement/CVolumetricMovement.cpp @@ -1641,7 +1641,7 @@ void CVolumetricMovement::SetBoundaryDisplacements(CGeometry *geometry, CConfig VarIncrement = 1.0/((su2double)config->GetGridDef_Nonlinear_Iter()); /*--- As initialization, set to zero displacements of all the surfaces except the symmetry - plane, internal and periodic bc the receive boundaries and periodic boundaries. ---*/ + plane (which is treated specially, see below), internal and the send-receive boundaries ---*/ for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { if (((config->GetMarker_All_KindBC(iMarker) != SYMMETRY_PLANE) && diff --git a/SU2_CFD/include/numerics/CNumerics.hpp b/SU2_CFD/include/numerics/CNumerics.hpp index 2e0704e76079..ef0172750f59 100644 --- a/SU2_CFD/include/numerics/CNumerics.hpp +++ b/SU2_CFD/include/numerics/CNumerics.hpp @@ -82,6 +82,9 @@ class CNumerics { Thermal_Diffusivity_i, /*!< \brief Thermal diffusivity at point i. */ Thermal_Diffusivity_j; /*!< \brief Thermal diffusivity at point j. */ su2double + SpecificHeat_i, /*!< \brief Specific heat c_p at point j. */ + SpecificHeat_j; /*!< \brief Specific heat c_p at point j. */ + su2double Cp_i, /*!< \brief Cp at point i. */ Cp_j; /*!< \brief Cp at point j. */ su2double @@ -751,6 +754,17 @@ class CNumerics { Thermal_Diffusivity_j = val_thermal_diffusivity_j; } + /*! + * \brief Set the specifc heat c_p. + * \param[in] val_specific_heat_i - Value of the specific heat at point i. + * \param[in] val_specific_heat_j - Value of the specific heat at point j. + */ + inline void SetSpecificHeat(su2double val_specific_heat_i, + su2double val_specific_heat_j) { + SpecificHeat_i = val_specific_heat_i; + SpecificHeat_j = val_specific_heat_j; + } + /*! * \brief Set the eddy viscosity. * \param[in] val_eddy_viscosity_i - Value of the eddy viscosity at point i. @@ -1590,6 +1604,11 @@ class CNumerics { */ virtual inline void SetGamma(su2double val_Gamma_i, su2double val_Gamma_j) { } + /*! + * \brief Set massflow, heatflow & inlet temperature for streamwise periodic flow. + * \param[in] SolverSPvals - Struct holding the values. + */ + virtual void SetStreamwisePeriodicValues(const StreamwisePeriodicValues SolverSPvals) { } }; /*! diff --git a/SU2_CFD/include/numerics/flow/flow_sources.hpp b/SU2_CFD/include/numerics/flow/flow_sources.hpp index 38df4d2e432f..2f5d7275facf 100644 --- a/SU2_CFD/include/numerics/flow/flow_sources.hpp +++ b/SU2_CFD/include/numerics/flow/flow_sources.hpp @@ -40,6 +40,7 @@ class CSourceBase_Flow : public CNumerics { protected: su2double* residual = nullptr; su2double** jacobian = nullptr; + struct StreamwisePeriodicValues SPvals; /*! * \brief Constructor of the class. @@ -55,6 +56,12 @@ class CSourceBase_Flow : public CNumerics { */ ~CSourceBase_Flow() override; + /*! + * \brief Set massflow, heatflow & inlet temperature for streamwise periodic flow. + * \param[in] SolverSPvals - Struct holding the values. + */ + void SetStreamwisePeriodicValues(const StreamwisePeriodicValues SolverSPvals) final { SPvals = SolverSPvals; } + }; /*! @@ -226,6 +233,8 @@ class CSourceBoussinesq final : public CSourceBase_Flow { * \author F. Palacios */ class CSourceGravity final : public CSourceBase_Flow { + su2double Force_Ref; + public: /*! * \param[in] val_nDim - Number of dimensions of the problem. @@ -323,21 +332,83 @@ class CSourceWindGust final : public CSourceBase_Flow { }; /*! - * \class CSourceRadiation - * \brief Class for a source term due to radiation. + * \class CSourceIncStreamwise_Periodic + * \brief Class for the source term integration of a streamwise periodic body force in the incompressible solver. * \ingroup SourceDiscr - * \author Ruben Sanchez + * \author T. Kattmann */ -class CSourceRadiation : public CSourceBase_Flow { +class CSourceIncStreamwise_Periodic final : public CSourceBase_Flow { private: - bool implicit; + bool turbulent; /*!< \brief Turbulence model used. */ + bool energy; /*!< \brief Energy equation on. */ + bool streamwisePeriodic_temperature; /*!< \brief Periodicity in energy equation */ + su2double Streamwise_Coord_Vector[MAXNDIM] = {0.0}; /*!< \brief Translation vector between streamwise periodic surfaces. */ + + su2double norm2_translation, /*!< \brief Square of distance between the 2 periodic surfaces. */ + dot_product, /*!< \brief Container for various dot-products. */ + scalar_factor; /*!< \brief Holds scalar factors to simplify final equations. */ + +public: + + /*! + * \brief Constructor of the class. + * \param[in] val_nDim - Number of dimensions of the problem. + * \param[in] val_nVar - Number of variables of the problem. + * \param[in] config - Definition of the particular problem. + */ + CSourceIncStreamwise_Periodic(unsigned short val_nDim, + unsigned short val_nVar, + CConfig *config); + + /*! + * \brief Source term integration for a body force. + * \param[in] config - Definition of the particular problem. + */ + ResidualType<> ComputeResidual(const CConfig *config) override; + +}; + +/*! + * \class CSourceIncStreamwisePeriodic_Outlet + * \brief Class for the outlet heat sink. Acts like a heatflux boundary on the outlet and not as a volume source. + * \ingroup SourceDiscr + * \author T. Kattmann + */ +class CSourceIncStreamwisePeriodic_Outlet : public CSourceBase_Flow { public: + /*! + * \brief Constructor of the class. * \param[in] val_nDim - Number of dimensions of the problem. * \param[in] val_nVar - Number of variables of the problem. * \param[in] config - Definition of the particular problem. */ + CSourceIncStreamwisePeriodic_Outlet(unsigned short val_nDim, + unsigned short val_nVar, + CConfig *config); + + /*! + * \brief Source term integration for boundary heat sink. + * \param[in] config - Definition of the particular problem. + */ + ResidualType<> ComputeResidual(const CConfig *config) override; + +}; + + +/*! + * \class CSourceRadiation + * \brief Class for a source term due to radiation. + * \ingroup SourceDiscr + * \author Ruben Sanchez + */ +class CSourceRadiation : public CSourceBase_Flow { +private: + bool implicit; + +public: + CSourceRadiation(unsigned short val_nDim, unsigned short val_nVar, const CConfig *config); /*! diff --git a/SU2_CFD/include/output/CFlowIncOutput.hpp b/SU2_CFD/include/output/CFlowIncOutput.hpp index 031343180017..59896cb0eea0 100644 --- a/SU2_CFD/include/output/CFlowIncOutput.hpp +++ b/SU2_CFD/include/output/CFlowIncOutput.hpp @@ -42,6 +42,8 @@ class CFlowIncOutput final: public CFlowOutput { unsigned short turb_model; /*!< \brief The kind of turbulence model*/ bool heat; /*!< \brief Boolean indicating whether have a heat problem*/ bool weakly_coupled_heat; /*!< \brief Boolean indicating whether have a weakly coupled heat equation*/ + unsigned short streamwisePeriodic; /*!< \brief Boolean indicating whether it is a streamwise periodic simulation. */ + bool streamwisePeriodic_temperature; /*!< \brief Boolean indicating streamwise periodic temperature is used. */ public: diff --git a/SU2_CFD/include/solvers/CIncEulerSolver.hpp b/SU2_CFD/include/solvers/CIncEulerSolver.hpp index f8f7e1ad35d6..796d409d4381 100644 --- a/SU2_CFD/include/solvers/CIncEulerSolver.hpp +++ b/SU2_CFD/include/solvers/CIncEulerSolver.hpp @@ -39,6 +39,7 @@ class CIncEulerSolver : public CFVMFlowSolverBase { protected: vector FluidModel; /*!< \brief fluid model used in the solver. */ + StreamwisePeriodicValues SPvals; /*! * \brief Preprocessing actions common to the Euler and NS solvers. @@ -385,4 +386,9 @@ class CIncEulerSolver : public CFVMFlowSolverBaseMatchPeriodic(config, iPeriodic); } + /*--- For Streamwise Periodic flow, find a unique reference node on the dedicated inlet marker. ---*/ + if (config->GetKind_Streamwise_Periodic() != NONE) + geometry[iMesh]->FindUniqueNode_PeriodicBound(config); + /*--- Initialize the communication framework for the periodic BCs. ---*/ geometry[iMesh]->PreprocessPeriodicComms(geometry[iMesh], config); @@ -1830,6 +1834,9 @@ void CDriver::Numerics_Preprocessing(CConfig *config, CGeometry **geometry, CSol else numerics[iMGlevel][FLOW_SOL][source_first_term] = new CSourceBodyForce(nDim, nVar_Flow, config); } + else if (incompressible && (config->GetKind_Streamwise_Periodic() != NONE)) { + numerics[iMGlevel][FLOW_SOL][source_first_term] = new CSourceIncStreamwise_Periodic(nDim, nVar_Flow, config); + } else if (incompressible && (config->GetKind_DensityModel() == BOUSSINESQ)) { numerics[iMGlevel][FLOW_SOL][source_first_term] = new CSourceBoussinesq(nDim, nVar_Flow, config); } @@ -1860,6 +1867,9 @@ void CDriver::Numerics_Preprocessing(CConfig *config, CGeometry **geometry, CSol /*--- 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() != 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); } diff --git a/SU2_CFD/src/numerics/flow/flow_sources.cpp b/SU2_CFD/src/numerics/flow/flow_sources.cpp index 2309c2f90457..b95e176eb6e5 100644 --- a/SU2_CFD/src/numerics/flow/flow_sources.cpp +++ b/SU2_CFD/src/numerics/flow/flow_sources.cpp @@ -27,6 +27,7 @@ */ #include "../../../include/numerics/flow/flow_sources.hpp" +#include "../../../../Common/include/toolboxes/geometry_toolbox.hpp" CSourceBase_Flow::CSourceBase_Flow(unsigned short val_nDim, unsigned short val_nVar, const CConfig* config) : CNumerics(val_nDim, val_nVar, config) { @@ -469,7 +470,9 @@ CNumerics::ResidualType<> CSourceBoussinesq::ComputeResidual(const CConfig* conf } CSourceGravity::CSourceGravity(unsigned short val_nDim, unsigned short val_nVar, const CConfig* config) : - CSourceBase_Flow(val_nDim, val_nVar, config) { } + CSourceBase_Flow(val_nDim, val_nVar, config) { + Force_Ref = config->GetForce_Ref(); + } CNumerics::ResidualType<> CSourceGravity::ComputeResidual(const CConfig* config) { @@ -479,7 +482,7 @@ CNumerics::ResidualType<> CSourceGravity::ComputeResidual(const CConfig* config) residual[iVar] = 0.0; /*--- Evaluate the source term ---*/ - residual[nDim] = Volume * U_i[0] * STANDARD_GRAVITY; + residual[nDim] = Volume * U_i[0] * STANDARD_GRAVITY / Force_Ref; return ResidualType<>(residual, jacobian, nullptr); } @@ -668,6 +671,94 @@ CNumerics::ResidualType<> CSourceWindGust::ComputeResidual(const CConfig* config return ResidualType<>(residual, jacobian, nullptr); } + +CSourceIncStreamwise_Periodic::CSourceIncStreamwise_Periodic(unsigned short val_nDim, + unsigned short val_nVar, + CConfig *config) : + CSourceBase_Flow(val_nDim, val_nVar, config) { + + turbulent = (config->GetKind_Turb_Model() != NONE); + energy = config->GetEnergy_Equation(); + streamwisePeriodic_temperature = config->GetStreamwise_Periodic_Temperature(); + + for (unsigned short iDim = 0; iDim < nDim; iDim++) + Streamwise_Coord_Vector[iDim] = config->GetPeriodic_Translation(0)[iDim]; + + /*--- Compute square of the distance between the 2 periodic surfaces via inner product with itself: + dot_prod(t*t) = (|t|_2)^2 ---*/ + norm2_translation = GeometryToolbox::SquaredNorm(nDim, Streamwise_Coord_Vector); + +} + +CNumerics::ResidualType<> CSourceIncStreamwise_Periodic::ComputeResidual(const CConfig *config) { + + /* Value of prescribed pressure drop which results in an artificial body force vector. */ + const su2double delta_p = SPvals.Streamwise_Periodic_PressureDrop; + + for (unsigned short iVar = 0; iVar < nVar; iVar++) residual[iVar] = 0.0; + + /*--- Compute the momentum equation source based on the prescribed (or computed if massflow) delta pressure ---*/ + for (unsigned short iDim = 0; iDim < nDim; iDim++) { + scalar_factor = delta_p / norm2_translation * Streamwise_Coord_Vector[iDim]; + residual[iDim+1] = -Volume * scalar_factor; + } + + /*--- Compute the periodic temperature contribution to the energy equation, if energy equation is considered ---*/ + if (energy && streamwisePeriodic_temperature) { + + scalar_factor = SPvals.Streamwise_Periodic_IntegratedHeatFlow * DensityInc_i / (SPvals.Streamwise_Periodic_MassFlow * norm2_translation); + + /*--- Compute scalar-product dot_prod(v*t) ---*/ + dot_product = GeometryToolbox::DotProduct(nDim, Streamwise_Coord_Vector, &V_i[1]); + + residual[nDim+1] = Volume * scalar_factor * dot_product; + + /*--- If a RANS turbulence model ias used an additional source term, based on the eddy viscosity gradient is added. ---*/ + if(turbulent) { + + /*--- Compute a scalar factor ---*/ + scalar_factor = SPvals.Streamwise_Periodic_IntegratedHeatFlow / (SPvals.Streamwise_Periodic_MassFlow * sqrt(norm2_translation) * Prandtl_Turb); + + /*--- Compute scalar product between periodic translation vector and eddy viscosity gradient. ---*/ + dot_product = GeometryToolbox::DotProduct(nDim, Streamwise_Coord_Vector, AuxVar_Grad_i[0]); + + residual[nDim+1] -= Volume * scalar_factor * dot_product; + } // if turbulent + } // if energy + + return ResidualType<>(residual, jacobian, nullptr); +} + +CSourceIncStreamwisePeriodic_Outlet::CSourceIncStreamwisePeriodic_Outlet(unsigned short val_nDim, + unsigned short val_nVar, + CConfig *config) : + CSourceBase_Flow(val_nDim, val_nVar, config) { } + +CNumerics::ResidualType<> CSourceIncStreamwisePeriodic_Outlet::ComputeResidual(const CConfig *config) { + + for (unsigned short iVar = 0; iVar < nVar; iVar++) residual[iVar] = 0.0; + + /*--- m_dot_local = rho * dot_prod(n_A*v), with n_A beeing the area-normal ---*/ + const su2double local_Massflow = DensityInc_i * GeometryToolbox::DotProduct(nDim, Normal, &V_i[1]); + + // Massflow weighted heat sink, which takes out + // a) the integrated amount over the Heatflux marker + // b) a user provided quantity, especially the case for CHT cases + su2double factor; + if (config->GetStreamwise_Periodic_OutletHeat() == 0.0) + factor = SPvals.Streamwise_Periodic_IntegratedHeatFlow; + else + factor = config->GetStreamwise_Periodic_OutletHeat() / config->GetHeat_Flux_Ref(); + + residual[nDim+1] -= abs(local_Massflow/SPvals.Streamwise_Periodic_MassFlow) * factor; + + /*--- Force the area avg inlet Temp to match the Inc_Temperature_Init with additional residual contribution ---*/ + const su2double delta_T = SPvals.Streamwise_Periodic_InletTemperature - config->GetInc_Temperature_Init()/config->GetTemperature_Ref(); + residual[nDim+1] += 0.5 * abs(local_Massflow) * SpecificHeat_i * delta_T; + + return ResidualType<>(residual, jacobian, nullptr); +} + CSourceRadiation::CSourceRadiation(unsigned short val_nDim, unsigned short val_nVar, const CConfig *config) : CSourceBase_Flow(val_nDim, val_nVar, config) { diff --git a/SU2_CFD/src/output/CFlowIncOutput.cpp b/SU2_CFD/src/output/CFlowIncOutput.cpp index 74f6358fc4d9..df6ca665daff 100644 --- a/SU2_CFD/src/output/CFlowIncOutput.cpp +++ b/SU2_CFD/src/output/CFlowIncOutput.cpp @@ -39,6 +39,9 @@ CFlowIncOutput::CFlowIncOutput(CConfig *config, unsigned short nDim) : CFlowOutp weakly_coupled_heat = config->GetWeakly_Coupled_Heat(); + streamwisePeriodic = config->GetKind_Streamwise_Periodic(); + streamwisePeriodic_temperature = config->GetStreamwise_Periodic_Temperature(); + /*--- Set the default history fields if nothing is set in the config file ---*/ if (nRequestedHistoryFields == 0){ @@ -219,6 +222,11 @@ void CFlowIncOutput::SetHistoryOutputFields(CConfig *config){ AddHistoryOutput("DEFORM_RESIDUAL", "DeformRes", ScreenOutputFormat::FIXED, "DEFORM", "Residual of the linear solver for the mesh deformation"); } + if(streamwisePeriodic) { + AddHistoryOutput("STREAMWISE_MASSFLOW", "SWMassflow", ScreenOutputFormat::FIXED, "STREAMWISE_PERIODIC", "Massflow in streamwise periodic flow"); + AddHistoryOutput("STREAMWISE_DP", "SWDeltaP", ScreenOutputFormat::FIXED, "STREAMWISE_PERIODIC", "Pressure drop in streamwise periodic flow"); + AddHistoryOutput("STREAMWISE_HEAT", "SWHeat", ScreenOutputFormat::FIXED, "STREAMWISE_PERIODIC", "Integrated heat for streamwise periodic flow"); + } /*--- Add analyze surface history fields --- */ AddAnalyzeSurfaceOutput(config); @@ -333,6 +341,12 @@ void CFlowIncOutput::LoadHistoryData(CConfig *config, CGeometry *geometry, CSolv SetHistoryOutputValue("MAX_CFL", flow_solver->GetMax_CFL_Local()); SetHistoryOutputValue("AVG_CFL", flow_solver->GetAvg_CFL_Local()); + if(streamwisePeriodic) { + SetHistoryOutputValue("STREAMWISE_MASSFLOW", flow_solver->GetStreamwisePeriodicValues().Streamwise_Periodic_MassFlow); + SetHistoryOutputValue("STREAMWISE_DP", flow_solver->GetStreamwisePeriodicValues().Streamwise_Periodic_PressureDrop); + SetHistoryOutputValue("STREAMWISE_HEAT", flow_solver->GetStreamwisePeriodicValues().Streamwise_Periodic_IntegratedHeatFlow); + } + /*--- Set the analyse surface history values --- */ SetAnalyzeSurface(flow_solver, geometry, config, false); @@ -487,6 +501,13 @@ void CFlowIncOutput::SetVolumeOutputFields(CConfig *config){ AddVolumeOutput("ASPECT_RATIO", "Aspect_Ratio", "MESH_QUALITY", "CV Face Area Aspect Ratio"); AddVolumeOutput("VOLUME_RATIO", "Volume_Ratio", "MESH_QUALITY", "CV Sub-Volume Ratio"); + // Streamwise Periodicity + if(streamwisePeriodic) { + AddVolumeOutput("RECOVERED_PRESSURE", "Recovered_Pressure", "SOLUTION", "Recovered physical pressure"); + if (heat && streamwisePeriodic_temperature) + AddVolumeOutput("RECOVERED_TEMPERATURE", "Recovered_Temperature", "SOLUTION", "Recovered physical temperature"); + } + // MPI-Rank AddVolumeOutput("RANK", "Rank", "MPI", "Rank of the MPI-partition"); } @@ -637,6 +658,13 @@ void CFlowIncOutput::LoadVolumeData(CConfig *config, CGeometry *geometry, CSolve SetVolumeOutputValue("Q_CRITERION", iPoint, GetQ_Criterion(&(Node_Flow->GetGradient_Primitive(iPoint)[1]))); } + // Streamwise Periodicity + if(streamwisePeriodic) { + SetVolumeOutputValue("RECOVERED_PRESSURE", iPoint, Node_Flow->GetStreamwise_Periodic_RecoveredPressure(iPoint)); + if (heat && streamwisePeriodic_temperature) + SetVolumeOutputValue("RECOVERED_TEMPERATURE", iPoint, Node_Flow->GetStreamwise_Periodic_RecoveredTemperature(iPoint)); + } + // Mesh quality metrics if (config->GetWrt_MeshQuality()) { SetVolumeOutputValue("ORTHOGONALITY", iPoint, geometry->Orthogonality[iPoint]); diff --git a/SU2_CFD/src/output/CFlowOutput.cpp b/SU2_CFD/src/output/CFlowOutput.cpp index 4c33d0354a26..8736b6f5d558 100644 --- a/SU2_CFD/src/output/CFlowOutput.cpp +++ b/SU2_CFD/src/output/CFlowOutput.cpp @@ -126,6 +126,7 @@ void CFlowOutput::SetAnalyzeSurface(CSolver *solver, CGeometry *geometry, CConfi const bool compressible = config->GetKind_Regime() == COMPRESSIBLE; const bool incompressible = config->GetKind_Regime() == INCOMPRESSIBLE; const bool energy = config->GetEnergy_Equation(); + const bool streamwisePeriodic = config->GetKind_Streamwise_Periodic(); const bool axisymmetric = config->GetAxisymmetric(); const unsigned short nMarker_Analyze = config->GetnMarker_Analyze(); @@ -207,6 +208,8 @@ void CFlowOutput::SetAnalyzeSurface(CSolver *solver, CGeometry *geometry, CConfi if (AxiFactor == 0.0) Vn = 0.0; else Vn /= Area; Vn2 = Vn * Vn; Pressure = solver->GetNodes()->GetPressure(iPoint); + /*--- Use recovered pressure here as pressure difference between in and outlet is zero otherwise ---*/ + if(streamwisePeriodic) Pressure = solver->GetNodes()->GetStreamwise_Periodic_RecoveredPressure(iPoint); SoundSpeed = solver->GetNodes()->GetSoundSpeed(iPoint); for (iDim = 0; iDim < nDim; iDim++) { diff --git a/SU2_CFD/src/output/COutput.cpp b/SU2_CFD/src/output/COutput.cpp index f3b8b5eacaff..943adc06633e 100644 --- a/SU2_CFD/src/output/COutput.cpp +++ b/SU2_CFD/src/output/COutput.cpp @@ -1228,7 +1228,7 @@ void COutput::PrepareHistoryFile(CConfig *config){ historyFileTable->SetAlign(PrintingToolbox::CTablePrinter::CENTER); historyFileTable->SetPrintHeaderTopLine(false); historyFileTable->SetPrintHeaderBottomLine(false); - historyFileTable->SetPrecision(10); + historyFileTable->SetPrecision(config->GetOutput_Precision()); /*--- Add the header to the history file. ---*/ diff --git a/SU2_CFD/src/solvers/CHeatSolver.cpp b/SU2_CFD/src/solvers/CHeatSolver.cpp index 11a54fceb2dc..121f0237742b 100644 --- a/SU2_CFD/src/solvers/CHeatSolver.cpp +++ b/SU2_CFD/src/solvers/CHeatSolver.cpp @@ -1544,7 +1544,11 @@ void CHeatSolver::ImplicitEuler_Iteration(CGeometry *geometry, CSolver **solver_ /*--- Solve or smooth the linear system ---*/ auto iter = System.Solve(Jacobian, LinSysRes, LinSysSol, geometry, config); + + /*--- Store the the number of iterations of the linear solver ---*/ SetIterLinSolver(iter); + + /*--- Store the value of the residual. ---*/ SetResLinSolver(System.GetResidual()); for (iPoint = 0; iPoint < nPointDomain; iPoint++) { diff --git a/SU2_CFD/src/solvers/CIncEulerSolver.cpp b/SU2_CFD/src/solvers/CIncEulerSolver.cpp index e7887bf793b6..90b3f0eab48d 100644 --- a/SU2_CFD/src/solvers/CIncEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CIncEulerSolver.cpp @@ -31,6 +31,7 @@ #include "../../include/fluid/CIncIdealGas.hpp" #include "../../include/fluid/CIncIdealGasPolynomial.hpp" #include "../../include/variables/CIncNSVariable.hpp" +#include "../../../Common/include/toolboxes/geometry_toolbox.hpp" CIncEulerSolver::CIncEulerSolver(CGeometry *geometry, CConfig *config, unsigned short iMesh, @@ -103,6 +104,7 @@ CIncEulerSolver::CIncEulerSolver(CGeometry *geometry, CConfig *config, unsigned nDim = geometry->GetnDim(); + /*--- Make sure to align the sizes with the constructor of CIncEulerVariable. ---*/ nVar = nDim+2; nPrimVar = nDim+9; nPrimVarGrad = nDim+4; /*--- Initialize nVarGrad for deallocation ---*/ @@ -1261,6 +1263,10 @@ void CIncEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_cont const bool viscous = config->GetViscous(); const bool radiation = config->AddRadiation(); const bool vol_heat = config->GetHeatSource(); + const bool turbulent = (config->GetKind_Turb_Model() != NONE); + const bool energy = config->GetEnergy_Equation(); + const bool streamwise_periodic = config->GetKind_Streamwise_Periodic(); + const bool streamwise_periodic_temperature = config->GetStreamwise_Periodic_Temperature(); if (body_force) { @@ -1377,7 +1383,7 @@ void CIncEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_cont if (yCoord > EPS) AuxVar = Total_Viscosity*yVelocity/yCoord; - /*--- Set the auxilairy variable for this node. ---*/ + /*--- Set the auxiliary variable for this node. ---*/ nodes->SetAuxVar(iPoint, 0, AuxVar); @@ -1490,6 +1496,100 @@ void CIncEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_cont } + if (streamwise_periodic) { + + /*--- For turbulent streamwise periodic problems w/ energy eq, we need an additional gradient of Eddy viscosity. ---*/ + if (streamwise_periodic_temperature && turbulent) { + + SU2_OMP_FOR_STAT(omp_chunk_size) + for (iPoint = 0; iPoint < nPoint; iPoint++) { + /*--- Set the auxiliary variable, Eddy viscosity mu_t, for this node. ---*/ + nodes->SetAuxVar(iPoint, 0, nodes->GetEddyViscosity(iPoint)); + } + + /*--- Compute the auxiliary variable gradient with GG or WLS. ---*/ + if (config->GetKind_Gradient_Method() == GREEN_GAUSS) { + SetAuxVar_Gradient_GG(geometry, config); + } + if (config->GetKind_Gradient_Method() == WEIGHTED_LEAST_SQUARES) { + SetAuxVar_Gradient_LS(geometry, config); + } + + } // if turbulent + + /*--- Set delta_p, m_dot, inlet_T, integrated_heat ---*/ + numerics->SetStreamwisePeriodicValues(SPvals); + + /*--- Loop over all points ---*/ + SU2_OMP_FOR_STAT(omp_chunk_size) + for (iPoint = 0; iPoint < nPointDomain; iPoint++) { + + /*--- Load the primitive variables ---*/ + numerics->SetPrimitive(nodes->GetPrimitive(iPoint), nullptr); + + /*--- Set incompressible density ---*/ + numerics->SetDensity(nodes->GetDensity(iPoint), 0.0); + + /*--- Load the volume of the dual mesh cell ---*/ + numerics->SetVolume(geometry->nodes->GetVolume(iPoint)); + + /*--- Load the aux variable gradient that we already computed. ---*/ + if(streamwise_periodic_temperature && turbulent) + numerics->SetAuxVarGrad(nodes->GetAuxVarGradient(iPoint), nullptr); + + /*--- Compute the streamwise periodic source residual and add to the total ---*/ + auto residual = numerics->ComputeResidual(config); + LinSysRes.AddBlock(iPoint, residual); + + /*--- Add the implicit Jacobian contribution ---*/ + if (implicit) Jacobian.AddBlock2Diag(iPoint, residual.jacobian_i); + + } // for iPoint + + if(!streamwise_periodic_temperature && energy) { + + CNumerics* second_numerics = numerics_container[SOURCE_SECOND_TERM + omp_get_thread_num()*MAX_TERMS]; + + /*--- Set delta_p, m_dot, inlet_T, integrated_heat ---*/ + second_numerics->SetStreamwisePeriodicValues(SPvals); + + /*--- This bit acts as a boundary condition rather than a source term. But logically it fits better here. ---*/ + for (auto iMarker = 0ul; iMarker < config->GetnMarker_All(); iMarker++) { + + /*--- Only "inlet"/donor periodic marker ---*/ + if (config->GetMarker_All_KindBC(iMarker) == PERIODIC_BOUNDARY && + config->GetMarker_All_PerBound(iMarker) == 1) { + + SU2_OMP_FOR_STAT(OMP_MIN_SIZE) + for (auto iVertex = 0ul; iVertex < nVertex[iMarker]; iVertex++) { + + iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + + if (!geometry->nodes->GetDomain(iPoint)) continue; + + /*--- Load the primitive variables ---*/ + second_numerics->SetPrimitive(nodes->GetPrimitive(iPoint), nullptr); + + /*--- Set incompressible density ---*/ + second_numerics->SetDensity(nodes->GetDensity(iPoint), 0.0); + + /*--- Set the specific heat ---*/ + second_numerics->SetSpecificHeat(nodes->GetSpecificHeatCp(iPoint), 0.0); + + /*--- Set the area normal ---*/ + second_numerics->SetNormal(geometry->vertex[iMarker][iVertex]->GetNormal()); + + /*--- Compute the streamwise periodic source residual and add to the total ---*/ + auto residual = second_numerics->ComputeResidual(config); + LinSysRes.AddBlock(iPoint, residual); + + }// for iVertex + }// if periodic inlet boundary + }// for iMarker + + }// if !streamwise_periodic_temperature + }// if streamwise_periodic + /*--- Check if a verification solution is to be computed. ---*/ if (VerificationSolution) { diff --git a/SU2_CFD/src/solvers/CIncNSSolver.cpp b/SU2_CFD/src/solvers/CIncNSSolver.cpp index ac182499e675..4418cef5eb53 100644 --- a/SU2_CFD/src/solvers/CIncNSSolver.cpp +++ b/SU2_CFD/src/solvers/CIncNSSolver.cpp @@ -97,6 +97,204 @@ void CIncNSSolver::Preprocessing(CGeometry *geometry, CSolver **solver_container ComputeVorticityAndStrainMag<1>(*config, iMesh); + /*--- Compute recovered pressure and temperature for streamwise periodic flow ---*/ + if (config->GetKind_Streamwise_Periodic() != NONE) + Compute_Streamwise_Periodic_Recovered_Values(config, geometry, iMesh); +} + +void CIncNSSolver::GetStreamwise_Periodic_Properties(const CGeometry *geometry, + CConfig *config, + const unsigned short iMesh) { + + /*---------------------------------------------------------------------------------------------*/ + // 1. Evaluate massflow, area avg density & Temperature and Area at streamwise periodic outlet. + // 2. Update delta_p is target massflow is chosen. + // 3. Loop Heatflux markers and integrate heat across the boundary. Only if energy equation is on. + /*---------------------------------------------------------------------------------------------*/ + + /*-------------------------------------------------------------------------------------------------*/ + /*--- 1. Evaluate Massflow [kg/s], area-averaged density [kg/m^3] and Area [m^2] at the ---*/ + /*--- (there can be only one) streamwise periodic outlet/donor marker. Massflow is obviously ---*/ + /*--- needed for prescribed massflow but also for the additional source and heatflux ---*/ + /*--- boundary terms of the energy equation. Area and the avg-density are used for the ---*/ + /*--- Pressure-Drop update in case of a prescribed massflow. ---*/ + /*-------------------------------------------------------------------------------------------------*/ + + const auto nZone = geometry->GetnZone(); + const auto InnerIter = config->GetInnerIter(); + const auto OuterIter = config->GetOuterIter(); + + su2double Area_Local = 0.0, + MassFlow_Local = 0.0, + Average_Density_Local = 0.0, + Temperature_Local = 0.0; + + for (auto iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { + + /*--- Only "outlet"/donor periodic marker ---*/ + if (config->GetMarker_All_KindBC(iMarker) == PERIODIC_BOUNDARY && + config->GetMarker_All_PerBound(iMarker) == 2) { + + for (auto iVertex = 0ul; iVertex < geometry->nVertex[iMarker]; iVertex++) { + + auto iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + + if (geometry->nodes->GetDomain(iPoint)) { + + /*--- A = dot_prod(n_A*n_A), with n_A beeing the area-normal. ---*/ + + const auto AreaNormal = geometry->vertex[iMarker][iVertex]->GetNormal(); + + auto FaceArea = GeometryToolbox::Norm(nDim, AreaNormal); + + /*--- m_dot = dot_prod(n*v) * A * rho, with n beeing unit normal. ---*/ + MassFlow_Local += nodes->GetProjVel(iPoint, AreaNormal) * nodes->GetDensity(iPoint); + + Area_Local += FaceArea; + + Average_Density_Local += FaceArea * nodes->GetDensity(iPoint); + + /*--- Due to periodicty, temperatures are equal one the inlet(1) and outlet(2) ---*/ + Temperature_Local += FaceArea * nodes->GetTemperature(iPoint); + + } // if domain + } // loop vertices + } // loop periodic boundaries + } // loop MarkerAll + + // MPI Communication: Sum Area, Sum rho*A & T*A and divide by AreaGlobbal, sum massflow + su2double Area_Global(0), Average_Density_Global(0), MassFlow_Global(0), Temperature_Global(0); + SU2_MPI::Allreduce(&Area_Local, &Area_Global, 1, MPI_DOUBLE, MPI_SUM, SU2_MPI::GetComm()); + SU2_MPI::Allreduce(&Average_Density_Local, &Average_Density_Global, 1, MPI_DOUBLE, MPI_SUM, SU2_MPI::GetComm()); + SU2_MPI::Allreduce(&MassFlow_Local, &MassFlow_Global, 1, MPI_DOUBLE, MPI_SUM, SU2_MPI::GetComm()); + SU2_MPI::Allreduce(&Temperature_Local, &Temperature_Global, 1, MPI_DOUBLE, MPI_SUM, SU2_MPI::GetComm()); + + Average_Density_Global /= Area_Global; + Temperature_Global /= Area_Global; + + /*--- Set solver variables ---*/ + SPvals.Streamwise_Periodic_MassFlow = MassFlow_Global; + SPvals.Streamwise_Periodic_InletTemperature = Temperature_Global; + + /*--- As deltaP changes with prescribed massflow the const config value should only be used once. ---*/ + if((nZone==1 && InnerIter==0) || + (nZone>1 && OuterIter==0 && InnerIter==0)) { + SPvals.Streamwise_Periodic_PressureDrop = config->GetStreamwise_Periodic_PressureDrop() / config->GetPressure_Ref(); + } + + if (config->GetKind_Streamwise_Periodic() == STREAMWISE_MASSFLOW) { + /*------------------------------------------------------------------------------------------------*/ + /*--- 2. Update the Pressure Drop [Pa] for the Momentum source term if Massflow is prescribed. ---*/ + /*--- The Pressure drop is iteratively adapted to result in the prescribed Target-Massflow. ---*/ + /*------------------------------------------------------------------------------------------------*/ + + /*--- Load/define all necessary variables ---*/ + const su2double TargetMassFlow = config->GetStreamwise_Periodic_TargetMassFlow() / (config->GetDensity_Ref() * config->GetVelocity_Ref()); + const su2double damping_factor = config->GetInc_Outlet_Damping(); + su2double Pressure_Drop_new, ddP; + + /*--- Compute update to Delta p based on massflow-difference ---*/ + ddP = 0.5 / ( Average_Density_Global * pow(Area_Global, 2)) * (pow(TargetMassFlow, 2) - pow(MassFlow_Global, 2)); + + /*--- Store updated pressure difference ---*/ + Pressure_Drop_new = SPvals.Streamwise_Periodic_PressureDrop + damping_factor*ddP; + /*--- During restarts, this routine GetStreamwise_Periodic_Properties can get called multiple times + (e.g. 4x for INC_RANS restart). Each time, the pressure drop gets updated. For INC_RANS restarts + it gets called 2x before the restart files are read such that the current massflow is + Area*inital-velocity which can be way off! + With this there is still a slight inconsitency wrt to a non-restarted simulation: The restarted "zero-th" + iteration does not get a pressure-update but the continuing simulation would have an update here. This can be + fully neglected if the pressure drop is converged. And for all other cases it should be minor difference at + best ---*/ + if((nZone==1 && InnerIter>0) || + (nZone>1 && OuterIter>0)) { + SPvals.Streamwise_Periodic_PressureDrop = Pressure_Drop_new; + } + + } // if massflow + + + if (config->GetEnergy_Equation()) { + /*---------------------------------------------------------------------------------------------*/ + /*--- 3. Compute the integrated Heatflow [W] for the energy equation source term, heatflux ---*/ + /*--- boundary term and recovered Temperature. The computation is not completely clear. ---*/ + /*--- Here the Heatflux from all Bounary markers in the config-file is used. ---*/ + /*---------------------------------------------------------------------------------------------*/ + + su2double HeatFlow_Local = 0.0, HeatFlow_Global = 0.0; + + /*--- Loop over all heatflux Markers ---*/ + for (auto iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { + + if (config->GetMarker_All_KindBC(iMarker) == HEAT_FLUX) { + + /*--- Identify the boundary by string name and retrive heatflux from config ---*/ + const auto Marker_StringTag = config->GetMarker_All_TagBound(iMarker); + const auto Wall_HeatFlux = config->GetWall_HeatFlux(Marker_StringTag); + + for (auto iVertex = 0ul; iVertex < geometry->nVertex[iMarker]; iVertex++) { + + auto iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + + if (!geometry->nodes->GetDomain(iPoint)) continue; + + const auto AreaNormal = geometry->vertex[iMarker][iVertex]->GetNormal(); + + auto FaceArea = GeometryToolbox::Norm(nDim, AreaNormal); + + HeatFlow_Local += FaceArea * (-1.0) * Wall_HeatFlux/config->GetHeat_Flux_Ref();; + } // loop Vertices + } // loop Heatflux marker + } // loop AllMarker + + /*--- MPI Communication sum up integrated Heatflux from all processes ---*/ + SU2_MPI::Allreduce(&HeatFlow_Local, &HeatFlow_Global, 1, MPI_DOUBLE, MPI_SUM, SU2_MPI::GetComm()); + + /*--- Set the solver variable Integrated Heatflux ---*/ + SPvals.Streamwise_Periodic_IntegratedHeatFlow = HeatFlow_Global; + } // if energy +} + + +void CIncNSSolver::Compute_Streamwise_Periodic_Recovered_Values(CConfig *config, const CGeometry *geometry, + const unsigned short iMesh) { + + const bool energy = (config->GetEnergy_Equation() && config->GetStreamwise_Periodic_Temperature()); + const auto InnerIter = config->GetInnerIter(); + + /*--- Reference node on inlet periodic marker to compute relative distance along periodic translation vector. ---*/ + const su2double* ReferenceNode = geometry->GetStreamwise_Periodic_RefNode(); + + /*--- Compute square of the distance between the 2 periodic surfaces. ---*/ + const su2double norm2_translation = GeometryToolbox::SquaredNorm(nDim, config->GetPeriodic_Translation(0)); + + /*--- Compute recoverd pressure and temperature for all points ---*/ + SU2_OMP_FOR_STAT(omp_chunk_size) + for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { + + /*--- First, compute helping terms based on relative distance (0,l) between periodic markers ---*/ + su2double dot_product = 0.0; + for (unsigned short iDim = 0; iDim < nDim; iDim++) + dot_product += fabs( (geometry->nodes->GetCoord(iPoint,iDim) - ReferenceNode[iDim]) * config->GetPeriodic_Translation(0)[iDim]); + + /*--- Second, substract/add correction from reduced pressure/temperature to get recoverd pressure/temperature ---*/ + const su2double Pressure_Recovered = nodes->GetPressure(iPoint) - SPvals.Streamwise_Periodic_PressureDrop / + norm2_translation * dot_product; + nodes->SetStreamwise_Periodic_RecoveredPressure(iPoint, Pressure_Recovered); + + /*--- InnerIter > 0 as otherwise MassFlow in the denominator would be zero ---*/ + if (energy && InnerIter > 0) { + su2double Temperature_Recovered = nodes->GetTemperature(iPoint); + Temperature_Recovered += SPvals.Streamwise_Periodic_IntegratedHeatFlow / + (SPvals.Streamwise_Periodic_MassFlow * nodes->GetSpecificHeatCp(iPoint) * norm2_translation) * dot_product; + nodes->SetStreamwise_Periodic_RecoveredTemperature(iPoint, Temperature_Recovered); + } + } // for iPoint + + /*--- Compute the integrated Heatflux Q into the domain, and massflow over periodic markers ---*/ + SU2_OMP_MASTER + GetStreamwise_Periodic_Properties(geometry, config, iMesh); + SU2_OMP_BARRIER } void CIncNSSolver::Viscous_Residual(unsigned long iEdge, CGeometry *geometry, CSolver **solver_container, @@ -151,6 +349,12 @@ void CIncNSSolver::BC_Wall_Generic(const CGeometry *geometry, const CConfig *con const bool implicit = (config->GetKind_TimeIntScheme() == EULER_IMPLICIT); const bool energy = config->GetEnergy_Equation(); + /*--- Variables for streamwise periodicity ---*/ + const bool streamwise_periodic = (config->GetKind_Streamwise_Periodic() != NONE); + const bool streamwise_periodic_temperature = config->GetStreamwise_Periodic_Temperature(); + su2double Cp, thermal_conductivity, dot_product, scalar_factor; + + /*--- Identify the boundary by string name ---*/ const auto Marker_Tag = config->GetMarker_All_TagBound(val_marker); @@ -219,6 +423,22 @@ void CIncNSSolver::BC_Wall_Generic(const CGeometry *geometry, const CConfig *con Compute the residual due to the prescribed heat flux. ---*/ LinSysRes(iPoint, nDim+1) -= Wall_HeatFlux*Area; + + /*--- With streamwise periodic flow and heatflux walls an additional term is introduced in the boundary formulation ---*/ + if (streamwise_periodic && streamwise_periodic_temperature) { + + Cp = nodes->GetSpecificHeatCp(iPoint); + thermal_conductivity = nodes->GetThermalConductivity(iPoint); + + /*--- Scalar factor of the residual contribution ---*/ + const su2double norm2_translation = GeometryToolbox::SquaredNorm(nDim, config->GetPeriodic_Translation(0)); + scalar_factor = SPvals.Streamwise_Periodic_IntegratedHeatFlow*thermal_conductivity / (SPvals.Streamwise_Periodic_MassFlow * Cp * norm2_translation); + + /*--- Dot product ---*/ + dot_product = GeometryToolbox::DotProduct(nDim, config->GetPeriodic_Translation(0), Normal); + + LinSysRes(iPoint, nDim+1) += scalar_factor*dot_product; + } // if streamwise_periodic } else { // ISOTHERMAL diff --git a/SU2_CFD/src/variables/CIncEulerVariable.cpp b/SU2_CFD/src/variables/CIncEulerVariable.cpp index 1b5bbe9482cc..df0e8da3737d 100644 --- a/SU2_CFD/src/variables/CIncEulerVariable.cpp +++ b/SU2_CFD/src/variables/CIncEulerVariable.cpp @@ -36,7 +36,8 @@ CIncEulerVariable::CIncEulerVariable(su2double pressure, const su2double *veloci (config->GetTime_Marching() == DT_STEPPING_2ND); const bool viscous = config->GetViscous(); - /*--- Allocate and initialize the primitive variables and gradients ---*/ + /*--- Allocate and initialize the primitive variables and gradients. + Make sure to align the sizes with the constructor of CIncEulerSolver ---*/ nPrimVar = nDim+9; nPrimVarGrad = nDim+4; @@ -114,6 +115,12 @@ CIncEulerVariable::CIncEulerVariable(su2double pressure, const su2double *veloci Lambda.resize(nPoint) = su2double(0.0); Sensor.resize(nPoint) = su2double(0.0); + if (config->GetKind_Streamwise_Periodic() != NONE) { + Streamwise_Periodic_RecoveredPressure.resize(nPoint) = su2double(0.0); + if (config->GetStreamwise_Periodic_Temperature()) + Streamwise_Periodic_RecoveredTemperature.resize(nPoint) = su2double(0.0); + } + /* Under-relaxation parameter. */ UnderRelaxation.resize(nPoint) = su2double(1.0); LocalCFL.resize(nPoint) = su2double(0.0); diff --git a/SU2_CFD/src/variables/CIncNSVariable.cpp b/SU2_CFD/src/variables/CIncNSVariable.cpp index 008dc5457090..68fb0000ccd0 100644 --- a/SU2_CFD/src/variables/CIncNSVariable.cpp +++ b/SU2_CFD/src/variables/CIncNSVariable.cpp @@ -42,6 +42,13 @@ CIncNSVariable::CIncNSVariable(su2double pressure, const su2double *velocity, su AuxVar.resize(nPoint,nAuxVar) = su2double(0.0); Grad_AuxVar.resize(nPoint,nAuxVar,nDim); } + + /*--- Allocate memory for the AuxVar+gradient of eddy viscosity mu_t ---*/ + if (config->GetStreamwise_Periodic_Temperature() && (config->GetKind_Turb_Model() != NONE)) { + nAuxVar = 1; + AuxVar.resize(nPoint,nAuxVar) = su2double(0.0); + Grad_AuxVar.resize(nPoint,nAuxVar,nDim); + } } bool CIncNSVariable::SetPrimVar(unsigned long iPoint, su2double eddy_visc, su2double turb_ke, CFluidModel *FluidModel) { diff --git a/SU2_DOT/src/SU2_DOT.cpp b/SU2_DOT/src/SU2_DOT.cpp index 3017cc90f8f1..f57ffd18df3d 100644 --- a/SU2_DOT/src/SU2_DOT.cpp +++ b/SU2_DOT/src/SU2_DOT.cpp @@ -283,27 +283,25 @@ int main(int argc, char *argv[]) { SetSensitivity_Files(geometry_container, config_container, nZone); } - for (iZone = 0; iZone < nZone; iZone++){ - if ((config_container[iZone]->GetDesign_Variable(0) != NONE) && - (config_container[iZone]->GetDesign_Variable(0) != SURFACE_FILE)) { + /*--- Initialize structure to store the gradient ---*/ + su2double** Gradient = new su2double*[config_container[ZONE_0]->GetnDV()]; - /*--- Initialize structure to store the gradient ---*/ + 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)](); + } - su2double** Gradient = new su2double*[config_container[ZONE_0]->GetnDV()]; + ofstream Gradient_file; + Gradient_file.precision(config->OptionIsSet("OUTPUT_PRECISION") ? config->GetOutput_Precision() : 6); - for (auto iDV = 0u; iDV < config_container[iZone]->GetnDV(); iDV++) { - Gradient[iDV] = new su2double[config_container[iZone]->GetnDV_Value(iDV)] (); - } + /*--- 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; - /*--- Write the gradient in a external file ---*/ - - ofstream Gradient_file; - if (rank == MASTER_NODE) - Gradient_file.open(config_container[iZone]->GetObjFunc_Grad_FileName().c_str(), ios::out); - /*--- Definition of the Class for surface deformation ---*/ surface_movement[iZone] = new CSurfaceMovement(); @@ -320,16 +318,22 @@ int main(int argc, char *argv[]) { else SetProjection_FD(geometry_container[iZone][INST_0], config_container[iZone], surface_movement[iZone] , Gradient); - /*--- Print gradients to screen and file ---*/ + } + } // for iZone - OutputGradient(Gradient, config_container[iZone], Gradient_file); + /*--- Write the gradient to a file ---*/ - for (auto iDV = 0u; iDV < config_container[iZone]->GetnDV(); iDV++){ - delete [] Gradient[iDV]; - } - delete [] Gradient; - } + 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; @@ -933,7 +937,7 @@ void SetSensitivity_Files(CGeometry ***geometry, CConfig **config, unsigned shor output->SetSurface_Filename(config[iZone]->GetSurfSens_FileName()); - /*--- Set the surface filename ---*/ + /*--- Set the volume filename ---*/ output->SetVolume_Filename(config[iZone]->GetVolSens_FileName()); diff --git a/SU2_PY/SU2/eval/functions.py b/SU2_PY/SU2/eval/functions.py index 066182004f28..b501159da884 100644 --- a/SU2_PY/SU2/eval/functions.py +++ b/SU2_PY/SU2/eval/functions.py @@ -223,6 +223,8 @@ def aerodynamics( config, state=None ): name = su2io.expand_part(name,config) link.extend(name) + pull.extend(config.get('CONFIG_LIST',[])) + # files: restarts if config.get('TIME_DOMAIN', 'NO') == 'YES' and config.get('RESTART_SOL','NO') =='YES': if 'RESTART_FILE_1' in files: # not the case for directdiff restart @@ -311,10 +313,9 @@ def aerodynamics( config, state=None ): su2io.update_persurface(konfig,state) # return output funcs = su2util.ordered_bunch() - for key in su2io.historyOutFields: - if key in state['FUNCTIONS']: + for key in state['FUNCTIONS']: funcs[key] = state['FUNCTIONS'][key] - + return funcs #: def aerodynamics() @@ -909,7 +910,9 @@ def update_mesh(config,state=None): pull = [] link = config['MESH_FILENAME'] link = su2io.expand_part(link,config) - + + pull.extend(config.get('CONFIG_LIST',[])) + # output redirection with redirect_folder('DEFORM',pull,link) as push: with redirect_output(log_deform): diff --git a/SU2_PY/SU2/eval/gradients.py b/SU2_PY/SU2/eval/gradients.py index eef13c15756f..0ab65f504438 100644 --- a/SU2_PY/SU2/eval/gradients.py +++ b/SU2_PY/SU2/eval/gradients.py @@ -767,15 +767,20 @@ def findiff( config, state=None ): else: step = 0.001 + opt_names = [] + for i in range(config['NZONES']): + for key in sorted(su2io.historyOutFields): + if su2io.historyOutFields[key]['TYPE'] == 'COEFFICIENT': + if (config['NZONES'] == 1): + opt_names.append(key) + else: + opt_names.append(key + '[' + str(i) + ']') + # ---------------------------------------------------- # Redundancy Check # ---------------------------------------------------- # master redundancy check - opt_names = [] - for key in sorted(su2io.historyOutFields): - if su2io.historyOutFields[key]['TYPE'] == 'COEFFICIENT': - opt_names.append(key) findiff_todo = all([key in state.GRADIENTS for key in opt_names]) if findiff_todo: grads = state['GRADIENTS'] @@ -827,7 +832,8 @@ def findiff( config, state=None ): # files to pull files = state['FILES'] - pull = []; link = [] + pull = []; link = [] + pull.extend(config.get('CONFIG_LIST',[])) # files: mesh name = files['MESH'] name = su2io.expand_part(name,konfig) diff --git a/SU2_PY/SU2/io/config.py b/SU2_PY/SU2/io/config.py index 81916ba14abd..485ace2213a5 100755 --- a/SU2_PY/SU2/io/config.py +++ b/SU2_PY/SU2/io/config.py @@ -470,6 +470,10 @@ def read_config(filename): data_dict[this_param] = this_value.strip("()").split(",") data_dict[this_param] = [i.strip(" ") for i in data_dict[this_param]] break + if case("CONFIG_LIST"): + data_dict[this_param] = this_value.strip("()").split(",") + data_dict[this_param] = [i.strip(" ") for i in data_dict[this_param]] + break if case("HISTORY_OUTPUT"): data_dict[this_param] = this_value.strip("()").split(",") data_dict[this_param] = [i.strip(" ") for i in data_dict[this_param]] @@ -907,6 +911,16 @@ def write_config(filename,param_dict): output_file.write(", ") output_file.write(")") break + + if case("CONFIG_LIST"): + n_lists = len(new_value) + output_file.write("(") + for i_value in range(n_lists): + output_file.write(new_value[i_value]) + if i_value+1 < n_lists: + output_file.write(", ") + output_file.write(")") + break if case("HISTORY_OUTPUT"): n_lists = len(new_value) diff --git a/SU2_PY/SU2/io/tools.py b/SU2_PY/SU2/io/tools.py index 4b0f9c401b7e..9201256340c8 100755 --- a/SU2_PY/SU2/io/tools.py +++ b/SU2_PY/SU2/io/tools.py @@ -154,10 +154,15 @@ def read_history( History_filename, nZones = 1): for key in plot_data.keys(): var = key for field in historyOutFields: - if key == historyOutFields[field]['HEADER']: + + if key == historyOutFields[field]['HEADER'] and nZones == 1: var = field + + if key.split('[')[0] == historyOutFields[field]['HEADER'] and nZones > 1: + var = field + '[' + key.split('[')[1] + history_data[var] = plot_data[key] - + return history_data #: def read_history() @@ -323,9 +328,15 @@ def read_aerodynamics( History_filename , nZones = 1, special_cases=[], final_av # pull only these functions Func_Values = ordered_bunch() for this_objfun in historyOutFields: - if this_objfun in history_data: - if historyOutFields[this_objfun]['TYPE'] == 'COEFFICIENT' or historyOutFields[this_objfun]['TYPE'] == 'D_COEFFICIENT': - Func_Values[this_objfun] = history_data[this_objfun] + if nZones == 1: + if this_objfun in history_data: + if historyOutFields[this_objfun]['TYPE'] == 'COEFFICIENT' or historyOutFields[this_objfun]['TYPE'] == 'D_COEFFICIENT': + Func_Values[this_objfun] = history_data[this_objfun] + else: + for iZone in range(nZones): + if this_objfun + '[' + str(iZone) + ']' in history_data: + if historyOutFields[this_objfun]['TYPE'] == 'COEFFICIENT' or historyOutFields[this_objfun]['TYPE'] == 'D_COEFFICIENT': + Func_Values[this_objfun + '[' + str(iZone) + ']'] = history_data[this_objfun + '[' + str(iZone) + ']'] if 'TIME_MARCHING' in special_cases: # for unsteady cases, average time-accurate objective function values diff --git a/SU2_PY/SU2/run/direct.py b/SU2_PY/SU2/run/direct.py index dd97e0d095c9..54c930a95955 100644 --- a/SU2_PY/SU2/run/direct.py +++ b/SU2_PY/SU2/run/direct.py @@ -91,10 +91,15 @@ def direct ( config ): # adapt the history_filename, if a restart solution is chosen # check for 'RESTART_ITER' is to avoid forced restart situation in "compute_polar.py"... if konfig.get('RESTART_SOL','NO') == 'YES' and konfig.get('RESTART_ITER',1) != 1: + if konfig.get('CONFIG_LIST',[]) != []: + konfig['CONV_FILENAME'] = 'config_CFD' # master cfg is always config_CFD. Hardcoded names are prob nt ideal. restart_iter = '_'+str(konfig['RESTART_ITER']).zfill(5) history_filename = konfig['CONV_FILENAME'] + restart_iter + plot_extension else: + if konfig.get('CONFIG_LIST',[]) != []: + konfig['CONV_FILENAME'] = 'config_CFD' history_filename = konfig['CONV_FILENAME'] + plot_extension + special_cases = su2io.get_specialCases(konfig) diff --git a/TestCases/incomp_navierstokes/streamwise_periodic/README.md b/TestCases/incomp_navierstokes/streamwise_periodic/README.md new file mode 100644 index 000000000000..0162663ce5c9 --- /dev/null +++ b/TestCases/incomp_navierstokes/streamwise_periodic/README.md @@ -0,0 +1,29 @@ +# Streamwise Periodicity testcases + +This folder contains the additional Testcases for streamwise periodic flow. +A Tutorial can be found on the SU2 website. +For all Testcases a gmsh .geo file is provided which allows to recreate/modify the mesh. + +## `pipe_slice_3d` + +Hagen Poiseuille flow through a 1-primal-cell thick pipe slice in 3D. + +Analytical solution of the velocity magnitude for steady laminar pipe flow in a round pipe `v_mag (r) = -1/(4*mu) * (Delta p / Delta x) * (R**2 - r**2)` therefore a pressure drop Delta p is prescribed. + +`Re = rho * v * L / mu = 1.0 * 0.6 * 5e-3 / 1.8e-5` makes Re=167, with the critical Reynolds number being Re~=2300. + +This testcase is a regression test. + +## `chtPinArray_2d` + +Extension of the tutorial case to a CHT problem with 1 additional solid zone. +A gradient validation between discrete and finite differences for this setup is described in the README of that folder. + +This gradient validation is also part of the regression tests. + +## `chtPinArray_3d` + +Extension of the `chtPinArray_2d` to the 3rd dimension with again one solid zone. +The mesh provided is coarse to keep the filesize and computation time low, but using the gmsh .geo script much higher mesh resolutions can be created. + +This primal simulation is part of the regression tests. diff --git a/TestCases/incomp_navierstokes/streamwise_periodic/chtPinArray_2d/DA_configMaster.cfg b/TestCases/incomp_navierstokes/streamwise_periodic/chtPinArray_2d/DA_configMaster.cfg new file mode 100644 index 000000000000..936f08747a18 --- /dev/null +++ b/TestCases/incomp_navierstokes/streamwise_periodic/chtPinArray_2d/DA_configMaster.cfg @@ -0,0 +1,113 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% SU2 configuration file % +% Case description: 2D cylinder array with CHT couplings % +% Author: T. Kattmann % +% Institution: Robert Bosch GmbH % +% Date: 2020.12.15 % +% File Version 7.1.0 "Blackbird" % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +SOLVER= MULTIPHYSICS +% +CONFIG_LIST= (configFluid.cfg, configSolid.cfg) +% +MARKER_ZONE_INTERFACE= ( fluid_pin1_interface, solid_pin1_interface, fluid_pin2_interface, solid_pin2_interface, fluid_pin3_interface, solid_pin3_interface ) +% +MARKER_CHT_INTERFACE= ( fluid_pin1_interface, solid_pin1_interface, fluid_pin2_interface, solid_pin2_interface, fluid_pin3_interface, solid_pin3_interface ) +% +CONV_RESIDUAL_MINVAL= -26 +% +% Number of total iterations +OUTER_ITER= 3000 +% +%CHT_ROBIN= NO +% +SCREEN_OUTPUT= (OUTER_ITER, BGS_ADJ_PRESSURE[0], BGS_ADJ_TEMPERATURE[0], BGS_ADJ_TEMPERATURE[1]) +SCREEN_WRT_FREQ_OUTER= 100 +% +HISTORY_OUTPUT= ( ITER, BGS_RES[0], BGS_RES[1], RMS_RES[0], RMS_RES[1] ) +% +OUTPUT_FILES= ( RESTART, PARAVIEW_MULTIBLOCK ) +OUTPUT_WRT_FREQ= 1000 +% +MESH_FILENAME= 2D-PinArray_FFD.su2 +MESH_FORMAT= SU2 +% +SOLUTION_ADJ_FILENAME= restart_adj +% +% -------------------- FREE-FORM DEFORMATION PARAMETERS -----------------------% +% +FFD_TOLERANCE= 1E-10 +FFD_ITERATIONS= 500 +% +% FFD box definition: 2D case (FFD_BoxTag, X1, Y1, 0.0, X2, Y2, 0.0, X3, Y3, 0.0, X4, Y4, 0.0, +% 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) +FFD_DEFINITION= (BOX, 0.0029772,0.0,0.0, 0.0081772,0.0,0.0 0.0081772,0.0026,0.0, 0.0029772,0.0026,0.0, 0.0,0.0,0.0, 0.0,0.0,0.0 0.0,0.0,0.0, 0.0,0.0,0.0 ) +% +% FFD box degree: 2D case (x_degree, y_degree, 0) +FFD_DEGREE= (8, 1, 0) +% +% Surface grid continuity at the intersection with the faces of the FFD boxes. +% To keep a particular level of surface continuity, SU2 automatically freezes the right +% number of control point planes (NO_DERIVATIVE, 1ST_DERIVATIVE, 2ND_DERIVATIVE, USER_INPUT) +FFD_CONTINUITY= NO_DERIVATIVE +% +% ----------------------- DESIGN VARIABLE PARAMETERS --------------------------% +% +%DV_KIND= FFD_SETTING +DV_KIND= FFD_CONTROL_POINT_2D,FFD_CONTROL_POINT_2D,FFD_CONTROL_POINT_2D,FFD_CONTROL_POINT_2D,FFD_CONTROL_POINT_2D,FFD_CONTROL_POINT_2D,FFD_CONTROL_POINT_2D,FFD_CONTROL_POINT_2D,FFD_CONTROL_POINT_2D +% +% Marker of the surface in which we are going apply the shape deformation +MARKER_SYM= ( fluid_symmetry ) +DV_MARKER= ( fluid_pin2_interface, solid_pin2_interface, fluid_symmetry ) +% +% Parameters of the shape deformation +% - FFD_SETTING ( 1.0 ) +% - FFD_CONTROL_POINT_2D ( FFD_BoxTag, i_Ind, j_Ind, x_Disp, y_Disp ) +%DV_PARAM= ( 1.0 ) +DV_PARAM= \ +( BOX, 0, 1, 0.0, 1.0);\ +( BOX, 1, 1, 0.0, 1.0);\ +( BOX, 2, 1, 0.0, 1.0);\ +( BOX, 3, 1, 0.0, 1.0);\ +( BOX, 4, 1, 0.0, 1.0);\ +( BOX, 5, 1, 0.0, 1.0);\ +( BOX, 6, 1, 0.0, 1.0);\ +( BOX, 7, 1, 0.0, 1.0);\ +( BOX, 8, 1, 0.0, 1.0) +% +% Value of the shape deformation +%DV_VALUE= 1.0 +DV_VALUE= 1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0 +% +% ------------------------ GRID DEFORMATION PARAMETERS ------------------------% +% +DEFORM_LINEAR_SOLVER= FGMRES +DEFORM_LINEAR_SOLVER_PREC= ILU +DEFORM_LINEAR_SOLVER_ERROR= 1E-14 +% +DEFORM_NONLINEAR_ITER= 1 +DEFORM_LINEAR_SOLVER_ITER= 1000 +% +DEFORM_CONSOLE_OUTPUT= YES +DEFORM_STIFFNESS_TYPE= WALL_DISTANCE +% +% Deformation coefficient (linear elasticity limits from -1.0 to 0.5, a larger +% value is also possible) +% !!! What is this doing !!! +DEFORM_COEFF = 1E6 +% +DEFINITION_DV= \ +( 19, 1.0 | fluid_pin2_interface, solid_pin2_interface, fluid_symmetry | BOX, 0, 1, 0.0, 1.0 );\ +( 19, 1.0 | fluid_pin2_interface, solid_pin2_interface, fluid_symmetry | BOX, 1, 1, 0.0, 1.0 );\ +( 19, 1.0 | fluid_pin2_interface, solid_pin2_interface, fluid_symmetry | BOX, 2, 1, 0.0, 1.0 );\ +( 19, 1.0 | fluid_pin2_interface, solid_pin2_interface, fluid_symmetry | BOX, 3, 1, 0.0, 1.0 );\ +( 19, 1.0 | fluid_pin2_interface, solid_pin2_interface, fluid_symmetry | BOX, 4, 1, 0.0, 1.0 );\ +( 19, 1.0 | fluid_pin2_interface, solid_pin2_interface, fluid_symmetry | BOX, 5, 1, 0.0, 1.0 );\ +( 19, 1.0 | fluid_pin2_interface, solid_pin2_interface, fluid_symmetry | BOX, 6, 1, 0.0, 1.0 );\ +( 19, 1.0 | fluid_pin2_interface, solid_pin2_interface, fluid_symmetry | BOX, 7, 1, 0.0, 1.0 );\ +( 19, 1.0 | fluid_pin2_interface, solid_pin2_interface, fluid_symmetry | BOX, 8, 1, 0.0, 1.0 ) + +%DEFORM_MESH= YES diff --git a/TestCases/incomp_navierstokes/streamwise_periodic/chtPinArray_2d/FD_configMaster.cfg b/TestCases/incomp_navierstokes/streamwise_periodic/chtPinArray_2d/FD_configMaster.cfg new file mode 100644 index 000000000000..9c29fb99e4e4 --- /dev/null +++ b/TestCases/incomp_navierstokes/streamwise_periodic/chtPinArray_2d/FD_configMaster.cfg @@ -0,0 +1,127 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% SU2 configuration file % +% Case description: 2D cylinder array with CHT couplings % +% Author: T. Kattmann % +% Institution: Robert Bosch GmbH % +% Date: 2020.12.15 % +% File Version 7.1.0 "Blackbird" % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +SOLVER= MULTIPHYSICS +% +CONFIG_LIST= (configFluid.cfg, configSolid.cfg) +% +MARKER_ZONE_INTERFACE= ( fluid_pin1_interface, solid_pin1_interface, fluid_pin2_interface, solid_pin2_interface, fluid_pin3_interface, solid_pin3_interface ) +% +MARKER_CHT_INTERFACE= ( fluid_pin1_interface, solid_pin1_interface, fluid_pin2_interface, solid_pin2_interface, fluid_pin3_interface, solid_pin3_interface ) +% +CONV_RESIDUAL_MINVAL= -26 +% +% FOR FAST RUNING REGRESSION TEST ONLY! +% FOR GADIENT VALIDATION USE OUTER_ITER= 3000! +OUTER_ITER= 101 + +% +%CHT_ROBIN= NO +% +SCREEN_OUTPUT= ( WALL_TIME, OUTER_ITER, BGS_PRESSURE[0], BGS_TEMPERATURE[0], BGS_TEMPERATURE[1], STREAMWISE_MASSFLOW[0], STREAMWISE_DP[0], AVG_TEMPERATURE[1] ) +SCREEN_WRT_FREQ_OUTER= 100 +% +HISTORY_OUTPUT= ( ITER, BGS_RES[0], BGS_RES[1], RMS_RES[0], RMS_RES[1], STREAMWISE_PERIODIC[0], FLOW_COEFF[0], AERO_COEFF[0], HEAT[1] ) +% +OUTPUT_FILES= ( RESTART, PARAVIEW_MULTIBLOCK ) +OUTPUT_WRT_FREQ= 10000 +% +MESH_FILENAME= 2D-PinArray_FFD.su2 +MESH_FORMAT= SU2 +% +% Options that have to be kept for finite_differences.py. Otherwise it won't run. +RESTART_SOL= NO +MARKER_MONITORING= ( NONE ) +SOLUTION_FILENAME= restart +SOLUTION_ADJ_FILENAME= restart_adj +RESTART_FILENAME= restart +CONV_FILENAME= history +TABULAR_FORMAT= CSV +% +% -------------------- FREE-FORM DEFORMATION PARAMETERS -----------------------% +% +FFD_TOLERANCE= 1E-10 +FFD_ITERATIONS= 500 +% +% FFD box definition: 2D case (FFD_BoxTag, X1, Y1, 0.0, X2, Y2, 0.0, X3, Y3, 0.0, X4, Y4, 0.0, +% 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) +FFD_DEFINITION= (BOX, 0.0029772,0.0,0.0, 0.0081772,0.0,0.0 0.0081772,0.0026,0.0, 0.0029772,0.0026,0.0, 0.0,0.0,0.0, 0.0,0.0,0.0 0.0,0.0,0.0, 0.0,0.0,0.0 ) +% +% FFD box degree: 2D case (x_degree, y_degree, 0) +FFD_DEGREE= (8, 1, 0) +% +% Surface grid continuity at the intersection with the faces of the FFD boxes. +% To keep a particular level of surface continuity, SU2 automatically freezes the right +% number of control point planes (NO_DERIVATIVE, 1ST_DERIVATIVE, 2ND_DERIVATIVE, USER_INPUT) +FFD_CONTINUITY= NO_DERIVATIVE +% +% ----------------------- DESIGN VARIABLE PARAMETERS --------------------------% +% +DV_KIND= FFD_SETTING +%DV_KIND= FFD_CONTROL_POINT_2D,FFD_CONTROL_POINT_2D,FFD_CONTROL_POINT_2D,FFD_CONTROL_POINT_2D,FFD_CONTROL_POINT_2D,FFD_CONTROL_POINT_2D,FFD_CONTROL_POINT_2D,FFD_CONTROL_POINT_2D,FFD_CONTROL_POINT_2D +% +% Marker of the surface in which we are going apply the shape deformation +MARKER_SYM= ( fluid_symmetry ) +DV_MARKER= ( fluid_pin2_interface, solid_pin2_interface, fluid_symmetry ) +% +% Parameters of the shape deformation +% - FFD_SETTING ( 1.0 ) +% - FFD_CONTROL_POINT_2D ( FFD_BoxTag, i_Ind, j_Ind, x_Disp, y_Disp ) +DV_PARAM= ( 1.0 ) +%DV_PARAM= \ +%( BOX, 0, 1, 0.0, 1.0);\ +%( BOX, 1, 1, 0.0, 1.0);\ +%( BOX, 2, 1, 0.0, 1.0);\ +%( BOX, 3, 1, 0.0, 1.0);\ +%( BOX, 4, 1, 0.0, 1.0);\ +%( BOX, 5, 1, 0.0, 1.0);\ +%( BOX, 6, 1, 0.0, 1.0);\ +%( BOX, 7, 1, 0.0, 1.0);\ +%( BOX, 8, 1, 0.0, 1.0) +% +% Value of the shape deformation +DV_VALUE= 1.0 +%DV_VALUE= 1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0 +% +% ------------------------ GRID DEFORMATION PARAMETERS ------------------------% +% +DEFORM_LINEAR_SOLVER= FGMRES +DEFORM_LINEAR_SOLVER_PREC= ILU +DEFORM_LINEAR_SOLVER_ERROR= 1E-14 +% +DEFORM_NONLINEAR_ITER= 1 +DEFORM_LINEAR_SOLVER_ITER= 1000 +% +DEFORM_CONSOLE_OUTPUT= YES +DEFORM_STIFFNESS_TYPE= WALL_DISTANCE +% +% Deformation coefficient (linear elasticity limits from -1.0 to 0.5, a larger +% value is also possible) +% !!! What is this doing !!! +DEFORM_COEFF = 1E6 +% +% For gradient validation uncomment the other DV's! +DEFINITION_DV= \ +( 19, 1.0 | fluid_pin2_interface, solid_pin2_interface, fluid_symmetry | BOX, 0, 1, 0.0, 1.0 );\ +%( 19, 1.0 | fluid_pin2_interface, solid_pin2_interface, fluid_symmetry | BOX, 1, 1, 0.0, 1.0 );\ +%( 19, 1.0 | fluid_pin2_interface, solid_pin2_interface, fluid_symmetry | BOX, 2, 1, 0.0, 1.0 );\ +%( 19, 1.0 | fluid_pin2_interface, solid_pin2_interface, fluid_symmetry | BOX, 3, 1, 0.0, 1.0 );\ +%( 19, 1.0 | fluid_pin2_interface, solid_pin2_interface, fluid_symmetry | BOX, 4, 1, 0.0, 1.0 );\ +%( 19, 1.0 | fluid_pin2_interface, solid_pin2_interface, fluid_symmetry | BOX, 5, 1, 0.0, 1.0 );\ +%( 19, 1.0 | fluid_pin2_interface, solid_pin2_interface, fluid_symmetry | BOX, 6, 1, 0.0, 1.0 );\ +%( 19, 1.0 | fluid_pin2_interface, solid_pin2_interface, fluid_symmetry | BOX, 7, 1, 0.0, 1.0 );\ +%( 19, 1.0 | fluid_pin2_interface, solid_pin2_interface, fluid_symmetry | BOX, 8, 1, 0.0, 1.0 ) + +%DEFORM_MESH= YES + +OPT_OBJECTIVE= AVG_TOTALTEMP +FIN_DIFF_STEP= 1e-8 +NZONES=2 diff --git a/TestCases/incomp_navierstokes/streamwise_periodic/chtPinArray_2d/README.md b/TestCases/incomp_navierstokes/streamwise_periodic/chtPinArray_2d/README.md new file mode 100644 index 000000000000..6b5b3615d406 --- /dev/null +++ b/TestCases/incomp_navierstokes/streamwise_periodic/chtPinArray_2d/README.md @@ -0,0 +1,28 @@ +# Gradient validation from start to finish + +This guide steps you through the steps necessary to perform a validation of the discrete adjoint sensitivities using finite differences. + +All necessary config files are present and this guide steps through the different tasks to do. + +If you are lucky enough too have some cores to spare, 14 is a suitable substitution for the `<#cores>` placeholder. + +## FFD-box creation +This step is optional as the provided mesh already contains FFD box. This is for completeness if a new mesh e.g. with different resolution is created. +In `configMaster.cfg` the mentioned options have to be uncommented and others commented if they appear twice in the config. +Note that (only!) for the FFD-box creation a `MARKER_HEATFLUX= ( fluid_symmetry ) is artificially is set to avoid an error. This has to be done to make the config-Postprocessing aware that this marker exists as it is used in `DV_MARKER`. +Call `SU2_DEF configMaster.cfg` which creates the new mesh with the name given in 'MESH_OUT_FILENAME'. + +## Primal run +Run `mpirun -n <#cores> SU2_CFD configMaster.cfg` + +## Discrete-Adjoint run +Rename\copy\symlink `restart_*.dat` -> `solution_*.dat` +Run `mpirun -n <#cores> SU2_CFD_AD DA_configMaster.cfg` and afterwards `SU2_DOT_AD DA_configMaster.cfg` + +## Finite-Differences run +The `OUTER_ITER` is set low in order to be suitable for the regression test. Set that back the number given in the config. +For the full gradient validation uncomment all design variables of the `DEFINITION_DV` config option. +Run `finite_differences.py -f FD_configMaster.cfg -z 2 -n <#cores>`. + +## Comparing results +Just plot the `of_grad.csv` and `FINDIFF/of_grad_findiff.csv` with your tool of choice. Paraview's `Line Chart View` is one option. diff --git a/TestCases/incomp_navierstokes/streamwise_periodic/chtPinArray_2d/configFluid.cfg b/TestCases/incomp_navierstokes/streamwise_periodic/chtPinArray_2d/configFluid.cfg new file mode 100644 index 000000000000..9f156eaa9090 --- /dev/null +++ b/TestCases/incomp_navierstokes/streamwise_periodic/chtPinArray_2d/configFluid.cfg @@ -0,0 +1,128 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% SU2 configuration file % +% Case description: Unit Cell flow around pin array (fluid) % +% Author: T. Kattmann % +% Institution: Robert Bosch GmbH % +% Date: 2020.12.15 % +% File Version 7.0.8 "Blackbird" % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% ------------- DIRECT, ADJOINT, AND LINEARIZED PROBLEM DEFINITION ------------% +% +SOLVER= INC_RANS +% +KIND_TURB_MODEL= SST +% +OBJECTIVE_FUNCTION= AVG_TEMPERATURE +OBJECTIVE_WEIGHT= 0.0 +% +OPT_OBJECTIVE= NONE +% ---------------- INCOMPRESSIBLE FLOW CONDITION DEFINITION -------------------% +% +INC_DENSITY_MODEL= CONSTANT +INC_DENSITY_INIT= 1045.0 +INC_VELOCITY_INIT= ( 0.1, 0.0, 0.0 ) +% +INC_ENERGY_EQUATION = YES +INC_TEMPERATURE_INIT= 338.0 +INC_NONDIM= DIMENSIONAL +SPECIFIC_HEAT_CP= 3540.0 +% +FREESTREAM_TURBULENCEINTENSITY= 0.05 +FREESTREAM_TURB2LAMVISCRATIO= 10.0 +% +% --------------------------- VISCOSITY MODEL ---------------------------------% +% +VISCOSITY_MODEL= CONSTANT_VISCOSITY +MU_CONSTANT= 0.001385 +% +% --------------------------- THERMAL CONDUCTIVITY MODEL ----------------------% +% +% Pr_lam = mu_lam [Pa*s] * c_p [J/(kg*K)] / lambda[W/(m*K)] +% = 1.385e-3 * 3540 / 0.42 +% = 11.7 +CONDUCTIVITY_MODEL= CONSTANT_PRANDTL +PRANDTL_LAM= 11.7 +% +TURBULENT_CONDUCTIVITY_MODEL= CONSTANT_PRANDTL_TURB +PRANDTL_TURB= 0.90 +% +% --------------------- STREAMWISE PERIODICITY DEFINITION ---------------------% +% +KIND_STREAMWISE_PERIODIC= PRESSURE_DROP +STREAMWISE_PERIODIC_PRESSURE_DROP= 208.023676 +%STREAMWISE_PERIODIC_MASSFLOW= 0.85 +%INC_OUTLET_DAMPING= 0.001 +% +STREAMWISE_PERIODIC_TEMPERATURE= NO +% +% inner pin length 0.00376991 m = (0.00322-0.00262)*2*pi +% with 5e5 W/m that is Q = 1884.96 +STREAMWISE_PERIODIC_OUTLET_HEAT= -1884.96 +% +% -------------------- BOUNDARY CONDITION DEFINITION --------------------------% +% +MARKER_SYM= ( fluid_symmetry ) +MARKER_PERIODIC= ( fluid_inlet, fluid_outlet, 0.0,0.0,0.0, 0.0,0.0,0.0, 0.0111544,0.0,0.0 ) +% +% Alternative to periodic simulation with velocity inlet and pressure outlet +%MARKER_HEATFLUX= ( fluid_pin1_interface, 5e5, \ +% fluid_pin2_interface, 5e5, \ +% fluid_pin3_interface, 5e5 ) +% +% Alternative options for non-periodic flow +%INC_INLET_TYPE= VELOCITY_INLET +%MARKER_INLET= ( fluid_inlet, 338.0, 0.75, 1.0, 0.0, 0.0 ) +% Test vals to hinder outlet backflow +%MARKER_INLET= ( fluid_inlet, 338.0, 0.3, 1.0, 0.0, 0.0 ) +% +%INC_OUTLET_TYPE= PRESSURE_OUTLET +%MARKER_OUTLET= ( fluid_outlet, 0.0 ) +% +% ------------------------ SURFACES IDENTIFICATION ----------------------------% +% +MARKER_MONITORING= ( NONE ) +% +MARKER_ANALYZE = ( fluid_outlet, fluid_inlet ) +MARKER_ANALYZE_AVERAGE = MASSFLUX +% +% ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% +% +%ITER= 3500 +NUM_METHOD_GRAD= GREEN_GAUSS +CFL_NUMBER= 1e3 +% +% ------------------------ LINEAR SOLVER DEFINITION ---------------------------% +% +LINEAR_SOLVER= FGMRES +LINEAR_SOLVER_PREC= ILU +LINEAR_SOLVER_ERROR= 1e-15 +LINEAR_SOLVER_ITER= 10 +% +% -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% +% +CONV_NUM_METHOD_FLOW= FDS +MUSCL_FLOW= YES +SLOPE_LIMITER_FLOW= NONE +TIME_DISCRE_FLOW= EULER_IMPLICIT +% +% -------------------- TURBULENT NUMERICAL METHOD DEFINITION ------------------% +% +CONV_NUM_METHOD_TURB= SCALAR_UPWIND +MUSCL_TURB= NO +SLOPE_LIMITER_TURB= NONE +TIME_DISCRE_TURB= EULER_IMPLICIT +% +% --------------------------- CONVERGENCE PARAMETERS --------------------------% +% +CONV_CRITERIA= RESIDUAL +CONV_RESIDUAL_MINVAL= -26 +CONV_STARTITER= 100000000 +% +% ------------------------- INPUT/OUTPUT INFORMATION --------------------------% +% +%MESH_FILENAME= fluid.su2 +% +HISTORY_OUTPUT= ( ITER, RMS_RES, STREAMWISE_PERIODIC, FLOW_COEFF, LINSOL, HEAT ) diff --git a/TestCases/incomp_navierstokes/streamwise_periodic/chtPinArray_2d/configMaster.cfg b/TestCases/incomp_navierstokes/streamwise_periodic/chtPinArray_2d/configMaster.cfg new file mode 100644 index 000000000000..111367a0e1a6 --- /dev/null +++ b/TestCases/incomp_navierstokes/streamwise_periodic/chtPinArray_2d/configMaster.cfg @@ -0,0 +1,116 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% SU2 configuration file % +% Case description: 2D cylinder array with CHT couplings % +% Author: T. Kattmann % +% Institution: Robert Bosch GmbH % +% Date: 2020.12.15 % +% File Version 7.1.0 "Blackbird" % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +SOLVER= MULTIPHYSICS +% +CONFIG_LIST= (configFluid.cfg, configSolid.cfg) +% +MARKER_ZONE_INTERFACE= ( fluid_pin1_interface, solid_pin1_interface, fluid_pin2_interface, solid_pin2_interface, fluid_pin3_interface, solid_pin3_interface ) +% +MARKER_CHT_INTERFACE= ( fluid_pin1_interface, solid_pin1_interface, fluid_pin2_interface, solid_pin2_interface, fluid_pin3_interface, solid_pin3_interface ) +% +CONV_RESIDUAL_MINVAL= -26 +% +% Number of total iterations +OUTER_ITER= 4000 +% +%CHT_ROBIN= NO +% +SCREEN_OUTPUT= ( OUTER_ITER, BGS_PRESSURE[0], BGS_TEMPERATURE[0], BGS_TEMPERATURE[1], STREAMWISE_MASSFLOW[0], STREAMWISE_DP[0], AVG_TEMPERATURE[1] ) +SCREEN_WRT_FREQ_OUTER= 100 +% +HISTORY_OUTPUT= ( ITER, BGS_RES[0], BGS_RES[1], RMS_RES[0], RMS_RES[1], STREAMWISE_PERIODIC[0], FLOW_COEFF[0], HEAT[1], LINSOL[0], LINSOL[1], HEAT[0] ) +% +OUTPUT_FILES= ( RESTART, PARAVIEW_MULTIBLOCK ) +OUTPUT_WRT_FREQ= 1000 +% +MESH_FILENAME= 2D-PinArray_FFD.su2 +MESH_FORMAT= SU2 +% +% -------------------- FREE-FORM DEFORMATION PARAMETERS -----------------------% +% +FFD_TOLERANCE= 1E-10 +FFD_ITERATIONS= 500 +% +% FFD box definition: 2D case (FFD_BoxTag, X1, Y1, 0.0, X2, Y2, 0.0, X3, Y3, 0.0, X4, Y4, 0.0, +% 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) +FFD_DEFINITION= (BOX, 0.0029772,0.0,0.0, 0.0081772,0.0,0.0 0.0081772,0.0026,0.0, 0.0029772,0.0026,0.0, 0.0,0.0,0.0, 0.0,0.0,0.0 0.0,0.0,0.0, 0.0,0.0,0.0 ) +% +% FFD box degree: 2D case (x_degree, y_degree, 0) +FFD_DEGREE= (8, 1, 0) +% +% Surface grid continuity at the intersection with the faces of the FFD boxes. +% To keep a particular level of surface continuity, SU2 automatically freezes the right +% number of control point planes (NO_DERIVATIVE, 1ST_DERIVATIVE, 2ND_DERIVATIVE, USER_INPUT) +FFD_CONTINUITY= NO_DERIVATIVE +% +% ----------------------- DESIGN VARIABLE PARAMETERS --------------------------% +% +% Config options for writing the FFD-box into the mesh. +% Comment these options if they appear elsewhere in the .cfg file. +%DV_KIND= FFD_SETTING +%DV_PARAM= ( 1.0 ) +%DV_VALUE= 1.0 +%MESH_FILENAME= 2D-PinArray.su2 +%MESH_OUT_FILENAME= 2D-PinArray_FFD.su2 +MARKER_SYM= ( fluid_symmetry ) + +DV_KIND= FFD_CONTROL_POINT_2D,FFD_CONTROL_POINT_2D,FFD_CONTROL_POINT_2D,FFD_CONTROL_POINT_2D,FFD_CONTROL_POINT_2D,FFD_CONTROL_POINT_2D,FFD_CONTROL_POINT_2D,FFD_CONTROL_POINT_2D,FFD_CONTROL_POINT_2D +% +% Marker of the surface in which we are going apply the shape deformation +DV_MARKER= ( fluid_pin2_interface, solid_pin2_interface, fluid_symmetry ) +% +% Parameters of the shape deformation +% - FFD_SETTING ( 1.0 ) +% - FFD_CONTROL_POINT_2D ( FFD_BoxTag, i_Ind, j_Ind, x_Disp, y_Disp ) +DV_PARAM= \ +( BOX, 0, 1, 0.0, 1.0);\ +( BOX, 1, 1, 0.0, 1.0);\ +( BOX, 2, 1, 0.0, 1.0);\ +( BOX, 3, 1, 0.0, 1.0);\ +( BOX, 4, 1, 0.0, 1.0);\ +( BOX, 5, 1, 0.0, 1.0);\ +( BOX, 6, 1, 0.0, 1.0);\ +( BOX, 7, 1, 0.0, 1.0);\ +( BOX, 8, 1, 0.0, 1.0) +% +% Value of the shape deformation +DV_VALUE= 1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0 +% +% ------------------------ GRID DEFORMATION PARAMETERS ------------------------% +% +DEFORM_LINEAR_SOLVER= FGMRES +DEFORM_LINEAR_SOLVER_PREC= ILU +DEFORM_LINEAR_SOLVER_ERROR= 1E-14 +% +DEFORM_NONLINEAR_ITER= 1 +DEFORM_LINEAR_SOLVER_ITER= 1000 +% +DEFORM_CONSOLE_OUTPUT= YES +DEFORM_STIFFNESS_TYPE= WALL_DISTANCE +% +% Deformation coefficient (linear elasticity limits from -1.0 to 0.5, a larger +% value is also possible) +% !!! What is this doing !!! +DEFORM_COEFF = 1E6 +% +DEFINITION_DV= \ +( 19, 1.0 | fluid_pin2_interface, solid_pin2_interface, fluid_symmetry | BOX, 0, 1, 0.0, 1.0 );\ +( 19, 1.0 | fluid_pin2_interface, solid_pin2_interface, fluid_symmetry | BOX, 1, 1, 0.0, 1.0 );\ +( 19, 1.0 | fluid_pin2_interface, solid_pin2_interface, fluid_symmetry | BOX, 2, 1, 0.0, 1.0 );\ +( 19, 1.0 | fluid_pin2_interface, solid_pin2_interface, fluid_symmetry | BOX, 3, 1, 0.0, 1.0 );\ +( 19, 1.0 | fluid_pin2_interface, solid_pin2_interface, fluid_symmetry | BOX, 4, 1, 0.0, 1.0 );\ +( 19, 1.0 | fluid_pin2_interface, solid_pin2_interface, fluid_symmetry | BOX, 5, 1, 0.0, 1.0 );\ +( 19, 1.0 | fluid_pin2_interface, solid_pin2_interface, fluid_symmetry | BOX, 6, 1, 0.0, 1.0 );\ +( 19, 1.0 | fluid_pin2_interface, solid_pin2_interface, fluid_symmetry | BOX, 7, 1, 0.0, 1.0 );\ +( 19, 1.0 | fluid_pin2_interface, solid_pin2_interface, fluid_symmetry | BOX, 8, 1, 0.0, 1.0 ) + +%DEFORM_MESH= YES diff --git a/TestCases/incomp_navierstokes/streamwise_periodic/chtPinArray_2d/configSolid.cfg b/TestCases/incomp_navierstokes/streamwise_periodic/chtPinArray_2d/configSolid.cfg new file mode 100644 index 000000000000..fa52f63e3f95 --- /dev/null +++ b/TestCases/incomp_navierstokes/streamwise_periodic/chtPinArray_2d/configSolid.cfg @@ -0,0 +1,70 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% SU2 configuration file % +% Case description: Unit Cell flow around pin array (solid) % +% Author: T. Kattmann % +% Institution: Robert Bosch GmbH % +% Date: 2020.12.15 % +% File Version 7.1.0 "Blackbird" % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% ------------- DIRECT, ADJOINT, AND LINEARIZED PROBLEM DEFINITION ------------% +% +SOLVER= HEAT_EQUATION +% +OBJECTIVE_FUNCTION= AVG_TEMPERATURE +OBJECTIVE_WEIGHT= 1.0 +% +OPT_OBJECTIVE= AVG_TOTALTEMP +% +% ---------------- (SOLIDS) CONDUCTION CONDITION DEFINITION -------------------% +% +INC_NONDIM= DIMENSIONAL +SOLID_TEMPERATURE_INIT= 345.0 +SOLID_DENSITY= 2719 +SPECIFIC_HEAT_CP = 871.0 +SOLID_THERMAL_CONDUCTIVITY= 200 +% +% -------------------- BOUNDARY CONDITION DEFINITION --------------------------% +% +MARKER_HEATFLUX= (solid_pin1_inner, 5e5, \ + solid_pin2_inner, 5e5, \ + solid_pin3_inner, 5e5, \ + solid_pin1_walls, 0.0, \ + solid_pin2_walls, 0.0, \ + solid_pin3_walls, 0.0) +% +%MARKER_ISOTHERMAL= (solid_pin1_inner, 300, solid_pin2_inner, 300, solid_pin3_inner, 300, solid_pin1_walls, 300, solid_pin2_walls, 300, solid_pin3_walls, 300) +% +% ------------------------ SURFACES IDENTIFICATION ----------------------------% +% +MARKER_MONITORING = ( solid_pin2_inner ) +% +% ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% +% +NUM_METHOD_GRAD= GREEN_GAUSS +CFL_NUMBER= 1e4 +% +% ------------------------ LINEAR SOLVER DEFINITION ---------------------------% +% +LINEAR_SOLVER= FGMRES +LINEAR_SOLVER_PREC= ILU +LINEAR_SOLVER_ERROR= 1E-15 +LINEAR_SOLVER_ITER= 20 +% +% --------------------------- CONVERGENCE PARAMETERS --------------------------% +% +CONV_CRITERIA= RESIDUAL +CONV_RESIDUAL_MINVAL= -20 +CONV_STARTITER= 10000000000 +% +% -------------------- HEAT NUMERICAL METHOD DEFINITION -----------------------% +% +TIME_DISCRE_HEAT= EULER_IMPLICIT +% +% ------------------------- INPUT/OUTPUT INFORMATION --------------------------% +% +%MESH_FILENAME= solid.su2 +% +HISTORY_OUTPUT= (ITER, RMS_RES, HEAT, LINSOL) diff --git a/TestCases/incomp_navierstokes/streamwise_periodic/chtPinArray_2d/of_grad_findiff.csv.ref b/TestCases/incomp_navierstokes/streamwise_periodic/chtPinArray_2d/of_grad_findiff.csv.ref new file mode 100644 index 000000000000..c830b62a8379 --- /dev/null +++ b/TestCases/incomp_navierstokes/streamwise_periodic/chtPinArray_2d/of_grad_findiff.csv.ref @@ -0,0 +1,2 @@ +"VARIABLE" , "AVG_DENSITY[0]", "AVG_ENTHALPY[0]", "AVG_NORMALVEL[0]", "DRAG[0]" , "EFFICIENCY[0]" , "FORCE_X[0]" , "FORCE_Y[0]" , "FORCE_Z[0]" , "LIFT[0]" , "MOMENT_X[0]" , "MOMENT_Y[0]" , "MOMENT_Z[0]" , "SIDEFORCE[0]" , "SURFACE_MACH[0]", "SURFACE_MASSFLOW[0]", "SURFACE_MOM_DISTORTION[0]", "SURFACE_PRESSURE_DROP[0]", "SURFACE_SECONDARY[0]", "SURFACE_SECOND_OVER_UNIFORM[0]", "SURFACE_STATIC_PRESSURE[0]", "SURFACE_STATIC_TEMPERATURE[0]", "SURFACE_TOTAL_PRESSURE[0]", "SURFACE_TOTAL_TEMPERATURE[0]", "SURFACE_UNIFORMITY[0]", "AVG_TEMPERATURE[1]", "MAXIMUM_HEATFLUX[1]", "TOTAL_HEATFLUX[1]", "FINDIFF_STEP" +0 , 0.0 , -100000.01639127731, 8.88180000002836e-08, 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , -0.04999999997368221, -5.5510000002640306e-08, -2.069999999187999 , 0.0 , 2.129999999989085 , 3.6999999980524834 , 330.00000030369847 , -30.00000106112566 , 314.99999977313564 , -30.00000106112566 , -1.400000004814217 , -129.99999512430804, 0.0 , -510.0000066704524, 1e-08 diff --git a/TestCases/incomp_navierstokes/streamwise_periodic/chtPinArray_3d/configFluid.cfg b/TestCases/incomp_navierstokes/streamwise_periodic/chtPinArray_3d/configFluid.cfg new file mode 100644 index 000000000000..7ef30f52a04f --- /dev/null +++ b/TestCases/incomp_navierstokes/streamwise_periodic/chtPinArray_3d/configFluid.cfg @@ -0,0 +1,114 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% SU2 configuration file % +% Case description: Unit Cell flow around pin array 3d (fluid) % +% Author: T. Kattmann % +% Institution: Robert Bosch GmbH % +% Date: 07.06.2019 % +% File Version 7.1.0 "Blackbird" % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% ------------- DIRECT, ADJOINT, AND LINEARIZED PROBLEM DEFINITION ------------% +% +SOLVER= INC_RANS +KIND_TURB_MODEL= SST +% +% ---------------- INCOMPRESSIBLE FLOW CONDITION DEFINITION -------------------% +% +INC_DENSITY_MODEL= CONSTANT +INC_DENSITY_INIT= 1045.0 +INC_VELOCITY_INIT= ( 0.1, 0.0, 0.0 ) +% +INC_ENERGY_EQUATION = YES +INC_TEMPERATURE_INIT= 338.0 +SPECIFIC_HEAT_CP= 3540.0 +% +INC_NONDIM= DIMENSIONAL +% +VISCOSITY_MODEL= CONSTANT_VISCOSITY +MU_CONSTANT= 0.001385 +% +FREESTREAM_TURBULENCEINTENSITY= 0.05 +FREESTREAM_TURB2LAMVISCRATIO= 10.0 +% +% --------------------------- THERMAL CONDUCTIVITY MODEL ----------------------% +% +% Pr_lam = mu_lam [Pa*s] * c_p [J/(kg*K)] / lambda[W/(m*K)] +% = 1.385e-3 * 3540 / 0.42 +% = 11.7 +CONDUCTIVITY_MODEL= CONSTANT_PRANDTL +PRANDTL_LAM= 11.7 +% +TURBULENT_CONDUCTIVITY_MODEL= CONSTANT_PRANDTL_TURB +PRANDTL_TURB= 0.90 +% +% --------------------- STREAMWISE PERIODICITY DEFINITION ---------------------% +% +KIND_STREAMWISE_PERIODIC= MASSFLOW +STREAMWISE_PERIODIC_PRESSURE_DROP= 210 +STREAMWISE_PERIODIC_MASSFLOW= 0.009675 +INC_OUTLET_DAMPING= 0.001 +% +STREAMWISE_PERIODIC_TEMPERATURE= NO +STREAMWISE_PERIODIC_OUTLET_HEAT= -17.958584 +% +% -------------------- BOUNDARY CONDITION DEFINITION --------------------------% +% +MARKER_HEATFLUX= ( fluid_top, 0.0, \ + fluid_bottom_interface, 0.0, \ + fluid_pin1, 0.0, \ + fluid_pin3, 0.0 ) +MARKER_SYM= ( fluid_sym_sides ) +MARKER_PERIODIC= ( fluid_inlet, fluid_outlet, 0.0,0.0,0.0, 0.0,0.0,0.0, 0.0111544,0.0,0.0 ) +% +% Alternative to periodic simulation +%INC_INLET_TYPE= VELOCITY_INLET +%MARKER_INLET= ( fluid_inlet, 338.0, 0.75, 1.0, 0.0, 0.0 ) +% +%INC_OUTLET_TYPE= PRESSURE_OUTLET +%MARKER_OUTLET= ( fluid_outlet, 0.0 ) +% +% ------------------------ SURFACES IDENTIFICATION ----------------------------% +% +MARKER_MONITORING= ( fluid_inlet, fluid_outlet ) +% +MARKER_ANALYZE = ( fluid_outlet, fluid_inlet ) +MARKER_ANALYZE_AVERAGE = MASSFLUX +% +% ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% +% +NUM_METHOD_GRAD= GREEN_GAUSS +CFL_NUMBER= 10 +CFL_ADAPT= NO +% +% ------------------------ LINEAR SOLVER DEFINITION ---------------------------% +% +LINEAR_SOLVER= FGMRES +LINEAR_SOLVER_PREC= ILU +LINEAR_SOLVER_ERROR= 1E-15 +LINEAR_SOLVER_ITER= 15 +% +% -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% +% +CONV_NUM_METHOD_FLOW= FDS +MUSCL_FLOW= YES +SLOPE_LIMITER_FLOW= NONE +TIME_DISCRE_FLOW= EULER_IMPLICIT +% +% -------------------- TURBULENT NUMERICAL METHOD DEFINITION ------------------% +% +CONV_NUM_METHOD_TURB= SCALAR_UPWIND +MUSCL_TURB= NO +SLOPE_LIMITER_TURB= NONE +TIME_DISCRE_TURB= EULER_IMPLICIT +% +% --------------------------- CONVERGENCE PARAMETERS --------------------------% +% +CONV_CRITERIA= RESIDUAL +CONV_RESIDUAL_MINVAL= -26 +CONV_STARTITER= 100000000 +% +% ------------------------- INPUT/OUTPUT INFORMATION --------------------------% +% +HISTORY_OUTPUT= ( ITER, RMS_RES, STREAMWISE_PERIODIC, FLOW_COEFF ) diff --git a/TestCases/incomp_navierstokes/streamwise_periodic/chtPinArray_3d/configMaster.cfg b/TestCases/incomp_navierstokes/streamwise_periodic/chtPinArray_3d/configMaster.cfg new file mode 100644 index 000000000000..621ec559cd66 --- /dev/null +++ b/TestCases/incomp_navierstokes/streamwise_periodic/chtPinArray_3d/configMaster.cfg @@ -0,0 +1,42 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% SU2 configuration file % +% Case description: 3D cylinder array with CHT couplings % +% Author: T. Kattmann % +% Institution: Robert Bosch GmbH % +% Date: 2020.12.15 % +% File Version 7.1.0 "Blackbird" % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +SOLVER= MULTIPHYSICS +% +CONFIG_LIST = (configFluid.cfg, configSolid.cfg) +% +MARKER_ZONE_INTERFACE= (fluid_bottom_interface, solid_bottom_interface, fluid_pin1, solid_pin1, fluid_pin2, solid_pin2, fluid_pin3, solid_pin3 ) +% +MARKER_CHT_INTERFACE= (fluid_bottom_interface, solid_bottom_interface, fluid_pin1, solid_pin1, fluid_pin2, solid_pin2, fluid_pin3, solid_pin3 ) +% +OUTER_ITER = 15000 +% +CONV_RESIDUAL_MINVAL= -26 +% +SCREEN_OUTPUT= (OUTER_ITER, BGS_PRESSURE[0], BGS_TEMPERATURE[0], BGS_TEMPERATURE[1], STREAMWISE_MASSFLOW[0], STREAMWISE_DP[0], AVG_TEMPERATURE[1] ) +SCREEN_WRT_FREQ_OUTER= 100 +% +OUTPUT_FILES= (RESTART, PARAVIEW_MULTIBLOCK) +OUTPUT_WRT_FREQ= 2500 +% +%CHT_ROBIN= NO +% +% Mesh input file +MESH_FILENAME= 3D_chtPinArray_coarse.su2 +% +% ----------------------- DESIGN VARIABLE PARAMETERS --------------------------% +% +% These are just default parameters so that we can run SU2_DOT_AD, they have no physical meaning for this test case. +% +DV_KIND= HICKS_HENNE +DV_MARKER= (fluid_pin2, solid_pin2) +DV_PARAM= (0.0, 0.5) +DV_VALUE= 0.1 diff --git a/TestCases/incomp_navierstokes/streamwise_periodic/chtPinArray_3d/configSolid.cfg b/TestCases/incomp_navierstokes/streamwise_periodic/chtPinArray_3d/configSolid.cfg new file mode 100644 index 000000000000..c4eb21b915c3 --- /dev/null +++ b/TestCases/incomp_navierstokes/streamwise_periodic/chtPinArray_3d/configSolid.cfg @@ -0,0 +1,70 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% SU2 configuration file % +% Case description: Unit Cell flow around pin array (solid) % +% Author: T. Kattmann % +% Institution: Robert Bosch GmbH % +% Date: 07.06.2019 % +% File Version 7.1.0 "Blackbird" % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% ------------- DIRECT, ADJOINT, AND LINEARIZED PROBLEM DEFINITION ------------% +% +SOLVER= HEAT_EQUATION +% +% ---------------- (SOLIDS) CONDUCTION CONDITION DEFINITION -------------------% +% +INC_NONDIM= DIMENSIONAL +SOLID_TEMPERATURE_INIT= 345.0 +SOLID_DENSITY= 2719 +SPECIFIC_HEAT_CP = 871.0 +SOLID_THERMAL_CONDUCTIVITY= 200 +% +% -------------------- BOUNDARY CONDITION DEFINITION --------------------------% +% +MARKER_SYM= ( solid_sym_sides) +% +MARKER_HEATFLUX= ( solid_bottom_heater, 5e5, \ + solid_block_inlet, 0.0, \ + solid_block_outlet, 0.0, \ + solid_pin1_inlet, 0.0, \ + solid_pin3_outlet, 0.0, \ + solid_pins_top, 0.0, \ + solid_bottom_interface, 0.0, \ + solid_pin1, 0.0, \ + solid_pin3, 0.0 ) +% +%MARKER_HEATFLUX= ( solid_bottom_heater, 5e5, solid_block_inlet, 0.0, solid_block_outlet, 0.0, solid_pin1_inlet, 0.0, solid_pin3_outlet, 0.0, solid_pins_top, 0.0 ) +%MARKER_ISOTHERMAL= ( solid_bottom_heater, 300 ) +% +% ------------------------ SURFACES IDENTIFICATION ----------------------------% +% +MARKER_MONITORING = ( solid_bottom_heater ) +% +% ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% +% +NUM_METHOD_GRAD= GREEN_GAUSS +CFL_NUMBER= 1000 +% +% ------------------------ LINEAR SOLVER DEFINITION ---------------------------% +% +LINEAR_SOLVER= FGMRES +LINEAR_SOLVER_PREC= ILU +LINEAR_SOLVER_ERROR= 1E-18 +LINEAR_SOLVER_ITER= 15 +% +% --------------------------- CONVERGENCE PARAMETERS --------------------------% +% +CONV_CRITERIA= RESIDUAL +CONV_RESIDUAL_MINVAL= -20 +CONV_STARTITER= 10000000000 +% +% -------------------- HEAT NUMERICAL METHOD DEFINITION -----------------------% +% +CONV_NUM_METHOD_HEAT = SPACE_CENTERED +TIME_DISCRE_HEAT= EULER_IMPLICIT +% +% ------------------------- INPUT/OUTPUT INFORMATION --------------------------% +% +HISTORY_OUTPUT= (ITER, RMS_RES, HEAT) diff --git a/TestCases/incomp_navierstokes/streamwise_periodic/pipeSlice_3d/sp_pipeSlice_3d_dp_hf_tp.cfg b/TestCases/incomp_navierstokes/streamwise_periodic/pipeSlice_3d/sp_pipeSlice_3d_dp_hf_tp.cfg new file mode 100644 index 000000000000..ffba18c797fc --- /dev/null +++ b/TestCases/incomp_navierstokes/streamwise_periodic/pipeSlice_3d/sp_pipeSlice_3d_dp_hf_tp.cfg @@ -0,0 +1,86 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% SU2 configuration file % +% Case description: Poiseuille flow for testing a body force/periodicity % +% Author: T. Kattmann % +% Institution: Robert Bosch GmbH % +% Date: 2020.12.14 % +% File Version 7.1.0 "Blackbird" % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% ------------- DIRECT, ADJOINT, AND LINEARIZED PROBLEM DEFINITION ------------% +% +SOLVER= INC_NAVIER_STOKES +% +KIND_TURB_MODEL= NONE +% +% ---------------- INCOMPRESSIBLE FLOW CONDITION DEFINITION -------------------% +% +INC_DENSITY_MODEL= CONSTANT +INC_ENERGY_EQUATION = NO +INC_DENSITY_INIT= 1.0 +INC_VELOCITY_INIT= ( 0.0, 0.0, 0.3 ) +INC_NONDIM= DIMENSIONAL +% +% --------------------------- VISCOSITY MODEL ---------------------------------% +% +VISCOSITY_MODEL= CONSTANT_VISCOSITY +MU_CONSTANT= 1.8e-5 +% +% --------------------- STREAMWISE PERIODICITY DEFINITION ---------------------% +% +KIND_STREAMWISE_PERIODIC= PRESSURE_DROP +STREAMWISE_PERIODIC_PRESSURE_DROP= 0.001 +% +% -------------------- BOUNDARY CONDITION DEFINITION --------------------------% +% +MARKER_HEATFLUX= (wall, 0.0) +MARKER_PERIODIC= ( inlet, outlet, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0005 ) +% +MARKER_PLOTTING= ( inlet ) +MARKER_MONITORING= ( wall ) +MARKER_ANALYZE = ( oulet ) +MARKER_ANALYZE_AVERAGE = AREA +% +% ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% +% +NUM_METHOD_GRAD= WEIGHTED_LEAST_SQUARES +%CFL_NUMBER= 1e10 +CFL_NUMBER= 50000 +%CFL_ADAPT= YES +CFL_ADAPT= NO +CFL_ADAPT_PARAM= ( 0.5, 10, 15.0, 1e30 ) +ITER= 15000 +% +% ------------------------ LINEAR SOLVER DEFINITION ---------------------------% +% +LINEAR_SOLVER= FGMRES +LINEAR_SOLVER_PREC= ILU +LINEAR_SOLVER_ERROR= 1E-15 +LINEAR_SOLVER_ITER= 10 +% +% -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% +% +CONV_NUM_METHOD_FLOW= FDS +MUSCL_FLOW= YES +SLOPE_LIMITER_FLOW= NONE +TIME_DISCRE_FLOW= EULER_IMPLICIT +% +% --------------------------- CONVERGENCE PARAMETERS --------------------------% +% +CONV_CRITERIA= RESIDUAL +CONV_RESIDUAL_MINVAL= -24 +CONV_STARTITER= 10 +% +% ------------------------- INPUT/OUTPUT INFORMATION ----------------------.su2 +% +MESH_FILENAME= pipe1cell3D.su2 +% +OUTPUT_FILES= ( RESTART, PARAVIEW_MULTIBLOCK, SURFACE_TECPLOT_ASCII ) +OUTPUT_WRT_FREQ= 1000 +% +HISTORY_OUTPUT= ( RMS_RES, FLOW_COEFF, STREAMWISE_PERIODIC, LINSOL ) +% +SCREEN_OUTPUT= ( INNER_ITER, RMS_PRESSURE, RMS_VELOCITY-X, RMS_VELOCITY-Z, STREAMWISE_MASSFLOW ) +SCREEN_WRT_FREQ_INNER= 100 diff --git a/TestCases/parallel_regression.py b/TestCases/parallel_regression.py index 2f18ab912e46..489db0f20d5c 100644 --- a/TestCases/parallel_regression.py +++ b/TestCases/parallel_regression.py @@ -463,6 +463,17 @@ def main(): inc_lam_bend.tol = 0.00001 test_list.append(inc_lam_bend) + # 3D laminar channnel with 1 cell in flow direction, streamwise periodic + sp_pipeSlice_3d_dp_hf_tp = TestCase('sp_pipeSlice_3d_dp_hf_tp') + sp_pipeSlice_3d_dp_hf_tp.cfg_dir = "incomp_navierstokes/streamwise_periodic/pipeSlice_3d" + sp_pipeSlice_3d_dp_hf_tp.cfg_file = "sp_pipeSlice_3d_dp_hf_tp.cfg" + sp_pipeSlice_3d_dp_hf_tp.test_iter = 10 + sp_pipeSlice_3d_dp_hf_tp.test_vals = [-11.119796, -11.234737, -8.694310, -0.000023] #last 4 lines + sp_pipeSlice_3d_dp_hf_tp.su2_exec = "mpirun -n 2 SU2_CFD" + sp_pipeSlice_3d_dp_hf_tp.timeout = 1600 + sp_pipeSlice_3d_dp_hf_tp.tol = 0.00001 + test_list.append(sp_pipeSlice_3d_dp_hf_tp) + ############################ ### Incompressible RANS ### ############################ @@ -1243,6 +1254,30 @@ def main(): cht_compressible.tol = 0.00001 test_list.append(cht_compressible) + # 2D CHT case streamwise periodicity + sp_pinArray_cht_2d_dp_hf = TestCase('sp_pinArray_cht_2d_dp_hf') + sp_pinArray_cht_2d_dp_hf.cfg_dir = "incomp_navierstokes/streamwise_periodic/chtPinArray_2d" + sp_pinArray_cht_2d_dp_hf.cfg_file = "configMaster.cfg" + sp_pinArray_cht_2d_dp_hf.test_iter = 100 + sp_pinArray_cht_2d_dp_hf.test_vals = [0.247022, -0.812199, -0.974877, -0.753315, 208.023676, 349.950000] #last 7 lines + sp_pinArray_cht_2d_dp_hf.su2_exec = "mpirun -n 2 SU2_CFD" + sp_pinArray_cht_2d_dp_hf.timeout = 1600 + sp_pinArray_cht_2d_dp_hf.tol = 0.00001 + sp_pinArray_cht_2d_dp_hf.multizone = True + test_list.append(sp_pinArray_cht_2d_dp_hf) + + # simple small 3D pin case massflow periodic with heatflux BC + sp_pinArray_3d_cht_mf_hf_tp = TestCase('sp_pinArray_3d_cht_mf_hf_tp') + sp_pinArray_3d_cht_mf_hf_tp.cfg_dir = "incomp_navierstokes/streamwise_periodic/chtPinArray_3d" + sp_pinArray_3d_cht_mf_hf_tp.cfg_file = "configMaster.cfg" + sp_pinArray_3d_cht_mf_hf_tp.test_iter = 30 + sp_pinArray_3d_cht_mf_hf_tp.test_vals = [0.511984, -3.063453, -0.451732, -0.008477, 214.707868, 365.670000] #last 7 lines + sp_pinArray_3d_cht_mf_hf_tp.su2_exec = "mpirun -n 2 SU2_CFD" + sp_pinArray_3d_cht_mf_hf_tp.timeout = 1600 + sp_pinArray_3d_cht_mf_hf_tp.tol = 0.00001 + sp_pinArray_3d_cht_mf_hf_tp.multizone = True + test_list.append(sp_pinArray_3d_cht_mf_hf_tp) + ########################## ### Python wrapper ### ########################## @@ -1596,6 +1631,20 @@ def main(): pass_list.append(sphere_ffd_def_bspline.run_def()) test_list.append(sphere_ffd_def_bspline) + # 2D FD streamwise periodic cht, avg temp obj func + fd_sp_pinArray_cht_2d_dp_hf = TestCase('fd_sp_pinArray_cht_2d_dp_hf') + fd_sp_pinArray_cht_2d_dp_hf.cfg_dir = "incomp_navierstokes/streamwise_periodic/chtPinArray_2d" + fd_sp_pinArray_cht_2d_dp_hf.cfg_file = "FD_configMaster.cfg" + fd_sp_pinArray_cht_2d_dp_hf.test_iter = 100 + fd_sp_pinArray_cht_2d_dp_hf.su2_exec = "finite_differences.py -z 2 -n 2 -f" + fd_sp_pinArray_cht_2d_dp_hf.timeout = 1600 + fd_sp_pinArray_cht_2d_dp_hf.reference_file = "of_grad_findiff.csv.ref" + fd_sp_pinArray_cht_2d_dp_hf.test_file = "FINDIFF/of_grad_findiff.csv" + fd_sp_pinArray_cht_2d_dp_hf.multizone = True + + pass_list.append(fd_sp_pinArray_cht_2d_dp_hf.run_filediff()) + test_list.append(fd_sp_pinArray_cht_2d_dp_hf) + # Tests summary print('==================================================================') diff --git a/TestCases/parallel_regression_AD.py b/TestCases/parallel_regression_AD.py index daf5969d201b..6cd67b598a0d 100644 --- a/TestCases/parallel_regression_AD.py +++ b/TestCases/parallel_regression_AD.py @@ -321,8 +321,19 @@ def main(): discadj_cht.su2_exec = "mpirun -n 2 SU2_CFD_AD" discadj_cht.timeout = 1600 discadj_cht.tol = 0.00001 - test_list.append(discadj_cht) - + test_list.append(discadj_cht) + + # 2D DA cht streamwise periodic case, 2 zones, avg temp objective + da_sp_pinArray_cht_2d_dp_hf = TestCase('da_sp_pinArray_cht_2d_dp_hf') + da_sp_pinArray_cht_2d_dp_hf.cfg_dir = "incomp_navierstokes/streamwise_periodic/chtPinArray_2d" + da_sp_pinArray_cht_2d_dp_hf.cfg_file = "DA_configMaster.cfg" + da_sp_pinArray_cht_2d_dp_hf.test_iter = 100 + da_sp_pinArray_cht_2d_dp_hf.test_vals = [-4.793283, -4.065832, -4.137121] #last 4 lines + da_sp_pinArray_cht_2d_dp_hf.su2_exec = "mpirun -n 2 SU2_CFD_AD" + da_sp_pinArray_cht_2d_dp_hf.timeout = 1600 + da_sp_pinArray_cht_2d_dp_hf.tol = 0.00001 + da_sp_pinArray_cht_2d_dp_hf.multizone = True + test_list.append(da_sp_pinArray_cht_2d_dp_hf) ###################################### ### RUN TESTS ### diff --git a/TestCases/tutorials.py b/TestCases/tutorials.py index 27d2d6125f97..6cd982fd6e21 100644 --- a/TestCases/tutorials.py +++ b/TestCases/tutorials.py @@ -42,6 +42,30 @@ def main(): ### RUN TUTORIAL CASES ### ###################################### + ### Incompressible Flow + + # 2D pin case massflow periodic with heatflux BC and prescribed extracted outlet heat + sp_pinArray_2d_mf_hf = TestCase('sp_pinArray_2d_mf_hf') + sp_pinArray_2d_mf_hf.cfg_dir = "../Tutorials/incompressible_flow/Inc_Streamwise_Periodic" + sp_pinArray_2d_mf_hf.cfg_file = "sp_pinArray_2d_mf_hf.cfg" + sp_pinArray_2d_mf_hf.test_iter = 25 + sp_pinArray_2d_mf_hf.test_vals = [-4.600340, 1.470386, -0.778623, 266.569743] #last 4 lines + sp_pinArray_2d_mf_hf.su2_exec = "mpirun -n 2 SU2_CFD" + sp_pinArray_2d_mf_hf.timeout = 1600 + sp_pinArray_2d_mf_hf.tol = 0.00001 + test_list.append(sp_pinArray_2d_mf_hf) + + # 2D pin case pressure drop periodic with heatflux BC and temperature periodicity + sp_pinArray_2d_dp_hf_tp = TestCase('sp_pinArray_2d_dp_hf_tp') + sp_pinArray_2d_dp_hf_tp.cfg_dir = "../Tutorials/incompressible_flow/Inc_Streamwise_Periodic" + sp_pinArray_2d_dp_hf_tp.cfg_file = "sp_pinArray_2d_dp_hf_tp.cfg" + sp_pinArray_2d_dp_hf_tp.test_iter = 25 + sp_pinArray_2d_dp_hf_tp.test_vals = [-4.667133, 1.395801, -0.709306, 208.023676] #last 4 lines + sp_pinArray_2d_dp_hf_tp.su2_exec = "mpirun -n 2 SU2_CFD" + sp_pinArray_2d_dp_hf_tp.timeout = 1600 + sp_pinArray_2d_dp_hf_tp.tol = 0.00001 + test_list.append(sp_pinArray_2d_dp_hf_tp) + ### Compressible Flow # Inviscid Bump @@ -151,7 +175,6 @@ def main(): tutorial_nicfd_nozzle.no_restart = True test_list.append(tutorial_nicfd_nozzle) - # Unsteady NACA0012 tutorial_unst_naca0012 = TestCase('unsteady_naca0012') tutorial_unst_naca0012.cfg_dir = "../Tutorials/compressible_flow/Unsteady_NACA0012" diff --git a/config_template.cfg b/config_template.cfg index b9d479ef717d..fd9e3d4930c9 100644 --- a/config_template.cfg +++ b/config_template.cfg @@ -687,6 +687,35 @@ BODY_FORCE= NO % Vector of body force values (BodyForce_X, BodyForce_Y, BodyForce_Z) BODY_FORCE_VECTOR= ( 0.0, 0.0, 0.0 ) +% --------------------- STREAMWISE PERIODICITY DEFINITION ---------------------% +% +% Generally for streamwise periodictiy one has to set MARKER_PERIODIC= (, , ...) +% appropriately as a boundary condition. +% +% Specify type of streamwise periodictiy (default=NONE, PRESSURE_DROP, MASSFLOW) +KIND_STREAMWISE_PERIODIC= NONE +% +% Delta P [Pa] value that drives the flow as a source term in the momentum equations. +% Defaults to 1.0. +STREAMWISE_PERIODIC_PRESSURE_DROP= 1.0 +% +% Target massflow [kg/s]. Necessary pressure drop is determined iteratively. +% Initial value is given via STREAMWISE_PERIODIC_PRESSURE_DROP. Default value 1.0. +% Use INC_OUTLET_DAMPING as a relaxation factor. Default value 0.1 is a good start. +STREAMWISE_PERIODIC_MASSFLOW= 0.0 +% +% Use streamwise periodic temperature (default=NO, YES) +% If NO, the heatflux is taken out at the outlet. +% This option is only necessary if INC_ENERGY_EQUATION=YES +STREAMWISE_PERIODIC_TEMPERATURE= NO +% +% Prescribe integrated heat [W] extracted at the periodic "outlet". +% Only active if STREAMWISE_PERIODIC_TEMPERATURE= NO. +% If set to zero, the heat is integrated automatically over all present MARKER_HEATFLUX. +% Upon convergence, the area averaged inlet temperature will be INC_TEMPERATURE_INIT. +% Defaults to 0.0. +STREAMWISE_PERIODIC_OUTLET_HEAT= 0.0 +% % -------------------- BOUNDARY CONDITION DEFINITION --------------------------% % % Euler wall boundary marker(s) (NONE = no marker)