941 lines
40 KiB
C++
941 lines
40 KiB
C++
/*
|
|
* NOTICE and LICENSE for Tecplot Input/Output Library (TecIO) - OpenFOAM
|
|
*
|
|
* Copyright (C) 1988-2009 Tecplot, Inc. All rights reserved worldwide.
|
|
*
|
|
* Tecplot hereby grants OpenCFD limited authority to distribute without
|
|
* alteration the source code to the Tecplot Input/Output library, known
|
|
* as TecIO, as part of its distribution of OpenFOAM and the
|
|
* OpenFOAM_to_Tecplot converter. Users of this converter are also hereby
|
|
* granted access to the TecIO source code, and may redistribute it for the
|
|
* purpose of maintaining the converter. However, no authority is granted
|
|
* to alter the TecIO source code in any form or manner.
|
|
*
|
|
* This limited grant of distribution does not supersede Tecplot, Inc.'s
|
|
* copyright in TecIO. Contact Tecplot, Inc. for further information.
|
|
*
|
|
* Tecplot, Inc.
|
|
* 3535 Factoria Blvd, Ste. 550
|
|
* Bellevue, WA 98006, USA
|
|
* Phone: +1 425 653 1200
|
|
* http://www.tecplot.com/
|
|
*
|
|
*/
|
|
#include "stdafx.h"
|
|
#include "MASTER.h"
|
|
#define TECPLOTENGINEMODULE
|
|
/*
|
|
******************************************************************
|
|
******************************************************************
|
|
******* ********
|
|
****** (C) 1988-2008 Tecplot, Inc. *******
|
|
******* ********
|
|
******************************************************************
|
|
******************************************************************
|
|
*/
|
|
|
|
/*
|
|
* datautil.c:
|
|
*
|
|
* version 1.00 : 12/10/91 (cm) changes made for manual
|
|
* version 1.01 : 12/30/91 Get and ReturnHugeBlock are now ptr to function
|
|
* version 6.00 : 04/21/92 updated to match version 6 of tecplot.
|
|
* version 6.30 : 10/15/92 updated to match binary file version 6.3
|
|
* version 6.30a: 05/04/93 (cm) minor changes to prototypes
|
|
* version : 11/01/93 (cm) put in D4GW stuff
|
|
* version 6.30b: 12/27/93 (cm) fixed missing NumKPts in DumpZone
|
|
* version 6.30c: 12/27/93 (cm) put back in D4GW stuff
|
|
BEGIN CODELOG TECXXX
|
|
C 03/06/96 (BDP)
|
|
C Update to V7
|
|
C
|
|
C 03/14/97 (BDP)
|
|
C Added code to main tecplot source. Now can
|
|
C be built stand alone or added so TecUtil_ functions
|
|
C can access.
|
|
C 06/02/98 (bdp)
|
|
C v75 coding. Also removed Array of ZoneSpec_s
|
|
C structs in favor of zonenames, i,j,and k dimensions
|
|
C and zonetype array.
|
|
END CODELOG
|
|
*/
|
|
|
|
|
|
|
|
#include "GLOBAL.h"
|
|
#include "TASSERT.h"
|
|
#include "Q_UNICODE.h"
|
|
#include "SYSTEM.h"
|
|
#include "ALLOC.h"
|
|
#include "TECXXX.h"
|
|
#include "ARRLIST.h"
|
|
#include "SET.h"
|
|
#include "DATASET.h"
|
|
#include "FILESTREAM.h"
|
|
#if defined TECPLOTKERNEL
|
|
/* CORE SOURCE CODE REMOVED */
|
|
#endif
|
|
#include "DATAIO.h"
|
|
#include "DATAIO4.h"
|
|
#include "DATAUTIL.h"
|
|
#include "STRLIST.h"
|
|
#include "Q_MSG.h"
|
|
#if defined MAKEARCHIVE
|
|
#define INITMODULE
|
|
#endif
|
|
#include "INPUT.h"
|
|
|
|
using namespace tecplot::strutil;
|
|
|
|
#if defined MAKEARCHIVE
|
|
#define ANGLEEPSILON 1.0e-10
|
|
|
|
void InitInputSpecs(void)
|
|
{
|
|
LineThicknessInputSpec.Type = Input_Double;
|
|
LineThicknessInputSpec.Min = 0.000001;
|
|
LineThicknessInputSpec.Max = 1.0;
|
|
LineThicknessInputSpec.InterfaceAdjust.ScaleFact = 100.0;
|
|
LineThicknessInputSpec.SuffixModifier = NULL;
|
|
|
|
PatternLengthInputSpec.Type = Input_Double;
|
|
PatternLengthInputSpec.Min = 0.0001;
|
|
PatternLengthInputSpec.Max = 1.0;
|
|
PatternLengthInputSpec.InterfaceAdjust.ScaleFact = 100.0;
|
|
PatternLengthInputSpec.SuffixModifier = NULL;
|
|
|
|
TextBoxMarginInputSpec.Type = Input_Double;
|
|
TextBoxMarginInputSpec.Min = 0.0;
|
|
TextBoxMarginInputSpec.Max = 20.0;
|
|
TextBoxMarginInputSpec.InterfaceAdjust.ScaleFact = 100.0;
|
|
TextBoxMarginInputSpec.SuffixModifier = NULL;
|
|
|
|
TextLineSpacingInputSpec.Type = Input_Double;
|
|
TextLineSpacingInputSpec.Min = 0.0;
|
|
TextLineSpacingInputSpec.Max = 5.0;
|
|
TextLineSpacingInputSpec.InterfaceAdjust.ScaleFact = 1.0;
|
|
TextLineSpacingInputSpec.SuffixModifier = NULL;
|
|
|
|
|
|
ArrowheadSizeInputSpec.Type = Input_Double;
|
|
ArrowheadSizeInputSpec.Min = 0.0;
|
|
ArrowheadSizeInputSpec.Max = 0.5;
|
|
ArrowheadSizeInputSpec.InterfaceAdjust.ScaleFact = 100.0;
|
|
ArrowheadSizeInputSpec.SuffixModifier = NULL;
|
|
|
|
TextAngleInputSpec.Type = Input_Double;
|
|
TextAngleInputSpec.Min = -PI - ANGLEEPSILON;
|
|
TextAngleInputSpec.Max = PI + ANGLEEPSILON;
|
|
TextAngleInputSpec.InterfaceAdjust.ScaleFact = DEGPERRADIANS;
|
|
TextAngleInputSpec.SuffixModifier = NULL;
|
|
|
|
ArrowheadAngleInputSpec.Type = Input_Double;
|
|
ArrowheadAngleInputSpec.Min = 1.0 / DEGPERRADIANS - ANGLEEPSILON;
|
|
ArrowheadAngleInputSpec.Max = PIOVER2 + ANGLEEPSILON;
|
|
ArrowheadAngleInputSpec.InterfaceAdjust.ScaleFact = DEGPERRADIANS;
|
|
ArrowheadAngleInputSpec.SuffixModifier = NULL;
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
|
|
void LocalReadBlock(FileStream_s *FileStream,
|
|
double *CurVPtr,
|
|
FieldDataType_e FieldDataTypeInFile,
|
|
HgIndex_t NumValues,
|
|
Boolean_t *IsOk)
|
|
{
|
|
REQUIRE(VALID_REF(IsOk) && VALID_BOOLEAN(*IsOk));
|
|
REQUIRE(!(*IsOk) || VALID_REF(FileStream));
|
|
REQUIRE(!(*IsOk) || VALID_FIELD_DATA_TYPE(FieldDataTypeInFile));
|
|
|
|
if (*IsOk)
|
|
{
|
|
Boolean_t DoRead = (CurVPtr != NULL);
|
|
Boolean_t ReadByBlock = (FieldDataType_Double == FieldDataTypeInFile) || !DoRead;
|
|
if (ReadByBlock)
|
|
{
|
|
ReadPureBlock(FileStream,
|
|
DoRead,
|
|
(void *)CurVPtr,
|
|
FieldDataTypeInFile,
|
|
0,
|
|
NumValues,
|
|
IsOk);
|
|
}
|
|
else
|
|
{
|
|
LgIndex_t N;
|
|
for (N = 0; *IsOk && (N < NumValues); N++)
|
|
{
|
|
double D = GetNextValue(FileStream, FieldDataTypeInFile, -LARGEDOUBLE, LARGEDOUBLE, IsOk);
|
|
if (DoRead)
|
|
CurVPtr[N] = D;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
*
|
|
* NOTE: ReadTec only allocates space for NodeMap and VDataBase
|
|
* if RawDataSpaceAllocated == FALSE and GetHeaderInfoOnly
|
|
* is FALSE.
|
|
*
|
|
* Also note that all data read in by ReadTec is currently
|
|
* limited to be in double precision.
|
|
*
|
|
*/
|
|
|
|
|
|
Boolean_t STDCALL ReadTec(Boolean_t GetHeaderInfoOnly,
|
|
char *FName,
|
|
short *IVersion,
|
|
char **DataSetTitle,
|
|
EntIndex_t *NumZones,
|
|
EntIndex_t *NumVars,
|
|
StringList_pa *VarNames,
|
|
StringList_pa *ZoneNames,
|
|
LgIndex_t **NumPtsI,
|
|
LgIndex_t **NumPtsJ,
|
|
LgIndex_t **NumPtsK,
|
|
ZoneType_e **ZoneType,
|
|
StringList_pa *UserRec,
|
|
Boolean_t RawDataSpaceAllocated,
|
|
NodeMap_t ***NodeMap,
|
|
double ***VDataBase)
|
|
{
|
|
Boolean_t InputIsOk = FALSE;
|
|
ArrayList_pa ZoneSpecList = NULL;
|
|
LgIndex_t *FNNumBndryConns = NULL; /* [NumZones] */
|
|
FileStream_s *ReadTecFileStream = NULL;
|
|
Set_pa *IsVarCellCentered = NULL; /* [NumZones] */
|
|
|
|
REQUIRE(VALID_BOOLEAN(GetHeaderInfoOnly));
|
|
REQUIRE(VALID_NON_ZERO_LEN_STR(FName));
|
|
REQUIRE(VALID_REF(IVersion));
|
|
REQUIRE(VALID_REF(DataSetTitle) || DataSetTitle == NULL);
|
|
REQUIRE(VALID_REF(NumZones));
|
|
REQUIRE(VALID_REF(NumVars));
|
|
REQUIRE(VarNames == NULL || VALID_REF(VarNames));
|
|
REQUIRE(ZoneNames == NULL || VALID_REF(ZoneNames));
|
|
REQUIRE(NumPtsI == NULL || VALID_REF(NumPtsI));
|
|
REQUIRE(NumPtsJ == NULL || VALID_REF(NumPtsJ));
|
|
REQUIRE(NumPtsK == NULL || VALID_REF(NumPtsK));
|
|
REQUIRE(ZoneType == NULL || VALID_REF(ZoneType));
|
|
REQUIRE(UserRec == NULL || VALID_REF(UserRec));
|
|
REQUIRE(VALID_BOOLEAN(RawDataSpaceAllocated));
|
|
REQUIRE(IMPLICATION(!GetHeaderInfoOnly && RawDataSpaceAllocated,
|
|
VALID_REF(NodeMap) && VALID_REF(VDataBase)));
|
|
|
|
#if defined MAKEARCHIVE
|
|
InitInputSpecs();
|
|
#endif
|
|
|
|
InputIsOk = OpenBinaryFileAndCheckMagicNumber(&ReadTecFileStream,
|
|
FName,
|
|
0,
|
|
IVersion);
|
|
|
|
if (InputIsOk)
|
|
InputIsOk = ReadDataFileHeader(ReadTecFileStream,
|
|
*IVersion,
|
|
FALSE,
|
|
NumZones,
|
|
NumVars,
|
|
(SmInteger_t *)NULL,
|
|
DataSetTitle,
|
|
(Text_s **)NULL,
|
|
(Geom_s **)NULL,
|
|
(StringList_pa **)NULL,
|
|
UserRec,
|
|
(AuxData_pa *)NULL,
|
|
&IsVarCellCentered,
|
|
(Boolean_t *)NULL,
|
|
(Boolean_t *)NULL,
|
|
&ZoneSpecList,
|
|
VarNames,
|
|
(ArrayList_pa *)NULL,
|
|
(Set_pa *)NULL,
|
|
&FNNumBndryConns,
|
|
(DataFileType_e *)NULL);
|
|
|
|
|
|
|
|
if (InputIsOk)
|
|
{
|
|
if (*NumZones == 0)
|
|
*NumVars = 0;
|
|
else if (*IVersion > 112)
|
|
{
|
|
/*
|
|
* This may not be true but we put it hear to remind us to make
|
|
* updates to this code when we change the version number.
|
|
*/
|
|
ErrMsg(translate("ReadTec does not yet support version %d "
|
|
"Tecplot binary data files."), *IVersion);
|
|
InputIsOk = FALSE;
|
|
}
|
|
else if (!GetHeaderInfoOnly)
|
|
{
|
|
EntIndex_t Z;
|
|
for (Z = 0; Z < *NumZones && InputIsOk; Z++)
|
|
{
|
|
InputIsOk = (MemberCount(IsVarCellCentered[Z]) == 0);
|
|
if (!InputIsOk)
|
|
ErrMsg(translate("Cell centered data not supported by ReadTec."));
|
|
}
|
|
}
|
|
}
|
|
|
|
if (IsVarCellCentered != NULL)
|
|
{
|
|
EntIndex_t Z;
|
|
for (Z = 0; Z < *NumZones; Z++)
|
|
DeallocSet(&IsVarCellCentered[Z]);
|
|
FREE_ARRAY(IsVarCellCentered, "Array of IsVarCellCentered sets");
|
|
}
|
|
|
|
if (InputIsOk)
|
|
{
|
|
EntIndex_t Z;
|
|
/*
|
|
* Allocate space for the zone info pieces.
|
|
*/
|
|
if (ZoneNames)
|
|
*ZoneNames = StringListAlloc();
|
|
if (NumPtsI)
|
|
*NumPtsI = ALLOC_ARRAY(*NumZones, LgIndex_t, "numptsi");
|
|
if (NumPtsJ)
|
|
*NumPtsJ = ALLOC_ARRAY(*NumZones, LgIndex_t, "numptsj");
|
|
if (NumPtsK)
|
|
*NumPtsK = ALLOC_ARRAY(*NumZones, LgIndex_t, "numptsk");
|
|
if (ZoneType)
|
|
*ZoneType = ALLOC_ARRAY(*NumZones, ZoneType_e, "zonetype");
|
|
for (Z = 0; Z < *NumZones; Z++)
|
|
{
|
|
ZoneSpec_s *ZoneSpec = GetZoneSpec(ZoneSpecList, Z);
|
|
if (ZoneSpec != NULL)
|
|
{
|
|
if (ZoneNames && *ZoneNames)
|
|
StringListAppendString(*ZoneNames, ZoneSpec->Name);
|
|
|
|
if (NumPtsI && *NumPtsI)
|
|
(*NumPtsI)[Z] = ZoneSpec->NumPtsI;
|
|
|
|
if (NumPtsJ && *NumPtsJ)
|
|
(*NumPtsJ)[Z] = ZoneSpec->NumPtsJ;
|
|
|
|
if (NumPtsK && *NumPtsK)
|
|
(*NumPtsK)[Z] = ZoneSpec->NumPtsK;
|
|
|
|
if (ZoneType && *ZoneType)
|
|
(*ZoneType)[Z] = ZoneSpec->Type;
|
|
}
|
|
else
|
|
{
|
|
if (ZoneNames && *ZoneNames)
|
|
StringListAppendString(*ZoneNames, NULL);
|
|
|
|
if (NumPtsI && *NumPtsI)
|
|
(*NumPtsI)[Z] = 0;
|
|
|
|
if (NumPtsJ && *NumPtsJ)
|
|
(*NumPtsJ)[Z] = 0;
|
|
|
|
if (NumPtsK && *NumPtsK)
|
|
(*NumPtsK)[Z] = 0;
|
|
|
|
if (ZoneType && *ZoneType)
|
|
(*ZoneType)[Z] = ZoneType_Invalid;
|
|
}
|
|
}
|
|
}
|
|
if (!GetHeaderInfoOnly && InputIsOk && (*NumZones > 0))
|
|
{
|
|
EntIndex_t *VarSharesFromZone = NULL; /* [NumVars] */
|
|
Boolean_t *IsVarPassive = NULL; /* [NumVars] */
|
|
EntIndex_t *ConnectivitySharesFromZone = NULL; /* [NumZones] */
|
|
FieldDataType_e *VarType = NULL;
|
|
int CurZone;
|
|
int CurVar;
|
|
LgIndex_t NumIPts = 0;
|
|
LgIndex_t NumJPts = 0;
|
|
LgIndex_t NumKPts = 0;
|
|
LgIndex_t TotalNumPts;
|
|
LgIndex_t I, J;
|
|
|
|
if ((*NumZones > 0) && !RawDataSpaceAllocated)
|
|
{
|
|
*VDataBase = ALLOC_ARRAY(*NumZones * (*NumVars), double *, "vdatabase array");
|
|
if (*VDataBase == NULL)
|
|
{
|
|
ErrMsg(translate("Cannot allocate space for field data"));
|
|
InputIsOk = FALSE;
|
|
}
|
|
else
|
|
{
|
|
int I;
|
|
for (I = 0; I < *NumZones*(*NumVars); I++)
|
|
(*VDataBase)[I] = NULL;
|
|
}
|
|
|
|
if (InputIsOk)
|
|
{
|
|
*NodeMap = ALLOC_ARRAY(*NumZones, NodeMap_t *, "nodemap array");
|
|
if (*NodeMap == NULL)
|
|
{
|
|
ErrMsg(translate("Cannot allocate space for nodemap"));
|
|
InputIsOk = FALSE;
|
|
}
|
|
else
|
|
{
|
|
int I;
|
|
for (I = 0; I < *NumZones; I++)
|
|
(*NodeMap)[I] = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (InputIsOk)
|
|
{
|
|
VarType = ALLOC_ARRAY(*NumVars + 1, FieldDataType_e, "Var Type");
|
|
VarSharesFromZone = ALLOC_ARRAY(*NumVars + 1, EntIndex_t, "VarSharesFromZone");
|
|
IsVarPassive = ALLOC_ARRAY(*NumVars + 1, Boolean_t, "IsVarPassive");
|
|
|
|
ConnectivitySharesFromZone = ALLOC_ARRAY(*NumZones, EntIndex_t, "ConnectivitySharesFromZone");
|
|
InputIsOk = (VarType != NULL &&
|
|
VarSharesFromZone != NULL &&
|
|
IsVarPassive != NULL &&
|
|
ConnectivitySharesFromZone != NULL);
|
|
}
|
|
|
|
/* for each zone */
|
|
for (CurZone = 0; CurZone < *NumZones && InputIsOk; CurZone++)
|
|
{
|
|
double X1 = GetNextValue(ReadTecFileStream, FieldDataType_Float, 0.0, 1000.0, &InputIsOk);
|
|
if (InputIsOk && (X1 == ZoneMarker))
|
|
{
|
|
ZoneSpec_s *CurZoneSpec = GetZoneSpec(ZoneSpecList, CurZone);
|
|
Boolean_t ZoneIsFinite = (CurZoneSpec->Type != ZoneType_Ordered);
|
|
Boolean_t ZoneIsFEPoly = (CurZoneSpec->Type == ZoneType_FEPolygon ||
|
|
CurZoneSpec->Type == ZoneType_FEPolyhedron);
|
|
Boolean_t InBlockFormat = CurZoneSpec->ZoneLoadInfo.IsInBlockFormat;
|
|
for (J = 0; J < *NumVars; J++)
|
|
{
|
|
VarSharesFromZone[J] = -1; /* eumulate DupVar: no DupVar */
|
|
VarType[J] = FieldDataType_Float;
|
|
IsVarPassive[J] = FALSE;
|
|
}
|
|
|
|
/* dupvars */
|
|
if (*IVersion > 45 && *IVersion < 101 && InputIsOk)
|
|
{
|
|
EntIndex_t NumDupVars, ZZ;
|
|
|
|
NumDupVars = (EntIndex_t)GetIoFileInt(ReadTecFileStream, *IVersion, 0, (LgIndex_t) * NumVars, &InputIsOk);
|
|
for (J = 0; J < NumDupVars; J++)
|
|
{
|
|
ZZ = (EntIndex_t)GetIoFileInt(ReadTecFileStream, *IVersion, 0, *NumVars, &InputIsOk) - 1;
|
|
VarSharesFromZone[ZZ] = CurZone - 1; /* emulate DupVar: share from previous zone */
|
|
}
|
|
/* Can't duplicate from the first zone */
|
|
if ((NumDupVars > 0) && (CurZone == 0))
|
|
{
|
|
ErrMsg(translate("Cannot duplicate variables from the first zone since there are "
|
|
"no previous zones to duplicate from."));
|
|
InputIsOk = FALSE;
|
|
}
|
|
}
|
|
|
|
/* get the data type for each variable */
|
|
if (*IVersion >= 70 && InputIsOk)
|
|
{
|
|
for (J = 0; J < *NumVars; J++)
|
|
{
|
|
VarType[J] = (FieldDataType_e)GetIoFileInt(ReadTecFileStream, *IVersion,
|
|
0,
|
|
(LgIndex_t)FieldDataType_Bit,
|
|
&InputIsOk);
|
|
if (!InputIsOk)
|
|
{
|
|
ErrMsg(translate("Invalid data type - binary input file corrupted"));
|
|
InputIsOk = FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (InputIsOk)
|
|
{
|
|
NumIPts = CurZoneSpec->NumPtsI;
|
|
NumJPts = CurZoneSpec->NumPtsJ;
|
|
NumKPts = CurZoneSpec->NumPtsK;
|
|
}
|
|
|
|
if (ZoneIsFinite)
|
|
TotalNumPts = NumIPts;
|
|
else
|
|
TotalNumPts = (NumIPts * NumJPts * NumKPts);
|
|
|
|
for (CurVar = 0; CurVar < *NumVars && InputIsOk; CurVar++)
|
|
{
|
|
if (!RawDataSpaceAllocated && TotalNumPts >= 1)
|
|
{
|
|
/*
|
|
* The calling program did not allocate space for the
|
|
* data so do it here.
|
|
*/
|
|
(*VDataBase)[CurVar+CurZone*(*NumVars)] =
|
|
ALLOC_ARRAY(TotalNumPts, double, "raw data");
|
|
}
|
|
}
|
|
|
|
if (*IVersion >= 105 && InputIsOk)
|
|
{
|
|
/* passive variables */
|
|
if ((Boolean_t)GetIoFileInt(ReadTecFileStream, *IVersion, 0, 1, &InputIsOk) && InputIsOk)
|
|
{
|
|
for (CurVar = 0; CurVar < *NumVars && InputIsOk; CurVar++)
|
|
{
|
|
IsVarPassive[CurVar] = (Boolean_t)GetIoFileInt(ReadTecFileStream,
|
|
*IVersion,
|
|
0, 1, &InputIsOk);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (*IVersion >= 101 && InputIsOk)
|
|
{
|
|
/* variable sharing: equivalent to DupVar for ReadTec */
|
|
if ((Boolean_t)GetIoFileInt(ReadTecFileStream, *IVersion, 0, 1, &InputIsOk) && InputIsOk)
|
|
{
|
|
for (CurVar = 0; CurVar < *NumVars && InputIsOk; CurVar++)
|
|
{
|
|
EntIndex_t SharedZone = GetIoFileInt(ReadTecFileStream, *IVersion,
|
|
-1, MaxNumZonesOrVars - 1,
|
|
&InputIsOk);
|
|
if (SharedZone != -1 && InputIsOk)
|
|
VarSharesFromZone[CurVar] = SharedZone;
|
|
}
|
|
}
|
|
|
|
/* face neighbor or FE node connectivity sharing */
|
|
if (InputIsOk)
|
|
{
|
|
EntIndex_t SharedZone = GetIoFileInt(ReadTecFileStream, *IVersion,
|
|
-1, MaxNumZonesOrVars - 1,
|
|
&InputIsOk);
|
|
if (InputIsOk)
|
|
ConnectivitySharesFromZone[CurZone] = SharedZone;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Non-shared variable min/max (but not for Zombie zones).
|
|
*/
|
|
if (*IVersion >= 103 && InputIsOk)
|
|
{
|
|
for (CurVar = 0; CurVar < *NumVars && InputIsOk; CurVar++)
|
|
{
|
|
if (VarSharesFromZone[CurVar] == -1 && !IsVarPassive[CurVar])
|
|
{
|
|
/*
|
|
* Currently ReadTec doesn't do anything with the
|
|
* min/max values.
|
|
*/
|
|
GetNextValue(ReadTecFileStream, FieldDataType_Double,
|
|
-LARGEDOUBLE, LARGEDOUBLE,
|
|
&InputIsOk);
|
|
GetNextValue(ReadTecFileStream, FieldDataType_Double,
|
|
-LARGEDOUBLE, LARGEDOUBLE,
|
|
&InputIsOk);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (InBlockFormat)
|
|
{
|
|
CurVar = -1;
|
|
while (InputIsOk && ((CurVar + 1) < *NumVars))
|
|
{
|
|
CurVar++;
|
|
if ((CurVar < *NumVars) && (TotalNumPts > 0))
|
|
{
|
|
double *CurVPtr = (*VDataBase)[CurVar+CurZone*(*NumVars)];
|
|
J = 0;
|
|
if (VarSharesFromZone[CurVar] != -1)
|
|
{
|
|
LgIndex_t M;
|
|
EntIndex_t SourceZone = VarSharesFromZone[CurVar];
|
|
double *SourceVPtr = (*VDataBase)[CurVar+SourceZone*(*NumVars)];
|
|
for (M = 0; M < TotalNumPts; M++)
|
|
CurVPtr[M] = SourceVPtr[M];
|
|
}
|
|
else if (!IsVarPassive[CurVar])
|
|
{
|
|
LocalReadBlock(ReadTecFileStream,
|
|
CurVPtr,
|
|
VarType[CurVar],
|
|
TotalNumPts,
|
|
&InputIsOk);
|
|
}
|
|
}
|
|
}
|
|
if (!InputIsOk)
|
|
ErrMsg(translate("Invalid raw data section of binary file"));
|
|
}
|
|
else if (TotalNumPts > 0)
|
|
{
|
|
/*
|
|
* Zone is not empty and is in POINT format
|
|
*/
|
|
J = -1;
|
|
if (InputIsOk)
|
|
{
|
|
LgIndex_t N;
|
|
N = 0;
|
|
while (InputIsOk && (N < TotalNumPts))
|
|
{
|
|
EntIndex_t CurVar;
|
|
for (CurVar = 0; InputIsOk && (CurVar < *NumVars); CurVar++)
|
|
{
|
|
double *CurVPtr = (*VDataBase)[CurVar+CurZone*(*NumVars)];
|
|
if (VarSharesFromZone[CurVar] != -1)
|
|
{
|
|
EntIndex_t SourceZone = VarSharesFromZone[CurVar];
|
|
double *SourceVPtr = (*VDataBase)[CurVar+SourceZone*(*NumVars)];
|
|
CurVPtr[N] = SourceVPtr[N];
|
|
}
|
|
else if (!IsVarPassive[CurVar])
|
|
{
|
|
double D = GetNextValue(ReadTecFileStream,
|
|
VarType[CurVar],
|
|
-LARGEDOUBLE,
|
|
LARGEDOUBLE,
|
|
&InputIsOk);
|
|
|
|
if (InputIsOk && CurVPtr)
|
|
CurVPtr[N] = D;
|
|
}
|
|
}
|
|
|
|
if (!InputIsOk)
|
|
ErrMsg(translate("Binary datafile corrupted!"));
|
|
N++;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (InputIsOk && *IVersion < 101)
|
|
{
|
|
if (ZoneIsFinite)
|
|
{
|
|
/*
|
|
* Pre-version 101 had FE connectivity sharing,
|
|
* FECONNECT, information here.
|
|
*/
|
|
Boolean_t DupConnectivity;
|
|
if (*IVersion > 61)
|
|
DupConnectivity = GetIoFileInt(ReadTecFileStream, *IVersion, 0, 1, &InputIsOk);
|
|
else
|
|
DupConnectivity = FALSE;
|
|
|
|
if (DupConnectivity)
|
|
ConnectivitySharesFromZone[CurZone] = CurZone - 1; /* previous zone */
|
|
else
|
|
ConnectivitySharesFromZone[CurZone] = -1;
|
|
}
|
|
else
|
|
ConnectivitySharesFromZone[CurZone] = -1;
|
|
}
|
|
|
|
if (InputIsOk && ZoneIsFinite && !ZoneIsFEPoly)
|
|
{
|
|
Boolean_t SkipNodemap;
|
|
NodeMap_t *NM = NULL;
|
|
NodeMap_t *ONM = NULL;
|
|
/*
|
|
* Allocate the nodemap ptr if necessary Note that if
|
|
* RawDataSpaceAllocated is TRUE then (*NodeMap)[CurZone]
|
|
* can either contain a valid address (read the connectivity
|
|
* list) or be NULL (skip the list).
|
|
*/
|
|
if (!RawDataSpaceAllocated && NumKPts*NumJPts >= 1)
|
|
{
|
|
(*NodeMap)[CurZone] = ALLOC_ARRAY(NumKPts * NumJPts, NodeMap_t, "node map");
|
|
if ((*NodeMap)[CurZone] == NULL)
|
|
ErrMsg(translate("Cannot allocate space for connectivity list",
|
|
"See the Tecplot User's Manual for a definition of 'connectivity list'"));
|
|
}
|
|
|
|
if (InputIsOk)
|
|
NM = (*NodeMap)[CurZone];
|
|
|
|
SkipNodemap = (NM == NULL);
|
|
|
|
if (InputIsOk && ConnectivitySharesFromZone[CurZone] != -1)
|
|
{
|
|
EntIndex_t SourceZone = ConnectivitySharesFromZone[CurZone];
|
|
if (SourceZone >= CurZone)
|
|
{
|
|
ErrMsg(translate("Zone %d is attempting to share connectivity "
|
|
"with a zone that has not yet been loaded."),
|
|
CurZone + 1);
|
|
InputIsOk = FALSE;
|
|
}
|
|
else
|
|
{
|
|
ONM = (*NodeMap)[SourceZone];
|
|
if (ONM == NULL)
|
|
{
|
|
ErrMsg(translate("Zone %d is attempting to share connectivity "
|
|
"with a zone that is not finite element."),
|
|
CurZone + 1);
|
|
InputIsOk = FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (InputIsOk)
|
|
{
|
|
/* load the FE node connectivity */
|
|
for (J = 0; J < NumJPts; J++)
|
|
for (I = 0; I < NumKPts; I++)
|
|
{
|
|
LgIndex_t M;
|
|
LgIndex_t L = J * NumKPts + I;
|
|
if (ConnectivitySharesFromZone[CurZone] != -1)
|
|
M = ONM[L];
|
|
else
|
|
M = GetNextI(ReadTecFileStream, &InputIsOk) - 1;
|
|
if (!SkipNodemap)
|
|
NM[L] = M;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* skip over the face neighbor connectivity */
|
|
if (*IVersion >= 101 && InputIsOk)
|
|
{
|
|
EntIndex_t SharedZone = ConnectivitySharesFromZone[CurZone];
|
|
if (SharedZone == -1 && FNNumBndryConns[CurZone] != 0)
|
|
{
|
|
LgIndex_t Connection = 0;
|
|
while (Connection < FNNumBndryConns[CurZone] && InputIsOk)
|
|
{
|
|
/*
|
|
* Face neighbor connection have the following format for both
|
|
* ASCII and binary:
|
|
*
|
|
* FaceNeighborMode_LocalOneToOne 3 cz,fz,cz
|
|
* FaceNeighborMode_LocalOneToMany nz+4 cz,fz,oz,nz,cz1,cz2,...,czn
|
|
* FaceNeighborMode_GlobalOneToOne 4 cz,fz,ZZ,CZ
|
|
* FaceNeighborMode_GlobalOneToMany 2*nz+4 cz,fz,oz,nz,ZZ1,CZ1,ZZ2,CZ2,...,ZZn,CZn
|
|
*
|
|
* Where:
|
|
* cz = cell in current zone
|
|
* fz = face of cell in current zone
|
|
* oz = face obsuration flag (only applies to one-to-many):
|
|
* 0 = face partially obscured
|
|
* 1 = face entirely obscured
|
|
* nz = number of cell or zone/cell associations (only applies to one-to-many)
|
|
* ZZ = remote Zone
|
|
* CZ = cell in remote zone
|
|
*/
|
|
(void)GetNextI(ReadTecFileStream, &InputIsOk); /* read cz */
|
|
if (!InputIsOk)
|
|
ErrMsg(translate("Unexpected end-of-file while reading face neighbor data."));
|
|
|
|
(void)GetNextI(ReadTecFileStream, &InputIsOk); /* read fz */
|
|
|
|
if (InputIsOk)
|
|
{
|
|
/*
|
|
* read FaceNeighborMode_LocalOneToOne: cz ||
|
|
* FaceNeighborMode_LocalOneToMany: oz ||
|
|
* FaceNeighborMode_GlobalOneToOne: ZZ ||
|
|
* FaceNeighborMode_GlobalOneToMany: oz
|
|
*/
|
|
if (CurZoneSpec->FNMode == FaceNeighborMode_LocalOneToOne)
|
|
(void)GetNextI(ReadTecFileStream, &InputIsOk);
|
|
else if (CurZoneSpec->FNMode == FaceNeighborMode_LocalOneToMany)
|
|
(void)GetNextI(ReadTecFileStream, &InputIsOk);
|
|
else if (CurZoneSpec->FNMode == FaceNeighborMode_GlobalOneToOne)
|
|
(void)GetNextI(ReadTecFileStream, &InputIsOk);
|
|
else if (CurZoneSpec->FNMode == FaceNeighborMode_GlobalOneToMany)
|
|
(void)GetNextI(ReadTecFileStream, &InputIsOk);
|
|
else
|
|
CHECK(FALSE);
|
|
|
|
if (CurZoneSpec->FNMode != FaceNeighborMode_LocalOneToOne && InputIsOk)
|
|
{
|
|
LgIndex_t NumAssociations = 0;
|
|
/*
|
|
* read FaceNeighborMode_LocalOneToMany: nz ||
|
|
* FaceNeighborMode_GlobalOneToOne: CZ ||
|
|
* FaceNeighborMode_GlobalOneToMany: nz
|
|
*/
|
|
if (CurZoneSpec->FNMode == FaceNeighborMode_LocalOneToMany)
|
|
NumAssociations = GetNextI(ReadTecFileStream, &InputIsOk);
|
|
else if (CurZoneSpec->FNMode == FaceNeighborMode_GlobalOneToOne)
|
|
(void)GetNextI(ReadTecFileStream, &InputIsOk);
|
|
else if (CurZoneSpec->FNMode == FaceNeighborMode_GlobalOneToMany)
|
|
NumAssociations = GetNextI(ReadTecFileStream, &InputIsOk);
|
|
else
|
|
CHECK(FALSE);
|
|
|
|
if (CurZoneSpec->FNMode != FaceNeighborMode_GlobalOneToOne && InputIsOk)
|
|
{
|
|
LgIndex_t Assoc;
|
|
if (CurZoneSpec->FNMode == FaceNeighborMode_LocalOneToMany)
|
|
for (Assoc = 0; Assoc < NumAssociations && InputIsOk; Assoc++)
|
|
(void)GetNextI(ReadTecFileStream, &InputIsOk); /* read czn */
|
|
else if (CurZoneSpec->FNMode == FaceNeighborMode_GlobalOneToMany)
|
|
for (Assoc = 0; Assoc < NumAssociations && InputIsOk; Assoc++)
|
|
{
|
|
(void)GetNextI(ReadTecFileStream, &InputIsOk); /* read ZZn */
|
|
(void)GetNextI(ReadTecFileStream, &InputIsOk); /* read CZn */
|
|
}
|
|
else
|
|
CHECK(FALSE);
|
|
|
|
if (InputIsOk)
|
|
Connection += NumAssociations;
|
|
}
|
|
else if (InputIsOk) /* CurZoneSpec->FNMode == FaceNeighborMode_GlobalOneToOne */
|
|
Connection += 1;
|
|
}
|
|
else if (InputIsOk) /* CurZoneSpec->FNMode == FaceNeighborMode_LocalOneToOne */
|
|
Connection += 1;
|
|
|
|
if (!InputIsOk)
|
|
ErrMsg(translate("Corrupt input file: invalid face neighbors."));
|
|
}
|
|
}
|
|
}
|
|
}/* face neighbor connectivity */
|
|
/* skip over face map section */
|
|
if (ZoneIsFEPoly &&
|
|
*IVersion >= 110 &&
|
|
ConnectivitySharesFromZone[CurZone] != -1 &&
|
|
InputIsOk)
|
|
{
|
|
if (!InBlockFormat)
|
|
{
|
|
ErrMsg(translate("Poly zones must be in block format"));
|
|
InputIsOk = FALSE;
|
|
}
|
|
if (InputIsOk)
|
|
{
|
|
HgIndex_t NumFaces = CurZoneSpec->NumPtsK;
|
|
if (*IVersion == 110) // ...version 111 moved these to the zone header
|
|
{
|
|
CurZoneSpec->NumFaceNodes = GetNextI(ReadTecFileStream, &InputIsOk);
|
|
CurZoneSpec->NumFaceBndryFaces = GetNextI(ReadTecFileStream, &InputIsOk);
|
|
CurZoneSpec->NumFaceBndryItems = GetNextI(ReadTecFileStream, &InputIsOk);
|
|
}
|
|
HgIndex_t TotalNumFaceNodes = CurZoneSpec->NumFaceNodes;
|
|
HgIndex_t TotalNumBndryFaces = CurZoneSpec->NumFaceBndryFaces;
|
|
HgIndex_t TotalNumBndryItems = CurZoneSpec->NumFaceBndryItems;
|
|
if (CurZoneSpec->Type == ZoneType_FEPolyhedron)
|
|
ReadInt32Block(ReadTecFileStream, FALSE, NULL, 0, NumFaces + 1, &InputIsOk);
|
|
if (InputIsOk)
|
|
ReadInt32Block(ReadTecFileStream, FALSE, NULL, 0, TotalNumFaceNodes, &InputIsOk);
|
|
if (InputIsOk)
|
|
ReadInt32Block(ReadTecFileStream, FALSE, NULL, 0, NumFaces, &InputIsOk);
|
|
if (InputIsOk)
|
|
ReadInt32Block(ReadTecFileStream, FALSE, NULL, 0, NumFaces, &InputIsOk);
|
|
if (TotalNumBndryFaces > 0)
|
|
{
|
|
if (InputIsOk)
|
|
ReadInt32Block(ReadTecFileStream, FALSE, NULL, 0, TotalNumBndryFaces + 1, &InputIsOk);
|
|
if (InputIsOk)
|
|
ReadInt32Block(ReadTecFileStream, FALSE, NULL, 0, TotalNumBndryItems, &InputIsOk);
|
|
if (InputIsOk)
|
|
{
|
|
if (*IVersion >= 112)
|
|
ReadInt32Block(ReadTecFileStream, FALSE, NULL, 0, TotalNumBndryItems, &InputIsOk);
|
|
else
|
|
ReadInt16Block(ReadTecFileStream, FALSE, NULL, 0, TotalNumBndryItems, &InputIsOk);
|
|
}
|
|
}
|
|
}
|
|
}/* face map section */
|
|
}
|
|
else
|
|
{
|
|
ErrMsg(translate("Corrupt input file"));
|
|
InputIsOk = FALSE;
|
|
}
|
|
}
|
|
|
|
if (VarSharesFromZone)
|
|
FREE_ARRAY(VarSharesFromZone, "VarSharesFromZone");
|
|
if (IsVarPassive)
|
|
FREE_ARRAY(IsVarPassive, "IsVarPassive");
|
|
if (ConnectivitySharesFromZone)
|
|
FREE_ARRAY(ConnectivitySharesFromZone, "ConnectivitySharesFromZone");
|
|
if (VarType)
|
|
FREE_ARRAY(VarType, "VarType");
|
|
|
|
if (!InputIsOk && !RawDataSpaceAllocated)
|
|
{
|
|
int I;
|
|
if (*VDataBase)
|
|
{
|
|
for (I = 0; I < *NumZones*(*NumVars); I++)
|
|
{
|
|
if ((*VDataBase)[I])
|
|
FREE_ARRAY((*VDataBase)[I], "vdatabase array");
|
|
}
|
|
FREE_ARRAY(*VDataBase, "vdatabase pointer array");
|
|
}
|
|
|
|
|
|
if (*NodeMap)
|
|
{
|
|
for (I = 0; I < *NumZones; I++)
|
|
{
|
|
if ((*NodeMap)[I])
|
|
FREE_ARRAY((*NodeMap)[I], "connectivity list");
|
|
}
|
|
FREE_ARRAY(*NodeMap, "connectivity pointer array");
|
|
}
|
|
}
|
|
} /*Reading Raw Data*/
|
|
|
|
if (FNNumBndryConns != NULL)
|
|
FREE_ARRAY(FNNumBndryConns, "FNNumBndryConns");
|
|
if (ZoneSpecList)
|
|
ArrayListDealloc(&ZoneSpecList, ZoneSpecItemDestructor, 0);
|
|
|
|
if (ReadTecFileStream)
|
|
{
|
|
#if defined TECPLOTKERNEL
|
|
/* CORE SOURCE CODE REMOVED */
|
|
#else
|
|
TP_FCLOSE(ReadTecFileStream->File);
|
|
free(ReadTecFileStream);
|
|
#endif
|
|
}
|
|
return (InputIsOk);
|
|
}
|
|
|
|
|
|
void * STDCALL TecAlloc(size_t size)
|
|
{
|
|
return (void *)ALLOC_ARRAY(size, char, "TecAlloc");
|
|
}
|
|
|
|
void STDCALL TecFree(void *ptr)
|
|
{
|
|
/* Hack to remove delete warning... */
|
|
char *Tmp = (char *)ptr;
|
|
FREE_ARRAY(Tmp, "TecAlloc");
|
|
}
|
|
|
|
|