5 double GetFunctionOrder(std::vector<double> &functionValues,std::vector<double> &independentVariable)
7 int numVals = independentVariable.size();
8 double f0 = functionValues[0];
9 double i0 = independentVariable[0];
10 double minorder = 10000.0000;
11 for(
int iVar = 1;iVar < numVals;iVar++){
12 double f1 = functionValues[iVar];
13 double i1 = independentVariable[iVar];
14 double order = std::log(f0/f1)/std::log(i0/i1);
16 if(order < minorder) minorder = order;
27 namespace dissipation {
32 if(interiorOrder == 2){
51 for(
int iStencil = 1;iStencil < stencilSet1.
numStencils;iStencil++)
98 for(
int iStencil = 1;iStencil < stencilSet2.
numStencils;iStencil++)
140 }
else if (interiorOrder == 4) {
159 for(
int iStencil = 1;iStencil < stencilSet1.
numStencils;iStencil++)
230 for(
int iStencil = 1;iStencil < stencilSet2.
numStencils;iStencil++)
337 }
else if (interiorOrder == 6) {
353 if(overallOrder == 2 ||
366 double boundaryWeight;
367 std::vector<double> centralWeightsRight;
368 std::vector<std::vector<double> > leftWeights;
369 std::vector<int> leftOrders;
371 if(interiorOrder == 2){
376 boundaryWeight = 2.0;
379 centralWeightsRight.resize(1,.5);
382 std::vector<double> leftwt(2,1.0);
384 leftWeights.push_back(leftwt);
387 leftOrders.resize(1,1);
389 }
else if(interiorOrder == 4) {
394 boundaryWeight = 48.0/17.0;
397 centralWeightsRight.resize(2,-1.0/12.0);
398 centralWeightsRight[0] *= -8.0;
401 leftWeights.resize(boundaryDepth);
402 double leftWeightsArr[4][6] =
404 {-24.0/17.0, 59.0/34.0 , -4.0/17.0 , -3.0/34.0, 0.0 , 0.0 },
405 {-.5 , 0.0 , .5 , 0.0 , 0.0 , 0.0 },
406 {4.0/43.0 , -59.0/86.0, 0.0 , 59.0/86.0, -4.0/43.0, 0.0 },
407 {3.0/98.0 , 0.0 , -59.0/98.0, 0.0 , 32.0/49.0, -4.0/49.0}
410 leftWeights.resize(boundaryDepth);
411 for (
int i=0; i < boundaryDepth; i++) {
412 leftWeights[i].resize(boundaryWidth);
413 for(
int j = 0;j < boundaryWidth;j++)
414 leftWeights[i][j] = leftWeightsArr[i][j];
418 leftOrders.resize(4,2);
420 }
else if(interiorOrder == 6) {
425 boundaryWeight = 43200.0/13649.0;
428 centralWeightsRight.resize(3);
429 centralWeightsRight[0] = 3.0/4.0;
430 centralWeightsRight[1] = -3.0/20.0;
431 centralWeightsRight[2] = 1.0/60.0;
434 double leftWeightsArr[6][9] =
436 {-21600.0/13649.0, 104009.0/54596.0, 30443.0/81894.0,
437 -33311.0/27298.0, 16863.0/27298.0, -15025.0/163788.0,
440 {-104009.0/240260.0, 0.0, -311.0/72078.0,
441 20229.0/24026.0, -24337.0/48052.0, 36661.0/360390.0,
444 {-30443.0/162660.0, 311.0/32532.0, 0.0,
445 -11155.0/16266.0, 41287.0/32532.0, -21999.0/54220.0,
448 {33311.0/107180.0, -20229.0/21436.0, 485.0/1398.0,
449 0.0, 4147.0/21436.0, 25427.0/321540.0,
450 72.0/5359.0, 0.0, 0.0},
452 {-16863.0/78770.0, 24337.0/31508.0, -41287.0/47262.0,
453 -4147.0/15754.0, 0.0, 342523.0/472620.0,
454 -1296.0/7877.0, 144.0/7877.0, 0.0},
456 {15025.0/525612.0, -36661.0/262806.0, 21999.0/87602.0,
457 -25427.0/262806.0, -342523.0/525612.0, 0.0,
458 32400.0/43801.0, -6480.0/43801.0, 720.0/43801.0}
461 leftWeights.resize(boundaryDepth);
462 for (
int i=0; i<boundaryDepth; i++) {
463 leftWeights[i].resize(boundaryWidth);
464 for(
int j = 0;j < boundaryWidth;j++)
465 leftWeights[i][j] = leftWeightsArr[i][j];
469 leftOrders.resize(6,3);
472 }
else if(interiorOrder == 8) {
475 std::cout <<
"Invalid interiorOrder " << interiorOrder
476 <<
" -- no such SBP operator!" << std::endl;
480 OperatorSetup(stencilSet, interiorOrder, boundaryDepth, boundaryWidth,
481 boundaryWeight, centralWeightsRight, leftWeights, leftOrders);
486 int boundaryWidth,
double boundaryWeight, std::vector<double> centralWeightsRight,
487 std::vector<std::vector<double> > leftWeights, std::vector<int> leftOrders) {
539 std::vector<double> stencilWeightsLeft;
540 std::vector<int> stencilOffsetsLeft;
542 for (
int iStencil=0; iStencil<stencilSet.
boundaryDepth; iStencil++) {
546 if (std::abs(leftWeights[iStencil][i]) > 0.0) {
547 stencilOffsetsLeft.push_back(i-iStencil);
548 stencilWeightsLeft.push_back(leftWeights[iStencil][i]);
573 for(
int iStencil = 1;iStencil < stencilSet.
numStencils;iStencil++){
584 for (
int i=1; i<=interiorOrder/2; i++) {
585 int il = interiorOrder/2 - i;
586 int ir = i-1 + interiorOrder/2;
598 for (
int i=0; i<stencilOffsetsLeft.size(); i++) {
599 stencilSet.
stencilOffsets[i+interiorOrder] = stencilOffsetsLeft[i];
600 stencilSet.
stencilWeights[i+interiorOrder] = stencilWeightsLeft[i];
612 for (
int jl=jls; jl<jle; jl++) {
613 int jr = jrs + (jle-1 - jl);
626 int numComponents,
int numTrials, std::vector<bool> &testResults)
639 testResults.resize(2*numDim*numStencils,
true);
641 size_t *numX =
new size_t [numDim];
642 double *deltaX =
new double [numDim];
647 double *inputData = NULL;
648 double *opData = NULL;
649 double *analyticData = NULL;
655 double baseLen = 1.0;
664 double epsOrder = 0.1;
665 double epsError = 1e-14;
667 for (
int iStencil=0; iStencil<
numStencils; iStencil++) {
673 if (iStencil == 0) shift = boundaryDepth;
674 else if (iStencil <= boundaryDepth) shift = iStencil-1;
675 else shift = baseNum - (iStencil-boundaryDepth-1);
680 for (
int iOrder=0; iOrder<=expOrder; iOrder++) {
684 std::vector<double> trialSpacing(numTrials,0.0);
686 std::vector<double> trialError(numTrials,0.0);
689 double len = baseLen;
692 for(
int iTrial = 0; iTrial < numTrials; iTrial++){
700 for(
int iDim = 0; iDim < numDim; iDim++){
701 numX[iDim] = baseNum;
704 deltaX[iDim] = len/(numX[iDim]-1);
705 trialSpacing[iTrial] = deltaX[iDim];
707 deltaX[iDim] = baseLen/(numX[iDim]-1);
710 numPoints *= numX[iDim];
713 opInterval[2*iDim] = 1;
714 opInterval[2*iDim+1] = numX[iDim];
719 if (iTrial > 0) x0 += shift*deltaX[
opDir];
737 size_t dirIndex[3] = {0,0,0};
738 size_t numIndex[3] = {1,1,1};
739 for (
int iDim=0; iDim<numDim; iDim++) numIndex[iDim] = numX[iDim];
741 for (dirIndex[2]=0; dirIndex[2]<numIndex[2]; dirIndex[2]++) {
745 size_t zIndex = dirIndex[2]*numIndex[0]*numIndex[1];
747 for (dirIndex[1]=0; dirIndex[1]<numIndex[1]; dirIndex[1]++) {
750 size_t yzIndex = zIndex + dirIndex[1]*numIndex[0];
752 for (dirIndex[0]=0; dirIndex[0]<numIndex[0]; dirIndex[0]++) {
753 size_t iPoint = yzIndex + dirIndex[0];
755 double xCurr = x0 + dirIndex[
opDir]*deltaX[
opDir];
758 inputData[iPoint] = std::pow(xCurr,static_cast<double>(iOrder));
763 analyticData[iPoint] = deltaX[
opDir]*
static_cast<double>(iOrder)*std::pow(xCurr,static_cast<double>(iOrder-1));
769 int fortOpDir =
opDir+1;
775 &stencilID[
opDir*numPoints],inputData,opData);
779 bool storeError =
true;
781 for(
size_t iPoint=0; iPoint<
numPoints; iPoint++) {
784 if (stencilIndex != iStencil)
continue;
786 double error = std::abs(opData[iPoint] - analyticData[iPoint]);
795 if (expOrder == iOrder && storeError) {
796 trialError[iTrial] = error;
805 if (iOrder < expOrder) {
809 testResults[stencilIndex*numDim*2 +
opDir*2] = testResults[stencilIndex*numDim*2 +
opDir*2] && (error < epsError);
816 delete [] analyticData;
821 if(expOrder == iOrder) {
827 testResults[iStencil*numDim*2 +
opDir*2 + 1] = (actualOrder + epsOrder > expOrder);
846 for(
int iDim = 0;iDim < numDim;iDim++)
847 numPoints *= dimSizes[iDim];
851 size_t xSize = dimSizes[0];
852 size_t ySize = dimSizes[1];
853 size_t zSize = dimSizes[2];
854 size_t plane = xSize*ySize;
855 size_t xStart = opInterval[0];
856 size_t xEnd = opInterval[1];
857 size_t yStart = opInterval[2];
858 size_t yEnd = opInterval[3];
859 size_t zStart = opInterval[4];
860 size_t zEnd = opInterval[5];
869 for(
size_t iZ = zStart;iZ <= zEnd;iZ++){
870 size_t iPointZ = iZ*plane;
871 size_t rightBoundaryZone = zSize - boundaryDepth;
873 if(iZ < boundaryDepth){
876 if (iZ >= rightBoundaryZone) {
879 zStencil = boundaryDepth+1+zSize-iZ;
881 for(
size_t iY = yStart;iY <= yEnd;iY++){
882 size_t iPointYZ = iPointZ + iY*xSize;
883 size_t rightBoundaryZone = ySize - boundaryDepth;
885 if(iY < boundaryDepth){
888 if (iY >= rightBoundaryZone) {
891 yStencil = boundaryDepth+1+ySize-iY;
893 for(
size_t iX = xStart;iX <= xEnd;iX++){
894 size_t iPoint = iPointYZ + iX;
895 size_t rightBoundaryZone = xSize - boundaryDepth;
896 stencilID[iPoint] = 1;
897 if(iX < boundaryDepth){
898 stencilID[iPoint] = 2+iX;
900 if (iX >= rightBoundaryZone){
901 stencilID[iPoint] = boundaryDepth+1+xSize-iX;
903 stencilID[numPoints+iPoint] = yStencil;
904 stencilID[2*numPoints+iPoint] = zStencil;
908 }
else if (numDim == 2) {
909 size_t xSize = dimSizes[0];
910 size_t ySize = dimSizes[1];
911 size_t xStart = opInterval[0];
912 size_t xEnd = opInterval[1];
913 size_t yStart = opInterval[2];
914 size_t yEnd = opInterval[3];
921 for(
size_t iY = yStart;iY <= yEnd;iY++){
922 size_t iPointY = iY*xSize;
923 size_t rightBoundaryZone = ySize - boundaryDepth;
925 if(iY < boundaryDepth){
928 if (iY >= rightBoundaryZone) {
929 yStencil = boundaryDepth+1+ySize-iY;
931 for(
size_t iX = xStart;iX <= xEnd;iX++){
932 size_t iPoint = iPointY + iX;
933 size_t rightBoundaryZone = xSize - boundaryDepth;
934 stencilID[iPoint] = 1;
935 if(iX < boundaryDepth){
936 stencilID[iPoint] = 2 + iX;
938 if (iX >= rightBoundaryZone){
939 stencilID[iPoint] = boundaryDepth+1+xSize-iX;
941 stencilID[numPoints+iPoint] = yStencil;
944 }
else if (numDim == 1) {
945 size_t xSize = dimSizes[0];
946 size_t xStart = opInterval[0];
947 size_t xEnd = opInterval[1];
952 for(
size_t iX = xStart;iX <= xEnd;iX++){
954 size_t rightBoundaryZone = xSize - boundaryDepth;
955 stencilID[iPoint] = 1;
956 if(iX < boundaryDepth){
957 stencilID[iPoint] = 2 + iX;
959 if (iX >= rightBoundaryZone){
960 stencilID[iPoint] = boundaryDepth+1+xSize-iX;
969 int *periodicDirs,
int *
stencilID,
bool fortranInterval)
976 for(
int iDim = 0;iDim < numDim;iDim++)
977 numPoints *= dimSizes[iDim];
981 size_t xSize = dimSizes[0];
982 size_t ySize = dimSizes[1];
983 size_t zSize = dimSizes[2];
984 size_t plane = xSize*ySize;
986 size_t xStart = opInterval[0];
987 size_t xEnd = opInterval[1];
988 size_t yStart = opInterval[2];
989 size_t yEnd = opInterval[3];
990 size_t zStart = opInterval[4];
991 size_t zEnd = opInterval[5];
1002 for(
size_t iZ = zStart;iZ <= zEnd;iZ++){
1003 size_t iPointZ = iZ*plane;
1004 size_t rightBoundaryZone = zSize - boundaryDepth;
1007 if(iZ < boundaryDepth){
1010 if (iZ >= rightBoundaryZone) {
1013 zStencil = boundaryDepth+1+zSize-iZ;
1015 if(periodicDirs[2] > 0)
1017 for(
size_t iY = yStart;iY <= yEnd;iY++){
1018 size_t iPointYZ = iPointZ + iY*xSize;
1019 size_t rightBoundaryZone = ySize - boundaryDepth;
1021 if(iY < boundaryDepth){
1024 if (iY >= rightBoundaryZone) {
1027 yStencil = boundaryDepth+1+ySize-iY;
1029 if(periodicDirs[1] > 0)
1031 for(
size_t iX = xStart;iX <= xEnd;iX++){
1032 size_t iPoint = iPointYZ + iX;
1033 size_t rightBoundaryZone = xSize - boundaryDepth;
1034 stencilID[iPoint] = 1;
1035 if(iX < boundaryDepth){
1036 stencilID[iPoint] = 2+iX;
1038 if (iX >= rightBoundaryZone){
1039 stencilID[iPoint] = boundaryDepth+1+xSize-iX;
1041 if(periodicDirs[0] > 0)
1042 stencilID[iPoint] = 1;
1043 stencilID[numPoints+iPoint] = yStencil;
1044 stencilID[2*numPoints+iPoint] = zStencil;
1048 }
else if (numDim == 2) {
1049 size_t xSize = dimSizes[0];
1050 size_t ySize = dimSizes[1];
1051 size_t xStart = opInterval[0];
1052 size_t xEnd = opInterval[1];
1053 size_t yStart = opInterval[2];
1054 size_t yEnd = opInterval[3];
1055 if(fortranInterval){
1061 for(
size_t iY = yStart;iY <= yEnd;iY++){
1062 size_t iPointY = iY*xSize;
1063 size_t rightBoundaryZone = ySize - boundaryDepth;
1065 if(iY < boundaryDepth){
1068 if (iY >= rightBoundaryZone) {
1069 yStencil = boundaryDepth+1+ySize-iY;
1071 if(periodicDirs[1] > 0)
1073 for(
size_t iX = xStart;iX <= xEnd;iX++){
1074 size_t iPoint = iPointY + iX;
1075 size_t rightBoundaryZone = xSize - boundaryDepth;
1076 stencilID[iPoint] = 1;
1077 if(iX < boundaryDepth){
1078 stencilID[iPoint] = 2 + iX;
1080 if (iX >= rightBoundaryZone){
1081 stencilID[iPoint] = boundaryDepth+1+xSize-iX;
1083 if(periodicDirs[0] > 0)
1084 stencilID[iPoint] = 1;
1085 stencilID[numPoints+iPoint] = yStencil;
1088 }
else if (numDim == 1) {
1089 size_t xSize = dimSizes[0];
1090 size_t xStart = opInterval[0];
1091 size_t xEnd = opInterval[1];
1092 if(fortranInterval){
1096 for(
size_t iX = xStart;iX <= xEnd;iX++){
1098 size_t rightBoundaryZone = xSize - boundaryDepth;
1099 stencilID[iPoint] = 1;
1100 if(iX < boundaryDepth){
1101 stencilID[iPoint] = 2 + iX;
1103 if (iX >= rightBoundaryZone){
1104 stencilID[iPoint] = boundaryDepth+1+xSize-iX;
1106 if(periodicDirs[0] > 0)
1107 stencilID[iPoint] = 1;
1118 int boundaryDepth,
int boundaryDirection,
1119 int *stencilConnectivity)
1122 int numDim = bufferSizes.size();
1125 for(
int iDim = 0;iDim < numDim;iDim++)
1126 numPointsBuffer *= bufferSizes[iDim];
1127 if(numPointsBuffer == 0)
1130 if(boundaryInterval.
NNodes() == 0)
1134 int normalDimension = std::abs(boundaryDirection)-1;
1137 assert(boundaryInterval[normalDimension].first == boundaryInterval[normalDimension].second);
1145 if(boundaryDirection > 0){
1146 boundaryZoneInterval[normalDimension].second += (boundaryDepth-1);
1148 boundaryZoneInterval[normalDimension].first -= (boundaryDepth-1);
1157 partitionInterval.
Overlap(boundaryZoneInterval,overlapInterval);
1160 if(overlapInterval.
NNodes() == 0)
1172 int *connectivityPtr = &stencilConnectivity[connectivityOffset];
1175 int firstStencil = 2;
1176 if(boundaryDirection > 0){
1178 int boundaryDistance = overlapInterval[normalDimension].first -
1179 boundaryInterval[normalDimension].first;
1180 firstStencil = 2 + boundaryDistance;
1182 int boundaryDistance = boundaryInterval[normalDimension].second -
1183 overlapInterval[normalDimension].first;
1184 firstStencil = (boundaryDepth + 2) + boundaryDistance;
1190 for(
int iDim = 0;iDim < numDim;iDim++){
1191 overlapBufferInterval[iDim].first -= partitionInterval[iDim].first;
1192 overlapBufferInterval[iDim].second -= partitionInterval[iDim].first;
1194 overlapBufferInterval[iDim].first += partitionBufferInterval[iDim].first;
1195 overlapBufferInterval[iDim].second += partitionBufferInterval[iDim].first;
1205 int currentStencil = firstStencil;
1206 int stencilIncrement = 1;
1207 if(boundaryDirection < 0)
1208 stencilIncrement = -1;
1209 for(
size_t iLayer = overlapBufferInterval[normalDimension].first;
1210 iLayer <= overlapBufferInterval[normalDimension].second;iLayer++){
1212 layerInterval[normalDimension].first = iLayer;
1213 layerInterval[normalDimension].second = iLayer;
1214 std::vector<size_t> layerIndices;
1216 std::vector<size_t>::iterator bufferIt = layerIndices.begin();
1217 while(bufferIt != layerIndices.end())
1218 connectivityPtr[*bufferIt++] = currentStencil;
1219 currentStencil += stencilIncrement;
1235 int *stencilConnectivity)
1240 int numDim = bufferSizes.size();
1243 for(
int iDim = 0;iDim < numDim;iDim++)
1244 numPointsBuffer *= bufferSizes[iDim];
1245 if(numPointsBuffer == 0)
1248 if(holeInterval.
NNodes() == 0)
1253 partitionInterval.
Overlap(holeInterval,overlapInterval);
1256 if(overlapInterval.
NNodes() == 0){
1266 for(
int iDim = 0;iDim < numDim;iDim++){
1267 overlapBufferInterval[iDim].first -= partitionInterval[iDim].first;
1268 overlapBufferInterval[iDim].second -= partitionInterval[iDim].first;
1270 overlapBufferInterval[iDim].first += partitionBufferInterval[iDim].first;
1271 overlapBufferInterval[iDim].second += partitionBufferInterval[iDim].first;
1279 std::vector<size_t> bufferIndices;
1280 bufferInterval.
GetFlatIndices(overlapBufferInterval,bufferIndices);
1282 std::vector<size_t>::iterator bufferIt = bufferIndices.begin();
1283 while(bufferIt != bufferIndices.end()){
1284 size_t bufferIndex = *bufferIt++;
1285 for(
int iDim = 0;iDim < numDim;iDim++){
1286 stencilConnectivity[iDim*numPointsBuffer+bufferIndex] = holeStencil;
1295 for(
int iDim = 0;iDim < numDim;iDim++)
1296 retVal *= (opInterval[2*iDim+1] - opInterval[2*iDim] + 1);
1302 for(
int iDim = 0;iDim < numDim;iDim++)
1303 retVal *= dimSize[iDim];
1308 int boundaryDepth,
int boundaryStart,
int holeBit,
int *inMask,
int *
stencilID)
1311 for(
int iDim = 0;iDim < numDim;iDim++)
1312 numPoints *= dimSizes[iDim];
1321 if(overlapExtent.NNodes() == 0)
1323 int rightBoundaryStart = boundaryStart + boundaryDepth;
1325 for(
int sweepDir = 0;sweepDir < numDim;sweepDir++){
1326 size_t stencilOffset = sweepDir*
numPoints;
1327 int *stencilConn = &stencilID[stencilOffset];
1330 if(sweepInterval[sweepDir].first < boundaryDepth)
1331 sweepInterval[sweepDir].first = boundaryDepth;
1332 if(sweepInterval[sweepDir].second > (bufferExtent[sweepDir].second-boundaryDepth))
1333 sweepInterval[sweepDir].second = bufferExtent[sweepDir].second-boundaryDepth;
1334 if(sweepInterval[sweepDir].first > sweepInterval[sweepDir].second)
1337 size_t sweepOffset = 1;
1338 int offDir = sweepDir;
1340 sweepOffset *= dimSizes[offDir-1];
1345 std::vector<size_t> sweepIndices;
1349 std::vector<size_t>::iterator sweepIt = sweepIndices.begin();
1350 while(sweepIt != sweepIndices.end()){
1351 size_t sweepIndex = *sweepIt++;
1354 if(inMask[sweepIndex]&holeBit)
1357 if(inMask[sweepIndex-sweepOffset]&holeBit){
1359 for(
int iBoundary = 0;iBoundary < boundaryDepth;iBoundary++){
1360 size_t connIndex = sweepIndex + iBoundary*sweepOffset;
1361 if(stencilConn[connIndex] != 1)
1363 stencilConn[connIndex] = boundaryStart+iBoundary;
1367 if(inMask[sweepIndex+sweepOffset]&holeBit){
1369 for(
int iBoundary = 0;iBoundary < boundaryDepth;iBoundary++){
1370 size_t connIndex = sweepIndex - iBoundary*sweepOffset;
1371 if(stencilConn[connIndex] != 1)
1373 stencilConn[connIndex] = rightBoundaryStart+iBoundary;
1382 int boundaryDepth,
int boundaryStart,
int holeBit,
1387 for(
int iDim = 0;iDim < numDim;iDim++)
1388 numPoints *= dimSizes[iDim];
1395 int rightBoundaryStart = boundaryStart + boundaryDepth;
1397 for(
int sweepDir = 0;sweepDir < numDim;sweepDir++){
1398 size_t stencilOffset = sweepDir*
numPoints;
1399 int *stencilConn = &stencilID[stencilOffset];
1402 if(sweepInterval[sweepDir].first < boundaryDepth)
1403 sweepInterval[sweepDir].first = boundaryDepth;
1404 if(sweepInterval[sweepDir].second > (bufferExtent[sweepDir].second-boundaryDepth))
1405 sweepInterval[sweepDir].second = bufferExtent[sweepDir].second-boundaryDepth;
1406 if(sweepInterval[sweepDir].first > sweepInterval[sweepDir].second)
1409 size_t sweepOffset = 1;
1410 int offDir = sweepDir;
1412 sweepOffset *= dimSizes[offDir-1];
1417 std::vector<size_t> sweepIndices;
1421 std::vector<size_t>::iterator sweepIt = sweepIndices.begin();
1422 while(sweepIt != sweepIndices.end()){
1423 size_t sweepIndex = *sweepIt++;
1426 if(inMask[sweepIndex]&holeBit)
1429 if(inMask[sweepIndex-sweepOffset]&holeBit){
1431 for(
int iBoundary = 0;iBoundary < boundaryDepth;iBoundary++){
1432 size_t connIndex = sweepIndex + iBoundary*sweepOffset;
1433 if(stencilConn[connIndex] != 1)
1435 stencilConn[connIndex] = boundaryStart+iBoundary;
1439 if(inMask[sweepIndex+sweepOffset]&holeBit){
1441 for(
int iBoundary = 0;iBoundary < boundaryDepth;iBoundary++){
1442 size_t connIndex = sweepIndex - iBoundary*sweepOffset;
1443 if(stencilConn[connIndex] != 1)
1445 stencilConn[connIndex] = rightBoundaryStart+iBoundary;
1455 int boundaryDepth,
int holeBit,
int *inMask,
int *
stencilID)
1459 for(
int iDim = 0;iDim < numDim;iDim++)
1460 numPointsBuffer *= dimSizes[iDim];
1461 if(numPointsBuffer == 0)
1473 std::vector<size_t> nodeList;
1479 bool holeFound =
false;
1480 if(nodeList.size() > 0){
1484 for(std::vector<size_t>::iterator nodeIt = nodeList.begin();
1485 nodeIt != nodeList.end(); nodeIt++){
1486 size_t nodeId = *nodeIt;
1487 if(inMask[nodeId] & holeBit){
1489 for(
int iDim = 0;iDim < numDim;iDim++)
1490 stencilID[iDim*numPointsBuffer+nodeId] = holeStencil;
1495 std::vector<size_t>::iterator nodeIt = nodeList.begin();
1496 while(nodeIt != nodeList.end()){
1497 size_t nodeId = *nodeIt++;
1498 if(inMask[nodeId] & holeBit)
1501 bool leftBoundary =
false;
1502 bool rightBoundary =
false;
1504 for(
int iSearch = 1;((iSearch <= boundaryDepth));iSearch++){
1507 if(iSearch <= nodeId && !leftBoundary){
1508 size_t searchNodeId = nodeId - iSearch;
1509 if((inMask[searchNodeId] & holeBit)){
1510 if(rightBoundary)
return(1);
1511 stencilID[nodeId] = 2 + iSearch - 1;
1512 leftBoundary =
true;
1518 size_t searchNodeId = nodeId + iSearch;
1519 if((inMask[searchNodeId] & holeBit)){
1520 if(leftBoundary)
return(1);
1521 stencilID[nodeId] = 2 + boundaryDepth + iSearch - 1;
1522 rightBoundary =
true;
1527 if(((nodeId < boundaryDepth) && rightBoundary) ||
1528 ((nodeId > (dimSizes[0]-boundaryDepth)) && leftBoundary))
1534 }
else if(numDim == 2){
1536 size_t iStart = opInterval[0].first;
1537 size_t iEnd = opInterval[0].second;
1538 size_t jStart = opInterval[1].first;
1539 size_t jEnd = opInterval[1].second;
1541 for(
size_t jIndex = jStart;jIndex <= jEnd;jIndex++){
1542 size_t jOffset = jIndex*dimSizes[0];
1543 for(
size_t iIndex = iStart;iIndex <= iEnd;iIndex++){
1544 size_t nodeId = jOffset + iIndex;
1545 if(inMask[nodeId] & holeBit)
1548 std::vector<bool> leftBoundary(2,
false);
1549 std::vector<bool> rightBoundary(2,
false);
1551 for(
int iSearch = 1;((iSearch <= boundaryDepth));iSearch++){
1555 if(iSearch <= iIndex && !leftBoundary[0]){
1556 size_t iSearchIndex = iIndex - iSearch;
1557 size_t searchNodeId = jOffset + iSearchIndex;
1558 if(inMask[searchNodeId] & holeBit){
1559 if(rightBoundary[0])
return(1);
1560 stencilID[nodeId] = 2 + iSearch - 1;
1561 leftBoundary[0] =
true;
1566 if(((iSearch + iIndex) < dimSizes[0]) && !rightBoundary[0]){
1567 size_t iSearchIndex = iIndex + iSearch;
1568 size_t searchNodeId = jOffset + iSearchIndex;
1569 if(inMask[searchNodeId] & holeBit){
1570 if(leftBoundary[0])
return(1);
1571 stencilID[nodeId] = 2 + boundaryDepth + iSearch - 1;
1572 rightBoundary[0] =
true;
1577 if(((iIndex < boundaryDepth) && rightBoundary[0]) ||
1578 ((iIndex > (dimSizes[0]-boundaryDepth)) && leftBoundary[0]))
1583 if(iSearch <= jIndex && !leftBoundary[1]){
1584 size_t jSearchIndex = jIndex - iSearch;
1585 size_t searchNodeId = jSearchIndex*dimSizes[0] + iIndex;
1586 if(inMask[searchNodeId] & holeBit){
1587 if(rightBoundary[1])
return(1);
1588 stencilID[numPointsBuffer+nodeId] = 2 + iSearch - 1;
1589 leftBoundary[1] =
true;
1594 if(((iSearch + jIndex) < dimSizes[1]) && !rightBoundary[1]){
1595 size_t jSearchIndex = jIndex + iSearch;
1596 size_t searchNodeId = jSearchIndex*dimSizes[0] + iIndex;
1597 if(inMask[searchNodeId] & holeBit){
1598 if(leftBoundary[1])
return(1);
1599 stencilID[numPointsBuffer+nodeId] = 2 + boundaryDepth + iSearch - 1;
1600 rightBoundary[1] =
true;
1605 if(((jIndex < boundaryDepth) && rightBoundary[1]) ||
1606 ((jIndex > (dimSizes[1]-boundaryDepth)) && leftBoundary[1]))
1615 size_t iStart = opInterval[0].first;
1616 size_t iEnd = opInterval[0].second;
1617 size_t jStart = opInterval[1].first;
1618 size_t jEnd = opInterval[1].second;
1619 size_t kStart = opInterval[2].first;
1620 size_t kEnd = opInterval[2].second;
1621 size_t nX = dimSizes[0];
1622 size_t nPlane = nX*dimSizes[1];
1624 for(
size_t kIndex = kStart;kIndex <= kEnd;kIndex++){
1625 size_t kOffset = kIndex*nPlane;
1626 for(
size_t jIndex = jStart;jIndex <= jEnd;jIndex++){
1627 size_t jOffset = jIndex*nX;
1628 size_t jkOffset = jOffset+kOffset;
1629 for(
size_t iIndex = iStart;iIndex <= iEnd;iIndex++){
1631 size_t nodeId = jkOffset + iIndex;
1632 if(inMask[nodeId] & holeBit)
1635 std::vector<bool> leftBoundary(3,
false);
1636 std::vector<bool> rightBoundary(3,
false);
1639 for(
int iSearch = 1;((iSearch <= boundaryDepth));iSearch++){
1643 if(iSearch <= iIndex && !leftBoundary[0]){
1644 size_t iSearchIndex = iIndex - iSearch;
1645 size_t searchNodeId = jkOffset + iSearchIndex;
1646 if(inMask[searchNodeId] & holeBit){
1647 if(rightBoundary[0])
return(1);
1648 stencilID[nodeId] = 2 + iSearch - 1;
1649 leftBoundary[0] =
true;
1654 if(((iSearch + iIndex) < dimSizes[0]) && !rightBoundary[0]){
1655 size_t iSearchIndex = iIndex + iSearch;
1656 size_t searchNodeId = jkOffset + iSearchIndex;
1657 if(inMask[searchNodeId] & holeBit){
1658 if(leftBoundary[0])
return(1);
1659 stencilID[nodeId] = 2 + boundaryDepth + iSearch - 1;
1660 rightBoundary[0] =
true;
1665 if(((iIndex < boundaryDepth) && rightBoundary[0]) ||
1666 ((iIndex > (dimSizes[0]-boundaryDepth)) && leftBoundary[0]))
1671 if(iSearch <= jIndex && !leftBoundary[1]){
1672 size_t jSearchIndex = jIndex - iSearch;
1673 size_t searchNodeId = jSearchIndex*nX + kOffset + iIndex;
1674 if(inMask[searchNodeId] & holeBit){
1675 if(rightBoundary[1])
return(1);
1676 stencilID[numPointsBuffer+nodeId] = 2 + iSearch - 1;
1677 leftBoundary[1] =
true;
1682 if(((iSearch + jIndex) < dimSizes[1]) && !rightBoundary[1]){
1683 size_t jSearchIndex = jIndex + iSearch;
1684 size_t searchNodeId = jSearchIndex*nX + kOffset + iIndex;
1685 if(inMask[searchNodeId] & holeBit){
1686 if(leftBoundary[1])
return(1);
1687 stencilID[numPointsBuffer+nodeId] = 2 + boundaryDepth + iSearch - 1;
1688 rightBoundary[1] =
true;
1693 if(((jIndex < boundaryDepth) && rightBoundary[1]) ||
1694 ((jIndex > (dimSizes[1]-boundaryDepth)) && leftBoundary[1]))
1699 if(iSearch <= kIndex && !leftBoundary[2]){
1700 size_t kSearchIndex = kIndex - iSearch;
1701 size_t searchNodeId = kSearchIndex*nPlane + jOffset + iIndex;
1702 if(inMask[searchNodeId] & holeBit){
1703 if(rightBoundary[2])
return(1);
1704 stencilID[2*numPointsBuffer+nodeId] = 2 + iSearch - 1;
1705 leftBoundary[2] =
true;
1710 if(((iSearch + kIndex) < dimSizes[2]) && !rightBoundary[2]){
1711 size_t kSearchIndex = kIndex + iSearch;
1712 size_t searchNodeId = kSearchIndex*nPlane + jOffset + iIndex;
1713 if(inMask[searchNodeId] & holeBit){
1714 if(leftBoundary[2])
return(1);
1715 stencilID[2*numPointsBuffer+nodeId] = 2 + boundaryDepth + iSearch - 1;
1716 rightBoundary[2] =
true;
1721 if(((kIndex < boundaryDepth) && rightBoundary[2]) ||
1722 ((kIndex > (dimSizes[2]-boundaryDepth)) && leftBoundary[2]))
1740 size_t *dualStencilConn,
size_t *numPointsStencil,
bool fortranInterval)
1743 size_t numPointsInterval =
IntervalSize(numDim,opInterval);
1746 if(fortranInterval){
1747 myInterval =
new size_t [2*numDim];
1748 for(
int iDim = 0;iDim < 2*numDim;iDim++){
1749 myInterval[iDim] = opInterval[iDim]-1;
1760 for(
int iStencil = 0;iStencil < numDim*
numStencils;iStencil++)
1761 numPointsStencil[iStencil] = 0;
1762 std::vector<std::list<size_t> > stencilPoints(numDim*numStencils);
1766 size_t xStart = myInterval[0];
1767 size_t xEnd = myInterval[1];
1768 size_t yStart = myInterval[2];
1769 size_t yEnd = myInterval[3];
1770 size_t zStart = myInterval[4];
1771 size_t zEnd = myInterval[5];
1772 size_t plane = dimSizes[0]*dimSizes[1];
1774 for(
size_t iZ = zStart;iZ <= zEnd;iZ++){
1775 size_t zIndex = iZ*plane;
1776 for(
size_t iY = yStart;iY <= yEnd;iY++){
1777 size_t yzIndex = zIndex + iY*dimSizes[0];
1778 for(
size_t iX = xStart;iX <= xEnd;iX++){
1779 size_t iPoint = yzIndex + iX;
1781 int iStencilX = stencilID[iPoint];
1783 int iStencilZ = stencilID[iPoint+numPointsBuffer*2];
1785 numPointsStencil[iStencilX-1]++;
1786 numPointsStencil[iStencilY+numStencils-1]++;
1787 numPointsStencil[iStencilZ+2*numStencils-1]++;
1789 stencilPoints[iStencilX-1].push_back(iPoint);
1790 stencilPoints[numStencils+iStencilY-1].push_back(iPoint);
1791 stencilPoints[2*numStencils+iStencilZ-1].push_back(iPoint);
1795 }
else if (numDim == 2) {
1797 size_t xStart = myInterval[0];
1798 size_t xEnd = myInterval[1];
1799 size_t yStart = myInterval[2];
1800 size_t yEnd = myInterval[3];
1801 for(
size_t iY = yStart;iY <= yEnd;iY++){
1802 size_t yIndex = iY*dimSizes[0];
1803 for(
size_t iX = xStart;iX <= xEnd;iX++){
1804 size_t iPoint = yIndex + iX;
1806 int iStencilX = stencilID[iPoint];
1809 numPointsStencil[iStencilX-1]++;
1810 numPointsStencil[iStencilY+numStencils-1]++;
1812 stencilPoints[iStencilX-1].push_back(iPoint);
1813 stencilPoints[numStencils+iStencilY-1].push_back(iPoint);
1819 for(
int iDim = 0;iDim < numDim;iDim++){
1821 for(
int iStencil = 0;iStencil <
numStencils;iStencil++){
1822 std::list<size_t> &pointList(stencilPoints[iDim*numStencils+iStencil]);
1823 std::list<size_t>::iterator stencilPointIt = pointList.begin();
1824 while(stencilPointIt != pointList.end()){
1825 dualStencilConn[iDim*numPointsInterval+iPoint++] = *stencilPointIt++;
1830 if(fortranInterval){
1832 for(
size_t iPoint = 0;iPoint < numDim*numPointsInterval;iPoint++)
1833 dualStencilConn[iPoint]++;
1834 delete [] myInterval;
1847 void SetMask(
const std::vector<size_t> &opIndices,
int maskBits,
int *inMask)
1849 std::vector<size_t>::const_iterator bufferIt = opIndices.begin();
1850 while(bufferIt != opIndices.end()){
1851 size_t bufferIndex = *bufferIt++;
1852 inMask[bufferIndex] |= maskBits;
1858 int maskBits,
int *inMask)
1863 std::vector<size_t> opIndices;
1866 return(
SetMask(opIndices,maskBits,inMask));
1869 void UnSetMask(
const std::vector<size_t> &opIndices,
int maskBits,
int *inMask)
1871 std::vector<size_t>::const_iterator bufferIt = opIndices.begin();
1872 while(bufferIt != opIndices.end()){
1873 size_t bufferIndex = *bufferIt++;
1874 if(inMask[bufferIndex]&maskBits)
1875 inMask[bufferIndex] ^= maskBits;
1881 int maskBits,
int *inMask)
1886 std::vector<size_t> opIndices;
1889 return(
UnSetMask(opIndices,maskBits,inMask));
int InvertStencilConnectivity(int numDim, size_t *dimSizes, size_t *opInterval, int numStencils, int *stencilID, size_t *dualStencilConn, size_t *numPointsStencil, bool fortranInterval=false)
Inverts stencil connectivity to populate the so-called dual stencil connectivity
void GetFlatIndices(const sizeextent &extent, ContainerType &indices) const
int * stencilSizes
The number of weights for each stencil.
void const size_t * numPoints
void size_t int size_t int * opDir
subroutine applyoperator(numDim, dimSizes, numComponents, numPoints, opDir, opInterval, numStencils, stencilSizes, stencilStarts, numValues, stencilWeights, stencilOffsets, stencilID, U, dU)
applyoperator applies an operator specified as a stencil set to the provided state data ...
int BoundaryStencilConnectivity(std::vector< size_t > &bufferSizes, pcpp::IndexIntervalType &partitionInterval, pcpp::IndexIntervalType &partitionBufferInterval, pcpp::IndexIntervalType &boundaryInterval, int boundaryDepth, int boundaryDirection, int *stencilConnectivity)
Update a stencil connectivity with a boundary.
int * stencilStarts
The starting index into the stencilWeight and stencilOffset arrays for each stencil.
int * stencilOffsets
The offsets wrt the grid point at which the stencil is being applied.
size_t IntervalSize(int numDim, size_t *opInterval)
void const size_t const size_t const size_t * opInterval
int BruteTest1(base &inOperator, int interiorOrder, int numDim, int numComponents, int numTrials, std::vector< bool > &testResults)
Brute-force accuracy test for SBP operators.
size_t BufferSize(int numDim, size_t *dimSize)
void double double double double double double double *void const size_t * dimSizes
int DetectHoles(int numDim, size_t *dimSizes, size_t *opInterval, int boundaryDepth, int holeBit, int *inMask, int *stencilID)
Detect unstructured holes and set up boundary stencil id's accordingly.
int MaskStencilConnectivity(int numDim, size_t *dimSizes, size_t *opInterval, int boundaryDepth, int boundaryStart, int holeBit, int *inMask, int *stencilID)
int HoleStencilConnectivity(std::vector< size_t > &bufferSizes, pcpp::IndexIntervalType &partitionInterval, pcpp::IndexIntervalType &partitionBufferInterval, pcpp::IndexIntervalType &holeInterval, int holeStencil, int *stencilConnectivity)
Update a stencil connectivity with a hole.
void UnSetMask(const std::vector< size_t > &opIndices, int maskBits, int *inMask)
int Initialize(stencilset &stencilSet1, stencilset &stencilSet2, int interiorOrder)
void size_t int size_t int size_t int int int int double int int * stencilID
int * stencilOrders
Boundary weight needed by BC's.
int CreateStencilConnectivity(int numDim, size_t *dimSizes, size_t *opInterval, int boundaryDepth, int *stencilID, bool fortranInterval=false)
Creates simple stencil connectivity assuming all domain boundaries are physical boundaries.
Encapsulation for a collection of operator stencils.
int numValues
The total number of weights for all stencils (reqd for Fortran)
void Overlap(const sizeextent &inextent, sizeextent &outextent) const
void const size_t const size_t * bufferSizes
double GetFunctionOrder(std::vector< double > &functionValues, std::vector< double > &independentVariable)
void size_t int size_t int size_t int int int int double int int double double *void size_t int size_t int int int int int double int size_t size_t size_t double double *void size_t int size_t int size_t size_t int double int double double *void size_t size_t size_t * bufferInterval
void Destroy()
Destroy utility destroys the stencil set memory.
bool IsValidOrder(int overallOrder)
bool ownData
Indicates whether this data structure owns the stencil memory.
int boundaryWidth
Boundary width is the size of the on-boundary stencil.
double * stencilWeights
The stencil weights.
void size_t int size_t int size_t int * numStencils
int numStencils
The number of stencils (e.g. interior + boundary)
double boundaryWeight
The order of accuracy for each stencil.
Simple Block Structured Mesh object.
void size_t int * numComponents
void OperatorSetup(base &stencilSet, int interiorOrder, int boundaryDepth, int boundaryWidth, double boundaryWeight, std::vector< double > centralWeightsRight, std::vector< std::vector< double > > leftWeights, std::vector< int > leftOrders)
Setup the SBP operator given the appropriate coefficients – called from Initialize.
int boundaryDepth
Boundary depth is the number of biased boundary stencils for one boundary.
void SetMask(const std::vector< size_t > &opIndices, int maskBits, int *inMask)
int overallOrder
The overall order of the scheme this stencil implements.
void InitSimple(const ContainerType &inSize)
void const size_t * numPointsBuffer
void FC_MODULE(euler, flux1d, EULER, FLUX1D)(const int *numDim
int StructuredHole(int numDim, size_t *dimSizes, size_t *opInterval, size_t *holeInterval, int boundaryDepth, int boundaryStart, int holeBit, int *inMask, int *stencilID)