diff --git a/AUTHORS.md b/AUTHORS.md index b9b3df93624..d677c251936 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -71,6 +71,7 @@ Eduardo Molina Edwin van der Weide Ethan Alan Hereth Florian Dittmann +Filip Hahs Francesco Poli Francisco D. Palacios Gaurav Bansal diff --git a/Common/include/CConfig.hpp b/Common/include/CConfig.hpp index e6cfbe0dbba..a2bd6c3d33e 100644 --- a/Common/include/CConfig.hpp +++ b/Common/include/CConfig.hpp @@ -184,6 +184,8 @@ class CConfig { nMarker_NearFieldBound, /*!< \brief Number of near field boundary markers. */ nMarker_ActDiskInlet, /*!< \brief Number of actuator disk inlet markers. */ nMarker_ActDiskOutlet, /*!< \brief Number of actuator disk outlet markers. */ + nMarker_ActDiskBemInlet, /*!< \brief Number of actuator disk BEM inlet markers. */ + nMarker_ActDiskBemOutlet, /*!< \brief Number of actuator disk BEM outlet markers. */ nMarker_Deform_Mesh_Sym_Plane, /*!< \brief Number of markers with symmetric deformation */ nMarker_Deform_Mesh, /*!< \brief Number of deformable markers at the boundary. */ nMarker_Fluid_Load, /*!< \brief Number of markers in which the flow load is computed/employed. */ @@ -212,8 +214,6 @@ class CConfig { nMarker_Damper, /*!< \brief Number of damper surface markers. */ nMarker_Load_Dir, /*!< \brief Number of load surface markers defined by magnitude and direction. */ nMarker_Disp_Dir, /*!< \brief Number of load surface markers defined by magnitude and direction. */ - nMarker_Load_Sine, /*!< \brief Number of load surface markers defined by magnitude and direction. */ - nMarker_FlowLoad, /*!< \brief Number of load surface markers. */ nMarker_Internal, /*!< \brief Number of internal flow markers. */ nMarker_All, /*!< \brief Total number of markers using the grid information. */ nMarker_Max, /*!< \brief Max number of number of markers using the grid information. */ @@ -242,6 +242,8 @@ class CConfig { *Marker_CHTInterface, /*!< \brief Conjugate heat transfer interface markers. */ *Marker_ActDiskInlet, /*!< \brief Actuator disk inlet markers. */ *Marker_ActDiskOutlet, /*!< \brief Actuator disk outlet markers. */ + *Marker_ActDiskBemInlet, /*!< \brief Actuator disk BEM inlet markers. */ + *Marker_ActDiskBemOutlet, /*!< \brief Actuator disk BEM outlet markers. */ *Marker_Inlet, /*!< \brief Inlet flow markers. */ *Marker_Inlet_Species, /*!< \brief Inlet species markers. */ *Marker_Inlet_Turb, /*!< \brief Inlet turbulent markers. */ @@ -265,7 +267,6 @@ class CConfig { *Marker_Load_Dir, /*!< \brief Load markers defined in cartesian coordinates. */ *Marker_Disp_Dir, /*!< \brief Load markers defined in cartesian coordinates. */ *Marker_Load_Sine, /*!< \brief Sine-wave loaded markers defined in cartesian coordinates. */ - *Marker_FlowLoad, /*!< \brief Flow Load markers. */ *Marker_Internal, /*!< \brief Internal flow markers. */ *Marker_All_TagBound; /*!< \brief Global index for markers using grid information. */ @@ -324,10 +325,6 @@ class CConfig { su2double *Disp_Dir_Multiplier; /*!< \brief Specified multiplier for load boundaries defined in cartesian coordinates. */ su2double **Load_Dir; /*!< \brief Specified flow direction vector (unit vector) for inlet boundaries. */ su2double **Disp_Dir; /*!< \brief Specified structural displacement direction (unit vector). */ - su2double *Load_Sine_Amplitude; /*!< \brief Specified amplitude for a sine-wave load. */ - su2double *Load_Sine_Frequency; /*!< \brief Specified multiplier for load boundaries defined in cartesian coordinates. */ - su2double **Load_Sine_Dir; /*!< \brief Specified flow direction vector (unit vector) for inlet boundaries. */ - su2double *FlowLoad_Value; /*!< \brief Specified force for flow load boundaries. */ su2double *ActDiskInlet_MassFlow; /*!< \brief Specified inlet mass flow for actuator disk. */ su2double *ActDiskInlet_Temperature; /*!< \brief Specified inlet temperature for actuator disk. */ su2double *ActDiskInlet_TotalTemperature; /*!< \brief Specified inlet total temperature for actuator disk. */ @@ -344,8 +341,16 @@ class CConfig { su2double *ActDiskOutlet_GrossThrust; /*!< \brief Specified outlet gross thrust for actuator disk. */ su2double *ActDiskOutlet_Force; /*!< \brief Specified outlet force for actuator disk. */ su2double *ActDiskOutlet_Power; /*!< \brief Specified outlet power for actuator disk. */ + su2double *ActDiskOutlet_Thrust_BEM; /*!< \brief Specified outlet thrust for actuator disk. */ + su2double *ActDiskOutlet_Torque_BEM; /*!< \brief Specified outlet torque for actuator disk. */ su2double **ActDisk_PressJump, **ActDisk_TempJump, **ActDisk_Omega; /*!< \brief Specified deltas for actuator disk.*/ + su2double **ActDiskBem_CG[3]; /*!< \brief Specified center for actuator disk BEM.*/ + su2double **ActDiskBem_Axis[3]; /*!< \brief Specified axis for actuator disk BEM.*/ + su2double BEM_blade_angle; /*!< \brief Propeller blade angle.*/ + string BEM_prop_filename; /*!< \brief Propeller filename.*/ + unsigned short ActDiskBem_Frequency; /*!< \brief Frequency of updating actuator disk with BEM. */ + bool History_File_Append_Flag; /*!< \brief Flag to append history file.*/ su2double *ActDisk_DeltaPress; /*!< \brief Specified pressure delta for actuator disk. */ su2double *ActDisk_DeltaTemp; /*!< \brief Specified temperature delta for actuator disk. */ su2double *ActDisk_TotalPressRatio; /*!< \brief Specified tot. pres. ratio for actuator disk. */ @@ -506,8 +511,6 @@ class CConfig { Kind_Deform_Linear_Solver_Prec, /*!< \brief Preconditioner of the linear solver. */ Kind_Linear_Solver, /*!< \brief Numerical solver for the implicit scheme. */ Kind_Linear_Solver_Prec, /*!< \brief Preconditioner of the linear solver. */ - Kind_AdjTurb_Linear_Solver, /*!< \brief Numerical solver for the turbulent adjoint implicit scheme. */ - Kind_AdjTurb_Linear_Prec, /*!< \brief Preconditioner of the turbulent adjoint linear solver. */ Kind_DiscAdj_Linear_Solver, /*!< \brief Linear solver for the discrete adjoint system. */ Kind_DiscAdj_Linear_Prec, /*!< \brief Preconditioner of the discrete adjoint linear solver. */ Kind_TimeNumScheme, /*!< \brief Global explicit or implicit time integration. */ @@ -620,9 +623,7 @@ class CConfig { su2double Roe_Kappa; /*!< \brief Relaxation of the Roe scheme. */ su2double Relaxation_Factor_Adjoint; /*!< \brief Relaxation coefficient for variable updates of adjoint solvers. */ su2double Relaxation_Factor_CHT; /*!< \brief Relaxation coefficient for the update of conjugate heat variables. */ - su2double AdjTurb_Linear_Error; /*!< \brief Min error of the turbulent adjoint linear solver for the implicit formulation. */ su2double EntropyFix_Coeff; /*!< \brief Entropy fix coefficient. */ - unsigned short AdjTurb_Linear_Iter; /*!< \brief Min error of the turbulent adjoint linear solver for the implicit formulation. */ unsigned short nLocationStations, /*!< \brief Number of section cuts to make when outputting mesh and cp . */ nWingStations; /*!< \brief Number of section cuts to make when calculating internal volume. */ su2double Kappa_1st_AdjFlow, /*!< \brief Lax 1st order dissipation coefficient for adjoint flow equations (coarse multigrid levels). */ @@ -666,7 +667,6 @@ class CConfig { su2double Total_CM; /*!< \brief Specify a Total CM instead of AoA (external flow only). */ su2double Total_CD; /*!< \brief Specify a target CD instead of AoA (external flow only). */ su2double dCL_dAlpha; /*!< \brief value of dCl/dAlpha. */ - su2double dCM_diH; /*!< \brief value of dCM/dHi. */ unsigned long Iter_Fixed_CM; /*!< \brief Iterations to re-evaluate the angle of attack (external flow only). */ unsigned long Iter_Fixed_NetThrust; /*!< \brief Iterations to re-evaluate the angle of attack (external flow only). */ unsigned long Iter_dCL_dAlpha; /*!< \brief Number of iterations to evaluate dCL_dAlpha. */ @@ -928,8 +928,6 @@ class CConfig { bool RampAndRelease; /*!< \brief option for ramp load and release */ bool Sine_Load; /*!< \brief option for sine load */ su2double Thermal_Diffusivity; /*!< \brief Thermal diffusivity used in the heat solver. */ - su2double Cyclic_Pitch, /*!< \brief Cyclic pitch for rotorcraft simulations. */ - Collective_Pitch; /*!< \brief Collective pitch for rotorcraft simulations. */ su2double Mach_Motion; /*!< \brief Mach number based on mesh velocity and freestream quantities. */ su2double Motion_Origin[3] = {0.0}, /*!< \brief Mesh motion origin. */ @@ -1112,7 +1110,6 @@ class CConfig { distortion[2], /*!< \brief SU2_GEO section locations array for the COption class. */ ea_lim[3], /*!< \brief equivalent area limit array for the COption class. */ grid_fix[6], /*!< \brief fixed grid (non-deforming region) array for the COption class. */ - htp_axis[2], /*!< \brief HTP axis for the COption class. */ ffd_axis[3], /*!< \brief FFD axis for the COption class. */ inc_crit[3], /*!< \brief incremental criteria array for the COption class. */ extrarelfac[2], /*!< \brief extra relaxation factor for Giles BC in the COption class. */ @@ -1177,6 +1174,7 @@ class CConfig { string caseName; /*!< \brief Name of the current case */ unsigned long edgeColorGroupSize; /*!< \brief Size of the edge groups colored for OpenMP parallelization of edge loops. */ + bool edgeColoringRelaxDiscAdj; /*!< \brief Allow fallback to smaller edge color group sizes and use more colors for the discrete adjoint. */ INLET_SPANWISE_INTERP Kind_InletInterpolationFunction; /*!brief type of spanwise interpolation function to use for the inlet face. */ INLET_INTERP_TYPE Kind_Inlet_InterpolationType; /*!brief type of spanwise interpolation data to use for the inlet face. */ @@ -1366,6 +1364,10 @@ class CConfig { unsigned short & nMarker_ActDiskInlet, unsigned short & nMarker_ActDiskOutlet, string* & Marker_ActDiskInlet, string* & Marker_ActDiskOutlet, su2double** & ActDisk_PressJump, su2double** & ActDisk_TempJump, su2double** & ActDisk_Omega); + void addActDiskBemOption(const string& name, + unsigned short& nMarker_ActDiskBemInlet, unsigned short& nMarker_ActDiskBemOutlet, string*& Marker_ActDiskBemInlet, string*& Marker_ActDiskBemOutlet, + su2double**& ActDiskBem_X, su2double**& ActDiskBem_Y, su2double**& ActDiskBem_Z); + void addWallFunctionOption(const string &name, unsigned short &list_size, string* &string_field, WALL_FUNCTIONS* &val_Kind_WF, unsigned short** &val_IntInfo_WF, su2double** &val_DoubleInfo_WF); @@ -4280,18 +4282,6 @@ class CConfig { */ su2double GetSemiSpan(void) const { return SemiSpan; } - /*! - * \brief Get the kind of solver for the implicit solver. - * \return Numerical solver for implicit formulation (solving the linear system). - */ - unsigned short GetKind_AdjTurb_Linear_Solver(void) const { return Kind_AdjTurb_Linear_Solver; } - - /*! - * \brief Get the kind of preconditioner for the implicit solver. - * \return Numerical preconditioner for implicit formulation (solving the linear system). - */ - unsigned short GetKind_AdjTurb_Linear_Prec(void) const { return Kind_AdjTurb_Linear_Prec; } - /*! * \brief Get the kind of solver for the implicit solver. * \return Numerical solver for implicit formulation (solving the linear system). @@ -4310,30 +4300,12 @@ class CConfig { */ unsigned short GetKind_Deform_Linear_Solver_Prec(void) const { return Kind_Deform_Linear_Solver_Prec; } - /*! - * \brief Set the kind of preconditioner for the implicit solver. - * \return Numerical preconditioner for implicit formulation (solving the linear system). - */ - void SetKind_AdjTurb_Linear_Prec(unsigned short val_kind_prec) { Kind_AdjTurb_Linear_Prec = val_kind_prec; } - - /*! - * \brief Get min error of the linear solver for the implicit formulation. - * \return Min error of the linear solver for the implicit formulation. - */ - su2double GetAdjTurb_Linear_Error(void) const { return AdjTurb_Linear_Error; } - /*! * \brief Get the entropy fix. * \return Vaule of the entropy fix. */ su2double GetEntropyFix_Coeff(void) const { return EntropyFix_Coeff; } - /*! - * \brief Get max number of iterations of the linear solver for the implicit formulation. - * \return Max number of iterations of the linear solver for the implicit formulation. - */ - unsigned short GetAdjTurb_Linear_Iter(void) const { return AdjTurb_Linear_Iter; } - /*! * \brief Get CFL reduction factor for adjoint turbulence model. * \return CFL reduction factor. @@ -5940,6 +5912,15 @@ class CConfig { */ su2double GetMarkerTranslationRate(unsigned short iMarkerMoving, unsigned short iDim) const { return MarkerTranslation_Rate[3*iMarkerMoving + iDim];} + /*! + * \brief Set the translation rate of the marker. + * \param[in] iDim - spatial component + * \param[in] val - translational velocity + */ + void SetMarkerTranslationRate(unsigned short iMarkerMoving, unsigned short iDim, su2double val) { + MarkerTranslation_Rate[3 * iMarkerMoving + iDim] = val; + } + /*! * \brief Get the rotation rate of the mesh. * \param[in] iDim - spatial component @@ -5963,6 +5944,16 @@ class CConfig { */ su2double GetMarkerRotationRate(unsigned short iMarkerMoving, unsigned short iDim) const { return MarkerRotation_Rate[3*iMarkerMoving + iDim];} + /*! + * \brief Set the rotation rate of the marker. + * \param[in] iMarkerMoving - Index of the moving marker (as specified in Marker_Moving) + * \param[in] iDim - spatial component + * \param[in] val - Rotational velocity + */ + void SetMarkerRotationRate(unsigned short iMarkerMoving, unsigned short iDim, su2double val) { + MarkerRotation_Rate[3 * iMarkerMoving + iDim] = val; + } + /*! * \brief Get the pitching rate of the mesh. * \param[in] iDim - spatial component @@ -6488,8 +6479,8 @@ class CConfig { su2double GetWeightCd(void) const { return WeightCd; } /*! - * \brief Value of the weight of the CD, CL, CM optimization. - * \return Value of the weight of the CD, CL, CM optimization. + * \brief Value of the damping factor for the Thrust BC (actuator disk). + * \return Value of the damping factor. */ void SetdNetThrust_dBCThrust(su2double val_dnetthrust_dbcthrust); @@ -6553,12 +6544,6 @@ class CConfig { */ void SetdCL_dAlpha(su2double val_dcl_dalpha) { dCL_dAlpha = val_dcl_dalpha; } - /*! - * \brief Value of the weight of the CD, CL, CM optimization. - * \return Value of the weight of the CD, CL, CM optimization. - */ - void SetdCM_diH(su2double val_dcm_dhi) { dCM_diH = val_dcm_dhi; } - /*! * \brief Value of the weight of the CD, CL, CM optimization. * \return Value of the weight of the CD, CL, CM optimization. @@ -6660,6 +6645,31 @@ class CConfig { */ su2double GetActDisk_Omega(const string& val_marker, unsigned short val_index) const; + /*! + * \brief Get the Center of the actuator disk with BEM. + */ + su2double GetActDiskBem_CG(unsigned short iDim, string val_marker, unsigned short val_index) const; + + /*! + * \brief Get the axis of the actuator disk with BEM. + */ + su2double GetActDiskBem_Axis(unsigned short iDim, string val_marker, unsigned short val_index) const; + + /*! + * \brief Get the frequency of updating the actuator disk with BEM. + */ + const unsigned short& GetActDiskBem_Frequency(void) const { return ActDiskBem_Frequency; } + + /*! + * \brief Get the blade angle of the propeller. + */ + su2double GetBEM_blade_angle(void) const { return BEM_blade_angle; } + + /*! + * \brief Get the filename of the propeller. + */ + const string& GetBEM_prop_filename(void) const { return BEM_prop_filename; } + /*! * \brief Get Actuator Disk Outlet for boundary val_marker (actuator disk inlet). * \return Actuator Disk Outlet from the config information for the marker val_marker. @@ -8192,6 +8202,20 @@ class CConfig { */ su2double GetActDiskOutlet_Power(const string& val_marker) const; + /*! + * \brief Get the thrust at the actuator disk outlet boundary. + * \param[in] val_marker - Marker corresponding to the outlet (actuator disk) boundary. + * \return The outlet (actuator disk) thrust. + */ + su2double GetActDiskOutlet_Thrust_BEM(string val_marker) const; + + /*! + * \brief Get the torque at the actuator disk outlet boundary. + * \param[in] val_marker - Marker corresponding to the outlet boundary. + * \return The outlet (actuator disk) torque. + */ + su2double GetActDiskOutlet_Torque_BEM(string val_marker) const; + /*! * \brief Get the back pressure (static) at an outlet boundary. * \param[in] val_index - Index corresponding to the outlet boundary. @@ -8227,6 +8251,24 @@ class CConfig { */ void SetActDiskOutlet_Power(unsigned short val_marker, su2double val_actdisk_power) { ActDiskOutlet_Power[val_marker] = val_actdisk_power; } + /*! + * \brief Set the thrust at the outlet (actuator disk) boundary. + * \param[in] val_marker - Marker corresponding to the outlet (actuator disk) boundary. + * \param[in] val_actdisk_thrust_bem - Value of the actuator disk thrust. + */ + void SetActDiskOutlet_Thrust_BEM(unsigned short val_marker, su2double val_actdisk_thrust_bem) { + ActDiskOutlet_Thrust_BEM[val_marker] = val_actdisk_thrust_bem; + } + + /*! + * \brief Get the back pressure (static) at an outlet boundary. + * \param[in] val_marker - Marker corresponding to the outlet boundary. + * \param[in] val_actdisk_torque_bem - Value of the actuator disk torque. + */ + void SetActDiskOutlet_Torque_BEM(unsigned short val_marker, su2double val_actdisk_torque_bem) { + ActDiskOutlet_Torque_BEM[val_marker] = val_actdisk_torque_bem; + } + /*! * \brief Get the displacement value at an displacement boundary. * \param[in] val_index - Index corresponding to the displacement boundary. @@ -8290,46 +8332,6 @@ class CConfig { */ const su2double* GetDisp_Dir(const string& val_index) const; - /*! - * \brief Get the amplitude of the sine-wave at a load boundary defined in cartesian coordinates. - * \param[in] val_index - Index corresponding to the load boundary. - * \return The load value. - */ - su2double GetLoad_Sine_Amplitude(const string& val_index) const; - - /*! - * \brief Get the frequency of the sine-wave at a load boundary in cartesian coordinates. - * \param[in] val_index - Index corresponding to the load boundary. - * \return The load frequency. - */ - su2double GetLoad_Sine_Frequency(const string& val_index) const; - - /*! - * \brief Get the force direction at a sine-wave loaded boundary in cartesian coordinates. - * \param[in] val_index - Index corresponding to the load boundary. - * \return The load direction. - */ - const su2double* GetLoad_Sine_Dir(const string& val_index) const; - - /*! - * \brief Get the force value at an load boundary. - * \param[in] val_index - Index corresponding to the load boundary. - * \return The load value. - */ - su2double GetFlowLoad_Value(const string& val_index) const; - - /*! - * \brief Cyclic pitch amplitude for rotor blades. - * \return The specified cyclic pitch amplitude. - */ - su2double GetCyclic_Pitch(void) const { return Cyclic_Pitch; } - - /*! - * \brief Collective pitch setting for rotor blades. - * \return The specified collective pitch setting. - */ - su2double GetCollective_Pitch(void) const { return Collective_Pitch; } - /*! * \brief Get name of the arbitrary mesh motion input file. * \return File name of the arbitrary mesh motion input file. @@ -8632,12 +8634,6 @@ class CConfig { */ unsigned long GetIter_dCL_dAlpha(void) const { return Iter_dCL_dAlpha; } - /*! - * \brief Get the value of the damping coefficient for fixed CL mode. - * \return Damping coefficient for fixed CL mode. - */ - su2double GetdCM_diH(void) const { return dCM_diH; } - /*! * \brief Get the value of iterations to re-evaluate the angle of attack. * \return Number of iterations. @@ -8645,8 +8641,8 @@ class CConfig { unsigned long GetIter_Fixed_NetThrust(void) const { return Iter_Fixed_NetThrust; } /*! - * \brief Get the value of the damping coefficient for fixed CL mode. - * \return Damping coefficient for fixed CL mode. + * \brief Get the value of NetThrust_dBCThrust. + * \return Value NetThrust_dBCThrust. */ su2double GetdNetThrust_dBCThrust(void) const { return dNetThrust_dBCThrust; } @@ -9672,6 +9668,11 @@ class CConfig { */ unsigned long GetEdgeColoringGroupSize(void) const { return edgeColorGroupSize; } + /*! + * \brief Check if the discrete adjoint is allowed to relax the coloring, that is, allow smaller edge color group sizes and allow more colors. + */ + bool GetEdgeColoringRelaxDiscAdj() const { return edgeColoringRelaxDiscAdj; } + /*! * \brief Get the ParMETIS load balancing tolerance. */ diff --git a/Common/include/basic_types/ad_structure.hpp b/Common/include/basic_types/ad_structure.hpp index dd7e3691377..bbed2a91a2c 100644 --- a/Common/include/basic_types/ad_structure.hpp +++ b/Common/include/basic_types/ad_structure.hpp @@ -396,6 +396,8 @@ FORCEINLINE void SetIndex(int& index, const su2double& data) { index = data.getI // WARNING: For performance reasons, this method does not perform bounds checking. // When using it, please ensure sufficient adjoint vector size by a call to AD::ResizeAdjoints(). +// This method does not perform locking either. +// It should be safeguarded by calls to AD::BeginUseAdjoints() and AD::EndUseAdjoints(). FORCEINLINE void SetDerivative(int index, const double val) { if (index == 0) // Allow multiple threads to "set the derivative" of passive variables without causing data races. return; @@ -406,6 +408,8 @@ FORCEINLINE void SetDerivative(int index, const double val) { // WARNING: For performance reasons, this method does not perform bounds checking. // If called after tape evaluations, the adjoints should exist. // Otherwise, please ensure sufficient adjoint vector size by a call to AD::ResizeAdjoints(). +// This method does not perform locking either. +// It should be safeguarded by calls to AD::BeginUseAdjoints() and AD::EndUseAdjoints(). FORCEINLINE double GetDerivative(int index) { return AD::getTape().getGradient(index, codi::AdjointsManagement::Manual); } diff --git a/Common/include/geometry/CGeometry.hpp b/Common/include/geometry/CGeometry.hpp index f8111060725..4af65411cc2 100644 --- a/Common/include/geometry/CGeometry.hpp +++ b/Common/include/geometry/CGeometry.hpp @@ -1720,10 +1720,14 @@ class CGeometry { /*! * \brief Get the edge coloring. * \note This method computes the coloring if that has not been done yet. + * \note Can be instructed to determine and use the maximum edge color group size between 1 and + * CGeometry::edgeColorGroupSize that yields a coloring that is at least as efficient as #COLORING_EFF_THRESH. * \param[out] efficiency - optional output of the coloring efficiency. + * \param[in] maximizeEdgeColorGroupSize - use the maximum edge color group size that gives an efficient coloring. * \return Reference to the coloring. */ - const CCompressedSparsePatternUL& GetEdgeColoring(su2double* efficiency = nullptr); + const CCompressedSparsePatternUL& GetEdgeColoring(su2double* efficiency = nullptr, + bool maximizeEdgeColorGroupSize = false); /*! * \brief Force the natural (sequential) edge coloring. diff --git a/Common/include/grid_movement/CSurfaceMovement.hpp b/Common/include/grid_movement/CSurfaceMovement.hpp index 0ef697e049d..4744c08f289 100644 --- a/Common/include/grid_movement/CSurfaceMovement.hpp +++ b/Common/include/grid_movement/CSurfaceMovement.hpp @@ -156,13 +156,6 @@ class CSurfaceMovement : public CGridMovement { void SetBoundary_Flutter3D(CGeometry* geometry, CConfig* config, CFreeFormDefBox** FFDBox, unsigned long iter, unsigned short iZone); - /*! - * \brief Set the collective pitch for a blade surface movement. - * \param[in] geometry - Geometrical definition of the problem. - * \param[in] config - Definition of the particular problem. - */ - void SetCollective_Pitch(CGeometry* geometry, CConfig* config); - /*! * \brief Set any surface deformationsbased on an input file. * \param[in] geometry - Geometrical definition of the problem. diff --git a/Common/include/option_structure.hpp b/Common/include/option_structure.hpp index 568558acf07..094bef921aa 100644 --- a/Common/include/option_structure.hpp +++ b/Common/include/option_structure.hpp @@ -1857,7 +1857,8 @@ enum ACTDISK_TYPE { DRAG_MINUS_THRUST = 4, /*!< \brief User specifies the D-T. */ MASSFLOW = 5, /*!< \brief User specifies the massflow. */ POWER = 6, /*!< \brief User specifies the power. */ - VARIABLE_LOAD = 7 /*!< \brief User specifies the load distribution. */ + VARIABLE_LOAD = 7, /*!< \brief User specifies the load distribution. */ + BLADE_ELEMENT = 8 /*!< \brief User specifies to use Blade element method. */ }; static const MapType ActDisk_Map = { MakePair("VARIABLES_JUMP", VARIABLES_JUMP) @@ -1867,6 +1868,7 @@ static const MapType ActDisk_Map = { MakePair("MASSFLOW", MASSFLOW) MakePair("POWER", POWER) MakePair("VARIABLE_LOAD", VARIABLE_LOAD) + MakePair("BLADE_ELEMENT", BLADE_ELEMENT) }; /*! diff --git a/Common/include/option_structure.inl b/Common/include/option_structure.inl index ce94055fca5..bafdb71332f 100644 --- a/Common/include/option_structure.inl +++ b/Common/include/option_structure.inl @@ -654,7 +654,7 @@ class COptionDVParam : public COptionBase { default: { string newstring; newstring.append(this->name); - newstring.append(": undefined design variable type found in configuration file."); + newstring.append(": undefined design variable type found in configuration file. "); return newstring; } } diff --git a/Common/include/toolboxes/graph_toolbox.hpp b/Common/include/toolboxes/graph_toolbox.hpp index c5929e8f8da..f1c0854ce27 100644 --- a/Common/include/toolboxes/graph_toolbox.hpp +++ b/Common/include/toolboxes/graph_toolbox.hpp @@ -484,7 +484,7 @@ T createNaturalColoring(Index_t numInnerIndexes) { * \param[out] indexColor - Optional, vector with colors given to the outer indices. * \return Coloring in the same type of the input pattern. */ -template +template T colorSparsePattern(const T& pattern, size_t groupSize = 1, bool balanceColors = false, std::vector* indexColor = nullptr) { static_assert(std::is_integral::value, ""); diff --git a/Common/src/CConfig.cpp b/Common/src/CConfig.cpp index 8da6cd22231..ba2afdafd5e 100644 --- a/Common/src/CConfig.cpp +++ b/Common/src/CConfig.cpp @@ -557,6 +557,19 @@ void CConfig::addActDiskOption(const string & name, unsigned short & nMarker_Act option_map.insert(pair(name, val)); } +void CConfig::addActDiskBemOption(const string& name, + unsigned short& nMarker_ActDiskBemInlet, unsigned short& nMarker_ActDiskBemOutlet, + string*& Marker_ActDiskBemInlet, string*& Marker_ActDiskBemOutlet, + su2double**& ActDiskBem_X, su2double**& ActDiskBem_Y, su2double**& ActDiskBem_Z) { + assert(option_map.find(name) == option_map.end()); + all_options.insert(pair(name, true)); + COptionBase* val = new COptionActDisk(name, + nMarker_ActDiskBemInlet, nMarker_ActDiskBemOutlet, + Marker_ActDiskBemInlet, Marker_ActDiskBemOutlet, + ActDiskBem_X, ActDiskBem_Y, ActDiskBem_Z); + option_map.insert(pair(name, val)); +} + void CConfig::addWallFunctionOption(const string &name, unsigned short &list_size, string* &string_field, WALL_FUNCTIONS* &val_Kind_WF, unsigned short** &val_IntInfo_WF, su2double** &val_DoubleInfo_WF) { @@ -856,8 +869,8 @@ void CConfig::SetPointersNull() { Marker_Isothermal = nullptr; Marker_HeatFlux = nullptr; Marker_EngineInflow = nullptr; Marker_Load = nullptr; Marker_Disp_Dir = nullptr; Marker_RoughWall = nullptr; Marker_EngineExhaust = nullptr; Marker_Displacement = nullptr; Marker_Load = nullptr; - Marker_Load_Dir = nullptr; Marker_Load_Sine = nullptr; Marker_Clamped = nullptr; - Marker_FlowLoad = nullptr; Marker_Internal = nullptr; + Marker_Load_Dir = nullptr; Marker_Clamped = nullptr; + Marker_Internal = nullptr; Marker_All_TagBound = nullptr; Marker_CfgFile_TagBound = nullptr; Marker_All_KindBC = nullptr; Marker_CfgFile_KindBC = nullptr; Marker_All_SendRecv = nullptr; Marker_All_PerBound = nullptr; Marker_ZoneInterface = nullptr; Marker_All_ZoneInterface = nullptr; Marker_Riemann = nullptr; @@ -868,7 +881,7 @@ void CConfig::SetPointersNull() { Isothermal_Temperature = nullptr; HeatTransfer_Coeff = nullptr; HeatTransfer_WallTemp = nullptr; Heat_Flux = nullptr; Displ_Value = nullptr; Load_Value = nullptr; - FlowLoad_Value = nullptr; Damper_Constant = nullptr; Wall_Emissivity = nullptr; + Damper_Constant = nullptr; Wall_Emissivity = nullptr; Roughness_Height = nullptr; /*--- Inlet Outlet Boundary Condition settings ---*/ @@ -905,7 +918,6 @@ void CConfig::SetPointersNull() { Load_Dir = nullptr; Load_Dir_Value = nullptr; Load_Dir_Multiplier = nullptr; Disp_Dir = nullptr; Disp_Dir_Value = nullptr; Disp_Dir_Multiplier = nullptr; - Load_Sine_Dir = nullptr; Load_Sine_Amplitude = nullptr; Load_Sine_Frequency = nullptr; Electric_Field_Mod = nullptr; Electric_Field_Dir = nullptr; RefNode_Displacement = nullptr; Electric_Constant = nullptr; @@ -921,6 +933,9 @@ void CConfig::SetPointersNull() { ActDiskOutlet_Power = nullptr; ActDiskOutlet_Temperature = nullptr; ActDiskOutlet_TotalTemperature = nullptr; ActDiskOutlet_MassFlow = nullptr; + ActDiskOutlet_Thrust_BEM = nullptr; + ActDiskOutlet_Torque_BEM = nullptr; + ActDisk_DeltaPress = nullptr; ActDisk_DeltaTemp = nullptr; ActDisk_TotalPressRatio = nullptr; ActDisk_TotalTempRatio = nullptr; ActDisk_StaticPressRatio = nullptr; ActDisk_StaticTempRatio = nullptr; ActDisk_NetThrust = nullptr; ActDisk_GrossThrust = nullptr; @@ -1418,15 +1433,13 @@ void CConfig::SetConfig_Options() { addDoubleOption("TARGET_CL", Target_CL, 0.0); /* DESCRIPTION: Damping factor for fixed CL mode. */ addDoubleOption("DCL_DALPHA", dCL_dAlpha, 0.2); - /* DESCRIPTION: Damping factor for fixed CL mode. */ - addDoubleOption("DCM_DIH", dCM_diH, 0.05); /* DESCRIPTION: Maximum number of iterations between AoA updates for fixed CL problem. */ addUnsignedLongOption("UPDATE_AOA_ITER_LIMIT", Update_AoA_Iter_Limit, 200); /* DESCRIPTION: Number of times Alpha is updated in a fix CL problem. */ addUnsignedLongOption("UPDATE_IH", Update_iH, 5); /* DESCRIPTION: Number of iterations to evaluate dCL_dAlpha . */ addUnsignedLongOption("ITER_DCL_DALPHA", Iter_dCL_dAlpha, 500); - /* DESCRIPTION: Damping factor for fixed CL mode. */ + /* DESCRIPTION: Value of dNetThrust/dBCThrust */ addDoubleOption("DNETTHRUST_DBCTHRUST", dNetThrust_dBCThrust, 1.0); /* DESCRIPTION: Number of times Alpha is updated in a fix CL problem. */ addUnsignedLongOption("UPDATE_BCTHRUST", Update_BCThrust, 5); @@ -1454,16 +1467,13 @@ void CConfig::SetConfig_Options() { /*!\brief REF_VELOCITY\n DESCRIPTION: Reference velocity (incompressible only) \ingroup Config*/ addDoubleOption("REF_VELOCITY", Velocity_Ref, -1.0); /* !\brief REF_VISCOSITY \n DESCRIPTION: Reference viscosity (incompressible only) \ingroup Config*/ - addDoubleOption("REF_VISCOSITY", Viscosity_Ref, -1.0); + addDoubleOption("REF_VISCOSITY", Viscosity_Ref, 1.0); /* DESCRIPTION: Type of mesh motion */ addEnumOption("REF_DIMENSIONALIZATION", Ref_NonDim, NonDim_Map, DIMENSIONAL); /*!\par CONFIG_CATEGORY: Boundary Markers \ingroup Config*/ /*--- Options related to various boundary markers ---*/ - /*!\brief HTP_AXIS\n DESCRIPTION: Location of the HTP axis*/ - htp_axis[0] = 0.0; htp_axis[1] = 0.0; - addDoubleArrayOption("HTP_AXIS", 2, htp_axis); /*!\brief MARKER_PLOTTING\n DESCRIPTION: Marker(s) of the surface in the surface flow solution file \ingroup Config*/ addStringListOption("MARKER_PLOTTING", nMarker_Plotting, Marker_Plotting); /*!\brief MARKER_MONITORING\n DESCRIPTION: Marker(s) of the surface where evaluate the non-dimensional coefficients \ingroup Config*/ @@ -1525,6 +1535,16 @@ void CConfig::SetConfig_Options() { nMarker_ActDiskInlet, nMarker_ActDiskOutlet, Marker_ActDiskInlet, Marker_ActDiskOutlet, ActDisk_PressJump, ActDisk_TempJump, ActDisk_Omega); + /*!\brief MARKER_ACTDISK_BEM_CG\n DESCRIPTION: Actuator disk CG for blade element momentum (BEM) method. \ingroup Config*/ + addActDiskBemOption("MARKER_ACTDISK_BEM_CG", + nMarker_ActDiskBemInlet, nMarker_ActDiskBemOutlet, Marker_ActDiskBemInlet, Marker_ActDiskBemOutlet, + ActDiskBem_CG[0], ActDiskBem_CG[1], ActDiskBem_CG[2]); + + /*!\brief MARKER_ACTDISK_BEM_AXIS\n DESCRIPTION: Actuator disk axis for blade element momentum (BEM) method. \ingroup Config*/ + addActDiskBemOption("MARKER_ACTDISK_BEM_AXIS", + nMarker_ActDiskBemInlet, nMarker_ActDiskBemOutlet, Marker_ActDiskBemInlet, Marker_ActDiskBemOutlet, + ActDiskBem_Axis[0], ActDiskBem_Axis[1], ActDiskBem_Axis[2]); + /*!\brief ACTDISK_FILENAME \n DESCRIPTION: Input file for a specified actuator disk (w/ extension) \n DEFAULT: actdiskinput.dat \ingroup Config*/ addStringOption("ACTDISK_FILENAME", ActDisk_FileName, string("actdiskinput.dat")); @@ -1606,10 +1626,10 @@ void CConfig::SetConfig_Options() { /*!\brief SPANWISE_KIND \n DESCRIPTION: type of algorithm to identify the span-wise sections at the turbo boundaries. \n OPTIONS: see \link SpanWise_Map \endlink \n Default: AUTOMATIC */ addEnumOption("SPANWISE_KIND", Kind_SpanWise, SpanWise_Map, AUTOMATIC); - /*!\brief TURBOMACHINERY_KIND \n DESCRIPTION: types of turbomachynery architecture. + /*!\brief TURBOMACHINERY_KIND \n DESCRIPTION: types of turbomachinery architecture. \n OPTIONS: see \link TurboMachinery_Map \endlink \n Default: AXIAL */ addEnumListOption("TURBOMACHINERY_KIND",nTurboMachineryKind, Kind_TurboMachinery, TurboMachinery_Map); - /*!\brief MARKER_SHROUD \n DESCRIPTION: markers in which velocity is forced to 0.0 . + /*!\brief MARKER_SHROUD \n DESCRIPTION: markers in which velocity is forced to 0.0. * \n Format: (shroud1, shroud2, ...)*/ addStringListOption("MARKER_SHROUD", nMarker_Shroud, Marker_Shroud); /*!\brief MARKER_SUPERSONIC_INLET \n DESCRIPTION: Supersonic inlet boundary marker(s) @@ -1633,7 +1653,7 @@ void CConfig::SetConfig_Options() { /*!\brief MARKER_HEATTRANSFER DESCRIPTION: Heat flux with specified heat transfer coefficient boundary marker(s)\n * Format: ( Heat transfer marker, heat transfer coefficient, wall temperature (static), ... ) \ingroup Config */ addExhaustOption("MARKER_HEATTRANSFER", nMarker_HeatTransfer, Marker_HeatTransfer, HeatTransfer_Coeff, HeatTransfer_WallTemp); - /*!\brief Smluchowski/Maxwell wall boundary marker(s) \n DESCRIPTION: Slip velocity and temperature jump wall boundary marker(s) + /*!\brief Smoluchowski/Maxwell wall boundary marker(s) \n DESCRIPTION: Slip velocity and temperature jump wall boundary marker(s) Format: ( Heat flux marker, wall temperature (static), momentum accomodation coefficient, thermal accomodation coefficient ... ) \ingroup Config*/ addStringDoubleListOption("MARKER_SMOLUCHOWSKI_MAXWELL", nMarker_Smoluchowski_Maxwell, Marker_Smoluchowski_Maxwell, Isothermal_Temperature); //Missing TMAC and TAC /*!\brief WALL_ROUGHNESS \n DESCRIPTION: Specified roughness heights at wall boundary marker(s) @@ -1650,9 +1670,19 @@ void CConfig::SetConfig_Options() { addBoolOption("SUBSONIC_ENGINE", SubsonicEngine, false); /* DESCRIPTION: Actuator disk double surface */ addBoolOption("ACTDISK_DOUBLE_SURFACE", ActDisk_DoubleSurface, false); + + /* DESCRIPTION: Actuator disk BEM switch for history file appending.*/ + addBoolOption("HISTORY_FILE_APPEND", History_File_Append_Flag, false); + /* DESCRIPTION: Propeller blade angle for actuator disk BEM.*/ + addDoubleOption("BEM_PROP_BLADE_ANGLE", BEM_blade_angle, 23.9); + /* DESCRIPTION: Propeller file name for actuator disk BEM.*/ + addStringOption("BEM_PROP_FILENAME", BEM_prop_filename, string("prop_geom_alfclcd_data.txt")); + /* DESCRIPTION: Frequency for updating actuator disk with BEM.*/ + addUnsignedShortOption("BEM_FREQ", ActDiskBem_Frequency, 40); + /* DESCRIPTION: Only half engine is in the computational grid */ addBoolOption("ENGINE_HALF_MODEL", Engine_HalfModel, false); - /* DESCRIPTION: Actuator disk double surface */ + /* DESCRIPTION: Actuator disk SU2_DEF */ addBoolOption("ACTDISK_SU2_DEF", ActDisk_SU2_DEF, false); /* DESCRIPTION: Definition of the distortion rack (radial number of proves / circumferential density (degree) */ distortion[0] = 5.0; distortion[1] = 15.0; @@ -1681,9 +1711,6 @@ void CConfig::SetConfig_Options() { /* DESCRIPTION: Load boundary marker(s) Format: (inlet marker, load, multiplier, dir_x, dir_y, dir_z, ... ), i.e. primitive variables specified. */ addInletOption("MARKER_DISPLACEMENT", nMarker_Disp_Dir, Marker_Disp_Dir, Disp_Dir_Value, Disp_Dir_Multiplier, Disp_Dir); - /* DESCRIPTION: Sine load boundary marker(s) - Format: (inlet marker, load, multiplier, dir_x, dir_y, dir_z, ... ), i.e. primitive variables specified. */ - addInletOption("MARKER_SINE_LOAD", nMarker_Load_Sine, Marker_Load_Sine, Load_Sine_Amplitude, Load_Sine_Frequency, Load_Sine_Dir); /*!\brief SINE_LOAD\n DESCRIPTION: option to apply the load as a sine*/ addBoolOption("SINE_LOAD", Sine_Load, false); sineload_coeff[0] = 0.0; sineload_coeff[1] = 0.0; sineload_coeff[2] = 0.0; @@ -1692,8 +1719,6 @@ void CConfig::SetConfig_Options() { /*!\brief RAMP_AND_RELEASE\n DESCRIPTION: release the load after applying the ramp*/ addBoolOption("RAMP_AND_RELEASE_LOAD", RampAndRelease, false); - /* DESCRIPTION: Flow load boundary marker(s) */ - addStringDoubleListOption("MARKER_FLOWLOAD", nMarker_FlowLoad, Marker_FlowLoad, FlowLoad_Value); /* DESCRIPTION: Damping factor for engine inlet condition */ addDoubleOption("DAMP_ENGINE_INFLOW", Damp_Engine_Inflow, 0.95); /* DESCRIPTION: Damping factor for engine exhaust condition */ @@ -1821,18 +1846,10 @@ void CConfig::SetConfig_Options() { addBoolOption("LOW_MACH_PREC", Low_Mach_Precon, false); /* DESCRIPTION: Post-reconstruction correction for low Mach number flows */ addBoolOption("LOW_MACH_CORR", Low_Mach_Corr, false); - /* DESCRIPTION: Time Step for dual time stepping simulations (s) */ + /* DESCRIPTION: Minimum value for beta for the Roe-Turkel preconditioner */ addDoubleOption("MIN_ROE_TURKEL_PREC", Min_Beta_RoeTurkel, 0.01); - /* DESCRIPTION: Time Step for dual time stepping simulations (s) */ + /* DESCRIPTION: Maximum value for beta for the Roe-Turkel preconditioner */ addDoubleOption("MAX_ROE_TURKEL_PREC", Max_Beta_RoeTurkel, 0.2); - /* DESCRIPTION: Linear solver for the turbulent adjoint systems */ - addEnumOption("ADJTURB_LIN_SOLVER", Kind_AdjTurb_Linear_Solver, Linear_Solver_Map, FGMRES); - /* DESCRIPTION: Preconditioner for the turbulent adjoint Krylov linear solvers */ - addEnumOption("ADJTURB_LIN_PREC", Kind_AdjTurb_Linear_Prec, Linear_Solver_Prec_Map, ILU); - /* DESCRIPTION: Minimum error threshold for the turbulent adjoint linear solver for the implicit formulation */ - addDoubleOption("ADJTURB_LIN_ERROR", AdjTurb_Linear_Error, 1E-5); - /* DESCRIPTION: Maximum number of iterations of the turbulent adjoint linear solver for the implicit formulation */ - addUnsignedShortOption("ADJTURB_LIN_ITER", AdjTurb_Linear_Iter, 10); /* DESCRIPTION: Entropy fix factor */ addDoubleOption("ENTROPY_FIX_COEFF", EntropyFix_Coeff, 0.001); /* DESCRIPTION: Linear solver for the discete adjoint systems */ @@ -1844,6 +1861,8 @@ void CConfig::SetConfig_Options() { /*!\par CONFIG_CATEGORY: Convergence\ingroup Config*/ /*--- Options related to convergence ---*/ + /*!\brief CONV_FIELD\n DESCRIPTION: Output field to monitor \n Default: depends on solver \ingroup Config*/ + addStringListOption("CONV_FIELD", nConvField, ConvField); /*!\brief CONV_RESIDUAL_MINVAL\n DESCRIPTION: Min value of the residual (log10 of the residual)\n DEFAULT: -14.0 \ingroup Config*/ addDoubleOption("CONV_RESIDUAL_MINVAL", MinLogResidual, -14.0); /*!\brief CONV_STARTITER\n DESCRIPTION: Iteration number to begin convergence monitoring\n DEFAULT: 5 \ingroup Config*/ @@ -1852,15 +1871,13 @@ void CConfig::SetConfig_Options() { addUnsignedShortOption("CONV_CAUCHY_ELEMS", Cauchy_Elems, 100); /*!\brief CONV_CAUCHY_EPS\n DESCRIPTION: Epsilon to control the series convergence \n DEFAULT: 1e-10 \ingroup Config*/ addDoubleOption("CONV_CAUCHY_EPS", Cauchy_Eps, 1E-10); - /*!\brief CONV_FIELD\n DESCRIPTION: Output field to monitor \n Default: depends on solver \ingroup Config*/ - addStringListOption("CONV_FIELD", nConvField, ConvField); /*!\brief CONV_WINDOW_STARTITER\n DESCRIPTION: Iteration number after START_ITER_WND to begin convergence monitoring\n DEFAULT: 15 \ingroup Config*/ addUnsignedLongOption("CONV_WINDOW_STARTITER", Wnd_StartConv_Iter, 15); - /*!\brief CONV_WINDOW_CAUCHY_ELEMS\n DESCRIPTION: Number of elements to apply the criteria. \n DEFAULT 100 \ingroup Config*/ - addUnsignedShortOption("CONV_WINDOW_CAUCHY_ELEMS", Wnd_Cauchy_Elems, 100); /*!\brief CONV_WINDOW_CAUCHY_EPS\n DESCRIPTION: Epsilon to control the series convergence \n DEFAULT: 1e-3 \ingroup Config*/ addDoubleOption("CONV_WINDOW_CAUCHY_EPS", Wnd_Cauchy_Eps, 1E-3); + /*!\brief CONV_WINDOW_CAUCHY_ELEMS\n DESCRIPTION: Number of elements to apply the criteria. \n DEFAULT 100 \ingroup Config*/ + addUnsignedShortOption("CONV_WINDOW_CAUCHY_ELEMS", Wnd_Cauchy_Elems, 100); /*!\brief WINDOW_CAUCHY_CRIT \n DESCRIPTION: Determines, if the cauchy convergence criterion should be used for windowed time averaged objective functions*/ addBoolOption("WINDOW_CAUCHY_CRIT",Wnd_Cauchy_Crit, false); /*!\brief CONV_WINDOW_FIELD @@ -2100,7 +2117,7 @@ void CConfig::SetConfig_Options() { /* DESCRIPTION: Determine if the mesh file supports multizone. \n DEFAULT: true (temporarily) */ addBoolOption("MULTIZONE_MESH", Multizone_Mesh, true); - /* DESCRIPTION: Determine if we need to allocate memory to store the multizone residual. \n DEFAULT: true (temporarily) */ + /* DESCRIPTION: Determine if we need to allocate memory to store the multizone residual. \n DEFAULT: false (temporarily) */ addBoolOption("MULTIZONE_RESIDUAL", Multizone_Residual, false); /* !\brief CONTROLLING_VARIABLE_NAMES \n DESCRIPTION: Names of the variables used as inputs for the data regression method in flamelet or data-driven fluid models. */ @@ -2343,9 +2360,9 @@ void CConfig::SetConfig_Options() { addDoubleOption("DEFORM_LIMIT", Deform_Limit, 1E6); /* DESCRIPTION: Type of element stiffness imposed for FEA mesh deformation (INVERSE_VOLUME, WALL_DISTANCE, CONSTANT_STIFFNESS) */ addEnumOption("DEFORM_STIFFNESS_TYPE", Deform_StiffnessType, Deform_Stiffness_Map, SOLID_WALL_DISTANCE); - /* DESCRIPTION: Poisson's ratio for constant stiffness FEA method of grid deformation */ + /* DESCRIPTION: Young's modulus for constant stiffness FEA method of grid deformation */ addDoubleOption("DEFORM_ELASTICITY_MODULUS", Deform_ElasticityMod, 2E11); - /* DESCRIPTION: Young's modulus and Poisson's ratio for constant stiffness FEA method of grid deformation */ + /* DESCRIPTION: Poisson's ratio for constant stiffness FEA method of grid deformation */ addDoubleOption("DEFORM_POISSONS_RATIO", Deform_PoissonRatio, 0.3); /* DESCRIPTION: Size of the layer of highest stiffness for wall distance-based mesh stiffness */ addDoubleOption("DEFORM_STIFF_LAYER_SIZE", Deform_StiffLayerSize, 0.0); @@ -2358,14 +2375,6 @@ void CConfig::SetConfig_Options() { /* DESCRIPTION: Maximum number of iterations of the linear solver for the implicit formulation */ addUnsignedLongOption("DEFORM_LINEAR_SOLVER_ITER", Deform_Linear_Solver_Iter, 1000); - /*!\par CONFIG_CATEGORY: Rotorcraft problem \ingroup Config*/ - /*--- option related to rotorcraft problems ---*/ - - /* DESCRIPTION: MISSING ---*/ - addDoubleOption("CYCLIC_PITCH", Cyclic_Pitch, 0.0); - /* DESCRIPTION: MISSING ---*/ - addDoubleOption("COLLECTIVE_PITCH", Collective_Pitch, 0.0); - /*!\par CONFIG_CATEGORY: FEM flow solver definition \ingroup Config*/ /*--- Options related to the finite element flow solver---*/ @@ -2392,7 +2401,7 @@ void CConfig::SetConfig_Options() { /*!\par CONFIG_CATEGORY: FEA solver \ingroup Config*/ /*--- Options related to the FEA solver ---*/ - /*!\brief FEA_FILENAME \n DESCRIPTION: Filename to input for element-based properties \n Default: element_properties.dat \ingroup Config */ + /*!\brief FEA_FILENAME \n DESCRIPTION: Filename to input for element-based properties \n Default: default_element_properties.dat \ingroup Config */ addStringOption("FEA_FILENAME", FEA_FileName, string("default_element_properties.dat")); /* DESCRIPTION: Determine if advanced features are used from the element-based FEA analysis (NO, YES = experimental) */ addBoolOption("FEA_ADVANCED_MODE", FEAAdvancedMode, false); @@ -2421,7 +2430,6 @@ void CConfig::SetConfig_Options() { /*!\brief DESIGN_VARIABLE_FEA * \n DESCRIPTION: Design variable for FEA problems \n OPTIONS: See \link DVFEA_Map \endlink \n DEFAULT VENKATAKRISHNAN \ingroup Config */ addEnumOption("DESIGN_VARIABLE_FEA", Kind_DV_FEA, DVFEA_Map, NODV_FEA); - /* DESCRIPTION: Consider a reference solution for the structure (optimization applications) * Options: NO, YES \ingroup Config */ addBoolOption("REFERENCE_GEOMETRY", RefGeom, false); @@ -2434,9 +2442,6 @@ void CConfig::SetConfig_Options() { /*!\brief REFERENCE_GEOMETRY_SURFACE\n DESCRIPTION: If true consider only the surfaces where loads are applied. \ingroup Config*/ addBoolOption("REFERENCE_GEOMETRY_SURFACE", RefGeomSurf, false); - /*!\brief TOTAL_DV_PENALTY\n DESCRIPTION: Penalty weight value to maintain the total sum of DV constant \ingroup Config*/ - addDoubleOption("TOTAL_DV_PENALTY", DV_Penalty, 0); - /*!\brief REFERENCE_NODE\n DESCRIPTION: Reference node for the structure (optimization applications) */ addUnsignedLongOption("REFERENCE_NODE", refNodeID, 0); /*!\brief REFERENCE_NODE_DISPLACEMENT\n DESCRIPTION: Target displacement of the reference node \ingroup Config*/ @@ -2444,6 +2449,9 @@ void CConfig::SetConfig_Options() { /*!\brief REFERENCE_NODE_PENALTY\n DESCRIPTION: Penalty weight value for the objective function \ingroup Config*/ addDoubleOption("REFERENCE_NODE_PENALTY", RefNode_Penalty, 1E3); + /*!\brief TOTAL_DV_PENALTY\n DESCRIPTION: Penalty weight value to maintain the total sum of DV constant \ingroup Config*/ + addDoubleOption("TOTAL_DV_PENALTY", DV_Penalty, 0); + /*!\brief STRESS_PENALTY_PARAM\n DESCRIPTION: Maximum allowed stress and KS exponent for structural optimization \ingroup Config*/ addDoubleArrayOption("STRESS_PENALTY_PARAM", 2, StressPenaltyParam.data()); @@ -2472,7 +2480,7 @@ void CConfig::SetConfig_Options() { addBoolOption("PSEUDO_STATIC", PseudoStatic, false); /* DESCRIPTION: Parameter alpha for Newmark scheme (s) */ addDoubleOption("NEWMARK_BETA", Newmark_beta, 0.25); - /* DESCRIPTION: Parameter delta for Newmark scheme (s) */ + /* DESCRIPTION: Parameter gamma for Newmark scheme (s) */ addDoubleOption("NEWMARK_GAMMA", Newmark_gamma, 0.5); /* DESCRIPTION: Apply the load as a ramp */ addBoolOption("RAMP_LOADING", Ramp_Load, false); @@ -2550,7 +2558,7 @@ void CConfig::SetConfig_Options() { /* DESCRIPTION: Determines if the convergence history of each individual zone is written to file */ addBoolOption("WRT_ZONE_HIST", Wrt_ZoneHist, false); - /* DESCRIPTION: Determines if the special output is written out */ + /* DESCRIPTION: Determines if the forces breakdown is written out */ addBoolOption("WRT_FORCES_BREAKDOWN", Wrt_ForcesBreakdown, false); @@ -2652,7 +2660,7 @@ void CConfig::SetConfig_Options() { /*!\par CONFIG_CATEGORY: Visualize Control Volumes \ingroup Config*/ /*--- options related to visualizing control volumes ---*/ - /* DESCRIPTION: Node number for the CV to be visualized */ + /* DESCRIPTION: Node number for the CV to be visualized (tecplot) */ addLongOption("VISUALIZE_CV", Visualize_CV, -1); /*!\par CONFIG_CATEGORY: Inverse design problem \ingroup Config*/ @@ -2667,10 +2675,10 @@ void CConfig::SetConfig_Options() { /*!\par CONFIG_CATEGORY: Unsupported options \ingroup Config*/ /*--- Options that are experimental and not intended for general use ---*/ - /* DESCRIPTION: Write extra output */ + /* DESCRIPTION: Write extra output (EXPERIMENTAL, NOT FOR GENERAL USE) */ addBoolOption("EXTRA_OUTPUT", ExtraOutput, false); - /* DESCRIPTION: Write extra heat output for a given zone heat solver zone */ + /* DESCRIPTION: Write extra heat output for a given heat solver zone */ addLongOption("EXTRA_HEAT_ZONE_OUTPUT", ExtraHeatOutputZone, -1); /*--- options related to the FFD problem ---*/ @@ -2918,6 +2926,9 @@ void CConfig::SetConfig_Options() { /* DESCRIPTION: Size of the edge groups colored for thread parallel edge loops (0 forces the reducer strategy). */ addUnsignedLongOption("EDGE_COLORING_GROUP_SIZE", edgeColorGroupSize, 512); + /* DESCRIPTION: Allow fallback to smaller edge color group sizes for the discrete adjoint and allow more colors. */ + addBoolOption("EDGE_COLORING_RELAX_DISC_ADJ", edgeColoringRelaxDiscAdj, true); + /*--- options that are used for libROM ---*/ /*!\par CONFIG_CATEGORY:libROM options \ingroup Config*/ @@ -4977,6 +4988,18 @@ void CConfig::SetPostprocessing(SU2_COMPONENT val_software, unsigned short val_i SU2_MPI::Error("Vorticity confinement feature currently not supported for incompressible or non-equilibrium model or axisymmetric flows.", CURRENT_FUNCTION); } + /*--- Actuator disk BEM method for propellers feature currently not supported for incompressible or non-equilibrium model or axisymmetric flows. ---*/ + + if ((Kind_Solver == MAIN_SOLVER::INC_EULER + || Kind_Solver == MAIN_SOLVER::INC_NAVIER_STOKES + || Kind_Solver == MAIN_SOLVER::INC_RANS + || Kind_Solver == MAIN_SOLVER::NEMO_EULER + || Kind_Solver == MAIN_SOLVER::NEMO_NAVIER_STOKES + || Axisymmetric) + && ActDisk_DoubleSurface) { + SU2_MPI::Error("Actuator disk BEM method for propellers feature currently not supported for incompressible or non-equilibrium model or axisymmetric flows.", CURRENT_FUNCTION); + } + /*--- Check the coefficients for the polynomial models. ---*/ if (Kind_Solver != MAIN_SOLVER::INC_EULER && Kind_Solver != MAIN_SOLVER::INC_NAVIER_STOKES && Kind_Solver != MAIN_SOLVER::INC_RANS) { @@ -5508,10 +5531,10 @@ void CConfig::SetMarkers(SU2_COMPONENT val_software) { iMarker_Smoluchowski_Maxwell, iMarker_Isothermal,iMarker_HeatFlux,iMarker_HeatTansfer, iMarker_EngineInflow, iMarker_EngineExhaust, iMarker_Damper, - iMarker_Displacement, iMarker_Load, iMarker_FlowLoad, iMarker_Internal, + iMarker_Displacement, iMarker_Load, iMarker_Internal, iMarker_Monitoring, iMarker_Designing, iMarker_GeoEval, iMarker_Plotting, iMarker_Analyze, iMarker_DV, iMarker_Moving, iMarker_SobolevBC, iMarker_PyCustom, iMarker_Supersonic_Inlet, iMarker_Supersonic_Outlet, - iMarker_Clamped, iMarker_ZoneInterface, iMarker_CHTInterface, iMarker_Load_Dir, iMarker_Disp_Dir, iMarker_Load_Sine, + iMarker_Clamped, iMarker_ZoneInterface, iMarker_CHTInterface, iMarker_Load_Dir, iMarker_Disp_Dir, iMarker_Fluid_Load, iMarker_Deform_Mesh, iMarker_Deform_Mesh_Sym_Plane, iMarker_ActDiskInlet, iMarker_ActDiskOutlet, iMarker_Turbomachinery, iMarker_MixingPlaneInterface; @@ -5527,9 +5550,11 @@ void CConfig::SetMarkers(SU2_COMPONENT val_software) { nMarker_HeatFlux + nMarker_HeatTransfer + nMarker_EngineInflow + nMarker_EngineExhaust + nMarker_Internal + nMarker_Supersonic_Inlet + nMarker_Supersonic_Outlet + nMarker_Displacement + nMarker_Load + - nMarker_FlowLoad + nMarker_Custom + nMarker_Damper + nMarker_Fluid_Load + - nMarker_Clamped + nMarker_Load_Sine + nMarker_Load_Dir + nMarker_Disp_Dir + - nMarker_ActDiskInlet + nMarker_ActDiskOutlet + nMarker_ZoneInterface; + nMarker_Custom + nMarker_Damper + nMarker_Fluid_Load + + nMarker_Clamped + nMarker_Load_Dir + nMarker_Disp_Dir + + nMarker_ActDiskInlet + nMarker_ActDiskOutlet + + nMarker_ActDiskBemInlet + nMarker_ActDiskBemOutlet + + nMarker_ZoneInterface; /*--- Add the possible send/receive domains ---*/ @@ -5684,6 +5709,9 @@ void CConfig::SetMarkers(SU2_COMPONENT val_software) { ActDiskOutlet_Force = new su2double[nMarker_ActDiskOutlet] (); ActDiskOutlet_Power = new su2double[nMarker_ActDiskOutlet] (); + ActDiskOutlet_Thrust_BEM = new su2double[nMarker_ActDiskOutlet](); + ActDiskOutlet_Torque_BEM = new su2double[nMarker_ActDiskOutlet](); + for (iMarker_ActDiskOutlet = 0; iMarker_ActDiskOutlet < nMarker_ActDiskOutlet; iMarker_ActDiskOutlet++) { Marker_CfgFile_TagBound[iMarker_CfgFile] = Marker_ActDiskOutlet[iMarker_ActDiskOutlet]; Marker_CfgFile_KindBC[iMarker_CfgFile] = ACTDISK_OUTLET; @@ -5859,23 +5887,11 @@ void CConfig::SetMarkers(SU2_COMPONENT val_software) { iMarker_CfgFile++; } - for (iMarker_Load_Sine = 0; iMarker_Load_Sine < nMarker_Load_Sine; iMarker_Load_Sine++) { - Marker_CfgFile_TagBound[iMarker_CfgFile] = Marker_Load_Sine[iMarker_Load_Sine]; - Marker_CfgFile_KindBC[iMarker_CfgFile] = LOAD_SINE_BOUNDARY; - iMarker_CfgFile++; - } - for (iMarker_Fluid_Load = 0; iMarker_Fluid_Load < nMarker_Fluid_Load; iMarker_Fluid_Load++) { Marker_CfgFile_TagBound[iMarker_CfgFile] = Marker_Fluid_Load[iMarker_Fluid_Load]; iMarker_CfgFile++; } - for (iMarker_FlowLoad = 0; iMarker_FlowLoad < nMarker_FlowLoad; iMarker_FlowLoad++) { - Marker_CfgFile_TagBound[iMarker_CfgFile] = Marker_FlowLoad[iMarker_FlowLoad]; - Marker_CfgFile_KindBC[iMarker_CfgFile] = FLOWLOAD_BOUNDARY; - iMarker_CfgFile++; - } - for (iMarker_CfgFile = 0; iMarker_CfgFile < nMarker_CfgFile; iMarker_CfgFile++) { Marker_CfgFile_Monitoring[iMarker_CfgFile] = NO; for (iMarker_Monitoring = 0; iMarker_Monitoring < nMarker_Monitoring; iMarker_Monitoring++) @@ -6035,9 +6051,9 @@ void CConfig::SetOutput(SU2_COMPONENT val_software, unsigned short val_izone) { iMarker_Smoluchowski_Maxwell, iWall_Catalytic, iMarker_Giles, iMarker_Outlet, iMarker_Isothermal, iMarker_HeatFlux, iMarker_HeatTransfer, iMarker_EngineInflow, iMarker_EngineExhaust, iMarker_Displacement, iMarker_Damper, - iMarker_Load, iMarker_FlowLoad, iMarker_Internal, iMarker_Monitoring, + iMarker_Load, iMarker_Internal, iMarker_Monitoring, iMarker_Designing, iMarker_GeoEval, iMarker_Plotting, iMarker_Analyze, iMarker_DV, iDV_Value, - iMarker_ZoneInterface, iMarker_PyCustom, iMarker_Load_Dir, iMarker_Disp_Dir, iMarker_Load_Sine, iMarker_Clamped, + iMarker_ZoneInterface, iMarker_PyCustom, iMarker_Load_Dir, iMarker_Disp_Dir, iMarker_Clamped, iMarker_Moving, iMarker_Supersonic_Inlet, iMarker_Supersonic_Outlet, iMarker_ActDiskInlet, iMarker_Emissivity, iMarker_StrongBC, iMarker_ActDiskOutlet, iMarker_MixingPlaneInterface, @@ -7323,15 +7339,6 @@ void CConfig::SetOutput(SU2_COMPONENT val_software, unsigned short val_izone) { BoundaryTable.PrintFooter(); } - if (nMarker_FlowLoad != 0) { - BoundaryTable << "Flow load boundary"; - for (iMarker_FlowLoad = 0; iMarker_FlowLoad < nMarker_FlowLoad; iMarker_FlowLoad++) { - BoundaryTable << Marker_FlowLoad[iMarker_FlowLoad]; - if (iMarker_FlowLoad < nMarker_FlowLoad-1) BoundaryTable << " "; - } - BoundaryTable.PrintFooter(); - } - if (nMarker_Internal != 0) { BoundaryTable << "Internal boundary"; for (iMarker_Internal = 0; iMarker_Internal < nMarker_Internal; iMarker_Internal++) { @@ -7530,15 +7537,6 @@ void CConfig::SetOutput(SU2_COMPONENT val_software, unsigned short val_izone) { BoundaryTable.PrintFooter(); } - if (nMarker_Load_Sine != 0) { - BoundaryTable << "Sine-Wave boundary"; - for (iMarker_Load_Sine = 0; iMarker_Load_Sine < nMarker_Load_Sine; iMarker_Load_Sine++) { - BoundaryTable << Marker_Load_Sine[iMarker_Load_Sine]; - if (iMarker_Load_Sine < nMarker_Load_Sine-1) BoundaryTable << " "; - } - BoundaryTable.PrintFooter(); - } - if (nMarker_Emissivity != 0) { BoundaryTable << "Radiative boundary"; for (iMarker_Emissivity = 0; iMarker_Emissivity < nMarker_Emissivity; iMarker_Emissivity++) { @@ -7600,6 +7598,12 @@ void CConfig::SetOutput(SU2_COMPONENT val_software, unsigned short val_izone) { } } + if (nMarker_ActDiskOutlet != 0) { + if (GetKind_ActDisk() == BLADE_ELEMENT) { + cout << endl << "Actuator disk with blade element momentum (BEM) method." << endl; + cout << "Actuator disk BEM method propeller data read from file: " << GetBEM_prop_filename() << endl; + } + } } bool CConfig::TokenizeString(string & str, string & option_name, @@ -8093,6 +8097,9 @@ CConfig::~CConfig() { delete[] ActDiskOutlet_Force; delete[] ActDiskOutlet_Power; + delete[] ActDiskOutlet_Thrust_BEM; + delete[] ActDiskOutlet_Torque_BEM; + delete[] Outlet_MassFlow; delete[] Outlet_Density; delete[] Outlet_Area; @@ -8678,6 +8685,22 @@ su2double CConfig::GetActDisk_Omega(const string& val_marker, unsigned short val return ActDisk_Omega[iMarker_ActDisk][val_value];; } +su2double CConfig::GetActDiskBem_CG(unsigned short iDim, string val_marker, unsigned short val_value) const { + unsigned short iMarker_ActDisk; + for (iMarker_ActDisk = 0; iMarker_ActDisk < nMarker_ActDiskBemInlet; iMarker_ActDisk++) + if ((Marker_ActDiskBemInlet[iMarker_ActDisk] == val_marker) || + (Marker_ActDiskBemOutlet[iMarker_ActDisk] == val_marker)) break; + return ActDiskBem_CG[iDim][iMarker_ActDisk][val_value]; +} + +su2double CConfig::GetActDiskBem_Axis(unsigned short iDim, string val_marker, unsigned short val_value) const { + unsigned short iMarker_ActDisk; + for (iMarker_ActDisk = 0; iMarker_ActDisk < nMarker_ActDiskBemInlet; iMarker_ActDisk++) + if ((Marker_ActDiskBemInlet[iMarker_ActDisk] == val_marker) || + (Marker_ActDiskBemOutlet[iMarker_ActDisk] == val_marker)) break; + return ActDiskBem_Axis[iDim][iMarker_ActDisk][val_value]; +} + su2double CConfig::GetOutlet_MassFlow(const string& val_marker) const { unsigned short iMarker_Outlet; for (iMarker_Outlet = 0; iMarker_Outlet < nMarker_Outlet; iMarker_Outlet++) @@ -9454,6 +9477,20 @@ su2double CConfig::GetActDiskOutlet_Power(const string& val_marker) const { return ActDiskOutlet_Power[iMarker_ActDiskOutlet]; } +su2double CConfig::GetActDiskOutlet_Thrust_BEM(string val_marker) const { + unsigned short iMarker_ActDiskOutlet; + for (iMarker_ActDiskOutlet = 0; iMarker_ActDiskOutlet < nMarker_ActDiskOutlet; iMarker_ActDiskOutlet++) + if (Marker_ActDiskOutlet[iMarker_ActDiskOutlet] == val_marker) break; + return ActDiskOutlet_Thrust_BEM[iMarker_ActDiskOutlet]; +} + +su2double CConfig::GetActDiskOutlet_Torque_BEM(string val_marker) const { + unsigned short iMarker_ActDiskOutlet; + for (iMarker_ActDiskOutlet = 0; iMarker_ActDiskOutlet < nMarker_ActDiskOutlet; iMarker_ActDiskOutlet++) + if (Marker_ActDiskOutlet[iMarker_ActDiskOutlet] == val_marker) break; + return ActDiskOutlet_Torque_BEM[iMarker_ActDiskOutlet]; +} + su2double CConfig::GetActDiskInlet_Temperature(const string& val_marker) const { unsigned short iMarker_ActDiskInlet; for (iMarker_ActDiskInlet = 0; iMarker_ActDiskInlet < nMarker_ActDiskInlet; iMarker_ActDiskInlet++) @@ -9559,27 +9596,6 @@ const su2double* CConfig::GetDisp_Dir(const string& val_marker) const { return Disp_Dir[iMarker_Disp_Dir]; } -su2double CConfig::GetLoad_Sine_Amplitude(const string& val_marker) const { - unsigned short iMarker_Load_Sine; - for (iMarker_Load_Sine = 0; iMarker_Load_Sine < nMarker_Load_Sine; iMarker_Load_Sine++) - if (Marker_Load_Sine[iMarker_Load_Sine] == val_marker) break; - return Load_Sine_Amplitude[iMarker_Load_Sine]; -} - -su2double CConfig::GetLoad_Sine_Frequency(const string& val_marker) const { - unsigned short iMarker_Load_Sine; - for (iMarker_Load_Sine = 0; iMarker_Load_Sine < nMarker_Load_Sine; iMarker_Load_Sine++) - if (Marker_Load_Sine[iMarker_Load_Sine] == val_marker) break; - return Load_Sine_Frequency[iMarker_Load_Sine]; -} - -const su2double* CConfig::GetLoad_Sine_Dir(const string& val_marker) const { - unsigned short iMarker_Load_Sine; - for (iMarker_Load_Sine = 0; iMarker_Load_Sine < nMarker_Load_Sine; iMarker_Load_Sine++) - if (Marker_Load_Sine[iMarker_Load_Sine] == val_marker) break; - return Load_Sine_Dir[iMarker_Load_Sine]; -} - su2double CConfig::GetWall_Emissivity(const string& val_marker) const { unsigned short iMarker_Emissivity = 0; @@ -9601,19 +9617,12 @@ bool CConfig::GetMarker_StrongBC(const string& val_marker) const { return false; } -su2double CConfig::GetFlowLoad_Value(const string& val_marker) const { - unsigned short iMarker_FlowLoad; - for (iMarker_FlowLoad = 0; iMarker_FlowLoad < nMarker_FlowLoad; iMarker_FlowLoad++) - if (Marker_FlowLoad[iMarker_FlowLoad] == val_marker) break; - return FlowLoad_Value[iMarker_FlowLoad]; -} short CConfig::FindInterfaceMarker(unsigned short iInterface) const { /*--- The names of the two markers that form the interface. ---*/ const auto& sideA = Marker_ZoneInterface[2*iInterface]; const auto& sideB = Marker_ZoneInterface[2*iInterface+1]; - for (unsigned short iMarker = 0; iMarker < nMarker_All; iMarker++) { /*--- If the marker is sideA or sideB of the interface (order does not matter). ---*/ const auto& tag = Marker_All_TagBound[iMarker]; diff --git a/Common/src/geometry/CGeometry.cpp b/Common/src/geometry/CGeometry.cpp index 9ed1804186a..aeca6421763 100644 --- a/Common/src/geometry/CGeometry.cpp +++ b/Common/src/geometry/CGeometry.cpp @@ -3609,7 +3609,7 @@ const su2vector& CGeometry::GetTransposeSparsePatternMap(Connecti return pattern.transposePtr(); } -const CCompressedSparsePatternUL& CGeometry::GetEdgeColoring(su2double* efficiency) { +const CCompressedSparsePatternUL& CGeometry::GetEdgeColoring(su2double* efficiency, bool maximizeEdgeColorGroupSize) { /*--- Check for dry run mode with dummy geometry. ---*/ if (nEdge == 0) return edgeColoring; @@ -3637,7 +3637,60 @@ const CCompressedSparsePatternUL& CGeometry::GetEdgeColoring(su2double* efficien /*--- Color the edges. ---*/ constexpr bool balanceColors = true; - edgeColoring = colorSparsePattern(pattern, edgeColorGroupSize, balanceColors); + + /*--- If requested, find an efficient coloring with maximum color group size (up to edgeColorGroupSize). ---*/ + if (maximizeEdgeColorGroupSize) { + auto upperEdgeColorGroupSize = edgeColorGroupSize + 1; /* upper bound that is deemed too large */ + auto nextEdgeColorGroupSize = edgeColorGroupSize; /* next value that we are going to try */ + auto lowerEdgeColorGroupSize = 1ul; /* lower bound that is known to work */ + + bool admissibleColoring = false; /* keep track wether the last tested coloring is admissible */ + + while (true) { + edgeColoring = colorSparsePattern(pattern, nextEdgeColorGroupSize, balanceColors); + + /*--- If the coloring fails, reduce the color group size. ---*/ + if (edgeColoring.empty()) { + upperEdgeColorGroupSize = nextEdgeColorGroupSize; + admissibleColoring = false; + } + /*--- If the coloring succeeds, check the efficiency. ---*/ + else { + const su2double currentEfficiency = + coloringEfficiency(edgeColoring, omp_get_max_threads(), nextEdgeColorGroupSize); + + /*--- If the coloring is not efficient, reduce the color group size. ---*/ + if (currentEfficiency < COLORING_EFF_THRESH) { + upperEdgeColorGroupSize = nextEdgeColorGroupSize; + admissibleColoring = false; + } + /*--- Otherwise, enlarge the color group size. ---*/ + else { + lowerEdgeColorGroupSize = nextEdgeColorGroupSize; + admissibleColoring = true; + } + } + + const auto increment = (upperEdgeColorGroupSize - lowerEdgeColorGroupSize) / 2; + nextEdgeColorGroupSize = lowerEdgeColorGroupSize + increment; + + /*--- Terminating condition. ---*/ + if (increment == 0) { + break; + } + } + + edgeColorGroupSize = nextEdgeColorGroupSize; + + /*--- If the last tested coloring was not admissible, recompute the final coloring. ---*/ + if (!admissibleColoring) { + edgeColoring = colorSparsePattern(pattern, edgeColorGroupSize, balanceColors); + } + } + /*--- No adaptivity. ---*/ + else { + edgeColoring = colorSparsePattern(pattern, edgeColorGroupSize, balanceColors); + } /*--- If the coloring fails use the natural coloring. This is a * "soft" failure as this "bad" coloring should be detected diff --git a/SU2_CFD/include/drivers/CDriver.hpp b/SU2_CFD/include/drivers/CDriver.hpp index e771c65a79f..ff2f335e500 100644 --- a/SU2_CFD/include/drivers/CDriver.hpp +++ b/SU2_CFD/include/drivers/CDriver.hpp @@ -818,6 +818,24 @@ class CDriver : public CDriverBase { */ void SetRotationRate(passivedouble rot_x, passivedouble rot_y, passivedouble rot_z); + /*! + * \brief Set the moving wall marker rotation rates. + * \param[in] iMaker - Index of moving wall marker. + * \param[in] rot_x - Value of Angular velocity about x-axes. + * \param[in] rot_y - Value of Angular velocity about y-axes. + * \param[in] rot_z - Value of Angular velocity about z-axes. + */ + void SetMarkerRotationRate(unsigned short iMarker, passivedouble rot_x, passivedouble rot_y, passivedouble rot_z); + + /*! + * \brief Set the moving wall marker translation rates. + * \param[in] iMaker - Index of moving wall marker. + * \param[in] vel_x - Value of velocity along x-axis. + * \param[in] vel_y - Value of velocity along y-axis. + * \param[in] vel_z - Value of velocity along z-axis. + */ + void SetMarkerTranslationRate(unsigned short iMarker, passivedouble vel_x, passivedouble vel_y, passivedouble vel_z); + /// \} }; diff --git a/SU2_CFD/include/solvers/CEulerSolver.hpp b/SU2_CFD/include/solvers/CEulerSolver.hpp index 04b49d9c523..63f82f3fa7e 100644 --- a/SU2_CFD/include/solvers/CEulerSolver.hpp +++ b/SU2_CFD/include/solvers/CEulerSolver.hpp @@ -65,6 +65,9 @@ class CEulerSolver : public CFVMFlowSolverBase > DonorGlobalIndex; /*!< \brief Value of the donor global index. */ vector DonorPrimVar; /*!< \brief Value of the donor variables at each boundary. */ vector > ActDisk_DeltaP; /*!< \brief Value of the Delta P. */ + vector > ActDisk_DeltaP_r; /*!< \brief Value of the DeltaP_r. */ + vector > ActDisk_Thrust_r; /*!< \brief Value of the Thrust_r. */ + vector > ActDisk_Torque_r; /*!< \brief Value of the Torque_r. */ vector > ActDisk_DeltaT; /*!< \brief Value of the Delta T. */ su2activevector @@ -76,6 +79,10 @@ class CEulerSolver : public CFVMFlowSolverBase > ActDisk_Fx; /*!< \brief Value of the actuator disk X component of the radial and tangential forces per Unit Area resultant. */ vector > ActDisk_Fy; /*!< \brief Value of the actuator disk Y component of the radial and tangential forces per Unit Area resultant. */ vector > ActDisk_Fz; /*!< \brief Value of the actuator disk Z component of the radial and tangential forces per Unit Area resultant. */ + vector > ActDisk_Fa_BEM; /*!< \brief Value of the actuator disk Axial Force per Unit Area. */ + vector > ActDisk_Fx_BEM; /*!< \brief Value of the actuator disk X component of the radial and tangential forces per Unit Area resultant. */ + vector > ActDisk_Fy_BEM; /*!< \brief Value of the actuator disk Y component of the radial and tangential forces per Unit Area resultant. */ + vector > ActDisk_Fz_BEM; /*!< \brief Value of the actuator disk Z component of the radial and tangential forces per Unit Area resultant. */ su2double Total_CL_Prev = 0.0, /*!< \brief Total lift coefficient for all the boundaries (fixed lift mode). */ @@ -217,6 +224,18 @@ class CEulerSolver : public CFVMFlowSolverBase::HybridParallelInitialization(const CConfig& confi * sum the fluxes for each cell and set the diagonal of the system matrix. ---*/ su2double parallelEff = 1.0; + +#ifdef CODI_REVERSE_TYPE + /*--- For the discrete adjoint, the reducer strategy is costly. Prefer coloring, possibly with reduced edge color + * group size. Find the maximum edge color group size that yields an efficient coloring. Also, allow larger numbers + * of colors. ---*/ + const bool relax = config.GetEdgeColoringRelaxDiscAdj(); + const auto& coloring = geometry.GetEdgeColoring(¶llelEff, relax); +#else const auto& coloring = geometry.GetEdgeColoring(¶llelEff); +#endif /*--- The decision to use the strategy is local to each rank. ---*/ ReducerStrategy = parallelEff < COLORING_EFF_THRESH; @@ -324,6 +333,29 @@ void CFVMFlowSolverBase::HybridParallelInitialization(const CConfig& confi << "\n The memory usage of the discrete adjoint solver is higher when using the fallback." #endif << endl; + } else { + if (SU2_MPI::GetRank() == MASTER_NODE) { + cout << "All ranks use edge coloring." << endl; + } + } + + const su2double coloredParallelEff = ReducerStrategy ? 1.0 : parallelEff; + su2double minColoredParallelEff = 1.0; + SU2_MPI::Reduce(&coloredParallelEff, &minColoredParallelEff, 1, MPI_DOUBLE, MPI_MIN, MASTER_NODE, SU2_MPI::GetComm()); + + const unsigned long coloredNumColors = ReducerStrategy ? 0 : coloring.getOuterSize(); + unsigned long maxColoredNumColors = 0; + SU2_MPI::Reduce(&coloredNumColors, &maxColoredNumColors, 1, MPI_UNSIGNED_LONG, MPI_MAX, MASTER_NODE, SU2_MPI::GetComm()); + + const unsigned long coloredEdgeColorGroupSize = ReducerStrategy ? 1 << 30 : geometry.GetEdgeColorGroupSize(); + unsigned long minColoredEdgeColorGroupSize = 1 << 30; + SU2_MPI::Reduce(&coloredEdgeColorGroupSize, &minColoredEdgeColorGroupSize, 1, MPI_UNSIGNED_LONG, MPI_MIN, MASTER_NODE, SU2_MPI::GetComm()); + + if (SU2_MPI::GetRank() == MASTER_NODE && numRanksUsingReducer != SU2_MPI::GetSize()) { + cout << "Among the ranks that use edge coloring,\n" + << " the minimum efficiency is " << minColoredParallelEff << ",\n" + << " the maximum number of colors is " << maxColoredNumColors << ",\n" + << " the minimum edge color group size is " << minColoredEdgeColorGroupSize << "." << endl; } } diff --git a/SU2_CFD/include/solvers/CScalarSolver.inl b/SU2_CFD/include/solvers/CScalarSolver.inl index 5b6415d65b0..343944ebd6c 100644 --- a/SU2_CFD/include/solvers/CScalarSolver.inl +++ b/SU2_CFD/include/solvers/CScalarSolver.inl @@ -46,7 +46,15 @@ CScalarSolver::CScalarSolver(CGeometry* geometry, CConfig* config, #ifdef HAVE_OMP /*--- Get the edge coloring, see notes in CEulerSolver's constructor. ---*/ su2double parallelEff = 1.0; +#ifdef CODI_REVERSE_TYPE + /*--- For the discrete adjoint, the reducer strategy is costly. Prefer coloring, possibly with reduced edge color + * group size. Find the maximum edge color group size that yields an efficient coloring. Also, allow larger numbers + * of colors. ---*/ + const bool relax = config->GetEdgeColoringRelaxDiscAdj(); + const auto& coloring = geometry->GetEdgeColoring(¶llelEff, relax); +#else const auto& coloring = geometry->GetEdgeColoring(¶llelEff); +#endif ReducerStrategy = parallelEff < COLORING_EFF_THRESH; diff --git a/SU2_CFD/include/variables/CVariable.hpp b/SU2_CFD/include/variables/CVariable.hpp index 050be2b7787..453dca7226b 100644 --- a/SU2_CFD/include/variables/CVariable.hpp +++ b/SU2_CFD/include/variables/CVariable.hpp @@ -2170,13 +2170,19 @@ class CVariable { } inline void GetAdjointSolution_time_n(unsigned long iPoint, su2double *adj_sol) const { - for (unsigned long iVar = 0; iVar < Solution_time_n.cols(); iVar++) - adj_sol[iVar] = SU2_TYPE::GetDerivative(Solution_time_n(iPoint,iVar)); + int index = 0; + for (unsigned long iVar = 0; iVar < Solution_time_n.cols(); iVar++) { + AD::SetIndex(index, Solution_time_n(iPoint, iVar)); + adj_sol[iVar] = AD::GetDerivative(index); + } } inline void GetAdjointSolution_time_n1(unsigned long iPoint, su2double *adj_sol) const { - for (unsigned long iVar = 0; iVar < Solution_time_n1.cols(); iVar++) - adj_sol[iVar] = SU2_TYPE::GetDerivative(Solution_time_n1(iPoint,iVar)); + int index = 0; + for (unsigned long iVar = 0; iVar < Solution_time_n1.cols(); iVar++) { + AD::SetIndex(index, Solution_time_n1(iPoint, iVar)); + adj_sol[iVar] = AD::GetDerivative(index); + } } /*! diff --git a/SU2_CFD/src/drivers/CDriver.cpp b/SU2_CFD/src/drivers/CDriver.cpp index c33977ad33f..d8ba985fafa 100644 --- a/SU2_CFD/src/drivers/CDriver.cpp +++ b/SU2_CFD/src/drivers/CDriver.cpp @@ -248,6 +248,8 @@ CDriverBase(confFile, val_nZone, MPICommunicator), StopCalc(false), fsi(false), cout << endl <<"---------------------- Turbomachinery Preprocessing ---------------------" << endl; PreprocessTurbomachinery(config_container, geometry_container, solver_container, interface_container); + } else { + mixingplane = false; } diff --git a/SU2_CFD/src/iteration/CIteration.cpp b/SU2_CFD/src/iteration/CIteration.cpp index 98190ef3972..977e8b713ef 100644 --- a/SU2_CFD/src/iteration/CIteration.cpp +++ b/SU2_CFD/src/iteration/CIteration.cpp @@ -90,9 +90,11 @@ void CIteration::SetGrid_Movement(CGeometry** geometry, CSurfaceMovement* surfac break; } - if (config->GetSurface_Movement(AEROELASTIC) || config->GetSurface_Movement(AEROELASTIC_RIGID_MOTION)) { + if (config->GetSurface_Movement(AEROELASTIC) || config->GetSurface_Movement(AEROELASTIC_RIGID_MOTION) || config->GetSurface_Movement(MOVING_WALL)) { /*--- Apply rigid mesh transformation to entire grid first, if necessary ---*/ + if (IntIter == 0) { + if (Kind_Grid_Movement == AEROELASTIC_RIGID_MOTION) { if (rank == MASTER_NODE) cout << endl << " Performing rigid mesh transformation." << endl; @@ -110,6 +112,11 @@ void CIteration::SetGrid_Movement(CGeometry** geometry, CSurfaceMovement* surfac grid_movement->UpdateMultiGrid(geometry, config); } + if (config->GetSurface_Movement(MOVING_WALL)) { + for (auto iMGlevel = 0u; iMGlevel <= config->GetnMGLevels(); iMGlevel++) { + geometry[iMGlevel]->SetWallVelocity(config, iMGlevel == 0u); + } + } } diff --git a/SU2_CFD/src/output/filewriter/CCGNSFileWriter.cpp b/SU2_CFD/src/output/filewriter/CCGNSFileWriter.cpp index 34f75473b61..a4b89f39551 100644 --- a/SU2_CFD/src/output/filewriter/CCGNSFileWriter.cpp +++ b/SU2_CFD/src/output/filewriter/CCGNSFileWriter.cpp @@ -38,7 +38,6 @@ void CCGNSFileWriter::WriteData(string val_filename) { /*--- We append the pre-defined suffix (extension) to the filename (prefix) ---*/ val_filename.append(fileExt); - /*--- Open the CGNS file for writing. ---*/ InitializeMeshFile(val_filename); @@ -132,15 +131,16 @@ void CCGNSFileWriter::WriteField(int iField, const string& FieldName) { /*--- Coordinate vector is written in blocks, one for each process. ---*/ cgsize_t nodeBegin = 1; auto nodeEnd = static_cast(nLocalPoints); - - if (isCoord) { - int CoordinateNumber; - CallCGNS(cg_coord_partial_write(cgnsFileID, cgnsBase, cgnsZone, dataType, FieldName.c_str(), &nodeBegin, &nodeEnd, - sendBufferField.data(), &CoordinateNumber)); - } else { - int fieldNumber; - CallCGNS(cg_field_partial_write(cgnsFileID, cgnsBase, cgnsZone, cgnsFields, dataType, FieldName.c_str(), &nodeBegin, - &nodeEnd, sendBufferField.data(), &fieldNumber)); + if (nLocalPoints > 0) { + if (isCoord) { + int CoordinateNumber; + CallCGNS(cg_coord_partial_write(cgnsFileID, cgnsBase, cgnsZone, dataType, FieldName.c_str(), &nodeBegin, &nodeEnd, + sendBufferField.data(), &CoordinateNumber)); + } else { + int fieldNumber; + CallCGNS(cg_field_partial_write(cgnsFileID, cgnsBase, cgnsZone, cgnsFields, dataType, FieldName.c_str(), &nodeBegin, + &nodeEnd, sendBufferField.data(), &fieldNumber)); + } } for (int i = 0; i < size; ++i) { diff --git a/SU2_CFD/src/python_wrapper_structure.cpp b/SU2_CFD/src/python_wrapper_structure.cpp index 8952d4b83eb..5ac88c4cb7c 100644 --- a/SU2_CFD/src/python_wrapper_structure.cpp +++ b/SU2_CFD/src/python_wrapper_structure.cpp @@ -783,3 +783,15 @@ void CDriver::SetRotationRate(passivedouble rot_x, passivedouble rot_y, passived main_config->SetRotation_Rate(1, rot_y); main_config->SetRotation_Rate(2, rot_z); } + +void CDriver::SetMarkerRotationRate(unsigned short iMarker, passivedouble rot_x, passivedouble rot_y, passivedouble rot_z) { + config_container[selected_zone]->SetMarkerRotationRate(iMarker, 0, rot_x); + config_container[selected_zone]->SetMarkerRotationRate(iMarker, 1, rot_y); + config_container[selected_zone]->SetMarkerRotationRate(iMarker, 2, rot_z); +} + +void CDriver::SetMarkerTranslationRate(unsigned short iMarker, passivedouble vel_x, passivedouble vel_y, passivedouble vel_z) { + config_container[selected_zone]->SetMarkerTranslationRate(iMarker, 0, vel_x); + config_container[selected_zone]->SetMarkerTranslationRate(iMarker, 1, vel_y); + config_container[selected_zone]->SetMarkerTranslationRate(iMarker, 2, vel_z); +} diff --git a/SU2_CFD/src/solvers/CDiscAdjFEASolver.cpp b/SU2_CFD/src/solvers/CDiscAdjFEASolver.cpp index a297039ea3a..baf00a826a2 100644 --- a/SU2_CFD/src/solvers/CDiscAdjFEASolver.cpp +++ b/SU2_CFD/src/solvers/CDiscAdjFEASolver.cpp @@ -232,22 +232,30 @@ void CDiscAdjFEASolver::ExtractAdjoint_Solution(CGeometry *geometry, CConfig *co /*--- Extract and store the adjoint solution ---*/ + AD::BeginUseAdjoints(); + for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { su2double Solution[MAXNVAR] = {0.0}; direct_solver->GetNodes()->GetAdjointSolution(iPoint,Solution); nodes->SetSolution(iPoint,Solution); } + AD::EndUseAdjoints(); + if (CrossTerm) return; /*--- Extract and store the adjoint solution at time n (including accel. and velocity) ---*/ if (config->GetTime_Domain()) { + AD::BeginUseAdjoints(); + for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { su2double Solution[MAXNVAR] = {0.0}; direct_solver->GetNodes()->GetAdjointSolution_time_n(iPoint,Solution); nodes->Set_Solution_time_n(iPoint,Solution); } + + AD::EndUseAdjoints(); } /*--- Set the residuals ---*/ @@ -358,6 +366,8 @@ void CDiscAdjFEASolver::SetSensitivity(CGeometry *geometry, CConfig *config, CSo /*--- Extract the geometric sensitivities ---*/ + AD::BeginUseAdjoints(); + for (unsigned long iPoint = 0; iPoint < nPoint; iPoint++) { auto Coord = geometry->nodes->GetCoord(iPoint); @@ -375,6 +385,8 @@ void CDiscAdjFEASolver::SetSensitivity(CGeometry *geometry, CConfig *config, CSo } } + AD::EndUseAdjoints(); + } void CDiscAdjFEASolver::ReadDV(const CConfig *config) { diff --git a/SU2_CFD/src/solvers/CDiscAdjSolver.cpp b/SU2_CFD/src/solvers/CDiscAdjSolver.cpp index 869f7c295ac..1c96cfb3ec7 100644 --- a/SU2_CFD/src/solvers/CDiscAdjSolver.cpp +++ b/SU2_CFD/src/solvers/CDiscAdjSolver.cpp @@ -321,6 +321,8 @@ void CDiscAdjSolver::ExtractAdjoint_Solution(CGeometry *geometry, CConfig *confi if (!config->GetMultizone_Problem()) nodes->Set_OldSolution(); + AD::BeginUseAdjoints(); + SU2_OMP_FOR_STAT(omp_chunk_size) for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { @@ -343,6 +345,8 @@ void CDiscAdjSolver::ExtractAdjoint_Solution(CGeometry *geometry, CConfig *confi } END_SU2_OMP_FOR + AD::EndUseAdjoints(); + direct_solver->ExtractAdjoint_SolutionExtra(nodes->GetSolutionExtra(), config); /*--- Residuals and time_n terms are not needed when evaluating multizone cross terms. ---*/ @@ -359,6 +363,8 @@ void CDiscAdjSolver::ExtractAdjoint_Solution(CGeometry *geometry, CConfig *confi /*--- Extract and store the adjoint of the primal solution at time n ---*/ if (time_n_needed) { + AD::BeginUseAdjoints(); + SU2_OMP_FOR_STAT(omp_chunk_size) for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { su2double Solution[MAXNVAR] = {0.0}; @@ -366,10 +372,14 @@ void CDiscAdjSolver::ExtractAdjoint_Solution(CGeometry *geometry, CConfig *confi nodes->Set_Solution_time_n(iPoint,Solution); } END_SU2_OMP_FOR + + AD::EndUseAdjoints(); } /*--- Extract and store the adjoint of the primal solution at time n-1 ---*/ if (time_n1_needed) { + AD::BeginUseAdjoints(); + SU2_OMP_FOR_STAT(omp_chunk_size) for (auto iPoint = 0ul; iPoint < nPoint; iPoint++) { su2double Solution[MAXNVAR] = {0.0}; @@ -377,6 +387,8 @@ void CDiscAdjSolver::ExtractAdjoint_Solution(CGeometry *geometry, CConfig *confi nodes->Set_Solution_time_n1(iPoint,Solution); } END_SU2_OMP_FOR + + AD::EndUseAdjoints(); } } @@ -481,6 +493,8 @@ void CDiscAdjSolver::SetAdjoint_Output(CGeometry *geometry, CConfig *config) { void CDiscAdjSolver::SetSensitivity(CGeometry *geometry, CConfig *config, CSolver*) { + AD::BeginUseAdjoints(); + SU2_OMP_PARALLEL { const bool time_stepping = (config->GetTime_Marching() != TIME_MARCHING::STEADY); @@ -514,6 +528,8 @@ void CDiscAdjSolver::SetSensitivity(CGeometry *geometry, CConfig *config, CSolve } END_SU2_OMP_PARALLEL + + AD::EndUseAdjoints(); } void CDiscAdjSolver::SetSurface_Sensitivity(CGeometry *geometry, CConfig *config) { diff --git a/SU2_CFD/src/solvers/CEulerSolver.cpp b/SU2_CFD/src/solvers/CEulerSolver.cpp index e665fbe06e1..64d4a42d50e 100644 --- a/SU2_CFD/src/solvers/CEulerSolver.cpp +++ b/SU2_CFD/src/solvers/CEulerSolver.cpp @@ -194,10 +194,23 @@ CEulerSolver::CEulerSolver(CGeometry *geometry, CConfig *config, AllocVectorOfVectors(nVertex, ActDisk_Fy); AllocVectorOfVectors(nVertex, ActDisk_Fz); + /*--- Actuator Disk BEM Fa, Fx, Fy and Fz allocations ---*/ + + AllocVectorOfVectors(nVertex, ActDisk_Fa_BEM); + AllocVectorOfVectors(nVertex, ActDisk_Fx_BEM); + AllocVectorOfVectors(nVertex, ActDisk_Fy_BEM); + AllocVectorOfVectors(nVertex, ActDisk_Fz_BEM); + /*--- Store the value of the Delta P at the Actuator Disk ---*/ AllocVectorOfVectors(nVertex, ActDisk_DeltaP); + /*--- Store the value of DeltaP_r, Thrust_r and Torque_r at the Actuator Disk for BEM ---*/ + + AllocVectorOfVectors(nVertex, ActDisk_DeltaP_r); + AllocVectorOfVectors(nVertex, ActDisk_Thrust_r); + AllocVectorOfVectors(nVertex, ActDisk_Torque_r); + /*--- Store the value of the Delta T at the Actuator Disk ---*/ AllocVectorOfVectors(nVertex, ActDisk_DeltaT); @@ -853,7 +866,7 @@ void CEulerSolver::SetNondimensionalization(CConfig *config, unsigned short iMes auxFluidModel = new CPengRobinson(Gamma, config->GetGas_Constant(), config->GetPressure_Critical(), config->GetTemperature_Critical(), config->GetAcentric_Factor()); break; - + case DATADRIVEN_FLUID: auxFluidModel = new CDataDrivenFluid(config); @@ -2514,6 +2527,7 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns Velocity2, Density, Area, SoundSpeed, TotalPressure, Vel_Infty2, RamDrag, TotalTemperature, VelocityJet, Vel_Infty, MaxPressure, MinPressure, MFR, InfVel2; + su2double DeltaPressure = 0.0, DeltaThrust = 0.0, DeltaTorque = 0.0; unsigned short iMarker_Inlet, iMarker_Outlet, nMarker_Inlet, nMarker_Outlet; string Inlet_TagBound, Outlet_TagBound; su2double DeltaPress = 0.0, DeltaTemp = 0.0, TotalPressRatio = 0.0, TotalTempRatio = 0.0, StaticPressRatio = 0.0, StaticTempRatio = 0.0, @@ -2566,6 +2580,10 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns auto *Outlet_Force = new su2double [config->GetnMarker_All()](); auto *Outlet_Power = new su2double [config->GetnMarker_All()](); + auto *Outlet_DeltaP = new su2double [config->GetnMarker_All()](); + auto *Outlet_Thrust = new su2double [config->GetnMarker_All()](); + auto *Outlet_Torque = new su2double [config->GetnMarker_All()](); + /*--- Comute MassFlow, average temp, press, etc. ---*/ for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { @@ -2674,6 +2692,9 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns TotalPressure = Pressure * pow( 1.0 + Mach * Mach * 0.5 * (Gamma - 1.0), Gamma / (Gamma - 1.0)); TotalTemperature = Temperature * (1.0 + Mach * Mach * 0.5 * (Gamma - 1.0)); VelocityJet = sqrt(Velocity2) ; + DeltaPressure = ActDisk_DeltaP_r[iMarker][iVertex]; + DeltaThrust = ActDisk_Thrust_r[iMarker][iVertex]; + DeltaTorque = ActDisk_Torque_r[iMarker][iVertex]; GrossThrust = MassFlow * VelocityJet; @@ -2685,6 +2706,9 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns Outlet_Area[iMarker] += Area; Outlet_GrossThrust[iMarker] += GrossThrust; Outlet_Power[iMarker] += MassFlow*Cp*TotalTemperature; + Outlet_DeltaP[iMarker] += DeltaPressure * Area; + Outlet_Thrust[iMarker] += DeltaThrust * Area; + Outlet_Torque[iMarker] += DeltaTorque * Area; su2double Outlet_ForceX = -(Pressure - Pressure_Inf)*Vector[0] -MassFlow*Velocity[0]; su2double Outlet_ForceY = -(Pressure - Pressure_Inf)*Vector[1] -MassFlow*Velocity[1]; @@ -2746,6 +2770,9 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns auto *Outlet_Force_Local = new su2double [nMarker_Outlet](); auto *Outlet_Power_Local = new su2double [nMarker_Outlet](); auto *Outlet_Area_Local = new su2double [nMarker_Outlet](); + auto *Outlet_DeltaP_Local = new su2double [nMarker_Outlet](); + auto *Outlet_Thrust_Local = new su2double [nMarker_Outlet](); + auto *Outlet_Torque_Local = new su2double [nMarker_Outlet](); auto *Outlet_MassFlow_Total = new su2double [nMarker_Outlet](); auto *Outlet_Pressure_Total = new su2double [nMarker_Outlet](); @@ -2756,6 +2783,9 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns auto *Outlet_Force_Total = new su2double [nMarker_Outlet](); auto *Outlet_Power_Total = new su2double [nMarker_Outlet](); auto *Outlet_Area_Total = new su2double [nMarker_Outlet](); + auto *Outlet_DeltaP_Total = new su2double [nMarker_Outlet](); + auto *Outlet_Thrust_Total = new su2double [nMarker_Outlet](); + auto *Outlet_Torque_Total = new su2double [nMarker_Outlet](); /*--- Copy the values to the local array for MPI ---*/ @@ -2805,6 +2835,9 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns Outlet_Force_Local[iMarker_Outlet] += Outlet_Force[iMarker]; Outlet_Power_Local[iMarker_Outlet] += Outlet_Power[iMarker]; Outlet_Area_Local[iMarker_Outlet] += Outlet_Area[iMarker]; + Outlet_DeltaP_Local[iMarker_Outlet] += Outlet_DeltaP[iMarker]; + Outlet_Thrust_Local[iMarker_Outlet] += Outlet_Thrust[iMarker]; + Outlet_Torque_Local[iMarker_Outlet] += Outlet_Torque[iMarker]; } } @@ -2855,6 +2888,9 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns SU2_MPI::Allreduce(Outlet_Force_Local, Outlet_Force_Total, nMarker_Outlet, MPI_DOUBLE, MPI_SUM, SU2_MPI::GetComm()); SU2_MPI::Allreduce(Outlet_Power_Local, Outlet_Power_Total, nMarker_Outlet, MPI_DOUBLE, MPI_SUM, SU2_MPI::GetComm()); SU2_MPI::Allreduce(Outlet_Area_Local, Outlet_Area_Total, nMarker_Outlet, MPI_DOUBLE, MPI_SUM, SU2_MPI::GetComm()); + SU2_MPI::Allreduce(Outlet_DeltaP_Local, Outlet_DeltaP_Total, nMarker_Outlet, MPI_DOUBLE, MPI_SUM, SU2_MPI::GetComm()); + SU2_MPI::Allreduce(Outlet_Thrust_Local, Outlet_Thrust_Total, nMarker_Outlet, MPI_DOUBLE, MPI_SUM, SU2_MPI::GetComm()); + SU2_MPI::Allreduce(Outlet_Torque_Local, Outlet_Torque_Total, nMarker_Outlet, MPI_DOUBLE, MPI_SUM, SU2_MPI::GetComm()); /*--- Compute the value of the average surface temperature and pressure and set the value in the config structure for future use ---*/ @@ -2945,6 +2981,8 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns config->SetActDiskOutlet_GrossThrust(iMarker_Outlet, Outlet_GrossThrust_Total[iMarker_Outlet]); config->SetActDiskOutlet_Force(iMarker_Outlet, Outlet_Force_Total[iMarker_Outlet]); config->SetActDiskOutlet_Power(iMarker_Outlet, Outlet_Power_Total[iMarker_Outlet]); + config->SetActDiskOutlet_Thrust_BEM(iMarker_Outlet, Outlet_Thrust_Total[iMarker_Outlet]); + config->SetActDiskOutlet_Torque_BEM(iMarker_Outlet, Outlet_Torque_Total[iMarker_Outlet]); } } @@ -3300,6 +3338,11 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns cout << setprecision(1) << Power * Ref * config->GetVelocity_Ref() / 550.0 << "." << endl; } + if (config->GetKind_ActDisk() == BLADE_ELEMENT) { + cout << setprecision(5); + cout << "Thrust_BEM (N): " << config->GetActDiskOutlet_Thrust_BEM(Outlet_TagBound) << ". "; + cout << "Torque_BEM (N-m): " << config->GetActDiskOutlet_Torque_BEM(Outlet_TagBound) << "." << endl; + } } } @@ -3319,6 +3362,9 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns delete [] Outlet_GrossThrust_Local; delete [] Outlet_Force_Local; delete [] Outlet_Power_Local; + delete [] Outlet_DeltaP_Local; + delete [] Outlet_Thrust_Local; + delete [] Outlet_Torque_Local; delete [] Outlet_MassFlow_Total; delete [] Outlet_Temperature_Total; @@ -3329,6 +3375,9 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns delete [] Outlet_GrossThrust_Total; delete [] Outlet_Force_Total; delete [] Outlet_Power_Total; + delete [] Outlet_DeltaP_Total; + delete [] Outlet_Thrust_Total; + delete [] Outlet_Torque_Total; delete [] Inlet_MassFlow_Local; delete [] Inlet_ReverseMassFlow_Local; @@ -3390,6 +3439,9 @@ void CEulerSolver::GetPower_Properties(CGeometry *geometry, CConfig *config, uns delete [] Outlet_GrossThrust; delete [] Outlet_Force; delete [] Outlet_Power; + delete [] Outlet_DeltaP; + delete [] Outlet_Thrust; + delete [] Outlet_Torque; } @@ -3432,6 +3484,11 @@ void CEulerSolver::SetActDisk_BCThrust(CGeometry *geometry, CSolver **solver_con Factor = (0.5*RefDensity*RefArea*RefVel2); Ref = config->GetDensity_Ref() * config->GetVelocity_Ref() * config->GetVelocity_Ref() * 1.0 * 1.0; + /*--- Blade element distribution is in input file. ---*/ + if (Kind_ActDisk == BLADE_ELEMENT) { + SetActDisk_BEM_VLAD(geometry, solver_container, config, iMesh, Output); + } + /*--- Variable load distribution is in input file. ---*/ if (Kind_ActDisk == VARIABLE_LOAD) { if(InnerIter == 0) { @@ -4037,6 +4094,432 @@ void CEulerSolver::ReadActDisk_InputFile(CGeometry *geometry, CSolver **solver_c } } +void CEulerSolver::SetActDisk_BEM_VLAD(CGeometry *geometry, CSolver **solver_container, + CConfig *config, unsigned short iMesh, bool Output) { + + /*! + * \function SetActDisk_BEM_VLAD + * \brief Actuator disk model with Blade Element Method (BEM) + * \author: Chandukrishna Y., T. N. Venkatesh and Josy Pullockara + * Institution: Computational and Theoretical Fluid Dynamics (CTFD), + * CSIR - National Aerospace Laboratories, Bangalore + * Academy of Scientific and Innovative Research, Ghaziabad + * \version 8.0.0 "Harrier" + * First release date : September 26 2023 + * modified on: + * + * Section properties of the propeller given in an input file. + * Cl, Cd of propeller sections need to be generated earlier and saved in this file + * Actuator disk data initialized in function SetActDisk_BCThrust. + * Propeller load calculated with Blade Element Method + * Interpolated load at each point on the actuator disk is set in SetActDisk_BEM_VLAD function + * Rest calculations follows the Variable Load (BC_ActDisk_VariableLoad) approach + * + */ + + /*--- InputFile reading ---*/ + static int ADBem_NBlade = 0, ADBem_NSection = 0, ADBem_NAlpha = 0; + static su2double ADBem_Diameter = 0.0, ADBem_HubRadius = 0.0, ADBem_Angle75R = 0.0; + static std::vector i_v, radius_v, chord_v, angle75r_v; + static std::vector > alpha_m, cl_m, cd_m; + + static su2double ADBem_Omega = 0.0; + static su2double ADBem_CG[MAXNDIM] = {0.0, 0.0, 0.0}; + static su2double ADBem_Axis[MAXNDIM] = {0.0}, ADBem_J = 0.0; + static unsigned short ADBem_Frequency = 0; + + /*--- BEM VLAD ---*/ + const int BEM_MAX_ITER = 20; + + unsigned long InnerIter = config->GetInnerIter(); + su2double Dens_FreeStream = config->GetDensity_FreeStream(); + const su2double* Vel_FreeStream = config->GetVelocity_FreeStream(); + + /*--- Input file provides force coefficients distributions along disk radius. + Initialization necessary only at initial iteration (InnerIter == 0) + when the tables (radius_v, chord_v, ...) are empty. ---*/ + if (radius_v.empty()) { + /*--- Get the RPM, CG, Axis and Frequency from config. ---*/ + for (unsigned short iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { + + if ((config->GetMarker_All_KindBC(iMarker) == ACTDISK_INLET) || + (config->GetMarker_All_KindBC(iMarker) == ACTDISK_OUTLET)) { + + const string Marker_Tag = config->GetMarker_All_TagBound(iMarker); + ADBem_Omega = config->GetActDisk_Omega(Marker_Tag, 0); + for (unsigned short iDim = 0; iDim < nDim; iDim++) { + ADBem_CG[iDim] = config->GetActDiskBem_CG(iDim, Marker_Tag, 0); + ADBem_Axis[iDim] = config->GetActDiskBem_Axis(iDim, Marker_Tag, 0); + } + } + } + ADBem_Frequency = config->GetActDiskBem_Frequency(); + + /*--- Get the file name that contains the propeller data. ---*/ + string ActDiskBem_filename = config->GetBEM_prop_filename(); + ifstream ActDiskBem_file; + + /*--- Open the file that contains the propeller data. ---*/ + ActDiskBem_file.open(ActDiskBem_filename.data(), ios::in); + + /*--- Error message if the propeller data input file fails to open. ---*/ + if (ActDiskBem_file.fail()) SU2_MPI::Error("Unable to open Actuator Disk BEM Input File", CURRENT_FUNCTION); + + string text_line_appo; + + getline(ActDiskBem_file, text_line_appo); + /*--- Read and assign the value of the number of propeller blades. ---*/ + getline(ActDiskBem_file, text_line_appo); + istringstream NBlade_value(text_line_appo); + NBlade_value >> ADBem_NBlade; + + /*--- Read and assign the value of the propeller diameter. ---*/ + getline(ActDiskBem_file, text_line_appo); + istringstream Diameter_value(text_line_appo); + Diameter_value >> ADBem_Diameter; + + /*--- Read and assign the value of the propeller hub radius. ---*/ + getline(ActDiskBem_file, text_line_appo); + istringstream HubR_value(text_line_appo); + HubR_value >> ADBem_HubRadius; + + /*--- Read and assign the value of the blade angle at 75% of R. ---*/ + getline(ActDiskBem_file, text_line_appo); + istringstream Angle75R_value(text_line_appo); + Angle75R_value >> ADBem_Angle75R; + + getline(ActDiskBem_file, text_line_appo); + /*--- Read and assign the value of the number of radial propeller blade sections and alphas for each. ---*/ + getline(ActDiskBem_file, text_line_appo); + istringstream NSection_NAlpha_value(text_line_appo); + NSection_NAlpha_value >> ADBem_NSection >> ADBem_NAlpha; + + /*--- Assign the vector dimensions. ---*/ + i_v.resize(ADBem_NSection, 0.0); + radius_v.resize(ADBem_NSection, 0.0); + chord_v.resize(ADBem_NSection, 0.0); + angle75r_v.resize(ADBem_NSection, 0.0); + + getline(ActDiskBem_file, text_line_appo); + /*--- Read and assign the values of the propeller blade section's id, radius, chord, angle75R. ---*/ + for (int iSection = 0; iSection < ADBem_NSection; iSection++) { + getline(ActDiskBem_file, text_line_appo); + istringstream sectionStream(text_line_appo); + sectionStream >> i_v[iSection] >> radius_v[iSection] >> chord_v[iSection] >> angle75r_v[iSection]; + } + + /*--- Assign the matrix dimensions. ---*/ + alpha_m.resize(ADBem_NAlpha, std::vector(ADBem_NSection, 0.0)); + cl_m.resize(ADBem_NAlpha, std::vector(ADBem_NSection, 0.0)); + cd_m.resize(ADBem_NAlpha, std::vector(ADBem_NSection, 0.0)); + + /*--- Read and assign the values for each of the propeller blade section's alpha, cl, cd. ---*/ + for (int iSection = 0; iSection < ADBem_NSection; iSection++) { + getline(ActDiskBem_file, text_line_appo); + for (int iAlpha = 0; iAlpha < ADBem_NAlpha; iAlpha++) { + getline(ActDiskBem_file, text_line_appo); + istringstream alphaStream(text_line_appo); + alphaStream >> alpha_m[iAlpha][iSection] >> cl_m[iAlpha][iSection] >> cd_m[iAlpha][iSection]; + } + } + } + + /*--- Update the propeller load according to the modified flow field after every ADBem_Frequency inner iterations. ---*/ + if (InnerIter % ADBem_Frequency != 0) return; + const su2double dia = ADBem_Diameter; + const su2double r_tip = 0.5 * dia; + su2double loc_Torque = 0.0; + su2double loc_thrust = 0.0; + su2double tot_area = 0.0, tot_tq = 0.0; + + su2double Normal[MAXNDIM]; + for (unsigned short iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { + if ((config->GetMarker_All_KindBC(iMarker) == ACTDISK_INLET) || + (config->GetMarker_All_KindBC(iMarker) == ACTDISK_OUTLET)) { + for (unsigned long iVertex = 0; iVertex < geometry->nVertex[iMarker]; iVertex++) { + const unsigned long iPoint = geometry->vertex[iMarker][iVertex]->GetNode(); + + /*--- Read Swirl params. ---*/ + const su2double Omega_RPM = ADBem_Omega; + const su2double omega_ref = config->GetOmega_Ref(); + const su2double Lref = config->GetLength_Ref(); + const su2double Omega_sw = Omega_RPM * (PI_NUMBER / 30.0) / (omega_ref); // Swirl rate + + /*--- Center of the rotor ---*/ + su2double Origin[3] = {0.0, 0.0, 0.0}; + for (unsigned short iDim = 0; iDim < nDim; iDim++) { + Origin[iDim] = ADBem_CG[iDim] / Lref; + } + + /*--- Compute the distance to the center of the rotor ---*/ + geometry->vertex[iMarker][iVertex]->GetNormal(Normal); + for (unsigned short iDim = 0; iDim < nDim; iDim++) { + Normal[iDim] = -Normal[iDim]; + } + + /*--- Get propeller axis from config file. ---*/ + for (unsigned short iDim = 0; iDim < nDim; iDim++){ + ActDisk_Axis(iMarker, iDim) = ADBem_Axis[iDim]; + } + su2double Area = 0.0; + for (unsigned short iDim = 0; iDim < nDim; iDim++) { + Area += Normal[iDim] * Normal[iDim]; + } + Area = sqrt(Area); + + su2double UnitNormal[3] = {0.0, 0.0, 0.0}; + for (unsigned short iDim = 0; iDim < nDim; iDim++) { + UnitNormal[iDim] = Normal[iDim] / Area; + } + + const su2double* Coord = geometry->nodes->GetCoord(iPoint); + + su2double radius = 0.0; + su2double radius_[3] = {0.0, 0.0, 0.0}; + for (unsigned short iDim = 0; iDim < nDim; iDim++) { + radius += (Coord[iDim] - Origin[iDim]) * (Coord[iDim] - Origin[iDim]); + radius_[iDim] = (Coord[iDim] - Origin[iDim]); + } + radius = sqrt(radius); + + /*--- Current solution at this boundary node and jumps values ---*/ + const su2double* V_domain = nodes->GetPrimitive(iPoint); + + if (abs(Omega_sw) > 1.0e-1) { + su2double Vn = 0.0; + for (unsigned short iDim = 0; iDim < nDim; iDim++) { + Vn += V_domain[iDim + 1] * UnitNormal[iDim]; + } + + const su2double RPM = abs(Omega_RPM); + const su2double rps = RPM / 60.0; + ADBem_J = Vel_FreeStream[0] / (rps * dia); + const su2double rho = V_domain[nDim + 2]; + const su2double T = V_domain[0]; + const su2double blade_angle = config->GetBEM_blade_angle(); + const su2double V = fabs(Vn); + + /*--- BEM model without parameter 'a' (ref?) ---*/ + su2double Torque = 0.0, dp_av = 0.0, dp_at_r = 0.0; + { + std::vector DtDr(ADBem_NSection, 0.0); + + int s_prop_nblades = ADBem_NBlade; + int sprop_sec_nalf = ADBem_NAlpha; + int sprop_sec_nrad = ADBem_NSection; + std::vector& sprop_sec_r1 = radius_v; + std::vector& sprop_sec_chord = chord_v; + std::vector& sprop_sec_setangle = angle75r_v; + std::vector >& sprop_sec_alf = alpha_m; + std::vector >& sprop_sec_cl_arr = cl_m; + std::vector >& sprop_sec_cd_arr = cd_m; + + su2double rad_p = radius; + + int j, isec, converged, n_iter; + int NR = sprop_sec_nrad; + su2double r_hub, alpha_corr, cl_corr_fac; + su2double base_mach, s_mach, b_num, thrust, torque; + su2double r_dash, t_loss, c_phi, rad, phi, alpha, radtodeg; + su2double bnew, V0, V2, cl = 0.0, cd = 0.0, Vlocal, DqDr = 0.0, tem1, tem2, q; + std::vector delta_r(ADBem_NSection, 0.0); + std::vector b(ADBem_NSection, 0.0); + static std::vector Dtorq(ADBem_NSection, 0.0); + + su2double n, omega, a0, den; + su2double ang_offset = 0.0; + + radtodeg = 180.0 / PI_NUMBER; + r_hub = ADBem_HubRadius; + ang_offset = blade_angle - ADBem_Angle75R; + + alpha_corr = 0.0; + base_mach = 0.22; + b_num = sqrt(1.0 - base_mach * base_mach); + a0 = sqrt(1.4 * 287 * T); + /*--- Change pitch by ang_offset and calculate delta_r for integration by trapezoidal rule. ---*/ + n = RPM / 60.0; + omega = n * 2.0 * PI_NUMBER; + + for (j = 0; j < NR; j++) { + if (j < 1) { + delta_r[j] = sprop_sec_r1[j + 1] - r_hub; + } else { + if (j < NR - 1) { + delta_r[j] = sprop_sec_r1[j + 1] - sprop_sec_r1[j - 1]; + } else { + delta_r[j] = r_tip - sprop_sec_r1[j - 1]; + } + } + delta_r[j] *= 0.5; + } + + thrust = 0.0; + torque = 0.0; + + for (j = 0; j < NR; j++) { + b[j] = 0.01; + converged = 0; + n_iter = 1; + while (converged == 0) { + V2 = omega * sprop_sec_r1[j] * (1 - b[j]); + V0 = V; + + phi = atan2(V0, V2); + + alpha = sprop_sec_setangle[j] + ang_offset - radtodeg * phi + alpha_corr; + rad = sprop_sec_r1[j]; + + /*--- get cl, cd from lookup table. ---*/ + isec = j + 1; + { + int i, salf = 0; + su2double fact; + + /*--- interpolating values of cl and cd for given alpha. ---*/ + if (alpha >= sprop_sec_alf[salf][isec - 1] && + alpha <= sprop_sec_alf[sprop_sec_nalf - 1][isec - 1]) { + for (i = 0; i < sprop_sec_nalf - 1; i++) { + if (alpha >= sprop_sec_alf[i][isec - 1] && alpha <= sprop_sec_alf[i + 1][isec - 1]) { + fact = (alpha - sprop_sec_alf[i][isec - 1]) + / (sprop_sec_alf[i + 1][isec - 1] - sprop_sec_alf[i][isec - 1]); + cl = sprop_sec_cl_arr[i][isec - 1] + + fact * (sprop_sec_cl_arr[i + 1][isec - 1] - sprop_sec_cl_arr[i][isec - 1]); + cd = sprop_sec_cd_arr[i][isec - 1] + + fact * (sprop_sec_cd_arr[i + 1][isec - 1] - sprop_sec_cd_arr[i][isec - 1]); + } + } + } else { + if (alpha < sprop_sec_alf[salf][isec - 1]) { + cl = sprop_sec_cl_arr[0][isec - 1]; + cd = sprop_sec_cd_arr[0][isec - 1]; + } + if (alpha > sprop_sec_alf[sprop_sec_nalf - 1][isec - 1]) { + cl = sprop_sec_cl_arr[sprop_sec_nalf - 1][isec - 1]; + cd = sprop_sec_cd_arr[sprop_sec_nalf - 1][isec - 1]; + } + } + } + + Vlocal = sqrt(V0 * V0 + V2 * V2); + q = 0.5 * rho * Vlocal * Vlocal; + s_mach = Vlocal / a0; + cl_corr_fac = 1.0; + if (s_mach > base_mach) { + den = 1.0 - s_mach * s_mach; + if (den > 0.0) cl_corr_fac = b_num / sqrt(den); + } + cl *= cl_corr_fac; + + /*--- tip loss factor. ---*/ + r_dash = rad / r_tip + 1.0e-5; + c_phi = cos(phi); + t_loss = 1.0; + if (r_dash > 0.90) { + t_loss = (2.0 / PI_NUMBER) * acos(exp(-(1.0 * s_prop_nblades * (1 - r_dash) / (r_dash * c_phi)))); + } + + DtDr[j] = q * s_prop_nblades * sprop_sec_chord[j] * (cl * cos(phi) - cd * sin(phi)); + DqDr = q * s_prop_nblades * sprop_sec_chord[j] * rad * (cd * cos(phi) + cl * sin(phi)); + + DtDr[j] *= t_loss; + DqDr *= t_loss; + + tem2 = DqDr / (4.0 * PI_NUMBER * rad * rad * rad * rho * V * omega); + bnew = 0.6 * b[j] + 0.4 * tem2; + if (bnew > 0.9) bnew = 0.9; + if (fabs(bnew - b[j]) < 1.0e-5) { + converged = 1; + } + if (bnew < 0.1) { + b[j] = bnew; + } + n_iter++; + if (n_iter > BEM_MAX_ITER) { + converged = 1; + } + } + thrust = thrust + DtDr[j] * delta_r[j]; + torque = torque + DqDr * delta_r[j]; + Dtorq[j] = DqDr; + } + + tem1 = rho * n * n * dia * dia * dia * dia; + tem2 = tem1 * dia; + + Torque = 2.0 * PI_NUMBER * torque; + dp_av = 2.0 * PI_NUMBER * torque; + + for (j = 0; j < NR; j++) { + DtDr[j] /= (2.0 * PI_NUMBER * sprop_sec_r1[j]); + Dtorq[j] = Dtorq[j]; + } + + if (rad_p < sprop_sec_r1[0]) { + tem2 = sprop_sec_r1[0] - r_hub; + tem1 = (rad_p - r_hub) / tem2; + tem2 = 1.0 - tem1; + dp_at_r = DtDr[0] * tem1; + Torque = Dtorq[0] * tem1; + } else { + if (rad_p > r_tip) { + dp_at_r = 0.0; + Torque = 0.0; + } else { + if (rad_p > sprop_sec_r1[NR - 1]) { + tem2 = r_tip - sprop_sec_r1[NR - 1]; + tem1 = (rad_p - sprop_sec_r1[NR - 1]) / tem2; + tem2 = 1.0 - tem1; + dp_at_r = DtDr[NR - 1] * tem2; + Torque = Dtorq[NR - 1] * tem2; + } else { + for (j = 0; j < NR - 1; j++) { + if ((sprop_sec_r1[j] < rad_p) && (sprop_sec_r1[j + 1] >= rad_p)) { + tem2 = sprop_sec_r1[j + 1] - sprop_sec_r1[j]; + tem1 = (rad_p - sprop_sec_r1[j]) / tem2; + tem2 = 1.0 - tem1; + dp_at_r = DtDr[j] * tem2 + DtDr[j + 1] * tem1; + Torque = Dtorq[j] * tem2 + Dtorq[j + 1] * tem1; + } + } + } + } + } + } + + tot_area += Area; + loc_Torque += Torque * Area; + tot_tq += dp_av; + loc_thrust += dp_at_r * Area; + const su2double Target_Press_Jump = dp_at_r; + + ActDisk_DeltaP_r[iMarker][iVertex] = Target_Press_Jump; + ActDisk_Thrust_r[iMarker][iVertex] = dp_at_r; + ActDisk_Torque_r[iMarker][iVertex] = Torque / (2 * PI_NUMBER * radius); + /*--- Non-dimensionalize the elemental load. ---*/ + const su2double dCp_v = Torque * ((Omega_sw * r_tip) / (rho * rps * rps * rps * pow(dia, 5))); + /*--- Force radial load to 0 as there is no information of radial load from BEM. ---*/ + const su2double dCr_v = 0.0; + const su2double rad_v = radius / r_tip; + const su2double Fa = dp_at_r; + const su2double Ft = (dCp_v * (2 * Dens_FreeStream * pow(Vel_FreeStream[0], 2)) / + ((ADBem_J * PI_NUMBER * rad_v) * (ADBem_J * PI_NUMBER * rad_v))) / + config->GetPressure_Ref(); + const su2double Fr = (dCr_v * (2 * Dens_FreeStream * pow(Vel_FreeStream[0], 2)) / + (pow(ADBem_J, 2) * PI_NUMBER * rad_v)) / config->GetPressure_Ref(); + const su2double Fx = (Ft + Fr) * (radius_[0] / (radius)); + const su2double Fy = (Ft + Fr) * (radius_[2] / (radius)); + const su2double Fz = -(Ft + Fr) * (radius_[1] / (radius)); + ActDisk_Fa_BEM[iMarker][iVertex] = Fa; + ActDisk_Fx_BEM[iMarker][iVertex] = Fx; + ActDisk_Fy_BEM[iMarker][iVertex] = Fy; + ActDisk_Fz_BEM[iMarker][iVertex] = Fz; + } + } + } + } +} + void CEulerSolver::SetFarfield_AoA(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh, bool Output) { @@ -5619,7 +6102,7 @@ void CEulerSolver::PreprocessBC_Giles(CGeometry *geometry, CConfig *config, CNum { Velocity_i[iDim] = nodes->GetVelocity(iPoint,iDim); } - + ComputeTurboVelocity(Velocity_i, turboNormal, turboVelocity, marker_flag, config->GetKind_TurboMachinery(iZone)); if(nDim ==2){ @@ -7643,7 +8126,7 @@ void CEulerSolver::BC_ActDisk_Inlet(CGeometry *geometry, CSolver **solver_contai unsigned short Kind_ActDisk = config->GetKind_ActDisk(); - if(Kind_ActDisk == VARIABLE_LOAD){ + if (Kind_ActDisk == VARIABLE_LOAD || Kind_ActDisk == BLADE_ELEMENT) { BC_ActDisk_VariableLoad(geometry, solver_container, conv_numerics, visc_numerics, config, val_marker, true); } else{ @@ -7657,7 +8140,7 @@ void CEulerSolver::BC_ActDisk_Outlet(CGeometry *geometry, CSolver **solver_conta unsigned short Kind_ActDisk = config->GetKind_ActDisk(); - if(Kind_ActDisk == VARIABLE_LOAD){ + if (Kind_ActDisk == VARIABLE_LOAD || Kind_ActDisk == BLADE_ELEMENT) { BC_ActDisk_VariableLoad(geometry, solver_container, conv_numerics, visc_numerics, config, val_marker, false); } else{ @@ -8115,6 +8598,8 @@ void CEulerSolver::BC_ActDisk_VariableLoad(CGeometry *geometry, CSolver **solver const auto Gas_Constant = config->GetGas_ConstantND(); const bool tkeNeeded = (config->GetKind_Turb_Model() == TURB_MODEL::SST); + unsigned short Kind_ActDisk = config->GetKind_ActDisk(); + /*--- Get the actuator disk center and axis coordinates for the current marker. ---*/ for (iDim = 0; iDim < nDim; iDim++){ Prop_Axis[iDim] = ActDisk_Axis(val_marker, iDim); @@ -8149,10 +8634,17 @@ void CEulerSolver::BC_ActDisk_VariableLoad(CGeometry *geometry, CSolver **solver /*--- Get the values of Fa (axial force per unit area), Fx, Fy and Fz (x, y and z components of the tangential and radial forces per unit area resultant). ---*/ - Fa = ActDisk_Fa[val_marker][iVertex]; - Fx = ActDisk_Fx[val_marker][iVertex]; - Fy = ActDisk_Fy[val_marker][iVertex]; - Fz = ActDisk_Fz[val_marker][iVertex]; + if (Kind_ActDisk == BLADE_ELEMENT) { + Fa = ActDisk_Fa_BEM[val_marker][iVertex]; + Fx = ActDisk_Fx_BEM[val_marker][iVertex]; + Fy = ActDisk_Fy_BEM[val_marker][iVertex]; + Fz = ActDisk_Fz_BEM[val_marker][iVertex]; + } else { /*--- default (Kind_ActDisk == VARIABLE_LOAD) ---*/ + Fa = ActDisk_Fa[val_marker][iVertex]; + Fx = ActDisk_Fx[val_marker][iVertex]; + Fy = ActDisk_Fy[val_marker][iVertex]; + Fz = ActDisk_Fz[val_marker][iVertex]; + } /*--- Get the primitive variables and the extrapolated variables. ---*/ if (val_inlet_surface){ @@ -8577,239 +9069,118 @@ void CEulerSolver::PreprocessAverage(CSolver **solver, CGeometry *geometry, CCon void CEulerSolver::TurboAverageProcess(CSolver **solver, CGeometry *geometry, CConfig *config, unsigned short marker_flag) { - unsigned long iVertex, iPoint, nVert; - unsigned short iDim, iVar, iMarker, iMarkerTP, iSpan, jSpan; - unsigned short average_process = config->GetKind_AverageProcess(); - unsigned short performance_average_process = config->GetKind_PerformanceAverageProcess(); - su2double Pressure = 0.0, Density = 0.0, Enthalpy = 0.0, *Velocity = nullptr, *TurboVelocity, - Area, TotalArea, Radius1, Radius2, Vt2, TotalAreaPressure, TotalAreaDensity, *TotalAreaVelocity, *UnitNormal, *TurboNormal, - TotalMassPressure, TotalMassDensity, *TotalMassVelocity; - string Marker_Tag, Monitoring_Tag; - su2double val_init_pressure; - unsigned short iZone = config->GetiZone(); - su2double TotalDensity, TotalPressure, *TotalVelocity, *TotalFluxes; - const su2double *AverageTurboNormal; - su2double TotalNu, TotalOmega, TotalKine, TotalMassNu, TotalMassOmega, TotalMassKine, TotalAreaNu, TotalAreaOmega, TotalAreaKine; - su2double Nu, Kine, Omega; - su2double MachTest, soundSpeed; - bool turbulent = (config->GetKind_Turb_Model() != TURB_MODEL::NONE); - bool spalart_allmaras = (config->GetKind_Turb_Model() == TURB_MODEL::SA); - bool menter_sst = (config->GetKind_Turb_Model() == TURB_MODEL::SST); - - /*-- Variables declaration and allocation ---*/ - Velocity = new su2double[nDim]; - UnitNormal = new su2double[nDim]; - TurboNormal = new su2double[nDim]; - TurboVelocity = new su2double[nDim]; - TotalVelocity = new su2double[nDim]; - TotalAreaVelocity = new su2double[nDim]; - TotalMassVelocity = new su2double[nDim]; - TotalFluxes = new su2double[nVar]; - - su2double avgDensity, *avgVelocity, avgPressure, avgKine, avgOmega, avgNu, avgAreaDensity, *avgAreaVelocity, avgAreaPressure, - avgAreaKine, avgAreaOmega, avgAreaNu, avgMassDensity, *avgMassVelocity, avgMassPressure, avgMassKine, avgMassOmega, avgMassNu, - avgMixDensity, *avgMixVelocity, *avgMixTurboVelocity, avgMixPressure, avgMixKine, avgMixOmega, avgMixNu; - - avgVelocity = new su2double[nDim]; - avgAreaVelocity = new su2double[nDim]; - avgMassVelocity = new su2double[nDim]; - avgMixVelocity = new su2double[nDim]; - avgMixTurboVelocity = new su2double[nDim]; - + const auto average_process = config->GetKind_AverageProcess(); + const auto performance_average_process = config->GetKind_PerformanceAverageProcess(); + const auto iZone = config->GetiZone(); + const bool turbulent = (config->GetKind_Turb_Model() != TURB_MODEL::NONE); + const bool spalart_allmaras = (config->GetKind_Turb_Model() == TURB_MODEL::SA); + const bool menter_sst = (config->GetKind_Turb_Model() == TURB_MODEL::SST); const auto nSpanWiseSections = config->GetnSpanWiseSections(); - for (iSpan= 0; iSpan < nSpanWiseSections + 1; iSpan++){ + for (auto iSpan= 0; iSpan < nSpanWiseSections + 1; iSpan++){ + su2double TotalDensity{0}, TotalPressure{0}, TotalNu{0}, TotalOmega{0}, TotalKine{0}, TotalVelocity[MAXNDIM], + TotalAreaDensity{0}, TotalAreaPressure{0}, TotalAreaNu{0}, TotalAreaOmega{0}, TotalAreaKine{0}, TotalAreaVelocity[MAXNDIM], + TotalMassDensity{0}, TotalMassPressure{0}, TotalMassNu{0}, TotalMassOmega{0}, TotalMassKine{0}, TotalMassVelocity[MAXNDIM]; + su2double TotalFluxes[MAXNVAR]; /*--- Forces initialization for contenitors ---*/ - for (iVar=0;iVarGetnMarker_All(); iMarker++){ - for (iMarkerTP=1; iMarkerTP < config->GetnMarker_Turbomachinery()+1; iMarkerTP++){ - if (config->GetMarker_All_Turbomachinery(iMarker) == iMarkerTP){ - if (config->GetMarker_All_TurbomachineryFlag(iMarker) == marker_flag){ - - /*--- Retrieve Old Solution ---*/ - - /*--- Loop over the vertices to sum all the quantities pithc-wise ---*/ - if(iSpan < nSpanWiseSections){ - for (iVertex = 0; iVertex < geometry->GetnVertexSpan(iMarker,iSpan); iVertex++) { - iPoint = geometry->turbovertex[iMarker][iSpan][iVertex]->GetNode(); - - /*--- Compute the integral fluxes for the boundaries ---*/ - Pressure = nodes->GetPressure(iPoint); - Density = nodes->GetDensity(iPoint); - Enthalpy = nodes->GetEnthalpy(iPoint); - - /*--- Normal vector for this vertex (negate for outward convention) ---*/ - geometry->turbovertex[iMarker][iSpan][iVertex]->GetNormal(UnitNormal); - geometry->turbovertex[iMarker][iSpan][iVertex]->GetTurboNormal(TurboNormal); - Area = geometry->turbovertex[iMarker][iSpan][iVertex]->GetArea(); - su2double VelNormal = 0.0, VelSq = 0.0; - - for (iDim = 0; iDim < nDim; iDim++) { - Velocity[iDim] = nodes->GetVelocity(iPoint,iDim); - VelNormal += UnitNormal[iDim]*Velocity[iDim]; - VelSq += Velocity[iDim]*Velocity[iDim]; - } + auto UpdateTotalQuantities = [&](const size_t iMarker, const size_t iSpan, const size_t iVertex){ + /*--- Increment integral quantities for averaging ---*/ - ComputeTurboVelocity(Velocity, TurboNormal , TurboVelocity, marker_flag, config->GetKind_TurboMachinery(iZone)); + const auto iPoint = geometry->turbovertex[iMarker][iSpan][iVertex]->GetNode(); - /*--- Compute different integral quantities for the boundary of interest ---*/ + /*--- Retrieve local quantities ---*/ + const auto Pressure = nodes->GetPressure(iPoint); + const auto Density = nodes->GetDensity(iPoint); + const auto Enthalpy = nodes->GetEnthalpy(iPoint); - TotalDensity += Density; - TotalPressure += Pressure; - for (iDim = 0; iDim < nDim; iDim++) - TotalVelocity[iDim] += Velocity[iDim]; + su2double Velocity[MAXNDIM] = {0}, UnitNormal[MAXNDIM] = {0}, TurboNormal[MAXNDIM] = {0}, TurboVelocity[MAXNDIM] = {0}; + geometry->turbovertex[iMarker][iSpan][iVertex]->GetNormal(UnitNormal); + geometry->turbovertex[iMarker][iSpan][iVertex]->GetTurboNormal(TurboNormal); + const auto Area = geometry->turbovertex[iMarker][iSpan][iVertex]->GetArea(); - TotalAreaPressure += Area*Pressure; - TotalAreaDensity += Area*Density; - for (iDim = 0; iDim < nDim; iDim++) - TotalAreaVelocity[iDim] += Area*Velocity[iDim]; + for (auto iDim=0u; iDim < nDim; iDim++) Velocity[iDim] = nodes->GetVelocity(iPoint, iDim); - TotalMassPressure += Area*(Density*TurboVelocity[0] )*Pressure; - TotalMassDensity += Area*(Density*TurboVelocity[0] )*Density; - for (iDim = 0; iDim < nDim; iDim++) - TotalMassVelocity[iDim] += Area*(Density*TurboVelocity[0] )*Velocity[iDim]; + ComputeTurboVelocity(Velocity, TurboNormal , TurboVelocity, marker_flag, config->GetKind_TurboMachinery(iZone)); - TotalFluxes[0] += Area*(Density*TurboVelocity[0]); - TotalFluxes[1] += Area*(Density*TurboVelocity[0]*TurboVelocity[0] + Pressure); - for (iDim = 2; iDim < nDim+1; iDim++) - TotalFluxes[iDim] += Area*(Density*TurboVelocity[0]*TurboVelocity[iDim -1]); - TotalFluxes[nDim+1] += Area*(Density*TurboVelocity[0]*Enthalpy); + /*--- Compute different integral quantities for the boundary of interest ---*/ + TotalDensity += Density; + TotalPressure += Pressure; + TotalAreaPressure += Area*Pressure; + TotalAreaDensity += Area*Density; - /*--- Compute turbulent integral quantities for the boundary of interest ---*/ + TotalMassPressure += Area*(Density*TurboVelocity[0] )*Pressure; + TotalMassDensity += Area*(Density*TurboVelocity[0] )*Density; - if(turbulent){ - if(menter_sst){ - Kine = solver[TURB_SOL]->GetNodes()->GetSolution(iPoint,0); - Omega = solver[TURB_SOL]->GetNodes()->GetSolution(iPoint,1); - } - if(spalart_allmaras){ - Nu = solver[TURB_SOL]->GetNodes()->GetSolution(iPoint,0); - } + for (auto iDim = 0u; iDim < nDim; iDim++) { + TotalVelocity[iDim] += Velocity[iDim]; + TotalAreaVelocity[iDim] += Area*Velocity[iDim]; + TotalMassVelocity[iDim] += Area*(Density*TurboVelocity[0] )*Velocity[iDim]; + } + + TotalFluxes[0] += Area*(Density*TurboVelocity[0]); + TotalFluxes[1] += Area*(Density*TurboVelocity[0]*TurboVelocity[0] + Pressure); + for (auto iDim = 2; iDim < nDim+1; iDim++) + TotalFluxes[iDim] += Area*(Density*TurboVelocity[0]*TurboVelocity[iDim -1]); + TotalFluxes[nDim+1] += Area*(Density*TurboVelocity[0]*Enthalpy); + + /*--- Compute turbulent integral quantities for the boundary of interest ---*/ + + if(turbulent){ + su2double Kine{0}, Omega{0}, Nu{0}; + if(menter_sst){ + Kine = solver[TURB_SOL]->GetNodes()->GetSolution(iPoint,0); + Omega = solver[TURB_SOL]->GetNodes()->GetSolution(iPoint,1); + } + if(spalart_allmaras){ + Nu = solver[TURB_SOL]->GetNodes()->GetSolution(iPoint,0); + } - TotalKine += Kine; - TotalOmega += Omega; - TotalNu += Nu; + TotalKine += Kine; + TotalOmega += Omega; + TotalNu += Nu; - TotalAreaKine += Area*Kine; - TotalAreaOmega += Area*Omega; - TotalAreaNu += Area*Nu; + TotalAreaKine += Area*Kine; + TotalAreaOmega += Area*Omega; + TotalAreaNu += Area*Nu; - TotalMassKine += Area*(Density*TurboVelocity[0] )*Kine; - TotalMassOmega += Area*(Density*TurboVelocity[0] )*Omega; - TotalMassNu += Area*(Density*TurboVelocity[0] )*Nu; + TotalMassKine += Area*(Density*TurboVelocity[0] )*Kine; + TotalMassOmega += Area*(Density*TurboVelocity[0] )*Omega; + TotalMassNu += Area*(Density*TurboVelocity[0] )*Nu; + } + }; + for (auto iMarker = 0u; iMarker < config->GetnMarker_All(); iMarker++){ + for (auto iMarkerTP=1; iMarkerTP < config->GetnMarker_Turbomachinery()+1; iMarkerTP++){ + if (config->GetMarker_All_Turbomachinery(iMarker) == iMarkerTP){ + if (config->GetMarker_All_TurbomachineryFlag(iMarker) == marker_flag){ - } + /*--- Loop over the vertices to sum all the quantities pitch-wise ---*/ + if(iSpan < nSpanWiseSections){ + for (auto iVertex = 0ul; iVertex < geometry->GetnVertexSpan(iMarker,iSpan); iVertex++) { + UpdateTotalQuantities(iMarker, iSpan, iVertex); } - } - else{ - for (jSpan= 0; jSpan < nSpanWiseSections; jSpan++){ - for (iVertex = 0; iVertex < geometry->GetnVertexSpan(iMarker,jSpan); iVertex++) { - iPoint = geometry->turbovertex[iMarker][jSpan][iVertex]->GetNode(); - - /*--- Compute the integral fluxes for the boundaries ---*/ - Pressure = nodes->GetPressure(iPoint); - Density = nodes->GetDensity(iPoint); - Enthalpy = nodes->GetEnthalpy(iPoint); - - /*--- Normal vector for this vertex (negate for outward convention) ---*/ - geometry->turbovertex[iMarker][jSpan][iVertex]->GetNormal(UnitNormal); - geometry->turbovertex[iMarker][jSpan][iVertex]->GetTurboNormal(TurboNormal); - Area = geometry->turbovertex[iMarker][jSpan][iVertex]->GetArea(); - su2double VelNormal = 0.0, VelSq = 0.0; - - for (iDim = 0; iDim < nDim; iDim++) { - Velocity[iDim] = nodes->GetVelocity(iPoint,iDim); - VelNormal += UnitNormal[iDim]*Velocity[iDim]; - VelSq += Velocity[iDim]*Velocity[iDim]; - } - - ComputeTurboVelocity(Velocity, TurboNormal , TurboVelocity, marker_flag, config->GetKind_TurboMachinery(iZone)); - - /*--- Compute different integral quantities for the boundary of interest ---*/ - - TotalDensity += Density; - TotalPressure += Pressure; - for (iDim = 0; iDim < nDim; iDim++) - TotalVelocity[iDim] += Velocity[iDim]; - - TotalAreaPressure += Area*Pressure; - TotalAreaDensity += Area*Density; - for (iDim = 0; iDim < nDim; iDim++) - TotalAreaVelocity[iDim] += Area*Velocity[iDim]; - - TotalMassPressure += Area*(Density*TurboVelocity[0] )*Pressure; - TotalMassDensity += Area*(Density*TurboVelocity[0] )*Density; - for (iDim = 0; iDim < nDim; iDim++) - TotalMassVelocity[iDim] += Area*(Density*TurboVelocity[0] )*Velocity[iDim]; - - TotalFluxes[0] += Area*(Density*TurboVelocity[0]); - TotalFluxes[1] += Area*(Density*TurboVelocity[0]*TurboVelocity[0] + Pressure); - for (iDim = 2; iDim < nDim+1; iDim++) - TotalFluxes[iDim] += Area*(Density*TurboVelocity[0]*TurboVelocity[iDim -1]); - TotalFluxes[nDim+1] += Area*(Density*TurboVelocity[0]*Enthalpy); - - - /*--- Compute turbulent integral quantities for the boundary of interest ---*/ - - if(turbulent){ - if(menter_sst){ - Kine = solver[TURB_SOL]->GetNodes()->GetSolution(iPoint,0); - Omega = solver[TURB_SOL]->GetNodes()->GetSolution(iPoint,1); - } - if(spalart_allmaras){ - Nu = solver[TURB_SOL]->GetNodes()->GetSolution(iPoint,0); - } - - TotalKine += Kine; - TotalOmega += Omega; - TotalNu += Nu; - - TotalAreaKine += Area*Kine; - TotalAreaOmega += Area*Omega; - TotalAreaNu += Area*Nu; - - TotalMassKine += Area*(Density*TurboVelocity[0] )*Kine; - TotalMassOmega += Area*(Density*TurboVelocity[0] )*Omega; - TotalMassNu += Area*(Density*TurboVelocity[0] )*Nu; - - } + } else { + for (auto jSpan= 0u; jSpan < nSpanWiseSections; jSpan++){ + for (auto iVertex = 0ul; iVertex < geometry->GetnVertexSpan(iMarker,jSpan); iVertex++) { + UpdateTotalQuantities(iMarker, jSpan, iVertex); } } - } - } - } - } - } + } + + } // marker_flag match + } // iMarkerTP match + } // iMarkerTP + } // iMarker #ifdef HAVE_MPI @@ -8855,155 +9226,148 @@ void CEulerSolver::TurboAverageProcess(CSolver **solver, CGeometry *geometry, CC #endif - for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++){ - for (iMarkerTP=1; iMarkerTP < config->GetnMarker_Turbomachinery()+1; iMarkerTP++){ + /*--- Compute pitch-wise averaged quantities ---*/ + for (auto iMarker = 0u; iMarker < config->GetnMarker_All(); iMarker++){ + for (auto iMarkerTP=1; iMarkerTP < config->GetnMarker_Turbomachinery()+1; iMarkerTP++){ if (config->GetMarker_All_Turbomachinery(iMarker) == iMarkerTP){ if (config->GetMarker_All_TurbomachineryFlag(iMarker) == marker_flag){ - TotalArea = geometry->GetSpanArea(iMarker,iSpan); - AverageTurboNormal = geometry->GetAverageTurboNormal(iMarker,iSpan); - nVert = geometry->GetnTotVertexSpan(iMarker,iSpan); + const auto TotalArea = geometry->GetSpanArea(iMarker,iSpan); + const auto AverageTurboNormal = geometry->GetAverageTurboNormal(iMarker,iSpan); + const auto nVert = geometry->GetnTotVertexSpan(iMarker,iSpan); /*--- compute normal Mach number as a check for massflow average and mixedout average ---*/ GetFluidModel()->SetTDState_Prho(TotalAreaPressure/TotalArea, TotalAreaDensity / TotalArea); - soundSpeed = GetFluidModel()->GetSoundSpeed(); - MachTest = TotalFluxes[0]/(TotalAreaDensity*soundSpeed); + const su2double soundSpeed = GetFluidModel()->GetSoundSpeed(), + MachTest = TotalFluxes[0]/(TotalAreaDensity*soundSpeed); /*--- Compute the averaged value for the boundary of interest for the span of interest ---*/ - /*--- compute algebraic average ---*/ - avgDensity = TotalDensity / nVert; - avgPressure = TotalPressure / nVert; - for (iDim = 0; iDim < nDim; iDim++) avgVelocity[iDim] = TotalVelocity[iDim] / nVert; - avgKine = TotalKine/nVert; - avgOmega = TotalOmega/nVert; - avgNu = TotalNu/nVert; - - /*--- compute area average ---*/ - avgAreaDensity = TotalAreaDensity / TotalArea; - avgAreaPressure = TotalAreaPressure / TotalArea; - for (iDim = 0; iDim < nDim; iDim++) avgAreaVelocity[iDim] = TotalAreaVelocity[iDim] / TotalArea; - avgAreaKine = TotalAreaKine / TotalArea; - avgAreaOmega = TotalAreaOmega / TotalArea; - avgAreaNu = TotalAreaNu / TotalArea; - - /*--- compute mass-flow average ---*/ - if (abs(MachTest)< config->GetAverageMachLimit()) { - avgMassDensity = avgAreaDensity; - avgMassPressure = avgAreaPressure; - for (iDim = 0; iDim < nDim; iDim++) avgMassVelocity[iDim] = avgAreaVelocity[iDim]; - avgMassKine = avgAreaKine; - avgMassOmega = avgAreaOmega; - avgMassNu = avgAreaNu; - }else{ - avgMassDensity = TotalMassDensity / TotalFluxes[0]; - avgMassPressure = TotalMassPressure / TotalFluxes[0]; - for (iDim = 0; iDim < nDim; iDim++) avgMassVelocity[iDim] = TotalMassVelocity[iDim] / TotalFluxes[0]; - avgMassKine = TotalMassKine / TotalFluxes[0]; - avgMassOmega = TotalMassOmega / TotalFluxes[0]; - avgMassNu = TotalMassNu / TotalFluxes[0]; - } - /*--- compute mixed-out average ---*/ - for (iVar = 0; iVarGetAverageMachLimit()); + su2double avgDensity{0}, avgPressure{0}, avgKine{0}, avgOmega{0}, avgNu{0}, + avgVelocity[MAXNDIM] = {0}, avgMixTurboVelocity[MAXNDIM] = {0}; + for (auto iVar = 0u; iVarGetAverageMachLimit()) { - avgMixDensity = avgAreaDensity; - avgMixPressure = avgAreaPressure; - for (iDim = 0; iDim < nDim; iDim++) - avgMixVelocity[iDim] = avgAreaVelocity[iDim]; - ComputeTurboVelocity(avgMixVelocity, AverageTurboNormal , avgMixTurboVelocity, marker_flag, config->GetKind_TurboMachinery(iZone)); - avgMixKine = avgAreaKine; - avgMixOmega = avgAreaOmega; - avgMixNu = avgAreaNu; - }else { - MixedOut_Average (config, val_init_pressure, AverageFlux[iMarker][iSpan], AverageTurboNormal, avgMixPressure, avgMixDensity); - avgMixTurboVelocity[0] = ( AverageFlux[iMarker][iSpan][1] - avgMixPressure) / AverageFlux[iMarker][iSpan][0]; - for (iDim = 2; iDim < nDim +1;iDim++) - avgMixTurboVelocity[iDim-1] = AverageFlux[iMarker][iSpan][iDim] / AverageFlux[iMarker][iSpan][0]; - - if (avgMixDensity!= avgMixDensity || avgMixPressure!= avgMixPressure || avgMixPressure < 0.0 || avgMixDensity < 0.0 ){ - val_init_pressure = avgAreaPressure; - MixedOut_Average (config, val_init_pressure, AverageFlux[iMarker][iSpan], AverageTurboNormal, avgMixPressure, avgMixDensity); - avgMixTurboVelocity[0] = ( AverageFlux[iMarker][iSpan][1] - avgMixPressure) / AverageFlux[iMarker][iSpan][0]; - for (iDim = 2; iDim < nDim +1;iDim++) - avgMixTurboVelocity[iDim-1] = AverageFlux[iMarker][iSpan][iDim] / AverageFlux[iMarker][iSpan][0]; - } - avgMixKine = avgMassKine; - avgMixOmega = avgMassOmega; - avgMixNu = avgMassNu; - } - /*--- Store averaged value for the selected average method ---*/ - switch(average_process){ + switch (average_process) + { case ALGEBRAIC: - AverageDensity[iMarker][iSpan] = avgDensity; - AveragePressure[iMarker][iSpan] = avgPressure; - ComputeTurboVelocity(avgVelocity, AverageTurboNormal , AverageTurboVelocity[iMarker][iSpan], marker_flag, config->GetKind_TurboMachinery(iZone)); - AverageKine[iMarker][iSpan] = avgKine; - AverageOmega[iMarker][iSpan] = avgOmega; - AverageNu[iMarker][iSpan] = avgNu; + /*--- compute algebraic average ---*/ + avgDensity = TotalDensity / nVert; + avgPressure = TotalPressure / nVert; + for (auto iDim = 0u; iDim < nDim; iDim++) avgVelocity[iDim] = TotalVelocity[iDim] / nVert; + if (turbulent) { + avgKine = TotalKine/nVert; + avgOmega = TotalOmega/nVert; + avgNu = TotalNu/nVert; + } break; - case AREA: - AverageDensity[iMarker][iSpan] = avgAreaDensity; - AveragePressure[iMarker][iSpan] = avgAreaPressure; - ComputeTurboVelocity(avgAreaVelocity, AverageTurboNormal , AverageTurboVelocity[iMarker][iSpan], marker_flag, config->GetKind_TurboMachinery(iZone)); - AverageKine[iMarker][iSpan] = avgAreaKine; - AverageOmega[iMarker][iSpan] = avgAreaOmega; - AverageNu[iMarker][iSpan] = avgAreaNu; + /*--- compute area average ---*/ + avgDensity = TotalAreaDensity / TotalArea; + avgPressure = TotalAreaPressure / TotalArea; + for (auto iDim = 0u; iDim < nDim; iDim++) avgVelocity[iDim] = TotalAreaVelocity[iDim] / TotalArea; + if (turbulent) { + avgKine = TotalAreaKine / TotalArea; + avgOmega = TotalAreaOmega / TotalArea; + avgNu = TotalAreaNu / TotalArea; + } break; - case MASSFLUX: - AverageDensity[iMarker][iSpan] = avgMassDensity; - AveragePressure[iMarker][iSpan] = avgMassPressure; - ComputeTurboVelocity(avgAreaVelocity, AverageTurboNormal , AverageTurboVelocity[iMarker][iSpan], marker_flag, config->GetKind_TurboMachinery(iZone)); - AverageKine[iMarker][iSpan] = avgMassKine; - AverageOmega[iMarker][iSpan] = avgMassOmega; - AverageNu[iMarker][iSpan] = avgMassNu; + /*--- compute mass-flux average ---*/ + if (belowMachLimit) { + avgDensity = TotalAreaDensity / TotalArea; + avgPressure = TotalAreaPressure / TotalArea; + for (auto iDim = 0u; iDim < nDim; iDim++) avgVelocity[iDim] = TotalAreaVelocity[iDim] / TotalArea; + if (turbulent) { + avgKine = TotalAreaKine / TotalArea; + avgOmega = TotalAreaOmega / TotalArea; + avgNu = TotalAreaNu / TotalArea; + } + } else { + avgDensity = TotalMassDensity / TotalFluxes[0]; + avgPressure = TotalMassPressure / TotalFluxes[0]; + for (auto iDim = 0u; iDim < nDim; iDim++) avgVelocity[iDim] = TotalMassVelocity[iDim] / TotalFluxes[0]; + if (turbulent) { + avgKine = TotalMassKine / TotalFluxes[0]; + avgOmega = TotalMassOmega / TotalFluxes[0]; + avgNu = TotalMassNu / TotalFluxes[0]; + } + } break; - case MIXEDOUT: - AverageDensity[iMarker][iSpan] = avgMixDensity; - AveragePressure[iMarker][iSpan] = avgMixPressure; - for (iDim = 0; iDim < nDim; iDim++) AverageTurboVelocity[iMarker][iSpan][iDim] = avgMixTurboVelocity[iDim]; - AverageKine[iMarker][iSpan] = avgMixKine; - AverageOmega[iMarker][iSpan] = avgMixOmega; - AverageNu[iMarker][iSpan] = avgMixNu; + /*--- compute mixed-out average ---*/ + avgDensity = TotalAreaDensity / TotalArea; + avgPressure = TotalAreaPressure / TotalArea; + if (belowMachLimit) { + for (auto iDim = 0u; iDim < nDim; iDim++) + avgVelocity[iDim] = TotalAreaVelocity[iDim] / TotalArea; + if (turbulent) { + avgKine = TotalAreaKine / TotalArea; + avgOmega = TotalAreaOmega / TotalArea; + avgNu = TotalAreaNu / TotalArea; + } + }else { + auto val_init_pressure = OldAveragePressure[iMarker][iSpan]; + MixedOut_Average (config, val_init_pressure, AverageFlux[iMarker][iSpan], AverageTurboNormal, avgPressure, avgDensity); + avgVelocity[0] = ( AverageFlux[iMarker][iSpan][1] - avgPressure) / AverageFlux[iMarker][iSpan][0]; + for (auto iDim = 2; iDim < nDim +1;iDim++) + avgVelocity[iDim-1] = AverageFlux[iMarker][iSpan][iDim] / AverageFlux[iMarker][iSpan][0]; + + if (isnan(avgDensity) || isnan(avgPressure) || avgPressure < 0.0 || avgDensity < 0.0 ){ + val_init_pressure = TotalAreaPressure / TotalArea; + MixedOut_Average (config, val_init_pressure, AverageFlux[iMarker][iSpan], AverageTurboNormal, avgPressure, avgDensity); + avgVelocity[0] = ( AverageFlux[iMarker][iSpan][1] - avgPressure) / AverageFlux[iMarker][iSpan][0]; + for (auto iDim = 2; iDim < nDim +1;iDim++) + avgVelocity[iDim-1] = AverageFlux[iMarker][iSpan][iDim] / AverageFlux[iMarker][iSpan][0]; + } + if (turbulent) { + avgKine = TotalMassKine / TotalFluxes[0]; + avgOmega = TotalMassOmega / TotalFluxes[0]; + avgNu = TotalMassNu / TotalFluxes[0]; + } + } break; - default: SU2_MPI::Error(" Invalid AVERAGE PROCESS input!", CURRENT_FUNCTION); break; } - /* --- check if averaged quantities are correct otherwise reset the old quantities ---*/ - if (AverageDensity[iMarker][iSpan]!= AverageDensity[iMarker][iSpan] || AveragePressure[iMarker][iSpan]!= AveragePressure[iMarker][iSpan]){ - cout<<"nan in mixing process routine for iSpan: " << iSpan<< " in marker " << config->GetMarker_All_TagBound(iMarker)<< endl; - AverageDensity[iMarker][iSpan] = OldAverageDensity[iMarker][iSpan]; - AveragePressure[iMarker][iSpan] = OldAveragePressure[iMarker][iSpan]; - for(iDim = 0; iDim < nDim;iDim++) - AverageTurboVelocity[iMarker][iSpan][iDim] = OldAverageTurboVelocity[iMarker][iSpan][iDim]; + AverageDensity[iMarker][iSpan] = avgDensity; + AveragePressure[iMarker][iSpan] = avgPressure; + if ((average_process == MIXEDOUT) && !belowMachLimit) { + for (auto iDim = 0u; iDim < nDim; iDim++) AverageTurboVelocity[iMarker][iSpan][iDim] = avgVelocity[iDim]; + } else { + ComputeTurboVelocity(avgVelocity, AverageTurboNormal , AverageTurboVelocity[iMarker][iSpan], marker_flag, config->GetKind_TurboMachinery(iZone)); + } + if (turbulent) { + AverageKine[iMarker][iSpan] = avgKine; + AverageOmega[iMarker][iSpan] = avgOmega; + AverageNu[iMarker][iSpan] = avgNu; } - - if (AverageDensity[iMarker][iSpan] < 0.0 || AveragePressure[iMarker][iSpan] < 0.0){ - cout << " negative density or pressure in mixing process routine for iSpan: " << iSpan<< " in marker " << config->GetMarker_All_TagBound(iMarker)<< endl; + /* --- check if averaged quantities are correct otherwise reset the old quantities ---*/ + const bool nanSolution = (isnan(AverageDensity[iMarker][iSpan]) || isnan(AveragePressure[iMarker][iSpan])); + const bool negSolution = (AverageDensity[iMarker][iSpan] < 0.0 || AveragePressure[iMarker][iSpan] < 0.0); + if (nanSolution || negSolution){ + if (nanSolution) + cout<<"nan in mixing process routine for iSpan: " << iSpan<< " in marker " << config->GetMarker_All_TagBound(iMarker)<< endl; + else + cout << " negative density or pressure in mixing process routine for iSpan: " << iSpan<< " in marker " << config->GetMarker_All_TagBound(iMarker)<< endl; AverageDensity[iMarker][iSpan] = OldAverageDensity[iMarker][iSpan]; AveragePressure[iMarker][iSpan] = OldAveragePressure[iMarker][iSpan]; - for(iDim = 0; iDim < nDim;iDim++) + for(auto iDim = 0u; iDim < nDim;iDim++) AverageTurboVelocity[iMarker][iSpan][iDim] = OldAverageTurboVelocity[iMarker][iSpan][iDim]; + } else { + /* --- update old average solution ---*/ + OldAverageDensity[iMarker][iSpan] = AverageDensity[iMarker][iSpan]; + OldAveragePressure[iMarker][iSpan] = AveragePressure[iMarker][iSpan]; + for(auto iDim = 0u; iDim < nDim;iDim++) + OldAverageTurboVelocity[iMarker][iSpan][iDim] = AverageTurboVelocity[iMarker][iSpan][iDim]; } - /* --- update old average solution ---*/ - OldAverageDensity[iMarker][iSpan] = AverageDensity[iMarker][iSpan]; - OldAveragePressure[iMarker][iSpan] = AveragePressure[iMarker][iSpan]; - for(iDim = 0; iDim < nDim;iDim++) - OldAverageTurboVelocity[iMarker][iSpan][iDim] = AverageTurboVelocity[iMarker][iSpan][iDim]; - /*--- to avoid back flow ---*/ if (AverageTurboVelocity[iMarker][iSpan][0] < 0.0){ AverageTurboVelocity[iMarker][iSpan][0] = soundSpeed*config->GetAverageMachLimit(); @@ -9012,161 +9376,69 @@ void CEulerSolver::TurboAverageProcess(CSolver **solver, CGeometry *geometry, CC /*--- compute cartesian average Velocity ---*/ ComputeBackVelocity(AverageTurboVelocity[iMarker][iSpan], AverageTurboNormal , AverageVelocity[iMarker][iSpan], marker_flag, config->GetKind_TurboMachinery(iZone)); - /*--- Store averaged performance value for the selected average method ---*/ - switch(performance_average_process){ - case ALGEBRAIC: - if(marker_flag == INFLOW){ - DensityIn[iMarkerTP - 1][iSpan] = avgDensity; - PressureIn[iMarkerTP - 1][iSpan] = avgPressure; - ComputeTurboVelocity(avgVelocity, AverageTurboNormal , TurboVelocityIn[iMarkerTP -1][iSpan], marker_flag, config->GetKind_TurboMachinery(iZone)); - KineIn[iMarkerTP - 1][iSpan] = avgKine; - OmegaIn[iMarkerTP - 1][iSpan] = avgOmega; - NuIn[iMarkerTP - 1][iSpan] = avgNu; - } - else{ - DensityOut[iMarkerTP - 1][iSpan] = avgDensity; - PressureOut[iMarkerTP - 1][iSpan] = avgPressure; - ComputeTurboVelocity(avgVelocity, AverageTurboNormal , TurboVelocityOut[iMarkerTP -1][iSpan], marker_flag, config->GetKind_TurboMachinery(iZone)); - KineOut[iMarkerTP - 1][iSpan] = avgKine; - OmegaOut[iMarkerTP - 1][iSpan] = avgOmega; - NuOut[iMarkerTP - 1][iSpan] = avgNu; - } - - break; - case AREA: - if(marker_flag == INFLOW){ - DensityIn[iMarkerTP - 1][iSpan] = avgAreaDensity; - PressureIn[iMarkerTP - 1][iSpan] = avgAreaPressure; - ComputeTurboVelocity(avgAreaVelocity, AverageTurboNormal , TurboVelocityIn[iMarkerTP -1][iSpan], marker_flag, config->GetKind_TurboMachinery(iZone)); - KineIn[iMarkerTP - 1][iSpan] = avgAreaKine; - OmegaIn[iMarkerTP - 1][iSpan] = avgAreaOmega; - NuIn[iMarkerTP - 1][iSpan] = avgAreaNu; - } - else{ - DensityOut[iMarkerTP - 1][iSpan] = avgAreaDensity; - PressureOut[iMarkerTP - 1][iSpan] = avgAreaPressure; - ComputeTurboVelocity(avgAreaVelocity, AverageTurboNormal , TurboVelocityOut[iMarkerTP -1][iSpan], marker_flag, config->GetKind_TurboMachinery(iZone)); - KineOut[iMarkerTP - 1][iSpan] = avgAreaKine; - OmegaOut[iMarkerTP - 1][iSpan] = avgAreaOmega; - NuOut[iMarkerTP - 1][iSpan] = avgAreaNu/TotalArea; - } - break; - - case MASSFLUX: - if(marker_flag == INFLOW){ - DensityIn[iMarkerTP - 1][iSpan] = avgMassDensity; - PressureIn[iMarkerTP - 1][iSpan] = avgMassPressure; - ComputeTurboVelocity(avgMassVelocity, AverageTurboNormal , TurboVelocityIn[iMarkerTP -1][iSpan], marker_flag, config->GetKind_TurboMachinery(iZone)); - KineIn[iMarkerTP - 1][iSpan] = avgMassKine; - OmegaIn[iMarkerTP - 1][iSpan] = avgMassOmega; - NuIn[iMarkerTP - 1][iSpan] = avgMassNu; - } - else{ - DensityOut[iMarkerTP - 1][iSpan] = avgMassDensity; - PressureOut[iMarkerTP - 1][iSpan] = avgMassPressure; - ComputeTurboVelocity(avgMassVelocity, AverageTurboNormal , TurboVelocityOut[iMarkerTP -1][iSpan], marker_flag, config->GetKind_TurboMachinery(iZone)); - KineOut[iMarkerTP - 1][iSpan] = avgMassKine; - OmegaOut[iMarkerTP - 1][iSpan] = avgMassOmega; - NuOut[iMarkerTP - 1][iSpan] = avgMassNu; - } - - break; - - case MIXEDOUT: - if (marker_flag == INFLOW){ - DensityIn[iMarkerTP - 1][iSpan] = avgMixDensity; - PressureIn[iMarkerTP - 1][iSpan] = avgMixPressure; - for (iDim = 0; iDim < nDim; iDim++) TurboVelocityIn[iMarkerTP -1][iSpan][iDim] = avgMixTurboVelocity[iDim]; - KineIn[iMarkerTP - 1][iSpan] = avgMixKine; - OmegaIn[iMarkerTP - 1][iSpan] = avgMixOmega; - NuIn[iMarkerTP - 1][iSpan] = avgMixNu; - } - else{ - DensityOut[iMarkerTP - 1][iSpan] = avgMixDensity; - PressureOut[iMarkerTP - 1][iSpan] = avgMixPressure; - for (iDim = 0; iDim < nDim; iDim++) TurboVelocityOut[iMarkerTP -1][iSpan][iDim] = avgMixTurboVelocity[iDim]; - KineOut[iMarkerTP - 1][iSpan] = avgMixKine; - OmegaOut[iMarkerTP - 1][iSpan] = avgMixOmega; - NuOut[iMarkerTP - 1][iSpan] = avgMixNu; - } - break; + if (marker_flag == INFLOW) { + DensityIn[iMarkerTP - 1][iSpan] = AverageDensity[iMarker][iSpan]; + PressureIn[iMarkerTP - 1][iSpan] = AveragePressure[iMarker][iSpan]; + KineIn[iMarkerTP - 1][iSpan] = AverageKine[iMarker][iSpan]; + OmegaIn[iMarkerTP - 1][iSpan] = AverageOmega[iMarker][iSpan]; + NuIn[iMarkerTP - 1][iSpan] = AverageNu[iMarker][iSpan]; + } else { + DensityOut[iMarkerTP - 1][iSpan] = AverageDensity[iMarker][iSpan]; + PressureOut[iMarkerTP - 1][iSpan] = AveragePressure[iMarker][iSpan]; + KineOut[iMarkerTP - 1][iSpan] = AverageKine[iMarker][iSpan]; + OmegaOut[iMarkerTP - 1][iSpan] = AverageOmega[iMarker][iSpan]; + NuOut[iMarkerTP - 1][iSpan] = AverageNu[iMarker][iSpan]; + } + + auto TurboVel = (marker_flag == INFLOW) ? TurboVelocityIn[iMarkerTP - 1][iSpan] : TurboVelocityOut[iMarkerTP - 1][iSpan]; - default: - SU2_MPI::Error(" Invalid MIXING_PROCESS input!", CURRENT_FUNCTION); - break; + if (performance_average_process == MIXEDOUT) { + for (auto iDim = 0u; iDim < nDim; iDim++) TurboVel[iDim] = avgMixTurboVelocity[iDim]; + } else { + ComputeTurboVelocity(avgVelocity, AverageTurboNormal , TurboVel, marker_flag, config->GetKind_TurboMachinery(iZone)); } } } - } - } - } + } // iMarkerTP + } // iMarker + } // iSpan /*--- Compute Outlet Static Pressure if Radial equilibrium is imposed ---*/ - for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++){ - for (iMarkerTP=1; iMarkerTP < config->GetnMarker_Turbomachinery()+1; iMarkerTP++){ + for (auto iMarker = 0u; iMarker < config->GetnMarker_All(); iMarker++){ + for (auto iMarkerTP=1; iMarkerTP < config->GetnMarker_Turbomachinery()+1; iMarkerTP++){ if (config->GetMarker_All_Turbomachinery(iMarker) == iMarkerTP){ if (config->GetMarker_All_TurbomachineryFlag(iMarker) == marker_flag){ - Marker_Tag = config->GetMarker_All_TagBound(iMarker); + auto Marker_Tag = config->GetMarker_All_TagBound(iMarker); if(config->GetBoolGiles() || config->GetBoolRiemann()){ if(config->GetBoolRiemann()){ if(config->GetKind_Data_Riemann(Marker_Tag) == RADIAL_EQUILIBRIUM){ RadialEquilibriumPressure[iMarker][nSpanWiseSections/2] = config->GetRiemann_Var1(Marker_Tag)/config->GetPressure_Ref(); - for (iSpan= nSpanWiseSections/2; iSpan < nSpanWiseSections-1; iSpan++){ - Radius2 = geometry->GetTurboRadius(iMarker,iSpan+1); - Radius1 = geometry->GetTurboRadius(iMarker,iSpan); - Vt2 = AverageTurboVelocity[iMarker][iSpan +1][1]*AverageTurboVelocity[iMarker][iSpan +1][1]; - RadialEquilibriumPressure[iMarker][iSpan +1] = RadialEquilibriumPressure[iMarker][iSpan] + AverageDensity[iMarker][iSpan +1]*Vt2/Radius2*(Radius2 - Radius1); - } - for (iSpan= nSpanWiseSections/2; iSpan > 0; iSpan--){ - Radius2 = geometry->GetTurboRadius(iMarker,iSpan); - Radius1 = geometry->GetTurboRadius(iMarker,iSpan-1); - Vt2 = AverageTurboVelocity[iMarker][iSpan - 1][1]*AverageTurboVelocity[iMarker][iSpan - 1][1]; - Radius1 = (Radius1 > EPS)? Radius1 : Radius2; - RadialEquilibriumPressure[iMarker][iSpan -1] = RadialEquilibriumPressure[iMarker][iSpan] - AverageDensity[iMarker][iSpan -1]*Vt2/Radius1*(Radius2 - Radius1); - } } - } - else{ + } else { if(config->GetKind_Data_Giles(Marker_Tag) == RADIAL_EQUILIBRIUM){ RadialEquilibriumPressure[iMarker][nSpanWiseSections/2] = config->GetGiles_Var1(Marker_Tag)/config->GetPressure_Ref(); - for (iSpan= nSpanWiseSections/2; iSpan < nSpanWiseSections-1; iSpan++){ - Radius2 = geometry->GetTurboRadius(iMarker,iSpan+1); - Radius1 = geometry->GetTurboRadius(iMarker,iSpan); - Vt2 = AverageTurboVelocity[iMarker][iSpan +1][1]*AverageTurboVelocity[iMarker][iSpan +1][1]; - RadialEquilibriumPressure[iMarker][iSpan +1] = RadialEquilibriumPressure[iMarker][iSpan] + AverageDensity[iMarker][iSpan +1]*Vt2/Radius2*(Radius2 - Radius1); - } - for (iSpan= nSpanWiseSections/2; iSpan > 0; iSpan--){ - Radius2 = geometry->GetTurboRadius(iMarker,iSpan); - Radius1 = geometry->GetTurboRadius(iMarker,iSpan-1); - Vt2 = AverageTurboVelocity[iMarker][iSpan -1][1]*AverageTurboVelocity[iMarker][iSpan - 1][1]; - Radius1 = (Radius1 > EPS)? Radius1 : Radius2; - RadialEquilibriumPressure[iMarker][iSpan -1] = RadialEquilibriumPressure[iMarker][iSpan] - AverageDensity[iMarker][iSpan -1]*Vt2/Radius1*(Radius2 - Radius1); - } } + } + for (auto iSpan= nSpanWiseSections/2; iSpan < nSpanWiseSections-1; iSpan++){ + const auto Radius2 = geometry->GetTurboRadius(iMarker,iSpan+1); + const auto Radius1 = geometry->GetTurboRadius(iMarker,iSpan); + const su2double Vt2 = AverageTurboVelocity[iMarker][iSpan +1][1]*AverageTurboVelocity[iMarker][iSpan +1][1]; + RadialEquilibriumPressure[iMarker][iSpan +1] = RadialEquilibriumPressure[iMarker][iSpan] + AverageDensity[iMarker][iSpan +1]*Vt2/Radius2*(Radius2 - Radius1); } - } - } - } - } - } - - /*--- Free locally allocated memory ---*/ - delete [] Velocity; - delete [] UnitNormal; - delete [] TurboNormal; - delete [] TurboVelocity; - delete [] TotalVelocity; - delete [] TotalAreaVelocity; - delete [] TotalFluxes; - delete [] TotalMassVelocity; - delete [] avgVelocity; - delete [] avgAreaVelocity; - delete [] avgMassVelocity; - delete [] avgMixVelocity; - delete [] avgMixTurboVelocity; - + for (auto iSpan= nSpanWiseSections/2; iSpan > 0; iSpan--){ + const su2double Radius2 = geometry->GetTurboRadius(iMarker,iSpan); + su2double Radius1 = geometry->GetTurboRadius(iMarker,iSpan-1); + const su2double Vt2 = AverageTurboVelocity[iMarker][iSpan -1][1]*AverageTurboVelocity[iMarker][iSpan - 1][1]; + Radius1 = (Radius1 > EPS)? Radius1 : Radius2; + RadialEquilibriumPressure[iMarker][iSpan -1] = RadialEquilibriumPressure[iMarker][iSpan] - AverageDensity[iMarker][iSpan -1]*Vt2/Radius1*(Radius2 - Radius1); + } + } // Giles or Riemann + } // marker_flag + } // iMarkerTP + } // iMarker is iMarkerTP + } // iMarker } void CEulerSolver::MixedOut_Average (CConfig *config, su2double val_init_pressure, const su2double *val_Averaged_Flux, diff --git a/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp b/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp index 7bc538c2fde..b39a09a2e24 100644 --- a/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp +++ b/SU2_DEF/include/drivers/CDiscAdjDeformationDriver.hpp @@ -1,5 +1,5 @@ /*! - * \file CDiscAdjDeformationDriver.cpp + * \file CDiscAdjDeformationDriver.hpp * \brief Headers of the main subroutines for driving the projection of sensitivities. * \author T. Economon, H. Kline, R. Sanchez, A. Gastaldi, H. Patel * \version 8.0.0 "Harrier" diff --git a/TestCases/TestCase.py b/TestCases/TestCase.py index 488865bc936..e46e1367425 100644 --- a/TestCases/TestCase.py +++ b/TestCases/TestCase.py @@ -111,8 +111,8 @@ def __init__(self,tag_in): self.ntest_vals = 4 self.test_vals = [] self.test_vals_aarch64 = [] - self.cpu_arch = platform.processor() - self.enabled_on_cpu_arch = ["x86_64", "aarch64"] + self.cpu_arch = platform.machine().casefold() + self.enabled_on_cpu_arch = ["x86_64","amd64","aarch64","arm64"] self.enabled_with_tsan = True self.command = self.Command() self.timeout = 0 @@ -340,10 +340,10 @@ def run_filediff(self, running_with_tsan=False): diff = '' try: fromdate = time.ctime(os.stat(fromfile).st_mtime) - fromlines = open(fromfile, 'U').readlines() + fromlines = open(fromfile, 'r').readlines() try: todate = time.ctime(os.stat(tofile).st_mtime) - tolines = open(tofile, 'U').readlines() + tolines = open(tofile, 'r').readlines() # If file tolerance is set to 0, make regular diff if self.tol_file_percent == 0.0: @@ -361,7 +361,7 @@ def run_filediff(self, running_with_tsan=False): if len(fromlines) != len(tolines): diff = ["ERROR: Number of lines in " + fromfile + " and " + tofile + " differ."] passed = False - + # Loop through all lines for i_line in range(0, len(fromlines)): @@ -957,7 +957,7 @@ def is_enabled(self, running_with_tsan=False): def adjust_test_data(self): - if self.cpu_arch == 'aarch64': + if self.cpu_arch == 'aarch64' or self.cpu_arch == 'arm64': if len(self.test_vals_aarch64) != 0: self.test_vals = self.test_vals_aarch64 diff --git a/TestCases/cgns_writer/config.cfg b/TestCases/cgns_writer/config.cfg new file mode 100644 index 00000000000..12930ef75c9 --- /dev/null +++ b/TestCases/cgns_writer/config.cfg @@ -0,0 +1,96 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% SU2 configuration file % +% Case description: Subsonic U-Turn % +% Author: Andrea Rausa % +% Institution: Politecnico di Milano % +% Date: 12/2/2023 % +% File Version 8.0.0 "Harrier" % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% ------------- DIRECT, ADJOINT, AND LINEARIZED PROBLEM DEFINITION ------------% +% +SOLVER= RANS +KIND_TURB_MODEL= SST +MATH_PROBLEM= DIRECT +RESTART_SOL= NO + +% -------------------- COMPRESSIBLE FREE-STREAM DEFINITION --------------------% +% +MACH_NUMBER= 0.2 +AOA= 0.0 +FREESTREAM_TEMPERATURE= 270.0 +REYNOLDS_NUMBER= 3.28E6 +REYNOLDS_LENGTH= 1 +REF_DIMENSIONALIZATION= FREESTREAM_VEL_EQ_MACH + +% ---------------------- REFERENCE VALUE DEFINITION ---------------------------% +% +REF_ORIGIN_MOMENT_X = -0.2473 +REF_ORIGIN_MOMENT_Y = 0.00 +REF_ORIGIN_MOMENT_Z = 0.00 +REF_LENGTH= 1 +REF_AREA= 1 + +% -------------------- BOUNDARY CONDITION DEFINITION --------------------------% +% +MARKER_HEATFLUX= ( OuterWall, 0.0, InnerWall, 0.0 ) +MARKER_FAR= ( Inlet, Outlet ) +MARKER_PLOTTING= ( InnerWall ) +MARKER_MONITORING= ( InnerWall ) + +% ------------------------ LINEAR SOLVER DEFINITION ---------------------------% +% +LINEAR_SOLVER= FGMRES +LINEAR_SOLVER_PREC= ILU +LINEAR_SOLVER_ERROR= 1.0e-6 +LINEAR_SOLVER_ITER= 15 + +% -------------------------- MULTIGRID PARAMETERS -----------------------------% +% +CFL_ADAPT= YES +CFL_NUMBER= 1 +CFL_REDUCTION_TURB= 1.0 +CFL_ADAPT_PARAM= ( 0.5, 1.01, 1.0, 5, 0.0001) +ITER= 1 + +% -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% +% +CONV_NUM_METHOD_FLOW= ROE +USE_VECTORIZATION= YES +MUSCL_FLOW= NO +SLOPE_LIMITER_FLOW= VENKATAKRISHNAN +VENKAT_LIMITER_COEFF= 0.03 +TIME_DISCRE_FLOW= EULER_IMPLICIT + +% -------------------- TURBULENT NUMERICAL METHOD DEFINITION ------------------% +% +CONV_NUM_METHOD_TURB= SCALAR_UPWIND +MUSCL_TURB= NO +TIME_DISCRE_TURB= EULER_IMPLICIT + + +% --------------------------- CONVERGENCE PARAMETERS --------------------------% +% +CONV_FIELD= MOMENT_X +CONV_STARTITER= 10 +CONV_CAUCHY_ELEMS= 100 +CONV_CAUCHY_EPS= 1E-6 + +% ------------------------- INPUT/OUTPUT INFORMATION --------------------------% +% +MESH_FILENAME= mesh.su2 +MESH_FORMAT= SU2 +SOLUTION_FILENAME= restart_flow +TABULAR_FORMAT= CSV +CONV_FILENAME= history_First +RESTART_FILENAME= restart_flow +VOLUME_FILENAME= flow +SURFACE_FILENAME= surface_flow +OUTPUT_WRT_FREQ= 100 +SCREEN_OUTPUT= (INNER_ITER, WALL_TIME, RMS_DENSITY, LIFT, DRAG, MOMENT_Z) +OUTPUT_FILES= (SURFACE_CGNS) +WRT_FORCES_BREAKDOWN= NO +VOLUME_OUTPUT= (COORDINATES) +HISTORY_OUTPUT= (ITER) diff --git a/TestCases/hybrid_regression.py b/TestCases/hybrid_regression.py index 801ca167f31..36450f79e35 100644 --- a/TestCases/hybrid_regression.py +++ b/TestCases/hybrid_regression.py @@ -436,7 +436,7 @@ def main(): cavity.cfg_dir = "moving_wall/cavity" cavity.cfg_file = "lam_cavity.cfg" cavity.test_iter = 25 - cavity.test_vals = [-5.627934, -0.164469, 0.052000, 2.547063] + cavity.test_vals = [-5.627868, -0.164404, 0.053310, 2.545839] test_list.append(cavity) # Spinning cylinder @@ -444,8 +444,8 @@ def main(): spinning_cylinder.cfg_dir = "moving_wall/spinning_cylinder" spinning_cylinder.cfg_file = "spinning_cylinder.cfg" spinning_cylinder.test_iter = 25 - spinning_cylinder.test_vals = [-8.001291, -2.607959, 1.501321, 1.488559] - spinning_cylinder.test_vals_aarch64 = [-8.001291, -2.607959, 1.501321, 1.488559] + spinning_cylinder.test_vals = [-8.006541, -2.609759, 1.495662, 1.486341] + spinning_cylinder.test_vals_aarch64 = [-8.006541, -2.609759, 1.495662, 1.486341] test_list.append(spinning_cylinder) ###################################### @@ -771,6 +771,7 @@ def main(): pywrapper_translating_naca0012.reference_file = "forces_0.csv.ref" pywrapper_translating_naca0012.reference_file_aarch64 = "forces_0_aarch64.csv.ref" pywrapper_translating_naca0012.test_file = "forces_0.csv" + pywrapper_translating_naca0012.tol_file_percent = 0.1 pywrapper_translating_naca0012.enabled_on_cpu_arch = ["x86_64"] pywrapper_translating_naca0012.enabled_with_tsan = False file_diff_list.append(pywrapper_translating_naca0012) @@ -784,6 +785,7 @@ def main(): pywrapper_updated_moving_frame_naca0012.reference_file = "forces_0.csv.ref" pywrapper_updated_moving_frame_naca0012.reference_file_aarch64 = "forces_0_aarch64.csv.ref" pywrapper_updated_moving_frame_naca0012.test_file = "forces_0.csv" + pywrapper_updated_moving_frame_naca0012.tol_file_percent = 0.1 pywrapper_updated_moving_frame_naca0012.enabled_on_cpu_arch = ["x86_64"] pywrapper_updated_moving_frame_naca0012.enabled_with_tsan = False file_diff_list.append(pywrapper_updated_moving_frame_naca0012) diff --git a/TestCases/hybrid_regression_AD.py b/TestCases/hybrid_regression_AD.py index a2243e14e24..dbaab977df3 100644 --- a/TestCases/hybrid_regression_AD.py +++ b/TestCases/hybrid_regression_AD.py @@ -238,11 +238,11 @@ def main(): pywrapper_FEA_AD_FlowLoad.cfg_dir = "py_wrapper/disc_adj_fea/flow_load_sens" pywrapper_FEA_AD_FlowLoad.cfg_file = "configAD_fem.cfg" pywrapper_FEA_AD_FlowLoad.test_iter = 100 - pywrapper_FEA_AD_FlowLoad.test_vals = [-0.131742, -0.553318, -0.000364, -0.003101] #last 4 columns + pywrapper_FEA_AD_FlowLoad.test_vals = [-0.131415, -0.551701, -0.000364, -0.003101] #last 4 columns pywrapper_FEA_AD_FlowLoad.test_vals_aarch64 = [-0.131745, -0.553214, -0.000364, -0.003101] pywrapper_FEA_AD_FlowLoad.command = TestCase.Command(exec = "python", param = "run_adjoint.py --parallel -f") pywrapper_FEA_AD_FlowLoad.timeout = 1600 - pywrapper_FEA_AD_FlowLoad.tol = 1e-4 + pywrapper_FEA_AD_FlowLoad.tol = 1e-2 pywrapper_FEA_AD_FlowLoad.new_output = False pywrapper_FEA_AD_FlowLoad.enabled_with_tsan = False test_list.append(pywrapper_FEA_AD_FlowLoad) @@ -253,11 +253,11 @@ def main(): pywrapper_CFD_AD_MeshDisp.cfg_dir = "py_wrapper/disc_adj_flow/mesh_disp_sens" pywrapper_CFD_AD_MeshDisp.cfg_file = "configAD_flow.cfg" pywrapper_CFD_AD_MeshDisp.test_iter = 1000 - pywrapper_CFD_AD_MeshDisp.test_vals = [30.000000, -2.520967, 1.375188, 0.000000] #last 4 columns + pywrapper_CFD_AD_MeshDisp.test_vals = [30.000000, -2.521422, 1.372295, 0.000000] #last 4 columns pywrapper_CFD_AD_MeshDisp.test_vals_aarch64 = [30.000000, -2.516536, 1.386443, 0.000000] pywrapper_CFD_AD_MeshDisp.command = TestCase.Command(exec = "python", param = "run_adjoint.py --parallel -f") pywrapper_CFD_AD_MeshDisp.timeout = 1600 - pywrapper_CFD_AD_MeshDisp.tol = 1e-4 + pywrapper_CFD_AD_MeshDisp.tol = 1e-2 pywrapper_CFD_AD_MeshDisp.new_output = False pywrapper_CFD_AD_MeshDisp.enabled_with_tsan = False test_list.append(pywrapper_CFD_AD_MeshDisp) diff --git a/TestCases/parallel_regression.py b/TestCases/parallel_regression.py index f26049592b8..c6e6edf30d5 100644 --- a/TestCases/parallel_regression.py +++ b/TestCases/parallel_regression.py @@ -486,6 +486,16 @@ def main(): propeller.timeout = 3200 test_list.append(propeller) + # Actuator disk BEM method for propeller + actuatordisk_bem = TestCase('actuatordisk_bem') + actuatordisk_bem.cfg_dir = "rans/actuatordisk_bem" + actuatordisk_bem.cfg_file = "actuatordisk_bem.cfg" + actuatordisk_bem.test_iter = 15 + actuatordisk_bem.test_vals = [-5.282249, -10.335140, 0.001383, -0.375718] + actuatordisk_bem.timeout = 3200 + actuatordisk_bem.tol = 0.001 + test_list.append(actuatordisk_bem) + ####################################### ### Axisymmetric Compressible RANS ### ####################################### @@ -915,7 +925,7 @@ def main(): cavity.cfg_dir = "moving_wall/cavity" cavity.cfg_file = "lam_cavity.cfg" cavity.test_iter = 25 - cavity.test_vals = [-5.611007, -0.146826, 1.113206, 1.491678] + cavity.test_vals = [-5.610928, -0.146749, 1.114461, 1.490381] test_list.append(cavity) # Spinning cylinder @@ -923,7 +933,7 @@ def main(): spinning_cylinder.cfg_dir = "moving_wall/spinning_cylinder" spinning_cylinder.cfg_file = "spinning_cylinder.cfg" spinning_cylinder.test_iter = 25 - spinning_cylinder.test_vals = [-7.802803, -2.362844, 1.687705, 1.519676] + spinning_cylinder.test_vals = [-7.806016, -2.364954, 1.683365, 1.517059] test_list.append(spinning_cylinder) ###################################### @@ -1545,6 +1555,20 @@ def main(): species3_multizone_restart.multizone = True test_list.append(species3_multizone_restart) + ##################### + ## CGNS writer ### + ##################### + + # CGNS writer + cgns_writer = TestCase('cgns_writer') + cgns_writer.cfg_dir = "cgns_writer" + cgns_writer.cfg_file = "config.cfg" + cgns_writer.test_iter = 1 + cgns_writer.test_vals = [-2.974473, 0.665204, 5.068846, -7.003873] + cgns_writer.command = TestCase.Command("mpirun -n 2", "SU2_CFD") + cgns_writer.new_output = True + test_list.append(cgns_writer) + ###################################### ### RUN TESTS ### ###################################### diff --git a/TestCases/py_wrapper/rotating_cylinder/run.py b/TestCases/py_wrapper/rotating_cylinder/run.py new file mode 100644 index 00000000000..537cdcb696e --- /dev/null +++ b/TestCases/py_wrapper/rotating_cylinder/run.py @@ -0,0 +1,19 @@ +import pysu2 # imports the SU2 wrapped module +from mpi4py import MPI +import numpy as np + +comm = MPI.COMM_WORLD +rank = comm.Get_rank() +rotation_vector = np.linspace(0,20,10) +SU2Driver = pysu2.CSinglezoneDriver("spinning_cylinder.cfg",1, comm) + +for i, rate in enumerate(rotation_vector): + SU2Driver.SetMarkerRotationRate(0,0,0,rate) + SU2Driver.Preprocess(i) + SU2Driver.Run() + SU2Driver.Postprocess() + SU2Driver.Output(i) + SU2Driver.Update() +SU2Driver.Finalize() + + \ No newline at end of file diff --git a/TestCases/py_wrapper/rotating_cylinder/spinning_cylinder.cfg b/TestCases/py_wrapper/rotating_cylinder/spinning_cylinder.cfg new file mode 100644 index 00000000000..194a46064dd --- /dev/null +++ b/TestCases/py_wrapper/rotating_cylinder/spinning_cylinder.cfg @@ -0,0 +1,115 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% SU2 configuration file % +% Case description: Laminar flow around a spinning cylinder % +% Author: Thomas D. Economon % +% Institution: Stanford University % +% Date: 2013.08.21 % +% File Version 7.5.1 "Blackbird" % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% ------------- DIRECT, ADJOINT, AND LINEARIZED PROBLEM DEFINITION ------------% +% +SOLVER= NAVIER_STOKES +KIND_TURB_MODEL= NONE +MATH_PROBLEM= DIRECT +RESTART_SOL= NO + +% ----------- COMPRESSIBLE AND INCOMPRESSIBLE FREE-STREAM DEFINITION ----------% +% +MACH_NUMBER= 0.1 +AOA= 0.0 +SIDESLIP_ANGLE= 0.0 +FREESTREAM_TEMPERATURE= 288.15 +REYNOLDS_NUMBER= 200.0 +REYNOLDS_LENGTH= 1.0 + +% ----------------------- DYNAMIC MESH DEFINITION -----------------------------% +% +SURFACE_MOVEMENT= MOVING_WALL +MACH_MOTION= 0.1 +MARKER_MOVING= ( cylinder ) +SURFACE_MOTION_ORIGIN= 0.5 0.0 0.0 +SURFACE_ROTATION_RATE = 0.0 0.0 -199.0738 + +% ---------------------- REFERENCE VALUE DEFINITION ---------------------------% +% +REF_ORIGIN_MOMENT_X = 0.00 +REF_ORIGIN_MOMENT_Y = 0.00 +REF_ORIGIN_MOMENT_Z = 0.00 +REF_LENGTH= 1.0 +REF_AREA= 1.0 + +% -------------------- BOUNDARY CONDITION DEFINITION --------------------------% +% +MARKER_HEATFLUX= ( cylinder, 0.0 ) +MARKER_FAR= ( farfield ) +MARKER_PLOTTING= ( cylinder ) +MARKER_MONITORING= ( cylinder ) + +% ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% +% +NUM_METHOD_GRAD= WEIGHTED_LEAST_SQUARES +CFL_NUMBER= 100.0 +CFL_ADAPT= NO +CFL_ADAPT_PARAM= ( 1.5, 0.5, 1.0, 100.0 ) +ITER= 99999 + +% ----------------------- SLOPE LIMITER DEFINITION ----------------------------% +% +VENKAT_LIMITER_COEFF= 0.03 +ADJ_SHARP_LIMITER_COEFF= 3.0 +REF_SHARP_EDGES= 3.0 +SENS_REMOVE_SHARP= NO + +% ------------------------ LINEAR SOLVER DEFINITION ---------------------------% +% +LINEAR_SOLVER= FGMRES +LINEAR_SOLVER_PREC= LU_SGS +LINEAR_SOLVER_ERROR= 1E-4 +LINEAR_SOLVER_ITER= 5 + +% -------------------------- MULTIGRID PARAMETERS -----------------------------% +% +MGLEVEL= 3 +MGCYCLE= V_CYCLE +MG_PRE_SMOOTH= ( 1, 1, 1, 1 ) +MG_POST_SMOOTH= ( 0, 0, 0, 0 ) +MG_CORRECTION_SMOOTH= ( 0, 0, 0, 0 ) +MG_DAMP_RESTRICTION= 0.5 +MG_DAMP_PROLONGATION= 0.5 + +% -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% +% +CONV_NUM_METHOD_FLOW= ROE +MUSCL_FLOW= YES +SLOPE_LIMITER_FLOW= NONE +JST_SENSOR_COEFF= ( 0.5, 0.02 ) +TIME_DISCRE_FLOW= EULER_IMPLICIT + +% --------------------------- CONVERGENCE PARAMETERS --------------------------% +% +CONV_RESIDUAL_MINVAL= -15 +CONV_STARTITER= 10 +CONV_CAUCHY_ELEMS= 100 +CONV_CAUCHY_EPS= 1E-7 + +% ------------------------- INPUT/OUTPUT INFORMATION --------------------------% +% +MESH_FILENAME= mesh_cylinder_lam.su2 +MESH_FORMAT= SU2 +MESH_OUT_FILENAME= mesh_out.su2 +SOLUTION_FILENAME= solution_flow.dat +SOLUTION_ADJ_FILENAME= solution_adj.dat +TABULAR_FORMAT= CSV +CONV_FILENAME= history +RESTART_FILENAME= restart_flow.dat +RESTART_ADJ_FILENAME= restart_adj.dat +VOLUME_FILENAME= flow +VOLUME_ADJ_FILENAME= adjoint +GRAD_OBJFUNC_FILENAME= of_grad.dat +SURFACE_FILENAME= surface_flow +SURFACE_ADJ_FILENAME= surface_adjoint +OUTPUT_WRT_FREQ= 100 +SCREEN_OUTPUT= (INNER_ITER, RMS_DENSITY, RMS_ENERGY, LIFT, DRAG) diff --git a/TestCases/rans/actuatordisk_bem/actuatordisk_bem.cfg b/TestCases/rans/actuatordisk_bem/actuatordisk_bem.cfg new file mode 100644 index 00000000000..cb74bf56621 --- /dev/null +++ b/TestCases/rans/actuatordisk_bem/actuatordisk_bem.cfg @@ -0,0 +1,122 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% SU2 configuration file % +% Case description: Actuator Disk - Blade Element Method % +% Author: Y Chandukrishna, Josy Poulose Pullockara, T N Venkatesh % +% Institution: Computational and Theoretical Fluid Dynamics (CTFD), % +% CSIR - National Aerospace Laboratories, Bangalore % +% Academy of Scientific and Innovative Research, Ghaziabad % +% Comments : % +% Date: 23/09/2023 % +% File Version 8.0.0 "Harrier" % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%----------- DIRECT, ADJOINT, AND LINEARIZED PROBLEM DEFINITION -------------------------% +SOLVER= RANS +KIND_TURB_MODEL= SA +%FREESTREAM_TURBULENCEINTENSITY=0.01 +MATH_PROBLEM= DIRECT +RESTART_SOL= YES +SYSTEM_MEASUREMENTS= SI + +% -------------------- COMPRESSIBLE FREE-STREAM DEFINITION --------------------% +MACH_NUMBER= 0.11617164 +AOA= 0.0 +SIDESLIP_ANGLE= 0.0 +REYNOLDS_NUMBER= 0.62E6 +REYNOLDS_LENGTH= 0.237 +FREESTREAM_TEMPERATURE= 295 +VISCOSITY_MODEL= CONSTANT_VISCOSITY +MU_CONSTANT= 1.84554E-5 +MU_REF= 1.716E-5 +MU_T_REF= 273.15 +SUTHERLAND_CONSTANT= 110.4 + +% ---------------------- REFERENCE VALUE DEFINITION ---------------------------% +% +REF_ORIGIN_MOMENT_X = 0.0 +REF_ORIGIN_MOMENT_Y = 0.0 +REF_ORIGIN_MOMENT_Z = 0.0 +REF_LENGTH= 1.0 +REF_AREA= 0.04411429 +REF_DIMENSIONALIZATION= DIMENSIONAL + +% --------------- ENGINE AND ACTUATOR DISK SIMULATION -------------------------% +% +HIGHLITE_AREA= 0.04411429 +ENGINE_NU_FACTOR= 0.0 + +% -------------------- BOUNDARY CONDITION DEFINITION --------------------------% +% +ACTDISK_DOUBLE_SURFACE = YES +ACTDISK_TYPE= BLADE_ELEMENT +ACTDISK_JUMP= DIFFERENCE +MARKER_ACTDISK = ( ACTDISK_IN, ACTDISK_OUT , 0.0, 0.0, 12715.2, 0.0, 0.0, 12715.2) +MARKER_ACTDISK_BEM_CG= ( ACTDISK_IN, ACTDISK_OUT, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ) +MARKER_ACTDISK_BEM_AXIS= ( ACTDISK_IN, ACTDISK_OUT, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 ) +BEM_PROP_FILENAME = prop_geom_alfclcd_data.txt +BEM_PROP_BLADE_ANGLE = 23.9 +BEM_FREQ = 40 +MARKER_FAR= ( Farfield ) + +% ------------------------ SURFACES IDENTIFICATION ----------------------------% +% +MARKER_PLOTTING = ( ACTDISK_IN, ACTDISK_OUT ) +MARKER_MONITORING = ( ACTDISK_IN, ACTDISK_OUT ) +MARKER_ANALYZE = ( ACTDISK_IN, ACTDISK_OUT ) +MARKER_ANALYZE_AVERAGE = MASSFLUX + +% ------------- COMMON PARAMETERS DEFINING THE NUMERICAL METHOD ---------------% +% +NUM_METHOD_GRAD= WEIGHTED_LEAST_SQUARES +CFL_NUMBER= 4.0 +CFL_ADAPT= NO +OBJECTIVE_FUNCTION= DRAG + +% ------------------------ LINEAR SOLVER DEFINITION ---------------------------% +% +LINEAR_SOLVER= FGMRES +LINEAR_SOLVER_PREC= ILU +LINEAR_SOLVER_ERROR= 1E-12 +LINEAR_SOLVER_ITER= 3 +CONV_CAUCHY_ELEMS= 1000 +CONV_CAUCHY_EPS= 1E-10 + +% -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% +% +CONV_NUM_METHOD_FLOW= ROE +MUSCL_FLOW= YES +TIME_DISCRE_FLOW= EULER_IMPLICIT + +% -------------------- TURBULENT NUMERICAL METHOD DEFINITION ------------------% +% +CONV_NUM_METHOD_TURB= SCALAR_UPWIND +MUSCL_TURB= NO +SLOPE_LIMITER_TURB= VENKATAKRISHNAN +TIME_DISCRE_TURB= EULER_IMPLICIT + +% --------------------------- CONVERGENCE PARAMETERS --------------------------% +% +ITER= 2000 +CONV_RESIDUAL_MINVAL= -8 +CONV_STARTITER= 10 + +% ------------------------- INPUT/OUTPUT INFORMATION --------------------------% +% +MESH_FILENAME= actuatordisk_bem.su2 +MESH_FORMAT= SU2 +MESH_OUT_FILENAME= mesh_out.su2 +SOLUTION_FILENAME= actuatordisk_bem.dat +TABULAR_FORMAT= CSV +CONV_FILENAME= history_actuatordisk_bem +OUTPUT_FILES= (RESTART, PARAVIEW, SURFACE_PARAVIEW) +WRT_FORCES_BREAKDOWN= YES +BREAKDOWN_FILENAME= forces_breakdown_actuatordisk_bem.dat +RESTART_FILENAME= restart_flow_actuatordisk_bem.dat +VOLUME_FILENAME= flow_actuatordisk_bem +SURFACE_FILENAME= surface_flow_actuatordisk_bem +OUTPUT_WRT_FREQ= 500 +%SCREEN_OUTPUT= (INNER_ITER, WALL_TIME, RMS_DENSITY, RMS_NU_TILDE, NONPHYSICAL_POINTS, LIFT, DRAG) +SCREEN_OUTPUT= (INNER_ITER, RMS_DENSITY, RMS_NU_TILDE, LIFT, DRAG) +HISTORY_OUTPUT= (INNER_ITER, RMS_RES, LIFT, DRAG, AERO_COEFF) diff --git a/TestCases/rans/actuatordisk_bem/prop_geom_alfclcd_data.txt b/TestCases/rans/actuatordisk_bem/prop_geom_alfclcd_data.txt new file mode 100644 index 00000000000..8ee50cc1728 --- /dev/null +++ b/TestCases/rans/actuatordisk_bem/prop_geom_alfclcd_data.txt @@ -0,0 +1,558 @@ +# Geometric parameters of propeller +4 : number of blades +0.237 : diameter (m) +0.01754 : radius of hub (m) +23.9 : angle at 75% radius, has to be consistent with section data +# Nsection, Nalf + 22 23 +#section,radius,chord,set angle +1 0.029625 0.011802 39.738358 +2 0.035550 0.013272 36.824936 +3 0.041475 0.014546 34.978134 +4 0.047400 0.016093 33.867138 +5 0.053325 0.017495 32.648598 +6 0.056288 0.018061 31.824940 +7 0.059250 0.018628 30.987774 +8 0.065175 0.019253 29.155754 +9 0.068137 0.019335 28.223461 +10 0.071100 0.019398 27.291164 +11 0.077025 0.019398 26.051857 +12 0.079988 0.019224 25.441435 +13 0.082950 0.019038 24.831013 +14 0.088875 0.018572 23.900000 +15 0.091837 0.018218 23.311188 +16 0.094800 0.017864 22.824017 +17 0.100725 0.016862 21.970278 +18 0.103688 0.016231 21.604017 +19 0.106650 0.015600 21.237759 +20 0.109613 0.014859 20.871506 +21 0.112575 0.014110 20.506992 +22 0.115538 0.011545 20.322815 +#Sec_1, alpha,cl,cd +-15.00 -0.42201 0.14538 +-10.00 -0.47384 0.03066 +-7.000 -0.31633 0.02323 +-5.000 -0.17261 0.02101 +-2.000 0.062180 0.02041 +0.0000 0.217500 0.02160 +2.0000 0.362500 0.02415 +5.0000 0.545000 0.03092 +8.0000 0.663400 0.04315 +10.000 0.715250 0.05540 +12.000 0.772350 0.07025 +15.000 0.846930 0.09997 +17.000 0.793240 0.14274 +20.000 0.741380 0.21541 +25.000 0.809181 0.31423 +30.000 0.799410 0.45780 +35.000 0.842714 0.58514 +40.000 0.859940 0.72557 +50.000 0.842806 1.01662 +60.000 0.753790 1.27954 +70.000 0.581530 1.49396 +80.000 0.346121 1.63350 +90.000 0.074679 1.67220 +#Sec_2, alpha,cl,cd +-15.00 -0.42201 0.14538 +-10.00 -0.47384 0.03066 +-7.000 -0.31633 0.02323 +-5.000 -0.17261 0.02101 +-2.000 0.062180 0.02041 +0.0000 0.217500 0.02160 +2.0000 0.362500 0.02415 +5.0000 0.545000 0.03092 +8.0000 0.663400 0.04315 +10.000 0.715250 0.05540 +12.000 0.772350 0.07025 +15.000 0.846930 0.09997 +17.000 0.793240 0.14274 +20.000 0.741380 0.21541 +25.000 0.809181 0.31423 +30.000 0.799410 0.45780 +35.000 0.842714 0.58514 +40.000 0.859940 0.72557 +50.000 0.842806 1.01662 +60.000 0.753790 1.27954 +70.000 0.581530 1.49396 +80.000 0.346121 1.63350 +90.000 0.074679 1.67220 +#Sec_3, alpha,cl,cd +-15.00 -0.42201 0.14538 +-10.00 -0.47384 0.03066 +-7.000 -0.31633 0.02323 +-5.000 -0.17261 0.02101 +-2.000 0.062180 0.02041 +0.0000 0.217500 0.02160 +2.0000 0.362500 0.02415 +5.0000 0.545000 0.03092 +8.0000 0.663400 0.04315 +10.000 0.715250 0.05540 +12.000 0.772350 0.07025 +15.000 0.846930 0.09997 +17.000 0.793240 0.14274 +20.000 0.741380 0.21541 +25.000 0.809181 0.31423 +30.000 0.799410 0.45780 +35.000 0.842714 0.58514 +40.000 0.859940 0.72557 +50.000 0.842806 1.01662 +60.000 0.753790 1.27954 +70.000 0.581530 1.49396 +80.000 0.346121 1.63350 +90.000 0.074679 1.67220 +#Sec_4, alpha,cl,cd +-15.00 -0.42201 0.14538 +-10.00 -0.47384 0.03066 +-7.000 -0.31633 0.02323 +-5.000 -0.17261 0.02101 +-2.000 0.062180 0.02041 +0.0000 0.217500 0.02160 +2.0000 0.362500 0.02415 +5.0000 0.545000 0.03092 +8.0000 0.663400 0.04315 +10.000 0.715250 0.05540 +12.000 0.772350 0.07025 +15.000 0.846930 0.09997 +17.000 0.793240 0.14274 +20.000 0.741380 0.21541 +25.000 0.809181 0.31423 +30.000 0.799410 0.45780 +35.000 0.842714 0.58514 +40.000 0.859940 0.72557 +50.000 0.842806 1.01662 +60.000 0.753790 1.27954 +70.000 0.581530 1.49396 +80.000 0.346121 1.63350 +90.000 0.074679 1.67220 +#Sec_5, alpha,cl,cd +-15.00 -0.42201 0.14538 +-10.00 -0.47384 0.03066 +-7.000 -0.31633 0.02323 +-5.000 -0.17261 0.02101 +-2.000 0.062180 0.02041 +0.0000 0.217500 0.02160 +2.0000 0.362500 0.02415 +5.0000 0.545000 0.03092 +8.0000 0.663400 0.04315 +10.000 0.715250 0.05540 +12.000 0.772350 0.07025 +15.000 0.846930 0.09997 +17.000 0.793240 0.14274 +20.000 0.741380 0.21541 +25.000 0.809181 0.31423 +30.000 0.799410 0.45780 +35.000 0.842714 0.58514 +40.000 0.859940 0.72557 +50.000 0.842806 1.01662 +60.000 0.753790 1.27954 +70.000 0.581530 1.49396 +80.000 0.346121 1.63350 +90.000 0.074679 1.67220 +#Sec_6,alpha,cl,cd +-15.00 -0.38500 0.18600 +-10.00 -0.39240 0.08201 +-7.000 -0.34387 0.02873 +-5.000 -0.16518 0.02386 +-2.000 0.119372 0.02119 +0.0000 0.311530 0.02133 +2.0000 0.500006 0.02276 +5.0000 0.767233 0.02742 +8.0000 0.997630 0.03621 +10.000 1.114230 0.04588 +12.000 1.181340 0.06145 +15.000 1.152260 0.10511 +17.000 1.004230 0.16952 +20.000 0.920632 0.26388 +25.000 0.932029 0.40397 +30.000 0.956910 0.54778 +35.000 0.974480 0.71086 +40.000 0.990417 0.86521 +50.000 0.953389 1.17309 +60.000 0.823469 1.46302 +70.000 0.606730 1.70462 +80.000 0.320770 1.86131 +90.000 -0.00218 1.90357 +#Sec_7,alpha,cl,cd +-15.00 -0.38500 0.18600 +-10.00 -0.39240 0.08201 +-7.000 -0.34387 0.02873 +-5.000 -0.16518 0.02386 +-2.000 0.119372 0.02119 +0.0000 0.311530 0.02133 +2.0000 0.500006 0.02276 +5.0000 0.767233 0.02742 +8.0000 0.997630 0.03621 +10.000 1.114230 0.04588 +12.000 1.181340 0.06145 +15.000 1.152260 0.10511 +17.000 1.004230 0.16952 +20.000 0.920632 0.26388 +25.000 0.932029 0.40397 +30.000 0.956910 0.54778 +35.000 0.974480 0.71086 +40.000 0.990417 0.86521 +50.000 0.953389 1.17309 +60.000 0.823469 1.46302 +70.000 0.606730 1.70462 +80.000 0.320770 1.86131 +90.000 -0.00218 1.90357 +#Sec_8,alpha,cl,cd +-15.00 -0.38500 0.18600 +-10.00 -0.39240 0.08201 +-7.000 -0.34387 0.02873 +-5.000 -0.16518 0.02386 +-2.000 0.119372 0.02119 +0.0000 0.311530 0.02133 +2.0000 0.500006 0.02276 +5.0000 0.767233 0.02742 +8.0000 0.997630 0.03621 +10.000 1.114230 0.04588 +12.000 1.181340 0.06145 +15.000 1.152260 0.10511 +17.000 1.004230 0.16952 +20.000 0.920632 0.26388 +25.000 0.932029 0.40397 +30.000 0.956910 0.54778 +35.000 0.974480 0.71086 +40.000 0.990417 0.86521 +50.000 0.953389 1.17309 +60.000 0.823469 1.46302 +70.000 0.606730 1.70462 +80.000 0.320770 1.86131 +90.000 -0.00218 1.90357 +#Sec_9,alpha,cl,cd +-15.00 -0.38500 0.18600 +-10.00 -0.39240 0.08201 +-7.000 -0.34387 0.02873 +-5.000 -0.16518 0.02386 +-2.000 0.119372 0.02119 +0.0000 0.311530 0.02133 +2.0000 0.500006 0.02276 +5.0000 0.767233 0.02742 +8.0000 0.997630 0.03621 +10.000 1.114230 0.04588 +12.000 1.181340 0.06145 +15.000 1.152260 0.10511 +17.000 1.004230 0.16952 +20.000 0.920632 0.26388 +25.000 0.932029 0.40397 +30.000 0.956910 0.54778 +35.000 0.974480 0.71086 +40.000 0.990417 0.86521 +50.000 0.953389 1.17309 +60.000 0.823469 1.46302 +70.000 0.606730 1.70462 +80.000 0.320770 1.86131 +90.000 -0.00218 1.90357 +#Sec_10,alpha,cl,cd +-15.00 -0.38500 0.18600 +-10.00 -0.39240 0.08201 +-7.000 -0.34387 0.02873 +-5.000 -0.16518 0.02386 +-2.000 0.119372 0.02119 +0.0000 0.311530 0.02133 +2.0000 0.500006 0.02276 +5.0000 0.767233 0.02742 +8.0000 0.997630 0.03621 +10.000 1.114230 0.04588 +12.000 1.181340 0.06145 +15.000 1.152260 0.10511 +17.000 1.004230 0.16952 +20.000 0.920632 0.26388 +25.000 0.932029 0.40397 +30.000 0.956910 0.54778 +35.000 0.974480 0.71086 +40.000 0.990417 0.86521 +50.000 0.953389 1.17309 +60.000 0.823469 1.46302 +70.000 0.606730 1.70462 +80.000 0.320770 1.86131 +90.000 -0.00218 1.90357 +#Sec_11,alpha,cl,cd +-15.00 -0.38500 0.18600 +-10.00 -0.39240 0.08201 +-7.000 -0.34387 0.02873 +-5.000 -0.16518 0.02386 +-2.000 0.119372 0.02119 +0.0000 0.311530 0.02133 +2.0000 0.500006 0.02276 +5.0000 0.767233 0.02742 +8.0000 0.997630 0.03621 +10.000 1.114230 0.04588 +12.000 1.181340 0.06145 +15.000 1.152260 0.10511 +17.000 1.004230 0.16952 +20.000 0.920632 0.26388 +25.000 0.932029 0.40397 +30.000 0.956910 0.54778 +35.000 0.974480 0.71086 +40.000 0.990417 0.86521 +50.000 0.953389 1.17309 +60.000 0.823469 1.46302 +70.000 0.606730 1.70462 +80.000 0.320770 1.86131 +90.000 -0.00218 1.90357 +#Sec_12,alpha,cl,cd +-15.00 -0.38500 0.18600 +-10.00 -0.39240 0.08201 +-7.000 -0.34387 0.02873 +-5.000 -0.16518 0.02386 +-2.000 0.119372 0.02119 +0.0000 0.311530 0.02133 +2.0000 0.500006 0.02276 +5.0000 0.767233 0.02742 +8.0000 0.997630 0.03621 +10.000 1.114230 0.04588 +12.000 1.181340 0.06145 +15.000 1.152260 0.10511 +17.000 1.004230 0.16952 +20.000 0.920632 0.26388 +25.000 0.932029 0.40397 +30.000 0.956910 0.54778 +35.000 0.974480 0.71086 +40.000 0.990417 0.86521 +50.000 0.953389 1.17309 +60.000 0.823469 1.46302 +70.000 0.606730 1.70462 +80.000 0.320770 1.86131 +90.000 -0.00218 1.90357 +#Sec_13,alpha,cl,cd +-15.00 -0.38500 0.18600 +-10.00 -0.39240 0.08201 +-7.000 -0.34387 0.02873 +-5.000 -0.16518 0.02386 +-2.000 0.119372 0.02119 +0.0000 0.311530 0.02133 +2.0000 0.500006 0.02276 +5.0000 0.767233 0.02742 +8.0000 0.997630 0.03621 +10.000 1.114230 0.04588 +12.000 1.181340 0.06145 +15.000 1.152260 0.10511 +17.000 1.004230 0.16952 +20.000 0.920632 0.26388 +25.000 0.932029 0.40397 +30.000 0.956910 0.54778 +35.000 0.974480 0.71086 +40.000 0.990417 0.86521 +50.000 0.953389 1.17309 +60.000 0.823469 1.46302 +70.000 0.606730 1.70462 +80.000 0.320770 1.86131 +90.000 -0.00218 1.90357 +#Sec_14,alpha,cl,cd +-15.00 -0.71025 0.250000 +-10.00 -0.62520 0.152360 +-7.000 -0.46165 0.067514 +-5.000 -0.31109 0.028340 +-2.000 0.002995 0.020170 +0.0000 0.209724 0.019035 +2.0000 0.420804 0.019842 +5.0000 0.726100 0.024640 +8.0000 1.005110 0.035811 +10.000 1.142203 0.051340 +12.000 1.071063 0.097789 +15.000 0.885860 0.219350 +17.000 0.917480 0.273890 +20.000 0.929127 0.350000 +25.000 0.982100 0.480000 +30.000 1.038380 0.614900 +35.000 1.072214 0.704314 +40.000 1.082084 0.920430 +50.000 1.032150 1.244025 +60.000 0.884800 1.549000 +70.000 0.652577 1.810174 +80.000 0.346247 1.982400 +90.000 -0.00090 2.034369 +#Sec_15,alpha,cl,cd +-15.00 -0.71025 0.250000 +-10.00 -0.62520 0.152360 +-7.000 -0.46165 0.067514 +-5.000 -0.31109 0.028340 +-2.000 0.002995 0.020170 +0.0000 0.209724 0.019035 +2.0000 0.420804 0.019842 +5.0000 0.726100 0.024640 +8.0000 1.005110 0.035811 +10.000 1.142203 0.051340 +12.000 1.071063 0.097789 +15.000 0.885860 0.219350 +17.000 0.917480 0.273890 +20.000 0.929127 0.350000 +25.000 0.982100 0.480000 +30.000 1.038380 0.614900 +35.000 1.072214 0.704314 +40.000 1.082084 0.920430 +50.000 1.032150 1.244025 +60.000 0.884800 1.549000 +70.000 0.652577 1.810174 +80.000 0.346247 1.982400 +90.000 -0.00090 2.034369 +#Sec_16,alpha,cl,cd +-15.00 -0.450235 0.123572 +-10.00 -0.509059 0.092961 +-7.000 -0.473475 0.068098 +-5.000 -0.311293 0.028335 +-2.000 -0.000500 0.020111 +0.0000 0.212258 0.019451 +2.0000 0.423786 0.020642 +5.0000 0.731349 0.026056 +8.0000 1.008821 0.038666 +10.000 1.135043 0.058155 +12.000 0.937040 0.138576 +15.000 0.964997 0.255187 +17.000 0.872200 0.324306 +20.000 0.857793 0.333029 +25.000 0.922114 0.460801 +30.000 1.045545 0.626256 +35.000 1.076223 0.775646 +40.000 1.084297 0.932095 +50.000 1.031466 1.254707 +60.000 0.883621 1.561348 +70.000 0.645650 1.814277 +80.000 0.337736 1.982865 +90.000 -0.00965 2.034968 +#Sec_17,alpha,cl,cd +-15.00 -0.450235 0.123572 +-10.00 -0.509059 0.092961 +-7.000 -0.473475 0.068098 +-5.000 -0.311293 0.028335 +-2.000 -0.000500 0.020111 +0.0000 0.212258 0.019451 +2.0000 0.423786 0.020642 +5.0000 0.731349 0.026056 +8.0000 1.008821 0.038666 +10.000 1.135043 0.058155 +12.000 0.937040 0.138576 +15.000 0.964997 0.255187 +17.000 0.872200 0.324306 +20.000 0.857793 0.333029 +25.000 0.922114 0.460801 +30.000 1.045545 0.626256 +35.000 1.076223 0.775646 +40.000 1.084297 0.932095 +50.000 1.031466 1.254707 +60.000 0.883621 1.561348 +70.000 0.645650 1.814277 +80.000 0.337736 1.982865 +90.000 -0.00965 2.034968 +#Sec_18,alpha,cl,cd +-15.00 -0.450235 0.123572 +-10.00 -0.509059 0.092961 +-7.000 -0.473475 0.068098 +-5.000 -0.311293 0.028335 +-2.000 -0.000500 0.020111 +0.0000 0.212258 0.019451 +2.0000 0.423786 0.020642 +5.0000 0.731349 0.026056 +8.0000 1.008821 0.038666 +10.000 1.135043 0.058155 +12.000 0.937040 0.138576 +15.000 0.964997 0.255187 +17.000 0.872200 0.324306 +20.000 0.857793 0.333029 +25.000 0.922114 0.460801 +30.000 1.045545 0.626256 +35.000 1.076223 0.775646 +40.000 1.084297 0.932095 +50.000 1.031466 1.254707 +60.000 0.883621 1.561348 +70.000 0.645650 1.814277 +80.000 0.337736 1.982865 +90.000 -0.00965 2.034968 +#Sec_19,alpha,cl,cd +-15.00 -0.624154 0.154154 +-10.00 -0.538409 0.080512 +-7.000 -0.481732 0.075544 +-5.000 -0.313564 0.031177 +-2.000 -0.002507 0.018085 +0.0000 0.210838 0.016733 +2.0000 0.422316 0.017475 +5.0000 0.727235 0.022779 +8.0000 0.990487 0.038041 +10.000 1.023327 0.079155 +12.000 1.014323 0.123481 +15.000 1.002321 0.213523 +17.000 0.965321 0.261254 +20.000 0.942346 0.312364 +25.000 0.925641 0.375215 +30.000 1.056059 0.616220 +35.000 1.086160 0.764234 +40.000 1.097267 0.923027 +50.000 1.046694 1.250085 +60.000 0.903101 1.564407 +70.000 0.665977 1.821230 +80.000 0.357959 1.994476 +90.000 0.008920 2.053167 +#Sec_20,alpha,cl,cd +-15.00 -0.624154 0.154154 +-10.00 -0.538409 0.080512 +-7.000 -0.481732 0.075544 +-5.000 -0.313564 0.031177 +-2.000 -0.002507 0.018085 +0.0000 0.210838 0.016733 +2.0000 0.422316 0.017475 +5.0000 0.727235 0.022779 +8.0000 0.990487 0.038041 +10.000 1.023327 0.079155 +12.000 1.014323 0.123481 +15.000 1.002321 0.213523 +17.000 0.965321 0.261254 +20.000 0.942346 0.312364 +25.000 0.925641 0.375215 +30.000 1.056059 0.616220 +35.000 1.086160 0.764234 +40.000 1.097267 0.923027 +50.000 1.046694 1.250085 +60.000 0.903101 1.564407 +70.000 0.665977 1.821230 +80.000 0.357959 1.994476 +90.000 0.008920 2.053167 +#Sec_21,alpha,cl,cd +-15.00 -0.624154 0.154154 +-10.00 -0.538409 0.080512 +-7.000 -0.481732 0.075544 +-5.000 -0.313564 0.031177 +-2.000 -0.002507 0.018085 +0.0000 0.210838 0.016733 +2.0000 0.422316 0.017475 +5.0000 0.727235 0.022779 +8.0000 0.990487 0.038041 +10.000 1.023327 0.079155 +12.000 1.014323 0.123481 +15.000 1.002321 0.213523 +17.000 0.965321 0.261254 +20.000 0.942346 0.312364 +25.000 0.925641 0.375215 +30.000 1.056059 0.616220 +35.000 1.086160 0.764234 +40.000 1.097267 0.923027 +50.000 1.046694 1.250085 +60.000 0.903101 1.564407 +70.000 0.665977 1.821230 +80.000 0.357959 1.994476 +90.000 0.008920 2.053167 +#Sec_22,alpha,cl,cd +-15.00 -0.624154 0.154154 +-10.00 -0.538409 0.080512 +-7.000 -0.481732 0.075544 +-5.000 -0.313564 0.031177 +-2.000 -0.002507 0.018085 +0.0000 0.210838 0.016733 +2.0000 0.422316 0.017475 +5.0000 0.727235 0.022779 +8.0000 0.990487 0.038041 +10.000 1.023327 0.079155 +12.000 1.014323 0.123481 +15.000 1.002321 0.213523 +17.000 0.965321 0.261254 +20.000 0.942346 0.312364 +25.000 0.925641 0.375215 +30.000 1.056059 0.616220 +35.000 1.086160 0.764234 +40.000 1.097267 0.923027 +50.000 1.046694 1.250085 +60.000 0.903101 1.564407 +70.000 0.665977 1.821230 +80.000 0.357959 1.994476 +90.000 0.008920 2.053167 diff --git a/TestCases/rans/actuatordisk_bem/readme.txt b/TestCases/rans/actuatordisk_bem/readme.txt new file mode 100644 index 00000000000..58d2abceca3 --- /dev/null +++ b/TestCases/rans/actuatordisk_bem/readme.txt @@ -0,0 +1,16 @@ +Propeller data provided as the test case here is the propeller used in the studies of Sinnige et al. 2018 in their experimental studies. Isolated propeller geometry as .stp file and experimental results (J vs CT, J vs CP) are provided as supplementary materials along with the publication. + +The current test case corresponds to the four bladed propeller of diameter 0.237m in a freestream velocity (Vinf) of 40m/s, advance ratio of J=0.8, propeller blade angle at 0.75R is 23.9 degrees. + +The experimental thrust and power (Non-Dimensional) at J ~ 0.8 are as follows: + +J=Vinf/nD CT=Thrust/rho*n2*D4 CP=Power/rho*n3*D5 +0.7963 0.0953 0.1025 + +The dimensional values are Thrust = 16.30 N and Torque = 0.6612 N-m. + +Reference: +----------- +Sinnige, T., van Arnhem, N., Stokkermans, T. C. A., Eitelberg, G., Veldhuis, L. L. M., ``Wingtip-Mounted + Propellers: Aerodynamic Analysis of Interaction Effects and Comparison with Conventional Layout,'' + Journal of Aircraft, 2018. diff --git a/TestCases/serial_regression.py b/TestCases/serial_regression.py index a8486bc11ea..a6e5302fae6 100644 --- a/TestCases/serial_regression.py +++ b/TestCases/serial_regression.py @@ -750,7 +750,7 @@ def main(): cavity.cfg_dir = "moving_wall/cavity" cavity.cfg_file = "lam_cavity.cfg" cavity.test_iter = 25 - cavity.test_vals = [-5.627934, -0.164470, 0.051972, 2.547039] + cavity.test_vals = [ -5.627868, -0.164405, 0.053283, 2.545817] test_list.append(cavity) # Spinning cylinder @@ -758,7 +758,7 @@ def main(): spinning_cylinder.cfg_dir = "moving_wall/spinning_cylinder" spinning_cylinder.cfg_file = "spinning_cylinder.cfg" spinning_cylinder.test_iter = 25 - spinning_cylinder.test_vals = [-7.889994, -2.469385, 1.708162, 1.670039] + spinning_cylinder.test_vals = [-7.892807, -2.467378, 1.702819, 1.669208] test_list.append(spinning_cylinder) ###################################### @@ -1066,7 +1066,9 @@ def main(): airfoilRBF.cfg_dir = "fea_fsi/Airfoil_RBF" airfoilRBF.cfg_file = "config.cfg" airfoilRBF.test_iter = 1 - airfoilRBF.test_vals = [1.000000, -2.786183, -4.977959] + + airfoilRBF.test_vals = [1.000000, -2.786186, -4.977944] + airfoilRBF.tol = 0.0001 airfoilRBF.multizone = True test_list.append(airfoilRBF) diff --git a/config_template.cfg b/config_template.cfg index 811df18a014..ea621b85e7e 100644 --- a/config_template.cfg +++ b/config_template.cfg @@ -29,6 +29,10 @@ SA_OPTIONS= NONE % % Transition model (NONE, LM) KIND_TRANS_MODEL= NONE +% +% Value of RMS roughness for transition model +HROUGHNESS= 1.0e-6 +% % Specify versions/correlations of the LM model (LM2015, MALAN, SULUKSNA, KRAUSE, KRAUSE_HYPER, MEDIDA, MEDIDA_BAEDER, MENTER_LANGTRY) LM_OPTIONS= NONE % @@ -50,6 +54,9 @@ MATH_PROBLEM= DIRECT % Axisymmetric simulation, only compressible flows (NO, YES) AXISYMMETRIC= NO % +% Gravity force +GRAVITY_FORCE= NO +% % Restart solution (NO, YES) RESTART_SOL= NO % @@ -146,6 +153,9 @@ WINDOW_START_ITER = 500 % Window used for reverse sweep and direct run. Options (SQUARE, HANN, HANN_SQUARE, BUMP) Square is default. WINDOW_FUNCTION = SQUARE % +% Starting direct solver iteration for the unsteady adjoint +UNST_ADJOINT_ITER= 0 +% % ------------------------------- DES Parameters ------------------------------% % % Specify Hybrid RANS/LES model (SA_DES, SA_DDES, SA_ZDES, SA_EDDES) @@ -200,6 +210,9 @@ FREESTREAM_VISCOSITY= 1.853E-5 % Free-stream turbulence intensity FREESTREAM_TURBULENCEINTENSITY= 0.05 % +% Value for freestream intermittency +FREESTREAM_INTERMITTENCY= 1.0 +% % Fix turbulence quantities to far-field values inside an upstream half-space TURB_FIXED_VALUES= NO % @@ -260,6 +273,9 @@ INC_INLET_TYPE= VELOCITY_INLET % Damping coefficient for iterative updates at pressure inlets. (0.1 by default) INC_INLET_DAMPING= 0.1 % +% Impose inlet velocity magnitude in the direction of the normal of the inlet face +INC_INLET_USENORMAL= NO +% % List of outlet types for incompressible flows. List length must % match number of outlet markers. Options: PRESSURE_OUTLET, MASS_FLOW_OUTLET INC_OUTLET_TYPE= PRESSURE_OUTLET @@ -267,6 +283,8 @@ INC_OUTLET_TYPE= PRESSURE_OUTLET % Damping coefficient for iterative updates at mass flow outlets. (0.1 by default) INC_OUTLET_DAMPING= 0.1 % +% Bulk Modulus for computing the Mach number +BULK_MODULUS= 1.42E5 % Epsilon^2 multipier in Beta calculation for incompressible preconditioner. BETA_FACTOR= 4.1 % @@ -295,8 +313,29 @@ DCL_DALPHA= 0.2 % Maximum number of iterations between AoA updates UPDATE_AOA_ITER_LIMIT= 100 % +% Number of times Alpha is updated in a fix CL problem. +UPDATE_IH= 5 +% % Number of iterations to evaluate dCL_dAlpha by using finite differences (500 by default) ITER_DCL_DALPHA= 500 +% +% Evaluate the dOF_dCL or dOF_dCMy during run time +EVAL_DOF_DCX= NO +% +% Damping factor for thrust BC (actuator disk). +NETTHRUST_DBCTHRUST= 1.0 +% +% parameter for the definition of a complex objective function +DCD_DCL_VALUE= 0.0 +% +% parameter for the definition of a complex objective function +DCMX_DCL_VALUE= 0.0 +% +% parameter for the definition of a complex objective function +DCMY_DCL_VALUE= 0.0 +% +% parameter for the definition of a complex objective function +DCMZ_DCL_VALUE= 0.0 % ---------------------- REFERENCE VALUE DEFINITION ---------------------------% % @@ -308,6 +347,12 @@ REF_ORIGIN_MOMENT_Z = 0.00 % Reference length for moment non-dimensional coefficients (m or in) REF_LENGTH= 1.0 % +% Reference velocity (incompressible only) +REF_VELOCITY= 1.0 +% +% Reference viscosity (incompressible only) +REF_VISCOSITY= 1.0 +% % Reference area for non-dimensional force coefficients (0 implies automatic % calculation) (m^2 or in^2) REF_AREA= 1.0 @@ -337,7 +382,10 @@ CRITICAL_TEMPERATURE= 131.00 % Critical Pressure (3588550.0 N/m^2 by default) CRITICAL_PRESSURE= 3588550.0 % -% Acentri factor (0.035 (air)) +% Critical Density (263.0 kg/m^3 by default) +CRITICAL_DENSITY= 263.0 +% +% Acentric factor (0.035 (air)) ACENTRIC_FACTOR= 0.035 % % Thermodynamics(operating) Pressure (101325 Pa default value, only for incompressible flow and FLUID_MIXTURE) @@ -359,7 +407,7 @@ MOLECULAR_WEIGHT= 28.96, 16.043 % Format -> Cp(T) : b0 + b1*T + b2*T^2 + b3*T^3 + b4*T^4 CP_POLYCOEFFS= (0.0, 0.0, 0.0, 0.0, 0.0) % -% Nonequilibrium fluid options +% --- Nonequilibrium fluid options % % Gas model - mixture GAS_MODEL= AIR-5 @@ -387,11 +435,17 @@ FILENAMES_INTERPOLATOR= (MLP_1.mlp, MLP_2.mlp, MLP_3.mlp) % Relaxation factor for the Newton solvers in the data-driven fluid model DATADRIVEN_NEWTON_RELAXATION= 0.8 +% +% Specify if there is ionization +IONIZATION= NO +% +% Specify if there is VT transfer residual limiting +VT_RESIDUAL_LIMITING= NO % % NEMO Inlet Options INLET_TEMPERATURE_VE = 288.15 INLET_GAS_COMPOSITION = (0.77, 0.23, 0.0, 0.0, 0.0) -% + % --------------------------- VISCOSITY MODEL ---------------------------------% % % Viscosity model (SUTHERLAND, CONSTANT_VISCOSITY, POLYNOMIAL_VISCOSITY, FLAMELET). @@ -435,7 +489,7 @@ TURBULENT_CONDUCTIVITY_MODEL= CONSTANT_PRANDTL_TURB % % Turbulent Prandtl number (0.9 (air) by default) PRANDTL_TURB= 0.90 -% + % ----------------------- DYNAMIC MESH DEFINITION -----------------------------% % % Type of dynamic mesh (NONE, RIGID_MOTION, ROTATING_FRAME, @@ -510,7 +564,7 @@ SURFACE_PLUNGING_AMPL= 0.0 0.0 0.0 % % Move Motion Origin for marker moving (1 or 0) MOVE_MOTION_ORIGIN = 0 -% + % ------------------------- BUFFET SENSOR DEFINITION --------------------------% % % Compute the Kenway-Martins separation sensor for buffet-onset detection @@ -606,6 +660,9 @@ DRAG_IN_SONICBOOM= 0.0 % -------------------------- ENGINE SIMULATION --------------------------------% % +% Evaluate a problem with engines +ENGINE= NO +% % Highlite area to compute MFR (1 in2 by default) HIGHLITE_AREA= 1.0 % @@ -627,6 +684,13 @@ ENGINE_NU_FACTOR= 3.0 % Actuator disk jump definition using ratio or difference (DIFFERENCE, RATIO) ACTDISK_JUMP= DIFFERENCE % +% secondary flow value for actuator disk +ACTDISK_SECONDARY_FLOW= 0.0 +% +% Actuator disk double surface +ACTDISK_DOUBLE_SURFACE= NO +% +% % Number of times BC Thrust is updated in a fix Net Thrust problem (5 by default) UPDATE_BCTHRUST= 100 % @@ -641,6 +705,9 @@ SUBSONIC_ENGINE_CYL= ( 0.0, 0.0, 0.0, 1.0, 0.0 , 0.0, 1.0 ) % % Flow variables that define the subsonic region (Mach, Alpha, Beta, Pressure, Temperature) SUBSONIC_ENGINE_VALUES= ( 0.4, 0.0, 0.0, 2116.216, 518.67 ) +% +% Definition of the distortion rack (radial number of proves / circumferential density (degree) +DISTORTION_RACK= (0.0, 0.0) % ------------------------- TURBOMACHINERY SIMULATION -------------------------% % @@ -685,6 +752,24 @@ MIXEDOUT_COEFF= (1.0, 1.0E-05, 15) % Limit of Mach number below which the mixedout algorithm is substituted % with a AREA average algorithm to avoid numerical issues AVERAGE_MACH_LIMIT= 0.05 +% +% Integer number of periodic time instances for Harmonic Balance +TIME_INSTANCES= 1 +% +% Time period for Harmonic Balance wihtout moving meshes +HB_PERIOD= -1 +% +% Turn on/off harmonic balance preconditioning +HB_PRECONDITION= NO +% +% Omega_HB = 2*PI*frequency - frequencies for Harmonic Balance method +OMEGA_HB= (0,1.0,-1.0) +% +% Determines if the single-zone driver is used. (deprecated) +SINGLEZONE_DRIVER= NO +% +% Determines if the special output is written out +SPECIAL_OUTPUT= NO % ------------------- RADIATIVE HEAT TRANSFER SIMULATION ----------------------% % @@ -713,7 +798,7 @@ HEAT_SOURCE_ROTATION_Z = 0.0 HEAT_SOURCE_CENTER = ( 0.0, 0.0, 0.0 ) % % Vector of heat source radii (Heat_Source_Radius_A, Heat_Source_Radius_B, Heat_Source_Radius_C) -HEAT_SOURCE_RADIUS = ( 1.0, 1.0, 1.0 ) +HEAT_SOURCE_AXES = ( 1.0, 1.0, 1.0 ) % % Wall emissivity of the marker for radiation purposes MARKER_EMISSIVITY = ( MARKER_NAME, 1.0 ) @@ -729,15 +814,23 @@ TIME_DISCRE_RADIATION = EULER_IMPLICIT % Specify scalar transport model (NONE, SPECIES_TRANSPORT, FLAMELET) KIND_SCALAR_MODEL= NONE % -% Mass diffusivity model (CONSTANT_DIFFUSIVITY, FLAMELET) +% mixing model for species transport (DAVIDSON, WILKE) +MIXING_VISCOSITY_MODEL= DAVIDSON +% +% Mass diffusivity model (CONSTANT_DIFFUSIVITY, CONSTANT_SCHMIDT, UNITY_LEWIS, CONSTANT_LEWIS, FLAMELET) DIFFUSIVITY_MODEL= CONSTANT_DIFFUSIVITY % % Mass diffusivity if DIFFUSIVITY_MODEL= CONSTANT_DIFFUSIVITY is chosen. D_air ~= 0.001 DIFFUSIVITY_CONSTANT= 0.001 % +% Laminar Schmidt number for mass diffusion (for constant schmidt number model) +SCHMIDT_NUMBER_LAMINAR= 1.0 % Turbulent Schmidt number of mass diffusion SCHMIDT_NUMBER_TURBULENT= 0.7 % +% list of constant Lewis numbers for all species for +CONSTANT_LEWIS_NUMBER= (1,1,1) +% % Inlet Species boundary marker(s) with the following format: % (inlet_marker, Species1, Species2, ..., SpeciesN-1, inlet_marker2, Species1, Species2, ...) % For N species, N-1 transport equations are solved, the last one Y_N is solved algebraically as 1-(sum of the species 1 to (N-1)) @@ -760,16 +853,16 @@ TIME_DISCRE_SPECIES= EULER_IMPLICIT CFL_REDUCTION_SPECIES= 1.0 % % Initial values for scalar transport -SPECIES_INIT= 1.0, ... +SPECIES_INIT= 1.0 % % Activate clipping for scalar transport equations SPECIES_CLIPPING= NO % % Maximum values for scalar clipping -SPECIES_CLIPPING_MAX= 1.0, ... +SPECIES_CLIPPING_MAX= 1.0 % % Minimum values for scalar clipping -SPECIES_CLIPPING_MIN= 0.0, ... +SPECIES_CLIPPING_MIN= 0.0 % --------------------- FLAMELET MODEL -----------------------------% % @@ -859,7 +952,7 @@ STREAMWISE_PERIODIC_TEMPERATURE= NO % 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) @@ -902,6 +995,20 @@ SPECIFIED_INLET_PROFILE= NO % File specifying inlet profile INLET_FILENAME= inlet.dat % +% If a file is provided to specify the inlet profile, +% this tolerance will be used to match the coordinates in the input file to +% the points on the grid. +% INLET_MATCHING_TOLERANCE= 1e-6 +% +% Type of spanwise interpolation to use for the inlet face (LINEAR_1D, AKIMA_1D, CUBIC_1D). +INLET_INTERPOLATION_FUNCTION= NONE +% +% Type of radial spanwise interpolation type for the inlet face (VR_VTHETA or ALPHA_PHI). +INLET_INTERPOLATION_DATA_TYPE= VRVTHETA +% +% Write interpolated inlet vertex data to the file Interpolated_Data_.dat +PRINT_INLET_INTERPOLATED_DATA= NO +% % Inlet boundary marker(s) with the following formats (NONE = no marker) % Total Conditions: (inlet marker, total temp, total pressure, flow_direction_x, % flow_direction_y, flow_direction_z, ... ) where flow_direction is @@ -923,8 +1030,11 @@ MARKER_INLET= ( NONE ) % Inc. Mass Flow: ( outlet marker, mass flow target (kg/s), ... ) MARKER_OUTLET= ( NONE ) % +% Propeller blade element actuator disk double surface (inlet, outlet) boundary condition +ACTDISK_DOUBLE_SURFACE = NO +% % Actuator disk boundary type (VARIABLE_LOAD, VARIABLES_JUMP, BC_THRUST, -% DRAG_MINUS_THRUST) +% DRAG_MINUS_THRUST, BLADE_ELEMENT) ACTDISK_TYPE= VARIABLES_JUMP % % Actuator disk boundary marker(s) with the following formats (NONE = no marker) @@ -938,11 +1048,33 @@ ACTDISK_TYPE= VARIABLES_JUMP % Drag-Thrust: ( inlet face marker, outlet face marker, % Takeoff Drag-Thrust (lbs), 0.0, Takeoff rev/min, % Cruise Drag-Thrust (lbs), 0.0, Cruise rev/min ) +% Blade element: ( inlet face marker, outlet face marker, +% Takeoff Drag-Thrust (lbs), 0.0, Takeoff rev/min, +% Cruise Drag-Thrust (lbs), 0.0, Cruise rev/min ) MARKER_ACTDISK= ( NONE ) % +% Blade element: ( inlet face marker, outlet face marker, +% X_CG of inlet, Y_CG of inlet, Z_CG of inlet, +% X_CG of outlet, Y_CG of outlet, Z_CG of outlet ) +MARKER_ACTDISK_BEM_CG= ( NONE ) +% +% Blade element: ( inlet face marker, outlet face marker, +% X_Axis of inlet, Y_Axis of inlet, Z_Axis of inlet, +% X_Axis of outlet, Y_Axis of outlet, Z_Axis of outlet ) +MARKER_ACTDISK_BEM_AXIS= ( NONE ) +% % Actuator disk data input file name ACTDISK_FILENAME= actuatordisk.dat % +% Propeller blade element section and aerodynamic data input file name +BEM_PROP_FILENAME = prop_geom_alfclcd_data.txt +% +% Propeller blade angle (degrees) at (0.75 * radius) +BEM_PROP_BLADE_ANGLE = 25.0 +% +% BEM calculation frequency +BEM_FREQ = 40 +% % Supersonic inlet boundary marker(s) (NONE = no marker) % Format: (inlet marker, temperature, static pressure, velocity_x, % velocity_y, velocity_z, ... ), i.e. primitive variables specified. @@ -998,6 +1130,9 @@ MARKER_SHROUD= (NONE) % MARKER_ZONE_INTERFACE= ( NONE ) % +% CHT interface boundary marker(s) +MARKER_CHT_INTERFACE= ( NONE ) +% % Specifies the interface (s) % The kind of interface is defined by listing pairs of markers (one from each % zone connected by the interface) @@ -1010,14 +1145,39 @@ MARKER_ZONE_INTERFACE= ( NONE ) % MARKER_FLUID_INTERFACE= ( NONE ) % -% Kind of interface interpolation among different zones (NEAREST_NEIGHBOR, -% ISOPARAMETRIC, SLIDING_MESH) +% Marker(s) in which the flow load is computed/applied +MARKER_FLUID_LOAD= ( NONE ) +% +% Kind of interface interpolation among different zones (NEAREST_NEIGHBOR, WEIGHTED_AVERAGE, +% ISOPARAMETRIC, RADIAL_BASIS_FUNCTION) KIND_INTERPOLATION= NEAREST_NEIGHBOR % +% Use conservative approach for interpolating between meshes +CONSERVATIVE_INTERPOLATION= YES +% +% Type of radial basis function to use for radial basis function interpolation +% (WENDLAND_C2, INV_MULTI_QUADRIC, GAUSSIAN, THIN_PLATE_SPLINE, MULTI_QUADRIC). +KIND_RADIAL_BASIS_FUNCTION = WENDLAND_C2 +% +% Radius for radial basis function. +RADIAL_BASIS_FUNCTION_PARAMETER = 0.015 +% +% Use polynomial term in radial basis function interpolation. +RADIAL_BASIS_FUNCTION_POLYNOMIAL_TERM = YES +% +% Tolerance to prune small coefficients from the RBF interpolation matrix. +RADIAL_BASIS_FUNCTION_PRUNE_TOLERANCE = 0 +% % Inflow and Outflow markers must be specified, for each blade (zone), following % the natural groth of the machine (i.e, from the first blade to the last) MARKER_TURBOMACHINERY= ( NONE ) % +% Integer number of spanwise sections to compute 3D turbo BC and Performance for turbomachinery +NUM_SPANWISE_SECTIONS= 1 +% +% type of algorithm to identify the span-wise sections at the turbo boundaries. 1 means automatic. +SPANWISE_KIND= 1 +% % Mixing-plane interface markers must be specified to activate the transfer of % information between zones MARKER_MIXINGPLANE_INTERFACE= ( NONE ) @@ -1039,14 +1199,75 @@ SPATIAL_FOURIER= NO % Catalytic wall marker(s) (NONE = no marker) % Format: ( marker name, ... ) CATALYTIC_WALL= ( NONE ) +% specify if catalytic wall is a supercatalytic wall +SUPERCATALYTIC_WALL= NO +% species composition at the supercatalytic wall +SUPERCATALYTIC_WALL_COMPOSITION= (0,0,0) +% catalytic efficiency +CATALYTIC_EFFICIENCY= 0.2 % % Inlet Turbulent boundary marker(s) with the following format: % SA Model: (inlet_marker1, NuFactor1, inlet_marker2, NuFactor2, ...) % SST Model: (inlet_marker1, TurbIntensity1, RatioTurbLamViscosity1, inlet_marker2, TurbIntensity2, RatioTurbLamViscosity2, ...) MARKER_INLET_TURBULENT= (inlet1, 0.05, 15, inlet2, 0.02, ...) % -% list of markers species transport and flamelet model where strong boundary conditions should be used -MARKER_SPECIES_STRONG_BC= (inlet, wall) +% Custom boundary marker(s) (this has to be implemented by users in the code). +MARKER_CUSTOM= ( NONE ) +% +% Smoluchowski/Maxwell slip wall boundary marker(s) +MARKER_SMOLUCHOWSKI_MAXWELL= ( NONE ) +% +% Clamped boundary marker(s) +MARKER_CLAMPED= ( NONE ) +% +% Load boundary marker(s) +MARKER_DAMPER= ( NONE ) +% +% Load boundary marker(s) +% Format: (inlet marker, load, multiplier, dir_x, dir_y, dir_z, ... ), +% i.e. primitive variables specified. +MARKER_LOAD= ( NONE ) +% +% option to apply the load as a sine +SINE_LOAD= NO +% the 1st coeff is the amplitude, +% the 2nd is the frequency, +% the 3rd is the phase in radians +SINE_LOAD_COEFF= (0.0, 0.0, 0.0) +% +RAMP_AND_RELEASE_LOAD= NO +% +% Apply the load as a ramp +RAMP_LOADING= NO +% +% Time while the load is to be increased linearly +RAMP_TIME= 1.0 +% +% Number of FSI iterations during which a ramp is applied +RAMP_FSI_ITER= 2 +% +% Aitken static relaxation factor +STAT_RELAX_PARAMETER= 0.4 +% +% Aitken dynamic maximum relaxation factor for the first iteration +AITKEN_DYN_MAX_INITIAL= 0.5 +% +% Aitken dynamic minimum relaxation factor for the first iteration +AITKEN_DYN_MIN_INITIAL= 0.5 +% +% Kind of relaxation +BGS_RELAXATION= NONE +% +% Relaxation required +RELAXATION= NO +% +% Transfer method used for multiphysics problems +DYNAMIC_LOAD_TRANSFER= RAMP +% +% Load boundary marker(s) +% Format: (inlet marker, load, multiplier, dir_x, dir_y, dir_z, ... ), +% i.e. primitive variables specified. +MARKER_DISPLACEMENT= ( NONE ) % ------------------------ WALL ROUGHNESS DEFINITION --------------------------% % The equivalent sand grain roughness height (k_s) on each of the wall. This must be in m. @@ -1071,6 +1292,14 @@ WALLMODEL_MAXITER= 200 % [Expert] relaxation factor for the Newton iterations of the standard wall function WALLMODEL_RELFAC= 0.5 +% ------------------------ CONJUGATE HEAT TRANSFER (CHT) --------------------------% +% +% Relaxation of the CHT coupling +RELAXATION_FACTOR_CHT= 1.0 +% +% CHT interface coupling methods +CHT_COUPLING_METHOD= DIRECT_TEMPERATURE_ROBIN_HEATFLUX + % ------------------------ SURFACES IDENTIFICATION ----------------------------% % % Marker(s) of the surface in the surface flow solution file @@ -1101,7 +1330,7 @@ MARKER_ANALYZE_AVERAGE = MASSFLUX % % Numerical method for spatial gradients (GREEN_GAUSS, WEIGHTED_LEAST_SQUARES) NUM_METHOD_GRAD= GREEN_GAUSS - +% % Numerical method for spatial gradients to be used for MUSCL reconstruction % Options are (GREEN_GAUSS, WEIGHTED_LEAST_SQUARES, LEAST_SQUARES). Default value is % NONE and the method specified in NUM_METHOD_GRAD is used. @@ -1124,6 +1353,9 @@ CFL_ADAPT_PARAM= ( 0.1, 2.0, 10.0, 1e10, 0.001 ) % Maximum Delta Time in local time stepping simulations MAX_DELTA_TIME= 1E6 % +% External iteration offset due to restart +EXT_ITER_OFFSET= 0 +% % Runge-Kutta alpha coefficients RK_ALPHA_COEFF= ( 0.66667, 0.66667, 1.000000 ) % @@ -1194,6 +1426,8 @@ ADJ_SHARP_LIMITER_COEFF= 3.0 % Remove sharp edges from the sensitivity evaluation (NO, YES) SENS_REMOVE_SHARP = NO % +SENS_SMOOTHING= NONE +% % Freeze the value of the limiter after a number of iterations LIMITER_ITER= 999999 % @@ -1222,6 +1456,15 @@ LINEAR_SOLVER= FGMRES % Same for discrete adjoint (smoothers not supported), replaces LINEAR_SOLVER in SU2_*_AD codes. DISCADJ_LIN_SOLVER= FGMRES % +% Linear solver for the turbulent adjoint systems +ADJTURB_LIN_SOLVER= FGMRES +% +% Preconditioner for the turbulent adjoint Krylov linear solvers +ADJTURB_LIN_PREC= ILU +% +% Maximum number of iterations of the turbulent adjoint linear solver for the implicit formulation +ADJTURB_LIN_ITER= 10 +% % Preconditioner of the Krylov linear solver or type of smoother (ILU, LU_SGS, LINELET, JACOBI) LINEAR_SOLVER_PREC= ILU % @@ -1266,6 +1509,11 @@ MG_DAMP_RESTRICTION= 0.75 % Damping factor for the correction prolongation MG_DAMP_PROLONGATION= 0.75 +% -------------------------- MESH SMOOTHING -----------------------------% +% +% Before each computation, implicitly smooth the nodal coordinates +SMOOTH_GEOMETRY= 0 + % -------------------- FLOW NUMERICAL METHOD DEFINITION -----------------------% % % Convective numerical method (JST, JST_KE, JST_MAT, LAX-FRIEDRICH, ROE, AUSM, @@ -1276,6 +1524,15 @@ CONV_NUM_METHOD_FLOW= ROE % Roe Low Dissipation function for Hybrid RANS/LES simulations (FD, NTS, NTS_DUCROS) ROE_LOW_DISSIPATION= FD % +% Roe coefficient +ROE_KAPPA= 0.5 +% +% Minimum value for beta for the Roe-Turkel preconditioner +MIN_ROE_TURKEL_PREC= 0.01 +% +% Maximum value for beta for the Roe-Turkel preconditioner +MAX_ROE_TURKEL_PREC= 0.2 +% % Post-reconstruction correction for low Mach number flows (NO, YES) LOW_MACH_CORR= NO % @@ -1299,6 +1556,10 @@ ENTROPY_FIX_COEFF= 0.0 % only) more diagonal dominant (but mathematically incorrect) so that higher CFL can be used. CENTRAL_JACOBIAN_FIX_FACTOR= 4.0 % +% Control numerical properties of the global Jacobian matrix using a multiplication factor +% for incompressible central schemes +CENTRAL_INC_JACOBIAN_FIX_FACTOR= 1.0 +% % Time discretization (RUNGE-KUTTA_EXPLICIT, EULER_IMPLICIT, EULER_EXPLICIT) TIME_DISCRE_FLOW= EULER_IMPLICIT % @@ -1306,6 +1567,12 @@ TIME_DISCRE_FLOW= EULER_IMPLICIT % For multizone discrete adjoint it will use FGMRES on inner iterations with restart frequency % equal to "QUASI_NEWTON_NUM_SAMPLES". NEWTON_KRYLOV= NO +% +% Integer parameters {startup iters, precond iters, initial tolerance relaxation}. +NEWTON_KRYLOV_IPARAM= (10, 3, 2) +% +% Double parameters {startup residual drop, precond tolerance, full tolerance residual drop, findiff step}. +NEWTON_KRYLOV_DPARAM= (1.0, 0.1, -6.0, 1e-5) % ------------------- FEM FLOW NUMERICAL METHOD DEFINITION --------------------% % @@ -1340,7 +1607,7 @@ ALIGNED_BYTES_MATMUL= 128 TIME_DISCRE_FEM_FLOW= RUNGE-KUTTA_EXPLICIT % % Number of time DOFs for the predictor step of ADER-DG (2 by default) -%TIME_DOFS_ADER_DG= 2 +TIME_DOFS_ADER_DG= 2 % Factor applied during quadrature in time for ADER-DG. (2.0 by default) %QUADRATURE_FACTOR_TIME_ADER_DG = 2.0 % @@ -1351,7 +1618,135 @@ LEVELS_TIME_ACCURATE_LTS= 1 % % Specify the method for matrix coloring for Jacobian computations (GREEDY_COLORING, NATURAL_COLORING) KIND_MATRIX_COLORING= GREEDY_COLORING +% +% Specify shock capturing method for DG +KIND_FEM_DG_SHOCK= NONE + +% ------------------- TOPOLOGY OPTIMIZATION --------------------% +% +% "Classic" density approach to topology optimization. Each element is +% assigned a density variable that is used to penalize its stiffness. +TOPOLOGY_OPTIMIZATION= NO +% +% Output file for the derivatives of the OBJECTIVE_FUNCTION w.r.t. the +% design densities. +TOPOL_OPTIM_OUTFILE= element_derivatives.dat +% +% The penalization exponent for the Simplified Isotropic Material with +% Penalization. +TOPOL_OPTIM_SIMP_EXPONENT= 1.0 +% +% The stiffness of void elements (normalized by ELASTICITY_MODULUS) +TOPOL_OPTIM_SIMP_MINSTIFF= 0.001 +% +% Filtering is required to avoid numerical issues, see [Sigmund, 2007] +% (DOI 10.1007/s00158-006-0087-x). Currently available options: +% CONSTANT; CONICAL (default); GAUSSIAN; DILATE; ERODE. +% The filter can have multiple sequential stages (2 in this case). +TOPOL_OPTIM_FILTER_KERNEL= (DILATE, ERODE) +% +% Each kernel can have its own radius (R1, R2, ...) or one value can be +% specified for all. +TOPOL_OPTIM_FILTER_RADIUS= 0.0 +% +% The Gaussian, Erode, and Dilate filters, have a constant parameter. +% Again this can be a list. +TOPOL_OPTIM_KERNEL_PARAM= 0.01 +% +% The filtering may become very expensive if the mesh has very refined +% regions. If different from 0 this option mitigates that by limiting the +% "logical radius" (for immediate neighbors that radius is 1, etc.). +TOPOL_OPTIM_SEARCH_LIMIT= 0 +% +% After the filtering, a projection step can be applied to increase the +% solid-void contrast, i.e. the discreteness of the solution. Options: +% NO_PROJECTION (default); HEAVISIDE_UP; HEAVISIDE_DOWN. +TOPOL_OPTIM_PROJECTION_TYPE= NO_PROJECTION +% +% The continuous Heaviside function (step) approximations require a +% parameter, large value equals more discrete. +TOPOL_OPTIM_PROJECTION_PARAM= 0.0 +% ------------------- FEA SOLVER FOR FLUID-STRUCTURE INTERACTION --------------------% +% +% Filename to input for element-based properties +FEA_FILENAME= default_element_properties.dat +% +% Determine if advanced features are used from the element-based FEA analysis (NO, YES = experimental) +FEA_ADVANCED_MODE= NO +% +% Modulus of elasticity +ELASTICITY_MODULUS= 1000.0 +% +% Poisson ratio +POISSON_RATIO= 0.35 +% +% Knowles B constant +KNOWLES_B= 1.0 +% +% Knowles N constant +KNOWLES_N= 1.0 +% +% ID of the region we want to compute the sensitivities using direct differentiation +FEA_ID_DIRECTDIFF= 0 +% +% +RESTART_STEADY_STATE= NO +% +% Time discretization +TIME_DISCRE_FEA= NEWMARK_IMPLICIT +% +% Parameter alpha for Newmark scheme (s) +NEWMARK_BETA= 0.25 +% +% Parameter gamma for Newmark scheme (s) +NEWMARK_GAMMA= 0.50 +% +% Newmark - Generalized alpha - coefficients +TIME_INT_STRUCT_COEFFS= 0.0 +% +% Apply dead loads +INCREMENTAL_LOAD= NO +% +% Maximum number of increments of the +NUMBER_INCREMENTS= 10 +% +% Definition of the UTOL RTOL ETOL +INCREMENTAL_CRITERIA= (0.0, 0.0, 0.0) +% +% Use of predictor +PREDICTOR= NO +% +% Order of the predictor +PREDICTOR_ORDER= 0 +% +% Geometric conditions +GEOMETRIC_CONDITIONS= SMALL_DEFORMATIONS +% +% Material model +MATERIAL_MODEL= LINEAR_ELASTIC +% +% Compressibility of the material +MATERIAL_COMPRESSIBILITY= COMPRESSIBLE +% +% -------------------- Dielectric effects ------------------% +% +% Include DE effects +DE_EFFECTS= NO +% +% Value of the Dielectric Elastomer constant +ELECTRIC_FIELD_CONST= 4.25e-11 +% +% Modulus of the Electric Fields +ELECTRIC_FIELD_MOD= 20e5 +% +% Direction of the Electic Fields +ELECTRIC_FIELD_DIR= (0.0, 1.0) + +% -------------------- Weakly Coupled Heat ------------------% +% +WEAKLY_COUPLED_HEAT_EQUATION= NO +% % -------------------- TURBULENT NUMERICAL METHOD DEFINITION ------------------% % % Convective numerical method (SCALAR_UPWIND, BOUNDED_SCALAR) @@ -1379,12 +1774,15 @@ SLOPE_LIMITER_HEAT = NONE % % Time discretization TIME_DISCRE_HEAT= EULER_IMPLICIT -% + % ---------------- ADJOINT-FLOW NUMERICAL METHOD DEFINITION -------------------% % % Frozen the slope limiter in the discrete adjoint formulation (NO, YES) FROZEN_LIMITER_DISC= NO % +% Continuous Adjoint frozen viscosity +% FROZEN_VISC_CONT= NO +% % Frozen the turbulent viscosity in the discrete adjoint formulation (NO, YES) FROZEN_VISC_DISC= NO % @@ -1414,6 +1812,20 @@ LIMIT_ADJFLOW= 1E6 % Use multigrid in the adjoint problem (NO, YES) MG_ADJFLOW= YES +% ---------------- MULTIZONE DEFINITION --------------% +% +% Determine if the mesh file supports multizone. \n DEFAULT: true (temporarily) +MULTIZONE_MESH= YES +% +% Determine if we need to allocate memory to store the multizone residual. \n DEFAULT: true (temporarily) +MULTIZONE_RESIDUAL= NO +% +% Determines if the convergence history of each individual zone is written to screen +WRT_ZONE_CONV= NO +% +% Determines if the convergence history of each individual zone is written to file +WRT_ZONE_HIST= NO + % ---------------- ADJOINT-TURBULENT NUMERICAL METHOD DEFINITION --------------% % % Convective numerical method (SCALAR_UPWIND) @@ -1425,7 +1837,6 @@ TIME_DISCRE_ADJTURB= EULER_IMPLICIT % Reduction factor of the CFL coefficient in the adjoint turbulent problem CFL_REDUCTION_ADJTURB= 0.01 - % -------------------- NEMO NUMERICAL METHOD DEFINITION -----------------------% % % Mixture transport properties (WILKE,GUPTA-YOS,CHAPMANN-ENSKOG, SUTHERLAND) @@ -1439,9 +1850,14 @@ GEO_MARKER= ( airfoil ) % Description of the geometry to be analyzed (AIRFOIL, WING) GEO_DESCRIPTION= AIRFOIL % +% Z location of the waterline +GEO_WATERLINE_LOCATION= 0.0 +% % Coordinate of the stations to be analyzed GEO_LOCATION_STATIONS= (0.0, 0.5, 1.0) % +% Definition of the nacelle location (higlite coordinates, tilt angle, toe angle) +GEO_NACELLE_LOCATION= (0.0, 0.0, 0.0, 0.0, 0.0) % Geometrical bounds (Y coordinate) for the wing geometry analysis or % fuselage evaluation (X coordinate) GEO_BOUNDS= (1.5, 3.5) @@ -1455,23 +1871,6 @@ GEO_NUMBER_STATIONS= 25 % Geometrical evaluation mode (FUNCTION, GRADIENT) GEO_MODE= FUNCTION -% ------------------------- GRID ADAPTATION STRATEGY --------------------------% -% -% Kind of grid adaptation (NONE, PERIODIC, FULL, FULL_FLOW, GRAD_FLOW, -% FULL_ADJOINT, GRAD_ADJOINT, GRAD_FLOW_ADJ, ROBUST, -% FULL_LINEAR, COMPUTABLE, COMPUTABLE_ROBUST, -% REMAINING, WAKE, SMOOTHING, SUPERSONIC_SHOCK) -KIND_ADAPT= FULL_FLOW -% -% Percentage of new elements (% of the original number of elements) -NEW_ELEMS= 5 -% -% Scale factor for the dual volume -DUALVOL_POWER= 0.5 -% -% Adapt the boundary elements (NO, YES) -ADAPT_BOUNDARY= YES - % ----------------------- DESIGN VARIABLE PARAMETERS --------------------------% % % Kind of deformation (NO_DEFORMATION, SCALE_GRID, TRANSLATE_GRID, ROTATE_GRID, @@ -1530,7 +1929,58 @@ DV_SENS_FILENAME= surface_sensitivity.dat % as an ASCII file with name given by DV_SENS_FILENAMEand with format as % rows of x, y, z, dJ/dx, dJ/dy, dJ/dz for each grid point. DV_SENSITIVITY_FORMAT= SU2_NATIVE +% DV_UNORDERED_SENS_FILENAME= unordered_sensitivity.dat +% +% Hold the grid fixed in a region +HOLD_GRID_FIXED= NO +% +% Coordinates of the box where the grid will be deformed (Xmin, Ymin, Zmin, Xmax, Ymax, Zmax) +HOLD_GRID_FIXED_COORDS= (-1e15, -1e15, -1e15, 1e15, 1e15, 1e15) +% +% Design variable for FEA problems +% options: NONE, YOUNG_MODULUS, POISSON_RATIO, DENSITY, DEAD_WEIGHT, ELECTRIC_FIELD +DESIGN_VARIABLE_FEA= NONE +% +% Penalty weight value to maintain the total sum of DV constant +TOTAL_DV_PENALTY= 0.0 +% +% Parameters for the corresponding OF (allowed stress and KS multiplier). +STRESS_PENALTY_PARAM= (1.0, 10.0) +% + +% ---------------- AUTOMATIC DIFFERENTIATION -------------------% +% +% Preaccumulation in the AD mode. +PREACC= YES + +% ---------------- PRESTRETCH FOR STRUCTURES -------------------% +% Consider a prestretch in the structural domain +PRESTRETCH= NO +% +% Filename to input for prestretching membranes +PRESTRETCH_FILENAME= prestretch_file.dat +% +% Iterative method for non-linear structural analysis +NONLINEAR_FEM_SOLUTION_METHOD= NEWTON_RAPHSON +% +% Formulation for bidimensional elasticity solver +FORMULATION_ELASTICITY_2D= PLANE_STRAIN +% +% Apply dead loads +DEAD_LOAD= NO +% +% pseudo static analysis (no density in dynamic analysis) +PSEUDO_STATIC= NO +% +% Dynamic or static structural analysis (deprecated -> use TIME_DOMAIN) +DYNAMIC_ANALYSIS= NO +% +% Time Step for dynamic analysis (s) (deprecated -> use TIME_STEP) +DYN_TIMESTEP= 0.0 +% +% Total Physical Time for dual time stepping simulations (s) (deprecated -> use MAX_TIME) +DYN_TIME= 1.0 % ---------------- MESH DEFORMATION PARAMETERS (NEW SOLVER) -------------------% % @@ -1572,6 +2022,41 @@ DEFORM_STIFFNESS_TYPE= WALL_DISTANCE % Deform the grid only close to the surface. It is possible to specify how much % of the volumetric grid is going to be deformed in meters or inches (1E6 by default) DEFORM_LIMIT = 1E6 +% +% Young modulus for constant stiffness FEA method of grid deformation +DEFORM_ELASTICITY_MODULUS= 2e11 +% +% Poisson ratio for constant stiffness FEA method of grid deformation +DEFORM_POISSON_RATIO= 0.3 +% +% Size of the layer of highest stiffness for wall distance-based mesh stiffness +DEFORM_STIFF_LAYER_SIZE= 0.0 + +% -------------------- REFERENCE GEOMETRY -----------------------% +% +% Consider a reference solution for the structure (optimization applications) +REFERENCE_GEOMETRY= NO +% +% Penalty weight value for the objective function +REFERENCE_GEOMETRY_PENALTY= 1.0E6 +% +% Reference geometry filename +REFERENCE_GEOMETRY_FILENAME= reference_geometry.dat +% +% Format of the reference geometry file +REFERENCE_GEOMETRY_FORMAT= SU2_REF +% +% If true consider only the surfaces where loads are applied. +REFERENCE_GEOMETRY_SURFACE= NO +% +% Reference node for the structure (optimization applications) +REFERENCE_NODE= 0 +% +% Target displacement of the reference node +REFERENCE_NODE_DISPLACEMENT= (0.0, 0.0) +% +% Penalty weight value for the objective function +REFERENCE_NODE_PENALTY= 1.0E3 % -------------------- FREE-FORM DEFORMATION PARAMETERS -----------------------% % @@ -1580,17 +2065,17 @@ FFD_TOLERANCE= 1E-10 % % Maximum number of iterations in the Free-Form Deformation point inversion FFD_ITERATIONS= 500 - +% % Parameters for prevention of self-intersections within FFD box FFD_INTPREV = YES FFD_INTPREV_ITER = 10 FFD_INTPREV_DEPTH = 3 - +% % Parameters for prevention of nonconvex elements in mesh after deformation CONVEXITY_CHECK = YES CONVEXITY_CHECK_ITER = 10 CONVEXITY_CHECK_DEPTH = 3 - +% % % FFD box definition: 3D case (FFD_BoxTag, X1, Y1, Z1, X2, Y2, Z2, X3, Y3, Z3, X4, Y4, Z4, % X5, Y5, Z5, X6, Y6, Z6, X7, Y7, Z7, X8, Y8, Z8) @@ -1655,6 +2140,14 @@ UQ_DELTA_B= 1.0 % The optimum value/strategy is case-dependent. EDGE_COLORING_GROUP_SIZE= 512 % +% Coloring tends to perform better for the discrete adjoint than reductions because +% it uses less memory and enables the shared reading optimization for color loops. +% This option allows an automatic fallback to smaller edge color group sizes on ranks +% where the requested edge color group size is not efficient. Specifically, the largest +% edge color group size up to EDGE_COLORING_GROUP_SIZE is chosen that is at least +% 0.875 efficient. Also, this option allows using more colors, up to 255 instead of up to 64. +EDGE_COLORING_RELAX_DISC_ADJ= YES +% % Independent "threads per MPI rank" setting for LU-SGS and ILU preconditioners. % For problems where time is spend mostly in the solution of linear systems (e.g. elasticity, % very high CFL central schemes), AND, if the memory bandwidth of the machine is saturated @@ -1757,6 +2250,10 @@ OUTPUT_WRT_FREQ= 10, 250, 42 % Output the performance summary to the console at the end of SU2_CFD WRT_PERFORMANCE= NO % +% Output the tape statistics (discrete adjoint) +WRT_AD_STATISTICS= NO +% +% % Overwrite or append iteration number to the restart files when saving WRT_RESTART_OVERWRITE= YES % @@ -1766,6 +2263,21 @@ WRT_SURFACE_OVERWRITE= YES % Overwrite or append iteration number to the volume files when saving WRT_VOLUME_OVERWRITE= YES % +% Determines if the forces breakdown is written out +WRT_FORCES_BREAKDOWN= NO +% +% MPI communication level (NONE, MINIMAL, FULL) +COMM_LEVEL= FULL +% +% Node number for the CV to be visualized (tecplot) (delete?) +VISUALIZE_CV= -1 +% +% Write extra output (EXPERIMENTAL, NOT FOR GENERAL USE) +EXTRA_OUTPUT= NO +% +% Write extra heat output for a given heat solver zone +EXTRA_HEAT_ZONE_OUTPUT= -1 + % ------------------------- INPUT/OUTPUT FILE INFORMATION --------------------------% % % Mesh input file @@ -1774,6 +2286,15 @@ MESH_FILENAME= mesh_NACA0012_inv.su2 % Mesh input file format (SU2, CGNS) MESH_FORMAT= SU2 % +% List of the number of grid points in the RECTANGLE or BOX grid in the x,y,z directions. (default: (33,33,33) ). +MESH_BOX_SIZE= (33, 33, 33) +% +% List of the length of the RECTANGLE or BOX grid in the x,y,z directions. (default: (1.0,1.0,1.0) ). +MESH_BOX_LENGTH= (1.0, 1.0, 1.0) +% +% List of the offset from 0.0 of the RECTANGLE or BOX grid in the x,y,z directions. (default: (0.0,0.0,0.0) ). +MESH_BOX_OFFSET= (0.0, 0.0, 0.0) +% % Mesh output file MESH_OUT_FILENAME= mesh_out.su2 % @@ -1786,6 +2307,9 @@ SOLUTION_ADJ_FILENAME= solution_adj.dat % Output tabular file format (TECPLOT, CSV) TABULAR_FORMAT= CSV % +% Set .precision(value) to specified value for SU2_DOT and HISTORY output. Useful for exact gradient validation. +OUTPUT_PRECISION= 10 +% % Files to output % Possible formats : (TECPLOT_ASCII, TECPLOT, SURFACE_TECPLOT_ASCII, % SURFACE_TECPLOT, CSV, SURFACE_CSV, PARAVIEW_ASCII, PARAVIEW_LEGACY, SURFACE_PARAVIEW_ASCII, @@ -1823,6 +2347,12 @@ SURFACE_FILENAME= surface_flow % Output file surface adjoint coefficient (w/o extension) SURFACE_ADJ_FILENAME= surface_adjoint % +% Output file surface sensitivity (discrete adjoint) (w/o extension) +SURFACE_SENS_FILENAME= surface_sens +% +% Output file volume sensitivity (discrete adjoint)) +VOLUME_SENS_FILENAME= volume_sens +% % Read binary restart files (YES, NO) READ_BINARY_RESTART= YES % @@ -1873,14 +2403,14 @@ REORIENT_ELEMENTS= YES % Definition of multipoint design problems, this option should be combined with the % the prefix MULTIPOINT in the objective function or constraint (e.g. MULTIPOINT_DRAG, MULTIPOINT_LIFT, etc.) MULTIPOINT_MACH_NUMBER= (0.79, 0.8, 0.81) +MULTIPOINT_WEIGHT= (0.33333, 0.33333, 0.33333) MULTIPOINT_AOA= (1.25, 1.25, 1.25) MULTIPOINT_SIDESLIP_ANGLE= (0.0, 0.0, 0.0) MULTIPOINT_TARGET_CL= (0.8, 0.8, 0.8) MULTIPOINT_REYNOLDS_NUMBER= (1E6, 1E6, 1E6) -MULTIPOINT_FREESTREAM_PRESSURE= (101325.0, 101325.0, 101325.0) MULTIPOINT_FREESTREAM_TEMPERATURE= (288.15, 288.15, 288.15) +MULTIPOINT_FREESTREAM_PRESSURE= (101325.0, 101325.0, 101325.0) MULTIPOINT_OUTLET_VALUE= (0.0, 0.0, 0.0) -MULTIPOINT_WEIGHT= (0.33333, 0.33333, 0.33333) MULTIPOINT_MESH_FILENAME= (mesh_NACA0012_m79.su2, mesh_NACA0012_m8.su2, mesh_NACA0012_m81.su2) % % Optimization objective function with scaling factor, separated by semicolons. @@ -1925,6 +2455,11 @@ DEFINITION_DV= ( 1, 1.0 | airfoil | 0, 0.05 ); ( 1, 1.0 | airfoil | 0, 0.10 ); ( % Use combined objective within gradient evaluation: may reduce cost to compute gradients when using the adjoint formulation. OPT_COMBINE_OBJECTIVE = NO % +% +% Number of iterations to average the objective function for unsteady adjoints, +% 0 averages over all time iterations, "N" averages over the last N iterations. +ITER_AVERAGE_OBJ= 0 + % --------------------- LIBROM PARAMETERS -----------------------% % LibROM can be found here: https://github.com/LLNL/libROM % @@ -1943,3 +2478,14 @@ MAX_BASIS_DIM = 100 % % Frequency of snapshots saves, for unsteady problems (default: 1. 2 means every other) ROM_SAVE_FREQ = 1 + +% --------------------- PASTIX PARAMETERS -----------------------% +% +% Number of calls to 'Build' that trigger re-factorization (0 means only once) +PASTIX_FACTORIZATION_FREQUENCY= 1 +% +% 0 - Quiet, 1 - During factorization and cleanup, 2 - Even more detail +PASTIX_VERBOSITY_LEVEL= 0 +% +% Level of fill for PaStiX incomplete LU factorization +PASTIX_FILL_LEVEL= 1 diff --git a/externals/cgns/adf/ADF_interface.c b/externals/cgns/adf/ADF_interface.c index 11c3502069a..59bd59d5466 100644 --- a/externals/cgns/adf/ADF_interface.c +++ b/externals/cgns/adf/ADF_interface.c @@ -1209,7 +1209,7 @@ else { /** this node is NOT a link **/ CHECK_ADF_ABORT( *error_return ) ; for( i=0; i 0 && lenfilename == strlen( link_data ) ) +else if ( lenfilename == strlen( link_data ) ) { strcpy( file, link_data) ; /** no link ? **/ } @@ -1688,7 +1688,7 @@ if ( lenfilename == 0 ) /** no filename **/ { *len_name = (int)strlen(link_data) - 1; } -else if ( lenfilename > 0 && lenfilename == strlen( link_data ) ) +else if ( lenfilename == strlen( link_data ) ) { *len_file = (int)lenfilename; } diff --git a/externals/cgns/adf/ADF_internals.c b/externals/cgns/adf/ADF_internals.c index a52878e13d6..27c673df9b8 100644 --- a/externals/cgns/adf/ADF_internals.c +++ b/externals/cgns/adf/ADF_internals.c @@ -155,7 +155,7 @@ bytes start end description range / format Variable: min 32 Data-chunks -(Minimum is 32 bytes, which cooresponds to the size required for a free-chunk) +(Minimum is 32 bytes, which corresponds to the size required for a free-chunk) bytes start end description range / format 4 0 3 "DaTa" boundary tag Tag 12 4 15 Pointer to End-of-Data-Tag @@ -7187,7 +7187,7 @@ NULL_STRING_POINTER ADF_FILE_NOT_OPENED PRISTK_NOT_FOUND Note: errors are only important for GET mode since you must then go ahead - and read the data fom the file. The stack is only meant to speed things + and read the data from the file. The stack is only meant to speed things up, not stop the process !!! ***********************************************************************/ int ADFI_stack_control( const unsigned int file_index, diff --git a/externals/cgns/adfh/ADFH.c b/externals/cgns/adfh/ADFH.c index 703cd0b62f6..94ec80cc491 100644 --- a/externals/cgns/adfh/ADFH.c +++ b/externals/cgns/adfh/ADFH.c @@ -61,6 +61,18 @@ static int CompressData = -1; #define ADFH_CONFIG_DEFAULT 0 +#if H5_VERSION_GE(1,10,3) && !defined(H5_USE_18_API) && !defined(H5_USE_16_API) +#define ADFH_HDF5_HAVE_110_API 1 +#else +#define ADFH_HDF5_HAVE_110_API 0 +#endif + +#if H5_VERSION_GE(1,12,0) && !defined(H5_USE_110_API) && !defined(H5_USE_18_API) && !defined(H5_USE_16_API) +#define ADFH_HDF5_HAVE_112_API 1 +#else +#define ADFH_HDF5_HAVE_112_API 0 +#endif + /*** HDF5's CORE FILE DRIVER PARAMETERS ****/ /* Enables using the core file driver */ @@ -72,11 +84,12 @@ static size_t core_vfd_increment = 10L*1024L*1024L; static hbool_t core_vfd_backing_store = ADFH_CONFIG_DEFAULT; /** MISC. HDF5 OPTIMIZATION TUNING PARAMETERS */ -static hsize_t h5pset_alignment_threshold = ADFH_CONFIG_DEFAULT; -static hsize_t h5pset_alignment_alignment = ADFH_CONFIG_DEFAULT; -static hsize_t h5pset_meta_block_size_size = ADFH_CONFIG_DEFAULT; -static hsize_t h5pset_buffer_size_size = ADFH_CONFIG_DEFAULT; -static hsize_t h5pset_sieve_buf_size_size = ADFH_CONFIG_DEFAULT; +static hsize_t h5pset_alignment_threshold = ADFH_CONFIG_DEFAULT; +static hsize_t h5pset_alignment_alignment = ADFH_CONFIG_DEFAULT; +static hsize_t h5pset_meta_block_size_size = ADFH_CONFIG_DEFAULT; +static hsize_t h5pset_buffer_size_size = ADFH_CONFIG_DEFAULT; +static hsize_t h5pset_sieve_buf_size_size = ADFH_CONFIG_DEFAULT; +static unsigned h5pset_elink_file_cache_size_size = ADFH_CONFIG_DEFAULT; #define TO_UPPER( c ) ((islower(c))?(toupper(c)):(c)) @@ -155,10 +168,9 @@ printf aaa ; printf("\n"); fflush(stdout); #define ADFH_MODE_RDO 3 /* the following keeps track of open and mounted files */ +#define ADFH_MAXIMUM_FILES 1024 -#define ADFH_MAXIMUM_FILES 128 - -/* Start to prepare re-entrance into lib, gather statics in one global struct */ +/* Start to prepare re-entrance into lib, gather static variables in one global struct */ /* Then, you'll just have to handle struct with something else but a static... */ /* MTA stands for... Multi-Threads-Aware */ typedef struct _ADFH_MTA { @@ -179,6 +191,9 @@ typedef struct _ADFH_MTA { int g_flags; hid_t g_files[ADFH_MAXIMUM_FILES]; + /* tracking and indexing settings for link creation order */ + unsigned int link_create_order; + #ifndef ADFH_FORCE_ID_CLOSE /* object ids returned to API user that should be closed */ hid_t *g_extids[ADFH_MAXIMUM_FILES]; @@ -289,7 +304,7 @@ if (mta_root == NULL){set_error(ADFH_ERR_ROOTNULL, err);return 1;} static herr_t gfind_by_name(hid_t, const char *, const H5L_info_t*, void *); static herr_t find_by_name(hid_t, const char *, const H5A_info_t*, void *); -#if H5_VERSION_GE(1,12,0) +#if ADFH_HDF5_HAVE_112_API #define has_child(ID,NAME) H5Literate2(ID, H5_INDEX_CRT_ORDER, H5_ITER_NATIVE, NULL, gfind_by_name, (void *)NAME) #define has_data(ID) H5Literate2(ID, H5_INDEX_CRT_ORDER, H5_ITER_NATIVE, NULL, gfind_by_name, (void *)D_DATA) #else @@ -366,7 +381,7 @@ static hid_t get_file_id (hid_t id) int token_cmp; /* find the file ID from the root ID */ -#if H5_VERSION_GE(1,12,0) +#if ADFH_HDF5_HAVE_112_API if (H5Oget_info_by_name3(id, "/", &gstat, H5O_INFO_BASIC, H5P_DEFAULT) >=0) { #else if (H5Oget_info_by_name(id, "/", &gstat, H5P_DEFAULT) >=0) { @@ -377,7 +392,7 @@ static hid_t get_file_id (hid_t id) if (objs == NULL) return fid; H5Fget_obj_ids(H5F_OBJ_ALL, H5F_OBJ_FILE, -1, objs); for (n = 0; n < nobj; n++) { -#if H5_VERSION_GE(1,12,0) +#if ADFH_HDF5_HAVE_112_API H5Oget_info_by_name3(objs[n], "/", &rstat, H5O_INFO_BASIC, H5P_DEFAULT); token_cmp = 1; if(gstat.fileno == rstat.fileno){ @@ -1053,7 +1068,7 @@ static herr_t compare_children(hid_t id, const char *name, const H5L_info_t *lin if (*name != D_PREFIX) { pstat = (H5O_info_t *)data; -#if H5_VERSION_GE(1,12,0) +#if ADFH_HDF5_HAVE_112_API if (H5Oget_info_by_name3(id, name, &stat, H5O_INFO_BASIC, H5P_DEFAULT) >= 0){ token_cmp = 1; if(pstat->fileno == stat.fileno){ @@ -1160,7 +1175,7 @@ static hid_t open_link(hid_t id, int *err) } } #ifdef ADFH_DEBUG_ON -#if H5_VERSION_GE(1,12,0) +#if ADFH_HDF5_HAVE_112_API H5Oget_info3(lid, &oinfo, H5O_INFO_BASIC); #else H5Oget_info(lid, &oinfo); @@ -1268,7 +1283,7 @@ static herr_t delete_children(hid_t id, const char *name, const H5L_info_t* linf } else { ADFH_DEBUG(("delete_children loop")); -#if H5_VERSION_GE(1,12,0) +#if ADFH_HDF5_HAVE_112_API if (! is_link(id)) H5Literate_by_name2(id, name, H5_INDEX_CRT_ORDER, H5_ITER_INC, NULL, delete_children, data, H5P_DEFAULT); #else if (! is_link(id)) H5Literate_by_name(id, name, H5_INDEX_CRT_ORDER, H5_ITER_INC, NULL, delete_children, data, H5P_DEFAULT); @@ -1428,7 +1443,7 @@ static herr_t fix_dimensions(hid_t id, const char *name, const H5L_info_t* linfo if (*name != D_PREFIX && (gid = H5Gopen2(id, name, H5P_DEFAULT)) >= 0 && !get_str_att(gid, A_TYPE, type, &err) && strcmp(type, ADFH_LK)) { -#if H5_VERSION_GE(1,12,0) +#if ADFH_HDF5_HAVE_112_API H5Literate2(gid, H5_INDEX_CRT_ORDER, H5_ITER_NATIVE, NULL, fix_dimensions, NULL); #else H5Literate(gid, H5_INDEX_CRT_ORDER, H5_ITER_NATIVE, NULL, fix_dimensions, NULL); @@ -1448,12 +1463,14 @@ static herr_t fix_dimensions(hid_t id, const char *name, const H5L_info_t* linfo void ADFH_Configure(const int option, const void *value, int *err) { if (option == ADFH_CONFIG_RESET && (int)((size_t)value == ADFH_CONFIG_RESET_HDF5)) { - core_vfd = ADFH_CONFIG_DEFAULT; - h5pset_alignment_threshold = ADFH_CONFIG_DEFAULT; - h5pset_alignment_alignment = ADFH_CONFIG_DEFAULT; - h5pset_meta_block_size_size = ADFH_CONFIG_DEFAULT; - h5pset_buffer_size_size = ADFH_CONFIG_DEFAULT; - h5pset_sieve_buf_size_size = ADFH_CONFIG_DEFAULT; + core_vfd = ADFH_CONFIG_DEFAULT; + h5pset_alignment_threshold = ADFH_CONFIG_DEFAULT; + h5pset_alignment_alignment = ADFH_CONFIG_DEFAULT; + h5pset_meta_block_size_size = ADFH_CONFIG_DEFAULT; + h5pset_buffer_size_size = ADFH_CONFIG_DEFAULT; + h5pset_sieve_buf_size_size = ADFH_CONFIG_DEFAULT; + h5pset_elink_file_cache_size_size = ADFH_CONFIG_DEFAULT; + set_error(NO_ERROR, err); return; } @@ -1498,6 +1515,10 @@ void ADFH_Configure(const int option, const void *value, int *err) h5pset_sieve_buf_size_size = (hsize_t)value; set_error(NO_ERROR, err); } + else if (option == ADFH_CONFIG_ELINK_FILE_CACHE_SIZE) { + h5pset_elink_file_cache_size_size = (unsigned)((size_t)value); + set_error(NO_ERROR, err); + } #if CG_BUILD_PARALLEL else if (option == ADFH_CONFIG_MPI_COMM) { MPI_Comm* comm = (MPI_Comm*)value; @@ -1550,7 +1571,7 @@ void ADFH_Move_Child(const double pid, /* check that node is actually child of the parent */ -#if H5_VERSION_GE(1,12,0) +#if ADFH_HDF5_HAVE_112_API if (H5Oget_info_by_name3(hid, ".", &stat, H5O_INFO_BASIC, H5P_DEFAULT) < 0 || !H5Literate2(hpid, H5_INDEX_CRT_ORDER, H5_ITER_NATIVE, NULL, compare_children, (void *)&stat)) { #else @@ -1606,7 +1627,7 @@ void ADFH_Move_Child(const double pid, set_int_att(hid, A_ORDER, new_order, err)) return; /*see if we need to decrement any node _orders under the old parent*/ -#if H5_VERSION_GE(1,12,0) +#if ADFH_HDF5_HAVE_112_API *err = H5Literate2(hpid, H5_INDEX_CRT_ORDER, H5_ITER_INC, NULL, fix_order, (void *)&old_order); #else *err = H5Literate(hpid, H5_INDEX_CRT_ORDER, H5_ITER_INC, NULL, fix_order, (void *)&old_order); @@ -1717,7 +1738,7 @@ void ADFH_Get_Label(const double id, { hid_t hid; char bufflabel[ADF_LABEL_LENGTH+1] = ""; - ADFH_DEBUG((">ADFH_Get_Label [%d]",id)); + ADFH_DEBUG((">ADFH_Get_Label [%f]",id)); if (label == NULL) { set_error(NULL_STRING_POINTER, err); @@ -1792,7 +1813,7 @@ void ADFH_Create(const double pid, new_int_att(gid, A_FLAGS, mta_root->g_flags, err)) return; #else int order = 0; -#if H5_VERSION_GE(1,12,0) +#if ADFH_HDF5_HAVE_112_API H5Literate2(hpid, H5_INDEX_CRT_ORDER, H5_ITER_INC, NULL, count_children, (void *)&order); #else H5Literate(hpid, H5_INDEX_CRT_ORDER, H5_ITER_INC, NULL, count_children, (void *)&order); @@ -1838,7 +1859,7 @@ void ADFH_Delete(const double pid, /* check that node is actually child of the parent */ -#if H5_VERSION_GE(1,12,0) +#if ADFH_HDF5_HAVE_112_API if (H5Oget_info_by_name3(hid, ".", &stat, H5O_INFO_BASIC, H5P_DEFAULT) < 0 || !H5Literate2(hpid, H5_INDEX_CRT_ORDER, H5_ITER_INC, NULL, compare_children, (void *)&stat)){ #else @@ -1862,7 +1883,7 @@ void ADFH_Delete(const double pid, if (! is_link(hid)) { -#if H5_VERSION_GE(1,12,0) +#if ADFH_HDF5_HAVE_112_API H5Literate2(hid, H5_INDEX_CRT_ORDER, H5_ITER_INC, NULL, delete_children, NULL); #else H5Literate(hid, H5_INDEX_CRT_ORDER, H5_ITER_INC, NULL, delete_children, NULL); @@ -1877,7 +1898,7 @@ void ADFH_Delete(const double pid, /* decrement node orders */ #ifndef ADFH_NO_ORDER -#if H5_VERSION_GE(1,12,0) +#if ADFH_HDF5_HAVE_112_API *err = H5Literate2(hpid, H5_INDEX_CRT_ORDER, H5_ITER_INC, NULL, fix_order, (void *)&old_order); #else *err = H5Literate(hpid, H5_INDEX_CRT_ORDER, H5_ITER_INC, NULL, fix_order, (void *)&old_order); @@ -1906,10 +1927,10 @@ void ADFH_Number_of_Children(const double id, *number = 0; if ((hid = open_node(id, err)) >= 0) { -#if H5_VERSION_GE(1,12,0) - H5Literate2(hid, H5_INDEX_CRT_ORDER, H5_ITER_NATIVE, &gskip, count_children, (void *)number); +#if ADFH_HDF5_HAVE_112_API + H5Literate2(hid, mta_root->link_create_order, H5_ITER_NATIVE, &gskip, count_children, (void *)number); #else - H5Literate(hid, H5_INDEX_CRT_ORDER, H5_ITER_NATIVE, &gskip, count_children, (void *)number); + H5Literate(hid, mta_root->link_create_order, H5_ITER_NATIVE, &gskip, count_children, (void *)number); #endif H5Gclose(hid); } @@ -1928,8 +1949,6 @@ void ADFH_Get_Node_ID(const double pid, hid_t sid, hpid; to_HDF_ID(pid,hpid); - ADFH_DEBUG((">ADFH_Get_Node_ID [%s][%d]",name,hpid)); - if (name == NULL) { set_error(NULL_STRING_POINTER, err); return; @@ -1939,6 +1958,8 @@ void ADFH_Get_Node_ID(const double pid, return; } + ADFH_DEBUG((">ADFH_Get_Node_ID [%s][%d]",name,hpid)); + *id = 0; set_error(NO_ERROR, err); if (*name == '/') { @@ -2011,11 +2032,10 @@ void ADFH_Children_Names(const double pid, #ifdef ADFH_NO_ORDER mta_root->i_count = 0; #endif - /*initialize names to null*/ - memset(names, 0, ilen*name_length); + memset(names, 0, (size_t)ilen*(size_t)name_length); if ((hpid = open_node(pid, err)) >= 0) { -#if H5_VERSION_GE(1,12,0) +#if ADFH_HDF5_HAVE_112_API H5Literate2(hpid,H5_INDEX_CRT_ORDER,H5_ITER_INC, NULL,children_names,(void *)names); #else @@ -2024,7 +2044,7 @@ void ADFH_Children_Names(const double pid, #endif if (names[0]==0) { -#if H5_VERSION_GE(1,12,0) +#if ADFH_HDF5_HAVE_112_API H5Literate2(hpid,H5_INDEX_NAME,H5_ITER_INC, NULL,children_names,(void *)names); #else @@ -2065,22 +2085,17 @@ void ADFH_Children_IDs(const double pid, mta_root->i_count = 0; #endif if ((hpid = open_node(pid, err)) >= 0) { -#if H5_VERSION_GE(1,12,0) - H5Literate2(hpid,H5_INDEX_CRT_ORDER,H5_ITER_INC, +#if ADFH_HDF5_HAVE_112_API + H5Literate2(hpid,mta_root->link_create_order,H5_ITER_INC, NULL,children_ids,(void *)IDs); #else - H5Literate(hpid,H5_INDEX_CRT_ORDER,H5_ITER_INC, + H5Literate(hpid,mta_root->link_create_order,H5_ITER_INC, NULL,children_ids,(void *)IDs); #endif if (IDs[0]==-1) { -#if H5_VERSION_GE(1,12,0) - H5Literate2(hpid,H5_INDEX_NAME,H5_ITER_INC, - NULL,children_ids,(void *)IDs); -#else - H5Literate(hpid,H5_INDEX_NAME,H5_ITER_INC, - NULL,children_ids,(void *)IDs); -#endif + set_error(CHILDREN_IDS_NOT_FOUND, err); + return; } H5Gclose(hpid); } @@ -2114,8 +2129,6 @@ void ADFH_Database_Open(const char *name, int i, pos, mode; hid_t g_propfileopen; - ADFH_DEBUG(("ADFH_Database_Open [%s]",name)); - /* to be thread safe, should have critical section here */ if (mta_root==NULL) { @@ -2128,6 +2141,8 @@ void ADFH_Database_Open(const char *name, */ mta_root->g_flags = 1; + mta_root->link_create_order = H5_INDEX_CRT_ORDER; + #ifndef ADFH_DEBUG_ON H5Eset_auto2(H5E_DEFAULT, NULL, NULL); #endif @@ -2156,6 +2171,8 @@ void ADFH_Database_Open(const char *name, return; } + ADFH_DEBUG(("ADFH_Database_Open [%s]",name)); + /* get open mode */ strncpy(buff, stat, 9); @@ -2230,14 +2247,17 @@ void ADFH_Database_Open(const char *name, /* HDF5 tuning parameters */ - /* http://www.hdfgroup.org/HDF5/doc/RM/H5P/H5Pset_meta_block_size.htm - * default setting is 2048 bytes + /* https://docs.hdfgroup.org/hdf5/develop/group___f_a_p_l.html#title72 + * 'Sets the minimum metadata block size.' + * Default setting is 2048 bytes. */ if ( h5pset_meta_block_size_size != ADFH_CONFIG_DEFAULT ) { H5Pset_meta_block_size(g_propfileopen, h5pset_meta_block_size_size); } - /* http://hdfgroup.org/HDF5/doc/RM/H5P/H5Pset_alignment.htm - * attention: this can increase filesize dramatically if lots of small datasets + /* https://docs.hdfgroup.org/hdf5/develop/group___f_a_p_l.html#title41 + * 'Sets alignment properties of a file access property list.' + * Default is no alignment. + * ATTENTION: this can increase filesize dramatically if lots of small datasets */ if ( h5pset_alignment_alignment != ADFH_CONFIG_DEFAULT ) { H5Pset_alignment(g_propfileopen, @@ -2245,42 +2265,36 @@ void ADFH_Database_Open(const char *name, h5pset_alignment_alignment); } - /* http://www.hdfgroup.org/HDF5/doc/RM/H5P/H5Pset_buffer.htm - * 1 MByte is default of hdf5 + /* https://docs.hdfgroup.org/hdf5/develop/group___d_x_p_l.html#title16 + * 'Sets type conversion and background buffers. + * 1 MByte is default. */ if ( h5pset_buffer_size_size != ADFH_CONFIG_DEFAULT ) { void *tconv=NULL; void *bkg=NULL; H5Pset_buffer(g_propfileopen, h5pset_buffer_size_size, tconv, bkg); } - /* http://hdfgroup.org/HDF5/doc/RM/RM_H5P.html#Property-SetSieveBufSize - * '.. used by file drivers that are capable of using data sieving' - * 1 MByte is default of hdf5 + /* https://docs.hdfgroup.org/hdf5/develop/group___f_a_p_l.html#title78 + * 'Used by file drivers that are capable of using data sieving.' + * 1 MByte is default. */ if ( h5pset_sieve_buf_size_size != ADFH_CONFIG_DEFAULT ) { H5Pset_sieve_buf_size(g_propfileopen, h5pset_sieve_buf_size_size); } + /* https://docs.hdfgroup.org/hdf5/develop/group___f_a_p_l.html#title48 + * 'Sets the number of files that can be held open in an external link open file cache.' + * 0 size is default. + */ + if ( h5pset_elink_file_cache_size_size != ADFH_CONFIG_DEFAULT ) { + H5Pset_elink_file_cache_size(g_propfileopen, h5pset_elink_file_cache_size_size); + } + #ifdef ADFH_H5F_CLOSE_STRONG /* set access property to close all open accesses when file closed */ H5Pset_fclose_degree(g_propfileopen, H5F_CLOSE_STRONG); #endif - /* Patch to read file created with CGNS 3.3 and hdf5 > 1.8 */ - if (mode == ADFH_MODE_RDO) { - H5Pset_libver_bounds(g_propfileopen, - H5F_LIBVER_LATEST, H5F_LIBVER_LATEST); - } - else { - /* Compatibility with V1.8 */ - H5Pset_libver_bounds(g_propfileopen, -#if H5_VERSION_GE(1,10,3) - H5F_LIBVER_V18, H5F_LIBVER_V18); -#else - H5F_LIBVER_LATEST, H5F_LIBVER_LATEST); -#endif - } - /* open the file */ #if CG_BUILD_PARALLEL @@ -2314,41 +2328,61 @@ void ADFH_Database_Open(const char *name, set_error(NO_ERROR, err); if (mode == ADFH_MODE_NEW) { + + /* Compatibility with V1.8 */ + H5Pset_libver_bounds(g_propfileopen, +#if ADFH_HDF5_HAVE_110_API + H5F_LIBVER_V18, H5F_LIBVER_V18); +#else + H5F_LIBVER_LATEST, H5F_LIBVER_LATEST); +#endif + hid_t g_propfilecreate = H5Pcreate(H5P_FILE_CREATE); - /* HDF5 tuning parameters */ + /* HDF5 tuning parameters */ - /* http://www.hdfgroup.org/HDF5/doc/RM/H5P/H5Pset_meta_block_size.htm - * default setting is 2048 bytes - */ - if ( h5pset_meta_block_size_size != ADFH_CONFIG_DEFAULT ) { - H5Pset_meta_block_size(g_propfileopen, h5pset_meta_block_size_size); - } + /* https://docs.hdfgroup.org/hdf5/develop/group___f_a_p_l.html#title72 + * 'Sets the minimum metadata block size.' + * Default setting is 2048 bytes. + */ + if ( h5pset_meta_block_size_size != ADFH_CONFIG_DEFAULT ) { + H5Pset_meta_block_size(g_propfileopen, h5pset_meta_block_size_size); + } + /* https://docs.hdfgroup.org/hdf5/develop/group___f_a_p_l.html#title41 + * 'Sets alignment properties of a file access property list.' + * Default is no alignment. + * ATTENTION: this can increase filesize dramatically if lots of small datasets + */ + if ( h5pset_alignment_alignment != ADFH_CONFIG_DEFAULT ) { + H5Pset_alignment(g_propfileopen, + h5pset_alignment_threshold, + h5pset_alignment_alignment); + } - /* http://hdfgroup.org/HDF5/doc/RM/H5P/H5Pset_alignment.htm - * attention: this can increase filesize dramatically if lots of small datasets - */ - if ( h5pset_alignment_alignment != ADFH_CONFIG_DEFAULT ) { - H5Pset_alignment(g_propfileopen, - h5pset_alignment_threshold, - h5pset_alignment_alignment); - } + /* https://docs.hdfgroup.org/hdf5/develop/group___d_x_p_l.html#title16 + * 'Sets type conversion and background buffers. + * 1 MByte is default. + */ + if ( h5pset_buffer_size_size != ADFH_CONFIG_DEFAULT ) { + void *tconv=NULL; void *bkg=NULL; + H5Pset_buffer(g_propfileopen, h5pset_buffer_size_size, tconv, bkg); + } - /* http://www.hdfgroup.org/HDF5/doc/RM/H5P/H5Pset_buffer.htm - * 1 MByte is default of hdf5 - */ - if ( h5pset_buffer_size_size != ADFH_CONFIG_DEFAULT) { - void *tconv=NULL; void *bkg=NULL; - H5Pset_buffer(g_propfileopen, h5pset_buffer_size_size, tconv, bkg); - } + /* https://docs.hdfgroup.org/hdf5/develop/group___f_a_p_l.html#title78 + * 'Used by file drivers that are capable of using data sieving.' + * 1 MByte is default. + */ + if ( h5pset_sieve_buf_size_size != ADFH_CONFIG_DEFAULT ) { + H5Pset_sieve_buf_size(g_propfileopen, h5pset_sieve_buf_size_size); + } - /* http://hdfgroup.org/HDF5/doc/RM/RM_H5P.html#Property-SetSieveBufSize - * '.. used by file drivers that are capable of using data sieving' - * 1 MByte is default of hdf5 - */ - if ( h5pset_sieve_buf_size_size != ADFH_CONFIG_DEFAULT) { - H5Pset_sieve_buf_size(g_propfileopen, h5pset_sieve_buf_size_size); - } + /* https://docs.hdfgroup.org/hdf5/develop/group___f_a_p_l.html#title48 + * 'Sets the number of files that can be held open in an external link open file cache.' + * 0 size is default. + */ + if ( h5pset_elink_file_cache_size_size != ADFH_CONFIG_DEFAULT ) { + H5Pset_elink_file_cache_size(g_propfileopen, h5pset_elink_file_cache_size_size); + } #if 0 /* MSB -- DISABLED as it is not compatible with HDF5 1.8 file format, need to resolve this CGNS-166 */ #if HDF5_HAVE_FILE_SPACE_STRATEGY @@ -2360,6 +2394,7 @@ void ADFH_Database_Open(const char *name, (prop set to file creation )*/ H5Pset_link_creation_order(g_propfilecreate, H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED); + fid = H5Fcreate(name, H5F_ACC_TRUNC, g_propfilecreate, g_propfileopen); H5Pclose(g_propfilecreate); H5Pclose(g_propfileopen); @@ -2381,7 +2416,7 @@ void ADFH_Database_Open(const char *name, } } else { -#if H5_VERSION_GE(1,12,0) +#if ADFH_HDF5_HAVE_112_API if (H5Fis_accessible(name, H5P_DEFAULT) <= 0) { #else if (H5Fis_hdf5(name) <= 0) { @@ -2390,29 +2425,80 @@ void ADFH_Database_Open(const char *name, set_error(ADFH_ERR_NOT_HDF5_FILE, err); return; } + #if CG_BUILD_PARALLEL #if HDF5_HAVE_COLL_METADATA H5Pset_all_coll_metadata_ops( g_propfileopen, 1 ); #endif #endif if (mode == ADFH_MODE_RDO) { + /* Patch to read file created with CGNS 3.3 and hdf5 > 1.8 */ + H5Pset_libver_bounds(g_propfileopen, + H5F_LIBVER_LATEST, H5F_LIBVER_LATEST); fid = H5Fopen(name, H5F_ACC_RDONLY, g_propfileopen); } else { + +#if !ADFH_HDF5_HAVE_110_API + H5Pset_libver_bounds(g_propfileopen, + H5F_LIBVER_LATEST, H5F_LIBVER_LATEST); +#endif + fid = H5Fopen(name, H5F_ACC_RDWR, g_propfileopen); + +#if ADFH_HDF5_HAVE_110_API + hid_t access_fapl = H5Fget_access_plist(fid); + + H5F_libver_t low, high; /* File format bounds */ + H5Pget_libver_bounds(access_fapl, &low, &high); + + if(low > H5F_LIBVER_V18) { + /* NOTE: HDF5 can not downgrade to a lower version bound (which can be done with h5repack), so + the best that can be done is not to use a version higher than the lower bound. */ + H5Fset_libver_bounds(fid, low, low); + } else { + H5Fset_libver_bounds(fid, H5F_LIBVER_V18, H5F_LIBVER_V18); + } + + H5Pclose(access_fapl); +#endif + } H5Pclose(g_propfileopen); if (fid < 0) { set_error(FILE_OPEN_ERROR, err); return; } + + /* + NOTE: Creation order was set by default in CGNS 3.1.3, so a + CGNS file created by earlier versions will not have this set. + Therefore, it should not be automatically assumed to be set in + H5Literate. + */ + gid = H5Gopen2(fid, "/", H5P_DEFAULT); + + /* Obtain the group creation flags and check for link creation ordering. */ + { + hid_t pid; + unsigned int crt_order_flags; + pid = H5Gget_create_plist(gid); + H5Pget_link_creation_order(pid, &crt_order_flags); + if (crt_order_flags == 0) { + mta_root->link_create_order = H5_INDEX_NAME; + } else { + mta_root->link_create_order = H5_INDEX_CRT_ORDER; + } + H5Pclose(pid); + } + #ifdef ADFH_FORTRAN_INDEXING if (mode != ADFH_MODE_RDO && child_exists(gid, D_OLDVERS)) { -#if H5_VERSION_GE(1,12,0) - H5Literate2(gid, H5_INDEX_CRT_ORDER, H5_ITER_INC, NULL, fix_dimensions, NULL); +#if ADFH_HDF5_HAVE_112_API + H5Literate2(gid, mta_root->link_create_order, H5_ITER_INC, NULL, fix_dimensions, NULL); #else - H5Literate(gid, H5_INDEX_CRT_ORDER, H5_ITER_INC, NULL, fix_dimensions, NULL); + H5Literate(gid, mta_root->link_create_order, H5_ITER_INC, NULL, fix_dimensions, NULL); #endif H5Lmove(gid, D_OLDVERS, gid, D_VERSION, H5P_DEFAULT, H5P_DEFAULT); } @@ -2437,7 +2523,7 @@ void ADFH_Database_Valid(const char *name, if (NULL == name || 0 == *name) *err = NULL_STRING_POINTER; else -#if H5_VERSION_GE(1,12,0) +#if ADFH_HDF5_HAVE_112_API *err = H5Fis_accessible(name, H5P_DEFAULT); #else *err = H5Fis_hdf5(name); @@ -2510,7 +2596,7 @@ void ADFH_Database_Delete(const char *name, { ADFH_DEBUG(("ADFH_Database_Delete [%s]",name)); -#if H5_VERSION_GE(1,12,0) +#if ADFH_HDF5_HAVE_112_API if (H5Fis_accessible(name, H5P_DEFAULT) <=0) #else if (H5Fis_hdf5(name) <= 0) @@ -2572,7 +2658,7 @@ void ADFH_Database_Close(const double root, nobj = H5Fget_obj_count(fid, H5F_OBJ_DATATYPE|H5F_OBJ_LOCAL); #ifdef ADFH_DEBUG_ON - printf("%s close DataType [%d] HIDs\n",ADFH_PREFIX,nobj); + printf("%s close DataType [%zd] HIDs\n",ADFH_PREFIX,nobj); #endif if (nobj) { H5Fget_obj_ids(fid, H5F_OBJ_DATATYPE|H5F_OBJ_LOCAL, -1, objs); @@ -2584,7 +2670,7 @@ void ADFH_Database_Close(const double root, nobj = H5Fget_obj_count(fid, H5F_OBJ_DATASET|H5F_OBJ_LOCAL); #ifdef ADFH_DEBUG_ON - printf("%s close DataSet [%d] HIDs\n",ADFH_PREFIX,nobj); + printf("%s close DataSet [%zd] HIDs\n",ADFH_PREFIX,nobj); #endif if (nobj) { H5Fget_obj_ids(fid, H5F_OBJ_DATASET|H5F_OBJ_LOCAL, -1, objs); @@ -2596,7 +2682,7 @@ void ADFH_Database_Close(const double root, nobj = H5Fget_obj_count(fid, H5F_OBJ_ATTR|H5F_OBJ_LOCAL); #ifdef ADFH_DEBUG_ON - printf("%s close Attr [%d] HIDs\n",ADFH_PREFIX,nobj); + printf("%s close Attr [%zd] HIDs\n",ADFH_PREFIX,nobj); #endif if (nobj) { H5Fget_obj_ids(fid, H5F_OBJ_ATTR|H5F_OBJ_LOCAL, -1, objs); @@ -2608,7 +2694,7 @@ void ADFH_Database_Close(const double root, nobj = H5Fget_obj_count(fid, H5F_OBJ_GROUP|H5F_OBJ_LOCAL); #ifdef ADFH_DEBUG_ON - printf("%s close Group [%d] HIDs\n",ADFH_PREFIX,nobj); + printf("%s close Group [%zd] HIDs\n",ADFH_PREFIX,nobj); #endif if (nobj) { H5Fget_obj_ids(fid, H5F_OBJ_GROUP|H5F_OBJ_LOCAL, -1, objs); @@ -3229,7 +3315,7 @@ void ADFH_Library_Version(char *version, return; } H5get_libversion(&maj, &min, &rel); - sprintf(version, "HDF5 Version %d.%d.%d", maj, min, rel); + sprintf(version, "HDF5 Version %u.%u.%u", maj, min, rel); set_error(NO_ERROR, err); } diff --git a/externals/cgns/adfh/ADFH.h b/externals/cgns/adfh/ADFH.h index 2dbd200f33b..d2a07d03b8f 100644 --- a/externals/cgns/adfh/ADFH.h +++ b/externals/cgns/adfh/ADFH.h @@ -117,6 +117,7 @@ #define NULL_NODEID_POINTER 62 #define MAX_FILE_SIZE_EXCEEDED 63 #define MAX_INT32_SIZE_EXCEEDED 64 +#define CHILDREN_IDS_NOT_FOUND 65 #endif /* ADF_INCLUDE */ @@ -175,7 +176,8 @@ #define ADFH_CONFIG_ALIGNMENT 6 #define ADFH_CONFIG_MD_BLOCK_SIZE 7 #define ADFH_CONFIG_HDF5_BUFFER 8 -#define ADFH_CONFIG_HDF5_SIEVE_BUF_SIZE 9 +#define ADFH_CONFIG_HDF5_SIEVE_BUF_SIZE 9 +#define ADFH_CONFIG_ELINK_FILE_CACHE_SIZE 10 #define ADFH_CONFIG_RESET 800 #define ADFH_CONFIG_RESET_HDF5 1 diff --git a/externals/cgns/cg_hashmap.c b/externals/cgns/cg_hashmap.c index 5b47a7978ba..ade13c4dca3 100644 --- a/externals/cgns/cg_hashmap.c +++ b/externals/cgns/cg_hashmap.c @@ -204,10 +204,17 @@ cgi_estimate_keysize(map_ssize_t n) */ #define GROWTH_RATE(d) ((d)->ma_used*2) +/* Dirty trick for unsupported flexible array init */ +struct _static_hashmapobject { + map_ssize_t table_size; + map_ssize_t map_usable; + map_ssize_t map_nentries; + char map_indices[8]; /* we define the size of the array to have a known struct at compile time */ +}; /* This immutable, empty cgns_hashmap_keyobject is used for HashMap_Clear() * (which cannot fail and thus can do no allocation). */ -static cgns_hashmap_keyobject empty_keys_struct = { +static struct _static_hashmapobject empty_keys_struct = { 1, /* table_size */ 0, /* map_usable (immutable) */ 0, /* map_nentries */ @@ -215,7 +222,7 @@ static cgns_hashmap_keyobject empty_keys_struct = { MAPIX_EMPTY, MAPIX_EMPTY, MAPIX_EMPTY, MAPIX_EMPTY}, /* map_indices */ }; -#define MAP_EMPTY_KEYS &empty_keys_struct +#define MAP_EMPTY_KEYS (cgns_hashmap_keyobject *)&empty_keys_struct static cgns_hashmap_keyobject* cgi_new_keys_object(map_ssize_t size) diff --git a/externals/cgns/cgns_error.c b/externals/cgns/cgns_error.c index e5d01d5e632..232a978f6fc 100644 --- a/externals/cgns/cgns_error.c +++ b/externals/cgns/cgns_error.c @@ -32,7 +32,7 @@ char cgns_error_mess[200] = "no CGNS error reported"; CGNSDLL void cgi_error(const char *format, ...) { va_list arg; va_start(arg, format); - vsprintf(cgns_error_mess,format, arg); + vsnprintf(cgns_error_mess, 200, format, arg); va_end(arg); if (cgns_error_handler) (*cgns_error_handler)(1, cgns_error_mess); @@ -43,7 +43,7 @@ CGNSDLL void cgi_warning(const char *format, ...) { va_start(arg, format); if (cgns_error_handler) { char warning_msg[200]; - vsprintf(warning_msg, format, arg); + vsnprintf(warning_msg, 200, format, arg); (*cgns_error_handler)(0, warning_msg); } else { diff --git a/externals/cgns/cgns_header.h b/externals/cgns/cgns_header.h index 140321b6b14..46e4b5e883c 100644 --- a/externals/cgns/cgns_header.h +++ b/externals/cgns/cgns_header.h @@ -1034,8 +1034,8 @@ CGNSDLL cgns_subreg *cgi_get_subreg (cgns_file *cg, int B, int Z, int S); CGNSDLL int cgi_update_posit(int cnt, int *index, char **label); CGNSDLL int cgi_set_posit(int fn, int B, int n, int *index, char **label); CGNSDLL int cgi_posit_id(double *posit_id); -CGNSDLL cgns_posit *cgi_get_posit(); -CGNSDLL int cgi_posit_index_dim(); +CGNSDLL cgns_posit *cgi_get_posit(void); +CGNSDLL int cgi_posit_index_dim(void); /* retrieve memory address of multiple patch children knowing their parent label (posit_label) and their parent memory address (posit) */ @@ -1067,7 +1067,7 @@ cgns_dataset * cgi_bcdataset_address(int local_mode, int given_no, char const *given_name, int *ier); /* read CGNS file into internal database */ -int cgi_read(); +int cgi_read(void); int cgi_read_base(cgns_base *base); int cgi_read_zone(cgns_zone *zone); int cgi_read_zonetype(double parent_id, char_33 parent_name, CGNS_ENUMT(ZoneType_t) *type); @@ -1157,7 +1157,7 @@ int cgi_write_zboco(double parent_id, cgns_zboco *zboco); int cgi_write_boco(double parent_id, cgns_boco *boco); int cgi_write_dataset(double parent_id, const char *label, cgns_dataset *dataset); int cgi_write_bcdata(double bcdata_id, cgns_bcdata *bcdata); -int cgi_write_ptset(double id, char_33 name, cgns_ptset *ptset, +int cgi_write_ptset(double id, char *name, cgns_ptset *ptset, int ndim, void *ptset_ptr); int cgi_write_equations(double parent_id, cgns_equations *equations); int cgi_write_model(double parent_id, cgns_model *model); @@ -1261,7 +1261,7 @@ int cgi_check_strlen(char const * string); int cgi_check_strlen_x2(char const *string); int cgi_check_mode(char const * filename, int file_mode, int mode_wanted); const char *cgi_adf_datatype(CGNS_ENUMT(DataType_t) type); -CGNSDLL CGNS_ENUMT(DataType_t) cgi_datatype(cchar_33 adf_type); +CGNSDLL CGNS_ENUMT(DataType_t) cgi_datatype(const char *adf_type); int cgi_check_dimensions(int ndims, cglong_t *dims); int cgi_check_location(int dim, CGNS_ENUMT(ZoneType_t) type, CGNS_ENUMT(GridLocation_t) loc); diff --git a/externals/cgns/cgns_internals.c b/externals/cgns/cgns_internals.c index 1077afd3bb8..0fd77e829bd 100644 --- a/externals/cgns/cgns_internals.c +++ b/externals/cgns/cgns_internals.c @@ -2126,7 +2126,7 @@ int cgi_read_conn(cgns_conn *conn) /* check */ if (cg->filetype == CGIO_FILE_ADF || cg->filetype == CGIO_FILE_ADF2) { if (conn->ptset.id==0) { - cgi_error("Niether PointRange nor PointList defined for GridConnectivity_t '%s'", + cgi_error("Neither PointRange nor PointList defined for GridConnectivity_t '%s'", conn->name); return CG_ERROR; } @@ -2136,7 +2136,7 @@ int cgi_read_conn(cgns_conn *conn) hid_t hid; to_HDF_ID(conn->ptset.id, hid); if (hid==0) { - cgi_error("Niether PointRange nor PointList defined for GridConnectivity_t '%s'", + cgi_error("Neither PointRange nor PointList defined for GridConnectivity_t '%s'", conn->name); return CG_ERROR; } @@ -8282,12 +8282,13 @@ int cgi_write_bcdata(double bcdata_id, cgns_bcdata *bcdata) return CG_OK; } -int cgi_write_ptset(double parent_id, char_33 name, cgns_ptset *ptset, +int cgi_write_ptset(double parent_id, char *name, cgns_ptset *ptset, int ndim, void *ptset_ptr) { cgsize_t dim_vals[12]; int num_dim; char_33 label; + int HDF5storage_type_original = HDF5storage_type; if (ptset->link) { return cgi_write_link(parent_id, name, ptset->link, &ptset->id); @@ -8305,10 +8306,19 @@ int cgi_write_ptset(double parent_id, char_33 name, cgns_ptset *ptset, dim_vals[1]=ptset->npts; num_dim = 2; + // PointLists should be contiguous for parallel reading/writing + if (ptset->type == CGNS_ENUMV(PointList) || + ptset->type == CGNS_ENUMV(PointListDonor) || + ptset->type == CGNS_ENUMV(ElementList) || + ptset->type == CGNS_ENUMV(CellListDonor)) { + HDF5storage_type = CG_CONTIGUOUS; + } + /* Create the node */ if (cgi_new_node(parent_id, name, label, &ptset->id, ptset->data_type, num_dim, dim_vals, ptset_ptr)) return CG_ERROR; + HDF5storage_type = HDF5storage_type_original; return CG_OK; } @@ -9945,15 +9955,15 @@ const char *cgi_adf_datatype(CGNS_ENUMV(DataType_t) type) return "NULL"; } -CGNS_ENUMT(DataType_t) cgi_datatype(cchar_33 adf_type) +CGNS_ENUMT(DataType_t) cgi_datatype(char const *adf_type) { - if (strcmp(adf_type, "I4") == 0) return CGNS_ENUMV(Integer); - if (strcmp(adf_type, "I8") == 0) return CGNS_ENUMV(LongInteger); - if (strcmp(adf_type, "R4") == 0) return CGNS_ENUMV(RealSingle); - if (strcmp(adf_type, "R8") == 0) return CGNS_ENUMV(RealDouble); - if (strcmp(adf_type, "C1") == 0) return CGNS_ENUMV(Character); - if (strcmp(adf_type, "X4") == 0) return CGNS_ENUMV(ComplexSingle); - if (strcmp(adf_type, "X8") == 0) return CGNS_ENUMV(ComplexDouble); + if (strncmp(adf_type, "I4", 33) == 0) return CGNS_ENUMV(Integer); + if (strncmp(adf_type, "I8", 33) == 0) return CGNS_ENUMV(LongInteger); + if (strncmp(adf_type, "R4", 33) == 0) return CGNS_ENUMV(RealSingle); + if (strncmp(adf_type, "R8", 33) == 0) return CGNS_ENUMV(RealDouble); + if (strncmp(adf_type, "C1", 33) == 0) return CGNS_ENUMV(Character); + if (strncmp(adf_type, "X4", 33) == 0) return CGNS_ENUMV(ComplexSingle); + if (strncmp(adf_type, "X8", 33) == 0) return CGNS_ENUMV(ComplexDouble); return CGNS_ENUMV(DataTypeNull); } @@ -11421,6 +11431,13 @@ static int cgi_next_posit(char *label, int index, char *name) label, index + 1, b->user_data[index].id); } } + else if (0 == strcmp (label, "IndexArray_t")) { + if (b->ptset && + (index == 1 || 0 == strcmp (b->ptset->name, name))) { + return cgi_add_posit((void *)b->ptset, + label, 1, b->ptset->id); + } + } else return CG_INCORRECT_PATH; } diff --git a/externals/cgns/cgns_io.h b/externals/cgns/cgns_io.h index e62c0d185e1..d9d49a8aa02 100644 --- a/externals/cgns/cgns_io.h +++ b/externals/cgns/cgns_io.h @@ -121,7 +121,7 @@ CGEXTERN int cgio_configure ( void *value ); -CGEXTERN void cgio_cleanup (); +CGEXTERN void cgio_cleanup (void); CGEXTERN int cgio_check_file ( const char *filename, diff --git a/externals/cgns/cgnslib.c b/externals/cgns/cgnslib.c index 387d0e3de75..6aa344c5e91 100644 --- a/externals/cgns/cgnslib.c +++ b/externals/cgns/cgnslib.c @@ -22,6 +22,64 @@ freely, subject to the following restrictions: * Revisions: * ***********************************************************************/ +/** + * \defgroup AccessingANode Accessing a node + * \defgroup ArbitraryGridMotion Arbitrary Grid Motion + * \defgroup AuxiliaryModel Auxiliary Model + * \defgroup Axisymmetry Axisymmetry + * \defgroup BCData Boundary Condition Data + * \defgroup BCDataset Boundary Condition Datasets + * \defgroup BaseIterativeData Base Iterative Data + * \defgroup BoundaryConditionDatasets Boundary Condition Datasets + * \defgroup BoundaryConditionType Boundary Condition Type and Location + * \defgroup CGNSBaseInformation CGNS Base Information + * \defgroup CGNSFamilyBoundaryDefinition Family Boundary Condition + * \defgroup CGNSFamilyDefinition Family Definition + * \defgroup CGNSFamilyHierarchyTreeDefinition Family Hierarchy Tree + * \defgroup CGNSFile File Operations + * \defgroup CGNSGeometryReference Geometry Reference + * \defgroup CGNSInterfaceCGIO Interfacing with CGIO + * \defgroup CGNSInternals Configuring CGNS Internals + * \defgroup CGNSZoneInformation CGNS Zone Information + * \defgroup ConvergenceHistory Convergence History + * \defgroup DataArrays Data Arrays + * \defgroup DataClass Data Class + * \defgroup DataConversionFactors Data Conversion Factors + * \defgroup DeletingANode Deleting a node + * \defgroup DescriptiveText Descriptive Text + * \defgroup DimensionalExponents Dimensional Exponents + * \defgroup DimensionalUnits Dimensional Units + * \defgroup DiscreteData Discrete Data + * \defgroup ElementConnectivity Element Connectivity + * \defgroup FamilyName Family Name + * \defgroup FlowEquationSet Flow Equation Set + * \defgroup FlowSolution Flow Solution + * \defgroup FlowSolutionData Flow Solution Data + * \defgroup FreeingMemory Freeing Memory + * \defgroup GeneralizedConnectivity Generalized Connectivity + * \defgroup GoverningEquations Governing Equations + * \defgroup Gravity Gravity + * \defgroup GridLocation Grid Location + * \defgroup IntegralData Integral Data + * \defgroup Links Links + * \defgroup OneToOneConnectivity One-to-One Connectivity + * \defgroup OrdinalValue Ordinal Value + * \defgroup OversetHoles Overset Holes + * \defgroup PointSets Point Sets + * \defgroup ReferenceState Reference State + * \defgroup RigidGridMotion Rigid Grid Motion + * \defgroup RindLayers Rind Layers + * \defgroup RotatingCoordinates Rotating Coordinates + * \defgroup SimulationType Simulation Type + * \defgroup SpecialBoundaryConditionProperty Special Boundary Condition Property + * \defgroup SpecialGridConnectivityProperty Special Grid Connectivity Property + * \defgroup UserDefinedData User Defined Data + * \defgroup ZoneGridConnectivity Zone Grid Connectivity + * \defgroup ZoneGridCoordinates Zone Grid Coordinates + * \defgroup ZoneIterativeData Zone Iterative Data + * \defgroup ZoneSubregions Zone Subregions + * + **/ #include #include @@ -259,7 +317,7 @@ const char * AverageInterfaceTypeName[NofValidAverageInterfaceTypes] = int n_open = 0; int cgns_file_size = 0; int file_number_offset = 0; -int VersionList[] = {4200, +int VersionList[] = {4500, 4400, 4300, 4200, 4110, 4100, 4000, 3210, 3200, 3140, 3130, 3110, 3100, @@ -317,7 +375,21 @@ void objlist_status(char *tag) * library functions ***********************************************************************/ -/* check for a valid CGNS file */ + +/** + * \ingroup CGNSFile + * + * \brief Check for a valid CGNS file. + * + * \param[in] filename \FILE_filename + * \param[in] file_type \FILE_file_type + * \return \ier + * + * \details For existing files, the function /e cg_is_cgns may be used to determine if a file is a CGNS file or not, and + * the type of file (\p CG_FILE_ADF or \p CG_FILE_HDF5). If the file is a CGNS file, \e cg_is_cgns returns \p CG_OK, + * otherwise \p CG_ERROR is returned and file_type is set to \p CG_FILE_NONE. + * + */ int cg_is_cgns(const char *filename, int *file_type) { @@ -334,12 +406,42 @@ int cg_is_cgns(const char *filename, int *file_type) return ierr ? CG_ERROR : CG_OK; } -/*********************************************************************** - * cg_open(char *filename, int mode, int *file_number) +/** + * \ingroup CGNSFile * - ***********************************************************************/ + * \brief Open a CGNS file. + * + * \param[in] filename \FILE_filename + * \param[in] mode \FILE_mode + * \param[out] fn \FILE_fn + * \return \ier + * + * \details The function \e cg_open must always be the first one called. It opens a CGNS file for reading and/or writing and returns + * an index number \e file_number. + * The index number serves to identify the CGNS file in subsequent function calls. Several CGNS files can be opened simultaneously. The current + * limit on the number of files opened at once depends on the platform. On an SGI workstation, this limit is set at 100 (parameter FOPEN_MAX in stdio.h). + * The file can be opened in one of the following modes: + * + *| | | + *|---|---| + *|__CG_MODE_READ__ | Read only mode. | + *|__CG_MODE_WRITE__| Write only mode. | + *|__CG_MODE_MODIFY__| Reading and/or writing is allowed.| + * + * When the file is opened, if no \e CGNSLibraryVersion_t node is found, a default value of 1.05 is assumed for the CGNS version number. Note that this + * corresponds to an old version of the CGNS standard, that doesn't include many data structures supported by the current standard. + * + * In order to reduce memory usage and improve execution speed, large arrays such as grid coordinates or flow solutions are not actually + * stored in memory. Instead, only basic information about the node is kept, while reads and writes of the data is directly to and from + * the application's memory. An attempt is also made to do the same with unstructured mesh element data. + * + * \note CGNS maintains one-way forward compatibility insofar as any file open and modified by, for example, version major.minor.patch + * will be readable with major.minor.patch< b>+< /b>. It can't be guaranteed the reverse major.minor.patch< b>-< /b> + * compatibility for that file will be true. + * + */ -int cg_open(const char *filename, int mode, int *file_number) +int cg_open(const char *filename, int mode, int *fn) { int cgio, filetype; cgsize_t dim_vals; @@ -385,7 +487,7 @@ int cg_open(const char *filename, int mode, int *file_number) } cg = &(cgns_files[n_cgns_files]); n_cgns_files++; - (*file_number) = n_cgns_files + file_number_offset; + (*fn) = n_cgns_files + file_number_offset; if (cgio_get_file_type(cgio, &filetype)) { cg_io_error("cgio_get_file_type"); @@ -399,7 +501,7 @@ int cg_open(const char *filename, int mode, int *file_number) cg->filetype = filetype; cg->cgio = cgio; cgio_get_root_id(cgio, &cg->rootid); - cg->file_number = (*file_number); + cg->file_number = (*fn); cg->version = 0; cg->deleted = 0; cg->added = 0; @@ -434,7 +536,7 @@ int cg_open(const char *filename, int mode, int *file_number) /* This code allows reading version newer than the lib, as long as the 1st digit of the versions are equal */ if ((cg->version / 1000) > (CGNSLibVersion / 1000)) { - cgi_error("The file %s was written with a more recent version of the CGNS library. You must update your CGNS library before trying to read this file.",filename); + cgi_error("A more recent version of the CGNS library created the file. Therefore, the CGNS library needs updating before reading the file '%s'.",filename); return CG_ERROR; } /* warn only if different in second digit */ @@ -511,17 +613,30 @@ int cg_open(const char *filename, int mode, int *file_number) return CG_OK; } -int cg_version(int file_number, float *FileVersion) +/** + * \ingroup CGNSFile + * + * \brief Get CGNS file version. + * + * \param[in] fn \FILE_fn + * \param[out] version \FILE_version + * \return \ier + * + * \details The function \e cg_version returns the CGNS version number. + * + */ + +int cg_version(int fn, float *version) { int nnod; double *id; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; /* if open in CG_MODE_WRITE */ if (cg->version) { - (*FileVersion)=(float)(cg->version)/1000; + (*version)=(float)(cg->version)/1000; return CG_OK; } @@ -531,7 +646,7 @@ int cg_version(int file_number, float *FileVersion) return CG_ERROR; if (nnod==0) { cg->version=3200; - *FileVersion= (float) 3.20; + *version= (float) 3.20; } else if (nnod!=1) { cgi_error("More then one CGNSLibraryVersion_t node found under ROOT."); return CG_ERROR; @@ -558,9 +673,9 @@ int cg_version(int file_number, float *FileVersion) return CG_ERROR; } /* save data */ - *FileVersion = *((float *)data); + *version = *((float *)data); free(data); - cg->version = (int)(1000.0*(*FileVersion)+0.5); + cg->version = (int)(1000.0*(*version)+0.5); /* To prevent round off error in version number for file of older or current version */ temp_version = cg->version; @@ -580,20 +695,32 @@ int cg_version(int file_number, float *FileVersion) free(id); } #if DEBUG_VERSION - printf("FileVersion=%f\n",*FileVersion); + printf("version=%f\n",*version); printf("cg->version=%d\n",cg->version); #endif return CG_OK; } +/** + * \ingroup CGNSFile + * + * \brief Get CGNS file precision. + * + * \param[in] fn \FILE_fn + * \param[out] precision \FILE_precision + * \return \ier + * + * \details Precision used to write the CGNS file. The \e precision value will be one of 32 (32-bit), 64 (64-bit), or 0 if not known. + * + */ -int cg_precision(int file_number, int *precision) +int cg_precision(int fn, int *precision) { int nb, nz; char_33 data_type; *precision = 0; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; /* if open in CG_MODE_WRITE */ @@ -615,10 +742,24 @@ int cg_precision(int file_number, int *precision) return CG_OK; } -int cg_close(int file_number) +/** + * \ingroup CGNSFile + * + * \brief Close a CGNS file. + * + * \param[in] fn \FILE_fn + * \return \ier + * + * \details The function \e cg_close must always be the last one called. It closes the CGNS file designated by the index number \e fn + * and frees the memory where the CGNS data was kept. When a file is opened for writing, \e cg_close writes all the CGNS data in + * memory onto disk prior to closing the file. Consequently, if is omitted, the CGNS file is not written properly. + * + */ + +int cg_close(int fn) { - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; #ifdef __CG_MALLOC_H__ @@ -667,12 +808,31 @@ int cg_close(int file_number) return CG_OK; } -int cg_save_as(int file_number, const char *filename, int file_type, +/** + * \ingroup CGNSFile + * + * \brief Save the open CGNS file. + * + * \param[in] fn \FILE_fn + * \param[in] filename \FILE_filename + * \param[in] file_type \FILE_file_type + * \param[in] follow_links \FILE_follow_links + * \return \ier + * + * \details The CGNS file identified by \e fn may be saved to a different filename and type using cg_save_as(). + * In order to save as an HDF5 file, the library must have been built with HDF5 support. ADF support is always built. + * The function cg_set_file_type() sets the default file type for newly created CGNS files. The function + * cg_get_file_type() returns the file type for the CGNS file identified by \e fn. If the CGNS library is built + * as 32-bit, the additional file type, \p CG_FILE_ADF2, is available. This allows creation of a 2.5 compatible CGNS file. + * + */ + +int cg_save_as(int fn, const char *filename, int file_type, int follow_links) { int output; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (file_type == CG_FILE_NONE) @@ -695,6 +855,22 @@ int cg_save_as(int file_number, const char *filename, int file_type, } return CG_OK; } +/** + * \ingroup CGNSFile + * + * \brief Set default file type. + * + * \param[in] file_type \FILE_file_type + * \return \ier + * + * \details When a CGNS file is newly created using \p CG_MODE_WRITE, the default type of database manager used is determined + * at compile time. If the CGNS library was built with HDF5 version 1.8 or later support, the file type will be \p CG_FILE_HDF5, + * otherwise \p CG_FILE_ADF is used. This may be changed either by setting an environment variable, \p CGNS_FILETYPE, to one + * of \e adf, \e hdf5, or \e adf2, or by calling the routine cg_set_file_type() prior to the cg_open() call. Calling + * cg_set_file_type() with the argument \p CG_FILE_NONE will reset the library to use the default file type. + * \b Note: If the environment variable \p CGNS_FILETYPE is set, it takes precedence. + * + */ int cg_set_file_type(int file_type) { @@ -734,9 +910,22 @@ int cg_set_file_type(int file_type) return CG_OK; } -int cg_get_file_type(int file_number, int *file_type) +/** + * \ingroup CGNSFile + * + * \brief Get file type for open CGNS file. + * + * \param[in] fn \FILE_fn + * \param[out] file_type \FILE_file_type + * \return \ier + * + * \details The function \p cg_get_file_type gets the file type (\e adf, \e hdf5, or \e adf2) for an open CGNS file. + * + */ + +int cg_get_file_type(int fn, int *file_type) { - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgio_get_file_type(cg->cgio, file_type)) { cg_io_error("cgio_get_file_type"); @@ -745,58 +934,115 @@ int cg_get_file_type(int file_number, int *file_type) return CG_OK; } -int cg_root_id(int file_number, double *root_id) +/** + * \ingroup CGNSInterfaceCGIO + * + * \brief Get the CGIO root node identifier for the CGNS file. + * + * \param[in] fn \FILE_fn + * \param[out] rootid Root node identifier for the CGNS file + * \return \ier + * + * \details The function \p cg_root_id allow the use of the low-level CGIO function + * in conjunction with the Mid Level Library. It returns the root node identifier for the CGNS file. + * + */ +int cg_root_id(int fn, double *rootid) { - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; - if (cgio_get_root_id(cg->cgio, root_id)) { + if (cgio_get_root_id(cg->cgio, rootid)) { cg_io_error("cgio_get_root_id"); return CG_ERROR; } return CG_OK; } -int cg_get_cgio(int file_number, int *cgio_num) +/** + * \ingroup CGNSInterfaceCGIO + * + * \brief Get the CGIO database identifier for the specified CGNS file. + * + * \param[in] fn \FILE_fn + * \param[out] cgio_num CGIO identifier for the CGNS file + * \return \ier + * + * \details The function \p cg_get_cgio allow the use of the low-level CGIO function + * in conjunction with the Mid Level Library. It returns the CGIO database identifier for the CGNS file. + * + */ +int cg_get_cgio(int fn, int *cgio_num) { - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; *cgio_num = cg->cgio; return CG_OK; } /* configure stuff */ - -int cg_configure(int what, void *value) +/** + * \ingroup CGNSInternals + * + * \brief Configure CGNS library internal options. + * + * \param[in] option The option to configure, currently one of \p CG_CONFIG_ERROR, \p CG_CONFIG_COMPRESS, \p CG_CONFIG_SET_PATH, \p CG_CONFIG_ADD_PATH, \p CG_CONFIG_FILE_TYPE, \p CG_CONFIG_RIND_INDEX, \p CG_CONFIG_HDF5_DISKLESS, \p CG_CONFIG_HDF5_DISKLESS_INCR, \p CG_CONFIG_HDF5_DISKLESS_WRITE, \p CG_CONFIG_HDF5_COMPRESS, or \p CG_CONFIG_HDF5_MPI_COMM as defined in cgnslib.h. + * \param[in] value The value to set, type cast as \e void * . In Fortran the type is \e TYPE(C_PTR). + * \return \ier + * + * + * \details The function \p cg_configure allows particular CGNS library internal options to be configured. The currently supported options and expected values are: + * + *| | | + *|---|---| + *|__CG_CONFIG_ERROR__| This allows an error call-back function to be defined by the user. The value should be a pointer to a function to receive the error. The function is defined as `void err_callback(int is_error, char *errmsg)`, and will be called for errors and warnings. The first argument, is_error, will be 0 for warning messages, 1 for error messages, and −1 if the program is going to terminate (i.e., a call to `cg_error_exit()`). The second argument is the error or warning message. If this is defined, warning and error messages will go to the function, rather than the terminal. A value of `NULL` will remove the call-back function. + *|__CG_CONFIG_COMPRESS__| This is the rewrite-upon-close setting. Note: Prior versions of the library would automatically rewrite the CGNS file when it was closed after being opened in modify mode if there was unused space. This is no longer done, due to possible conflicts when using parallel I/O. The previous behavior may be recovered by setting value to a positive integer. In this case the file will be rewritten if the number of node deletions or modifications are equal to or exceed this number. Setting value to a negative number will force the rewrite when the file is closed. The default value is 0 (no rewrite). + *|__CG_CONFIG_SET_PATH__| Sets the search path for locating linked-to files. The argument value should be a character string containing one or more directories, formatted the same as for the `PATH` environment variable. This will replace any current settings. Setting value to `NULL` will remove all paths. + *|__CG_CONFIG_ADD_PATH__| Adds a directory, or list of directories, to the linked-to file search path. This is the same as `CG_CONFIG_SET_PATH`, but adds to the path instead of replacing it. + *|__CG_CONFIG_FILE_TYPE__| Sets the default file type for newly created CGNS files. The argument, value should be set to one of `CG_FILE_NONE`, `CG_FILE_ADF`, `CG_FILE_HDF5`, or `CG_FILE_ADF2`. See the discussion above for `cg_set_file_type`. + *|__CG_CONFIG_RIND_INDEX__| This option affects index bounds on structured arrays with rind planes. By default (`CG_CONFIG_RIND_CORE`), the core array locations always begin at index 1. Lower rind planes, if present, would have an index less than 1. For backward compatibility, `CG_CONFIG_RIND_ZERO` is provided and the index 1 will then locate the start of the array and not necessarily the start the core array. Note: Use of this option does not change the cgns file in any way; it only modifies the API to the library. The API changed for versions of the Mid-Level Library greater than 3.4. Before, it did not produce this behavior. Index 1 always represented the start of an array: in an array with no rind planes, the core location would have index 1; in an array with 1 rind plane, the core location would have index 2. In version 3.4 of the Mid-Level Library, the behavior of the API was fixed to match that specified in the SIDS: core array locations always begin at index 1. This option allows for configuring the library to pre-3.4 indexing behavior (set value to `CG_CONFIG_RIND_ZERO`) or the new default behavior (set value to `CG_CONFIG_RIND_CORE`). Note that using `CG_CONFIG_RIND_ZERO` is considered obsolete, but is provided for backwards compatibility. Most users should not set this option and use the default. Values used for this option do not need to be explicitly cast as `void*`. + *|__CG_CONFIG_HDF5_COMPRESS__| Sets the compression level for data written from HDF5. The default is no compression. Setting value to -1, will use the default compression level of 6. The acceptable values are 0 to 9, corresponding to gzip compression levels. + *|__CG_CONFIG_HDF5_MPI_COMM__| Sets the MPI communicator for parallel I/O. The default is `MPI_COMM_WORLD`. The new communicator is given by typecasting it to a `void *`. This is generally used internally - see `cgp_mpi_comm` instead. + *|__CG_CONFIG_HDF5_DISKLESS_INCR__| Value specifies the increment by which allocated memory is to be increased each time more memory is required, in bytes. The default is 10MiB. Ideally, value should be set large enough to minimize repeated increases. The type of value is size_t in C and C_SIZE_T in Fortran. Due to a bug with gfortran, it is advisable to use C_LOC or C_FUNLOC in-line of the call instead of using a variable. + *|__CG_CONFIG_HDF5_DISKLESS_WRITE__| Value indicates whether to write (value=1) the memory contents to disk when the file is closed. Otherwise, value=0 does not persist the memory to disk. + *|__CG_CONFIG_HDF5_ALIGNMENT__| Configures HDF5's H5Pset_alignment and sets the alignment, value[1], properties of a file access property list so that any file object greater than or equal in size to a threshold, value[0], bytes will be aligned on an address which is a multiple of alignment. + *|__CG_CONFIG_HDF5_MD_BLOCK_SIZE__| Configures HDF5's H5Pset_meta_block_size and sets the minimum size, value (in bytes), of metadata block allocations. + *|__CG_CONFIG_HDF5_BUFFER__| Configures HDF5's H5Pset_buffer and sets the maximum size, value (in bytes), for the type conversion buffer and background buffer. + *|__CG_CONFIG_HDF5_SIEVE_BUF_SIZE__| Configures HDF5's H5Pset_sieve_buf_size and sets the maximum size, value (in bytes), of the data sieve buffer. + *|__CG_CONFIG_RESET__| Value indicates the configuration values to reset to their default values. Currently, only CG_CONFIG_RESET_HDF5 is a valid value and will reset all the CG_CONFIG_HDF5_* parameters, excluding CG_CONFIG_HDF5_MPI_COMM and CG_CONFIG_HDF5_DISKLESS, to their default values. + * + * + */ +int cg_configure(int option, void *value) { /* cgio options */ - if (what > 100) { - if( cgio_configure(what, value) != CG_OK) { + if (option > 100) { + if( cgio_configure(option, value) != CG_OK) { cg_io_error("cgio_configure"); return CG_ERROR; } } /* error message handler */ - else if (what == CG_CONFIG_ERROR) { + else if (option == CG_CONFIG_ERROR) { cgns_error_handler = (void (*)(int, char *))value; } /* file compression */ - else if (what == CG_CONFIG_COMPRESS) { + else if (option == CG_CONFIG_COMPRESS) { cgns_compress = (int)((size_t)value); } /* initialize link search path */ - else if (what == CG_CONFIG_SET_PATH) { + else if (option == CG_CONFIG_SET_PATH) { return cg_set_path((const char *)value); } /* add to link search path */ - else if (what == CG_CONFIG_ADD_PATH) { + else if (option == CG_CONFIG_ADD_PATH) { return cg_set_path((const char *)value); } /* default file type */ - else if (what == CG_CONFIG_FILE_TYPE) { + else if (option == CG_CONFIG_FILE_TYPE) { return cg_set_file_type((int)((size_t)value)); } /* allow pre v3.4 rind-plane indexing */ - else if (what == CG_CONFIG_RIND_INDEX) { + else if (option == CG_CONFIG_RIND_INDEX) { if (value != CG_CONFIG_RIND_ZERO && value != CG_CONFIG_RIND_CORE) { cgi_error("unknown config setting"); @@ -811,24 +1057,56 @@ int cg_configure(int what, void *value) return CG_OK; } +/** + * \ingroup CGNSInternals + * + * \brief Set CGNS error handler + * + * \param[in] func error handler function + * \return \ier + */ int cg_error_handler(void (*func)(int, char *)) { cgns_error_handler = func; return CG_OK; } +/** + * \ingroup CGNSInternals + * + * \brief Set CGNS compression mode + * + * \param[in] compress CGNS compress (rewrite) setting + * \return \ier + */ int cg_set_compress(int compress) { cgns_compress = compress; return CG_OK; } +/** + * \ingroup CGNSInternals + * + * \brief Get CGNS compression mode + * + * \param[out] compress CGNS compress (rewrite) setting + * \return \ier + */ int cg_get_compress(int *compress) { *compress = cgns_compress; return CG_OK; } +/** + * \ingroup CGNSInternals + * + * \brief Set the CGNS link search path + * + * \param[in] path to search for linked to files when opening a file with external links. + * \return \ier + */ int cg_set_path(const char *path) { cgio_path_delete(NULL); @@ -841,6 +1119,14 @@ int cg_set_path(const char *path) return CG_OK; } +/** + * \ingroup CGNSInternals + * + * \brief Add to the CGNS link search path + * + * \param[in] path to search for linked to files when opening a file with external links. + * \return \ier + */ int cg_add_path(const char *path) { if (cgio_path_add(path)) { @@ -966,11 +1252,20 @@ const char *cg_AverageInterfaceTypeName(CGNS_ENUMT( AverageInterfaceType_t ) ty /*****************************************************************************\ * Read and Write CGNSBase_t Nodes \*****************************************************************************/ - -int cg_nbases(int file_number, int *nbases) +/** + * \ingroup CGNSBaseInformation + * + * \brief Get number of CGNS base nodes in file + * + * \param[in] fn \FILE_fn + * \param[out] nbases Number of bases present in the CGNS file fn. + * \return \ier + * + */ +int cg_nbases(int fn, int *nbases) { - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -979,12 +1274,25 @@ int cg_nbases(int file_number, int *nbases) return CG_OK; } -int cg_base_read(int file_number, int B, char *basename, int *cell_dim, +/** + * \ingroup CGNSBaseInformation + * + * \brief Read CGNS base information + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[out] basename Name of the base + * \param[out] cell_dim Dimension of the cells; 3 for volume cells, 2 for surface cells and 1 for line cells. + * \param[out] phys_dim Number of coordinates required to define a vector in the field. + * \return \ier + * + */ +int cg_base_read(int fn, int B, char *basename, int *cell_dim, int *phys_dim) { cgns_base *base; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -999,11 +1307,23 @@ int cg_base_read(int file_number, int B, char *basename, int *cell_dim, return CG_OK; } -int cg_base_id(int file_number, int B, double *base_id) + +/** + * \ingroup CGNSBaseInformation + * + * \brief Get the CGIO identifier of the CGNS base + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[out] base_id CGIO node identifier for the base + * \return \ier + * + */ +int cg_base_id(int fn, int B, double *base_id) { cgns_base *base; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -1015,11 +1335,22 @@ int cg_base_id(int file_number, int B, double *base_id) return CG_OK; } -int cg_cell_dim(int file_number, int B, int *cell_dim) +/** + * \ingroup CGNSBaseInformation + * + * \brief Get the cell dimension for the CGNS base + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[out] cell_dim Dimension of the cells; 3 for volume cells, 2 for surface cells and 1 for line cells. + * \return \ier + * + */ +int cg_cell_dim(int fn, int B, int *cell_dim) { cgns_base *base; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; base = cgi_get_base(cg, B); if (base==0) return CG_ERROR; @@ -1028,7 +1359,20 @@ int cg_cell_dim(int file_number, int B, int *cell_dim) return CG_OK; } -int cg_base_write(int file_number, const char * basename, int cell_dim, +/** + * \ingroup CGNSBaseInformation + * + * \brief Create and/or write to a CGNS base node + * + * \param[in] fn \FILE_fn + * \param[in] basename Name of the base. + * \param[in] cell_dim Dimension of the cells; 3 for volume cells, 2 for surface cells and 1 for line cells. + * \param[in] phys_dim Number of coordinates required to define a vector in the field. + * \param[out] B \B_Base + * \return \ier + * + */ +int cg_base_write(int fn, const char * basename, int cell_dim, int phys_dim, int *B) { cgns_base *base = NULL; @@ -1043,7 +1387,7 @@ int cg_base_write(int file_number, const char * basename, int cell_dim, return CG_ERROR; } /* get memory address for base */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_WRITE)) return CG_ERROR; @@ -1101,11 +1445,22 @@ int cg_base_write(int file_number, const char * basename, int cell_dim, * Read and Write Zone_t Nodes \*****************************************************************************/ -int cg_nzones(int file_number, int B, int *nzones) +/** + * \ingroup CGNSZoneInformation + * + * \brief Get number of zone in base + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[out] nzones Number of zones present in base B. + * \return \ier + * + */ +int cg_nzones(int fn, int B, int *nzones) { cgns_base *base; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -1117,11 +1472,23 @@ int cg_nzones(int file_number, int B, int *nzones) return CG_OK; } -int cg_zone_type(int file_number, int B, int Z, CGNS_ENUMT(ZoneType_t) *type) +/** + * \ingroup CGNSZoneInformation + * + * \brief Get type of zone (structured or unstructured) + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[out] zonetype Type of the zone. The admissible types are Structured and Unstructured. + * \return \ier + * + */ +int cg_zone_type(int fn, int B, int Z, CGNS_ENUMT(ZoneType_t) *zonetype) { cgns_zone *zone; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -1129,16 +1496,43 @@ int cg_zone_type(int file_number, int B, int Z, CGNS_ENUMT(ZoneType_t) *type) zone = cgi_get_zone(cg, B, Z); if (zone==0) return CG_ERROR; - *type = zone->type; + *zonetype = zone->type; return CG_OK; } -int cg_zone_read(int file_number, int B, int Z, char *zonename, cgsize_t *nijk) + +/** + * \ingroup CGNSZoneInformation + * + * \brief Read zone information + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[out] zonename Name of the zone + * \param[out] size Number of vertices, cells, and boundary vertices in each (index)-dimension. For structured grids, the dimensions have unit stride in the array (e.g., `[NVertexI, NVertexJ, NVertexK, NCellI, NCellJ, NCellK, NBoundVertexI, NBoundVertexJ, NBoundVertexK]`). +Note that for unstructured grids, the number of cells is the number of highest order elements. Thus, in three dimensions it's the number of 3-D cells, and in two dimensions it's the number of 2-D cells. +Also for unstructured grids, if the nodes are sorted between internal nodes and boundary nodes, the optional parameter `NBoundVertex` must be set equal to the number of boundary nodes. By default, `NBoundVertex` equals zero, meaning that the nodes are unsorted. +Note that a non-zero value for `NBoundVertex` only applies to unstructured grids. For structured grids, the `NBoundVertex` parameter always equals 0 in all directions. + *|Mesh Type | Size| + *|---------------|-----| + *| 3D structured | `NVertexI`, `NVertexJ`, `NVertexK` + *| ^ | `NCellI`, `NCellJ`, `NCellK` + *| ^ | `NBoundVertexI = 0`, `NBoundVertexJ = 0`, `NBoundVertexK = 0` + *| 2D structured | `NVertexI`, `NVertexJ` + *| ^ | `NCellI`, `NCellJ` + *| ^ | `NBoundVertexI = 0`, `NBoundVertexJ = 0` + *|3D unstructured| `NVertex`, `NCell3D`, `NBoundVertex` + *|2D unstructured| `NVertex`, `NCell2D`, `NBoundVertex` + * \return \ier + * + */ +int cg_zone_read(int fn, int B, int Z, char *zonename, cgsize_t *size) { cgns_zone *zone; int i; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -1148,16 +1542,17 @@ int cg_zone_read(int file_number, int B, int Z, char *zonename, cgsize_t *nijk) strcpy(zonename, zone->name); - for (i=0; i<3*(zone->index_dim); i++) nijk[i] = zone->nijk[i]; + for (i=0; i<3*(zone->index_dim); i++) size[i] = zone->nijk[i]; return CG_OK; } -int cg_zone_id(int file_number, int B, int Z, double *zone_id) + +int cg_zone_id(int fn, int B, int Z, double *zone_id) { cgns_zone *zone; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -1169,11 +1564,22 @@ int cg_zone_id(int file_number, int B, int Z, double *zone_id) return CG_OK; } -int cg_index_dim(int file_number, int B, int Z, int *index_dim) +/** + * \ingroup CGNSZoneInformation + * + * \brief Get the index dimension of the CGNS zone + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[out] index_dim Index dimension for the zone. For Structured zones, this will be the base cell dimension and for Unstructured zones it will be 1 + * \return \ier + */ +int cg_index_dim(int fn, int B, int Z, int *index_dim) { cgns_zone *zone; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; zone = cgi_get_zone(cg, B, Z); if (zone==0) return CG_ERROR; @@ -1182,8 +1588,34 @@ int cg_index_dim(int file_number, int B, int Z, int *index_dim) return CG_OK; } -int cg_zone_write(int file_number, int B, const char *zonename, const cgsize_t * nijk, - CGNS_ENUMT( ZoneType_t ) type, int *Z) +/** + * \ingroup CGNSZoneInformation + * + * \brief Create and/or write to a CGNS zone + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] zonename Name of the zone. + * \param[in] size Number of vertices, cells, and boundary vertices in each (index)-dimension. For structured grids, the dimensions have unit stride in the array (e.g., [NVertexI, NVertexJ, NVertexK, NCellI, NCellJ, NCellK, NBoundVertexI, NBoundVertexJ, NBoundVertexK]). + *Note that for unstructured grids, the number of cells is the number of highest order elements. Thus, in three dimensions it's the number of 3-D cells, and in two dimensions it's the number of 2-D cells. + *Also for unstructured grids, if the nodes are sorted between internal nodes and boundary nodes, the optional parameter NBoundVertex must be set equal to the number of boundary nodes. By default, NBoundVertex equals zero, meaning that the nodes are unsorted. + *Note that a non-zero value for NBoundVertex only applies to unstructured grids. For structured grids, the NBoundVertex parameter always equals 0 in all directions. + *|Mesh Type | Size| + *|---------------|-----| + *| 3D structured | NVertexI, NVertexJ, NVertexK + *| | NCellI, NCellJ, NCellK + *| | NBoundVertexI = 0, NBoundVertexJ = 0, NBoundVertexK = 0 + *|2D structured | NVertexI, NVertexJ + *| | NCellI, NCellJ + *| | NBoundVertexI = 0, NBoundVertexJ = 0 + *|3D unstructured| NVertex, NCell3D, NBoundVertex + *|2D unstructured| NVertex, NCell2D, NBoundVertex + * \param[in] zonetype Type of the zone. The admissible types are Structured and Unstructured. + * \param[out] Z \Z_Zone + * \return \ier + */ +int cg_zone_write(int fn, int B, const char *zonename, const cgsize_t * size, + CGNS_ENUMT( ZoneType_t ) zonetype, int *Z) { cgns_base *base; cgns_zone *zone = NULL; @@ -1195,7 +1627,7 @@ int cg_zone_write(int file_number, int B, const char *zonename, const cgsize_t * if (cgi_check_strlen(zonename)) return CG_ERROR; /* get memory address file */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; /* verify input */ @@ -1206,9 +1638,9 @@ int cg_zone_write(int file_number, int B, const char *zonename, const cgsize_t * if (base==0) return CG_ERROR; /* Set index dimension */ - if (type == CGNS_ENUMV( Structured )) + if (zonetype == CGNS_ENUMV( Structured )) index_dim = base->cell_dim; - else if (type == CGNS_ENUMV( Unstructured )) + else if (zonetype == CGNS_ENUMV( Unstructured )) index_dim = 1; else { cgi_error("Invalid zone type - not Structured or Unstructured"); @@ -1216,13 +1648,13 @@ int cg_zone_write(int file_number, int B, const char *zonename, const cgsize_t * } for (i=0; inijk"); return CG_ERROR; } - for (i=0; i<3*index_dim; i++) zone->nijk[i] = nijk[i]; + for (i=0; i<3*index_dim; i++) zone->nijk[i] = size[i]; zone->index_dim = index_dim; - zone->type = type; + zone->type = zonetype; /* save data in file */ dim_vals[0]=zone->index_dim; @@ -1294,9 +1726,9 @@ int cg_zone_write(int file_number, int B, const char *zonename, const cgsize_t * if (cgi_new_node(base->id, zone->name, "Zone_t", &zone->id, CG_SIZE_DATATYPE, 2, dim_vals, (void *)zone->nijk)) return CG_ERROR; - dim_vals[0] = (cgsize_t)strlen(ZoneTypeName[type]); + dim_vals[0] = (cgsize_t)strlen(ZoneTypeName[zonetype]); if (cgi_new_node(zone->id, "ZoneType", "ZoneType_t", &dummy_id, - "C1", 1, dim_vals, ZoneTypeName[type])) return CG_ERROR; + "C1", 1, dim_vals, ZoneTypeName[zonetype])) return CG_ERROR; return CG_OK; } @@ -1305,11 +1737,22 @@ int cg_zone_write(int file_number, int B, const char *zonename, const cgsize_t * * Read and Write Family_t Nodes \*****************************************************************************/ -int cg_nfamilies(int file_number, int B, int *nfamilies) +/** + * \ingroup CGNSFamilyDefinition + * + * \brief Get number of Family_t node at CGNSBase_t level + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[out] nfamilies Number of families in base B + * \return \ier + * + */ +int cg_nfamilies(int fn, int B, int *nfamilies) { cgns_base *base; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -1321,17 +1764,31 @@ int cg_nfamilies(int file_number, int B, int *nfamilies) return CG_OK; } -int cg_family_read(int file_number, int B, int F, char *family_name, +/** + * \ingroup CGNSFamilyDefinition + * + * \brief Read family information (CGNSBase_t level) + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Fam Family index number, where 1 ≤ Fam ≤ nfamilies. + * \param[out] family_name Name of the family + * \param[out] nboco Number of boundary conditions for this family. This should be either 0 or 1. + * \param[out] ngeos Number of geometry references for this family. + * \return \ier + * + */ +int cg_family_read(int fn, int B, int Fam, char *family_name, int *nboco, int *ngeos) { cgns_family *family; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; - family = cgi_get_family(cg, B, F); + family = cgi_get_family(cg, B, Fam); if (family==0) return CG_ERROR; strcpy(family_name, family->name); @@ -1342,7 +1799,20 @@ int cg_family_read(int file_number, int B, int F, char *family_name, } /* ** FAMILY TREE ** */ -int cg_family_write(int file_number, int B, const char * family_name, int *F) + +/** + * \ingroup CGNSFamilyDefinition + * + * \brief Read family information (CGNSBase_t level) + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] family_name Name of the family + * \param[out] Fam Family index number, where 1 ≤ Fam ≤ nfamilies. + * \return \ier + * + */ +int cg_family_write(int fn, int B, const char * family_name, int *Fam) { int index; cgns_base *base; @@ -1353,7 +1823,7 @@ int cg_family_write(int file_number, int B, const char * family_name, int *F) int skip = 0; /* Check file access */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_WRITE)) return CG_ERROR; @@ -1467,7 +1937,7 @@ int cg_family_write(int file_number, int B, const char * family_name, int *F) (*nfamilies_p)++; } - (*F) = index+1; + (*Fam) = index+1; if( ! skip ) { /* If not an existing intermediate family node */ memset( family, 0, sizeof(cgns_family) ); @@ -1491,45 +1961,86 @@ int cg_family_write(int file_number, int B, const char * family_name, int *F) /*----------------------------------------------------------------------*/ -int cg_nfamily_names(int file_number, int B, int F, int *nnames) +/** + * \ingroup CGNSFamilyDefinition + * + * \brief Get number of family names under Family_t (CGNSBase_t level) + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Fam Family index number, where 1 ≤ Fam ≤ nfamilies. + * \param[out] nnames Number of FamilyName_t nodes for this family. + * \return \ier + * + */ +int cg_nfamily_names(int fn, int B, int Fam, int *nnames) { cgns_family *fam; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; - fam = cgi_get_family(cg, B, F); + fam = cgi_get_family(cg, B, Fam); if (fam == 0) return CG_ERROR; *nnames = fam->nfamname; return CG_OK; } -int cg_family_name_read(int file_number, int B, int F, int N, char *name, char *family) +/** + * \ingroup CGNSFamilyDefinition + * + * \brief Read multiple family names under Family_t (CGNSBase_t level) + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Fam Family index number, where 1 ≤ Fam ≤ nfamilies. + * \param[in] N Family name index number, where 1 ≤ N ≤ nNames. + * \param[out] node_name Name of the FamilyName_t node. FamilyParent is used to refer to the parent family of the Family_t node. + * \param[out] family_name Name of the family + * \return \ier + * + */ +int cg_family_name_read(int fn, int B, int Fam, int N, char *node_name, char *family_name) { cgns_family *fam; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; - fam = cgi_get_family(cg, B, F); + fam = cgi_get_family(cg, B, Fam); if (fam == 0) return CG_ERROR; if (N < 1 || N > fam->nfamname) { cgi_error("family name index out of range\n"); return CG_ERROR; } - strcpy(name, fam->famname[N-1].name); - strcpy(family, fam->famname[N-1].family); + strcpy(node_name, fam->famname[N-1].name); + strcpy(family_name, fam->famname[N-1].family); return CG_OK; } + /* ** FAMILY TREE ** */ -int cg_family_name_write(int file_number, int B, int F, - const char *name, const char *family) + +/** + * \ingroup CGNSFamilyDefinition + * + * \brief Write multiple family names under Family_t (CGNSBase_t level) + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Fam Family index number, where 1 ≤ Fam ≤ nfamilies. + * \param[out] node_name Name of the FamilyName_t node. FamilyParent is used to refer to the parent family of the Family_t node. + * \param[out] family_name Name of the family + * \return \ier + * + */ +int cg_family_name_write(int fn, int B, int Fam, + const char *node_name, const char *family_name) { int index; cgsize_t dim; @@ -1537,25 +2048,25 @@ int cg_family_name_write(int file_number, int B, int F, cgns_famname *famname = 0; /* verify input */ - if (cgi_check_strlen(name)) return CG_ERROR; + if (cgi_check_strlen(node_name)) return CG_ERROR; - if ( strlen(family) > (CGIO_MAX_NAME_LENGTH+1)*CG_MAX_GOTO_DEPTH ) { - cgi_error( "Family path too long (%s, size %ld)", family, strlen(family) ); + if ( strlen(family_name) > (CGIO_MAX_NAME_LENGTH+1)*CG_MAX_GOTO_DEPTH ) { + cgi_error( "Family path too long (%s, size %ld)", family_name, strlen(family_name) ); return CG_ERROR; } - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_WRITE)) return CG_ERROR; - fam = cgi_get_family(cg, B, F); + fam = cgi_get_family(cg, B, Fam); if (fam == 0) return CG_ERROR; for (index = 0; index < fam->nfamname; index++) { - if (0 == strcmp(name, fam->famname[index].name)) { + if (0 == strcmp(node_name, fam->famname[index].name)) { if (cg->mode == CG_MODE_WRITE) { - cgi_error("Duplicate child name found: %s", name); + cgi_error("Duplicate child name found: %s", node_name); return CG_ERROR; } if (cgi_delete_node(fam->id, fam->famname[index].id)) @@ -1574,8 +2085,8 @@ int cg_family_name_write(int file_number, int B, int F, fam->nfamname++; } - strcpy(famname->name, name); - strcpy(famname->family, family); + strcpy(famname->name, node_name); + strcpy(famname->family, family_name); dim = (cgsize_t)strlen(famname->family); if (cgi_new_node(fam->id, famname->name, "FamilyName_t", &famname->id, @@ -1584,9 +2095,18 @@ int cg_family_name_write(int file_number, int B, int F, return CG_OK; } -/* ** FAMILY TREE ** */ -/* FamilyTree extension */ -int cg_node_family_write( const char* family_name, int* F) + +/** + * \ingroup CGNSFamilyHierarchyTreeDefinition + * + * \brief Create a Family_t node (Family_t level) + * + * \param[in] family_name Name of the family + * \param[out] Fam Family index number, where 1 ≤ Fam ≤ nfamilies. + * \return \ier + * + */ +int cg_node_family_write( const char* family_name, int* Fam) { int ier=0, n, nfamilies; cgns_family* family; @@ -1604,7 +2124,7 @@ int cg_node_family_write( const char* family_name, int* F) /* check for valid posit */ if (posit == 0) { cgi_error("No current position set by cg_goto\n"); - (*F) = 0; + (*Fam) = 0; return CG_ERROR; } @@ -1631,7 +2151,7 @@ int cg_node_family_write( const char* family_name, int* F) } else { cgi_error("Family_t node not supported under '%s' type node",posit->label); - (*F) = -1; + (*Fam) = -1; return CG_INCORRECT_PATH; } @@ -1645,7 +2165,7 @@ int cg_node_family_write( const char* family_name, int* F) cgi_error( "Could not find Family_t node %s\n" , family_name ); return CG_ERROR; } - *F = n + 1; + *Fam = n + 1; } else { cgi_error( "No Family_t container \n"); @@ -1655,7 +2175,15 @@ int cg_node_family_write( const char* family_name, int* F) return CG_OK; } -/* ** FAMILY TREE ** */ +/** + * \ingroup CGNSFamilyHierarchyTreeDefinition + * + * \brief Get number of families (Family_t level) + * + * \param[out] nfamilies Number of families in current node (CGNSBase_t or Family_t). + * \return \ier + * + */ int cg_node_nfamilies( int* nfamilies ) { /* This is valid and used during write as well as read mode. */ @@ -1682,8 +2210,19 @@ int cg_node_nfamilies( int* nfamilies ) return CG_OK; } -/* ** FAMILY TREE ** */ -int cg_node_family_read( int F, char* family_name, int* nFamBC, int *nGeo ) +/** + * \ingroup CGNSFamilyHierarchyTreeDefinition + * + * \brief Read family info (Family_t level) + * + * \param[in] Fam Family index number, where 1 ≤ Fam ≤ nfamilies. + * \param[out] family_name Name of the family. + * \param[out] nFamBC Number of boundary conditions for this family. This should be either 0 or 1. + * \param[out] nGeo Number of geometry references for this family. + * \return \ier + * + */ +int cg_node_family_read( int Fam, char* family_name, int* nFamBC, int *nGeo ) { int ier = 0; cgns_family* family; @@ -1693,7 +2232,7 @@ int cg_node_family_read( int F, char* family_name, int* nFamBC, int *nGeo ) /* verify input */ if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; - family = cgi_family_address( CG_MODE_READ, F, "dummy", &ier ); + family = cgi_family_address( CG_MODE_READ, Fam, "dummy", &ier ); if( family == 0 ) return ier; strcpy( family_name, family->name ); @@ -1703,7 +2242,16 @@ int cg_node_family_read( int F, char* family_name, int* nFamBC, int *nGeo ) return CG_OK; } -/* ** FAMILY TREE ** */ +/** + * \ingroup CGNSFamilyHierarchyTreeDefinition + * + * \brief Write multiple family names under Family_t (Family_t level) + * + * \param[in] node_name Name of the FamilyName_t node. FamilyParent is used to refer to the parent family of the Family_t node. + * \param[in] family_name Name of the family. + * \return \ier + * + */ int cg_node_family_name_write( const char* node_name, const char* family_name ) { int index; @@ -1767,7 +2315,15 @@ int cg_node_family_name_write( const char* node_name, const char* family_name ) return CG_OK; } -/* ** FAMILY TREE ** */ +/** + * \ingroup CGNSFamilyHierarchyTreeDefinition + * + * \brief Get number of family names under Family_t (Family_t level) + * + * \param[out] nnames Number of FamilyName_t nodes for this family. + * \return \ier + * + */ int cg_node_nfamily_names( int* nnames ) { /* This is valid and used during write as well as read mode. */ @@ -1792,7 +2348,17 @@ int cg_node_nfamily_names( int* nnames ) return CG_OK; } -/* ** FAMILY TREE ** */ +/** + * \ingroup CGNSFamilyHierarchyTreeDefinition + * + * \brief Read family info (Family_t level) + * + * \param[in] N Family name index number, where 1 ≤ N ≤ nNames. + * \param[out] node_name Name of the FamilyName_t node. FamilyParent is used to refer to the parent family of the Family_t node. + * \param[out] family_name Name of the family. + * \return \ier + * + */ int cg_node_family_name_read(int N, char* node_name, char* family_name ) { cgns_famname *famname; @@ -1815,17 +2381,31 @@ int cg_node_family_name_read(int N, char* node_name, char* family_name ) /*----------------------------------------------------------------------*/ -int cg_fambc_read(int file_number, int B, int F, int BC, +/** + * \ingroup CGNSFamilyBoundaryDefinition + * + * \brief Read boundary condition type for a family + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Fam Family index number, where 1 ≤ Fam ≤ nfamilies. + * \param[in] BC Family boundary condition index number. This must be equal to 1. + * \param[out] fambc_name Name of the FamilyBC_t node. + * \param[out] bocotype Boundary condition type for the family. See the eligible types for BCType_t in the Typedefs section. + * \return \ier + */ + +int cg_fambc_read(int fn, int B, int Fam, int BC, char *fambc_name, CGNS_ENUMT(BCType_t) *bocotype) { cgns_family *family; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; - family = cgi_get_family(cg, B, F); + family = cgi_get_family(cg, B, Fam); if (family==0) return CG_ERROR; if (BC<=0 || BC>family->nfambc) { @@ -1838,7 +2418,21 @@ int cg_fambc_read(int file_number, int B, int F, int BC, return CG_OK; } -int cg_fambc_write(int file_number, int B, int F, const char * fambc_name, +/** + * \ingroup CGNSFamilyBoundaryDefinition + * + * \brief Write boundary condition type for a family + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Fam Family index number, where 1 ≤ Fam ≤ nfamilies. + * \param[in] fambc_name Name of the FamilyBC_t node. + * \param[in] bocotype Boundary condition type for the family. See the eligible types for BCType_t in the Typedefs section. + * \param[out] BC Family boundary condition index number. This must be equal to 1. + * \return \ier + * + */ +int cg_fambc_write(int fn, int B, int Fam, const char * fambc_name, CGNS_ENUMT( BCType_t ) bocotype, int *BC) { int index; @@ -1853,13 +2447,13 @@ int cg_fambc_write(int file_number, int B, int F, const char * fambc_name, return CG_ERROR; } - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_WRITE)) return CG_ERROR; /* get memory address for family */ - family = cgi_get_family(cg, B, F); + family = cgi_get_family(cg, B, Fam); if (family==0) return CG_ERROR; /* Overwrite a FamilyBC_t Node: */ @@ -1906,9 +2500,19 @@ int cg_fambc_write(int file_number, int B, int F, const char * fambc_name, return CG_OK; } -/* FamilyTree extension */ /* ** FAMILY TREE ** */ /*----------------------------------------------------------------------*/ +/** + * \ingroup CGNSFamilyBoundaryDefinition + * + * \brief Read boundary condition information (Family_t level) + * + * \param[in] BC Family boundary condition index number. This must be equal to 1. + * \param[out] fambc_name Name of the FamilyBC_t node. + * \param[out] bocotype Boundary condition type for the family. See the eligible types for BCType_t in the Typedefs section. + * \return \ier + * + */ int cg_node_fambc_read( int BC, char* fambc_name, CGNS_ENUMT(BCType_t) *bocotype) { @@ -1946,6 +2550,17 @@ int cg_node_fambc_read( int BC, char* fambc_name, } /*----------------------------------------------------------------------*/ +/** + * \ingroup CGNSFamilyBoundaryDefinition + * + * \brief Write boundary condition information (Family_t level) + * + * \param[in] fambc_name Name of the FamilyBC_t node. + * \param[in] bocotype Boundary condition type for the family. See the eligible types for BCType_t in the Typedefs section. + * \param[out] BC Family boundary condition index number. This must be equal to 1. + * \return \ier + * + */ int cg_node_fambc_write( const char* fambc_name, CGNS_ENUMT(BCType_t) bocotype, int *BC ) { @@ -2030,18 +2645,33 @@ int cg_node_fambc_write( const char* fambc_name, /*----------------------------------------------------------------------*/ - -int cg_geo_read(int file_number, int B, int F, int G, char *geo_name, +/** + * \ingroup CGNSGeometryReference + * + * \brief Read geometry reference information + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Fam Family index number, where 1 ≤ Fam ≤ nfamilies. + * \param[in] G Geometry reference index number, where 1 ≤ G ≤ nGeo. + * \param[out] geo_name Name of GeometryReference_t node. + * \param[out] geo_file Name of geometry file + * \param[out] CAD_name Geometry format + * \param[out] npart Number of geometry entities + * \return \ier + * + */ +int cg_geo_read(int fn, int B, int Fam, int G, char *geo_name, char **geo_file, char *CAD_name, int *npart) { cgns_family *family; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; - family = cgi_get_family(cg, B, F); + family = cgi_get_family(cg, B, Fam); if (family==0) return CG_ERROR; if (G<=0 || G>family->ngeos) { @@ -2061,8 +2691,23 @@ int cg_geo_read(int file_number, int B, int F, int G, char *geo_name, return CG_OK; } -int cg_geo_write(int file_number, int B, int F, const char * geo_name, - const char * filename, const char * CADname, int *G) +/** + * \ingroup CGNSGeometryReference + * + * \brief Create a GeometryReference_t node + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Fam Family index number, where 1 ≤ Fam ≤ nfamilies. + * \param[in] geo_name Name of GeometryReference_t node. + * \param[in] geo_file Name of geometry file + * \param[in] CAD_name Geometry format + * \param[out] G Geometry reference index number, where 1 ≤ G ≤ nGeo. + * \return \ier + * + */ +int cg_geo_write(int fn, int B, int Fam, const char * geo_name, + const char *geo_file, const char * CAD_name, int *G) { int index; cgsize_t length; @@ -2072,15 +2717,15 @@ int cg_geo_write(int file_number, int B, int F, const char * geo_name, /* verify input */ if (cgi_check_strlen(geo_name)) return CG_ERROR; - if (cgi_check_strlen(CADname)) return CG_ERROR; + if (cgi_check_strlen(CAD_name)) return CG_ERROR; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_WRITE)) return CG_ERROR; /* get memory address for family */ - family = cgi_get_family(cg, B, F); + family = cgi_get_family(cg, B, Fam); if (family==0) return CG_ERROR; /* Overwrite a GeometryReference_t Node: */ @@ -2119,9 +2764,9 @@ int cg_geo_write(int file_number, int B, int F, const char * geo_name, memset(geo, 0, sizeof(cgns_geo)); strcpy(geo->name, geo_name); - strcpy(geo->format, CADname); + strcpy(geo->format, CAD_name); - length = (int)strlen(filename); + length = (int)strlen(geo_file); if (length<=0) { cgi_error("filename undefined for GeometryReference node!"); return CG_ERROR; @@ -2131,7 +2776,7 @@ int cg_geo_write(int file_number, int B, int F, const char * geo_name, cgi_error("Error allocation geo->file"); return CG_ERROR; } - strcpy(geo->file, filename); + strcpy(geo->file, geo_file); /* save data in file */ if (cgi_new_node(family->id, geo->name, "GeometryReference_t", &geo->id, @@ -2148,6 +2793,19 @@ int cg_geo_write(int file_number, int B, int F, const char * geo_name, /* FamilyTree extension */ /* ** FAMILY TREE ** */ /*----------------------------------------------------------------------*/ +/** + * \ingroup CGNSGeometryReference + * + * \brief Read geometry reference information (Family_t level) + * + * \param[in] G Geometry reference index number, where 1 ≤ G ≤ nGeo. + * \param[out] geo_name Name of GeometryReference_t node. + * \param[out] geo_file Name of geometry file + * \param[out] CAD_name Geometry format + * \param[out] npart Number of geometry entities + * \return \ier + * + */ int cg_node_geo_read( int G, char *geo_name, char **geo_file, char *CAD_name, int *npart ) { @@ -2192,8 +2850,21 @@ int cg_node_geo_read( int G, char *geo_name, } /*----------------------------------------------------------------------*/ +/** + * \ingroup CGNSGeometryReference + * + * \brief Create GeometryReference_t node (Family_t level) + * + * \param[in] geo_name Name of GeometryReference_t node. + * \param[in] geo_file Name of geometry file + * \param[in] CAD_name Geometry format + * \param[out] G Geometry reference index number, where 1 ≤ G ≤ nGeo. + * + * \return \ier + * + */ int cg_node_geo_write( const char *geo_name, - const char *filename, const char *CADname, int *G) + const char *geo_file, const char *CAD_name, int *G) { int index; cgsize_t length; @@ -2203,7 +2874,7 @@ int cg_node_geo_write( const char *geo_name, /* verify input */ if (cgi_check_strlen(geo_name)) return CG_ERROR; - if (cgi_check_strlen(CADname)) return CG_ERROR; + if (cgi_check_strlen(CAD_name)) return CG_ERROR; CHECK_FILE_OPEN @@ -2261,9 +2932,9 @@ int cg_node_geo_write( const char *geo_name, memset(geo, 0, sizeof(cgns_geo)); strcpy(geo->name, geo_name); - strcpy(geo->format, CADname); + strcpy(geo->format, CAD_name); - length = (int)strlen(filename); + length = (int)strlen(geo_file); if (length<=0) { cgi_error("filename undefined for GeometryReference node!"); return CG_ERROR; @@ -2273,7 +2944,7 @@ int cg_node_geo_write( const char *geo_name, cgi_error("Error allocation geo->file"); return CG_ERROR; } - strcpy(geo->file, filename); + strcpy(geo->file, geo_file); /* save data in file */ if (cgi_new_node(family->id, geo->name, "GeometryReference_t", &geo->id, @@ -2291,17 +2962,30 @@ int cg_node_geo_write( const char *geo_name, /*----------------------------------------------------------------------*/ - -int cg_part_read(int file_number, int B, int F, int G, int P, char *part_name) +/** + * \ingroup CGNSGeometryReference + * + * \brief Get geometry entity name + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Fam Family index number, where 1 ≤ Fam ≤ nfamilies. + * \param[in] G Geometry reference index number, where 1 ≤ G ≤ nGeo. + * \param[in] P Geometry entity index number, where 1 ≤ P ≤ nparts + * \param[out] part_name Name of a geometry entity in the file FileName. + * \return \ier + * + */ +int cg_part_read(int fn, int B, int Fam, int G, int P, char *part_name) { cgns_family *family; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; - family = cgi_get_family(cg, B, F); + family = cgi_get_family(cg, B, Fam); if (family==0) return CG_ERROR; if (P<=0 || P>family->geo[G-1].npart) { @@ -2312,7 +2996,21 @@ int cg_part_read(int file_number, int B, int F, int G, int P, char *part_name) return CG_OK; } -int cg_part_write(int file_number, int B, int F, int G, const char * part_name, +/** + * \ingroup CGNSGeometryReference + * + * \brief Write geometry entity name + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Fam Family index number, where 1 ≤ Fam ≤ nfamilies. + * \param[in] G Geometry reference index number, where 1 ≤ G ≤ nGeo. + * \param[in] part_name Name of a geometry entity in the file FileName. + * \param[out] P Geometry entity index number, where 1 ≤ P ≤ nparts + * \return \ier + * + */ +int cg_part_write(int fn, int B, int Fam, int G, const char * part_name, int *P) { int index; @@ -2323,13 +3021,13 @@ int cg_part_write(int file_number, int B, int F, int G, const char * part_name, /* verify input */ if (cgi_check_strlen(part_name)) return CG_ERROR; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_WRITE)) return CG_ERROR; /* get memory address for geo */ - family = cgi_get_family(cg, B, F); + family = cgi_get_family(cg, B, Fam); if (family==0) return CG_ERROR; if (G > family->ngeos || G <=0) { cgi_error("Invalid index for GeometryEntity_t node"); @@ -2382,6 +3080,17 @@ int cg_part_write(int file_number, int B, int F, int G, const char * part_name, /* FamilyTree extension */ /* ** FAMILY TREE ** */ /*----------------------------------------------------------------------*/ +/** + * \ingroup CGNSGeometryReference + * + * \brief Get geometry entity name (Family_t level) + * + * \param[in] G Geometry reference index number, where 1 ≤ G ≤ nGeo. + * \param[in] P Geometry entity index number, where 1 ≤ P ≤ nparts + * \param[out] part_name Name of a geometry entity in the file FileName. + * \return \ier + * + */ int cg_node_part_read(int G, int P, char *part_name) { cgns_family* family = 0; @@ -2416,6 +3125,17 @@ int cg_node_part_read(int G, int P, char *part_name) } /*----------------------------------------------------------------------*/ +/** + * \ingroup CGNSGeometryReference + * + * \brief Write geometry entity name (Family_t level) + * + * \param[in] G Geometry reference index number, where 1 ≤ G ≤ nGeo. + * \param[in] part_name Name of a geometry entity in the file FileName. + * \param[out] P Geometry entity index number, where 1 ≤ P ≤ nparts + * \return \ier + * + */ int cg_node_part_write(int G, const char * part_name, int *P) { int index; @@ -2498,11 +3218,23 @@ int cg_node_part_write(int G, const char * part_name, int *P) * Read and Write DiscreteData_t Nodes \*****************************************************************************/ -int cg_ndiscrete(int file_number, int B, int Z, int *ndiscrete) +/** + * \ingroup DiscreteData + * + * \brief Get number of `DiscreteData_t` nodes + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[out] ndiscrete Number of `DiscreteData_t` data structures under zone Z. + * \return \ier + * + */ +int cg_ndiscrete(int fn, int B, int Z, int *ndiscrete) { cgns_zone *zone; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -2514,11 +3246,24 @@ int cg_ndiscrete(int file_number, int B, int Z, int *ndiscrete) return CG_OK; } -int cg_discrete_read(int file_number, int B, int Z, int D, char *discrete_name) +/** + * \ingroup DiscreteData + * + * \brief Get name of `DiscreteData_t` node + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] D Discrete data index number, where 1 ≤ D ≤ ndiscrete. + * \param[out] discrete_name Name of `DiscreteData_t` data structures. + * \return \ier + * + */ +int cg_discrete_read(int fn, int B, int Z, int D, char *discrete_name) { cgns_discrete *discrete; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -2531,7 +3276,20 @@ int cg_discrete_read(int file_number, int B, int Z, int D, char *discrete_name) return CG_OK; } -int cg_discrete_write(int file_number, int B, int Z, const char * discrete_name, +/** + * \ingroup DiscreteData + * + * \brief Create a `DiscreteData_t` node + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] discrete_name Name of `DiscreteData_t` data structures. + * \param[out] D Discrete data index number, where 1 ≤ D ≤ ndiscrete. + * \return \ier + * + */ +int cg_discrete_write(int fn, int B, int Z, const char * discrete_name, int *D) { cgns_zone *zone; @@ -2541,7 +3299,7 @@ int cg_discrete_write(int file_number, int B, int Z, const char * discrete_name /* verify input */ if (cgi_check_strlen(discrete_name)) return CG_ERROR; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_WRITE)) return CG_ERROR; @@ -2593,12 +3351,28 @@ int cg_discrete_write(int file_number, int B, int Z, const char * discrete_name return CG_OK; } -int cg_discrete_size(int file_number, int B, int Z, int D, + + +/** + * \ingroup DiscreteData + * + * \brief Get the dimensions of `DiscreteData_t` node + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] D Discrete data index number, where 1 ≤ D ≤ ndiscrete. + * \param[out] data_dim Number of dimensions defining the discrete data. If a point set has been defined, this will be 1, otherwise this will be the current zone index dimension. + * \param[out] dim_vals The array of data_dim dimensions for the discrete data. + * \return \ier + * + */ +int cg_discrete_size(int fn, int B, int Z, int D, int *data_dim, cgsize_t *dim_vals) { cgns_discrete *discrete; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -2621,6 +3395,20 @@ int cg_discrete_size(int file_number, int B, int Z, int D, /*----------------------------------------------------------------------*/ +/** + * \ingroup DiscreteData + * + * \brief Get info about a point set `DiscreteData_t` node + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] D Discrete data index number, where 1 ≤ D ≤ ndiscrete. + * \param[out] ptset_type Type of point set defining the interface for the discrete data; either PointRange or PointList. + * \param[out] npnts Number of points defining the interface for the discrete data. For a ptset_type of PointRange, npnts is always two. For a ptset_type of PointList, npnts is the number of points in the list. + * \return \ier + * + */ int cg_discrete_ptset_info(int fn, int B, int Z, int D, CGNS_ENUMT(PointSetType_t) *ptset_type, cgsize_t *npnts) { @@ -2644,6 +3432,19 @@ int cg_discrete_ptset_info(int fn, int B, int Z, int D, return CG_OK; } +/** + * \ingroup DiscreteData + * + * \brief Read a point set `DiscreteData_t` node + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] D Discrete data index number, where 1 ≤ D ≤ ndiscrete. + * \param[out] pnts Array of points defining the interface for the discrete data. + * \return \ier + * + */ int cg_discrete_ptset_read(int fn, int B, int Z, int D, cgsize_t *pnts) { int dim = 0; @@ -2667,6 +3468,23 @@ int cg_discrete_ptset_read(int fn, int B, int Z, int D, cgsize_t *pnts) return CG_OK; } +/** + * \ingroup DiscreteData + * + * \brief Create a point set `DiscreteData_t` node + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] discrete_name Name of `DiscreteData_t` data structures. + * \param[in] location Grid location where the discrete data is recorded. The current admissible locations are Vertex, CellCenter, IFaceCenter, JFaceCenter, and KFaceCenter. + * \param[in] ptset_type Type of point set defining the interface for the discrete data; either PointRange or PointList. + * \param[in] npnts Number of points defining the interface for the discrete data. For a ptset_type of PointRange, npnts is always two. For a ptset_type of PointList, npnts is the number of points in the list. + * \param[in] pnts Array of points defining the interface for the discrete data. + * \param[out] D Discrete data index number, where 1 ≤ D ≤ ndiscrete. + * \return \ier + * + */ int cg_discrete_ptset_write(int fn, int B, int Z, const char *discrete_name, CGNS_ENUMT(GridLocation_t) location, CGNS_ENUMT(PointSetType_t) ptset_type, cgsize_t npnts, @@ -2728,11 +3546,23 @@ int cg_discrete_ptset_write(int fn, int B, int Z, * Read and Write GridCoordinates_t Nodes \*****************************************************************************/ -int cg_ngrids(int file_number, int B, int Z, int *ngrids) +/** + * \ingroup ZoneGridCoordinates + * + * \brief Get number of `GridCoordinates_t` nodes + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[out] ngrids Number of `GridCoordinates_t` nodes for zone Z. + * \return \ier + * + */ +int cg_ngrids(int fn, int B, int Z, int *ngrids) { cgns_zone *zone; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -2745,11 +3575,24 @@ int cg_ngrids(int file_number, int B, int Z, int *ngrids) return CG_OK; } -int cg_grid_read(int file_number, int B, int Z, int G, char *gridname) +/** + * \ingroup ZoneGridCoordinates + * + * \brief Get Name of a `GridCoordinates_t` node + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] G \G_Grid + * \param[out] grid_coord_name Name of the GridCoordinates_t node. Note that the name "GridCoordinates" is reserved for the original grid and must be the first GridCoordinates_t node to be defined. + * \return \ier + * + */ +int cg_grid_read(int fn, int B, int Z, int G, char *grid_coord_name) { cgns_zcoor *zcoor; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -2759,21 +3602,34 @@ int cg_grid_read(int file_number, int B, int Z, int G, char *gridname) if (zcoor==0) return CG_ERROR; /* Return ADF name for the GridCoordinates_t node */ - strcpy(gridname,zcoor->name); + strcpy(grid_coord_name,zcoor->name); return CG_OK; } -int cg_grid_write(int file_number, int B, int Z, const char * zcoorname, int *G) +/** + * \ingroup ZoneGridCoordinates + * + * \brief Create a `GridCoordinates_t` nodes + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] grid_coord_name Name of the GridCoordinates_t node. Note that the name "GridCoordinates" is reserved for the original grid and must be the first GridCoordinates_t node to be defined. + * \param[out] G \G_Grid + * \return \ier + * + */ +int cg_grid_write(int fn, int B, int Z, const char * grid_coord_name, int *G) { cgns_zone *zone; cgns_zcoor *zcoor = NULL; int index, n, index_dim; /* verify input */ - if (cgi_check_strlen(zcoorname)) return CG_ERROR; + if (cgi_check_strlen(grid_coord_name)) return CG_ERROR; /* get memory address */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_WRITE)) return CG_ERROR; @@ -2783,11 +3639,11 @@ int cg_grid_write(int file_number, int B, int Z, const char * zcoorname, int *G) /* Overwrite a GridCoordinates_t Node: */ for (index=0; indexnzcoor; index++) { - if (strcmp(zcoorname, zone->zcoor[index].name)==0) { + if (strcmp(grid_coord_name, zone->zcoor[index].name)==0) { /* in CG_MODE_WRITE, children names must be unique */ if (cg->mode==CG_MODE_WRITE) { - cgi_error("Duplicate child name found: %s",zcoorname); + cgi_error("Duplicate child name found: %s",grid_coord_name); return CG_ERROR; } @@ -2816,7 +3672,7 @@ int cg_grid_write(int file_number, int B, int Z, const char * zcoorname, int *G) /* save data in memory */ memset(zcoor, 0, sizeof(cgns_zcoor)); - strcpy(zcoor->name,zcoorname); + strcpy(zcoor->name,grid_coord_name); index_dim = zone->index_dim; zcoor->rind_planes = (int *)malloc(index_dim*2*sizeof(int)); @@ -2838,7 +3694,23 @@ int cg_grid_write(int file_number, int B, int Z, const char * zcoorname, int *G) * Read and Write GridCoordinates_t bounding box \*****************************************************************************/ -int cg_grid_bounding_box_read(int file_number, int B, int Z, int G, CGNS_ENUMT(DataType_t) type, void* boundingbox) +/** + * \ingroup ZoneGridCoordinates + * + * \brief Get bounding box associated with a `GridCoordinates_t` node + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] G \G_Grid + * \param[in] datatype Data type of the bounding box array written to the file or read. Admissible data types for a coordinate bounding box are RealSingle and RealDouble. + * \param[out] boundingbox Data Array with bounding box values. + * \return \ier + * + * \details When reading a bounding box, if the information is missing from the file, the boundingbox array will remain untouched, and the CG_NODE_NOT_FOUND status is returned. The CGNS MLL relies on the user to compute the bounding box and ensure that the bounding box being stored is coherent with the coordinates under GridCoordinates_t node. + * + */ +int cg_grid_bounding_box_read(int fn, int B, int Z, int G, CGNS_ENUMT(DataType_t) datatype, void* boundingbox) { cgns_zcoor *zcoor; cgns_base *base; @@ -2849,7 +3721,7 @@ int cg_grid_bounding_box_read(int file_number, int B, int Z, int G, CGNS_ENUMT(D cgsize_t dim_vals[12]; cgsize_t num; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -2866,8 +3738,8 @@ int cg_grid_bounding_box_read(int file_number, int B, int Z, int G, CGNS_ENUMT(D /* check bounding box is not an empty array*/ if (strcmp(data_type,"MT")==0) { - cgi_warning("No bounding box read"); - return CG_OK; + cgi_error("No bounding box found for reading"); + return CG_NODE_NOT_FOUND; } if (strcmp(data_type,"R4") && @@ -2891,25 +3763,41 @@ int cg_grid_bounding_box_read(int file_number, int B, int Z, int G, CGNS_ENUMT(D } /* verify input */ - if (type != CGNS_ENUMV(RealSingle) && type != CGNS_ENUMV(RealDouble)) { - cgi_error("Invalid data type for bounding box array: %d", type); + if (datatype != CGNS_ENUMV(RealSingle) && datatype != CGNS_ENUMV(RealDouble)) { + cgi_error("Invalid data type for bounding box array: %d", datatype); return CG_ERROR; } /* transfer small bounding box data to user with correct data type */ - cgi_convert_data(num, cgi_datatype(data_type), vdata, type, boundingbox); + cgi_convert_data(num, cgi_datatype(data_type), vdata, datatype, boundingbox); CGNS_FREE(vdata); return CG_OK; } -int cg_grid_bounding_box_write(int file_number, int B, int Z, int G, CGNS_ENUMT(DataType_t) type, void* boundingbox) +/** + * \ingroup ZoneGridCoordinates + * + * \brief Write bounding box associated with a `GridCoordinates_t` node + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] G \G_Grid + * \param[in] datatype Data type of the bounding box array written to the file or read. Admissible data types for a coordinate bounding box are RealSingle and RealDouble. + * \param[in] boundingbox Data Array with bounding box values. + * \return \ier + * + * \details The CGNS MLL relies on the user to compute the bounding box and ensure that the bounding box being stored is coherent with the coordinates under GridCoordinates_t node. + + */ +int cg_grid_bounding_box_write(int fn, int B, int Z, int G, CGNS_ENUMT(DataType_t) datatype, void* boundingbox) { cgns_base *base; cgns_zcoor *zcoor; cgsize_t dim_vals[2]; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_WRITE)) return CG_ERROR; @@ -2940,13 +3828,13 @@ int cg_grid_bounding_box_write(int file_number, int B, int Z, int G, CGNS_ENUMT( /* Check input */ if (boundingbox == NULL) return CG_OK; - if (type != CGNS_ENUMV(RealSingle) && type != CGNS_ENUMV(RealDouble)) { - cgi_error("Invalid data type for bounding box array: %d", type); + if (datatype != CGNS_ENUMV(RealSingle) && datatype != CGNS_ENUMV(RealDouble)) { + cgi_error("Invalid data type for bounding box array: %d", datatype); return CG_ERROR; } /* Write Bounding box into existing GridCoordinates_t node */ - if (cgio_set_dimensions(cg->cgio, zcoor->id, cgi_adf_datatype(type), 2, dim_vals)) { + if (cgio_set_dimensions(cg->cgio, zcoor->id, cgi_adf_datatype(datatype), 2, dim_vals)) { cg_io_error("cgio_set_dimensions"); return CG_ERROR; } @@ -2962,11 +3850,23 @@ int cg_grid_bounding_box_write(int file_number, int B, int Z, int G, CGNS_ENUMT( * Read and Write GridCoordinates_t/DataArray_t Nodes \*****************************************************************************/ -int cg_ncoords(int file_number, int B, int Z, int *ncoords) +/** + * \ingroup ZoneGridCoordinates + * + * \brief Get number of coordinate arrays + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[out] ncoords Number of coordinate arrays for zone Z. + * \return \ier + * + */ +int cg_ncoords(int fn, int B, int Z, int *ncoords) { cgns_zcoor *zcoor; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -2978,12 +3878,26 @@ int cg_ncoords(int file_number, int B, int Z, int *ncoords) return CG_OK; } -int cg_coord_info(int file_number, int B, int Z, int C, CGNS_ENUMT(DataType_t) *type, +/** + * \ingroup ZoneGridCoordinates + * + * \brief Get info about a coordinate array + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] C \C_Coordinate + * \param[out] datatype Data type of the coordinate array written to the file. Admissible data types for a coordinate array are RealSingle and RealDouble. + * \param[out] coordname Name of the coordinate array. It is strongly advised to use the SIDS nomenclature conventions when naming the coordinate arrays to insure file compatibility. + * \return \ier + * + */ +int cg_coord_info(int fn, int B, int Z, int C, CGNS_ENUMT(DataType_t) *datatype, char *coordname) { cgns_zcoor *zcoor; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -2996,21 +3910,37 @@ int cg_coord_info(int file_number, int B, int Z, int C, CGNS_ENUMT(DataType_t) cgi_error("coord number %d invalid",C); return CG_ERROR; } - *type = cgi_datatype(zcoor->coord[C-1].data_type); + *datatype = cgi_datatype(zcoor->coord[C-1].data_type); strcpy(coordname, zcoor->coord[C-1].name); return CG_OK; } -int cg_coord_read(int file_number, int B, int Z, const char *coordname, - CGNS_ENUMT(DataType_t) type, const cgsize_t *s_rmin, - const cgsize_t *s_rmax, void *coord_ptr) +/** + * \ingroup ZoneGridCoordinates + * + * \brief Read grid coordinate array + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] coordname Name of the coordinate array. It is strongly advised to use the SIDS nomenclature conventions when naming the coordinate arrays to insure file compatibility. + * \param[in] mem_datatype Data type of an array in memory. Admissible data types for a coordinate array are RealSingle and RealDouble. + * \param[in] s_rmin Lower range index in file (eg., imin, jmin, kmin). + * \param[in] s_rmax Upper range index in file (eg., imax, jmax, kmax). + * \param[out] coord_array Array of coordinate values. + * \return \ier + * + */ +int cg_coord_read(int fn, int B, int Z, const char *coordname, + CGNS_ENUMT(DataType_t) mem_datatype, const cgsize_t *s_rmin, + const cgsize_t *s_rmax, void *coord_array) { cgns_zone *zone; int n, m_numdim; /* get memory addresses */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; zone = cgi_get_zone(cg, B, Z); @@ -3032,12 +3962,32 @@ int cg_coord_read(int file_number, int B, int Z, const char *coordname, m_dimvals[n] = m_rmax[n]; } - return cg_coord_general_read(file_number, B, Z, coordname, - s_rmin, s_rmax, type, + return cg_coord_general_read(fn, B, Z, coordname, + s_rmin, s_rmax, mem_datatype, m_numdim, m_dimvals, m_rmin, m_rmax, - coord_ptr); + coord_array); } +/** + * \ingroup ZoneGridCoordinates + * + * \brief Read subset of grid coordinates to a shaped array + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] coordname Name of the coordinate array. It is strongly advised to use the SIDS nomenclature conventions when naming the coordinate arrays to insure file compatibility. + * \param[in] m_type Data type of an array in memory. Admissible data types for a coordinate array are RealSingle and RealDouble. + * \param[in] s_rmin Lower range index in file (eg., imin, jmin, kmin). + * \param[in] s_rmax Upper range index in file (eg., imax, jmax, kmax). + * \param[in] m_numdim Number of dimensions of array in memory. + * \param[in] m_dimvals Dimensions of array in memory. + * \param[in] m_rmin Lower range index in memory (eg., imin, jmin, kmin). + * \param[in] m_rmax Upper range index in memory (eg., imax, jmax, kmax). + * \param[out] coord_ptr Array of coordinate values. + * \return \ier + * + */ int cg_coord_general_read(int fn, int B, int Z, const char *coordname, const cgsize_t *s_rmin, const cgsize_t *s_rmax, CGNS_ENUMT(DataType_t) m_type, @@ -3087,11 +4037,11 @@ int cg_coord_general_read(int fn, int B, int Z, const char *coordname, coord_ptr); } -int cg_coord_id(int file_number, int B, int Z, int C, double *coord_id) +int cg_coord_id(int fn, int B, int Z, int C, double *coord_id) { cgns_zcoor *zcoor; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -3109,7 +4059,22 @@ int cg_coord_id(int file_number, int B, int Z, int C, double *coord_id) return CG_OK; } -int cg_coord_write(int file_number, int B, int Z, CGNS_ENUMT(DataType_t) type, +/** + * \ingroup ZoneGridCoordinates + * + * \brief Write grid coordinates + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] datatype Data type of the coordinate array written to the file. Admissible data types for a coordinate array are RealSingle and RealDouble. + * \param[in] coordname Name of the coordinate array. It is strongly advised to use the SIDS nomenclature conventions when naming the coordinate arrays to insure file compatibility. + * \param[in] coord_ptr Array of coordinate values. + * \param[out] C \C_Coordinate + * \return \ier + * + */ +int cg_coord_write(int fn, int B, int Z, CGNS_ENUMT(DataType_t) datatype, const char *coordname, const void *coord_ptr, int *C) { cgns_zone *zone; @@ -3121,12 +4086,12 @@ int cg_coord_write(int file_number, int B, int Z, CGNS_ENUMT(DataType_t) type, /* verify input */ if (cgi_check_strlen(coordname)) return CG_ERROR; - if (type!=CGNS_ENUMV( RealSingle ) && type!=CGNS_ENUMV( RealDouble )) { - cgi_error("Invalid datatype for coord. array: %d", type); + if (datatype!=CGNS_ENUMV( RealSingle ) && datatype!=CGNS_ENUMV( RealDouble )) { + cgi_error("Invalid datatype for coord. array: %d", datatype); return CG_ERROR; } /* get memory addresses */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; zone = cgi_get_zone(cg, B, Z); @@ -3157,17 +4122,34 @@ int cg_coord_write(int file_number, int B, int Z, CGNS_ENUMT(DataType_t) type, m_rmax[n] = m_dimvals[n]; } - status = cg_coord_general_write(file_number, B, Z, coordname, - type, s_rmin, s_rmax, - type, m_numdim, m_dimvals, m_rmin, m_rmax, + status = cg_coord_general_write(fn, B, Z, coordname, + datatype, s_rmin, s_rmax, + datatype, m_numdim, m_dimvals, m_rmin, m_rmax, coord_ptr, C); HDF5storage_type = CG_COMPACT; return status; } -int cg_coord_partial_write(int file_number, int B, int Z, - CGNS_ENUMT(DataType_t) type, +/** + * \ingroup ZoneGridCoordinates + * + * \brief Write subset of grid coordinates + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] datatype Data type of the coordinate array written to the file. Admissible data types for a coordinate array are RealSingle and RealDouble. + * \param[in] coordname Name of the coordinate array. It is strongly advised to use the SIDS nomenclature conventions when naming the coordinate arrays to insure file compatibility. + * \param[in] s_rmin Lower range index in file (eg., imin, jmin, kmin). + * \param[in] s_rmax Upper range index in file (eg., imax, jmax, kmax). + * \param[in] coord_ptr Array of coordinate values. + * \param[out] C \C_Coordinate + * \return \ier + * + */ +int cg_coord_partial_write(int fn, int B, int Z, + CGNS_ENUMT(DataType_t) datatype, const char *coordname, const cgsize_t *s_rmin, const cgsize_t *s_rmax, const void *coord_ptr, int *C) @@ -3177,7 +4159,7 @@ int cg_coord_partial_write(int file_number, int B, int Z, int status; /* get memory addresses */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; zone = cgi_get_zone(cg, B, Z); @@ -3198,13 +4180,35 @@ int cg_coord_partial_write(int file_number, int B, int Z, m_dimvals[n] = m_rmax[n]; } - status = cg_coord_general_write(file_number, B, Z, coordname, - type, s_rmin, s_rmax, - type, m_numdim, m_dimvals, m_rmin, m_rmax, + status = cg_coord_general_write(fn, B, Z, coordname, + datatype, s_rmin, s_rmax, + datatype, m_numdim, m_dimvals, m_rmin, m_rmax, coord_ptr, C); return status; } +/** + * \ingroup ZoneGridCoordinates + * + * \brief Write shaped array to a subset of grid coordinates + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] coordname Name of the coordinate array. It is strongly advised to use the SIDS nomenclature conventions when naming the coordinate arrays to insure file compatibility. + * \param[in] s_type Data type of the coordinate array written to the file. Admissible data types for a coordinate array are RealSingle and RealDouble. + * \param[in] m_type Data type of an array in memory. Admissible data types for a coordinate array are RealSingle and RealDouble. + * \param[in] s_rmin Lower range index in file (eg., imin, jmin, kmin). + * \param[in] s_rmax Upper range index in file (eg., imax, jmax, kmax). + * \param[in] m_numdim Number of dimensions of array in memory. + * \param[in] m_dimvals Dimensions of array in memory. + * \param[in] m_rmin Lower range index in memory (eg., imin, jmin, kmin). + * \param[in] m_rmax Upper range index in memory (eg., imax, jmax, kmax). + * \param[in] coord_ptr Array of coordinate values. + * \param[out] C \C_Coordinate + * \return \ier + * + */ int cg_coord_general_write(int fn, int B, int Z, const char *coordname, CGNS_ENUMT(DataType_t) s_type, const cgsize_t *s_rmin, const cgsize_t *s_rmax, @@ -3435,11 +4439,23 @@ static int read_parent_data(cgns_section *section) /*----------------------------------------------------------------------*/ -int cg_nsections(int file_number, int B, int Z, int *nsections) +/** + * \ingroup ElementConnectivity + * + * \brief Get number of element sections + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[out] nsections Number of element sections. + * \return \ier + * + */ +int cg_nsections(int fn, int B, int Z, int *nsections) { cgns_zone *zone; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; /* verify input */ @@ -3452,13 +4468,31 @@ int cg_nsections(int file_number, int B, int Z, int *nsections) return CG_OK; } -int cg_section_read(int file_number, int B, int Z, int S, char *SectionName, +/** + * \ingroup ElementConnectivity + * + * \brief Get info for an element section + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] S \CONN_S + * \param[in] type Type of element. See the eligible types for ElementType_t in the Typedefs section. + * \param[out] SectionName Name of the Elements_t node. + * \param[out] start Index of first element in the section. + * \param[out] end Index of last element in the section. + * \param[out] nbndry Index of last boundary element in the section. Set to zero if the elements are unsorted. + * \param[out] parent_flag Flag indicating if the parent data are defined. If the parent data exist, parent_flag is set to 1; otherwise it is set to 0. + * \return \ier + * + */ +int cg_section_read(int fn, int B, int Z, int S, char *SectionName, CGNS_ENUMT(ElementType_t) *type, cgsize_t *start, cgsize_t *end, int *nbndry, int *parent_flag) { cgns_section *section; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; /* verify input */ @@ -3478,7 +4512,27 @@ int cg_section_read(int file_number, int B, int Z, int S, char *SectionName, return CG_OK; } -int cg_section_write(int file_number, int B, int Z, const char * SectionName, +/** + * \ingroup ElementConnectivity + * + * \brief Write fixed size element data + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] type Type of element. See the eligible types for ElementType_t in the Typedefs section. + * \param[in] SectionName Name of the Elements_t node. + * \param[in] start Index of first element in the section. + * \param[in] end Index of last element in the section. + * \param[in] nbndry Index of last boundary element in the section. Set to zero if the elements are unsorted. + * \param[in] elements Element connectivity data. The element connectivity order is given in Element Numbering Conventions. + * \param[out] S \CONN_S + * \return \ier + * + * \details This writing function only works with fixed size elements. + * + */ +int cg_section_write(int fn, int B, int Z, const char * SectionName, CGNS_ENUMT(ElementType_t)type, cgsize_t start, cgsize_t end, int nbndry, const cgsize_t * elements, int *S) @@ -3491,7 +4545,7 @@ int cg_section_write(int file_number, int B, int Z, const char * SectionName, return CG_ERROR; } - if (cg_section_general_write(file_number, B, Z, SectionName, type, + if (cg_section_general_write(fn, B, Z, SectionName, type, cgi_datatype(CG_SIZE_DATATYPE), start, end, 0, nbndry, S)){ return CG_ERROR; @@ -3510,7 +4564,26 @@ int cg_section_write(int file_number, int B, int Z, const char * SectionName, return CG_OK; } -int cg_poly_section_write(int file_number, int B, int Z, const char * SectionName, +/** + * \ingroup ElementConnectivity + * + * \brief Write element data + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] type Type of element. See the eligible types for ElementType_t in the Typedefs section. + * \param[in] SectionName Name of the Elements_t node. + * \param[in] start Index of first element in the section. + * \param[in] end Index of last element in the section. + * \param[in] nbndry Index of last boundary element in the section. Set to zero if the elements are unsorted. + * \param[in] elements Element connectivity data. The element connectivity order is given in Element Numbering Conventions. + * \param[in] connect_offset Element connectivity offset data. This is required for NGON_n, NFACE_n and MIXED according to Elements_t Structure Definition. + * \param[out] S \CONN_S + * \return \ier + * + */ +int cg_poly_section_write(int fn, int B, int Z, const char * SectionName, CGNS_ENUMT(ElementType_t)type, cgsize_t start, cgsize_t end, int nbndry, const cgsize_t * elements, const cgsize_t * connect_offset, int *S) @@ -3520,7 +4593,7 @@ int cg_poly_section_write(int file_number, int B, int Z, const char * SectionNam cgsize_t num, ElementDataSize=0; /* get file and check mode */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; num = end - start + 1; @@ -3537,7 +4610,7 @@ int cg_poly_section_write(int file_number, int B, int Z, const char * SectionNam if (ElementDataSize < 0) return CG_ERROR; /* Create empty section */ - if (cg_section_general_write(file_number, B, Z, SectionName, type, + if (cg_section_general_write(fn, B, Z, SectionName, type, cgi_datatype(CG_SIZE_DATATYPE), start, end, ElementDataSize, nbndry, S)){ return CG_ERROR; @@ -3567,7 +4640,24 @@ int cg_poly_section_write(int file_number, int B, int Z, const char * SectionNam return CG_OK; } -int cg_section_partial_write(int file_number, int B, int Z, const char * SectionName, +/** + * \ingroup ElementConnectivity + * + * \brief Write subset of element data + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] type Type of element. See the eligible types for ElementType_t in the Typedefs section. + * \param[in] SectionName Name of the Elements_t node. + * \param[in] start Index of first element in the section. + * \param[in] end Index of last element in the section. + * \param[in] nbndry Index of last boundary element in the section. Set to zero if the elements are unsorted. + * \param[out] S \CONN_S + * \return \ier + * + */ +int cg_section_partial_write(int fn, int B, int Z, const char * SectionName, CGNS_ENUMT(ElementType_t) type, cgsize_t start, cgsize_t end, int nbndry, int *S) { @@ -3580,20 +4670,39 @@ int cg_section_partial_write(int file_number, int B, int Z, const char * Section ElementDataSize = num * elemsize; /* create empty section */ - if (cg_section_general_write(file_number, B, Z, SectionName, type, + if (cg_section_general_write(fn, B, Z, SectionName, type, cgi_datatype(CG_SIZE_DATATYPE), start, end, ElementDataSize, nbndry, S)){ return CG_ERROR; } /* if not fixed element size, need to create valid data for sizing */ - if (cg_section_initialize(file_number, B, Z, *S)) { + if (cg_section_initialize(fn, B, Z, *S)) { return CG_ERROR; } return CG_OK; } -int cg_section_general_write(int file_number, int B, int Z, const char * SectionName, +/** + * \ingroup ElementConnectivity + * + * \brief Write section data without element data + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] type Type of element. See the eligible types for ElementType_t in the Typedefs section. + * \param[in] elementDataType Data type of an array. Admissible data types are Integer and LongInteger. + * \param[in] SectionName Name of the Elements_t node. + * \param[in] start Index of first element in the section. + * \param[in] end Index of last element in the section. + * \param[in] elementDataSize Number of element connectivity data values. + * \param[in] nbndry Index of last boundary element in the section. Set to zero if the elements are unsorted. + * \param[out] S \CONN_S + * \return \ier + * + */ +int cg_section_general_write(int fn, int B, int Z, const char * SectionName, const CGNS_ENUMT(ElementType_t) type, const CGNS_ENUMT(DataType_t) elementDataType, cgsize_t start, cgsize_t end, cgsize_t elementDataSize, int nbndry, int *S) @@ -3650,7 +4759,7 @@ int cg_section_general_write(int file_number, int B, int Z, const char * Section } /* get file and check mode */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_WRITE)) @@ -3771,12 +4880,11 @@ int cg_section_general_write(int file_number, int B, int Z, const char * Section /* Do not write I8 in library that is not 64bit */ return CG_ERROR; } + HDF5storage_type = CG_CONTIGUOUS; /* ElementRange */ if (cgi_new_node(section->id, "ElementRange", "IndexRange_t", &dummy_id, data_type, 1, &dim_vals, prange)) return CG_ERROR; - HDF5storage_type = CG_CONTIGUOUS; - /* ElementStartOffset */ if (section->connect_offset && cgi_new_node(section->id, section->connect_offset->name, "DataArray_t", @@ -3793,11 +4901,22 @@ int cg_section_general_write(int file_number, int B, int Z, const char * Section return CG_OK; } -/* This function is a kind of helper to be used after a cg_section_general_write +/** + * \ingroup ElementConnectivity + * + * \brief Initialize element data for not fixed size elements + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[out] S \CONN_S + * \return \ier + * + * \details This function is a kind of helper to be used after a cg_section_general_write * cg_section_general_write reserve enough space while this function put * coherent init data. Then cg_poly_elements_partial_write would run safely. */ -int cg_section_initialize(int file_number, int B, int Z, int S) +int cg_section_initialize(int fn, int B, int Z, int S) { cgsize_t nm, nn, num, val; cgsize_t s_start, s_end, s_stride; @@ -3807,7 +4926,7 @@ int cg_section_initialize(int file_number, int B, int Z, int S) cgns_section *section = NULL; /* get file and check mode */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; /* verify input */ @@ -4010,17 +5129,28 @@ int cg_section_initialize(int file_number, int B, int Z, int S) return CG_OK; } - /*----------------------------------------------------------------------*/ -/* This function was created for revision 1.2 to return the size of the - connectivity vector, which can't be known without it *when type=MIXED */ - -int cg_ElementDataSize(int file_number, int B, int Z, int S, +/** + * \ingroup ElementConnectivity + * + * \brief Get size of element connectivity data array + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] S \CONN_S + * \param[out] ElementDataSize Number of element connectivity data values. + * \return \ier + * + * \details This function was created for revision 1.2 to return the size of the + * connectivity vector, which can't be known without it *when type=MIXED* + */ +int cg_ElementDataSize(int fn, int B, int Z, int S, cgsize_t *ElementDataSize) { cgns_section *section; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; /* verify input */ @@ -4033,13 +5163,30 @@ int cg_ElementDataSize(int file_number, int B, int Z, int S, return CG_OK; } -int cg_ElementPartialSize(int file_number, int B, int Z, int S, +/** + * \ingroup ElementConnectivity + * + * \brief Get size of element connectivity data array for partial read + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] S \CONN_S + * \param[in] start Index of first element in the section. + * \param[in] end Index of last element in the section. + * \param[out] ElementDataSize Number of element connectivity data values. + * \return \ier + * + * \details This function was created for revision 1.2 to return the size of the + * connectivity vector, which can't be known without it *when type=MIXED* + */ +int cg_ElementPartialSize(int fn, int B, int Z, int S, cgsize_t start, cgsize_t end, cgsize_t *ElementDataSize) { cgns_section *section; cgsize_t size, cnt, *offset_data; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; /* verify input */ @@ -4131,14 +5278,27 @@ int cg_ElementPartialSize(int file_number, int B, int Z, int S, } /*----------------------------------------------------------------------*/ - -int cg_elements_read(int file_number, int B, int Z, int S, cgsize_t *elements, +/** + * \ingroup ElementConnectivity + * + * \brief Read fixed size element data + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] S \CONN_S + * \param[out] elements Element connectivity data. The element connectivity order is given in Element Numbering Conventions. + * \param[out] parent_data For boundary or interface elements, this array contains information on the cell(s) and cell face(s) sharing the element. If you do not need to read the ParentData when reading the ElementData, you may set the value to NULL. + * \return \ier + * + */ +int cg_elements_read(int fn, int B, int Z, int S, cgsize_t *elements, cgsize_t *parent_data) { cgns_section *section; cgsize_t count, num, ElementDataSize=0; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; /* verify input */ @@ -4191,15 +5351,29 @@ int cg_elements_read(int file_number, int B, int Z, int S, cgsize_t *elements, } /*----------------------------------------------------------------------*/ - -int cg_poly_elements_read(int file_number, int B, int Z, int S, cgsize_t *elements, +/** + * \ingroup ElementConnectivity + * + * \brief Read element data + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] S \CONN_S + * \param[out] elements Element connectivity data. The element connectivity order is given in Element Numbering Conventions. + * \param[out] connect_offset Element connectivity offset data. This is required for NGON_n, NFACE_n and MIXED according to Elements_t Structure Definition. + * \param[out] parent_data For boundary or interface elements, this array contains information on the cell(s) and cell face(s) sharing the element. If you do not need to read the ParentData when reading the ElementData, you may set the value to NULL. + * \return \ier + * + */ +int cg_poly_elements_read(int fn, int B, int Z, int S, cgsize_t *elements, cgsize_t *connect_offset, cgsize_t *parent_data) { cgns_section *section; cgsize_t count, num, ElementDataSize=0, ConnectOffsetSize=0; cgsize_t *offset_data=0; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; /* verify input */ @@ -4264,7 +5438,24 @@ int cg_poly_elements_read(int file_number, int B, int Z, int S, cgsize_t *elemen } /*----------------------------------------------------------------------*/ -int cg_elements_partial_read(int file_number, int B, int Z, int S, + +/** + * \ingroup ElementConnectivity + * + * \brief Read subset of fixed size element data + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] S \CONN_S + * \param[in] start Index of first element in the section. + * \param[in] end Index of last element in the section. + * \param[out] elements Element connectivity data. The element connectivity order is given in Element Numbering Conventions. + * \param[out] parent_data For boundary or interface elements, this array contains information on the cell(s) and cell face(s) sharing the element. If you do not need to read the ParentData when reading the ElementData, you may set the value to NULL. + * \return \ier + * + */ +int cg_elements_partial_read(int fn, int B, int Z, int S, cgsize_t start, cgsize_t end, cgsize_t *elements, cgsize_t *parent_data) { @@ -4274,7 +5465,7 @@ int cg_elements_partial_read(int file_number, int B, int Z, int S, cgsize_t s_start[2], s_end[2], s_stride[2]; cgsize_t m_start[2], m_end[2], m_stride[2], m_dim[2]; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; /* verify input */ @@ -4437,19 +5628,34 @@ int cg_elements_partial_read(int file_number, int B, int Z, int S, return CG_OK; } - /*----------------------------------------------------------------------*/ -int cg_elements_general_read(int file_number, int B, int Z, int S, +/** + * \ingroup ElementConnectivity + * + * \brief Read subset of fixed size element data to a typed array + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] S \CONN_S + * \param[in] start Index of first element in the section. + * \param[in] end Index of last element in the section. + * \param[in] m_type Data type of an array in memory. Admissible data types are Integer and LongInteger. + * \param[out] elements Element connectivity data. The element connectivity order is given in Element Numbering Conventions. + * \return \ier + * + */ +int cg_elements_general_read(int fn, int B, int Z, int S, cgsize_t start, cgsize_t end, CGNS_ENUMT(DataType_t) m_type, void* elements) { cgns_section* section; - cgsize_t size; + cgsize_t size = 0; cgsize_t s_start[1], s_end[1], s_stride[1]; cgsize_t m_start[1], m_end[1], m_stride[1], m_dim[1]; CGNS_ENUMT(DataType_t) s_type; int ier = CG_OK; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; /* verify input */ @@ -4563,8 +5769,24 @@ int cg_elements_general_read(int file_number, int B, int Z, int S, /*----------------------------------------------------------------------*/ -int cg_parent_elements_general_read(int file_number, int B, int Z, int S, - cgsize_t start, cgsize_t end, CGNS_ENUMT(DataType_t) m_type, void* parelem) +/** + * \ingroup ElementConnectivity + * + * \brief Read parent info for an element section + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] S \CONN_S + * \param[in] start Index of first element in the section. + * \param[in] end Index of last element in the section. + * \param[in] m_type Data type of an array in memory. Admissible data types are Integer and LongInteger. + * \param[out] ParentElement For boundary or interface elements, this array contains information on the cell(s) sharing the element. + * \return \ier + * + */ +int cg_parent_elements_general_read(int fn, int B, int Z, int S, + cgsize_t start, cgsize_t end, CGNS_ENUMT(DataType_t) m_type, void* ParentElement) { cgns_section* section; cgsize_t s_start[2], s_end[2], s_stride[2]; @@ -4572,7 +5794,7 @@ int cg_parent_elements_general_read(int file_number, int B, int Z, int S, CGNS_ENUMT(DataType_t) s_type; int ier = CG_OK; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; /* verify input */ @@ -4596,7 +5818,7 @@ int cg_parent_elements_general_read(int file_number, int B, int Z, int S, return CG_ERROR; } - if (parelem == NULL || section->parelem == NULL) { + if (ParentElement == NULL || section->parelem == NULL) { cgi_error("Error reading ParentElementsPosition."); return CG_ERROR; } @@ -4623,7 +5845,7 @@ int cg_parent_elements_general_read(int file_number, int B, int Z, int S, if (section->connect->dim_vals[0] == m_end[0] && section->connect->dim_vals[1] == 2) { if (cgio_read_all_data_type(cg->cgio, section->parelem->id, - cgi_adf_datatype(m_type), parelem)) { + cgi_adf_datatype(m_type), ParentElement)) { cg_io_error("cgio_read_all_data_type"); return CG_ERROR; } @@ -4631,7 +5853,7 @@ int cg_parent_elements_general_read(int file_number, int B, int Z, int S, else { if (cgio_read_data_type(cg->cgio, section->parelem->id, s_start, s_end, s_stride, cgi_adf_datatype(m_type), 2, m_dim, - m_start, m_end, m_stride, parelem)) { + m_start, m_end, m_stride, ParentElement)) { cg_io_error("cgio_read_data_type"); return CG_ERROR; } @@ -4663,7 +5885,7 @@ int cg_parent_elements_general_read(int file_number, int B, int Z, int S, return CG_ERROR; } } - ier = cgi_convert_data(2*m_dim[0], s_type, conv_data, m_type, parelem); + ier = cgi_convert_data(2*m_dim[0], s_type, conv_data, m_type, ParentElement); free(conv_data); if (ier) return CG_ERROR; } @@ -4672,7 +5894,7 @@ int cg_parent_elements_general_read(int file_number, int B, int Z, int S, if (section->parelem->dim_vals[0] == m_dim[0] && section->parelem->dim_vals[1] == 2) { if (cgio_read_all_data_type(cg->cgio, section->parelem->id, - cgi_adf_datatype(m_type), parelem)) { + cgi_adf_datatype(m_type), ParentElement)) { cg_io_error("cgio_read_all_data_type"); return CG_ERROR; } @@ -4680,7 +5902,7 @@ int cg_parent_elements_general_read(int file_number, int B, int Z, int S, else { if (cgio_read_data_type(cg->cgio, section->parelem->id, s_start, s_end, s_stride, cgi_adf_datatype(m_type), 2, m_dim, - m_start, m_end, m_stride, parelem)) { + m_start, m_end, m_stride, ParentElement)) { cg_io_error("cgio_read_data_type"); return CG_ERROR; } @@ -4690,8 +5912,25 @@ int cg_parent_elements_general_read(int file_number, int B, int Z, int S, } /*----------------------------------------------------------------------*/ -int cg_parent_elements_position_general_read(int file_number, int B, int Z, int S, - cgsize_t start, cgsize_t end, CGNS_ENUMT(DataType_t) m_type, void* parface) + +/** + * \ingroup ElementConnectivity + * + * \brief Read parent position info for an element section + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] S \CONN_S + * \param[in] start Index of first element in the section. + * \param[in] end Index of last element in the section. + * \param[in] m_type Data type of an array in memory. Admissible data types are Integer and LongInteger. + * \param[out] ParentFace For boundary or interface elements, this array contains information on the cell face(s) sharing the element. + * \return \ier + * + */ +int cg_parent_elements_position_general_read(int fn, int B, int Z, int S, + cgsize_t start, cgsize_t end, CGNS_ENUMT(DataType_t) m_type, void* ParentFace) { cgns_section* section; cgsize_t s_start[2], s_end[2], s_stride[2]; @@ -4699,7 +5938,7 @@ int cg_parent_elements_position_general_read(int file_number, int B, int Z, int CGNS_ENUMT(DataType_t) s_type; int ier = CG_OK; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; /* verify input */ @@ -4723,7 +5962,7 @@ int cg_parent_elements_position_general_read(int file_number, int B, int Z, int return CG_ERROR; } - if (parface == NULL || section->parface == NULL) { + if (ParentFace == NULL || section->parface == NULL) { cgi_error("Error reading ParentElementsPosition."); return CG_ERROR; } @@ -4750,7 +5989,7 @@ int cg_parent_elements_position_general_read(int file_number, int B, int Z, int if (section->connect->dim_vals[0] == m_end[0] && section->connect->dim_vals[1] == 2) { if (cgio_read_all_data_type(cg->cgio, section->parface->id, - cgi_adf_datatype(m_type), parface)) { + cgi_adf_datatype(m_type), ParentFace)) { cg_io_error("cgio_read_all_data_type"); return CG_ERROR; } @@ -4758,7 +5997,7 @@ int cg_parent_elements_position_general_read(int file_number, int B, int Z, int else { if (cgio_read_data_type(cg->cgio, section->parface->id, s_start, s_end, s_stride, cgi_adf_datatype(m_type), 2, m_dim, - m_start, m_end, m_stride, parface)) { + m_start, m_end, m_stride, ParentFace)) { cg_io_error("cgio_read_data_type"); return CG_ERROR; } @@ -4790,7 +6029,7 @@ int cg_parent_elements_position_general_read(int file_number, int B, int Z, int return CG_ERROR; } } - ier = cgi_convert_data(m_dim[0]*2, s_type, conv_data, m_type, parface); + ier = cgi_convert_data(m_dim[0]*2, s_type, conv_data, m_type, ParentFace); free(conv_data); if (ier) return CG_ERROR; } @@ -4799,7 +6038,7 @@ int cg_parent_elements_position_general_read(int file_number, int B, int Z, int if (section->connect->dim_vals[0] == m_dim[0] && section->connect->dim_vals[1] == 2) { if (cgio_read_all_data_type(cg->cgio, section->parface->id, - cgi_adf_datatype(m_type), parface)) { + cgi_adf_datatype(m_type), ParentFace)) { cg_io_error("cgio_read_all_data_type"); return CG_ERROR; } @@ -4807,7 +6046,7 @@ int cg_parent_elements_position_general_read(int file_number, int B, int Z, int else { if (cgio_read_data_type(cg->cgio, section->parface->id, s_start, s_end, s_stride, cgi_adf_datatype(m_type), 2, m_dim, - m_start, m_end, m_stride, parface)) { + m_start, m_end, m_stride, ParentFace)) { cg_io_error("cgio_read_data_type"); return CG_ERROR; } @@ -4817,7 +6056,24 @@ int cg_parent_elements_position_general_read(int file_number, int B, int Z, int } /*----------------------------------------------------------------------*/ -int cg_poly_elements_partial_read(int file_number, int B, int Z, int S, +/** + * \ingroup ElementConnectivity + * + * \brief Read subset of element data + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] S \CONN_S + * \param[in] start Index of first element in the section. + * \param[in] end Index of last element in the section. + * \param[out] elements Element connectivity data. The element connectivity order is given in Element Numbering Conventions. + * \param[out] connect_offset Element connectivity offset data. This is required for NGON_n, NFACE_n and MIXED according to Elements_t Structure Definition. + * \param[out] parent_data For boundary or interface elements, this array contains information on the cell(s) and cell face(s) sharing the element. If you do not need to read the ParentData when reading the ElementData, you may set the value to NULL. + * \return \ier + * + */ +int cg_poly_elements_partial_read(int fn, int B, int Z, int S, cgsize_t start, cgsize_t end, cgsize_t *elements, cgsize_t *connect_offset, cgsize_t *parent_data) { @@ -4827,7 +6083,7 @@ int cg_poly_elements_partial_read(int file_number, int B, int Z, int S, cgsize_t s_start[2], s_end[2], s_stride[2]; cgsize_t m_start[2], m_end[2], m_stride[2], m_dim[2]; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; /* verify input */ @@ -4996,7 +6252,24 @@ int cg_poly_elements_partial_read(int file_number, int B, int Z, int S, } /*----------------------------------------------------------------------*/ -int cg_poly_elements_general_read(int file_number, int B, int Z, int S, +/** + * \ingroup ElementConnectivity + * + * \brief Read subset of element data to typed arrays + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] S \CONN_S + * \param[in] start Index of first element in the section. + * \param[in] end Index of last element in the section. + * \param[in] m_type Data type of an array in memory. Admissible data types are Integer and LongInteger. + * \param[out] elements Element connectivity data. The element connectivity order is given in Element Numbering Conventions. + * \param[out] connect_offset Element connectivity offset data. This is required for NGON_n, NFACE_n and MIXED according to Elements_t Structure Definition. + * \return \ier + * + */ +int cg_poly_elements_general_read(int fn, int B, int Z, int S, cgsize_t start, cgsize_t end, CGNS_ENUMT(DataType_t) m_type, void* elements, void* connect_offset) { @@ -5007,7 +6280,7 @@ int cg_poly_elements_general_read(int file_number, int B, int Z, int S, CGNS_ENUMT(DataType_t) s_type; int ier = CG_OK; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; /* verify input */ @@ -5130,12 +6403,26 @@ int cg_poly_elements_general_read(int file_number, int B, int Z, int S, } /*----------------------------------------------------------------------*/ - -int cg_elements_partial_write(int file_number, int B, int Z, int S, +/** + * \ingroup ElementConnectivity + * + * \brief Write element data for a fixed size element section + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] S \CONN_S + * \param[in] start Index of first element in the section. + * \param[in] end Index of last element in the section. + * \param[in] elements Element connectivity data. The element connectivity order is given in Element Numbering Conventions. + * \return \ier + * + */ +int cg_elements_partial_write(int fn, int B, int Z, int S, cgsize_t start, cgsize_t end, const cgsize_t *elements) { - if (cg_elements_general_write(file_number, B, Z, S, + if (cg_elements_general_write(fn, B, Z, S, start, end, cgi_datatype(CG_SIZE_DATATYPE), elements)) { return CG_ERROR; } @@ -5302,7 +6589,23 @@ int cg_elements_partial_write(int file_number, int B, int Z, int S, } \ } -int cg_elements_general_write(int file_number, int B, int Z, int S, +/** + * \ingroup ElementConnectivity + * + * \brief Write element data for a fixed size element section + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] S \CONN_S + * \param[in] start Index of first element in the section. + * \param[in] end Index of last element in the section. + * \param[in] m_type Data type of an array in memory. Admissible data types are Integer and LongInteger. + * \param[in] elements Element connectivity data. The element connectivity order is given in Element Numbering Conventions. + * \return \ier + * + */ +int cg_elements_general_write(int fn, int B, int Z, int S, cgsize_t start, cgsize_t end, const CGNS_ENUMT(DataType_t) m_type, const void *elements) { @@ -5318,7 +6621,7 @@ int cg_elements_general_write(int file_number, int B, int Z, int S, int ier = CG_OK; /* get file and check mode */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_WRITE)) @@ -5601,11 +6904,27 @@ int cg_elements_general_write(int file_number, int B, int Z, int S, return CG_OK; } -int cg_poly_elements_partial_write(int file_number, int B, int Z, int S, +/** + * \ingroup ElementConnectivity + * + * \brief Write element data for an element section + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] S \CONN_S + * \param[in] start Index of first element in the section. + * \param[in] end Index of last element in the section. + * \param[in] elements Element connectivity data. The element connectivity order is given in Element Numbering Conventions. + * \param[in] connect_offset Element connectivity offset data. This is required for NGON_n, NFACE_n and MIXED according to Elements_t Structure Definition. + * \return \ier + * + */ +int cg_poly_elements_partial_write(int fn, int B, int Z, int S, cgsize_t start, cgsize_t end, const cgsize_t *elements, const cgsize_t *connect_offset) { - if (cg_poly_elements_general_write(file_number, B, Z, S, + if (cg_poly_elements_general_write(fn, B, Z, S, start, end, cgi_datatype(CG_SIZE_DATATYPE), elements, connect_offset)) { return CG_ERROR; @@ -5613,7 +6932,24 @@ int cg_poly_elements_partial_write(int file_number, int B, int Z, int S, return CG_OK; } -int cg_poly_elements_general_write(int file_number, int B, int Z, int S, +/** + * \ingroup ElementConnectivity + * + * \brief Write element data for an element section + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] S \CONN_S + * \param[in] start Index of first element in the section. + * \param[in] end Index of last element in the section. + * \param[in] m_type Data type of an array in memory. Admissible data types are Integer and LongInteger. + * \param[in] elements Element connectivity data. The element connectivity order is given in Element Numbering Conventions. + * \param[in] input_connect_offset Element connectivity offset data. This is required for NGON_n, NFACE_n and MIXED according to Elements_t Structure Definition. + * \return \ier + * + */ +int cg_poly_elements_general_write(int fn, int B, int Z, int S, cgsize_t start, cgsize_t end, const CGNS_ENUMT(DataType_t) m_type, const void *elements, const void *input_connect_offset) { @@ -5634,7 +6970,7 @@ int cg_poly_elements_general_write(int file_number, int B, int Z, int S, CGNS_ENUMT(DataType_t) s_type; /* get file and check mode */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_WRITE)) @@ -6198,15 +7534,27 @@ int cg_poly_elements_general_write(int file_number, int B, int Z, int S, } /*----------------------------------------------------------------------*/ - -int cg_parent_data_write(int file_number, int B, int Z, int S, +/** + * \ingroup ElementConnectivity + * + * \brief Write parent info for an element section + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] S \CONN_S + * \param[in] parent_data For boundary or interface elements, this array contains information on the cell(s) and cell face(s) sharing the element. If you do not need to read the ParentData when reading the ElementData, you may set the value to NULL. + * \return \ier + * + */ +int cg_parent_data_write(int fn, int B, int Z, int S, const cgsize_t * parent_data) { cgns_section *section; cgsize_t num; /* get file and check mode */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_WRITE)) @@ -6289,9 +7637,22 @@ int cg_parent_data_write(int file_number, int B, int Z, int S, return CG_OK; } - - -int cg_parent_data_partial_write(int file_number, int B, int Z, int S, +/** + * \ingroup ElementConnectivity + * + * \brief Write subset of parent info for an element section + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] S \CONN_S + * \param[in] start Index of first element in the section. + * \param[in] end Index of last element in the section. + * \param[in] parent_data For boundary or interface elements, this array contains information on the cell(s) and cell face(s) sharing the element. If you do not need to read the ParentData when reading the ElementData, you may set the value to NULL. + * \return \ier + * + */ +int cg_parent_data_partial_write(int fn, int B, int Z, int S, cgsize_t start, cgsize_t end, const cgsize_t *parent_data) { @@ -6299,7 +7660,7 @@ int cg_parent_data_partial_write(int file_number, int B, int Z, int S, cgsize_t size; /* get file and check mode */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_WRITE)) return CG_ERROR; @@ -6414,11 +7775,23 @@ int cg_parent_data_partial_write(int file_number, int B, int Z, int S, * Read and Write FlowSolution_t Nodes \*****************************************************************************/ -int cg_nsols(int file_number, int B, int Z, int *nsols) +/** + * \ingroup FlowSolution + * + * \brief Get number of FlowSolution_t nodes + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[out] nsols Number of flow solutions for zone Z. + * \return \ier + * + */ +int cg_nsols(int fn, int B, int Z, int *nsols) { cgns_zone *zone; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -6430,12 +7803,26 @@ int cg_nsols(int file_number, int B, int Z, int *nsols) return CG_OK; } -int cg_sol_info(int file_number, int B, int Z, int S, char *solname, +/** + * \ingroup FlowSolution + * + * \brief Get information about a FlowSolution_t node + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] S \SOL_S + * \param[out] solname Name of the flow solution. + * \param[out] location Grid location where the solution is recorded. The current admissible locations are Vertex, CellCenter, IFaceCenter, JFaceCenter, and KFaceCenter. + * \return \ier + * + */ +int cg_sol_info(int fn, int B, int Z, int S, char *solname, CGNS_ENUMT(GridLocation_t) *location) { cgns_sol *sol; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -6448,11 +7835,11 @@ int cg_sol_info(int file_number, int B, int Z, int S, char *solname, return CG_OK; } -int cg_sol_id(int file_number, int B, int Z, int S, double *sol_id) +int cg_sol_id(int fn, int B, int Z, int S, double *sol_id) { cgns_sol *sol; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -6464,7 +7851,21 @@ int cg_sol_id(int file_number, int B, int Z, int S, double *sol_id) return CG_OK; } -int cg_sol_write(int file_number, int B, int Z, const char * solname, +/** + * \ingroup FlowSolution + * + * \brief Create and/or write to a FlowSolution_t node + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] solname Name of the flow solution. + * \param[in] location Grid location where the solution is recorded. The current admissible locations are Vertex, CellCenter, IFaceCenter, JFaceCenter, and KFaceCenter. + * \param[out] S \SOL_S + * \return \ier + * + */ +int cg_sol_write(int fn, int B, int Z, const char * solname, CGNS_ENUMT(GridLocation_t) location, int *S) { cgns_zone *zone; @@ -6487,7 +7888,7 @@ int cg_sol_write(int file_number, int B, int Z, const char * solname, } */ /* get memory address for FlowSolution node */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_WRITE)) return CG_ERROR; @@ -6562,12 +7963,26 @@ int cg_sol_write(int file_number, int B, int Z, const char * solname, return CG_OK; } -int cg_sol_size(int file_number, int B, int Z, int S, +/** + * \ingroup FlowSolution + * + * \brief Get the dimensions of a FlowSolution_t node + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] S \SOL_S + * \param[out] data_dim Number of dimensions defining the solution data. If a point set has been defined, this will be 1, otherwise this will be the current zone index dimension. + * \param[out] dim_vals The array of data_dim dimensions for the solution data. + * \return \ier + * + */ +int cg_sol_size(int fn, int B, int Z, int S, int *data_dim, cgsize_t *dim_vals) { cgns_sol *sol; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -6589,7 +8004,20 @@ int cg_sol_size(int file_number, int B, int Z, int S, } /*----------------------------------------------------------------------*/ - +/** + * \ingroup FlowSolution + * + * \brief Get info about a point set FlowSolution_t node + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] S \SOL_S + * \param[out] ptset_type Type of point set defining the interface in the current solution; either PointRange or PointList. + * \param[out] npnts Number of points defining the interface in the current solution. For a ptset_type of PointRange, npnts is always two. For a ptset_type of PointList, npnts is the number of points in the PointList. + * \return \ier + * + */ int cg_sol_ptset_info(int fn, int B, int Z, int S, CGNS_ENUMT(PointSetType_t) *ptset_type, cgsize_t *npnts) { @@ -6613,6 +8041,19 @@ int cg_sol_ptset_info(int fn, int B, int Z, int S, return CG_OK; } +/** + * \ingroup FlowSolution + * + * \brief Read a point set FlowSolution_t node + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] S \SOL_S + * \param[out] pnts Array of points defining the interface in the current solution. + * \return \ier + * + */ int cg_sol_ptset_read(int fn, int B, int Z, int S, cgsize_t *pnts) { int dim = 0; @@ -6636,6 +8077,23 @@ int cg_sol_ptset_read(int fn, int B, int Z, int S, cgsize_t *pnts) return CG_OK; } +/** + * \ingroup FlowSolution + * + * \brief Create a point set FlowSolution_t node + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] solname Name of the flow solution. + * \param[in] location Grid location where the solution is recorded. The current admissible locations are Vertex, CellCenter, IFaceCenter, JFaceCenter, and KFaceCenter. + * \param[in] ptset_type Type of point set defining the interface in the current solution; either PointRange or PointList. + * \param[in] npnts Number of points defining the interface in the current solution. For a ptset_type of PointRange, npnts is always two. For a ptset_type of PointList, npnts is the number of points in the PointList. + * \param[in] pnts Array of points defining the interface in the current solution. + * \param[out] S \SOL_S + * \return \ier + * + */ int cg_sol_ptset_write(int fn, int B, int Z, const char *solname, CGNS_ENUMT(GridLocation_t) location, CGNS_ENUMT(PointSetType_t) ptset_type, cgsize_t npnts, @@ -6696,12 +8154,24 @@ int cg_sol_ptset_write(int fn, int B, int Z, const char *solname, /*****************************************************************************\ * Read and Write flow field DataArray_t Nodes \*****************************************************************************/ - -int cg_nfields(int file_number, int B, int Z, int S, int *nfields) +/** + * \ingroup FlowSolutionData + * + * \brief Get number of flow solution arrays + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] S \SOL_S + * \param[out] nfields Number of data arrays in flow solution S. + * \return \ier + * + */ +int cg_nfields(int fn, int B, int Z, int S, int *nfields) { cgns_sol *sol; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -6713,12 +8183,27 @@ int cg_nfields(int file_number, int B, int Z, int S, int *nfields) return CG_OK; } -int cg_field_info(int file_number, int B, int Z, int S, int F, - CGNS_ENUMT(DataType_t) *type, char *fieldname) +/** + * \ingroup FlowSolutionData + * + * \brief Get info about a flow solution array + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] S \SOL_S + * \param[in] F Solution array index number, where 1 ≤ F ≤ nfields. + * \param[out] datatype Data type of the solution array written to the file. Admissible data types for a solution array are Integer, LongInteger, RealSingle, and RealDouble. + * \param[out] fieldname Name of the solution array. It is strongly advised to use the SIDS nomenclature conventions when naming the solution arrays to insure file compatibility. + * \return \ier + * + */ +int cg_field_info(int fn, int B, int Z, int S, int F, + CGNS_ENUMT(DataType_t) *datatype, char *fieldname) { cgns_array *field; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -6727,20 +8212,37 @@ int cg_field_info(int file_number, int B, int Z, int S, int F, if (field==0) return CG_ERROR; strcpy(fieldname, field->name); - *type = cgi_datatype(field->data_type); + *datatype = cgi_datatype(field->data_type); return CG_OK; } -int cg_field_read(int file_number, int B, int Z, int S, const char *fieldname, - CGNS_ENUMT(DataType_t) type, const cgsize_t *s_rmin, +/** + * \ingroup FlowSolutionData + * + * \brief Read flow solution + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] S \SOL_S + * \param[in] fieldname Name of the solution array. It is strongly advised to use the SIDS nomenclature conventions when naming the solution arrays to insure file compatibility. + * \param[in] mem_datatype Data type of an array in memory. Admissible data types for a solution array are Integer, LongInteger, RealSingle, and RealDouble. + * \param[in] s_rmin Lower range index in file (eg., imin, jmin, kmin). + * \param[in] s_rmax Upper range index in file (eg., imax, jmax, kmax). + * \param[out] field_ptr Array of solution values. + * \return \ier + * + */ +int cg_field_read(int fn, int B, int Z, int S, const char *fieldname, + CGNS_ENUMT(DataType_t) mem_datatype, const cgsize_t *s_rmin, const cgsize_t *s_rmax, void *field_ptr) { cgns_sol *sol; int n, m_numdim; /* get memory addresses */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; /* get memory address for solution */ @@ -6767,12 +8269,33 @@ int cg_field_read(int file_number, int B, int Z, int S, const char *fieldname, m_dimvals[n] = m_rmax[n]; } - return cg_field_general_read(file_number, B, Z, S, fieldname, - s_rmin, s_rmax, type, + return cg_field_general_read(fn, B, Z, S, fieldname, + s_rmin, s_rmax, mem_datatype, m_numdim, m_dimvals, m_rmin, m_rmax, field_ptr); } +/** + * \ingroup FlowSolutionData + * + * \brief Read subset of flow solution to a shaped array + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] S \SOL_S + * \param[in] fieldname Name of the solution array. It is strongly advised to use the SIDS nomenclature conventions when naming the solution arrays to insure file compatibility. + * \param[in] s_rmin Lower range index in file (eg., imin, jmin, kmin). + * \param[in] s_rmax Upper range index in file (eg., imax, jmax, kmax). + * \param[in] m_type Data type of an array in memory. Admissible data types for a solution array are Integer, LongInteger, RealSingle, and RealDouble. + * \param[in] m_numdim Number of dimensions of array in memory. + * \param[in] m_dimvals Dimensions of array in memory. + * \param[in] m_rmin Lower range index in memory (eg., imin, jmin, kmin). + * \param[in] m_rmax Upper range index in memory (eg., imax, jmax, kmax). + * \param[out] field_ptr Array of solution values. + * \return \ier + * + */ int cg_field_general_read(int fn, int B, int Z, int S, const char *fieldname, const cgsize_t *s_rmin, const cgsize_t *s_rmax, CGNS_ENUMT(DataType_t) m_type, @@ -6826,11 +8349,11 @@ int cg_field_general_read(int fn, int B, int Z, int S, const char *fieldname, field_ptr); } -int cg_field_id(int file_number, int B, int Z, int S, int F, double *field_id) +int cg_field_id(int fn, int B, int Z, int S, int F, double *field_id) { cgns_array *field; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -6842,7 +8365,23 @@ int cg_field_id(int file_number, int B, int Z, int S, int F, double *field_id) return CG_OK; } -int cg_field_write(int file_number, int B, int Z, int S, +/** + * \ingroup FlowSolutionData + * + * \brief Write flow solution + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] S \SOL_S + * \param[in] fieldname Name of the solution array. It is strongly advised to use the SIDS nomenclature conventions when naming the solution arrays to insure file compatibility. + * \param[in] type Data type of the solution array written to the file. Admissible data types for a solution array are Integer, LongInteger, RealSingle, and RealDouble. + * \param[in] field_ptr Array of solution values. + * \param[out] F \SOL_F + * \return \ier + * + */ +int cg_field_write(int fn, int B, int Z, int S, CGNS_ENUMT(DataType_t) type, const char *fieldname, const void *field_ptr, int *F) { @@ -6862,7 +8401,7 @@ int cg_field_write(int file_number, int B, int Z, int S, } /* get memory addresses */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; zone = cgi_get_zone(cg, B, Z); @@ -6900,13 +8439,31 @@ int cg_field_write(int file_number, int B, int Z, int S, m_rmax[n] = m_dimvals[n]; } - return cg_field_general_write(file_number, B, Z, S, fieldname, + return cg_field_general_write(fn, B, Z, S, fieldname, type, s_rmin, s_rmax, type, m_numdim, m_dimvals, m_rmin, m_rmax, field_ptr, F); } -int cg_field_partial_write(int file_number, int B, int Z, int S, +/** + * \ingroup FlowSolutionData + * + * \brief Write subset of flow solution + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] S \SOL_S + * \param[in] fieldname Name of the solution array. It is strongly advised to use the SIDS nomenclature conventions when naming the solution arrays to insure file compatibility. + * \param[in] type Data type of the solution array written to the file. Admissible data types for a solution array are Integer, LongInteger, RealSingle, and RealDouble. + * \param[in] s_rmin Lower range index in file (eg., imin, jmin, kmin). + * \param[in] s_rmax Upper range index in file (eg., imax, jmax, kmax). + * \param[in] field_ptr Array of solution values. + * \param[out] F \SOL_F + * \return \ier + * + */ +int cg_field_partial_write(int fn, int B, int Z, int S, CGNS_ENUMT( DataType_t ) type, const char *fieldname, const cgsize_t *s_rmin, const cgsize_t *s_rmax, const void *field_ptr, int *F) @@ -6917,7 +8474,7 @@ int cg_field_partial_write(int file_number, int B, int Z, int S, int status; /* get memory addresses */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; zone = cgi_get_zone(cg, B, Z); @@ -6948,7 +8505,7 @@ int cg_field_partial_write(int file_number, int B, int Z, int S, m_dimvals[n] = m_rmax[n]; } - status = cg_field_general_write(file_number, B, Z, S, fieldname, + status = cg_field_general_write(fn, B, Z, S, fieldname, type, s_rmin, s_rmax, type, m_numdim, m_dimvals, m_rmin, m_rmax, field_ptr, F); @@ -6958,6 +8515,30 @@ int cg_field_partial_write(int file_number, int B, int Z, int S, } +/** + * \ingroup FlowSolutionData + * + * \brief Write shaped array to a subset of flow solution + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] S \SOL_S + * \param[in] fieldname Name of the solution array. It is strongly advised to use the SIDS nomenclature conventions when naming the solution arrays to insure file compatibility. + * \param[in] s_type Data type of the solution array written to the file. Admissible data types for a solution array are Integer, LongInteger, RealSingle, and RealDouble. + * \param[in] s_rmin Lower range index in file (eg., imin, jmin, kmin). + * \param[in] s_rmax Upper range index in file (eg., imax, jmax, kmax). + * + * \param[in] m_type Data type of an array in memory. Admissible data types for a solution array are Integer, LongInteger, RealSingle, and RealDouble. + * \param[in] m_numdim Number of dimensions of array in memory. + * \param[in] m_dimvals Dimensions of array in memory. + * \param[in] m_rmin Lower range index in memory (eg., imin, jmin, kmin). + * \param[in] m_rmax Upper range index in memory (eg., imax, jmax, kmax). + * \param[in] field_ptr Array of solution values. + * \param[out] F \SOL_F + * \return \ier + * + */ int cg_field_general_write(int fn, int B, int Z, int S, const char *fieldname, CGNS_ENUMT(DataType_t) s_type, const cgsize_t *s_rmin, const cgsize_t *s_rmax, @@ -7030,7 +8611,19 @@ int cg_field_general_write(int fn, int B, int Z, int S, const char *fieldname, * Read and write ZoneSubRegion_t Nodes * \*************************************************************************/ -int cg_nsubregs(int fn, int B, int Z, int *nsubreg) +/** + * \ingroup ZoneSubregions + * + * \brief Get number of ZoneSubRegion_t nodes + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[out] nsubregs Number of ZoneSubRegion_t nodes under Zone Z. + * \return \ier + * + */ +int cg_nsubregs(int fn, int B, int Z, int *nsubregs) { cgns_zone *zone; @@ -7042,7 +8635,7 @@ int cg_nsubregs(int fn, int B, int Z, int *nsubreg) zone = cgi_get_zone(cg, B, Z); if (zone==0) return CG_ERROR; - (*nsubreg) = zone->nsubreg; + (*nsubregs) = zone->nsubreg; return CG_OK; } @@ -7056,7 +8649,26 @@ static cgns_subreg *cg_subreg_read(int fn, int B, int Z, int S) return cgi_get_subreg(cg, B, Z, S); } -int cg_subreg_info(int fn, int B, int Z, int S, char *name, int *dimension, +/** + * \ingroup ZoneSubregions + * + * \brief Get info about a ZoneSubRegion_t node + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] S ZoneSubRegion index number, where 1 ≤ S ≤ nsubregs. + * \param[out] regname Name of the ZoneSubRegion_t node. + * \param[out] dimension Dimensionality of the subregion, 1 for lines, 2 for faces, 3 for volumes. + * \param[out] location Grid location used in the definition of the point set. The currently admissible locations are Vertex and CellCenter. + * \param[out] ptset_type Type of point set defining the interface for the subregion data; either PointRange or PointList. + * \param[out] npnts Number of points defining the interface for the subregion data. For a ptset_type of PointRange, npnts is always two. For a ptset_type of PointList, npnts is the number of points in the PointList. + * \param[out] bcname_len String length of bcname. + * \param[out] gcname_len String length of gcname. + * \return \ier + * + */ +int cg_subreg_info(int fn, int B, int Z, int S, char *regname, int *dimension, CGNS_ENUMT(GridLocation_t) *location, CGNS_ENUMT(PointSetType_t) *ptset_type, cgsize_t *npnts, int *bcname_len, int *gcname_len) @@ -7065,7 +8677,7 @@ int cg_subreg_info(int fn, int B, int Z, int S, char *name, int *dimension, if (subreg == NULL) return CG_ERROR; - strcpy(name,subreg->name); + strcpy(regname,subreg->name); *dimension = subreg->reg_dim; *location = subreg->location; if (subreg->ptset) { @@ -7088,6 +8700,19 @@ int cg_subreg_info(int fn, int B, int Z, int S, char *name, int *dimension, return CG_OK; } +/** + * \ingroup ZoneSubregions + * + * \brief Read point set data for a ZoneSubRegion_t node + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] S ZoneSubRegion index number, where 1 ≤ S ≤ nsubregs. + * \param[out] pnts Array of points defining the interface for the subregion data. + * \return \ier + * + */ int cg_subreg_ptset_read(int fn, int B, int Z, int S, cgsize_t *pnts) { int dim = 0; @@ -7105,6 +8730,19 @@ int cg_subreg_ptset_read(int fn, int B, int Z, int S, cgsize_t *pnts) return CG_OK; } +/** + * \ingroup ZoneSubregions + * + * \brief Read the BC_t node name for a ZoneSubRegion_t node + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] S ZoneSubRegion index number, where 1 ≤ S ≤ nsubregs. + * \param[out] bcname The name of a BC_t node which defines the subregion. + * \return \ier + * + */ int cg_subreg_bcname_read(int fn, int B, int Z, int S, char *bcname) { cgns_subreg *subreg = cg_subreg_read(fn, B, Z, S); @@ -7119,6 +8757,19 @@ int cg_subreg_bcname_read(int fn, int B, int Z, int S, char *bcname) return CG_OK; } +/** + * \ingroup ZoneSubregions + * + * \brief Read the GridConnectivity_t node name for a ZoneSubRegion_t node + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] S ZoneSubRegion index number, where 1 ≤ S ≤ nsubregs. + * \param[out] gcname The name of a GridConnectivity_t or GridConnectivity1to1_t node which defines the subregion. + * \return \ier + * + */ int cg_subreg_gcname_read(int fn, int B, int Z, int S, char *gcname) { cgns_subreg *subreg = cg_subreg_read(fn, B, Z, S); @@ -7198,7 +8849,25 @@ static cgns_subreg *cg_subreg_write(int fn, int B, int Z, const char *name, return subreg; } -int cg_subreg_ptset_write(int fn, int B, int Z, const char *name, +/** + * \ingroup ZoneSubregions + * + * \brief Create a point set ZoneSubRegion_t node + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] regname Name of the ZoneSubRegion_t node. + * \param[in] dimension Dimensionality of the subregion, 1 for lines, 2 for faces, 3 for volumes. + * \param[in] location Grid location used in the definition of the point set. The currently admissible locations are Vertex and CellCenter. + * \param[in] ptset_type Type of point set defining the interface for the subregion data; either PointRange or PointList. + * \param[in] npnts Number of points defining the interface for the subregion data. For a ptset_type of PointRange, npnts is always two. For a ptset_type of PointList, npnts is the number of points in the PointList. + * \param[in] pnts Array of points defining the interface for the subregion data. + * \param[out] S ZoneSubRegion index number, where 1 ≤ S ≤ nsubregs. + * \return \ier + * + */ +int cg_subreg_ptset_write(int fn, int B, int Z, const char *regname, int dimension, CGNS_ENUMT(GridLocation_t) location, CGNS_ENUMT(PointSetType_t) ptset_type, cgsize_t npnts, const cgsize_t *pnts, int *S) @@ -7221,7 +8890,7 @@ int cg_subreg_ptset_write(int fn, int B, int Z, const char *name, if (cgi_check_location(dimension+1, cg->base[B-1].zone[Z-1].type, location)) return CG_ERROR; - subreg = cg_subreg_write(fn, B, Z, name, dimension, S); + subreg = cg_subreg_write(fn, B, Z, regname, dimension, S); if (subreg == NULL) return CG_ERROR; subreg->location = location; @@ -7261,7 +8930,22 @@ int cg_subreg_ptset_write(int fn, int B, int Z, const char *name, return CG_OK; } -int cg_subreg_bcname_write(int fn, int B, int Z, const char *name, int dimension, +/** + * \ingroup ZoneSubregions + * + * \brief Create a ZoneSubRegion_t node that references a BC_t node + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] regname Name of the ZoneSubRegion_t node. + * \param[in] dimension Dimensionality of the subregion, 1 for lines, 2 for faces, 3 for volumes. + * \param[in] bcname The name of a BC_t node which defines the subregion. + * \param[out] S ZoneSubRegion index number, where 1 ≤ S ≤ nsubregs. + * \return \ier + * + */ +int cg_subreg_bcname_write(int fn, int B, int Z, const char *regname, int dimension, const char *bcname, int *S) { cgsize_t dim_vals = 1; @@ -7273,7 +8957,7 @@ int cg_subreg_bcname_write(int fn, int B, int Z, const char *name, int dimension return CG_ERROR; } - subreg = cg_subreg_write(fn, B, Z, name, dimension, S); + subreg = cg_subreg_write(fn, B, Z, regname, dimension, S); if (subreg == NULL) return CG_ERROR; subreg->bcname = CGNS_NEW(cgns_descr, 1); @@ -7296,7 +8980,22 @@ int cg_subreg_bcname_write(int fn, int B, int Z, const char *name, int dimension return CG_OK; } -int cg_subreg_gcname_write(int fn, int B, int Z, const char *name, int dimension, +/** + * \ingroup ZoneSubregions + * + * \brief Create a ZoneSubRegion_t node that references a GridConnectivity_t node + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] regname Name of the ZoneSubRegion_t node. + * \param[in] dimension Dimensionality of the subregion, 1 for lines, 2 for faces, 3 for volumes. + * \param[in] gcname The name of a GridConnectivity_t or GridConnectivity1to1_t node which defines the subregion. + * \param[out] S ZoneSubRegion index number, where 1 ≤ S ≤ nsubregs. + * \return \ier + * + */ +int cg_subreg_gcname_write(int fn, int B, int Z, const char *regname, int dimension, const char *gcname, int *S) { cgsize_t dim_vals = 1; @@ -7308,7 +9007,7 @@ int cg_subreg_gcname_write(int fn, int B, int Z, const char *name, int dimension return CG_ERROR; } - subreg = cg_subreg_write(fn, B, Z, name, dimension, S); + subreg = cg_subreg_write(fn, B, Z, regname, dimension, S); if (subreg == NULL) return CG_ERROR; subreg->gcname = CGNS_NEW(cgns_descr, 1); @@ -7335,6 +9034,18 @@ int cg_subreg_gcname_write(int fn, int B, int Z, const char *name, int dimension * Read and write ZoneGridConnectivity_t Nodes * \*************************************************************************/ +/** + * \ingroup ZoneGridConnectivity + * + * \brief Get number of ZoneGridConnectivity_t nodes + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[out] nzconns Number of ZoneGridConnectivity_t nodes under Zone Z. + * \return \ier + * + */ int cg_nzconns(int fn, int B, int Z, int *nzconns) { cgns_zone *zone; @@ -7352,7 +9063,20 @@ int cg_nzconns(int fn, int B, int Z, int *nzconns) return CG_OK; } -int cg_zconn_read(int fn, int B, int Z, int C, char *name) +/** + * \ingroup ZoneGridConnectivity + * + * \brief Read ZoneGridConnectivity_t node + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] ZC Zone grid connectivity index number, where 1 ≤ ZC ≤ nzconns. + * \param[out] zcname Name of the ZoneGridConnectivity_t node + * \return \ier + * + */ +int cg_zconn_read(int fn, int B, int Z, int ZC, char *zcname) { cgns_zconn *zconn; @@ -7363,22 +9087,35 @@ int cg_zconn_read(int fn, int B, int Z, int C, char *name) /* Get memory address for ZoneGridConnectivity_t node */ /* cgi_get_zconnZC() also sets active ZoneGridConnectivity_t node */ - zconn = cgi_get_zconnZC(cg, B, Z, C); + zconn = cgi_get_zconnZC(cg, B, Z, ZC); if (zconn==0) return CG_ERROR; /* Return name for the ZoneGridConnectivity_t node */ - strcpy(name,zconn->name); + strcpy(zcname,zconn->name); return CG_OK; } -int cg_zconn_write(int fn, int B, int Z, const char *name, int *C) +/** + * \ingroup ZoneGridConnectivity + * + * \brief Create ZoneGridConnectivity_t node + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] zcname Name of the ZoneGridConnectivity_t node + * \param[out] ZC Zone grid connectivity index number, where 1 ≤ ZC ≤ nzconns. + * \return \ier + * + */ +int cg_zconn_write(int fn, int B, int Z, const char *zcname, int *ZC) { cgns_zone *zone; cgns_zconn *zconn = NULL; int index; /* verify input */ - if (cgi_check_strlen(name)) return CG_ERROR; + if (cgi_check_strlen(zcname)) return CG_ERROR; /* get memory address */ cg = cgi_get_file(fn); @@ -7391,11 +9128,11 @@ int cg_zconn_write(int fn, int B, int Z, const char *name, int *C) /* Overwrite a ZoneGridConnectivity_t Node: */ for (index = 0; index < zone->nzconn; index++) { - if (0 == strcmp(name, zone->zconn[index].name)) { + if (0 == strcmp(zcname, zone->zconn[index].name)) { /* in CG_MODE_WRITE, children names must be unique */ if (cg->mode == CG_MODE_WRITE) { - cgi_error("Duplicate child name found: %s",name); + cgi_error("Duplicate child name found: %s",zcname); return CG_ERROR; } @@ -7421,11 +9158,11 @@ int cg_zconn_write(int fn, int B, int Z, const char *name, int *C) zconn = &(zone->zconn[zone->nzconn]); zone->nzconn++; } - (*C) = index+1; - zone->active_zconn = *C; + (*ZC) = index+1; + zone->active_zconn = *ZC; memset(zconn, 0, sizeof(cgns_zconn)); - strcpy(zconn->name,name); + strcpy(zconn->name,zcname); /* save data in file */ if (cgi_new_node(zone->id, zconn->name, "ZoneGridConnectivity_t", @@ -7434,7 +9171,19 @@ int cg_zconn_write(int fn, int B, int Z, const char *name, int *C) return CG_OK; } -int cg_zconn_get(int fn, int B, int Z, int *C) +/** + * \ingroup ZoneGridConnectivity + * + * \brief Get the current ZoneGridConnectivity_t node + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[out] ZC Zone grid connectivity index number, where 1 ≤ ZC ≤ nzconns. + * \return \ier + * + */ +int cg_zconn_get(int fn, int B, int Z, int *ZC) { cgns_zone *zone; @@ -7446,18 +9195,30 @@ int cg_zconn_get(int fn, int B, int Z, int *C) if (zone==0) return CG_ERROR; if (zone->nzconn <= 0) { - *C = 0; + *ZC = 0; cgi_error("no ZoneGridConnectivity_t node found."); return CG_NODE_NOT_FOUND; } if (zone->active_zconn <= 0 || zone->active_zconn > zone->nzconn) zone->active_zconn = 1; - *C = zone->active_zconn; + *ZC = zone->active_zconn; return CG_OK; } -int cg_zconn_set(int fn, int B, int Z, int C) +/** + * \ingroup ZoneGridConnectivity + * + * \brief Set the current ZoneGridConnectivity_t node + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] ZC Zone grid connectivity index number, where 1 ≤ ZC ≤ nzconns. + * \return \ier + * + */ +int cg_zconn_set(int fn, int B, int Z, int ZC) { cgns_zconn *zconn; @@ -7466,7 +9227,7 @@ int cg_zconn_set(int fn, int B, int Z, int C) /* Get memory address for ZoneGridConnectivity_t node */ /* cgi_get_zconnZC() also sets active ZoneGridConnectivity_t node */ - zconn = cgi_get_zconnZC(cg, B, Z, C); + zconn = cgi_get_zconnZC(cg, B, Z, ZC); if (zconn==0) return CG_ERROR; return CG_OK; } @@ -7475,11 +9236,23 @@ int cg_zconn_set(int fn, int B, int Z, int C) * Read and Write OversetHoles_t Nodes \*****************************************************************************/ -int cg_nholes(int file_number, int B, int Z, int *nholes) +/** + * \ingroup OversetHoles + * + * \brief Get number of overset holes in a zone + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[out] nholes Number of overset holes in zone Z. + * \return \ier + * + */ +int cg_nholes(int fn, int B, int Z, int *nholes) { cgns_zconn *zconn; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -7490,14 +9263,31 @@ int cg_nholes(int file_number, int B, int Z, int *nholes) return CG_OK; } -int cg_hole_info(int file_number, int B, int Z, int J, char *holename, +/** + * \ingroup OversetHoles + * + * \brief Get info about an overset hole + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] J Overset hole index number, where 1 ≤ J ≤ nholes. + * \param[out] holename Name of the overset hole. + * \param[out] location Grid location used in the definition of the point set. The currently admissible locations are Vertex and CellCenter. + * \param[out] ptset_type The extent of the overset hole may be defined using a range of points or cells, or using a discrete list of all points or cells in the overset hole. If a range of points or cells is used, ptset_type is set to PointRange. When a discrete list of points or cells is used, ptset_type equals PointList. + * \param[out] nptsets Number of point sets used to define the hole. If ptset_type is PointRange, several point sets may be used. If ptset_type is PointList, only one point set is allowed. + * \param[out] npnts Number of points (or cells) in the point set. For a ptset_type of PointRange, npnts is always two. For a ptset_type of PointList, npnts is the number of points or cells in the PointList. + * \return \ier + * + */ +int cg_hole_info(int fn, int B, int Z, int J, char *holename, CGNS_ENUMT(GridLocation_t) *location, CGNS_ENUMT(PointSetType_t) *ptset_type, int *nptsets, cgsize_t *npnts) { cgns_hole *hole; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -7515,12 +9305,25 @@ int cg_hole_info(int file_number, int B, int Z, int J, char *holename, return CG_OK; } -int cg_hole_read(int file_number, int B, int Z, int J, cgsize_t *pnts) +/** + * \ingroup OversetHoles + * + * \brief Read overset hole data + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] J Overset hole index number, where 1 ≤ J ≤ nholes. + * \param[out] pnts Array of points or cells in the point set. + * \return \ier + * + */ +int cg_hole_read(int fn, int B, int Z, int J, cgsize_t *pnts) { cgns_hole *hole; int set, index_dim; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -7561,11 +9364,11 @@ int cg_hole_read(int file_number, int B, int Z, int J, cgsize_t *pnts) return CG_OK; } -int cg_hole_id(int file_number, int B, int Z, int J, double *hole_id) +int cg_hole_id(int fn, int B, int Z, int J, double *hole_id) { cgns_hole *hole; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -7577,7 +9380,25 @@ int cg_hole_id(int file_number, int B, int Z, int J, double *hole_id) return CG_OK; } -int cg_hole_write(int file_number, int B, int Z, const char * holename, +/** + * \ingroup OversetHoles + * + * \brief Write overset hole data + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] holename Name of the overset hole. + * \param[in] location Grid location used in the definition of the point set. The currently admissible locations are Vertex and CellCenter. + * \param[in] ptset_type The extent of the overset hole may be defined using a range of points or cells, or using a discrete list of all points or cells in the overset hole. If a range of points or cells is used, ptset_type is set to PointRange. When a discrete list of points or cells is used, ptset_type equals PointList. + * \param[in] nptsets Number of point sets used to define the hole. If ptset_type is PointRange, several point sets may be used. If ptset_type is PointList, only one point set is allowed. + * \param[in] npnts Number of points (or cells) in the point set. For a ptset_type of PointRange, npnts is always two. For a ptset_type of PointList, npnts is the number of points or cells in the PointList. + * \param[in] pnts Array of points or cells in the point set. + * \param[out] J Overset hole index number, where 1 ≤ J ≤ nholes. + * \return \ier + * + */ +int cg_hole_write(int fn, int B, int Z, const char * holename, CGNS_ENUMT(GridLocation_t) location, CGNS_ENUMT(PointSetType_t) ptset_type, int nptsets, cgsize_t npnts, const cgsize_t * pnts, int *J) @@ -7611,7 +9432,7 @@ int cg_hole_write(int file_number, int B, int Z, const char * holename, return CG_ERROR; } /* get memory address for file */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_WRITE)) return CG_ERROR; @@ -7740,11 +9561,23 @@ int cg_hole_write(int file_number, int B, int Z, const char * holename, * Read and Write GridConnectivity_t Nodes \*****************************************************************************/ -int cg_nconns(int file_number, int B, int Z, int *nconns) +/** + * \ingroup GeneralizedConnectivity + * + * \brief Get number of generalized connectivity interfaces in a zone + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[out] nconns Number of interfaces for zone Z. + * \return \ier + * + */ +int cg_nconns(int fn, int B, int Z, int *nconns) { cgns_zconn *zconn; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -7755,21 +9588,46 @@ int cg_nconns(int file_number, int B, int Z, int *nconns) return CG_OK; } -/* in cg_conn_info, donor_datatype is useless starting with version 1.27, because - it's always I4. However this arg. is left for backward compatibility of API - and to be able to read old files */ -int cg_conn_info(int file_number, int B, int Z, int J, char *connectname, +/** + * \ingroup GeneralizedConnectivity + * + * \brief Get info about a generalized connectivity interface + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] J Interface index number, where 1 ≤ J ≤ nconns. + * \param[out] connectname Name of the interface. + * \param[out] location Grid location used in the definition of the point set. The currently admissible locations are Vertex and CellCenter. + * \param[out] connect_type Type of interface being defined. The admissible types are Overset, Abutting, and Abutting1to1. + * \param[out] ptset_type Type of point set defining the interface in the current zone; either PointRange or PointList. + * \param[out] npnts Number of points defining the interface in the current zone. For a ptset_type of PointRange, npnts is always two. For a ptset_type of PointList, npnts is the number of points in the PointList. + * \param[out] donorname Name of the zone interfacing with the current zone. + * \param[out] donor_zonetype Type of the donor zone. The admissible types are Structured and Unstructured. + * \param[out] donor_ptset_type Type of point set defining the interface in the donor zone; either PointListDonor or CellListDonor. + * \param[out] donor_datatype Data type in which the donor points are stored in the file. As of Version 3.0, this value is ignored when writing, and on reading it will return either Integer or LongInteger depending on whether the file was written using 32 or 64-bit. The donor_datatype argument was left in these functions only for backward compatibility. The donor data is always read as cgsize_t. + * \param[out] ndata_donor Number of points or cells in the current zone. These are paired with points, cells, or fractions thereof in the donor zone. + * \return \ier + * + * \details In cg_conn_info, donor_datatype is useless starting with version 1.27, because + * it's always I4. However this arg. is left for backward compatibility of API + * and to be able to read old files + * + */ +int cg_conn_info(int fn, int B, int Z, int J, char *connectname, CGNS_ENUMT(GridLocation_t) *location, - CGNS_ENUMT(GridConnectivityType_t) *type, + CGNS_ENUMT(GridConnectivityType_t) *connect_type, CGNS_ENUMT(PointSetType_t) *ptset_type, cgsize_t *npnts, char *donorname, CGNS_ENUMT(ZoneType_t) *donor_zonetype, CGNS_ENUMT(PointSetType_t) *donor_ptset_type, CGNS_ENUMT(DataType_t) *donor_datatype, cgsize_t *ndata_donor) { - int dZ; + int dZ, dB; cgns_conn *conn; + char_33 basedonorname, zonedonorname; + char *separator; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -7778,7 +9636,7 @@ int cg_conn_info(int file_number, int B, int Z, int J, char *connectname, if (conn==0) return CG_ERROR; strcpy(connectname, conn->name); - *type = conn->type; + *connect_type = conn->type; *location = conn->location; *ptset_type = conn->ptset.type; *npnts = conn->ptset.npts; @@ -7789,12 +9647,34 @@ int cg_conn_info(int file_number, int B, int Z, int J, char *connectname, *ndata_donor = conn->dptset.npts; *donor_ptset_type = conn->dptset.type; + /* Split donorname into BaseName + zoneName */ + separator = strchr(donorname, '/'); + if (separator != NULL) { + /* get ending zoneName */ + strcpy(zonedonorname, separator + sizeof(char)); + /* get base but do not use path syntax */ + memcpy(basedonorname, donorname, (separator - donorname)*sizeof(char)); + basedonorname[separator - donorname] = '\0'; + /* Find donor base index */ + for (dB=0;dBnbases; dB++) { + if (strcmp(cg->base[dB].name,basedonorname)==0) { + break; + } + } + } + else { + /* zoneName is in current base */ + strcpy(basedonorname, cg->base[B-1].name); + strcpy(zonedonorname, donorname); + dB = B-1; + } + /* Find ZoneType_t of DonorZone given its name */ *donor_zonetype = CGNS_ENUMV( ZoneTypeNull ); - for (dZ=0; dZbase[B-1].nzones; dZ++) { - if (strcmp(cg->base[B-1].zone[dZ].name,donorname)==0) { - *donor_zonetype = cg->base[B-1].zone[dZ].type; + for (dZ=0; dZbase[dB].nzones; dZ++) { + if (strcmp(cg->base[dB].zone[dZ].name,zonedonorname)==0) { + *donor_zonetype = cg->base[dB].zone[dZ].type; break; } } @@ -7805,10 +9685,25 @@ int cg_conn_info(int file_number, int B, int Z, int J, char *connectname, return CG_OK; } -/* in cg_conn_read, donor_datatype is useless starting with version 1.27, because - it's always I4. However this arg. is left for backward compatibility of API - and to be able to read old files */ -int cg_conn_read(int file_number, int B, int Z, int J, cgsize_t *pnts, +/** + * \ingroup GeneralizedConnectivity + * + * \brief Read generalized connectivity data + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] J Interface index number, where 1 ≤ J ≤ nconns. + * \param[out] pnts Array of points defining the interface in the current zone. + * \param[out] donor_datatype Data type in which the donor points are stored in the file. As of Version 3.0, this value is ignored when writing, and on reading it will return either Integer or LongInteger depending on whether the file was written using 32 or 64-bit. The donor_datatype argument was left in these functions only for backward compatibility. The donor data is always read as cgsize_t. + * \param[out] donor_data Array of donor points or cells corresponding to ndata_donor. Note that it is possible that the same donor point or cell may be used multiple times. + * \return \ier + * + * \details in cg_conn_read, donor_datatype is useless starting with version 1.27, because + * it's always I4. However this arg. is left for backward compatibility of API + * and to be able to read old files + */ +int cg_conn_read(int fn, int B, int Z, int J, cgsize_t *pnts, CGNS_ENUMT(DataType_t) donor_datatype, cgsize_t *donor_data) { cgns_conn *conn; @@ -7824,7 +9719,7 @@ int cg_conn_read(int file_number, int B, int Z, int J, cgsize_t *pnts, #endif /* Find address */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -7872,16 +9767,29 @@ int cg_conn_read(int file_number, int B, int Z, int J, cgsize_t *pnts, return CG_OK; } -int cg_conn_read_short(int file_number, int B, int Z, int J, cgsize_t *pnts) +/** + * \ingroup GeneralizedConnectivity + * + * \brief Read generalized connectivity data without donor information + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] J Interface index number, where 1 ≤ J ≤ nconns. + * \param[out] pnts Array of points defining the interface in the current zone. + * \return \ier + * + */ +int cg_conn_read_short(int fn, int B, int Z, int J, cgsize_t *pnts) { - return cg_conn_read(file_number, B, Z, J, pnts, CGNS_ENUMV(DataTypeNull), NULL); + return cg_conn_read(fn, B, Z, J, pnts, CGNS_ENUMV(DataTypeNull), NULL); } -int cg_conn_id(int file_number, int B, int Z, int J, double *conn_id) +int cg_conn_id(int fn, int B, int Z, int J, double *conn_id) { cgns_conn *conn; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -7893,9 +9801,33 @@ int cg_conn_id(int file_number, int B, int Z, int J, double *conn_id) return CG_OK; } -int cg_conn_write(int file_number, int B, int Z, const char * connectname, +/** + * \ingroup GeneralizedConnectivity + * + * \brief Write generalized connectivity data + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] connectname Name of the interface. + * \param[in] location Grid location used in the definition of the point set. The currently admissible locations are Vertex and CellCenter. + * \param[in] connect_type Type of interface being defined. The admissible types are Overset, Abutting, and Abutting1to1. + * \param[in] ptset_type Type of point set defining the interface in the current zone; either PointRange or PointList. + * \param[in] npnts Number of points defining the interface in the current zone. For a ptset_type of PointRange, npnts is always two. For a ptset_type of PointList, npnts is the number of points in the PointList. + * \param[in] pnts Array of points defining the interface in the current zone. + * \param[in] donorname Name of the zone interfacing with the current zone. + * \param[in] donor_zonetype Type of the donor zone. The admissible types are Structured and Unstructured. + * \param[in] donor_ptset_type Type of point set defining the interface in the donor zone; either PointListDonor or CellListDonor. + * \param[in] donor_datatype Data type in which the donor points are stored in the file. As of Version 3.0, this value is ignored when writing, and on reading it will return either Integer or LongInteger depending on whether the file was written using 32 or 64-bit. The donor_datatype argument was left in these functions only for backward compatibility. The donor data is always read as cgsize_t. + * \param[in] ndata_donor Number of points or cells in the current zone. These are paired with points, cells, or fractions thereof in the donor zone. + * \param[in] donor_data Array of donor points or cells corresponding to ndata_donor. Note that it is possible that the same donor point or cell may be used multiple times. + * \param[out] J Interface index number, where 1 ≤ J ≤ nconns. + * \return \ier + * + */ +int cg_conn_write(int fn, int B, int Z, const char * connectname, CGNS_ENUMT(GridLocation_t) location, - CGNS_ENUMT(GridConnectivityType_t) type, + CGNS_ENUMT(GridConnectivityType_t) connect_type, CGNS_ENUMT(PointSetType_t) ptset_type, cgsize_t npnts, const cgsize_t * pnts, const char * donorname, CGNS_ENUMT(ZoneType_t) donor_zonetype, @@ -7917,8 +9849,8 @@ int cg_conn_write(int file_number, int B, int Z, const char * connectname, /* verify input */ if (cgi_check_strlen(connectname)) return CG_ERROR; if (cgi_check_strlen(donorname)) return CG_ERROR; - if (INVALID_ENUM(type,NofValidGridConnectivityTypes)) { - cgi_error("Invalid input: GridConnectivityType=%d ?",type); + if (INVALID_ENUM(connect_type,NofValidGridConnectivityTypes)) { + cgi_error("Invalid input: GridConnectivityType=%d ?",connect_type); return CG_ERROR; } if (location != CGNS_ENUMV(Vertex) && @@ -7930,7 +9862,7 @@ int cg_conn_write(int file_number, int B, int Z, const char * connectname, cgi_error("Invalid input: GridLocation=%d ?",location); return CG_ERROR; } - if (type == CGNS_ENUMV(Overset) && + if (connect_type == CGNS_ENUMV(Overset) && location != CGNS_ENUMV(Vertex) && location != CGNS_ENUMV(CellCenter)) { cgi_error("GridLocation must be Vertex or CellCenter for Overset"); @@ -7986,7 +9918,7 @@ int cg_conn_write(int file_number, int B, int Z, const char * connectname, } /* get memory address of file */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_WRITE)) return CG_ERROR; @@ -8060,7 +9992,7 @@ int cg_conn_write(int file_number, int B, int Z, const char * connectname, } } else PointListSize=npnts; - if (ndata_donor && type == CGNS_ENUMV(Abutting1to1) && PointListSize != ndata_donor) { + if (ndata_donor && connect_type == CGNS_ENUMV(Abutting1to1) && PointListSize != ndata_donor) { cgi_error("Invalid input for ndata_donor in cg_conn_write"); return CG_ERROR; } @@ -8100,7 +10032,7 @@ int cg_conn_write(int file_number, int B, int Z, const char * connectname, /* write conn info to internal memory */ memset(conn, 0, sizeof(cgns_conn)); strcpy(conn->name,connectname); - conn->type = type; + conn->type = connect_type; conn->location = location; conn->ptset.id = 0; conn->ptset.link = 0; @@ -8180,15 +10112,34 @@ int cg_conn_write(int file_number, int B, int Z, const char * connectname, return CG_OK; } -int cg_conn_write_short(int file_number, int B, int Z, const char * connectname, +/** + * \ingroup GeneralizedConnectivity + * + * \brief Write generalized connectivity data without donor information + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] connectname Name of the interface. + * \param[in] location Grid location used in the definition of the point set. The currently admissible locations are Vertex and CellCenter. + * \param[in] connect_type Type of interface being defined. The admissible types are Overset, Abutting, and Abutting1to1. + * \param[in] ptset_type Type of point set defining the interface in the current zone; either PointRange or PointList. + * \param[in] npnts Number of points defining the interface in the current zone. For a ptset_type of PointRange, npnts is always two. For a ptset_type of PointList, npnts is the number of points in the PointList. + * \param[in] pnts Array of points defining the interface in the current zone. + * \param[in] donorname Name of the zone interfacing with the current zone. + * \param[out] J Interface index number, where 1 ≤ J ≤ nconns. + * \return \ier + * + */ +int cg_conn_write_short(int fn, int B, int Z, const char * connectname, CGNS_ENUMT(GridLocation_t) location, - CGNS_ENUMT(GridConnectivityType_t) type, + CGNS_ENUMT(GridConnectivityType_t) connect_type, CGNS_ENUMT(PointSetType_t) ptset_type, cgsize_t npnts, const cgsize_t * pnts, const char * donorname, int *J) { - return cg_conn_write (file_number, B, Z, connectname, location, - type, ptset_type, npnts, pnts, donorname, + return cg_conn_write (fn, B, Z, connectname, location, + connect_type, ptset_type, npnts, pnts, donorname, CGNS_ENUMV(ZoneTypeNull), CGNS_ENUMV(PointSetTypeNull), CGNS_ENUMV(DataTypeNull), 0, NULL, J); } @@ -8197,11 +10148,23 @@ int cg_conn_write_short(int file_number, int B, int Z, const char * connectname * Read and write GridConnectivity1to1_t Nodes \*****************************************************************************/ -int cg_n1to1(int file_number, int B, int Z, int *n1to1) +/** + * \ingroup OneToOneConnectivity + * + * \brief Get number of 1-to-1 interfaces in a zone + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[out] n1to1 Number of one-to-one interfaces in zone Z, stored under GridConnectivity1to1_t nodes. (I.e., this does not include one-to-one interfaces that may be stored under GridConnectivity_t nodes, used for generalized zone interfaces.) + * \return \ier + * + */ +int cg_n1to1(int fn, int B, int Z, int *n1to1) { cgns_zconn *zconn; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -8212,7 +10175,18 @@ int cg_n1to1(int file_number, int B, int Z, int *n1to1) return CG_OK; } -int cg_n1to1_global(int file_number, int B, int *n1to1_global) +/** + * \ingroup OneToOneConnectivity + * + * \brief Get total number of 1-to-1 interfaces in a database + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] n1to1_global Total number of one-to-one interfaces in base B, stored under GridConnectivity1to1_t nodes. (I.e., this does not include one-to-one interfaces that may be stored under GridConnectivity_t nodes, used for generalized zone interfaces.) Note that the function cg_n1to1 (described below) may be used to get the number of one-to-one interfaces in a specific zone. + * \return \ier + * + */ +int cg_n1to1_global(int fn, int B, int *n1to1_global) { cgns_base *base; cgns_zone *zone; @@ -8227,7 +10201,7 @@ int cg_n1to1_global(int file_number, int B, int *n1to1_global) cgsize6_t *Drange = 0, *Ddonor_range = 0; int index_dim; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -8244,7 +10218,7 @@ int cg_n1to1_global(int file_number, int B, int *n1to1_global) if (zconn==0) continue; /* if ZoneGridConnectivity_t is undefined */ if (zconn->n1to1 ==0) continue; for (J=1; J<=zconn->n1to1; J++) { - if (cg_1to1_read(file_number, B, Z, J, connectname, donorname, + if (cg_1to1_read(fn, B, Z, J, connectname, donorname, range, donor_range, transform)) return CG_ERROR; if (cgi_zone_no(base, donorname, &D)) return CG_ERROR; @@ -8268,7 +10242,24 @@ int cg_n1to1_global(int file_number, int B, int *n1to1_global) return CG_OK; } -int cg_1to1_read(int file_number, int B, int Z, int J, char *connectname, +/** + * \ingroup OneToOneConnectivity + * + * \brief Read 1-to-1 connectivity data for a zone + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] J Interface index number, where 1 ≤ J ≤ n1to1. + * \param[out] connectname Name of the interface. + * \param[out] donorname Name of the zone interfacing with the current zone. + * \param[out] range Range of points for the current zone. + * \param[out] donor_range Range of points for the donor zone. + * \param[out] transform Short hand notation for the transformation matrix defining the relative orientation of the two zones. + * \return \ier + * + */ +int cg_1to1_read(int fn, int B, int Z, int J, char *connectname, char *donorname, cgsize_t *range, cgsize_t *donor_range, int *transform) { @@ -8280,7 +10271,7 @@ int cg_1to1_read(int file_number, int B, int Z, int J, char *connectname, in 3D, range[0], range[1], range[2] = imin, jmin, kmin range[3], range[4], range[5] = imax, jmax, kmax */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -8315,7 +10306,23 @@ int cg_1to1_read(int file_number, int B, int Z, int J, char *connectname, return CG_OK; } -int cg_1to1_read_global(int file_number, int B, char **connectname, char **zonename, +/** + * \ingroup OneToOneConnectivity + * + * \brief Read data for all 1-to-1 interfaces in a database + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[out] connectname Name of the interface. + * \param[out] zonename Name of the first zone, for all one-to-one interfaces in base B. + * \param[out] donorname Name of the second zone, for all one-to-one interfaces in base B. + * \param[out] range Range of points for the first zone, for all one-to-one interfaces in base B. + * \param[out] donor_range Range of points for the current zone, for all one-to-one interfaces in base B. + * \param[out] transform Short hand notation for the transformation matrix defining the relative orientation of the two zones. This transformation is given for all one-to-one interfaces in base B. + * \return \ier + * + */ +int cg_1to1_read_global(int fn, int B, char **connectname, char **zonename, char **donorname, cgsize_t **range, cgsize_t **donor_range, int **transform) { @@ -8331,7 +10338,7 @@ int cg_1to1_read_global(int file_number, int B, char **connectname, char **zonen char_33 *Dzonename = 0; cgsize6_t *Drange = 0, *Ddonor_range = 0; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -8350,7 +10357,7 @@ int cg_1to1_read_global(int file_number, int B, char **connectname, char **zonen if (zconn==0) continue; /* if ZoneGridConnectivity_t is undefined */ if (zconn->n1to1 ==0) continue; for (J=1; J<=zconn->n1to1; J++) { - if (cg_1to1_read(file_number, B, Z, J, connect, donor, rang, + if (cg_1to1_read(fn, B, Z, J, connect, donor, rang, drang, trans)) return CG_ERROR; if (cgi_zone_no(base, donor, &D)) return CG_ERROR; /* count each interface only once */ @@ -8376,11 +10383,11 @@ int cg_1to1_read_global(int file_number, int B, char **connectname, char **zonen return CG_OK; } -int cg_1to1_id(int file_number, int B, int Z, int J, double *one21_id) +int cg_1to1_id(int fn, int B, int Z, int J, double *one21_id) { cgns_1to1 *one21; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -8392,7 +10399,24 @@ int cg_1to1_id(int file_number, int B, int Z, int J, double *one21_id) return CG_OK; } -int cg_1to1_write(int file_number, int B, int Z, const char * connectname, +/** + * \ingroup OneToOneConnectivity + * + * \brief Write 1-to-1 connectivity data for a zone + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] connectname Name of the interface. + * \param[in] donorname Name of the zone interfacing with the current zone. + * \param[in] range Range of points for the current zone. + * \param[in] donor_range Range of points for the donor zone. + * \param[in] transform Short hand notation for the transformation matrix defining the relative orientation of the two zones. + * \param[out] J Interface index number, where 1 ≤ J ≤ n1to1. + * \return \ier + * + */ +int cg_1to1_write(int fn, int B, int Z, const char * connectname, const char * donorname, const cgsize_t * range, const cgsize_t * donor_range, const int * transform, int *J) { @@ -8412,7 +10436,7 @@ int cg_1to1_write(int file_number, int B, int Z, const char * connectname, #endif /* get memory address of file */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_WRITE)) return CG_ERROR; @@ -8554,12 +10578,23 @@ int cg_1to1_write(int file_number, int B, int Z, const char * connectname, /*****************************************************************************\ * Read and write BC_t Nodes \*****************************************************************************/ - -int cg_nbocos(int file_number, int B, int Z, int *nbocos) +/** + * \ingroup BoundaryConditionType + * + * \brief Get number of boundary condition in zone + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[out] nbocos Number of boundary conditions in zone Z. + * \return \ier + * + */ +int cg_nbocos(int fn, int B, int Z, int *nbocos) { cgns_zboco *zboco; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -8570,7 +10605,27 @@ int cg_nbocos(int file_number, int B, int Z, int *nbocos) return CG_OK; } -int cg_boco_info(int file_number, int B, int Z, int BC, char *boconame, +/** + * \ingroup BoundaryConditionType + * + * \brief Get boundary condition info + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] BC Boundary condition index number, where 1 ≤ BC ≤ nbocos. + * \param[out] boconame Name of the boundary condition. + * \param[out] bocotype Type of boundary condition defined. See the eligible types for BCType_t in the Typedefs section. Note that if bocotype is FamilySpecified the boundary condition type is being specified for the family to which the boundary belongs. The boundary condition type for the family may be read and written using cg_fambc_read and cg_fambc_write. + * \param[out] ptset_type The extent of the boundary condition may be defined using a range of points or elements using PointRange, or using a discrete list of all points or elements at which the boundary condition is applied using PointList. When the boundary condition is to be applied anywhere other than points, then GridLocation_t under the BC_t node must be used to indicate this. The value of GridLocation_t may be read or written by cg_boco_gridlocation_read and cg_boco_gridlocation_write. As in previous versions of the library, this may also be done by first using cg_goto to access the BC_t node, then using cg_gridlocation_read or cg_gridlocation_write. + * \param[out] npnts Number of points or elements defining the boundary condition region. For a ptset_type of PointRange, npnts is always two. For a ptset_type of PointList, npnts is the number of points or elements in the list. + * \param[out] NormalIndex Index vector indicating the computational coordinate direction of the boundary condition patch normal. + * \param[out] NormalListSize If the normals are defined in NormalList, NormalListSize is the number of points in the patch times phys_dim, the number of coordinates required to define a vector in the field. If the normals are not defined in NormalList, NormalListSize is 0. + * \param[out] NormalDataType Data type used in the definition of the normals. Admissible data types for the normals are RealSingle and RealDouble. + * \param[out] ndataset Number of boundary condition datasets for the current boundary condition. + * \return \ier + * + */ +int cg_boco_info(int fn, int B, int Z, int BC, char *boconame, CGNS_ENUMT(BCType_t) *bocotype, CGNS_ENUMT(PointSetType_t) *ptset_type, cgsize_t *npnts, int *NormalIndex, cgsize_t *NormalListSize, CGNS_ENUMT(DataType_t) *NormalDataType, int *ndataset) @@ -8578,7 +10633,7 @@ int cg_boco_info(int file_number, int B, int Z, int BC, char *boconame, cgns_boco *boco; int n, index_dim; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -8619,12 +10674,26 @@ int cg_boco_info(int file_number, int B, int Z, int BC, char *boconame, return CG_OK; } -int cg_boco_read(int file_number, int B, int Z, int BC, cgsize_t *pnts, void *NormalList) +/** + * \ingroup BoundaryConditionType + * + * \brief Read boundary condition data and normals + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] BC Boundary condition index number, where 1 ≤ BC ≤ nbocos. + * \param[out] pnts Array of point or element indices defining the boundary condition region. There should be npnts values, each of dimension IndexDimension (i.e., 1 for unstructured grids, and 2 or 3 for structured grids with 2-D or 3-D elements, respectively). + * \param[out] NormalList List of vectors normal to the boundary condition patch pointing into the interior of the zone. + * \return \ier + * + */ +int cg_boco_read(int fn, int B, int Z, int BC, cgsize_t *pnts, void *NormalList) { cgns_boco *boco; int dim = 0; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -8634,7 +10703,7 @@ int cg_boco_read(int file_number, int B, int Z, int BC, cgsize_t *pnts, void *No /* Read point-set directly from ADF-file */ if (boco->ptset && boco->ptset->npts > 0) { - cg_index_dim(file_number, B, Z, &dim); + cg_index_dim(fn, B, Z, &dim); if (cgi_read_int_data(boco->ptset->id, boco->ptset->data_type, boco->ptset->npts * dim, pnts)) return CG_ERROR; } else { @@ -8652,11 +10721,11 @@ int cg_boco_read(int file_number, int B, int Z, int BC, cgsize_t *pnts, void *No return CG_OK; } -int cg_boco_id(int file_number, int B, int Z, int BC, double *boco_id) +int cg_boco_id(int fn, int B, int Z, int BC, double *boco_id) { cgns_boco *boco; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -8668,12 +10737,25 @@ int cg_boco_id(int file_number, int B, int Z, int BC, double *boco_id) return CG_OK; } -int cg_boco_gridlocation_read(int file_number, int B, int Z, +/** + * \ingroup BoundaryConditionType + * + * \brief Read boundary condition location + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] BC Boundary condition index number, where 1 ≤ BC ≤ nbocos. + * \param[out] location Grid location used in the definition of the point set. The currently admissible locations are Vertex (the default if not given), and CellCenter. Interpretation of CellCenter, and additional allowable values of grid location depends on the base cell dimension. For CellDim=1, CellCenter refers to line elements. For CellDim=2, CellCenter refers to area elements, and the additional value EdgeCenter is allowed. For CellDim=3, CellCenter refers to volume elements, and in addition to EdgeCenter, the values of FaceCenter, IFaceCenter, JFaceCenter, and KFaceCenter may be used. + * \return \ier + * + */ +int cg_boco_gridlocation_read(int fn, int B, int Z, int BC, CGNS_ENUMT(GridLocation_t) *location) { cgns_boco *boco; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -8685,7 +10767,24 @@ int cg_boco_gridlocation_read(int file_number, int B, int Z, return CG_OK; } -int cg_boco_write(int file_number, int B, int Z, const char * boconame, +/** + * \ingroup BoundaryConditionType + * + * \brief Write boundary condition type and data + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] boconame Name of the boundary condition. + * \param[in] bocotype Type of boundary condition defined. See the eligible types for BCType_t in the Typedefs section. Note that if bocotype is FamilySpecified the boundary condition type is being specified for the family to which the boundary belongs. The boundary condition type for the family may be read and written using cg_fambc_read and cg_fambc_write. + * \param[in] ptset_type The extent of the boundary condition may be defined using a range of points or elements using PointRange, or using a discrete list of all points or elements at which the boundary condition is applied using PointList. When the boundary condition is to be applied anywhere other than points, then GridLocation_t under the BC_t node must be used to indicate this. The value of GridLocation_t may be read or written by cg_boco_gridlocation_read and cg_boco_gridlocation_write. As in previous versions of the library, this may also be done by first using cg_goto to access the BC_t node, then using cg_gridlocation_read or cg_gridlocation_write. + * \param[in] npnts Number of points or elements defining the boundary condition region. For a ptset_type of PointRange, npnts is always two. For a ptset_type of PointList, npnts is the number of points or elements in the list. + * \param[in] pnts Array of point or element indices defining the boundary condition region. There should be npnts values, each of dimension IndexDimension (i.e., 1 for unstructured grids, and 2 or 3 for structured grids with 2-D or 3-D elements, respectively). + * \param[out] BC Boundary condition index number, where 1 ≤ BC ≤ nbocos. + * \return \ier + * + */ +int cg_boco_write(int fn, int B, int Z, const char * boconame, CGNS_ENUMT(BCType_t) bocotype, CGNS_ENUMT(PointSetType_t) ptset_type, cgsize_t npnts, const cgsize_t * pnts, int *BC) @@ -8699,7 +10798,7 @@ int cg_boco_write(int file_number, int B, int Z, const char * boconame, cgsize_t length; /* get memory address of file */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_WRITE)) @@ -8804,6 +10903,7 @@ int cg_boco_write(int file_number, int B, int Z, const char * boconame, boco->location = location; boco->ptset = CGNS_NEW(cgns_ptset,1); boco->ptset->type = ptype; + strcpy(boco->ptset->name, PointSetTypeName[boco->ptset->type]); strcpy(boco->ptset->data_type,CG_SIZE_DATATYPE); boco->ptset->npts = npnts; @@ -8844,9 +10944,7 @@ int cg_boco_write(int file_number, int B, int Z, const char * boconame, /* Save Point-Set on Disk */ if (npnts > 0) { - char_33 PointSetName; - strcpy(PointSetName, PointSetTypeName[boco->ptset->type]); - if (cgi_write_ptset(boco->id, PointSetName, boco->ptset, index_dim, + if (cgi_write_ptset(boco->id, boco->ptset->name, boco->ptset, index_dim, (void *)pnts)) return CG_ERROR; } if (boco->location != CGNS_ENUMV(Vertex)) { @@ -8860,14 +10958,27 @@ int cg_boco_write(int file_number, int B, int Z, const char * boconame, return CG_OK; } -int cg_boco_gridlocation_write(int file_number, int B, int Z, +/** + * \ingroup BoundaryConditionType + * + * \brief Write boundary condition location + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] BC Boundary condition index number, where 1 ≤ BC ≤ nbocos. + * \param[in] location Grid location used in the definition of the point set. The currently admissible locations are Vertex (the default if not given), and CellCenter. Interpretation of CellCenter, and additional allowable values of grid location depends on the base cell dimension. For CellDim=1, CellCenter refers to line elements. For CellDim=2, CellCenter refers to area elements, and the additional value EdgeCenter is allowed. For CellDim=3, CellCenter refers to volume elements, and in addition to EdgeCenter, the values of FaceCenter, IFaceCenter, JFaceCenter, and KFaceCenter may be used. + * \return \ier + * + */ +int cg_boco_gridlocation_write(int fn, int B, int Z, int BC, CGNS_ENUMT(GridLocation_t) location) { cgns_boco *boco; cgsize_t dim_vals; double dummy_id; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_WRITE)) return CG_ERROR; @@ -8892,7 +11003,23 @@ int cg_boco_gridlocation_write(int file_number, int B, int Z, return CG_OK; } -int cg_boco_normal_write(int file_number, int B, int Z, int BC, const int * NormalIndex, +/** + * \ingroup BoundaryConditionType + * + * \brief Write boundary condition normals + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] BC Boundary condition index number, where 1 ≤ BC ≤ nbocos. + * \param[in] NormalIndex Index vector indicating the computational coordinate direction of the boundary condition patch normal. + * \param[in] NormalListFlag Flag indicating if the normals are defined in NormalList and are to be written out; 1 if they are defined, 0 if they're not. + * \param[in] NormalDataType Data type used in the definition of the normals. Admissible data types for the normals are RealSingle and RealDouble. + * \param[in] NormalList List of vectors normal to the boundary condition patch pointing into the interior of the zone. + * \return \ier + * + */ +int cg_boco_normal_write(int fn, int B, int Z, int BC, const int * NormalIndex, int NormalListFlag, CGNS_ENUMT(DataType_t) NormalDataType, const void * NormalList) { @@ -8901,7 +11028,7 @@ int cg_boco_normal_write(int file_number, int B, int Z, int BC, const int * Norm cgsize_t npnts, index_dim; /* get memory address of file */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_WRITE)) return CG_ERROR; @@ -8975,13 +11102,30 @@ int cg_boco_normal_write(int file_number, int B, int Z, int BC, const int * Norm * Read and write BCDataSet_t Nodes \*****************************************************************************/ -int cg_dataset_read(int file_number, int B, int Z, int BC, int DSet, char *name, +/** + * \ingroup BCDataset + * + * \brief Read boundary condition dataset info + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] BC Boundary condition index number, where 1 ≤ BC ≤ nbocos. + * \param[in] DSet Dataset index number, where 1 ≤ Dset ≤ ndataset. + * \param[out] DatasetName Name of dataset. + * \param[out] BCType Simple boundary condition type for the dataset. The supported types are listed in the table of Simple Boundary Condition Types in the SIDS manual, but note that FamilySpecified does not apply here. + * \param[out] DirichletFlag Flag indicating if the dataset contains Dirichlet data. + * \param[out] NeumannFlag Flag indicating if the dataset contains Neumann data. + * \return \ier + * + */ +int cg_dataset_read(int fn, int B, int Z, int BC, int DSet, char *DatasetName, CGNS_ENUMT(BCType_t) *BCType, int *DirichletFlag, int *NeumannFlag) { cgns_dataset *dataset; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -8989,7 +11133,7 @@ int cg_dataset_read(int file_number, int B, int Z, int BC, int DSet, char *name, dataset = cgi_get_dataset(cg, B, Z, BC, DSet); if (dataset==0) return CG_ERROR; - strcpy(name, dataset->name); + strcpy(DatasetName, dataset->name); *BCType = dataset->type; if (dataset->dirichlet) *DirichletFlag=1; else *DirichletFlag=0; @@ -8999,7 +11143,22 @@ int cg_dataset_read(int file_number, int B, int Z, int BC, int DSet, char *name, return CG_OK; } -int cg_dataset_write(int file_number, int B, int Z, int BC, const char * name, +/** + * \ingroup BCDataset + * + * \brief Write boundary condition dataset info + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] BC Boundary condition index number, where 1 ≤ BC ≤ nbocos. + * \param[in] DatasetName Name of dataset. + * \param[in] BCType Simple boundary condition type for the dataset. The supported types are listed in the table of Simple Boundary Condition Types in the SIDS manual, but note that FamilySpecified does not apply here. + * \param[out] Dset Dataset index number, where 1 ≤ Dset ≤ ndataset. + * \return \ier + * + */ +int cg_dataset_write(int fn, int B, int Z, int BC, const char * DatasetName, CGNS_ENUMT( BCType_t ) BCType, int *Dset) { cgns_boco *boco; @@ -9012,10 +11171,10 @@ int cg_dataset_write(int file_number, int B, int Z, int BC, const char * name, cgi_error("Invalid BCType: %d",BCType); return CG_ERROR; } - if (cgi_check_strlen(name)) return CG_ERROR; + if (cgi_check_strlen(DatasetName)) return CG_ERROR; /* get memory address of file */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_WRITE)) return CG_ERROR; @@ -9025,11 +11184,11 @@ int cg_dataset_write(int file_number, int B, int Z, int BC, const char * name, /* Overwrite a BCDataSet_t node : */ for (index=0; indexndataset; index++) { - if (strcmp(name, boco->dataset[index].name)==0) { + if (strcmp(DatasetName, boco->dataset[index].name)==0) { /* in CG_MODE_WRITE, children names must be unique */ if (cg->mode==CG_MODE_WRITE) { - cgi_error("Duplicate child name found: %s",name); + cgi_error("Duplicate child name found: %s",DatasetName); return CG_ERROR; } @@ -9058,7 +11217,7 @@ int cg_dataset_write(int file_number, int B, int Z, int BC, const char * name, /* save data in memory */ memset(dataset, 0, sizeof(cgns_dataset)); dataset->type = BCType; - strcpy(dataset->name, name); + strcpy(dataset->name, DatasetName); dataset->location = CGNS_ENUMV(Vertex); /* save data in file */ @@ -9072,7 +11231,23 @@ int cg_dataset_write(int file_number, int B, int Z, int BC, const char * name, * write BCdata_t Nodes \*****************************************************************************/ -int cg_bcdata_write(int file_number, int B, int Z, int BC, int Dset, +/** + * \ingroup BCData + * + * \brief Write boundary condition data + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] BC Boundary condition index number, where 1 ≤ BC ≤ nbocos. + * \param[in] Dset Dataset index number, where 1 ≤ Dset ≤ ndataset. + * \param[in] BCDataType Type of boundary condition in the dataset. Admissible boundary condition types are Dirichlet and Neumann. + * \return \ier + * + * \details To write the boundary condition data itself, after creating the BCData_t node using the function cg_bcdata_write, use cg_goto to access the node, then cg_array_write to write the data. Note that when using cg_goto to access a BCData_t node, the node index should be specified as either Dirichlet or Neumann, depending on the type of boundary condition. See the description of cg_goto for details. + * + */ +int cg_bcdata_write(int fn, int B, int Z, int BC, int Dset, CGNS_ENUMT(BCDataType_t) BCDataType) { cgns_dataset *dataset; @@ -9085,7 +11260,7 @@ int cg_bcdata_write(int file_number, int B, int Z, int BC, int Dset, } /* get memory address of file */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_WRITE)) return CG_ERROR; @@ -9136,11 +11311,23 @@ int cg_bcdata_write(int file_number, int B, int Z, int BC, int Dset, * Read and write RigidGridMotion_t Nodes \*****************************************************************************/ -int cg_n_rigid_motions(int file_number, int B, int Z, int *n_rigid_motions) +/** + * \ingroup RigidGridMotion + * + * \brief Get number of RigidGridMotion_t nodes + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[out] n_rigid_motions Number of RigidGridMotion_t nodes under zone Z. + * \return \ier + * + */ +int cg_n_rigid_motions(int fn, int B, int Z, int *n_rigid_motions) { cgns_zone *zone; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -9153,13 +11340,27 @@ int cg_n_rigid_motions(int file_number, int B, int Z, int *n_rigid_motions) return CG_OK; } -int cg_rigid_motion_read(int file_number, int B, int Z, int R, char *name, +/** + * \ingroup RigidGridMotion + * + * \brief Read RigidGridMotion_t node + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] R Rigid rotation index number, where 1 ≤ R ≤ n_rigid_motions. + * \param[out] name Name of the RigidGridMotion_t node. + * \param[out] type Type of rigid grid motion. The admissible types are CG_Null, CG_UserDefined, ConstantRate, and VariableRate. + * \return \ier + * + */ +int cg_rigid_motion_read(int fn, int B, int Z, int R, char *name, CGNS_ENUMT(RigidGridMotionType_t) *type) { cgns_rmotion *rmotion; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -9173,7 +11374,21 @@ int cg_rigid_motion_read(int file_number, int B, int Z, int R, char *name, return CG_OK; } -int cg_rigid_motion_write(int file_number, int B, int Z, const char * rmotionname, +/** + * \ingroup RigidGridMotion + * + * \brief Create RigidGridMotion_t node + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] rmotionname Name of the RigidGridMotion_t node. + * \param[in] type Type of rigid grid motion. The admissible types are CG_Null, CG_UserDefined, ConstantRate, and VariableRate. + * \param[out] R Rigid rotation index number, where 1 ≤ R ≤ n_rigid_motions. + * \return \ier + * + */ +int cg_rigid_motion_write(int fn, int B, int Z, const char * rmotionname, CGNS_ENUMT(RigidGridMotionType_t) type, int *R) { cgns_zone *zone; @@ -9190,7 +11405,7 @@ int cg_rigid_motion_write(int file_number, int B, int Z, const char * rmotionnam } /* get memory address for RigidGridMotion_t node */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_WRITE)) return CG_ERROR; @@ -9248,11 +11463,23 @@ int cg_rigid_motion_write(int file_number, int B, int Z, const char * rmotionnam * Read and write ArbitraryGridMotion_t Nodes \*****************************************************************************/ -int cg_n_arbitrary_motions(int file_number, int B, int Z, int *n_arbitrary_motions) +/** + * \ingroup ArbitraryGridMotion + * + * \brief Get number of ArbitraryGridMotion_t nodes + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[out] n_arbitrary_motions Number of ArbitraryGridMotion_t nodes under zone Z. + * \return \ier + * + */ +int cg_n_arbitrary_motions(int fn, int B, int Z, int *n_arbitrary_motions) { cgns_zone *zone; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -9265,13 +11492,27 @@ int cg_n_arbitrary_motions(int file_number, int B, int Z, int *n_arbitrary_motio return CG_OK; } -int cg_arbitrary_motion_read(int file_number, int B, int Z, int A, char *name, +/** + * \ingroup ArbitraryGridMotion + * + * \brief Read ArbitraryGridMotion_t node + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] A Arbitrary grid motion index number, where 1 ≤ A ≤ n_arbitrary_motions. + * \param[out] name Name of the ArbitraryGridMotion_t node. + * \param[out] type Type of arbitrary grid motion. The admissible types are CG_Null, CG_UserDefined, NonDeformingGrid, and DeformingGrid. + * \return \ier + * + */ +int cg_arbitrary_motion_read(int fn, int B, int Z, int A, char *name, CGNS_ENUMT(ArbitraryGridMotionType_t) *type) { cgns_amotion *amotion; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -9285,7 +11526,21 @@ int cg_arbitrary_motion_read(int file_number, int B, int Z, int A, char *name, return CG_OK; } -int cg_arbitrary_motion_write(int file_number, int B, int Z, const char * amotionname, +/** + * \ingroup ArbitraryGridMotion + * + * \brief Write ArbitraryGridMotion_t node + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] amotionname Name of the ArbitraryGridMotion_t node. + * \param[in] type Type of arbitrary grid motion. The admissible types are CG_Null, CG_UserDefined, NonDeformingGrid, and DeformingGrid. + * \param[out] A Arbitrary grid motion index number, where 1 ≤ A ≤ n_arbitrary_motions. + * \return \ier + * + */ +int cg_arbitrary_motion_write(int fn, int B, int Z, const char * amotionname, CGNS_ENUMT(ArbitraryGridMotionType_t) type, int *A) { cgns_zone *zone; @@ -9302,7 +11557,7 @@ int cg_arbitrary_motion_write(int file_number, int B, int Z, const char * amotio } /* get memory address for ArbitraryGridMotion_t node */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_WRITE)) return CG_ERROR; @@ -9360,11 +11615,22 @@ int cg_arbitrary_motion_write(int file_number, int B, int Z, const char * amotio * Read and write SimulationType_t Node \*****************************************************************************/ -int cg_simulation_type_read(int file_number, int B, CGNS_ENUMT(SimulationType_t) *type) +/** + * \ingroup SimulationType + * + * \brief Read simulation type + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[out] SimulationType Type of simulation. Valid types are CG_Null, CG_UserDefined, TimeAccurate, and NonTimeAccurate. + * \return \ier + * + */ +int cg_simulation_type_read(int fn, int B, CGNS_ENUMT(SimulationType_t) *SimulationType) { cgns_base *base; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -9372,24 +11638,35 @@ int cg_simulation_type_read(int file_number, int B, CGNS_ENUMT(SimulationType_t) base = cgi_get_base(cg, B); if (base==0) return CG_ERROR; - *type = base->type; + *SimulationType = base->type; return CG_OK; } -int cg_simulation_type_write(int file_number, int B, CGNS_ENUMT(SimulationType_t) type) +/** + * \ingroup SimulationType + * + * \brief Write simulation type + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] SimulationType Type of simulation. Valid types are CG_Null, CG_UserDefined, TimeAccurate, and NonTimeAccurate. + * \return \ier + * + */ +int cg_simulation_type_write(int fn, int B, CGNS_ENUMT(SimulationType_t) SimulationType) { cgns_base *base; cgsize_t length; /* check input */ - if (INVALID_ENUM(type,NofValidSimulationTypes)) { - cgi_error("Invalid input: SimulationType=%d ?",type); + if (INVALID_ENUM(SimulationType,NofValidSimulationTypes)) { + cgi_error("Invalid input: SimulationType=%d ?", SimulationType); return CG_ERROR; } /* get memory address for file */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_WRITE)) return CG_ERROR; @@ -9408,13 +11685,13 @@ int cg_simulation_type_write(int file_number, int B, CGNS_ENUMT(SimulationType_t if (cgi_delete_node(base->id, base->type_id)) return CG_ERROR; } - base->type = type; + base->type = SimulationType; base->type_id = 0; /* save data in file */ - length = (cgsize_t)strlen(SimulationTypeName[type]); + length = (cgsize_t)strlen(SimulationTypeName[SimulationType]); if (cgi_new_node(base->id, "SimulationType", "SimulationType_t", &base->type_id, - "C1", 1, &length, (void *)SimulationTypeName[type])) return CG_ERROR; + "C1", 1, &length, (void *)SimulationTypeName[SimulationType])) return CG_ERROR; return CG_OK; } @@ -9423,11 +11700,23 @@ int cg_simulation_type_write(int file_number, int B, CGNS_ENUMT(SimulationType_t * read and write BaseIterativeData_t Node \*****************************************************************************/ -int cg_biter_read(int file_number, int B, char *bitername, int *nsteps) +/** + * \ingroup BaseIterativeData + * + * \brief Read BaseIterativeData_t node + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[out] bitername Name of the BaseIterativeData_t node. + * \param[out] nsteps Number of time steps or iterations. + * \return \ier + * + */ +int cg_biter_read(int fn, int B, char *bitername, int *nsteps) { cgns_biter *biter; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -9441,7 +11730,19 @@ int cg_biter_read(int file_number, int B, char *bitername, int *nsteps) return CG_OK; } -int cg_biter_write(int file_number, int B, const char * bitername, int nsteps) +/** + * \ingroup BaseIterativeData + * + * \brief Write BaseIterativeData_t node + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] bitername Name of the BaseIterativeData_t node. + * \param[in] nsteps Number of time steps or iterations. + * \return \ier + * + */ +int cg_biter_write(int fn, int B, const char * bitername, int nsteps) { cgns_base *base; cgns_biter *biter; @@ -9454,7 +11755,7 @@ int cg_biter_write(int file_number, int B, const char * bitername, int nsteps) } /* get memory address for BaseIterativeData_t node */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_WRITE)) return CG_ERROR; @@ -9498,11 +11799,23 @@ int cg_biter_write(int file_number, int B, const char * bitername, int nsteps) * read and write ZoneIterativeData_t Node \*****************************************************************************/ -int cg_ziter_read(int file_number, int B, int Z, char *zitername) +/** + * \ingroup ZoneIterativeData + * + * \brief Read ZontIterativeData_t node + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[out] zitername Name of the ZoneIterativeData_t node. + * \return \ier + * + */ +int cg_ziter_read(int fn, int B, int Z, char *zitername) { cgns_ziter *ziter; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -9515,7 +11828,19 @@ int cg_ziter_read(int file_number, int B, int Z, char *zitername) return CG_OK; } -int cg_ziter_write(int file_number, int B, int Z, const char * zitername) +/** + * \ingroup ZoneIterativeData + * + * \brief Write ZontIterativeData_t node + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] zitername Name of the ZoneIterativeData_t node. + * \return \ier + * + */ +int cg_ziter_write(int fn, int B, int Z, const char * zitername) { cgns_zone *zone; cgns_ziter *ziter; @@ -9524,7 +11849,7 @@ int cg_ziter_write(int file_number, int B, int Z, const char * zitername) if (cgi_check_strlen(zitername)) return CG_ERROR; /* get memory address for ZoneIterativeData_t node */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_WRITE)) return CG_ERROR; @@ -9565,13 +11890,24 @@ int cg_ziter_write(int file_number, int B, int Z, const char * zitername) * read and write Gravity_t Node \*****************************************************************************/ -int cg_gravity_read(int file_number, int B, float *gravity_vector) +/** + * \ingroup Gravity + * + * \brief Read Gravity_t node + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] gravity_vector Components of the gravity vector. The number of components must equal PhysicalDimension. (In Fortran, this is an array of Real*4 values.) + * \return \ier + * + */ +int cg_gravity_read(int fn, int B, float *gravity_vector) { cgns_base *base; cgns_gravity *gravity; /* get memory address for file */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -9588,13 +11924,24 @@ int cg_gravity_read(int file_number, int B, float *gravity_vector) return CG_OK; } -int cg_gravity_write(int file_number, int B, float const *gravity_vector) +/** + * \ingroup Gravity + * + * \brief Write Gravity_t node + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] gravity_vector Components of the gravity vector. The number of components must equal PhysicalDimension. (In Fortran, this is an array of Real*4 values.) + * \return \ier + * + */ +int cg_gravity_write(int fn, int B, float const *gravity_vector) { cgns_base *base; cgns_gravity *gravity; /* get memory address for file */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_WRITE)) return CG_ERROR; @@ -9644,14 +11991,28 @@ int cg_gravity_write(int file_number, int B, float const *gravity_vector) * read and write Axisymmetry_t Node \*****************************************************************************/ -int cg_axisym_read(int file_number, int B, float *ref_point, float *axis) +/** + * \ingroup Axisymmetry + * + * \brief Read Axisymmetry_t node + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[out] ref_point Origin used for defining the axis of rotation. (In Fortran, this is an array of Real*4 values.) + * \param[out] axis Direction cosines of the axis of rotation, through the reference point. (In Fortran, this is an array of Real*4 values.) + * \return \ier + * + * \details This node can only be used for a bi-dimensional model, i.e., PhysicalDimension must equal two. + * + */ +int cg_axisym_read(int fn, int B, float *ref_point, float *axis) { int n; cgns_base *base; cgns_axisym *axisym; /* get memory address for file */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -9673,14 +12034,28 @@ int cg_axisym_read(int file_number, int B, float *ref_point, float *axis) return CG_OK; } -int cg_axisym_write(int file_number, int B, float const *ref_point, float const *axis) +/** + * \ingroup Axisymmetry + * + * \brief Create axisymmetry data + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] ref_point Origin used for defining the axis of rotation. (In Fortran, this is an array of Real*4 values.) + * \param[in] axis Direction cosines of the axis of rotation, through the reference point. (In Fortran, this is an array of Real*4 values.) + * \return \ier + * + * \details Axisymmetry_t node can only be used for a bi-dimensional model, i.e., PhysicalDimension must equal two. + * + */ +int cg_axisym_write(int fn, int B, float const *ref_point, float const *axis) { int n; cgns_base *base; cgns_axisym *axisym; /* get memory address for file */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_WRITE)) return CG_ERROR; @@ -9739,14 +12114,28 @@ int cg_axisym_write(int file_number, int B, float const *ref_point, float const /*****************************************************************************\ * read and write BCProperty_t Node \*****************************************************************************/ - -int cg_bc_wallfunction_read(int file_number, int B, int Z, int BC, +/** + * \ingroup SpecialBoundaryConditionProperty + * + * \brief Read wall function data + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] BC Boundary condition index number, where 1 ≤ BC ≤ nbocos. + * \param[out] WallFunctionType The wall function type. Valid types are CG_Null, CG_UserDefined, and Generic. + * \return \ier + * + * \details The "read" functions will return with ier = 2 = CG_NODE_NOT_FOUND if the requested boundary condition property, or the BCProperty_t node itself, doesn't exist. + * + */ +int cg_bc_wallfunction_read(int fn, int B, int Z, int BC, CGNS_ENUMT(WallFunctionType_t) *WallFunctionType) { cgns_bprop *bprop; /* get memory address for file */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -9764,7 +12153,22 @@ int cg_bc_wallfunction_read(int file_number, int B, int Z, int BC, return CG_OK; } -int cg_bc_wallfunction_write(int file_number, int B, int Z, int BC, +/** + * \ingroup SpecialBoundaryConditionProperty + * + * \brief Write wall function data + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] BC Boundary condition index number, where 1 ≤ BC ≤ nbocos. + * \param[in] WallFunctionType The wall function type. Valid types are CG_Null, CG_UserDefined, and Generic. + * \return \ier + * + * \details The "write" functions will create the BCProperty_t node if it doesn't already exist, then add the appropriate boundary condition property. Multiple boundary condition properties may be recorded under the same BCProperty_t node. + * + */ +int cg_bc_wallfunction_write(int fn, int B, int Z, int BC, CGNS_ENUMT(WallFunctionType_t) WallFunctionType) { cgns_bprop *bprop; @@ -9780,7 +12184,7 @@ int cg_bc_wallfunction_write(int file_number, int B, int Z, int BC, } /* get memory address of file */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_WRITE)) return CG_ERROR; @@ -9853,8 +12257,24 @@ int cg_bc_wallfunction_write(int file_number, int B, int Z, int BC, } /*----------------------------------------------------------------------*/ - -int cg_bc_area_read(int file_number, int B, int Z, int BC, +/** + * \ingroup SpecialBoundaryConditionProperty + * + * \brief Read area related data + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] BC Boundary condition index number, where 1 ≤ BC ≤ nbocos. + * \param[out] AreaType The type of area. Valid types are CG_Null, CG_UserDefined, BleedArea, and CaptureArea. + * \param[out] SurfaceArea The size of the area. (In Fortran, this is a Real*4 value.) + * \param[out] RegionName The name of the region, 32 characters max. + * \return \ier + * + * \details The "read" functions will return with ier = 2 = CG_NODE_NOT_FOUND if the requested boundary condition property, or the BCProperty_t node itself, doesn't exist. + * + */ +int cg_bc_area_read(int fn, int B, int Z, int BC, CGNS_ENUMT(AreaType_t) *AreaType, float *SurfaceArea, char *RegionName) { @@ -9862,7 +12282,7 @@ int cg_bc_area_read(int file_number, int B, int Z, int BC, cgns_bprop *bprop; /* get memory address for file */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -9888,7 +12308,24 @@ int cg_bc_area_read(int file_number, int B, int Z, int BC, return CG_OK; } -int cg_bc_area_write(int file_number, int B, int Z, int BC, +/** + * \ingroup SpecialBoundaryConditionProperty + * + * \brief Write area related data + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] BC Boundary condition index number, where 1 ≤ BC ≤ nbocos. + * \param[in] AreaType The type of area. Valid types are CG_Null, CG_UserDefined, BleedArea, and CaptureArea. + * \param[in] SurfaceArea The size of the area. (In Fortran, this is a Real*4 value.) + * \param[in] RegionName The name of the region, 32 characters max. + * \return \ier + * + * \details The "write" functions will create the BCProperty_t node if it doesn't already exist, then add the appropriate boundary condition property. Multiple boundary condition properties may be recorded under the same BCProperty_t node. + * + */ +int cg_bc_area_write(int fn, int B, int Z, int BC, CGNS_ENUMT( AreaType_t ) AreaType, float SurfaceArea, const char *RegionName) { @@ -9907,7 +12344,7 @@ int cg_bc_area_write(int file_number, int B, int Z, int BC, } /* get memory address of file */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_WRITE)) return CG_ERROR; @@ -10018,8 +12455,24 @@ int cg_bc_area_write(int file_number, int B, int Z, int BC, /*****************************************************************************\ * read and write GridConnectivityProperty_t Node \*****************************************************************************/ - -int cg_conn_periodic_read(int file_number, int B, int Z, int J, +/** + * \ingroup SpecialGridConnectivityProperty + * + * \brief Read data for periodic interface + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] J Grid connectivity index number, where 1 ≤ J ≤ nconns for the "cg_conn" functions, and 1 ≤ J ≤ n1to1 for the "cg_1to1" functions. + * \param[out] RotationCenter An array of size phys_dim defining the coordinates of the origin for defining the rotation angle between the periodic interfaces. (phys_dim is the number of coordinates required to define a vector in the field.) (In Fortran, this is an array of Real*4 values.) + * \param[out] RotationAngle An array of size phys_dim defining the rotation angle from the current interface to the connecting interface. If rotating about more than one axis, the rotation is performed first about the x-axis, then the y-axis, then the z-axis. (In Fortran, this is an array of Real*4 values.) + * \param[out] Translation An array of size phys_dim defining the translation from the current interface to the connecting interface. (In Fortran, this is an array of Real*4 values.) + * \return \ier + * + * \details The "read" functions will return with ier = 2 = CG_NODE_NOT_FOUND if the requested connectivity property, or the GridConnectivityProperty_t node itself, doesn't exist. + * + */ +int cg_conn_periodic_read(int fn, int B, int Z, int J, float *RotationCenter, float *RotationAngle, float *Translation) { @@ -10029,7 +12482,7 @@ int cg_conn_periodic_read(int file_number, int B, int Z, int J, cgns_cperio *cperio; /* get memory address for file */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -10061,7 +12514,24 @@ int cg_conn_periodic_read(int file_number, int B, int Z, int J, return CG_OK; } -int cg_conn_periodic_write(int file_number, int B, int Z, int J, +/** + * \ingroup SpecialGridConnectivityProperty + * + * \brief Write data for periodic interface + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] J Grid connectivity index number, where 1 ≤ J ≤ nconns for the "cg_conn" functions, and 1 ≤ J ≤ n1to1 for the "cg_1to1" functions. + * \param[in] RotationCenter An array of size phys_dim defining the coordinates of the origin for defining the rotation angle between the periodic interfaces. (phys_dim is the number of coordinates required to define a vector in the field.) (In Fortran, this is an array of Real*4 values.) + * \param[in] RotationAngle An array of size phys_dim defining the rotation angle from the current interface to the connecting interface. If rotating about more than one axis, the rotation is performed first about the x-axis, then the y-axis, then the z-axis. (In Fortran, this is an array of Real*4 values.) + * \param[in] Translation An array of size phys_dim defining the translation from the current interface to the connecting interface. (In Fortran, this is an array of Real*4 values.) + * \return \ier + * + * \details The "write" functions will create the GridConnectivityProperty_t node if it doesn't already exist, then add the appropriate connectivity property. Multiple grid connectivity properties may be recorded under the same GridConnectivityProperty_t node. + * + */ +int cg_conn_periodic_write(int fn, int B, int Z, int J, float const *RotationCenter, float const *RotationAngle, float const *Translation) { @@ -10072,7 +12542,7 @@ int cg_conn_periodic_write(int file_number, int B, int Z, int J, int n; /* get memory address of file */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_WRITE)) return CG_ERROR; @@ -10166,14 +12636,28 @@ int cg_conn_periodic_write(int file_number, int B, int Z, int J, } /*----------------------------------------------------------------------*/ - -int cg_conn_average_read(int file_number, int B, int Z, int J, +/** + * \ingroup SpecialGridConnectivityProperty + * + * \brief Read data for averaging interface + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] J Grid connectivity index number, where 1 ≤ J ≤ nconns for the "cg_conn" functions, and 1 ≤ J ≤ n1to1 for the "cg_1to1" functions. + * \param[out] AverageInterfaceType The type of averaging to be done. Valid types are CG_Null, CG_UserDefined, AverageAll, AverageCircumferential, AverageRadial, AverageI, AverageJ, and AverageK. + * \return \ier + * + * \details The "read" functions will return with ier = 2 = CG_NODE_NOT_FOUND if the requested connectivity property, or the GridConnectivityProperty_t node itself, doesn't exist. + * + */ +int cg_conn_average_read(int fn, int B, int Z, int J, CGNS_ENUMT(AverageInterfaceType_t) *AverageInterfaceType) { cgns_cprop *cprop; /* get memory address for file */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -10191,7 +12675,22 @@ int cg_conn_average_read(int file_number, int B, int Z, int J, return CG_OK; } -int cg_conn_average_write(int file_number, int B, int Z, int J, +/** + * \ingroup SpecialGridConnectivityProperty + * + * \brief Write data for averaging interface + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] J Grid connectivity index number, where 1 ≤ J ≤ nconns for the "cg_conn" functions, and 1 ≤ J ≤ n1to1 for the "cg_1to1" functions. + * \param[in] AverageInterfaceType The type of averaging to be done. Valid types are CG_Null, CG_UserDefined, AverageAll, AverageCircumferential, AverageRadial, AverageI, AverageJ, and AverageK. + * \return \ier + * + * \details The "write" functions will create the GridConnectivityProperty_t node if it doesn't already exist, then add the appropriate connectivity property. Multiple grid connectivity properties may be recorded under the same GridConnectivityProperty_t node. + * + */ +int cg_conn_average_write(int fn, int B, int Z, int J, CGNS_ENUMT(AverageInterfaceType_t) AverageInterfaceType) { cgns_cprop *cprop; @@ -10207,7 +12706,7 @@ int cg_conn_average_write(int file_number, int B, int Z, int J, } /* get memory address of file */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_WRITE)) return CG_ERROR; @@ -10278,8 +12777,24 @@ int cg_conn_average_write(int file_number, int B, int Z, int J, } /*----------------------------------------------------------------------*/ - -int cg_1to1_periodic_read(int file_number, int B, int Z, int J, +/** + * \ingroup SpecialGridConnectivityProperty + * + * \brief Read data for periodic interface + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] J Grid connectivity index number, where 1 ≤ J ≤ nconns for the "cg_conn" functions, and 1 ≤ J ≤ n1to1 for the "cg_1to1" functions. + * \param[out] RotationCenter An array of size phys_dim defining the coordinates of the origin for defining the rotation angle between the periodic interfaces. (phys_dim is the number of coordinates required to define a vector in the field.) (In Fortran, this is an array of Real*4 values.) + * \param[out] RotationAngle An array of size phys_dim defining the rotation angle from the current interface to the connecting interface. If rotating about more than one axis, the rotation is performed first about the x-axis, then the y-axis, then the z-axis. (In Fortran, this is an array of Real*4 values.) + * \param[out] Translation An array of size phys_dim defining the translation from the current interface to the connecting interface. (In Fortran, this is an array of Real*4 values.) + * \return \ier + * + * \details The "read" functions will return with ier = 2 = CG_NODE_NOT_FOUND if the requested connectivity property, or the GridConnectivityProperty_t node itself, doesn't exist. + * + */ +int cg_1to1_periodic_read(int fn, int B, int Z, int J, float *RotationCenter, float *RotationAngle, float *Translation) { @@ -10290,7 +12805,7 @@ int cg_1to1_periodic_read(int file_number, int B, int Z, int J, cgns_1to1 *one21; /* get memory address for file */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -10324,7 +12839,24 @@ int cg_1to1_periodic_read(int file_number, int B, int Z, int J, return CG_OK; } -int cg_1to1_periodic_write(int file_number, int B, int Z, int J, +/** + * \ingroup SpecialGridConnectivityProperty + * + * \brief Write data for periodic interface + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] J Grid connectivity index number, where 1 ≤ J ≤ nconns for the "cg_conn" functions, and 1 ≤ J ≤ n1to1 for the "cg_1to1" functions. + * \param[in] RotationCenter An array of size phys_dim defining the coordinates of the origin for defining the rotation angle between the periodic interfaces. (phys_dim is the number of coordinates required to define a vector in the field.) (In Fortran, this is an array of Real*4 values.) + * \param[in] RotationAngle An array of size phys_dim defining the rotation angle from the current interface to the connecting interface. If rotating about more than one axis, the rotation is performed first about the x-axis, then the y-axis, then the z-axis. (In Fortran, this is an array of Real*4 values.) + * \param[in] Translation An array of size phys_dim defining the translation from the current interface to the connecting interface. (In Fortran, this is an array of Real*4 values.) + * \return \ier + * + * \details The "write" functions will create the GridConnectivityProperty_t node if it doesn't already exist, then add the appropriate connectivity property. Multiple grid connectivity properties may be recorded under the same GridConnectivityProperty_t node. + * + */ +int cg_1to1_periodic_write(int fn, int B, int Z, int J, float const *RotationCenter, float const *RotationAngle, float const *Translation) @@ -10336,7 +12868,7 @@ int cg_1to1_periodic_write(int file_number, int B, int Z, int J, int n; /* get memory address of file */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_WRITE)) return CG_ERROR; @@ -10432,15 +12964,29 @@ int cg_1to1_periodic_write(int file_number, int B, int Z, int J, } /*----------------------------------------------------------------------*/ - -int cg_1to1_average_read(int file_number, int B, int Z, int J, +/** + * \ingroup SpecialGridConnectivityProperty + * + * \brief Read data for averaging interface + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] J Grid connectivity index number, where 1 ≤ J ≤ nconns for the "cg_conn" functions, and 1 ≤ J ≤ n1to1 for the "cg_1to1" functions. + * \param[out] AverageInterfaceType The type of averaging to be done. Valid types are CG_Null, CG_UserDefined, AverageAll, AverageCircumferential, AverageRadial, AverageI, AverageJ, and AverageK. + * \return \ier + * + * \details The "read" functions will return with ier = 2 = CG_NODE_NOT_FOUND if the requested connectivity property, or the GridConnectivityProperty_t node itself, doesn't exist. + * + */ +int cg_1to1_average_read(int fn, int B, int Z, int J, CGNS_ENUMT(AverageInterfaceType_t) *AverageInterfaceType) { cgns_cprop *cprop; cgns_1to1 *one21; /* get memory address for file */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; @@ -10460,7 +13006,22 @@ int cg_1to1_average_read(int file_number, int B, int Z, int J, return CG_OK; } -int cg_1to1_average_write(int file_number, int B, int Z, int J, +/** + * \ingroup SpecialGridConnectivityProperty + * + * \brief Write data for averaging interface + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] J Grid connectivity index number, where 1 ≤ J ≤ nconns for the "cg_conn" functions, and 1 ≤ J ≤ n1to1 for the "cg_1to1" functions. + * \param[in] AverageInterfaceType The type of averaging to be done. Valid types are CG_Null, CG_UserDefined, AverageAll, AverageCircumferential, AverageRadial, AverageI, AverageJ, and AverageK. + * \return \ier + * + * \details The "write" functions will create the GridConnectivityProperty_t node if it doesn't already exist, then add the appropriate connectivity property. Multiple grid connectivity properties may be recorded under the same GridConnectivityProperty_t node. + * + */ +int cg_1to1_average_write(int fn, int B, int Z, int J, CGNS_ENUMT(AverageInterfaceType_t) AverageInterfaceType) { cgns_cprop *cprop; @@ -10476,7 +13037,7 @@ int cg_1to1_average_write(int file_number, int B, int Z, int J, } /* get memory address of file */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_WRITE)) return CG_ERROR; @@ -10555,7 +13116,7 @@ int cg_1to1_average_write(int file_number, int B, int Z, int J, * Go - To Function \*****************************************************************************/ -int vcg_goto(int file_number, int B, va_list ap) +int vcg_goto(int fn, int B, va_list ap) { int n; int index[CG_MAX_GOTO_DEPTH]; @@ -10565,7 +13126,7 @@ int vcg_goto(int file_number, int B, va_list ap) posit = 0; /* set global variable cg */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; /* read variable argument list */ @@ -10575,15 +13136,41 @@ int vcg_goto(int file_number, int B, va_list ap) if (strcmp("end",label[n])==0 || strcmp("END",label[n])==0) break; index[n] = va_arg(ap, int); } - return cgi_set_posit(file_number, B, n, index, label); + return cgi_set_posit(fn, B, n, index, label); } -int cg_goto(int file_number, int B, ...) +/** + * \ingroup AccessingANode + * + * \brief Access a node via label/name, index pairs + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] ... Variable argument list used to specify the path to a node. It is composed of an unlimited list of pair-arguments identifying each node in the path. Nodes may be identified by their label or name. Thus, a pair-argument may be of the form + + "CGNS_NodeLabel", NodeIndex + +where CGNS_NodeLabel is the node label and NodeIndex is the node index, or + + "CGNS_NodeName", 0 + +where CGNS_NodeName is the node name. The 0 in the second form is required, to indicate that a node name is being specified rather than a node label. In addition, a pair-argument may be specified as + + "..", 0 + +indicating the parent of the current node. The different pair-argument forms may be intermixed in the same function call. + +There is one exception to this rule. When accessing a BCData_t node, the index must be set to either Dirichlet or Neumann since only these two types are allowed. (Note that Dirichlet and Neumann are defined in the include files cgnslib.h and cgnslib_f.h). Since "Dirichlet" and "Neuman" are also the names for these nodes, you may also use the "Dirichlet", 0 or "Neuman", 0 to access the node. See the example below. + * \return \ier + * + * \details The character string "end" (or 'end' for the Fortran function) must be the last argument. It is used to indicate the end of the argument list. You may also use the empty string, "" ('' for Fortran), or the NULL string in C, to terminate the list. + */ +int cg_goto(int fn, int B, ...) { va_list ap; int status; va_start(ap, B); - status = vcg_goto(file_number, B, ap); + status = vcg_goto(fn, B, ap); va_end(ap); return status; } @@ -10599,7 +13186,7 @@ int cg_goto(int file_number, int B, ...) * */ -int cg_goto_f08(int file_number, int B, ...) +int cg_goto_f08(int fn, int B, ...) { int n; @@ -10611,7 +13198,7 @@ int cg_goto_f08(int file_number, int B, ...) posit = 0; /* set global variable cg */ - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; va_start(ap, B); @@ -10625,12 +13212,12 @@ int cg_goto_f08(int file_number, int B, ...) } va_end(ap); - return cgi_set_posit(file_number, B, n, index, label); + return cgi_set_posit(fn, B, n, index, label); } /*-----------------------------------------------------------------------*/ -int vcg_gorel(int file_number, va_list ap) +int vcg_gorel(int fn, va_list ap) { int n = 0; int index[CG_MAX_GOTO_DEPTH]; @@ -10640,7 +13227,7 @@ int vcg_gorel(int file_number, va_list ap) cgi_error ("position not set with cg_goto"); return CG_ERROR; } - if (file_number != posit_file) { + if (fn != posit_file) { cgi_error("current position is in the wrong file"); return CG_ERROR; } @@ -10655,12 +13242,37 @@ int vcg_gorel(int file_number, va_list ap) return cgi_update_posit(n, index, label); } -int cg_gorel(int file_number, ...) +/** + * \ingroup AccessingANode + * + * \brief Access a node via relative path + * + * \param[in] fn \FILE_fn + * \param[in] ... Variable argument list used to specify the path to a node. It is composed of an unlimited list of pair-arguments identifying each node in the path. Nodes may be identified by their label or name. Thus, a pair-argument may be of the form + + "CGNS_NodeLabel", NodeIndex + +where CGNS_NodeLabel is the node label and NodeIndex is the node index, or + + "CGNS_NodeName", 0 + +where CGNS_NodeName is the node name. The 0 in the second form is required, to indicate that a node name is being specified rather than a node label. In addition, a pair-argument may be specified as + + "..", 0 + +indicating the parent of the current node. The different pair-argument forms may be intermixed in the same function call. + +There is one exception to this rule. When accessing a BCData_t node, the index must be set to either Dirichlet or Neumann since only these two types are allowed. (Note that Dirichlet and Neumann are defined in the include files cgnslib.h and cgnslib_f.h). Since "Dirichlet" and "Neuman" are also the names for these nodes, you may also use the "Dirichlet", 0 or "Neuman", 0 to access the node. See the example below. + * \return \ier + * + * \details The character string "end" (or 'end' for the Fortran function) must be the last argument. It is used to indicate the end of the argument list. You may also use the empty string, "" ('' for Fortran), or the NULL string in C, to terminate the list. + */ +int cg_gorel(int fn, ...) { va_list ap; int status; - va_start (ap, file_number); - status = vcg_gorel(file_number, ap); + va_start (ap, fn); + status = vcg_gorel(fn, ap); va_end(ap); return status; } @@ -10675,7 +13287,7 @@ int cg_gorel(int file_number, ...) * directly callable from FORTRAN. * */ -int cg_gorel_f08(int file_number, ...) +int cg_gorel_f08(int fn, ...) { int n = 0; int index[CG_MAX_GOTO_DEPTH]; @@ -10686,12 +13298,12 @@ int cg_gorel_f08(int file_number, ...) cgi_error ("position not set with cg_goto"); return CG_ERROR; } - if (file_number != posit_file) { + if (fn != posit_file) { cgi_error("current position is in the wrong file"); return CG_ERROR; } - va_start (ap, file_number); + va_start (ap, fn); for (n = 0; n < CG_MAX_GOTO_DEPTH; n++) { label[n] = va_arg(ap, char *); if (label[n] == NULL || label[n][0] == 0) break; @@ -10704,8 +13316,18 @@ int cg_gorel_f08(int file_number, ...) } /*-----------------------------------------------------------------------*/ +/** + * \ingroup AccessingANode + * + * \brief Access a node via pathname + * + * \param[in] fn \FILE_fn + * \param[in] path The pathname for the node to go to. If a position has been already set, this may be a relative path, otherwise it is an absolute path name, starting with "/Basename", where Basename is the base under which you wish to move. -int cg_gopath(int file_number, const char *path) + * \return \ier + * + */ +int cg_gopath(int fn, const char *path) { int n, len; const char *p = path, *s; @@ -10742,7 +13364,7 @@ int cg_gopath(int file_number, const char *path) strncpy(label[0], p, len); label[0][len] = 0; - cg = cgi_get_file(file_number); + cg = cgi_get_file(fn); if (cg == 0) return CG_ERROR; for (n = 0; n < cg->nbases; n++) { @@ -10755,7 +13377,7 @@ int cg_gopath(int file_number, const char *path) cgi_error("base '%s' not found", label[0]); return CG_ERROR; } - ierr = cgi_set_posit(file_number, B, 0, index, lab); + ierr = cgi_set_posit(fn, B, 0, index, lab); if (ierr != CG_OK) return ierr; if (s == 0) return CG_OK; p = s; @@ -10768,7 +13390,7 @@ int cg_gopath(int file_number, const char *path) cgi_error("position not set with cg_goto"); return CG_ERROR; } - if (file_number != posit_file) { + if (fn != posit_file) { cgi_error("current position is in the wrong file"); return CG_ERROR; } @@ -10804,19 +13426,43 @@ int cg_gopath(int file_number, const char *path) } /*-----------------------------------------------------------------------*/ - -int cg_golist(int file_number, int B, int depth, char **label, int *index) +/** + * \ingroup AccessingANode + * + * \brief Access a node via arrays of labels and indices + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] depth Depth of the path list. The maximum depth is defined in cgnslib.h by CG_MAX_GOTO_DEPTH, and is currently equal to 20. + * \param[in] label Array of node labels for the path. This argument may be passed as NULL to cg_where(), otherwise it must be dimensioned by the calling program. The maximum size required is label[MAX_GO_TO_DEPTH][33]. You may call cg_where() with both label and index set to NULL in order to get the current depth, then dimension to that value. + * \param[in] index Array of node indices for the path. This argument may be passed as NULL to cg_where(), otherwise it must be dimensioned by the calling program. The maximum size required is index[MAX_GO_TO_DEPTH]. You may call cg_where() with both label and index set to NULL in order to get the current depth, then dimension to that value. + * \return \ier + * + */ +int cg_golist(int fn, int B, int depth, char **label, int *index) { if (depth >= CG_MAX_GOTO_DEPTH) { cgi_error("path is too deep"); return CG_ERROR; } - return cgi_set_posit(file_number, B, depth, index, label); + return cgi_set_posit(fn, B, depth, index, label); } /*-----------------------------------------------------------------------*/ - -int cg_where(int *file_number, int *B, int *depth, char **label, int *num) +/** + * \ingroup AccessingANode + * + * \brief Get path to current node + * + * \param[out] fn \FILE_fn + * \param[out] B \B_Base + * \param[out] depth Depth of the path list. The maximum depth is defined in cgnslib.h by CG_MAX_GOTO_DEPTH, and is currently equal to 20. + * \param[out] label Array of node labels for the path. This argument may be passed as NULL to cg_where(), otherwise it must be dimensioned by the calling program. The maximum size required is label[MAX_GO_TO_DEPTH][33]. You may call cg_where() with both label and index set to NULL in order to get the current depth, then dimension to that value. + * \param[out] num Array of node indices for the path. This argument may be passed as NULL to cg_where(), otherwise it must be dimensioned by the calling program. The maximum size required is index[MAX_GO_TO_DEPTH]. You may call cg_where() with both label and index set to NULL in order to get the current depth, then dimension to that value. + * \return \ier + * + */ +int cg_where(int *fn, int *B, int *depth, char **label, int *num) { int n; @@ -10824,7 +13470,7 @@ int cg_where(int *file_number, int *B, int *depth, char **label, int *num) cgi_error ("position not set with cg_goto"); return CG_ERROR; } - *file_number = posit_file; + *fn = posit_file; *B = posit_base; /* first entry is base */ *depth = posit_depth > 1 ? posit_depth - 1 : 0; @@ -10843,6 +13489,15 @@ int cg_where(int *file_number, int *B, int *depth, char **label, int *num) * Read and write Multiple path nodes \*****************************************************************************/ +/** + * \ingroup FamilyName + * + * \brief Read family name + * + * \param[out] family_name Family name. + * \return \ier + * + */ int cg_famname_read(char *family_name) { char *famname; @@ -10861,6 +13516,15 @@ int cg_famname_read(char *family_name) return CG_OK; } +/** + * \ingroup FamilyName + * + * \brief Write family name + * + * \param[in] family_name Family name. + * \return \ier + * + */ int cg_famname_write(const char * family_name) { char *famname; @@ -10891,7 +13555,15 @@ int cg_famname_write(const char * family_name) } /*----------------------------------------------------------------------*/ - +/** + * \ingroup FamilyName + * + * \brief Get Number of family names + * + * \param[out] nfams Number of additional family names. + * \return \ier + * + */ int cg_nmultifam(int *nfams) { CHECK_FILE_OPEN @@ -10922,6 +13594,17 @@ int cg_nmultifam(int *nfams) return CG_OK; } +/** + * \ingroup FamilyName + * + * \brief Read multiple family names + * + * \param[in] N Family name index number, where 1 ≤ N ≤ nNames. + * \param[out] name Node name. + * \param[out] family Family name + * \return \ier + * + */ int cg_multifam_read(int N, char *name, char *family) { cgns_famname *famname; @@ -10940,6 +13623,17 @@ int cg_multifam_read(int N, char *name, char *family) return CG_OK; } +/** + * \ingroup FamilyName + * + * \brief Write multiple family names + * + * \param[in] name Node name. + * \param[in] family Family name + * \return \ier + * + * \details The additional family names written with cg_multifam_write are stored in AdditionalFamilyName_t nodes. + */ int cg_multifam_write(const char *name, const char *family) { cgns_famname *famname; @@ -10975,7 +13669,18 @@ int cg_multifam_write(const char *name, const char *family) } /*----------------------------------------------------------------------*/ - +/** + * \ingroup ConvergenceHistory + * + * \brief Read ConvergenceHistory_t node + * + * \param[out] iterations Number of iterations for which convergence information is recorded. + * \param[out] NormDefinitions Description of the convergence information recorded in the data arrays. + * \return \ier + * + * \details The function cg_convergence_read reads a ConvergenceHistory_t node. If NormDefinitions is not defined in the CGNS database, this function returns a null string. If NormDefinitions exists, the library will allocate the space to store the description string, and return the description string to the application. It is the responsibility of the application to free this space when it is no longer needed by a call to cg_free(NormDefinitions). + * + */ int cg_convergence_read(int *iterations, char **NormDefinitions) { cgns_converg *converg; @@ -11002,6 +13707,18 @@ int cg_convergence_read(int *iterations, char **NormDefinitions) return CG_OK; } +/** + * \ingroup ConvergenceHistory + * + * \brief Write ConvergenceHistory_t node + * + * \param[in] iterations Number of iterations for which convergence information is recorded. + * \param[in] NormDefinitions Description of the convergence information recorded in the data arrays. + * \return \ier + * + * \details The function cg_convergence_write creates a ConvergenceHistory_t node. It must be the first one called when recording convergence history data. The NormDefinitions may be left undefined (i.e., a blank string). After creation of this node, the descriptors, data arrays, data class, and dimensional units characterizing the ConvergenceHistory_t data structure may be added. + * + */ int cg_convergence_write(int iterations, const char * NormDefinitions) { cgns_converg *converg; @@ -11052,7 +13769,17 @@ int cg_convergence_write(int iterations, const char * NormDefinitions) } /*----------------------------------------------------------------------*/ - +/** + * \ingroup ReferenceState + * + * \brief Read text description of reference state. + * + * \param[in] StateDescription Text description of reference state. + * \return \ier + * + * \details The function cg_state_read reads the StateDescription of the local ReferenceState_t node. If StateDescription is undefined in the CGNS database, this function returns a null string. If StateDescription exists, the library will allocate the space to store the description string, and return the description string to the application. It is the responsibility of the application to free this space when it is no longer needed by a call to cg_free(StateDescription). + * + */ int cg_state_read(char **StateDescription) { cgns_state *state; @@ -11078,6 +13805,17 @@ int cg_state_read(char **StateDescription) return CG_OK; } +/** + * \ingroup ReferenceState + * + * \brief Create ReferenceState_t node + * + * \param[in] StateDescription Text description of reference state. + * \return \ier + * + * \details The function cg_state_write creates the ReferenceState_t node and must be called even if StateDescription is undefined (i.e., a blank string). The descriptors, data arrays, data class, and dimensional units characterizing the ReferenceState_t data structure may be added to this data structure after its creation. + * + */ int cg_state_write(const char * StateDescription) { cgns_state *state; @@ -11127,7 +13865,21 @@ int cg_state_write(const char * StateDescription) } /*----------------------------------------------------------------------*/ - +/** + * \ingroup FlowEquationSet + * + * \brief Read Flow equation set info + * + * \param[out] EquationDimension Dimensionality of the governing equations; it is the number of spatial variables describing the flow. + * \param[out] GoverningEquationsFlag Flag indicating whether or not this FlowEquationSet_t node includes the definition of the governing equations; 0 if it doesn't, 1 if it does. + * \param[out] GasModelFlag Flag indicating whether or not this FlowEquationSet_t node includes the definition of a gas model; 0 if it doesn't, 1 if it does. + * \param[out] ViscosityModelFlag Flag indicating whether or not this FlowEquationSet_t node includes the definition of a viscosity model; 0 if it doesn't, 1 if it does. + * \param[out] ThermalConductivityModelFlag Flag indicating whether or not this FlowEquationSet_t node includes the definition of a thermal conductivity model; 0 if it doesn't, 1 if it does. + * \param[out] TurbulenceClosureFlag Flag indicating whether or not this FlowEquationSet_t node includes the definition of the turbulence closure; 0 if it doesn't, 1 if it does. + * \param[out] TurbulenceModelFlag Flag indicating whether or not this FlowEquationSet_t node includes the definition of a turbulence model; 0 if it doesn't, 1 if it does. + * \return \ier + * + */ int cg_equationset_read(int *EquationDimension, int *GoverningEquationsFlag, int *GasModelFlag, int *ViscosityModelFlag, int *ThermalConductivityModelFlag, @@ -11169,6 +13921,16 @@ int cg_equationset_read(int *EquationDimension, return CG_OK; } +/** + * \ingroup FlowEquationSet + * + * \brief Read chemistry equation set info + * + * \param[out] ThermalRelaxationFlag Flag indicating whether or not this FlowEquationSet_t node includes the definition of a thermal relaxation model; 0 if it doesn't, 1 if it does. + * \param[out] ChemicalKineticsFlag Flag indicating whether or not this FlowEquationSet_t node includes the definition of a chemical kinetics model; 0 if it doesn't, 1 if it does. + * \return \ier + * + */ int cg_equationset_chemistry_read(int *ThermalRelaxationFlag, int *ChemicalKineticsFlag) { @@ -11192,6 +13954,17 @@ int cg_equationset_chemistry_read(int *ThermalRelaxationFlag, return CG_OK; } +/** + * \ingroup FlowEquationSet + * + * \brief Read electromagnetic equation set info + * + * \param[out] ElecFldModelFlag Flag indicating whether or not this FlowEquationSet_t node includes the definition of an electric field model for electromagnetic flows;; 0 if it doesn't, 1 if it does. + * \param[out] MagnFldModelFlag Flag indicating whether or not this FlowEquationSet_t node includes the definition of a magnetic field model for electromagnetic flows;; 0 if it doesn't, 1 if it does. + * \param[out] ConductivityModelFlag Flag indicating whether or not this FlowEquationSet_t node includes the definition of a conductivity model for electromagnetic flows; 0 if it doesn't, 1 if it does. + * \return \ier + * + */ int cg_equationset_elecmagn_read(int *ElecFldModelFlag, int *MagnFldModelFlag, int *ConductivityModelFlag) { @@ -11218,6 +13991,15 @@ int cg_equationset_elecmagn_read(int *ElecFldModelFlag, int *MagnFldModelFlag, return CG_OK; } +/** + * \ingroup FlowEquationSet + * + * \brief Write dimensionality of flow equations + * + * \param[in] EquationDimension Dimensionality of the governing equations; it is the number of spatial variables describing the flow. + * \return \ier + * + */ int cg_equationset_write(int EquationDimension) { cgns_equations *equations; @@ -11263,6 +14045,15 @@ int cg_equationset_write(int EquationDimension) /*----------------------------------------------------------------------*/ +/** + * \ingroup GoverningEquations + * + * \brief Read type of governing equation + * + * \param[out] EquationsType Type of governing equations. The admissible types are CG_Null, CG_UserDefined, FullPotential, Euler, NSLaminar, NSTurbulent, NSLaminarIncompressible, and NSTurbulentIncompressible. + * \return \ier + * + */ int cg_governing_read(CGNS_ENUMT(GoverningEquationsType_t) *EquationsType) { cgns_governing *governing; @@ -11280,6 +14071,16 @@ int cg_governing_read(CGNS_ENUMT(GoverningEquationsType_t) *EquationsType) return CG_OK; } + +/** + * \ingroup GoverningEquations + * + * \brief Write type of governing equation + * + * \param[in] Equationstype Type of governing equations. The admissible types are CG_Null, CG_UserDefined, FullPotential, Euler, NSLaminar, NSTurbulent, NSLaminarIncompressible, and NSTurbulentIncompressible. + * \return \ier + * + */ int cg_governing_write(CGNS_ENUMT(GoverningEquationsType_t) Equationstype) { cgns_governing *governing; @@ -11336,6 +14137,15 @@ int cg_governing_write(CGNS_ENUMT(GoverningEquationsType_t) Equationstype) /*----------------------------------------------------------------------*/ +/** + * \ingroup GoverningEquations + * + * \brief Read flags for diffusion terms + * + * \param[out] diffusion_model Flags defining which diffusion terms are included in the governing equations. This is only applicable to the Navier-Stokes equations with structured grids. See the discussion in the SIDS manual for details. + * \return \ier + * + */ int cg_diffusion_read(int *diffusion_model) { int n, ndata, ier=0; @@ -11373,6 +14183,15 @@ int cg_diffusion_read(int *diffusion_model) return CG_OK; } +/** + * \ingroup GoverningEquations + * + * \brief Write flags for diffusion terms + * + * \param[in] diffusion_model Flags defining which diffusion terms are included in the governing equations. This is only applicable to the Navier-Stokes equations with structured grids. See the discussion in the SIDS manual for details. + * \return \ier + * + */ int cg_diffusion_write(const int * diffusion_model) { int *diffusion; @@ -11421,6 +14240,36 @@ int cg_diffusion_write(const int * diffusion_model) /*----------------------------------------------------------------------*/ +/** + * \ingroup AuxiliaryModel + * + * \brief Read auxiliary model types + * + * \param[out] ModelLabel The CGNS label for the model being defined. The models supported by CGNS are: + * - GasModel_t + * - ViscosityModel_t + * - ThermalConductivityModel_t + * - TurbulenceClosure_t + * - TurbulenceModel_t + * - ThermalRelaxationModel_t + * - ChemicalKineticsModel_t + * - EMElectricFieldModel_t + * - EMMagneticFieldModel_t + * - EMConductivityModel_t + * \param[out] ModelType One of the model types (listed below) allowed for the ModelLabel selected. + * The types allowed for the various models are: + * GasModel_t CG_Null, CG_UserDefined, Ideal, VanderWaals, CaloricallyPerfect, ThermallyPerfect, ConstantDensity, RedlichKwong + * ViscosityModel_t CG_Null, CG_UserDefined, Constant, PowerLaw, SutherlandLaw + * ThermalConductivityModel_t CG_Null, CG_UserDefined, PowerLaw, SutherlandLaw, ConstantPrandtl + * TurbulenceModel_t CG_Null, CG_UserDefined, Algebraic_BaldwinLomax, Algebraic_CebeciSmith, HalfEquation_JohnsonKing, OneEquation_BaldwinBarth, OneEquation_SpalartAllmaras, TwoEquation_JonesLaunder, TwoEquation_MenterSST, TwoEquation_Wilcox + * TurbulenceClosure_t CG_Null, CG_UserDefined, EddyViscosity, ReynoldsStress, ReynoldsStressAlgebraic + * ThermalRelaxationModel_t CG_Null, CG_UserDefined, Frozen, ThermalEquilib, ThermalNonequilib + * ChemicalKineticsModel_t CG_Null, CG_UserDefined, Frozen, ChemicalEquilibCurveFit, ChemicalEquilibMinimization, ChemicalNonequilib + * EMElectricFieldModel_t CG_Null, CG_UserDefined, Constant, Frozen, Interpolated, Voltage + * EMMagneticFieldModel_t CG_Null, CG_UserDefined, Constant, Frozen, Interpolated + * EMConductivityModel_t CG_Null, CG_UserDefined, Constant, Frozen, Equilibrium_LinRessler, Chemistry_LinRessler + * \return \ier + */ int cg_model_read(const char *ModelLabel, CGNS_ENUMT(ModelType_t) *ModelType) { cgns_model *model; @@ -11439,6 +14288,36 @@ int cg_model_read(const char *ModelLabel, CGNS_ENUMT(ModelType_t) *ModelType) return CG_OK; } +/** + * \ingroup AuxiliaryModel + * + * \brief Write auxiliary model types + * + * \param[in] ModelLabel The CGNS label for the model being defined. The models supported by CGNS are: + * - GasModel_t + * - ViscosityModel_t + * - ThermalConductivityModel_t + * - TurbulenceClosure_t + * - TurbulenceModel_t + * - ThermalRelaxationModel_t + * - ChemicalKineticsModel_t + * - EMElectricFieldModel_t + * - EMMagneticFieldModel_t + * - EMConductivityModel_t + * \param[in] ModelType One of the model types (listed below) allowed for the ModelLabel selected. + * The types allowed for the various models are: + * GasModel_t CG_Null, CG_UserDefined, Ideal, VanderWaals, CaloricallyPerfect, ThermallyPerfect, ConstantDensity, RedlichKwong + * ViscosityModel_t CG_Null, CG_UserDefined, Constant, PowerLaw, SutherlandLaw + * ThermalConductivityModel_t CG_Null, CG_UserDefined, PowerLaw, SutherlandLaw, ConstantPrandtl + * TurbulenceModel_t CG_Null, CG_UserDefined, Algebraic_BaldwinLomax, Algebraic_CebeciSmith, HalfEquation_JohnsonKing, OneEquation_BaldwinBarth, OneEquation_SpalartAllmaras, TwoEquation_JonesLaunder, TwoEquation_MenterSST, TwoEquation_Wilcox + * TurbulenceClosure_t CG_Null, CG_UserDefined, EddyViscosity, ReynoldsStress, ReynoldsStressAlgebraic + * ThermalRelaxationModel_t CG_Null, CG_UserDefined, Frozen, ThermalEquilib, ThermalNonequilib + * ChemicalKineticsModel_t CG_Null, CG_UserDefined, Frozen, ChemicalEquilibCurveFit, ChemicalEquilibMinimization, ChemicalNonequilib + * EMElectricFieldModel_t CG_Null, CG_UserDefined, Constant, Frozen, Interpolated, Voltage + * EMMagneticFieldModel_t CG_Null, CG_UserDefined, Constant, Frozen, Interpolated + * EMConductivityModel_t CG_Null, CG_UserDefined, Constant, Frozen, Equilibrium_LinRessler, Chemistry_LinRessler + * \return \ier + */ int cg_model_write(const char * ModelLabel, CGNS_ENUMT(ModelType_t) ModelType) { cgns_model *model; @@ -11604,7 +14483,15 @@ int cg_model_write(const char * ModelLabel, CGNS_ENUMT(ModelType_t) ModelType) } /*----------------------------------------------------------------------*/ - +/** + * \ingroup DataArrays + * + * \brief Get number of data arrays under current node + * + * \param[out] narrays Number of DataArray_t nodes under the current node. + * + * \return \ier + */ int cg_narrays(int *narrays) { @@ -11731,6 +14618,19 @@ int cg_narrays(int *narrays) return CG_OK; } +/** + * \ingroup DataArrays + * + * \brief Get data array info + * + * \param[in] A Data array index, where 1 ≤ A ≤ narrays. + * \param[out] ArrayName Name of the DataArray_t node. + * \param[out] DataType Type of data held in the DataArray_t node. The admissible types are Integer, LongInteger, RealSingle, RealDouble, and Character. + * \param[out] DataDimension Number of dimensions of array in file (max 12). See Node Management Routines in CGIO User's Guide. + * \param[out] DimensionVector Dimensions of array in file. + * + * \return \ier + */ int cg_array_info(int A, char *ArrayName, CGNS_ENUMT(DataType_t) *DataType, int *DataDimension, cgsize_t *DimensionVector) { @@ -11754,6 +14654,16 @@ int cg_array_info(int A, char *ArrayName, CGNS_ENUMT(DataType_t) *DataType, return CG_OK; } +/** + * \ingroup DataArrays + * + * \brief Read data array + * + * \param[in] A Data array index, where 1 ≤ A ≤ narrays. + * \param[out] Data The data array in memory. + * + * \return \ier + */ int cg_array_read(int A, void *Data) { cgns_array *array; @@ -11783,6 +14693,18 @@ int cg_array_read(int A, void *Data) return CG_OK; } + +/** + * \ingroup DataArrays + * + * \brief Read data array as a certain type + * + * \param[in] A Data array index, where 1 ≤ A ≤ narrays. + * \param[in] type Type of data held in the DataArray_t node. The admissible types are Integer, LongInteger, RealSingle, RealDouble, and Character. + * \param[out] Data The data array in memory. + * + * \return \ier + */ int cg_array_read_as(int A, CGNS_ENUMT(DataType_t) type, void *Data) { cgns_array *array; @@ -11843,6 +14765,27 @@ int cg_array_read_as(int A, CGNS_ENUMT(DataType_t) type, void *Data) return ier ? CG_ERROR : CG_OK; } + +/** + * \ingroup DataArrays + * + * \brief Read subset of data array to a shaped memory + * + * \param[in] A Data array index, where 1 ≤ A ≤ narrays. + * \param[in] s_rmin Lower range index in file (eg., imin, jmin, kmin). + * \param[in] s_rmax Upper range index in file (eg., imax, jmax, kmax). + * \param[in] m_type The type of data held in memory. The admissible types are Integer, LongInteger, RealSingle, RealDouble, and Character. + * \param[in] m_numdim Number of dimensions of array in memory (max 12). + * \param[in] m_dimvals Dimensions of array in memory. + * \param[in] m_rmin Lower range index in memory (eg., imin, jmin, kmin). + * \param[in] m_rmax Upper range index in memory (eg., imax, jmax, kmax). + * \param[out] data The data array in memory. + * + * \return \ier + * + * \details The functions cg_array_general_read allow for type conversion when reading from the file. + * When using cg_array_general_read, the lower core elements in the file have index 1 for defining range_min and range_max; whereas for the array in memory, defined by mem_rank and mem_dimensions, the lower array elements in memory have index 1 for defining mem_range_min and mem_range_max. The actual lower and upper bounds of the array in memory can be anything. For example, to fully read a two-dimensional 6 × 6 data array with 1 rind plane on each side in the file to an 8 × 8 array in memory (mem_rank = 2 and mem_dimensions = (8,8)), set range_min and range_max to (0,0) and (7,7), and set mem_range_min and mem_range_max to (1,1) and (8,8). + */ int cg_array_general_read(int A, const cgsize_t *s_rmin, const cgsize_t *s_rmax, CGNS_ENUMT(DataType_t) m_type, @@ -11883,6 +14826,19 @@ int cg_array_general_read(int A, data); } +/** + * \ingroup DataArrays + * + * \brief Write data array + * + * \param[in] ArrayName Name of the DataArray_t node. + * \param[in] DataType Type of data held in the DataArray_t node. The admissible types are Integer, LongInteger, RealSingle, RealDouble, and Character. + * \param[in] DataDimension Number of dimensions of array in file (max 12). See Node Management Routines in CGIO User's Guide. + * \param[in] DimensionVector Dimensions of array in file. + * \param[in] Data The data array in memory. + * + * \return \ier + */ int cg_array_write(const char * ArrayName, CGNS_ENUMT(DataType_t) DataType, int DataDimension, const cgsize_t * DimensionVector, const void * Data) @@ -11948,6 +14904,30 @@ int cg_array_write(const char * ArrayName, CGNS_ENUMT(DataType_t) DataType, return CG_OK; } +/** + * \ingroup DataArrays + * + * \brief Write shaped array to a subset of data array + * + * \param[in] arrayname Name of the DataArray_t node. + * \param[in] s_type Type of data held in the DataArray_t node. The admissible types are Integer, LongInteger, RealSingle, RealDouble, and Character. + * \param[in] s_numdim Number of dimensions of array in file (max 12). See Node Management Routines in CGIO User's Guide. + * \param[in] s_dimvals Dimensions of array in file. + * \param[in] s_rmin Lower range index in file (eg., imin, jmin, kmin). + * \param[in] s_rmax Upper range index in file (eg., imax, jmax, kmax). + * \param[in] m_type The type of data held in memory. The admissible types are Integer, LongInteger, RealSingle, RealDouble, and Character. + * \param[in] m_numdim Number of dimensions of array in memory (max 12). + * \param[in] m_dimvals Dimensions of array in memory. + * \param[in] m_rmin Lower range index in memory (eg., imin, jmin, kmin). + * \param[in] m_rmax Upper range index in memory (eg., imax, jmax, kmax). + * \param[in] data The data array in memory. + * + * \return \ier + * + * \details The function cg_array_general_write may be used to write from a subset of the array in memory to a subset of the array in the file. When using the partial write, any existing data from range_min to range_max will be overwritten by the new values. All other values will not be affected. + * The functions cg_array_general_write allow for type conversion when reading to the file. + * When using cg_array_general_write, the lower core elements in the file have index 1 for defining range_min and range_max; whereas for the array in memory, defined by mem_rank and mem_dimensions, the lower array elements in memory have index 1 for defining mem_range_min and mem_range_max. The actual lower and upper bounds of the array in memory can be anything. For example, to fully read a two-dimensional 6 × 6 data array with 1 rind plane on each side in the file to an 8 × 8 array in memory (mem_rank = 2 and mem_dimensions = (8,8)), set range_min and range_max to (0,0) and (7,7), and set mem_range_min and mem_range_max to (1,1) and (8,8). + */ int cg_array_general_write(const char *arrayname, CGNS_ENUMT(DataType_t) s_type, int s_numdim, const cgsize_t *s_dimvals, @@ -12013,7 +14993,15 @@ int cg_array_general_write(const char *arrayname, } /*----------------------------------------------------------------------*/ - +/** + * \ingroup IntegralData + * + * \brief Get number of IntegralData_t nodes + * + * \param[out] nintegrals Number of IntegralData_t nodes under current node. + * + * \return \ier + */ int cg_nintegrals(int *nintegrals) { CHECK_FILE_OPEN @@ -12043,6 +15031,16 @@ int cg_nintegrals(int *nintegrals) return CG_OK; } +/** + * \ingroup IntegralData + * + * \brief Get name of an IntegralData_t node + * + * \param[in] IntegralDataIndex Integral data index number, where 1 ≤ IntegralDataIndex ≤ nintegrals. + * \param[out] IntegralDataName Name of the IntegralData_t data structure. + * + * \return \ier + */ int cg_integral_read(int IntegralDataIndex, char *IntegralDataName) { int ier=0; @@ -12061,6 +15059,15 @@ int cg_integral_read(int IntegralDataIndex, char *IntegralDataName) return CG_OK; } +/** + * \ingroup IntegralData + * + * \brief Create IntegralData_t node + * + * \param[in] IntegralDataName Name of the IntegralData_t data structure. + * + * \return \ier + */ int cg_integral_write(const char * IntegralDataName) { cgns_integral *integral; @@ -12095,7 +15102,15 @@ int cg_integral_write(const char * IntegralDataName) } /*----------------------------------------------------------------------*/ - +/** + * \ingroup RindLayers + * + * \brief Read number of rind layers + * + * \param[out] RindData Number of rind layers for each computational direction (structured grid) or number of rind points or elements (unstructured grid). For structured grids, the low/high sides have unit stride in the array (e.g., [NRindLowI, NRindHighI, NRindLowJ, NRindHighJ, NRindLowK, NRindHighK]). + * + * \return \ier + */ int cg_rind_read(int *RindData) { int n, ier=0; @@ -12120,6 +15135,17 @@ int cg_rind_read(int *RindData) return CG_OK; } +/** + * \ingroup RindLayers + * + * \brief Write number of rind layers + * + * \param[in] RindData Number of rind layers for each computational direction (structured grid) or number of rind points or elements (unstructured grid). For structured grids, the low/high sides have unit stride in the array (e.g., [NRindLowI, NRindHighI, NRindLowJ, NRindHighJ, NRindLowK, NRindHighK]). + * + * \return \ier + * + * \details When writing rind data for elements, cg_section_write must be called first, followed by cg_goto to access the Elements_t node, and then cg_rind_write. + */ int cg_rind_write(const int * RindData) { int n, ier=0; @@ -12160,7 +15186,15 @@ int cg_rind_write(const int * RindData) } /*----------------------------------------------------------------------*/ - +/** + * \ingroup DescriptiveText + * + * \brief Get number of descriptors in file + * + * \param[out] ndescriptors Number of Descriptor_t nodes under the current node. + * \return \ier + * + */ int cg_ndescriptors(int *ndescriptors) { @@ -12287,6 +15321,20 @@ int cg_ndescriptors(int *ndescriptors) return CG_OK; } +/** + * \ingroup DescriptiveText + * + * \brief Read descriptive text + * + * \param[in] descr_no Descriptor index number, where 1 ≤ descr_no ≤ ndescriptors. + * \param[out] descr_name Name of the Descriptor_t node. + * \param[out] descr_text Description held in the Descriptor_t node. + * \return \ier + * + * + * \details Note that with cg_descriptor_read the memory for the descriptor character string, text, will be allocated by the Mid-Level Library. The application code is responsible for releasing this memory when it is no longer needed by calling cg_free(text). + * + */ int cg_descriptor_read(int descr_no, char *descr_name, char **descr_text) { cgns_descr *descr; @@ -12309,6 +15357,15 @@ int cg_descriptor_read(int descr_no, char *descr_name, char **descr_text) return CG_OK; } +/** + * \ingroup DescriptiveText + * + * \brief Write descriptive text + * + * \param[in] descr_name Name of the Descriptor_t node. + * \param[in] descr_text Description held in the Descriptor_t node. + * \return \ier + */ int cg_descriptor_write(const char * descr_name, const char * descr_text) { cgns_descr *descr; @@ -12343,7 +15400,14 @@ int cg_descriptor_write(const char * descr_name, const char * descr_text) } /*----------------------------------------------------------------------*/ - +/** + * \ingroup DimensionalUnits + * + * \brief Get number of dimensional units + * + * \param[out] nunits Number of units used in the file (i.e., either 5 or 8). + * \return \ier + */ int cg_nunits(int *nunits) { cgns_units *units; @@ -12361,6 +15425,19 @@ int cg_nunits(int *nunits) return CG_OK; } +/** + * \ingroup DimensionalUnits + * + * \brief Read first five dimensional units + * + * \param[out] mass Mass units. Admissible values are CG_Null, CG_UserDefined, Kilogram, Gram, Slug, and PoundMass. + * \param[out] length Length units. Admissible values are CG_Null, CG_UserDefined, Meter, Centimeter, Millimeter, Foot, and Inch. + * \param[out] time Time units. Admissible values are CG_Null, CG_UserDefined, and Second. + * \param[out] temperature Temperature units. Admissible values are CG_Null, CG_UserDefined, Kelvin, Celsius, Rankine, and Fahrenheit. + * \param[out] angle Angle units. Admissible values are CG_Null, CG_UserDefined, Degree, and Radian. + * + * \return \ier + */ int cg_units_read(CGNS_ENUMT(MassUnits_t) *mass, CGNS_ENUMT(LengthUnits_t) *length, CGNS_ENUMT(TimeUnits_t) *time, @@ -12386,6 +15463,19 @@ int cg_units_read(CGNS_ENUMT(MassUnits_t) *mass, return CG_OK; } +/** + * \ingroup DimensionalUnits + * + * \brief Write first five dimensional units + * + * \param[in] mass Mass units. Admissible values are CG_Null, CG_UserDefined, Kilogram, Gram, Slug, and PoundMass. + * \param[in] length Length units. Admissible values are CG_Null, CG_UserDefined, Meter, Centimeter, Millimeter, Foot, and Inch. + * \param[in] time Time units. Admissible values are CG_Null, CG_UserDefined, and Second. + * \param[in] temperature Temperature units. Admissible values are CG_Null, CG_UserDefined, Kelvin, Celsius, Rankine, and Fahrenheit. + * \param[in] angle Angle units. Admissible values are CG_Null, CG_UserDefined, Degree, and Radian. + * + * \return \ier + */ int cg_units_write(CGNS_ENUMT(MassUnits_t) mass, CGNS_ENUMT(LengthUnits_t) length, CGNS_ENUMT(TimeUnits_t) time, @@ -12444,6 +15534,21 @@ int cg_units_write(CGNS_ENUMT(MassUnits_t) mass, return CG_OK; } +/** + * \ingroup DimensionalUnits + * + * \brief Read all eight dimensional units + * + * \param[out] mass Mass units. Admissible values are CG_Null, CG_UserDefined, Kilogram, Gram, Slug, and PoundMass. + * \param[out] length Length units. Admissible values are CG_Null, CG_UserDefined, Meter, Centimeter, Millimeter, Foot, and Inch. + * \param[out] time Time units. Admissible values are CG_Null, CG_UserDefined, and Second. + * \param[out] temperature Temperature units. Admissible values are CG_Null, CG_UserDefined, Kelvin, Celsius, Rankine, and Fahrenheit. + * \param[out] angle Angle units. Admissible values are CG_Null, CG_UserDefined, Degree, and Radian. + * \param[out] current Electric current units. Admissible values are CG_Null, CG_UserDefined, Ampere, Abampere, Statampere, Edison, and auCurrent. + * \param[out] amount Substance amount units. Admissible values are CG_Null, CG_UserDefined, Mole, Entities, StandardCubicFoot, and StandardCubicMeter. + * \param[out] intensity Luminous intensity units. Admissible values are CG_Null, CG_UserDefined, Candela, Candle, Carcel, Hefner, and Violle. + * \return \ier + */ int cg_unitsfull_read(CGNS_ENUMT(MassUnits_t) *mass, CGNS_ENUMT(LengthUnits_t) *length, CGNS_ENUMT(TimeUnits_t) *time, @@ -12475,6 +15580,22 @@ int cg_unitsfull_read(CGNS_ENUMT(MassUnits_t) *mass, return CG_OK; } +/** + * \ingroup DimensionalUnits + * + * \brief Write all eight dimensional units + * + * \param[in] mass Mass units. Admissible values are CG_Null, CG_UserDefined, Kilogram, Gram, Slug, and PoundMass. + * \param[in] length Length units. Admissible values are CG_Null, CG_UserDefined, Meter, Centimeter, Millimeter, Foot, and Inch. + * \param[in] time Time units. Admissible values are CG_Null, CG_UserDefined, and Second. + * \param[in] temperature Temperature units. Admissible values are CG_Null, CG_UserDefined, Kelvin, Celsius, Rankine, and Fahrenheit. + * \param[in] angle Angle units. Admissible values are CG_Null, CG_UserDefined, Degree, and Radian. + * \param[in] current Electric current units. Admissible values are CG_Null, CG_UserDefined, Ampere, Abampere, Statampere, Edison, and auCurrent. + * \param[in] amount Substance amount units. Admissible values are CG_Null, CG_UserDefined, Mole, Entities, StandardCubicFoot, and StandardCubicMeter. + * \param[in] intensity Luminous intensity units. Admissible values are CG_Null, CG_UserDefined, Candela, Candle, Carcel, Hefner, and Violle. + * + * \return \ier + */ int cg_unitsfull_write(CGNS_ENUMT(MassUnits_t) mass, CGNS_ENUMT(LengthUnits_t) length, CGNS_ENUMT(TimeUnits_t) time, @@ -12553,6 +15674,13 @@ int cg_unitsfull_write(CGNS_ENUMT(MassUnits_t) mass, /*----------------------------------------------------------------------*/ +/** + * \ingroup DimensionalExponents + * + * \brief Get exponent data type + * \param[out] DataType Data type in which the exponents are recorded. Admissible data types for the exponents are RealSingle and RealDouble. + * \return \ier + */ int cg_exponents_info(CGNS_ENUMT(DataType_t) *DataType) { cgns_exponent *exponent; @@ -12570,6 +15698,13 @@ int cg_exponents_info(CGNS_ENUMT(DataType_t) *DataType) return CG_OK; } +/** + * \ingroup DimensionalExponents + * + * \brief Get number of dimensional exponents + * \param[out] numexp Number of exponents used in the file (i.e., either 5 or 8). + * \return \ier + */ int cg_nexponents(int *numexp) { cgns_exponent *exponent; @@ -12587,6 +15722,15 @@ int cg_nexponents(int *numexp) return CG_OK; } +/** + * \ingroup DimensionalExponents + * + * \brief Read first five dimensional exponents + * \param[out] exponents Exponents for the dimensional units for mass, length, time, temperature, angle, electric current, substance amount, and luminous intensity, in that order. + * \return \ier + * + * \details When reading exponent data, either cg_exponents_read or cg_expfull_read may be used, regardless of the number of exponents used in the file. If cg_exponents_read is used, but all eight exponents are used in the file, only the first five exponents are returned. If cg_expfull_read is used, but only five exponents are used in the file, the returned values of the exponents for electric current, substance amount, and luminous intensity will be zero. + */ int cg_exponents_read(void *exponents) { cgns_exponent *exponent; @@ -12617,6 +15761,15 @@ int cg_exponents_read(void *exponents) return CG_OK; } + +/** + * \ingroup DimensionalExponents + * + * \brief Write first five dimensional exponents + * \param[in] DataType Data type in which the exponents are recorded. Admissible data types for the exponents are RealSingle and RealDouble. + * \param[in] exponents Exponents for the dimensional units for mass, length, time, temperature, angle, electric current, substance amount, and luminous intensity, in that order. + * \return \ier + */ int cg_exponents_write(CGNS_ENUMT(DataType_t) DataType, const void * exponents) { cgns_exponent *exponent; @@ -12666,6 +15819,15 @@ int cg_exponents_write(CGNS_ENUMT(DataType_t) DataType, const void * exponents) return CG_OK; } +/** + * \ingroup DimensionalExponents + * + * \brief Read all eight dimensional exponents + * \param[out] exponents Exponents for the dimensional units for mass, length, time, temperature, angle, electric current, substance amount, and luminous intensity, in that order. + * \return \ier + * + * \details When reading exponent data, either cg_exponents_read or cg_expfull_read may be used, regardless of the number of exponents used in the file. If cg_exponents_read is used, but all eight exponents are used in the file, only the first five exponents are returned. If cg_expfull_read is used, but only five exponents are used in the file, the returned values of the exponents for electric current, substance amount, and luminous intensity will be zero. + */ int cg_expfull_read(void *exponents) { cgns_exponent *exponent; @@ -12723,6 +15885,14 @@ int cg_expfull_read(void *exponents) return CG_OK; } +/** + * \ingroup DimensionalExponents + * + * \brief Write all eight dimensional exponents + * \param[in] DataType Data type in which the exponents are recorded. Admissible data types for the exponents are RealSingle and RealDouble. + * \param[in] exponents Exponents for the dimensional units for mass, length, time, temperature, angle, electric current, substance amount, and luminous intensity, in that order. + * \return \ier + */ int cg_expfull_write(CGNS_ENUMT(DataType_t) DataType, const void * exponents) { cgns_exponent *exponent; @@ -12779,7 +15949,13 @@ int cg_expfull_write(CGNS_ENUMT(DataType_t) DataType, const void * exponents) } /*----------------------------------------------------------------------*/ - +/** + * \ingroup DataConversionFactors + * + * \brief Get conversion factors data type + * \param[out] DataType Data type in which the conversion factors are recorded. Admissible data types for the exponents are RealSingle and RealDouble. + * \return \ier + */ int cg_conversion_info(CGNS_ENUMT(DataType_t) *DataType) { cgns_conversion *conversion; @@ -12797,6 +15973,20 @@ int cg_conversion_info(CGNS_ENUMT(DataType_t) *DataType) return CG_OK; } +/** + * \ingroup DataConversionFactors + * + * \brief Read conversion factors + * \param[out] ConversionFactors Two-element array containing the scaling and offset factors. + * \return \ier + * + * \details The DataConversion_t data structure contains factors to convert the nondimensional data to "raw" dimensional data. The scaling and offset factors are contained in the two-element array ConversionFactors. In pseudo-Fortran, the conversion process is as follows: + + ConversionScale = ConversionFactors(1) + ConversionOffset = ConversionFactors(2) + Data(raw) = Data(nondimensional)*ConversionScale + ConversionOffset + + */ int cg_conversion_read(void *ConversionFactors) { cgns_conversion *conversion; @@ -12821,6 +16011,14 @@ int cg_conversion_read(void *ConversionFactors) return CG_OK; } +/** + * \ingroup DataConversionFactors + * + * \brief Write conversion factors + * \param[in] DataType Data type in which the conversion factors are recorded. Admissible data types for the exponents are RealSingle and RealDouble. + * \param[in] ConversionFactors Two-element array containing the scaling and offset factors. + * \return \ier + */ int cg_conversion_write(CGNS_ENUMT(DataType_t) DataType, const void * ConversionFactors) { @@ -12868,7 +16066,23 @@ int cg_conversion_write(CGNS_ENUMT(DataType_t) DataType, } /*----------------------------------------------------------------------*/ +/** + * \ingroup DataClass + * + * \brief Read data class + * \param[out] dataclass Data class for the nodes at this level. See below for the data classes currently supported in CGNS. + * \return \ier + * + * \details The data classes currently supported in CGNS are: + + Dimensional Regular dimensional data. + NormalizedByDimensional Nondimensional data that is normalized by dimensional reference quantities. + NormalizedByUnknownDimensional All fields and reference data are nondimensional. + NondimensionalParameter Nondimensional parameters such as Mach number and lift coefficient. + DimensionlessConstant Constant such as π. +These classes are declared within typedef DataClass_t in cgnslib.h, and as parameters in cgnslib_f.h. + */ int cg_dataclass_read(CGNS_ENUMT(DataClass_t) *dataclass) { CGNS_ENUMT(DataClass_t) *DataClass; @@ -12887,6 +16101,23 @@ int cg_dataclass_read(CGNS_ENUMT(DataClass_t) *dataclass) return CG_OK; } +/** + * \ingroup DataClass + * + * \brief Write data class + * \param[in] dataclass Data class for the nodes at this level. See below for the data classes currently supported in CGNS. + * \return \ier + * + * \details The data classes currently supported in CGNS are: + + Dimensional Regular dimensional data. + NormalizedByDimensional Nondimensional data that is normalized by dimensional reference quantities. + NormalizedByUnknownDimensional All fields and reference data are nondimensional. + NondimensionalParameter Nondimensional parameters such as Mach number and lift coefficient. + DimensionlessConstant Constant such as π. + +These classes are declared within typedef DataClass_t in cgnslib.h, and as parameters in cgnslib_f.h. + */ int cg_dataclass_write(CGNS_ENUMT(DataClass_t) dataclass) { CGNS_ENUMT(DataClass_t) *DataClass; @@ -12910,7 +16141,14 @@ int cg_dataclass_write(CGNS_ENUMT(DataClass_t) dataclass) } /*----------------------------------------------------------------------*/ - +/** + * \ingroup GridLocation + * + * \brief Read grid location + * \param[out] GridLocation Location in the grid. The admissible locations are CG_Null, CG_UserDefined, Vertex, CellCenter, FaceCenter, IFaceCenter, JFaceCenter, KFaceCenter, and EdgeCenter. + * \return \ier + * + */ int cg_gridlocation_read(CGNS_ENUMT(GridLocation_t) *GridLocation) { CGNS_ENUMT(GridLocation_t) *location; @@ -12940,6 +16178,14 @@ int cg_gridlocation_read(CGNS_ENUMT(GridLocation_t) *GridLocation) return CG_OK; } +/** + * \ingroup GridLocation + * + * \brief Write grid location + * \param[in] GridLocation Location in the grid. The admissible locations are CG_Null, CG_UserDefined, Vertex, CellCenter, FaceCenter, IFaceCenter, JFaceCenter, KFaceCenter, and EdgeCenter. + * \return \ier + * + */ int cg_gridlocation_write(CGNS_ENUMT(GridLocation_t) GridLocation) { CGNS_ENUMT(GridLocation_t) *location; @@ -13023,6 +16269,14 @@ int cg_gridlocation_write(CGNS_ENUMT(GridLocation_t) GridLocation) /*----------------------------------------------------------------------*/ +/** + * \ingroup OrdinalValue + * + * \brief Read ordinal value + * \param[out] Ordinal Any integer value. + * \return \ier + * + */ int cg_ordinal_read(int *Ordinal) { int *ordinal; @@ -13040,6 +16294,14 @@ int cg_ordinal_read(int *Ordinal) return CG_OK; } +/** + * \ingroup OrdinalValue + * + * \brief Write ordinal value + * \param[in] Ordinal Any integer value. + * \return \ier + * + */ int cg_ordinal_write(int Ordinal) { int *ordinal; @@ -13063,7 +16325,14 @@ int cg_ordinal_write(int Ordinal) } /*----------------------------------------------------------------------*/ - +/** + * \ingroup Links + * + * \brief Test if a node is a link + * \param[out] path_length Length of the path name of the linked node. The value 0 is returned if the node is not a link + * \return \ier + * + */ int cg_is_link(int *path_length) { double posit_id; @@ -13086,6 +16355,19 @@ int cg_is_link(int *path_length) return CG_OK; } +/** + * \ingroup Links + * + * \brief Get path information for a link at the current location + * \param[out] filename Name of the linked file, or empty string if the link is within the same file. + * \param[out] link_path Path name of the node which the link points to. + * + * \return \ier + * + * \details Use cg_goto(_f) to position to a location in the file prior to calling these routines. + * Memory is allocated by the library for the return values of the C function cg_link_read. This memory should be freed by the user when no longer needed by calling cg_free(filename) and cg_free(link_path). + * + */ int cg_link_read(char **filename, char **link_path) { int name_len, file_len; @@ -13115,6 +16397,26 @@ int cg_link_read(char **filename, char **link_path) return CG_OK; } +/** + * \ingroup Links + * + * \brief Create a link at the current location + * + * \param[in] nodename Name of the link node to create, e.g., GridCoordinates. + * \param[in] filename Name of the linked file, or empty string if the link is within the same file. + * \param[in] name_in_file Path name of the node which the link points to. This can be a simple or a compound name, e.g., Base/Zone 1/GridCoordinates. + * + * \return \ier + * + * \details Use cg_goto(_f) to position to a location in the file prior to calling these routines. + +When using cg_link_write, the node being linked to does not have to exist when the link is created. However, when the link is used, an error will occur if the linked-to node does not exist. + +Only nodes that support child nodes will support links. + +It is assumed that the CGNS version for the file containing the link, as determined by the CGNSLibraryVersion_t node, is also applicable to filename, the file containing the linked node. + * + */ int cg_link_write(const char * nodename, const char * filename, const char * name_in_file) { double posit_id, link_id; @@ -13199,7 +16501,26 @@ int cg_link_write(const char * nodename, const char * filename, const char * nam } /*----------------------------------------------------------------------*/ - +/** + * \ingroup UserDefinedData + * + * + * \brief Get number of UserDefinedData_t nodes + * + * \param[out] nuser_data Number of UserDefinedData_t nodes under current node. + * + * \return \ier + * + * \details After accessing a particular UserDefinedData_t node using cg_goto, + * the Point Set functions may be used to read or write point set information for the node. + * The function cg_gridlocation_write may also be used to specify the location of the data with respect to the grid (e.g., Vertex or FaceCenter). + * + * Multiple levels of UserDefinedData_t nodes may be written and retrieved by positioning via cg_goto. E.g., + * + * ier = cg_goto(fn, B, "Zone_t", Z, "UserDefinedData_t", ud1, + * "UserDefinedData_t", ud2, "UserDefinedData_t", ud3, "end"); + * + */ int cg_nuser_data(int *nuser_data) { @@ -13320,6 +16641,18 @@ int cg_nuser_data(int *nuser_data) return CG_OK; } +/** + * \ingroup UserDefinedData + * + * + * \brief Get name of an UserDefinedData_t node + * + * \param[in] Index User-defined data index number, where 1 ≤ Index ≤ nuser_data. + * \param[out] UserDataName Name of the UserDefinedData_t node. + * + * \return \ier + * + */ int cg_user_data_read(int Index, char *UserDataName) { int ier=0; @@ -13338,6 +16671,17 @@ int cg_user_data_read(int Index, char *UserDataName) return CG_OK; } +/** + * \ingroup UserDefinedData + * + * + * \brief Create UserDefinedData_t node + * + * \param[in] UserDataName Name of the UserDefinedData_t node. + * + * \return \ier + * + */ int cg_user_data_write(const char * UserDataName) { cgns_user_data *user_data; @@ -13369,7 +16713,18 @@ int cg_user_data_write(const char * UserDataName) } /*----------------------------------------------------------------------*/ - +/** + * \ingroup RotatingCoordinates + * + * + * \brief Read rotating coordinates data + * + * \param[out] rot_rate Components of the angular velocity of the grid about the center of rotation. (In Fortran, this is an array of Real*4 values.) + * \param[out] rot_center Coordinates of the center of rotation. (In Fortran, this is an array of Real*4 values.) + * + * \return \ier + * + */ int cg_rotating_read(float *rot_rate, float *rot_center) { cgns_rotating *rotating; @@ -13400,6 +16755,18 @@ int cg_rotating_read(float *rot_rate, float *rot_center) return CG_OK; } +/** + * \ingroup RotatingCoordinates + * + * + * \brief Create rotating coordinates data + * + * \param[in] rot_rate Components of the angular velocity of the grid about the center of rotation. (In Fortran, this is an array of Real*4 values.) + * \param[in] rot_center Coordinates of the center of rotation. (In Fortran, this is an array of Real*4 values.) + * + * \return \ier + * + */ int cg_rotating_write(float const *rot_rate, float const *rot_center) { cgns_rotating *rotating; @@ -13469,7 +16836,18 @@ int cg_rotating_write(float const *rot_rate, float const *rot_center) } /*----------------------------------------------------------------------*/ - +/** + * \ingroup PointSets + * + * + * \brief Get point set information + * + * \param[out] ptset_type The point set type; either PointRange for a range of points or cells, or PointList for a list of discrete points or cells. + * \param[out] npnts The number of points or cells in the point set. For a point set type of PointRange, npnts is always two. For a point set type of PointList, npnts is the number of points or cells in the list. + * + * \return \ier + * + */ int cg_ptset_info(CGNS_ENUMT(PointSetType_t) *ptset_type, cgsize_t *npnts) { cgns_ptset *ptset; @@ -13490,6 +16868,17 @@ int cg_ptset_info(CGNS_ENUMT(PointSetType_t) *ptset_type, cgsize_t *npnts) return CG_OK; } +/** + * \ingroup PointSets + * + * + * \brief Read point set data + * + * \param[out] pnts The array of point or cell indices defining the point set. There should be npnts values, each of dimension IndexDimension (i.e., 1 for unstructured grids, and 2 or 3 for structured grids with 2-D or 3-D elements, respectively). + * + * \return \ier + * + */ int cg_ptset_read(cgsize_t *pnts) { cgns_ptset *ptset; @@ -13517,6 +16906,19 @@ int cg_ptset_read(cgsize_t *pnts) return CG_OK; } +/** + * \ingroup PointSets + * + * + * \brief Write point set data + * + * \param[in] ptset_type The point set type; either PointRange for a range of points or cells, or PointList for a list of discrete points or cells. + * \param[in] npnts The number of points or cells in the point set. For a point set type of PointRange, npnts is always two. For a point set type of PointList, npnts is the number of points or cells in the list. + * \param[in] pnts The array of point or cell indices defining the point set. There should be npnts values, each of dimension IndexDimension (i.e., 1 for unstructured grids, and 2 or 3 for structured grids with 2-D or 3-D elements, respectively). + * + * \return \ier + * + */ int cg_ptset_write(CGNS_ENUMT(PointSetType_t) ptset_type, cgsize_t npnts, const cgsize_t * pnts) { @@ -13605,6 +17007,17 @@ int cg_ptset_write(CGNS_ENUMT(PointSetType_t) ptset_type, cgsize_t npnts, * Read and write FamilyBCDataSet_t nodes \*****************************************************************************/ +/** + * \ingroup BoundaryConditionDatasets + * + * + * \brief Get number of family boundary condition datasets + * + * \param[out] n_dataset Number of BCDataSet nodes under the current FamilyBC_t node. + * \return \ier + * + * \details The above functions are applicable to BCDataSet_t nodes that are used to define boundary conditions for a CFD family, and thus are children of a FamilyBC_t node. The FamilyBC_t node must first be accessed using cg_goto. + */ int cg_bcdataset_info(int *n_dataset) { CHECK_FILE_OPEN @@ -13628,6 +17041,22 @@ int cg_bcdataset_info(int *n_dataset) return CG_OK; } + +/** + * \ingroup BoundaryConditionDatasets + * + * + * \brief Read family boundary condition dataset info + * + * \param[in] index Dataset index number, where 1 ≤ index ≤ ndataset. + * \param[out] name Name of dataset. + * \param[out] BCType Simple boundary condition type for the dataset. The supported types are listed in the table of Simple Boundary Condition Types in the SIDS manual, but note that FamilySpecified does not apply here. + * \param[out] DirichletFlag Flag indicating if the dataset contains Dirichlet data. + * \param[out] NeumannFlag Flag indicating if the dataset contains Neumann data. + * \return \ier + * + * \details The above functions are applicable to BCDataSet_t nodes that are used to define boundary conditions for a CFD family, and thus are children of a FamilyBC_t node. The FamilyBC_t node must first be accessed using cg_goto. + */ int cg_bcdataset_read(int index, char *name, CGNS_ENUMT(BCType_t) *BCType, int *DirichletFlag, int *NeumannFlag) { @@ -13651,6 +17080,21 @@ int cg_bcdataset_read(int index, char *name, CGNS_ENUMT(BCType_t) *BCType, return CG_OK; } + +/** + * \ingroup BoundaryConditionDatasets + * + * + * \brief Write family boundary condition dataset info + * + * \param[in] name Name of dataset. + * \param[in] BCType Simple boundary condition type for the dataset. The supported types are listed in the table of Simple Boundary Condition Types in the SIDS manual, but note that FamilySpecified does not apply here. + * \param[in] BCDataType Type of boundary condition in the dataset (i.e., for a BCData_t child node). Admissible types are Dirichlet and Neumann. + * \return \ier + * + * \details The above functions are applicable to BCDataSet_t nodes that are used to define boundary conditions for a CFD family, and thus are children of a FamilyBC_t node. The FamilyBC_t node must first be accessed using cg_goto. + * The first time cg_bcdataset_write is called with a particular DatasetName, BCType, and BCDataType, a new BCDataSet_t node is created, with a child BCData_t node. Subsequent calls with the same DatasetName and BCType may be made to add additional BCData_t nodes, of type BCDataType, to the existing BCDataSet_t node. + */ int cg_bcdataset_write(const char *name, CGNS_ENUMT(BCType_t) BCType, CGNS_ENUMT(BCDataType_t) BCDataType) { @@ -13771,9 +17215,20 @@ int cg_bcdataset_write(const char *name, CGNS_ENUMT(BCType_t) BCType, } /****************************************************************************/ -/* the index in this list IS the cgnslib.h/ElementType_t index */ +/** + * \ingroup ElementConnectivity + * + * + * \brief Get number of nodes for an element type. + * + * \param[in] type Type of element. See the eligible types for ElementType_t in the Typedefs section. + * \param[out] npe Number of nodes for an element of type type. + * \return \ier + * + */ int cg_npe(CGNS_ENUMT( ElementType_t ) type, int *npe) { +/* the index in this list IS the cgnslib.h/ElementType_t index */ static int el_size[NofValidElementTypes] = { 0, /* ElementTypeNull */ 0, /* ElementTypeUserDefined */ @@ -13904,7 +17359,39 @@ int cg_npe(CGNS_ENUMT( ElementType_t ) type, int *npe) /*****************************************************************************\ * General Delete Function \*****************************************************************************/ - +/** + * \ingroup DeletingANode + * + * \brief Delete a node + * + * \param[in] node_name Name of the child to be deleted. + * \return \ier + * + * \details The function cg_delete_node is used is conjunction with cg_goto. Once positioned at a parent node with cg_goto, a child of this node can be deleted with cg_delete_node. This function requires a single argument, NodeName, which is the name of the child to be deleted. + +Since the highest level that can be pointed to with cg_goto is a base node for a CGNS database (CGNSBase_t), the highest-level nodes that can be deleted are the children of a CGNSBase_t node. In other words, nodes located directly under the ADF (or HDF) root node (CGNSBase_t and CGNSLibraryVersion_t) can not be deleted with cg_delete. + +A few other nodes are not allowed to be deleted from the database because these are required nodes as defined by the SIDS, and deleting them would make the file non-CGNS compliant. These are: + + Under Zone_t: ZoneType + Under GridConnectivity1to1_t: PointRange, PointRangeDonor, Transform + Under OversetHoles_t: PointList and any IndexRange_t + Under GridConnectivity_t: PointRange, PointList, CellListDonor, PointListDonor + Under BC_t: PointList, PointRange + Under GeometryReference_t: GeometryFile, GeometryFormat + Under Elements_t: ElementRange, ElementConnectivity + Under Gravity_t: GravityVector + Under Axisymmetry_t: AxisymmetryReferencePoint, AxisymmetryAxisVector + Under RotatingCoordinates_t: RotationCenter, RotationRateVector + Under Periodic_t: RotationCenter, RotationAngle, Translation + Under AverageInterface_t: AverageInterfaceType + Under WallFunction_t: WallFunctionType + Under Area_t: AreaType, SurfaceArea, RegionName + +When a child node is deleted, both the database and the file on disk are updated to remove the node. One must be careful not to delete a node from within a loop of that node type. For example, if the number of zones below a CGNSBase_t node is nzones, a zone should never be deleted from within a zone loop! By deleting a zone, the total number of zones (nzones) changes, as well as the zone indexing. Suppose for example that nzones is 5, and that the third zone is deleted. After calling cg_delete_node, nzones is changed to 4, and the zones originally indexed 4 and 5 are now indexed 3 and 4. + * + * + */ int cg_delete_node(const char *node_name) { int n, m, index_dim; @@ -14797,7 +18284,19 @@ int cg_delete_node(const char *node_name) /*****************************************************************************\ * Free library malloced memory \*****************************************************************************/ +/** + * \ingroup FreeingMemory + * + * \brief Release library-allocated memory + * + * \param[in] data Data allocated by the Mid-Level Library. + * \return \ier + * + * \details This function does not affect the structure of a CGNS file; it is provided as a convenience to free memory allocated by the Mid-Level Library. This isn't necessary in Fortran, and thus an equivalent Fortran function is not provided. +The functions that are used to allocate memory for return values are cg_descriptor_read, cg_convergence_read, cg_geo_read, cg_link_read, and cg_state_read. Each of these may allocate space to contain the data returned to the application. It is the responsibility of the application to free this data when it is no longer needed. Calling cg_free is identical to calling the standard C function free, however it is probably safer in that the memory is freed in the same module in which it is created, particularly when the Mid-Level Library is a shared library or DLL. The routine checks for NULL data and will return CG_ERROR in this case, otherwise it returns CG_OK. + * + */ int cg_free(void *data) { if (data != NULL) { CGNS_FREE (data); diff --git a/externals/cgns/cgnslib.h b/externals/cgns/cgnslib.h index f2b3d5c2218..476c7689da1 100644 --- a/externals/cgns/cgnslib.h +++ b/externals/cgns/cgnslib.h @@ -32,16 +32,19 @@ * |_____|_| |_|_| \____/|_| \_\ |_/_/ \_\_| \_| |_| * * ------------------- DEVELOPER'S NOTES --------------------------- + * * (1) When adding a defined constant to this file, also add the same defined * constant to cgns_f.F90 + * + * (2) Fortran length of names for variables is limited to 31 characters. * * ------------------------------------------------------------------------- */ #ifndef CGNSLIB_H #define CGNSLIB_H -#define CGNS_VERSION 4200 -#define CGNS_DOTVERS 4.20 +#define CGNS_VERSION 4400 +#define CGNS_DOTVERS 4.40 #define CGNS_COMPATVERSION 2540 #define CGNS_COMPATDOTVERS 2.54 @@ -129,15 +132,16 @@ #define CG_CONFIG_FILE_TYPE 5 #define CG_CONFIG_RIND_INDEX 6 -#define CG_CONFIG_HDF5_COMPRESS 201 -#define CG_CONFIG_HDF5_MPI_COMM 202 -#define CG_CONFIG_HDF5_DISKLESS 203 -#define CG_CONFIG_HDF5_DISKLESS_INCR 204 -#define CG_CONFIG_HDF5_DISKLESS_WRITE 205 -#define CG_CONFIG_HDF5_ALIGNMENT 206 -#define CG_CONFIG_HDF5_MD_BLOCK_SIZE 207 -#define CG_CONFIG_HDF5_BUFFER 208 -#define CG_CONFIG_HDF5_SIEVE_BUF_SIZE 209 +#define CG_CONFIG_HDF5_COMPRESS 201 +#define CG_CONFIG_HDF5_MPI_COMM 202 +#define CG_CONFIG_HDF5_DISKLESS 203 +#define CG_CONFIG_HDF5_DISKLESS_INCR 204 +#define CG_CONFIG_HDF5_DISKLESS_WRITE 205 +#define CG_CONFIG_HDF5_ALIGNMENT 206 +#define CG_CONFIG_HDF5_MD_BLOCK_SIZE 207 +#define CG_CONFIG_HDF5_BUFFER 208 +#define CG_CONFIG_HDF5_SIEVE_BUF_SIZE 209 +#define CG_CONFIG_HDF5_ELINK_CACHE_SIZE 210 #define CG_CONFIG_RESET 1000 diff --git a/externals/cgns/pcgnslib.c b/externals/cgns/pcgnslib.c index 1acc54a5b30..90079fd9f29 100644 --- a/externals/cgns/pcgnslib.c +++ b/externals/cgns/pcgnslib.c @@ -17,6 +17,14 @@ freely, subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. -------------------------------------------------------------------------*/ +/** + * \defgroup ParallelMisc Parallel Miscellaneous Routines + * \defgroup ParallelFile Parallel File Operations + * \defgroup ParallelGridCoordinate Parallel Grid Coordinate Data + * \defgroup ElementConnectivityData Parallel Element Connectivity Data + * \defgroup SolutionData Parallel Solution Data + * \defgroup ArrayData Parallel Array Data + **/ #include #include @@ -48,6 +56,13 @@ typedef struct cg_rw_t { } u; } cg_rw_t; +typedef struct cg_rw__ptr_t { + union { + void **rbuf; /* Pointer to buffer for read */ + const void **wbuf; /* Pointer to buffer to write */ + } u; +} cg_rw_ptr_t; + /* flag for parallel reading or parallel writing */ enum cg_par_rw{ CG_PAR_READ, @@ -358,6 +373,15 @@ static int check_parallel(cgns_file *cgfile) /*== Begin Function Definitions ==*/ /*================================*/ +/** + * \ingroup ParallelMisc + * + * \brief Set the MPI communicator. + * + * \param[in] comm The MPI communicator to be used by the CGNS library. + * \details Sets the MPI communicator for parallel operations by the CGNS library. The default value is MPI_COMM_WORLD. + * \return \ier + */ int cgp_mpi_comm(MPI_Comm comm) { /* check if we are actually running a parallel program */ @@ -378,7 +402,15 @@ int cgp_mpi_comm(MPI_Comm comm) return ctx_cgio.pcg_mpi_initialized ? CG_OK : CG_ERROR; } - +/** + * \ingroup ParallelMisc + * + * \brief Set the MPI info object. + * + * \param[in] info The MPI info object to be used by the CGNS library. + * \return \ier + * \details Passes the MPI info object for parallel operations to the CGNS library. Notes for Fortran: the data type for info is an INTEGER. + */ int cgp_mpi_info(MPI_Info info) { ctx_cgio.pcg_mpi_info = info; @@ -387,7 +419,16 @@ int cgp_mpi_info(MPI_Info info) } /*---------------------------------------------------------*/ - +/** + * \ingroup ParallelMisc + * + * \brief Set the parallel IO mode. + * + * \param[in] mode Parallel input/output mode. + * \return \ier + * \details Sets the mode for parallel data reads and writes. The default value is \p CGP_COLLECTIVE, which allows any number of processes to access the data. + * When set to \p CGP_COLLECTIVE, all processes must access the data. + */ int cgp_pio_mode(CGNS_ENUMT(PIOmode_t) mode) { if (mode == CGP_INDEPENDENT) @@ -404,6 +445,14 @@ int cgp_pio_mode(CGNS_ENUMT(PIOmode_t) mode) /*---------------------------------------------------------*/ +/** + * \ingroup ParallelMisc + * + * \brief Exit with error message. + * + * \details Is similar to \e cg_error_exit in that the process will exit with an error message. + * However, it will also print the process rank, and call \p MPI_Abort with an exit code of 1. + */ void cgp_error_exit(void) { @@ -416,6 +465,17 @@ void cgp_error_exit(void) } /*===== File IO Prototypes ================================*/ +/** + * \ingroup ParallelFile + * + * \brief Open a file for parallel IO. + * + * \param[in] filename \FILE_filename + * \param[in] mode \FILE_mode + * \param[out] fn \FILE_fn + * \return \ier + * \details Similar to \e cg_open and calls that routine. The differences is that \e cgp_open explicitly sets an internal CGNS flag to indicate parallel access. + */ int cgp_open(const char *filename, int mode, int *fn) { @@ -439,7 +499,15 @@ int cgp_open(const char *filename, int mode, int *fn) } /*---------------------------------------------------------*/ - +/** + * \ingroup ParallelFile + * + * \brief Close a CGNS file. + * + * \param[in] fn \FILE_fn + * \return \ier + * \details Similar to \e cg_close and calls that routine. + */ int cgp_close(int fn) { /* reset parallel access */ @@ -448,6 +516,22 @@ int cgp_close(int fn) } /*===== Grid IO Prototypes ================================*/ +/** + * \ingroup ParallelGridCoordinate + * + * \brief Create a coordinate data node by multiple processes in a parallel fashion. + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] type \PGRID_datatype + * \param[in] coordname \PGRID_coordname + * \param[out] C \PGRID_Coordinate + * \return \ier + * \details To write the data in parallel, first call /e cgp_coord_write to create an empty data node. This call is identical + * to /e cg_coord_write with /p coord_array set to NULL (no data written). The actual data is then written to the node in parallel + * using either /e cgp_coord_write_data or /e cgp_coord_general_write_data where /p range_min and /p range_max specify the subset of coordinate data to be written by a given process. + */ int cgp_coord_write(int fn, int B, int Z, CGNS_ENUMT(DataType_t) type, const char *coordname, int *C) @@ -459,6 +543,24 @@ int cgp_coord_write(int fn, int B, int Z, CGNS_ENUMT(DataType_t) type, } /*---------------------------------------------------------*/ +/** + * \ingroup ParallelGridCoordinate + * + * \brief Write coordinate data in parallel. + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] C \C_Coordinate + * \param[in] rmin \PGRID_range_min + * \param[in] rmax \PGRID_range_max + * \param[in] coords \PGRID_coord_array + * \return \ier + * \details Writes the actual data to the node in parallel, where /p rmin and /p rmax specify the subset + * of coordinate data to be written by a given process. It is the + * responsibility of the application to ensure that the data type for the coordinate data + * matches that as defined in the file; no conversions are done. + */ int cgp_coord_write_data(int fn, int B, int Z, int C, const cgsize_t *rmin, const cgsize_t *rmax, const void *coords) @@ -509,10 +611,29 @@ int cgp_coord_write_data(int fn, int B, int Z, int C, } /*---------------------------------------------------------*/ +/** + * \ingroup ParallelGridCoordinate + * + * \brief Write shaped array to a subset of grid coordinates in parallel. + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] C \PGRID_Coordinate + * \param[in] rmin \PGRID_range_min + * \param[in] rmax \PGRID_range_max + * \param[in] m_type \PGRID_mem_datatype + * \param[in] m_numdim \PGRID_mem_rank + * \param[in] m_arg_dimvals \PGRID_mem_dimensions + * \param[in] m_rmin \PGRID_mem_range_min + * \param[in] m_rmax \PGRID_mem_range_max + * \param[out] coords \PGRID_coord_array + * \return \ier + * \details The \e cgp_coord_general_write_data perform data conversions if \e datatype is different from \e mem_datatype. If \e coords == NULL, meaning + * this processor writes no data, then only \e fn, \e B, \e Z, and \e C need be set. In this case, \e Z and \e C are "representative" + * and can point to any valid zone. + */ -/* Note: if data == NULL, meaning this processor reads no data, then - only fn, B, Z, and C need be set. In this case, Z and C are "representative" - and can point to any valid zone */ int cgp_coord_general_write_data(int fn, int B, int Z, int C, const cgsize_t *rmin, const cgsize_t *rmax, CGNS_ENUMT(DataType_t) m_type, @@ -598,6 +719,24 @@ int cgp_coord_general_write_data(int fn, int B, int Z, int C, } /*---------------------------------------------------------*/ +/** + * \ingroup ParallelGridCoordinate + * + * \brief Read coordinate data in parallel. + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] C \C_Coordinate + * \param[in] rmin \PGRID_range_min + * \param[in] rmax \PGRID_range_max + * \param[out] coords \PGRID_coord_array + * \return \ier + * \details Reads the actual data to the node in parallel, where /p rmin and /p rmax specify the subset + * of coordinate data to be read by a given process. It is the + * responsibility of the application to ensure that the data type for the coordinate data + * matches that as defined in the file; no conversions are done. + */ int cgp_coord_read_data(int fn, int B, int Z, int C, const cgsize_t *rmin, const cgsize_t *rmax, void *coords) @@ -647,10 +786,29 @@ int cgp_coord_read_data(int fn, int B, int Z, int C, } /*---------------------------------------------------------*/ +/** + * \ingroup ParallelGridCoordinate + * + * \brief Read shaped array to a subset of grid coordinates in parallel. + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] C \C_Coordinate + * \param[in] rmin \PGRID_range_min + * \param[in] rmax \PGRID_range_max + * \param[in] m_type \PGRID_mem_datatype + * \param[in] m_numdim \PGRID_mem_rank + * \param[in] m_arg_dimvals \PGRID_mem_dimensions + * \param[in] m_rmin \PGRID_mem_range_min + * \param[in] m_rmax \PGRID_mem_range_max + * \param[out] coords \PGRID_coord_array + * \return \ier + * \details The \e cgp_coord_general_read_data perform data conversions if \e datatype is different from \e mem_datatype. If \e coords == NULL, meaning + * this processor reads no data, then only \e fn, \e B, \e Z, and \e C need be set. In this case, \e Z and \e C are "representative" + * and can point to any valid zone. + */ -/* Note: if data == NULL, meaning this processor reads no data, then - only fn, B, Z, and C need be set. In this case, Z and C are "representative" - and can point to any valid zone */ int cgp_coord_general_read_data(int fn, int B, int Z, int C, const cgsize_t *rmin, const cgsize_t *rmax, CGNS_ENUMT(DataType_t) m_type, @@ -736,6 +894,28 @@ int cgp_coord_general_read_data(int fn, int B, int Z, int C, } /*===== Elements IO Prototypes ============================*/ +/* TODO: ref. cg_section_write + Add somewhere: (Note that for Fortran calls, all integer arguments are integer*4 in 32-bit mode and integer*8 in 64-bit mode. See 64-bit Fortran Portability and Issues.) +*/ +/** + * \ingroup ElementConnectivityData + * + * \brief Create a section data node. + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] sectionname \PCONN_ElementSectionName + * \param[in] type \PCONN_type + * \param[in] start \PCONN_start + * \param[in] end \PCONN_end + * \param[in] nbndry \PCONN_nbndry + * \param[out] S \CONN_S + * \return \ier + * \details \p cgp_section_write is used to write element connectivity data by multiple processes in a parallel fashion. To write the element data in parallel, first call \e cgp_section_write to create an empty data node. This call is identical to \e cg_section_write with \e Elements set to \e NULL (no data written). The actual element data is then written to the node in parallel using \p cgp_element_write_data where \e start and \e end specify the range of the elements to be written by a given process. + * NOTE (1): Routine only works for constant sized elements, since it is not possible to compute file offsets for variable sized elements without knowledge of the entire element connectivity data. + * NOTE (2): It is the responsibility of the application to ensure that \e cgsize_t in the application is the same size as that defined in the file; no conversions are done. + */ int cgp_section_write(int fn, int B, int Z, const char *sectionname, CGNS_ENUMT(ElementType_t) type, cgsize_t start, cgsize_t end, @@ -751,19 +931,31 @@ int cgp_section_write(int fn, int B, int Z, const char *sectionname, return cg_section_partial_write(fn, B, Z, sectionname, type, start, end, nbndry, S); } +/** + * \ingroup ElementConnectivityData + * + * \brief Create a section data node. + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] sectionname \PCONN_ElementSectionName + * \param[in] type \PCONN_type + * \param[in] start \PCONN_start + * \param[in] end \PCONN_end + * \param[in] maxoffset \PCONN_MaxOffset + * \param[in] nbndry \PCONN_nbndry + * \param[out] S \CONN_S + * \return \ier + * \details \p cgp_poly_section_write is used to write element connectivity data by multiple processes in a parallel fashion. To write the element data in parallel, first call \e cgp_section_write to create an empty data node. This call is identical to \e cg_section_write with \e Elements set to \e NULL (no data written). The actual element data is then written to the node in parallel using \p cgp_element_write_data where \e start and \e end specify the range of the elements to be written by a given process. + * NOTE (1): Routine only works for constant sized elements, since it is not possible to compute file offsets for variable sized elements without knowledge of the entire element connectivity data. + * NOTE (2): It is the responsibility of the application to ensure that \e cgsize_t in the application is the same size as that defined in the file; no conversions are done. + */ int cgp_poly_section_write(int fn, int B, int Z, const char *sectionname, CGNS_ENUMT(ElementType_t) type, cgsize_t start, cgsize_t end, cgsize_t maxoffset, int nbndry, int *S) { - cgns_zone *zone; - cgns_section *section = NULL; - double dummy_id; - int index; - int data[2]; - cgsize_t dim_vals; - cgsize_t num, ElementDataSize=0; - cg = cgi_get_file(fn); if (check_parallel(cg)) return CG_ERROR; if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_WRITE)) @@ -780,7 +972,23 @@ int cgp_poly_section_write(int fn, int B, int Z, const char *sectionname, } /*---------------------------------------------------------*/ - +/** + * \ingroup ElementConnectivityData + * + * \brief Write element data in parallel. + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] S \CONN_S + * \param[in] start \PCONN_start + * \param[in] end \PCONN_end + * \param[in] elements \PCONN_Elements + * \return \ier + * \details \p cgp_elements_write_data is used to write element connectivity data by multiple processes in a parallel fashion. To write the element data in parallel, first call \e cgp_section_write to create an empty data node. This call is identical to \e cg_section_write with \e Elements set to \e NULL (no data written). The actual element data is then written to the node in parallel using \p cgp_element_write_data where \e start and \e end specify the range of the elements to be written by a given process. + * NOTE (1): Routine only works for constant sized elements, since it is not possible to compute file offsets for variable sized elements without knowledge of the entire element connectivity data. + * NOTE (2): It is the responsibility of the application to ensure that \e cgsize_t in the application is the same size as that defined in the file; no conversions are done. + */ int cgp_elements_write_data(int fn, int B, int Z, int S, cgsize_t start, cgsize_t end, const cgsize_t *elements) { @@ -827,7 +1035,21 @@ int cgp_elements_write_data(int fn, int B, int Z, int S, cgsize_t start, } /*---------------------------------------------------------*/ - +/** + * \ingroup ElementConnectivityData + * + * \brief Write element data in parallel. + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] S \CONN_S + * \param[in] start \PCONN_start + * \param[in] end \PCONN_end + * \param[in] elements \PCONN_Elements + * \param[in] offsets \PCONN_Offsets + * \return \ier + */ int cgp_poly_elements_write_data(int fn, int B, int Z, int S, cgsize_t start, cgsize_t end, const cgsize_t *elements, const cgsize_t *offsets) { @@ -902,7 +1124,20 @@ int cgp_poly_elements_write_data(int fn, int B, int Z, int S, cgsize_t start, /*---------------------------------------------------------*/ - +/** + * \ingroup ElementConnectivityData + * + * \brief Read element data in parallel. + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] S \CONN_S + * \param[in] start \PCONN_start + * \param[in] end \PCONN_end + * \param[out] elements \PCONN_Elements + * \return \ier + */ int cgp_elements_read_data(int fn, int B, int Z, int S, cgsize_t start, cgsize_t end, cgsize_t *elements) { @@ -946,7 +1181,20 @@ int cgp_elements_read_data(int fn, int B, int Z, int S, cgsize_t start, return readwrite_data_parallel(hid, type, 1, &rmin, &rmax, &Data, CG_PAR_READ); } - +/** + * \ingroup ElementConnectivityData + * + * \brief Write parent info for an element section data in parallel. + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] S \CONN_S + * \param[in] start \PCONN_start + * \param[in] end \PCONN_end + * \param[in] parent_data \PCONN_Elements + * \return \ier + */ int cgp_parent_data_write(int fn, int B, int Z, int S, cgsize_t start, cgsize_t end, const cgsize_t *parent_data) @@ -1062,7 +1310,20 @@ int cgp_parent_data_write(int fn, int B, int Z, int S, } /*===== Solution IO Prototypes ============================*/ - +/** + * \ingroup SolutionData + * + * \brief Create a solution field data node in parallel. + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] S \PSOL_S + * \param[in] DataType \PSOL_datatype + * \param[in] fieldname \PSOL_fieldname + * \param[in] F \PSOL_F + * \return \ier + */ int cgp_field_write(int fn, int B, int Z, int S, CGNS_ENUMT(DataType_t) DataType, const char *fieldname, int *F) { @@ -1073,13 +1334,27 @@ int cgp_field_write(int fn, int B, int Z, int S, } /*---------------------------------------------------------*/ - +/** + * \ingroup SolutionData + * + * \brief Write field data in parallel. + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] S \PSOL_S + * \param[in] F \PSOL_F + * \param[in] rmin \PSOL_range_min + * \param[in] rmax \PSOL_range_max + * \param[in] data \PSOL_solution_array + * \return \ier + */ int cgp_field_write_data(int fn, int B, int Z, int S, int F, const cgsize_t *rmin, const cgsize_t *rmax, const void *data) { int n; hid_t hid; - cgns_array *field; + cgns_array *field = NULL; CGNS_ENUMT(DataType_t) type; cg = cgi_get_file(fn); @@ -1114,9 +1389,29 @@ int cgp_field_write_data(int fn, int B, int Z, int S, int F, /*---------------------------------------------------------*/ -/* Note: if data == NULL, meaning this processor reads no data, then - only fn, B, Z, S, and F need be set. In this case, Z, S, and F are - "representative" and can point to any valid zone */ +/** + * \ingroup SolutionData + * + * \brief Write shaped array to a subset of flow solution field in parallel. + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] S \PSOL_S + * \param[in] F \PSOL_F + * \param[in] rmin \PSOL_range_min + * \param[in] rmax \PSOL_range_max + * \param[in] m_type \PSOL_mem_datatype + * \param[in] m_numdim \PSOL_mem_rank + * \param[in] m_arg_dimvals \PSOL_mem_dimensions + * \param[in] m_rmin \PSOL_mem_range_min + * \param[in] m_rmax \PSOL_mem_range_max + * \param[in] data \PSOL_solution_array + * \return \ier + * \details If \e data == NULL, meaning this processor reads no data, then + * only \e fn,\e B, \e Z, \e S, and \e F need be set. In this case, \e Z, \e S, and \e F are + * "representative" and can point to any valid zone. + */ int cgp_field_general_write_data(int fn, int B, int Z, int S, int F, const cgsize_t *rmin, const cgsize_t *rmax, CGNS_ENUMT(DataType_t) m_type, @@ -1127,7 +1422,7 @@ int cgp_field_general_write_data(int fn, int B, int Z, int S, int F, int n, ier; hid_t hid; cgns_sol *sol; - cgns_array *field; + cgns_array *field = NULL; /* get memory addresses */ cg = cgi_get_file(fn); @@ -1198,13 +1493,27 @@ int cgp_field_general_write_data(int fn, int B, int Z, int S, int F, } /*---------------------------------------------------------*/ - +/** + * \ingroup SolutionData + * + * \brief Read field data in parallel. + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] S \PSOL_S + * \param[in] F \PSOL_F + * \param[in] rmin \PSOL_range_min + * \param[in] rmax \PSOL_range_max + * \param[in] data \PSOL_solution_array + * \return \ier + */ int cgp_field_read_data(int fn, int B, int Z, int S, int F, const cgsize_t *rmin, const cgsize_t *rmax, void *data) { int n; hid_t hid; - cgns_array *field; + cgns_array *field = NULL; CGNS_ENUMT(DataType_t) type; cg = cgi_get_file(fn); @@ -1238,9 +1547,29 @@ int cgp_field_read_data(int fn, int B, int Z, int S, int F, /*---------------------------------------------------------*/ -/* Note: if data == NULL, meaning this processor reads no data, then - only fn, B, Z, S, and F need be set. In this case, Z, S, and F are - "representative" and can point to any valid zone */ +/** + * \ingroup SolutionData + * + * \brief Read subset of flow solution field to a shaped array in parallel. + * + * \param[in] fn \FILE_fn + * \param[in] B \B_Base + * \param[in] Z \Z_Zone + * \param[in] S \PSOL_S + * \param[in] F \PSOL_F + * \param[in] rmin \PSOL_range_min + * \param[in] rmax \PSOL_range_max + * \param[in] m_type \PSOL_mem_datatype + * \param[in] m_numdim \PSOL_mem_rank + * \param[in] m_arg_dimvals \PSOL_mem_dimensions + * \param[in] m_rmin \PSOL_mem_range_min + * \param[in] m_rmax \PSOL_mem_range_max + * \param[out] data \PSOL_solution_array + * \return \ier + * \details If \e data == NULL, meaning this processor reads no data, then + * only \e fn, \e B, \e Z, \e S, and \e F need be set. In this case, \e Z, \e S, and \e F are + * "representative" and can point to any valid zone. + */ int cgp_field_general_read_data(int fn, int B, int Z, int S, int F, const cgsize_t *rmin, const cgsize_t *rmax, CGNS_ENUMT(DataType_t) m_type, @@ -1251,7 +1580,7 @@ int cgp_field_general_read_data(int fn, int B, int Z, int S, int F, int n, ier; hid_t hid; cgns_sol *sol; - cgns_array *field; + cgns_array *field = NULL; /* get memory addresses */ cg = cgi_get_file(fn); @@ -1321,7 +1650,18 @@ int cgp_field_general_read_data(int fn, int B, int Z, int S, int F, } /*===== Array IO Prototypes ===============================*/ - +/** + * \ingroup ArrayData + * + * \brief Create an array data node. + * + * \param[in] ArrayName \PARR_arrayname + * \param[in] DataType \PARR_datatype + * \param[in] DataDimension \PARR_rank + * \param[in] DimensionVector \PARR_dimensions + * \param[in] A \PARR_A + * \return \ier + */ int cgp_array_write(const char *ArrayName, CGNS_ENUMT(DataType_t) DataType, int DataDimension, const cgsize_t *DimensionVector, int *A) { @@ -1355,7 +1695,17 @@ int cgp_array_write(const char *ArrayName, CGNS_ENUMT(DataType_t) DataType, } /*---------------------------------------------------------*/ - +/** + * \ingroup ArrayData + * + * \brief Write array data in parallel. + * + * \param[in] A \PARR_A + * \param[in] rmin \PARR_range_min + * \param[in] rmax \PARR_range_max + * \param[in] data \PARR_data + * \return \ier + */ int cgp_array_write_data(int A, const cgsize_t *rmin, const cgsize_t *rmax, const void *data) { @@ -1390,9 +1740,26 @@ int cgp_array_write_data(int A, const cgsize_t *rmin, /*---------------------------------------------------------*/ -/* Note: if data == NULL, meaning this processor reads no data, then - only A need be set. In this case, A is "representative" and can point to - any valid array being written by another processor */ +/** + * \ingroup ArrayData + * + * \brief Write shaped array to a subset of data array in parallel. + * + * \param[in] A \PARR_A + * \param[in] rmin \PARR_range_min + * \param[in] rmax \PARR_range_max + * \param[in] m_type \PARR_mem_datatype + * \param[in] m_numdim \PARR_mem_rank + * \param[in] m_arg_dimvals \PARR_mem_dimensions + * \param[in] m_rmin \PARR_mem_range_min + * \param[in] m_rmax \PARR_mem_range_max + * \param[out] data \PARR_data + * \return \ier + * \details If \e data == NULL, meaning this processor reads no data, then + * only \e A need be set. In this case, \e A is "representative" and can point to + * any valid array being written by another processor + * + */ int cgp_array_general_write_data(int A, const cgsize_t *rmin, const cgsize_t *rmax, CGNS_ENUMT(DataType_t) m_type, @@ -1468,7 +1835,17 @@ int cgp_array_general_write_data(int A, } /*---------------------------------------------------------*/ - +/** + * \ingroup ArrayData + * + * \brief Read array data in parallel. + * + * \param[in] A \PARR_A + * \param[in] rmin \PARR_range_min + * \param[in] rmax \PARR_range_max + * \param[in] data \PARR_data + * \return \ier + */ int cgp_array_read_data(int A, const cgsize_t *rmin, const cgsize_t *rmax, void *data) { @@ -1502,9 +1879,25 @@ int cgp_array_read_data(int A, const cgsize_t *rmin, /*---------------------------------------------------------*/ -/* Note: if data == NULL, meaning this processor reads no data, then - only A need be set. In this case, A is "representative" and can point to - any valid array being written by another processor */ +/** + * \ingroup ArrayData + * + * \brief Read subset of data array to a shaped array in parallel. + * + * \param[in] A \PARR_A + * \param[in] rmin \PARR_range_min + * \param[in] rmax \PARR_range_max + * \param[in] m_type \PARR_mem_datatype + * \param[in] m_numdim \PARR_mem_rank + * \param[in] m_arg_dimvals \PARR_mem_dimensions + * \param[in] m_rmin \PARR_mem_range_min + * \param[in] m_rmax \PARR_mem_range_max + * \param[out] data \PARR_data + * \return \ier + * \details If \e data == NULL, meaning this processor reads no data, then + only \e A need be set. In this case, \e A is "representative" and can point to + any valid array being written by another processor. + */ int cgp_array_general_read_data(int A, const cgsize_t *rmin, const cgsize_t *rmax, CGNS_ENUMT(DataType_t) m_type, @@ -1579,17 +1972,18 @@ int cgp_array_general_read_data(int A, dataset, CG_PAR_READ); } +/******************************** + Multidataset APIs +*********************************/ -#if HDF5_HAVE_MULTI_DATASETS - -static int readwrite_multi_data_parallel(size_t count, H5D_rw_multi_t *multi_info, +static int readwrite_multi_data_parallel(size_t count, hid_t *dset_id, hid_t *mem_type_id, hid_t *mem_space_id, hid_t *file_space_id, + cg_rw_ptr_t *data, int ndims, const cgsize_t *rmin, const cgsize_t *rmax, enum cg_par_rw rw_mode) { /* * Needs to handle a NULL dataset. MSB */ int k, n; - hid_t data_id, mem_shape_id, data_shape_id, hid; hsize_t *start, *dims; herr_t herr; hid_t plist_id; @@ -1599,24 +1993,24 @@ static int readwrite_multi_data_parallel(size_t count, H5D_rw_multi_t *multi_inf /* convert from CGNS to HDF5 data type */ for (n = 0; n < count; n++) { - switch ((CGNS_ENUMT(DataType_t))multi_info[n].mem_type_id) { + switch ((CGNS_ENUMT(DataType_t))mem_type_id[n]) { case CGNS_ENUMV(Character): - multi_info[n].mem_type_id = H5T_NATIVE_CHAR; + mem_type_id[n] = H5T_NATIVE_CHAR; break; case CGNS_ENUMV(Integer): - multi_info[n].mem_type_id = H5T_NATIVE_INT32; + mem_type_id[n] = H5T_NATIVE_INT32; break; case CGNS_ENUMV(LongInteger): - multi_info[n].mem_type_id = H5T_NATIVE_INT64; + mem_type_id[n] = H5T_NATIVE_INT64; break; case CGNS_ENUMV(RealSingle): - multi_info[n].mem_type_id = H5T_NATIVE_FLOAT; + mem_type_id[n] = H5T_NATIVE_FLOAT; break; case CGNS_ENUMV(RealDouble): - multi_info[n].mem_type_id = H5T_NATIVE_DOUBLE; + mem_type_id[n] = H5T_NATIVE_DOUBLE; break; default: - cgi_error("unhandled data type %d\n", multi_info[n].mem_type_id); + cgi_error("unhandled data type %ld\n", mem_type_id[n]); free(start); free(dims); return CG_ERROR; @@ -1632,8 +2026,8 @@ static int readwrite_multi_data_parallel(size_t count, H5D_rw_multi_t *multi_inf for (k = 0; k < count; k++) { /* Create a shape for the data in memory */ - multi_info[k].mem_space_id = H5Screate_simple(ndims, dims, NULL); - if (multi_info[k].mem_space_id < 0) { + mem_space_id[k] = H5Screate_simple(ndims, dims, NULL); + if (mem_space_id[k] < 0) { cgi_error("H5Screate_simple() failed"); free(start); free(dims); @@ -1641,8 +2035,8 @@ static int readwrite_multi_data_parallel(size_t count, H5D_rw_multi_t *multi_inf } /* Open the data */ - if ((multi_info[k].dset_id = H5Dopen2(multi_info[k].dset_id, " data", H5P_DEFAULT)) < 0) { - H5Sclose(multi_info[k].mem_space_id); /** needs loop **/ + if ((dset_id[k] = H5Dopen2(dset_id[k], " data", H5P_DEFAULT)) < 0) { + H5Sclose(mem_space_id[k]); /** needs loop **/ cgi_error("H5Dopen2() failed"); free(start); free(dims); @@ -1650,10 +2044,10 @@ static int readwrite_multi_data_parallel(size_t count, H5D_rw_multi_t *multi_inf } /* Create a shape for the data in the file */ - multi_info[k].dset_space_id = H5Dget_space(multi_info[k].dset_id); - if (multi_info[k].dset_space_id < 0) { - H5Sclose(multi_info[k].mem_space_id); - H5Dclose(multi_info[k].dset_id); + file_space_id[k] = H5Dget_space(dset_id[k]); + if (file_space_id[k] < 0) { + H5Sclose(mem_space_id[k]); + H5Dclose(dset_id[k]); cgi_error("H5Dget_space() failed"); free(start); free(dims); @@ -1661,12 +2055,11 @@ static int readwrite_multi_data_parallel(size_t count, H5D_rw_multi_t *multi_inf } /* Select a section of the array in the file */ - herr = H5Sselect_hyperslab(multi_info[k].dset_space_id, H5S_SELECT_SET, start, + herr = H5Sselect_hyperslab(file_space_id[k], H5S_SELECT_SET, start, NULL, dims, NULL); if (herr < 0) { - H5Sclose(data_shape_id); - H5Sclose(mem_shape_id); - H5Dclose(data_id); + H5Sclose(mem_space_id[k]); + H5Dclose(dset_id[k]); cgi_error("H5Sselect_hyperslab() failed"); free(start); free(dims); @@ -1677,9 +2070,6 @@ static int readwrite_multi_data_parallel(size_t count, H5D_rw_multi_t *multi_inf /* Set the access property list for data transfer */ plist_id = H5Pcreate(H5P_DATASET_XFER); if (plist_id < 0) { - H5Sclose(data_shape_id); - H5Sclose(mem_shape_id); - H5Dclose(data_id); cgi_error("H5Pcreate() failed"); free(start); free(dims); @@ -1690,31 +2080,43 @@ static int readwrite_multi_data_parallel(size_t count, H5D_rw_multi_t *multi_inf herr = H5Pset_dxpl_mpio(plist_id, ctx_cgio.default_pio_mode); if (herr < 0) { H5Pclose(plist_id); - H5Sclose(data_shape_id); - H5Sclose(mem_shape_id); - H5Dclose(data_id); cgi_error("H5Pset_dxpl_mpio() failed"); free(start); free(dims); return CG_ERROR; } + /* If HDF5 does not support multi-dataset APIs, then resort to doing them one-by-one */ +#if HDF5_HAVE_MULTI_DATASETS /* Read or Write the data in parallel */ if (rw_mode == CG_PAR_READ) { - herr = H5Dread_multi(plist_id, count, multi_info); + herr = H5Dread_multi(count, dset_id, mem_type_id, mem_space_id, file_space_id, plist_id, data[0].u.rbuf); if (herr < 0) { cgi_error("H5Dread_multi() failed"); } } else { - herr = H5Dwrite_multi(plist_id, count, multi_info); + herr = H5Dwrite_multi(count, dset_id, mem_type_id, mem_space_id, file_space_id, plist_id, data[0].u.wbuf); if (herr < 0) { cgi_error("H5Dwrite_multi() failed"); } } +#else + for (k = 0; k < count; k++) { + if (rw_mode == CG_PAR_READ) { + herr = H5Dread(dset_id[k], mem_type_id[k], mem_space_id[k], file_space_id[k], plist_id, data[0].u.rbuf[k]); + if (herr < 0) { + cgi_error("H5Dread_multi() -- pseudo -- failed"); + } + } else { + herr = H5Dwrite(dset_id[k], mem_type_id[k], mem_space_id[k], file_space_id[k], plist_id, data[0].u.wbuf[k]); + if (herr < 0) { + cgi_error("H5Dwrite_multi() -- pseudo -- failed"); + } + } + } +#endif + H5Pclose(plist_id); - H5Sclose(data_shape_id); - H5Sclose(mem_shape_id); - H5Dclose(data_id); free(start); free(dims); return herr < 0 ? CG_ERROR : CG_OK; @@ -1723,72 +2125,97 @@ static int readwrite_multi_data_parallel(size_t count, H5D_rw_multi_t *multi_inf /*------------------- multi-dataset functions --------------------------------------*/ int cgp_coord_multi_read_data(int fn, int B, int Z, int *C, const cgsize_t *rmin, const cgsize_t *rmax, - void *coordsX, void *coordsY, void *coordsZ) + int nsets, void *buf[]) { - int n; - hid_t hid; - cgns_zone *zone; - cgns_zcoor *zcoor; - cgsize_t dims[3]; - cgsize_t index_dim; - CGNS_ENUMT(DataType_t) type[3]; - H5D_rw_multi_t multi_info[3]; + int n; + hid_t hid; + cgns_zone *zone = NULL; + cgns_zcoor *zcoor = NULL; + cgsize_t dims[3]; - cg = cgi_get_file(fn); - if (check_parallel(cg)) return CG_ERROR; + hid_t *dset_id = NULL; + hid_t *mem_type_id = NULL; + hid_t *mem_space_id = NULL; + hid_t *file_space_id = NULL; - if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_WRITE)) - return CG_ERROR; + int status; - zone = cgi_get_zone(cg, B, Z); - if (zone==0) return CG_ERROR; + cg = cgi_get_file(fn); + if (check_parallel(cg)) return CG_ERROR; - zcoor = cgi_get_zcoorGC(cg, B, Z); - if (zcoor==0) return CG_ERROR; + if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_WRITE)) + goto error; - for (n = 0; n < 3; n++) { - if (C[n] > zcoor->ncoords || C[n] <= 0) { - cgi_error("coord number %d invalid",C[n]); - return CG_ERROR; + dset_id = (hid_t *)malloc(nsets*sizeof(hid_t)); + mem_type_id = (hid_t *)malloc(nsets*sizeof(hid_t)); + mem_space_id = (hid_t *)malloc(nsets*sizeof(hid_t)); + file_space_id = (hid_t *)malloc(nsets*sizeof(hid_t)); + + zone = cgi_get_zone(cg, B, Z); + if (zone==0) goto error; + + zcoor = cgi_get_zcoorGC(cg, B, Z); + if (zcoor==0) goto error; + + for (n = 0; n < nsets; n++) { + if (C[n] > zcoor->ncoords || C[n] <= 0) { + cgi_error("coord number %d invalid",C[n]); + goto error; + } } - } - for (n = 0; n < zone->index_dim; n++) { - dims[n] = zone->nijk[n] + zcoor->rind_planes[2*n] + - zcoor->rind_planes[2*n+1]; - if (rmin[n] > rmax[n] || rmin[n] < 1 || rmax[n] > dims[n]) { - cgi_error("Invalid index ranges."); - return CG_ERROR; + for (n = 0; n < zone->index_dim; n++) { + dims[n] = zone->nijk[n] + zcoor->rind_planes[2*n] + + zcoor->rind_planes[2*n+1]; + if (rmin[n] > rmax[n] || rmin[n] < 1 || rmax[n] > dims[n]) { + cgi_error("Invalid index ranges."); + goto error; + } } - } - for (n = 0; n < 3; n++) { - multi_info[n].mem_type_id = cgi_datatype(zcoor->coord[C[n]-1].data_type); - to_HDF_ID(zcoor->coord[C[n]-1].id, hid); - multi_info[n].dset_id = hid; - } + for (n = 0; n < nsets; n++) { + mem_type_id[n] = cgi_datatype(zcoor->coord[C[n]-1].data_type); + to_HDF_ID(zcoor->coord[C[n]-1].id, hid); + dset_id[n] = hid; + } - multi_info[0].u.rbuf = coordsX; - multi_info[1].u.rbuf = coordsY; - multi_info[2].u.rbuf = coordsZ; + cg_rw_ptr_t Data; + Data.u.rbuf = buf; + status = readwrite_multi_data_parallel(nsets, dset_id, mem_type_id, mem_space_id, file_space_id, &Data, + zone->index_dim, rmin, rmax, CG_PAR_READ); - return readwrite_multi_data_parallel(3, multi_info, - zone->index_dim, rmin, rmax, CG_PAR_READ); + return status; + + error: + if(dset_id) + free(dset_id); + if(mem_type_id) + free(mem_type_id); + if(mem_space_id) + free(mem_space_id); + if(file_space_id) + free(file_space_id); + + return CG_ERROR; } /*---------------------------------------------------------*/ int cgp_coord_multi_write_data(int fn, int B, int Z, int *C, const cgsize_t *rmin, const cgsize_t *rmax, - const void *coordsX, const void *coordsY, const void *coordsZ) + int nsets, const void *buf[]) { int n; - cgns_zone *zone; - cgns_zcoor *zcoor; - cgsize_t dims[3]; - cgsize_t index_dim; - CGNS_ENUMT(DataType_t) type[3]; - H5D_rw_multi_t multi_info[3]; hid_t hid; + cgns_zone *zone = NULL; + cgns_zcoor *zcoor = NULL; + cgsize_t dims[3]; + + hid_t *dset_id = NULL; + hid_t *mem_type_id = NULL; + hid_t *mem_space_id = NULL; + hid_t *file_space_id = NULL; + + int status; cg = cgi_get_file(fn); if (check_parallel(cg)) return CG_ERROR; @@ -1796,16 +2223,21 @@ int cgp_coord_multi_write_data(int fn, int B, int Z, int *C, const cgsize_t *rmi if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_WRITE)) return CG_ERROR; + dset_id = (hid_t *)malloc(nsets*sizeof(hid_t)); + mem_type_id = (hid_t *)malloc(nsets*sizeof(hid_t)); + mem_space_id = (hid_t *)malloc(nsets*sizeof(hid_t)); + file_space_id = (hid_t *)malloc(nsets*sizeof(hid_t)); + zone = cgi_get_zone(cg, B, Z); - if (zone==0) return CG_ERROR; + if (zone==0) goto error; zcoor = cgi_get_zcoorGC(cg, B, Z); - if (zcoor==0) return CG_ERROR; + if (zcoor==0) goto error; - for (n = 0; n < 3; n++) { + for (n = 0; n < nsets; n++) { if (C[n] > zcoor->ncoords || C[n] <= 0) { cgi_error("coord number %d invalid",C[n]); - return CG_ERROR; + goto error; } } @@ -1814,35 +2246,52 @@ int cgp_coord_multi_write_data(int fn, int B, int Z, int *C, const cgsize_t *rmi zcoor->rind_planes[2*n+1]; if (rmin[n] > rmax[n] || rmin[n] < 1 || rmax[n] > dims[n]) { cgi_error("Invalid index ranges."); - return CG_ERROR; + goto error; } } - for (n = 0; n < 3; n++) { - multi_info[n].mem_type_id = cgi_datatype(zcoor->coord[C[n]-1].data_type); + for (n = 0; n < nsets; n++) { + mem_type_id[n] = cgi_datatype(zcoor->coord[C[n]-1].data_type); to_HDF_ID(zcoor->coord[C[n]-1].id, hid); - multi_info[n].dset_id = hid; + dset_id[n] = hid; } - multi_info[0].u.wbuf = coordsX; - multi_info[1].u.wbuf = coordsY; - multi_info[2].u.wbuf = coordsZ; + cg_rw_ptr_t Data; + Data.u.wbuf = buf; + status = readwrite_multi_data_parallel(nsets, dset_id, mem_type_id, mem_space_id, file_space_id, &Data, + zone->index_dim, rmin, rmax, CG_PAR_WRITE); + + return status; + + error: + if(dset_id) + free(dset_id); + if(mem_type_id) + free(mem_type_id); + if(mem_space_id) + free(mem_space_id); + if(file_space_id) + free(file_space_id); + + return CG_ERROR; - return readwrite_multi_data_parallel(3, multi_info, - zone->index_dim, rmin, rmax, CG_PAR_WRITE); } /*---------------------------------------------------------*/ -int vcgp_field_multi_write_data(int fn, int B, int Z, int S, int *F, - const cgsize_t *rmin, const cgsize_t *rmax, int nsets, va_list ap) +int cgp_field_multi_write_data(int fn, int B, int Z, int S, int *F, + const cgsize_t *rmin, const cgsize_t *rmax, int nsets, const void *buf[]) { int n, m; hid_t hid; - cgns_array *field; - CGNS_ENUMT(DataType_t) type; - H5D_rw_multi_t *multi_info; + cgns_array *field = NULL; + + hid_t *dset_id = NULL; + hid_t *mem_type_id = NULL; + hid_t *mem_space_id = NULL; + hid_t *file_space_id = NULL; + int status; cg = cgi_get_file(fn); @@ -1851,7 +2300,10 @@ int vcgp_field_multi_write_data(int fn, int B, int Z, int S, int *F, if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_WRITE)) return CG_ERROR; - multi_info = (H5D_rw_multi_t *)malloc(nsets*sizeof(H5D_rw_multi_t)); + dset_id = (hid_t *)malloc(nsets*sizeof(hid_t)); + mem_type_id = (hid_t *)malloc(nsets*sizeof(hid_t)); + mem_space_id = (hid_t *)malloc(nsets*sizeof(hid_t)); + file_space_id = (hid_t *)malloc(nsets*sizeof(hid_t)); for (n = 0; n < nsets; n++) { field = cgi_get_field(cg, B, Z, S, F[n]); @@ -1867,50 +2319,50 @@ int vcgp_field_multi_write_data(int fn, int B, int Z, int S, int *F, } } - multi_info[n].u.wbuf = va_arg(ap, const void *); - - multi_info[n].mem_type_id = cgi_datatype(field->data_type); + mem_type_id[n] = cgi_datatype(field->data_type); to_HDF_ID(field->id,hid); - multi_info[n].dset_id = hid; + dset_id[n] = hid; } - status = readwrite_multi_data_parallel(nsets, multi_info, + cg_rw_ptr_t Data; + Data.u.wbuf = buf; + status = readwrite_multi_data_parallel(nsets, dset_id, mem_type_id, mem_space_id, file_space_id, &Data, field->data_dim, rmin, rmax, CG_PAR_WRITE); - free(multi_info); + free(dset_id); + free(mem_type_id); + free(mem_space_id); + free(file_space_id); return status; error: - if(multi_info) - free(multi_info); + if(dset_id) + free(dset_id); + if(mem_type_id) + free(mem_type_id); + if(mem_space_id) + free(mem_space_id); + if(file_space_id) + free(file_space_id); return CG_ERROR; } -int cgp_field_multi_write_data(int fn, int B, int Z, int S, int *F, - const cgsize_t *rmin, const cgsize_t *rmax, int nsets, ...) -{ - va_list ap; - int status; - va_start(ap, nsets); - status = vcgp_field_multi_write_data(fn, B, Z, S, F, rmin, rmax, nsets, ap); - va_end(ap); - return status; - -} - - /*---------------------------------------------------------*/ -int vcgp_field_multi_read_data(int fn, int B, int Z, int S, int *F, - const cgsize_t *rmin, const cgsize_t *rmax, int nsets, va_list ap) +int cgp_field_multi_read_data(int fn, int B, int Z, int S, int *F, + const cgsize_t *rmin, const cgsize_t *rmax, int nsets, void *buf[]) { int n, m; hid_t hid; - cgns_array *field; - CGNS_ENUMT(DataType_t) type; - H5D_rw_multi_t *multi_info; + cgns_array *field = NULL; + + hid_t *dset_id; + hid_t *mem_type_id; + hid_t *mem_space_id; + hid_t *file_space_id; + int status; cg = cgi_get_file(fn); @@ -1919,7 +2371,10 @@ int vcgp_field_multi_read_data(int fn, int B, int Z, int S, int *F, if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) return CG_ERROR; - multi_info = (H5D_rw_multi_t *)malloc(nsets*sizeof(H5D_rw_multi_t)); + dset_id = (hid_t *)malloc(nsets*sizeof(hid_t)); + mem_type_id = (hid_t *)malloc(nsets*sizeof(hid_t)); + mem_space_id = (hid_t *)malloc(nsets*sizeof(hid_t)); + file_space_id = (hid_t *)malloc(nsets*sizeof(hid_t)); for (n = 0; n < nsets; n++) { @@ -1935,54 +2390,60 @@ int vcgp_field_multi_read_data(int fn, int B, int Z, int S, int *F, goto error; } } - multi_info[n].u.rbuf = va_arg(ap, void *); - multi_info[n].mem_type_id = cgi_datatype(field->data_type); + mem_type_id[n] = cgi_datatype(field->data_type); to_HDF_ID(field->id,hid); - multi_info[n].dset_id = hid; + dset_id[n] = hid; } - status = readwrite_multi_data_parallel(nsets, multi_info, + cg_rw_ptr_t Data; + Data.u.rbuf = buf; + status = readwrite_multi_data_parallel(nsets, dset_id, mem_type_id, mem_space_id, file_space_id, &Data, field->data_dim, rmin, rmax, CG_PAR_READ); - free(multi_info); + + free(dset_id); + free(mem_type_id); + free(mem_space_id); + free(file_space_id); return status; error: - if(multi_info) - free(multi_info); + if(dset_id) + free(dset_id); + if(mem_type_id) + free(mem_type_id); + if(mem_space_id) + free(mem_space_id); + if(file_space_id) + free(file_space_id); return CG_ERROR; } -int cgp_field_multi_read_data(int fn, int B, int Z, int S, int *F, - const cgsize_t *rmin, const cgsize_t *rmax, int nsets, ...) -{ - va_list ap; - int status; - va_start(ap, nsets); - status = vcgp_field_multi_read_data(fn, B, Z, S, F, rmin, rmax, nsets, ap); - va_end(ap); - return status; - -} - /*---------------------------------------------------------*/ -int vcgp_array_multi_write_data(int fn, int *A, const cgsize_t *rmin, - const cgsize_t *rmax, int nsets, va_list ap) +int cgp_array_multi_write_data(int fn, int *A, const cgsize_t *rmin, + const cgsize_t *rmax, int nsets, const void *buf[]) { int n, m, ierr = 0; hid_t hid; - cgns_array *array; - CGNS_ENUMT(DataType_t) type; - H5D_rw_multi_t *multi_info; + cgns_array *array = NULL; + + hid_t *dset_id; + hid_t *mem_type_id; + hid_t *mem_space_id; + hid_t *file_space_id; + int status; cg = cgi_get_file(fn); if (check_parallel(cg)) return CG_ERROR; - multi_info = (H5D_rw_multi_t *)malloc(nsets*sizeof(H5D_rw_multi_t)); + dset_id = (hid_t *)malloc(nsets*sizeof(hid_t)); + mem_type_id = (hid_t *)malloc(nsets*sizeof(hid_t)); + mem_space_id = (hid_t *)malloc(nsets*sizeof(hid_t)); + file_space_id = (hid_t *)malloc(nsets*sizeof(hid_t)); for (n = 0; n < nsets; n++) { @@ -1999,55 +2460,60 @@ int vcgp_array_multi_write_data(int fn, int *A, const cgsize_t *rmin, } } - multi_info[n].u.wbuf = va_arg(ap, const void *); - - multi_info[n].mem_type_id = cgi_datatype(array->data_type); + mem_type_id[n] = cgi_datatype(array->data_type); to_HDF_ID(array->id, hid); - multi_info[n].dset_id = hid; + dset_id[n] = hid; } - status = readwrite_multi_data_parallel(nsets, multi_info, + cg_rw_ptr_t Data; + Data.u.wbuf = buf; + status = readwrite_multi_data_parallel(nsets, dset_id, mem_type_id, mem_space_id, file_space_id, &Data, array->data_dim, rmin, rmax, CG_PAR_WRITE); - free(multi_info); + free(dset_id); + free(mem_type_id); + free(mem_space_id); + free(file_space_id); return status; error: - if(multi_info) - free(multi_info); - - return CG_ERROR; -} - -int cgp_array_multi_write_data(int fn, int *A, const cgsize_t *rmin, - const cgsize_t *rmax, int nsets, ...) -{ - va_list ap; - int status; - va_start(ap, nsets); - status = vcgp_array_multi_write_data(fn, A, rmin, rmax, nsets, ap); - va_end(ap); - return status; + if(dset_id) + free(dset_id); + if(mem_type_id) + free(mem_type_id); + if(mem_space_id) + free(mem_space_id); + if(file_space_id) + free(file_space_id); + return CG_ERROR; } /*---------------------------------------------------------*/ -int vcgp_array_multi_read_data(int fn, int *A, const cgsize_t *rmin, - const cgsize_t *rmax, int nsets, va_list ap) +int cgp_array_multi_read_data(int fn, int *A, const cgsize_t *rmin, + const cgsize_t *rmax, int nsets, void *buf[]) { int n, m, ierr = 0; hid_t hid; - cgns_array *array; - CGNS_ENUMT(DataType_t) type; - H5D_rw_multi_t *multi_info; + cgns_array *array = NULL; + + hid_t *dset_id; + hid_t *mem_type_id; + hid_t *mem_space_id; + hid_t *file_space_id; + int status; cg = cgi_get_file(fn); if (check_parallel(cg)) return CG_ERROR; - multi_info = (H5D_rw_multi_t *)malloc(nsets*sizeof(H5D_rw_multi_t)); + + dset_id = (hid_t *)malloc(nsets*sizeof(hid_t)); + mem_type_id = (hid_t *)malloc(nsets*sizeof(hid_t)); + mem_space_id = (hid_t *)malloc(nsets*sizeof(hid_t)); + file_space_id = (hid_t *)malloc(nsets*sizeof(hid_t)); for (n = 0; n < nsets; n++) { @@ -2063,36 +2529,159 @@ int vcgp_array_multi_read_data(int fn, int *A, const cgsize_t *rmin, goto error; } } - multi_info[n].u.rbuf = va_arg(ap, void *); - multi_info[n].mem_type_id = cgi_datatype(array->data_type); + mem_type_id[n] = cgi_datatype(array->data_type); to_HDF_ID(array->id, hid); - multi_info[n].dset_id = hid; + dset_id[n] = hid; } - status = readwrite_multi_data_parallel(nsets, multi_info, + + cg_rw_ptr_t Data; + Data.u.rbuf = buf; + status = readwrite_multi_data_parallel(nsets, dset_id, mem_type_id, mem_space_id, file_space_id, &Data, array->data_dim, rmin, rmax, CG_PAR_READ); - free(multi_info); + free(dset_id); + free(mem_type_id); + free(mem_space_id); + free(file_space_id); return status; error: - if(multi_info) - free(multi_info); + if(dset_id) + free(dset_id); + if(mem_type_id) + free(mem_type_id); + if(mem_space_id) + free(mem_space_id); + if(file_space_id) + free(file_space_id); return CG_ERROR; } -int cgp_array_multi_read_data(int fn, int *A, const cgsize_t *rmin, - const cgsize_t *rmax, int nsets, ...) +/*===== PointList Functions =============================*/ + +/** + * \ingroup PointListData + * + * \brief Write index array to PointList in parallel. + * + * \details Must use functions in @ref AccessingANode to point to a PointSet to read from + * + * \param[in] file_number \FILE_fn + * \param[in] rmin Lower range index in file + * \param[in] rmax Upper range index in file + * \param[in] points Array of points + * \return \ier + */ +int cgp_ptlist_write_data(int file_number, cgsize_t rmin, + cgsize_t end, const cgsize_t *points) { - va_list ap; - int status; - va_start(ap, nsets); - status = vcgp_array_multi_read_data(fn, A, rmin, rmax, nsets, ap); - va_end(ap); - return status; + hid_t hid; + cgns_ptset *ptset; + cgsize_t range_min[2], range_max[2]; + CGNS_ENUMT(DataType_t) type; + + /* get memory address of file */ + cg = cgi_get_file(file_number); + if (check_parallel(cg)) return CG_ERROR; + + if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_WRITE)) + return CG_ERROR; + + if (posit == 0) { + cgi_error("No current position set by cg_goto\n"); + return CG_ERROR; + } + else if (strcmp(posit->label, "IndexArray_t") == 0) { + ptset = (cgns_ptset *) posit->posit; + } else { + cgi_error("Goto not pointing to IndexArray_t, but %s\n", posit->label); + return CG_ERROR; + } + + if (points) { + if (rmin > end || + rmin < 1 || + end > ptset->npts) { + cgi_error("Error in requested point set range."); + return CG_ERROR; + } + } + + range_min[0] = 1; + range_max[0] = 1; + range_min[1] = rmin; + range_max[1] = end; + type = cgi_datatype(ptset->data_type); + to_HDF_ID(ptset->id, hid); + + cg_rw_t Data; + Data.u.wbuf = points; + return readwrite_data_parallel(hid, type, + 2, range_min, range_max, &Data, CG_PAR_WRITE); } -#endif +/** + * \ingroup PointListData + * + * \brief Read index array to PointList in parallel. + * + * \details Must use functions in @ref AccessingANode to point to a PointSet to read from + * + * \param[in] file_number \FILE_fn + * \param[in] rmin Lower range index in file + * \param[in] rmax Upper range index in file + * \param[in] points Array of points + * \return \ier + */ +int cgp_ptlist_read_data(int file_number, cgsize_t rmin, cgsize_t rmax, cgsize_t *points) +{ + hid_t hid; + cgns_ptset *ptset; + cgsize_t range_min[2], range_max[2]; + CGNS_ENUMT(DataType_t) type; + + /* get memory address of file */ + cg = cgi_get_file(file_number); + if (check_parallel(cg)) return CG_ERROR; + + if (cgi_check_mode(cg->filename, cg->mode, CG_MODE_READ)) + return CG_ERROR; + + if (posit == 0) { + cgi_error("No current position set by cg_goto\n"); + return CG_ERROR; + } + else if (strcmp(posit->label, "IndexArray_t") == 0) { + ptset = (cgns_ptset *) posit->posit; + } else { + cgi_error("Goto not pointing to IndexArray_t, but %s\n", posit->label); + return CG_ERROR; + } + + if (points) { + if (rmin > rmax || + rmin < 1 || + rmax > ptset->npts) { + cgi_error("Error in requested point set range."); + return CG_ERROR; + } + } + + range_min[0] = 1; + range_max[0] = 1; + range_min[1] = rmin; + range_max[1] = rmax; + type = cgi_datatype(ptset->data_type); + + to_HDF_ID(ptset->id, hid); + + cg_rw_t Data; + Data.u.rbuf = points; + return readwrite_data_parallel(hid, type, + 2, range_min, range_max, &Data, CG_PAR_READ); +} +/*---------------------------------------------------------*/ diff --git a/externals/cgns/pcgnslib.h b/externals/cgns/pcgnslib.h index 5f96aa6bb5e..542b0a73e2b 100644 --- a/externals/cgns/pcgnslib.h +++ b/externals/cgns/pcgnslib.h @@ -78,10 +78,10 @@ CGNSDLL int cgp_coord_general_read_data(int fn, int B, int Z, int C, const cgsize_t *m_rmin, const cgsize_t *m_rmax, void *coords); CGNSDLL int cgp_coord_multi_read_data(int fn, int B, int Z, int *C, const cgsize_t *rmin, const cgsize_t *rmax, - void *coordsX, void *coordsY, void *coordsZ); + int nsets, void **buf); CGNSDLL int cgp_coord_multi_write_data(int fn, int B, int Z, int *C, const cgsize_t *rmin, const cgsize_t *rmax, - const void *coordsX, const void *coordsY, const void *coordsZ); + int nsets, const void **buf); /*===== Unstructured Grid Prototypes =====*/ @@ -123,11 +123,12 @@ CGNSDLL int cgp_field_general_read_data(int fn, int B, int Z, int S, int F, int m_numdim, const cgsize_t *m_arg_dimvals, const cgsize_t *m_rmin, const cgsize_t *m_rmax, void *data); + CGNSDLL int cgp_field_multi_read_data(int fn, int B, int Z, int S, int *F, - const cgsize_t *rmin, const cgsize_t *rmax, int nsets, ...); + const cgsize_t *rmin, const cgsize_t *rmax, int nsets, void **buf); CGNSDLL int cgp_field_multi_write_data(int fn, int B, int Z, int S, int *F, - const cgsize_t *rmin, const cgsize_t *rmax, int nsets, ...); + const cgsize_t *rmin, const cgsize_t *rmax, int nsets, const void **buf); /*===== Array IO Prototypes =====*/ @@ -150,10 +151,16 @@ CGNSDLL int cgp_array_general_read_data(int A, const cgsize_t *m_rmin, const cgsize_t *m_rmax, void *data); CGNSDLL int cgp_array_multi_write_data(int fn, int *A, const cgsize_t *rmin, - const cgsize_t *rmax, int nsets, ...); + const cgsize_t *rmax, int nsets, const void **buf); CGNSDLL int cgp_array_multi_read_data(int fn, int *A, const cgsize_t *rmin, - const cgsize_t *rmax, int nsets, ...); + const cgsize_t *rmax, int nsets, void **buf); + + +/*===== PointList Prototypes =====*/ +CGNSDLL int cgp_ptlist_write_data(int file_number, cgsize_t start, + cgsize_t end, const cgsize_t *points); +CGNSDLL int cgp_ptlist_read_data(int file_number, cgsize_t start, cgsize_t end, cgsize_t *points); /*===== exit with error and call MPI_Abort =====*/ diff --git a/externals/codi b/externals/codi index eee1b5eea2d..0ad036f2c82 160000 --- a/externals/codi +++ b/externals/codi @@ -1 +1 @@ -Subproject commit eee1b5eea2ded8126c34c1415e3b9cf15a3e70f2 +Subproject commit 0ad036f2c8254fa7b77180a443d99248c047c877 diff --git a/meson_scripts/init.py b/meson_scripts/init.py index 4ca1095e6e1..6bda759c734 100755 --- a/meson_scripts/init.py +++ b/meson_scripts/init.py @@ -55,7 +55,7 @@ def init_submodules( # This information of the modules is used if projects was not cloned using git # The sha tag must be maintained manually to point to the correct commit - sha_version_codi = "eee1b5eea2ded8126c34c1415e3b9cf15a3e70f2" + sha_version_codi = "0ad036f2c8254fa7b77180a443d99248c047c877" github_repo_codi = "https://github.com/scicompkl/CoDiPack" sha_version_medi = "aafc2d1966ba1233640af737e71c77c1a86183fd" github_repo_medi = "https://github.com/SciCompKL/MeDiPack"