This repository has been archived on 2023-11-20. You can view files and clone it, but cannot push or open issues or pull requests.
foam-extend4.1-coherent-io/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/set.cpp
2010-08-25 22:42:57 +01:00

696 lines
16 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
/*
*****************************************************************
*****************************************************************
******* ********
****** Copyright (C) 1988-2008 Tecplot, Inc. *******
******* ********
*****************************************************************
*****************************************************************
*/
#define SETMODULE
#include "GLOBAL.h"
#include "TASSERT.h"
#include "Q_UNICODE.h"
#include "ALLOC.h"
#include "SET.h"
/* * SET FUNCTIONS * */
#if defined TECPLOTKERNEL
/* CORE SOURCE CODE REMOVED */
#if InitNumZones > InitNumVars
#else
#endif
#if ZoneExpansionFactor > VarExpansionFactor
#else
#endif
#else
#define SetInitSize (PadOut(1,SetBitSize))
#define SetExpansionFactor 2
#endif
using namespace tecplot::strutil;
/*
*/
Set_pa AllocSet(Boolean_t show_error_msg)
{
Set_pa Set = ALLOC_ITEM(struct _Set_a, "Set header");
if (Set)
{
Set->size = SetInitSize;
Set->data = ALLOC_ARRAY(SetInitSize / SetBitSize, SetData_t, "Set data");
if (Set->data == NULL)
DeallocSet(&Set);
else
ClearSet(Set);
}
if ((Set == NULL) && show_error_msg)
{
# if defined TECPLOTKERNEL
/* CORE SOURCE CODE REMOVED */
# else
fprintf(stderr, "Out of memory for sets");
# endif
}
return Set;
} /* AllocSet() */
/*
*/
void DeallocSet(Set_pa *Set)
{
if (Set && *Set)
{
if ((*Set)->data)
FREE_ARRAY((*Set)->data, "Set data");
FREE_ITEM(*Set, "Set header");
*Set = NULL;
}
} /* DeallocSet() */
/**
* This function adapts the DeallocSet function to work with the
* ArrayList's deallocation callback.
*/
Boolean_t SetItemDestructor(void *ItemRef,
ArbParam_t ClientData)
{
Set_pa *SetRef = (Set_pa *)ItemRef;
REQUIRE(VALID_REF(SetRef));
REQUIRE(VALID_REF(*SetRef) || *SetRef == NULL);
if (*SetRef != NULL)
DeallocSet(SetRef);
ENSURE(*SetRef == NULL);
return TRUE;
}
/*
*/
Boolean_t ExpandSet(Set_pa Set,
SetIndex_t max_val,
Boolean_t show_error_msg)
{
SetData_t *data;
long new_size;
REQUIRE(max_val >= 0);
if (!Set)
{
if (show_error_msg)
{
# if defined TECPLOTKERNEL
/* CORE SOURCE CODE REMOVED */
# else
fprintf(stderr, "Null Set expand");
# endif
}
return FALSE;
}
if (max_val <= Set->size)
return TRUE;
new_size = Set->size;
while (new_size < max_val)
new_size *= SetExpansionFactor;
new_size = PadOut(new_size, SetBitSize);
data = ALLOC_ARRAY(new_size / SetBitSize, SetData_t, "new Set data");
if (!data)
{
if (show_error_msg)
{
# if defined TECPLOTKERNEL
/* CORE SOURCE CODE REMOVED */
# else
fprintf(stderr, "Out of memory for sets");
# endif
}
return FALSE;
}
size_t old_set_size_in_bytes = sizeof(data[0]) * (Set->size / SetBitSize);
memcpy(data, Set->data, old_set_size_in_bytes);
size_t new_set_size_in_bytes = sizeof(data[0]) * (new_size / SetBitSize);
size_t numBytesToReset = new_set_size_in_bytes - old_set_size_in_bytes;
memset(((char*)data) + old_set_size_in_bytes, 0, numBytesToReset);
FREE_ARRAY(Set->data, "old Set data");
Set->data = data;
Set->size = new_size;
return TRUE;
} /* ExpandSet() */
/*
*/
Boolean_t CopySet(Set_pa dst,
Set_pa src,
Boolean_t show_error_msg)
{
if (dst && dst->data &&
src && src->data &&
ExpandSet(dst, src->size, show_error_msg))
{
SetIndex_t src_size_in_words = src->size / SetBitSize;
size_t numBytesToCopy = sizeof(dst->data[0]) * src_size_in_words;
memcpy(dst->data, src->data, numBytesToCopy);
SetIndex_t dst_size_in_words = dst->size / SetBitSize;
CHECK(dst_size_in_words>=src_size_in_words); // ...guaranteed by above ExpandSet() call
size_t numBytesToReset = sizeof(dst->data[0]) * (dst_size_in_words - src_size_in_words);
memset((char*)(dst->data + src_size_in_words), 0, numBytesToReset);
return TRUE;
}
else
return FALSE;
} /* CopySet() */
/*
*/
Boolean_t AppendSet(Set_pa dst,
Set_pa src,
Boolean_t show_error_msg)
{
if (dst && dst->data &&
src && src->data)
{
SetIndex_t member;
ForAllMembersInSet(member, src)
{
if (!AddToSet(dst, member, TRUE))
return FALSE;
}
return TRUE;
}
else
return FALSE;
} /* AppendSet() */
/*
*/
void ClearSet(Set_pa Set)
{
if (Set && Set->data)
memset(Set->data, 0, Set->size / SetBitSize * sizeof(Set->data[0]));
} /* ClearSet() */
#if defined USE_FUNCTIONS_FOR_SETS
/*
*/
Boolean_t AddToSet(Set_pa Set,
SetIndex_t member,
Boolean_t show_error_msg)
{
REQUIRE(member >= 0);
if (Set &&
Set->data &&
((member + 1 <= Set->size) || ExpandSet(Set, member + 1, show_error_msg)))
{
SetIndex_t word = member / SetBitSize;
SetData_t bit = (SetData_t)1 << (member % SetBitSize);
Set->data[word] |= bit;
return TRUE;
}
else
return FALSE;
} /* AddToSet() */
#endif
/*
*/
void RemoveFromSet(Set_pa Set,
SetIndex_t member)
{
REQUIRE(member >= 0);
if (Set && (member < Set->size) && Set->data)
{
SetIndex_t word = member / SetBitSize;
SetData_t bit = (SetData_t)1 << (member % SetBitSize);
Set->data[word] &= (((SetData_t) - 1) ^ bit);
}
} /* RemoveFromSet() */
/**
* Similar to RemoveFromSet except it shifts the Set.
*/
void DeleteSetMember(Set_pa Set,
SetIndex_t Member)
{
SetIndex_t LastMember;
REQUIRE(VALID_REF(Set));
REQUIRE(Member >= 0);
LastMember = GetPrevMember(Set, BAD_SET_VALUE);
if (Member <= LastMember)
{
ShiftSet(Set, Member + 1, LastMember, -1);
RemoveFromSet(Set, LastMember);
}
}
/**
* Similar to AddToSet except that if the new member is within the currently
* defined set the members are shifted accordingly.
*/
Boolean_t InsertSetMember(Set_pa Set,
SetIndex_t Member,
Boolean_t ShowErrMsg)
{
Boolean_t IsOk = TRUE;
SetIndex_t OrigLastMember;
REQUIRE(VALID_REF(Set));
/* first, determine if we need to shift the set */
OrigLastMember = GetPrevMember(Set, BAD_SET_VALUE);
if (Member <= OrigLastMember)
{
IsOk = ExpandSet(Set, (OrigLastMember + 1) + 1, ShowErrMsg);
ShiftSet(Set, Member, OrigLastMember, 1);
}
if (IsOk)
IsOk = AddToSet(Set, Member, ShowErrMsg);
ENSURE(VALID_BOOLEAN(IsOk));
return IsOk;
}
#if defined USE_FUNCTIONS_FOR_SETS
/*
*/
Boolean_t InSet(Set_pa Set,
SetIndex_t member)
{
/*
* Sometimes InSet is called with negative numbers. This is not correct, but
* its what we have to work with. Maybe some day, we can make this assertion.
REQUIRE(member>=0);
*/
if (Set && (0 <= member && member < Set->size))
{
SetIndex_t word = member / SetBitSize;
SetData_t bit = (SetData_t)1 << (member % SetBitSize);
return (Set->data[word]&bit) != 0;
}
else
return FALSE;
} /* InSet() */
#endif
/*
*/
Boolean_t IsEmpty(Set_pa Set)
{
if (Set && Set->data)
{
SetIndex_t set_size_in_words = Set->size / SetBitSize;
SetIndex_t word;
for (word = 0; word < set_size_in_words; word++)
if (Set->data[word] != 0)
return FALSE;
}
return TRUE;
} /* IsEmpty() */
/*
*/
Boolean_t HasVoids(Set_pa Set)
{
Boolean_t Result = FALSE;
SetIndex_t ContiguousMember = 0;
SetIndex_t Member = 0;
REQUIRE(VALID_REF(Set));
/* look for voids in the set */
ForAllMembersInSet(Member, Set)
{
if (Member == ContiguousMember)
{
ContiguousMember++;
}
else
{
Result = TRUE;
break;
}
}
ENSURE(VALID_BOOLEAN(Result));
return Result;
}
/*
*/
SetIndex_t MemberCount(Set_pa Set)
{
SetIndex_t count = 0;
if (Set && Set->data)
{
SetIndex_t set_size_in_words = Set->size / SetBitSize;
SetIndex_t word;
for (word = 0; word < set_size_in_words; word++)
{
SetData_t word_val = Set->data[word];
while (word_val)
{
if (word_val&1)
count++;
word_val = word_val >> 1;
}
}
}
return count;
} /* MemberCount() */
/*
*/
SetIndex_t GetNextMember(Set_pa Set,
SetIndex_t start_at)
{
SetIndex_t next_member = BAD_SET_VALUE;
if (Set && Set->data)
{
SetIndex_t set_size_in_words = Set->size / SetBitSize;
SetIndex_t word;
SetData_t word_val = 0;
int bit;
if (start_at == BAD_SET_VALUE)
{
word = 0;
bit = 0;
if (word < set_size_in_words)
word_val = Set->data[0];
}
else if (start_at + 1 < Set->size)
{
word = (start_at + 1) / SetBitSize;
bit = (start_at + 1) % SetBitSize;
if (word < set_size_in_words)
word_val = Set->data[word] >> bit;
}
else
{
return BAD_SET_VALUE;
}
while ((word < set_size_in_words) && (word_val == 0))
{
word++;
bit = 0;
if (word < set_size_in_words)
word_val = Set->data[word];
}
if (word < set_size_in_words)
{
while (!(word_val&1))
{
word_val >>= 1;
bit++;
}
next_member = word * SetBitSize + bit;
}
}
return next_member;
} /* GetNextMember() */
/*
*/
SetIndex_t GetPrevMember(Set_pa Set,
SetIndex_t start_at)
{
SetIndex_t next_member = BAD_SET_VALUE;
if (Set && Set->data)
{
SetIndex_t set_size_in_words = Set->size / SetBitSize;
SetIndex_t word;
SetData_t word_val = 0;
int bit;
if (start_at == BAD_SET_VALUE)
{
word = set_size_in_words - 1;
bit = SetBitSize - 1;
if (word >= 0)
word_val = Set->data[word];
}
else if (start_at > 0)
{
word = (start_at - 1) / SetBitSize;
bit = (start_at - 1) % SetBitSize;
if (word >= 0)
word_val = Set->data[word] << (SetBitSize - bit - 1);
}
else
{
return BAD_SET_VALUE;
}
while ((word >= 0) && (word_val == 0))
{
word--;
bit = SetBitSize - 1;
if (word >= 0)
word_val = Set->data[word] << (SetBitSize - bit - 1);
}
if (word >= 0)
{
while (!(word_val&SetLastBit))
{
word_val <<= 1;
bit--;
}
next_member = word * SetBitSize + bit;
}
}
return next_member;
} /* GetPrevMember() */
/*
*/
Boolean_t EqualSets(Set_pa set1,
Set_pa set2)
{
SetIndex_t set1_size_in_words,
set2_size_in_words,
min_set_size_in_words,
ii;
if (!set1 || !set2)
return FALSE;
set1_size_in_words = set1->size / SetBitSize;
set2_size_in_words = set2->size / SetBitSize;
min_set_size_in_words = MIN(set1_size_in_words, set2_size_in_words);
for (ii = 0; ii < min_set_size_in_words; ii++)
if (set1->data[ii] != set2->data[ii])
return FALSE;
for (ii = min_set_size_in_words; ii < set1_size_in_words; ii++)
if (set1->data[ii] != 0)
return FALSE;
for (ii = min_set_size_in_words; ii < set2_size_in_words; ii++)
if (set2->data[ii] != 0)
return FALSE;
return TRUE;
} /* EqualSets() */
Boolean_t IsSubSet(Set_pa childset,
Set_pa parentset)
{
SetIndex_t s;
ForAllMembersInSet(s, childset)
{
if (!InSet(parentset, s))
return (FALSE);
}
return (TRUE);
} /* IsSubSet() */
/*
* functions added 11/7 by byron. These are roughed in for now and could
* stand to be optimized later.....
*/
/*
* Return the number of members in a set that preceed a given member.
*/
SetIndex_t MemberOffset(Set_pa Set,
SetIndex_t Member)
{
SetIndex_t I;
SetIndex_t Offset = -1;
if (InSet(Set, Member))
{
for (I = 0; I <= Member; I++)
{
if (InSet(Set, I))
Offset++;
}
}
return (Offset);
}
/*
* Return the position in the set of the nth member of a set.
*/
SetIndex_t OffsetMember(Set_pa Set,
SetIndex_t Offset)
{
SetIndex_t I;
SetIndex_t Member = BAD_SET_VALUE;
for (I = 0; I <= Offset; I++)
{
Member = GetNextMember(Set, Member);
if (Member == BAD_SET_VALUE)
break;
}
return (Member);
}
Boolean_t CopySetMember(Set_pa DstSet,
SetIndex_t DstOffset,
Set_pa SrcSet,
SetIndex_t SrcOffset)
{
if (InSet(SrcSet, SrcOffset))
return (AddToSet(DstSet, DstOffset, TRUE));
else
RemoveFromSet(DstSet, DstOffset);
return (TRUE);
}
/*
* Initial:
* v---ShiftPos1 v--ShiftPos2
* +-------------------------------------+
* | | | | | | | |x| | | | | | | |x| | | |
* +-------------------------------------+
*
* Shift +2
* v---ShiftPos1 v--ShiftPos2
* +-------------------------------------+
* | | | | | | | | | |x| | | | | | | |x| |
* +-------------------------------------+
*
*
* Shift all bits between ShiftPos1 and ShiftPos2
* by ShiftAmount. The bits that the shift
* replaces fill in the hole left by the shift
*
*
*/
void ShiftSet(Set_pa Set,
SetIndex_t ShiftPos1,
SetIndex_t ShiftPos2,
SetIndex_t ShiftAmount)
{
Set_pa NewSet;
SetIndex_t DPos;
SetIndex_t SPos;
if ((Set == NULL) || (IsEmpty(Set)))
return;
NewSet = AllocSet(TRUE);
if (NewSet == NULL)
return;
if (!CopySet(NewSet, Set, TRUE))
return;
if (ShiftAmount < 0)
{
DPos = ShiftPos2;
SPos = ShiftPos1 - 1;
while (DPos > ShiftPos2 + ShiftAmount)
CopySetMember(NewSet, DPos--, Set, SPos--);
SPos = ShiftPos2;
while (SPos >= ShiftPos1)
CopySetMember(NewSet, DPos--, Set, SPos--);
}
else if (ShiftAmount > 0)
{
DPos = ShiftPos1;
SPos = ShiftPos2 + 1;
while (DPos < ShiftPos1 + ShiftAmount)
CopySetMember(NewSet, DPos++, Set, SPos++);
SPos = ShiftPos1;
while (SPos <= ShiftPos2)
CopySetMember(NewSet, DPos++, Set, SPos++);
}
CopySet(Set, NewSet, TRUE);
DeallocSet(&NewSet);
}