PHengLEI-NCCR/API/DataStruct/include/PHSlice.hxx

133 lines
4.9 KiB
C++
Raw Normal View History

2024-10-14 09:32:17 +08:00
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// PPPPP H H EEEEE N N GGGGG L EEEEE III +
// P P H H E NN N G L E I +
// PPPPP HHHHH EEEEE N N N G GG L EEEEE I +
// P H H E N N N G G L E I +
// P H H EEEEE N N GGGGG LLLLL EEEEE III +
//------------------------------------------------------------------------+
// Platform for Hybrid Engineering Simulation of Flows +
// China Aerodynamics Research and Development Center +
// (C) Copyright, Since 2010 +
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#pragma once
namespace PHSPACE
{
// This member template is also used in the implementation of
// operator() with any combination of int and Rank parameters.
// It's called by constructSlice(), above. This version handles
// Range parameters.
template < typename T, int N > template < int N2 >
void PHArray<T, N>::slice(int &setRank, Range r, PHArray<T, N2> &array_in, SimpleArray<int, N2> &rankMap, int sourceRank)
{
// NEEDS WORK: ordering will change completely when some ranks
// are deleted.
rankMap[sourceRank] = setRank;
length_[setRank] = array_in.length(sourceRank);
stride_[setRank] = array_in.stride(sourceRank);
storage_.setAscendingFlag(setRank, array_in.isRankStoredAscending(sourceRank));
storage_.setBase(setRank, array_in.base(sourceRank));
slice(setRank, r);
++ setRank;
}
// This member template is also used in the implementation of
// operator() with any combination of int and Rank parameters.
// It's called by constructSlice(), above. This version handles
// int parameters, which reduce the dimensionality by one.
template < typename T, int N > template <int N2 >
void PHArray<T, N>::slice(int &setRank, int i, PHArray<T, N2> &array_in, SimpleArray<int, N2> &rankMap, int sourceRank)
{
rankMap[sourceRank] = -1;
data_ += i * array_in.stride(sourceRank);
}
template < typename T, int N > template<int N2>
void PHArray<T, N>::slice(int &setRank, PHnilArraySection nil, PHArray<T, N2> &array_in, SimpleArray<int, N2> &rankMap, int sourceRank)
{ }
// This member template is used to implement operator() with any
// combination of int and Range parameters. There's room for up
// to 11 parameters, but any unused parameters have no effect.
template < typename T, int N > template < int N2, typename R0,
typename R1, typename R2, typename R3, typename R4, typename R5, typename R6, typename R7,
typename R8, typename R9, typename R10 >
void PHArray<T, N>::constructSlice(PHArray<T, N2> &array_in,
R0 r0, R1 r1, R2 r2, R3 r3, R4 r4, R5 r5, R6 r6, R7 r7, R8 r8, R9 r9, R10 r10)
{
MemoryBlockReference<T>::changeBlock(array_in);
int setRank = 0;
SimpleArray<int, N2> rankMap;
slice(setRank, r0 , array_in, rankMap, 0 );
slice(setRank, r1 , array_in, rankMap, 1 );
slice(setRank, r2 , array_in, rankMap, 2 );
slice(setRank, r3 , array_in, rankMap, 3 );
slice(setRank, r4 , array_in, rankMap, 4 );
slice(setRank, r5 , array_in, rankMap, 5 );
slice(setRank, r6 , array_in, rankMap, 6 );
slice(setRank, r7 , array_in, rankMap, 7 );
slice(setRank, r8 , array_in, rankMap, 8 );
slice(setRank, r9 , array_in, rankMap, 9 );
slice(setRank, r10, array_in, rankMap, 10);
// Redo the ordering_ array to account for dimensions which
// have been sliced away.
int j = 0;
for (int i = 0; i < N2; ++ i)
{
if (rankMap[array_in.ordering(i)] != -1)
{
storage_.setOrdering(j ++, rankMap[array_in.ordering(i)]);
}
}
calculateZeroOffset();
}
/*
* After calling slice(int rank, Range r), the array refers only to the
* Range r of the original array.
* e.g. Array<int,1> x(100);
* x.slice(firstRank, Range(25,50));
* x = 0; // Sets elements 25..50 of the original array to 0
*/
template<typename T, int N>
void PHArray<T, N>::slice(int rank, Range r)
{
int first = r.first(lbound(rank));
int last = r.last (ubound(rank));
int stride = r.stride();
// Will the storage be non-contiguous?
// (1) Slice in the minor dimension and the range does not span
// the entire index interval (NB: non-unit strides are possible)
// (2) Slice in a middle dimension and the range is not Range::all()
length_[rank] = (last - first) / stride + 1;
// TV 20000312: added second term here, for testsuite/Josef-Wagenhuber
int offset = (first - base(rank) * stride) * stride_[rank];
data_ += offset;
zeroOffset_ += offset;
stride_[rank] *= stride;
// JCC: adjust ascending flag if slicing with backwards Range
if (stride < 0)
{
storage_.setAscendingFlag(rank, !isRankStoredAscending(rank));
}
}
}