void Margolus::PrintParameters() const { cout << "\n------------------------------\n---Output field parameters:---\n------------------------------\n"; cout << "Size X:\t" << GetSizeX() << endl; cout << "Size Y:\t" << GetSizeY() << endl; cout << "Size Z:\t" << GetSizeZ() << endl; cout << "Temperature:\t" << *T << endl; cout << "Steam energy:\t" << *steamEnergy_ << endl; cout << "Substances count:\t" << subs.size() << endl; for (const pSub & sub : subs) { cout << sub->GetName() << "\t" << sub->GetFillCount() << endl; } cout << "Energy count:\t" << energy.size() << endl; for (const Energy & en : energy) { cout << en.name1 << "-" << en.name2 << " E=" << en.energy << " H=" << *en.energyH << " S=" << *en.energyS << endl; } cout << "Energy cell count:\t" << energyCell.size() << endl; for (const Energy & en : energyCell) { cout << en.name1 << "-" << en.name2 << " E=" << en.energy << " H=" << *en.energyH << " S=" << *en.energyS << endl; } cout << "------------------------------\n---Output field parameters:---\n------------------------------\n"; cout << "Press any key to continue ... \n"; string s; cin >> s; }
void cBlockArea::CropNibbles(NIBBLEARRAY & a_Array, int a_AddMinX, int a_SubMaxX, int a_AddMinY, int a_SubMaxY, int a_AddMinZ, int a_SubMaxZ) { int NewSizeX = GetSizeX() - a_AddMinX - a_SubMaxX; int NewSizeY = GetSizeY() - a_AddMinY - a_SubMaxY; int NewSizeZ = GetSizeZ() - a_AddMinZ - a_SubMaxZ; NIBBLETYPE * NewNibbles = new NIBBLETYPE[NewSizeX * NewSizeY * NewSizeZ]; int idx = 0; for (int y = 0; y < NewSizeY; y++) { for (int z = 0; z < NewSizeZ; z++) { for (int x = 0; x < NewSizeX; x++) { NewNibbles[idx++] = a_Array[MakeIndex(x + a_AddMinX, y + a_AddMinY, z + a_AddMinZ)]; } // for x } // for z } // for y delete a_Array; a_Array = NewNibbles; }
void cBlockArea::CropBlockTypes(int a_AddMinX, int a_SubMaxX, int a_AddMinY, int a_SubMaxY, int a_AddMinZ, int a_SubMaxZ) { int NewSizeX = GetSizeX() - a_AddMinX - a_SubMaxX; int NewSizeY = GetSizeY() - a_AddMinY - a_SubMaxY; int NewSizeZ = GetSizeZ() - a_AddMinZ - a_SubMaxZ; BLOCKTYPE * NewBlockTypes = new BLOCKTYPE[NewSizeX * NewSizeY * NewSizeZ]; int idx = 0; for (int y = 0; y < NewSizeY; y++) { for (int z = 0; z < NewSizeZ; z++) { for (int x = 0; x < NewSizeX; x++) { int OldIndex = MakeIndex(x + a_AddMinX, y + a_AddMinY, z + a_AddMinZ); NewBlockTypes[idx++] = m_BlockTypes[OldIndex]; } // for x } // for z } // for y delete m_BlockTypes; m_BlockTypes = NewBlockTypes; }
void cBlockArea::Merge(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_RelZ, eMergeStrategy a_Strategy) { // Block types are compulsory, block metas are voluntary if (!HasBlockTypes() || !a_Src.HasBlockTypes()) { LOGWARNING("%s: cannot merge because one of the areas doesn't have blocktypes.", __FUNCTION__); return; } // Dst is *this, Src is a_Src int SrcOffX = std::max(0, -a_RelX); // Offset in Src where to start reading int DstOffX = std::max(0, a_RelX); // Offset in Dst where to start writing int SizeX = std::min(a_Src.GetSizeX() - SrcOffX, GetSizeX() - DstOffX); // How many blocks to copy int SrcOffY = std::max(0, -a_RelY); // Offset in Src where to start reading int DstOffY = std::max(0, a_RelY); // Offset in Dst where to start writing int SizeY = std::min(a_Src.GetSizeY() - SrcOffY, GetSizeY() - DstOffY); // How many blocks to copy int SrcOffZ = std::max(0, -a_RelZ); // Offset in Src where to start reading int DstOffZ = std::max(0, a_RelZ); // Offset in Dst where to start writing int SizeZ = std::min(a_Src.GetSizeZ() - SrcOffZ, GetSizeZ() - DstOffZ); // How many blocks to copy const NIBBLETYPE * SrcMetas = a_Src.GetBlockMetas(); NIBBLETYPE * DstMetas = m_BlockMetas; bool IsDummyMetas = ((SrcMetas == NULL) || (DstMetas == NULL)); if (IsDummyMetas) { SrcMetas = new NIBBLETYPE[a_Src.GetBlockCount()]; DstMetas = new NIBBLETYPE[GetBlockCount()]; } switch (a_Strategy) { case msOverwrite: { InternalMergeBlocks( m_BlockTypes, a_Src.GetBlockTypes(), DstMetas, SrcMetas, SizeX, SizeY, SizeZ, SrcOffX, SrcOffY, SrcOffZ, DstOffX, DstOffY, DstOffZ, a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(), m_SizeX, m_SizeY, m_SizeZ, MergeCombinatorOverwrite ); break; } // case msOverwrite case msFillAir: { InternalMergeBlocks( m_BlockTypes, a_Src.GetBlockTypes(), DstMetas, SrcMetas, SizeX, SizeY, SizeZ, SrcOffX, SrcOffY, SrcOffZ, DstOffX, DstOffY, DstOffZ, a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(), m_SizeX, m_SizeY, m_SizeZ, MergeCombinatorFillAir ); break; } // case msFillAir case msImprint: { InternalMergeBlocks( m_BlockTypes, a_Src.GetBlockTypes(), DstMetas, SrcMetas, SizeX, SizeY, SizeZ, SrcOffX, SrcOffY, SrcOffZ, DstOffX, DstOffY, DstOffZ, a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(), m_SizeX, m_SizeY, m_SizeZ, MergeCombinatorImprint ); break; } // case msImprint case msLake: { InternalMergeBlocks( m_BlockTypes, a_Src.GetBlockTypes(), DstMetas, SrcMetas, SizeX, SizeY, SizeZ, SrcOffX, SrcOffY, SrcOffZ, DstOffX, DstOffY, DstOffZ, a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(), m_SizeX, m_SizeY, m_SizeZ, MergeCombinatorLake ); break; } // case msLake default: { LOGWARNING("Unknown block area merge strategy: %d", a_Strategy); ASSERT(!"Unknown block area merge strategy"); break; } } // switch (a_Strategy) if (IsDummyMetas) { delete[] SrcMetas; delete[] DstMetas; } }
double Margolus::CalculationBlockEnergy(const Block3D& block, cuint& ix, cuint& iy, cuint& iz) { double sumEnergy = 0.0; Cell cellIn, cellOut; //x gran 1 if (ix > 0) { for (uint z = 0; z < 2; ++z) { cellIn = block.cells[0][1][z]; cellOut = cells[ix - 1][iy + 1][iz + z]; PareEnergy(cellIn, cellOut, sumEnergy); cellIn = block.cells[0][0][z]; cellOut = cells[ix - 1][iy][iz + z]; PareEnergy(cellIn, cellOut, sumEnergy); } } //x gran 2 if (ix < GetSizeX() - 2) { for (uint z = 0; z < 2; ++z) { cellIn = block.cells[1][1][z]; cellOut = cells[ix + 2][iy + 1][iz + z]; PareEnergy(cellIn, cellOut, sumEnergy); cellIn = block.cells[1][0][z]; cellOut = cells[ix + 2][iy][iz + z]; PareEnergy(cellIn, cellOut, sumEnergy); } } //y gran 1 if (iy > 0) { for (uint z = 0; z < 2; ++z) { cellIn = block.cells[1][0][z]; cellOut = cells[ix + 1][iy - 1][iz + z]; PareEnergy(cellIn, cellOut, sumEnergy); cellIn = block.cells[0][0][z]; cellOut = cells[ix][iy - 1][iz + z]; PareEnergy(cellIn, cellOut, sumEnergy); } } //y gran 2 if (iy < GetSizeY() - 2) { for (uint z = 0; z < 2; ++z) { cellIn = block.cells[1][1][z]; cellOut = cells[ix + 1][iy + 2][iz + z]; PareEnergy(cellIn, cellOut, sumEnergy); cellIn = block.cells[0][1][z]; cellOut = cells[ix][iy + 2][iz + z]; PareEnergy(cellIn, cellOut, sumEnergy); } } //z gran 1 if (iz > 0) { for (uint i = 0; i < 4; ++i) { cellIn = block.cells[indexF[i][0]][indexF[i][1]][0]; cellOut = cells[ix + indexF[i][0]][iy + indexF[i][1]][iz - 1]; PareEnergy(cellIn, cellOut, sumEnergy); } } //z gran 2 if (iz < GetSizeZ() - 2) { for (uint i = 0; i < 4; ++i) { cellIn = block.cells[indexF[i][0]][indexF[i][1]][1]; cellOut = cells[ix + indexF[i][0]][iy + indexF[i][1]][iz + 2]; PareEnergy(cellIn, cellOut, sumEnergy); } } //inside block for (uint i = 0; i < 4; ++i) { for (uint z = 0; z < 2; ++z) { cellIn = block.cells[indexF[i][0]][indexF[i][1]][z]; cellOut = block.cells[indexF[i + 1][0]][indexF[i + 1][1]][z]; PareEnergyFull(cellIn, cellOut, sumEnergy); } { cellIn = block.cells[indexF[i][0]][indexF[i][1]][0]; cellOut = block.cells[indexF[i][0]][indexF[i][1]][1]; PareEnergyFull(cellIn, cellOut, sumEnergy); } } if (!moveForward || block.move[movement] > 0) { sumEnergy += block.move[movement] * *steamEnergy_; } return sumEnergy; }
void Margolus::Calculation(cuint& dx, cuint& dy, cuint& dz) { //#pragma omp parallel for for (uint ix = dx; ix < GetSizeX() - 1; ix += 2) { for (uint iy = dy; iy < GetSizeY() - 1; iy += 2) { for (uint iz = dz; iz < GetSizeZ() - 1; iz += 2) { if (CheckEmpty(ix, iy, iz)) { continue; } blockSize3D = 1; CreateRotateNotBlock3D(blocks3D[0], ix, iy, iz); if (modifierMove && CheckMod(ix, iy, iz)) { if (CheckActive (ix, iy)) { if (CheckCanRotate3D(ClockWiceX, ix, iy, iz)) { CreateRotateBlock3D(blocks3D[blockSize3D], ClockWiceX, ix, iy, iz, false, true); ++blockSize3D; CreateRotateBlock3D(blocks3D[blockSize3D], ClockWiceX, ix, iy, iz, true, true); ++blockSize3D; CreateRotateBlock3D(blocks3D[blockSize3D], ClockWiceX, ix, iy, iz); ++blockSize3D; } if (CheckCanRotate3D(CounterClockWiceX, ix, iy, iz)) { CreateRotateBlock3D(blocks3D[blockSize3D], CounterClockWiceX, ix, iy, iz, false, true); ++blockSize3D; CreateRotateBlock3D(blocks3D[blockSize3D], CounterClockWiceX, ix, iy, iz, true, true); ++blockSize3D; CreateRotateBlock3D(blocks3D[blockSize3D], CounterClockWiceX, ix, iy, iz); ++blockSize3D; } if (CheckCanRotate3D(ClockWiceY, ix, iy, iz)) { CreateRotateBlock3D(blocks3D[blockSize3D], ClockWiceY, ix, iy, iz, false, true); ++blockSize3D; CreateRotateBlock3D(blocks3D[blockSize3D], ClockWiceY, ix, iy, iz, true, true); ++blockSize3D; CreateRotateBlock3D(blocks3D[blockSize3D], ClockWiceY, ix, iy, iz); ++blockSize3D; } if (CheckCanRotate3D(CounterClockWiceY, ix, iy, iz)) { CreateRotateBlock3D(blocks3D[blockSize3D], CounterClockWiceY, ix, iy, iz, false, true); ++blockSize3D; CreateRotateBlock3D(blocks3D[blockSize3D], CounterClockWiceY, ix, iy, iz, true, true); ++blockSize3D; CreateRotateBlock3D(blocks3D[blockSize3D], CounterClockWiceY, ix, iy, iz); ++blockSize3D; } if (CheckCanRotate3D(ClockWiceZ, ix, iy, iz)) { CreateRotateBlock3D(blocks3D[blockSize3D], ClockWiceZ, ix, iy, iz, false, true); ++blockSize3D; CreateRotateBlock3D(blocks3D[blockSize3D], ClockWiceZ, ix, iy, iz, true, true); ++blockSize3D; CreateRotateBlock3D(blocks3D[blockSize3D], ClockWiceZ, ix, iy, iz); ++blockSize3D; } if (CheckCanRotate3D(CounterClockWiceZ, ix, iy, iz)) { CreateRotateBlock3D(blocks3D[blockSize3D], CounterClockWiceZ, ix, iy, iz, false, true); ++blockSize3D; CreateRotateBlock3D(blocks3D[blockSize3D], CounterClockWiceZ, ix, iy, iz, true, true); ++blockSize3D; CreateRotateBlock3D(blocks3D[blockSize3D], CounterClockWiceZ, ix, iy, iz); ++blockSize3D; } } else { CreateRotateBlock3D(blocks3D[blockSize3D], ClockWiceX, ix, iy, iz, false, true); ++blockSize3D; CreateRotateBlock3D(blocks3D[blockSize3D], CounterClockWiceX, ix, iy, iz, false, true); ++blockSize3D; CreateRotateBlock3D(blocks3D[blockSize3D], ClockWiceY, ix, iy, iz, false, true); ++blockSize3D; CreateRotateBlock3D(blocks3D[blockSize3D], CounterClockWiceY, ix, iy, iz, false, true); ++blockSize3D; CreateRotateBlock3D(blocks3D[blockSize3D], ClockWiceZ, ix, iy, iz, false, true); ++blockSize3D; CreateRotateBlock3D(blocks3D[blockSize3D], CounterClockWiceZ, ix, iy, iz, false, true); ++blockSize3D; } } else { if (CheckCanRotate3D(ClockWiceX, ix, iy, iz)) { CreateRotateBlock3D(blocks3D[blockSize3D], ClockWiceX, ix, iy, iz); ++blockSize3D; } if (CheckCanRotate3D(CounterClockWiceX, ix, iy, iz)) { CreateRotateBlock3D(blocks3D[blockSize3D], CounterClockWiceX, ix, iy, iz); ++blockSize3D; } if (CheckCanRotate3D(ClockWiceY, ix, iy, iz)) { CreateRotateBlock3D(blocks3D[blockSize3D], ClockWiceY, ix, iy, iz); ++blockSize3D; } if (CheckCanRotate3D(CounterClockWiceY, ix, iy, iz)) { CreateRotateBlock3D(blocks3D[blockSize3D], CounterClockWiceY, ix, iy, iz); ++blockSize3D; } if (CheckCanRotate3D(ClockWiceZ, ix, iy, iz)) { CreateRotateBlock3D(blocks3D[blockSize3D], ClockWiceZ, ix, iy, iz); ++blockSize3D; } if (CheckCanRotate3D(CounterClockWiceZ, ix, iy, iz)) { CreateRotateBlock3D(blocks3D[blockSize3D], CounterClockWiceZ, ix, iy, iz); ++blockSize3D; } } double Z = 0.0; // + Energy for (uint i = 0; i < blockSize3D; ++i) { double energy = CalculationBlockEnergy(blocks3D[i], ix, iy, iz); //кДж/моль blocks3D[i].energy = exp(-energy / (R * *T)); Z += blocks3D[i].energy; } //normalization double sumProbability = 0.0; double rnd = (double)(rand()) / RAND_MAX; for (uint i = 0; i < blockSize3D; ++i) { sumProbability += blocks3D[i].energy / Z; if (rnd <= sumProbability) { ChangeBlock(blocks3D[i], ix, iy, iz); break; } } } } } }
void cBlockArea::MergeByStrategy(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_RelZ, eMergeStrategy a_Strategy, const NIBBLETYPE * SrcMetas, NIBBLETYPE * DstMetas) { // Block types are compulsory, block metas are voluntary if (!HasBlockTypes() || !a_Src.HasBlockTypes()) { LOGWARNING("%s: cannot merge because one of the areas doesn't have blocktypes.", __FUNCTION__); return; } // Dst is *this, Src is a_Src int SrcOffX = std::max(0, -a_RelX); // Offset in Src where to start reading int DstOffX = std::max(0, a_RelX); // Offset in Dst where to start writing int SizeX = std::min(a_Src.GetSizeX() - SrcOffX, GetSizeX() - DstOffX); // How many blocks to copy int SrcOffY = std::max(0, -a_RelY); // Offset in Src where to start reading int DstOffY = std::max(0, a_RelY); // Offset in Dst where to start writing int SizeY = std::min(a_Src.GetSizeY() - SrcOffY, GetSizeY() - DstOffY); // How many blocks to copy int SrcOffZ = std::max(0, -a_RelZ); // Offset in Src where to start reading int DstOffZ = std::max(0, a_RelZ); // Offset in Dst where to start writing int SizeZ = std::min(a_Src.GetSizeZ() - SrcOffZ, GetSizeZ() - DstOffZ); // How many blocks to copy switch (a_Strategy) { case cBlockArea::msOverwrite: { InternalMergeBlocks<MetasValid, MergeCombinatorOverwrite<MetasValid> >( m_BlockTypes, a_Src.GetBlockTypes(), DstMetas, SrcMetas, SizeX, SizeY, SizeZ, SrcOffX, SrcOffY, SrcOffZ, DstOffX, DstOffY, DstOffZ, a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(), m_Size.x, m_Size.y, m_Size.z ); return; } // case msOverwrite case cBlockArea::msFillAir: { InternalMergeBlocks<MetasValid, MergeCombinatorFillAir<MetasValid> >( m_BlockTypes, a_Src.GetBlockTypes(), DstMetas, SrcMetas, SizeX, SizeY, SizeZ, SrcOffX, SrcOffY, SrcOffZ, DstOffX, DstOffY, DstOffZ, a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(), m_Size.x, m_Size.y, m_Size.z ); return; } // case msFillAir case cBlockArea::msImprint: { InternalMergeBlocks<MetasValid, MergeCombinatorImprint<MetasValid> >( m_BlockTypes, a_Src.GetBlockTypes(), DstMetas, SrcMetas, SizeX, SizeY, SizeZ, SrcOffX, SrcOffY, SrcOffZ, DstOffX, DstOffY, DstOffZ, a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(), m_Size.x, m_Size.y, m_Size.z ); return; } // case msImprint case cBlockArea::msLake: { InternalMergeBlocks<MetasValid, MergeCombinatorLake<MetasValid> >( m_BlockTypes, a_Src.GetBlockTypes(), DstMetas, SrcMetas, SizeX, SizeY, SizeZ, SrcOffX, SrcOffY, SrcOffZ, DstOffX, DstOffY, DstOffZ, a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(), m_Size.x, m_Size.y, m_Size.z ); return; } // case msLake case cBlockArea::msSpongePrint: { InternalMergeBlocks<MetasValid, MergeCombinatorSpongePrint<MetasValid> >( m_BlockTypes, a_Src.GetBlockTypes(), DstMetas, SrcMetas, SizeX, SizeY, SizeZ, SrcOffX, SrcOffY, SrcOffZ, DstOffX, DstOffY, DstOffZ, a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(), m_Size.x, m_Size.y, m_Size.z ); return; } // case msSpongePrint case cBlockArea::msDifference: { InternalMergeBlocks<MetasValid, MergeCombinatorDifference<MetasValid> >( m_BlockTypes, a_Src.GetBlockTypes(), DstMetas, SrcMetas, SizeX, SizeY, SizeZ, SrcOffX, SrcOffY, SrcOffZ, DstOffX, DstOffY, DstOffZ, a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(), m_Size.x, m_Size.y, m_Size.z ); return; } // case msDifference case cBlockArea::msMask: { InternalMergeBlocks<MetasValid, MergeCombinatorMask<MetasValid> >( m_BlockTypes, a_Src.GetBlockTypes(), DstMetas, SrcMetas, SizeX, SizeY, SizeZ, SrcOffX, SrcOffY, SrcOffZ, DstOffX, DstOffY, DstOffZ, a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(), m_Size.x, m_Size.y, m_Size.z ); return; } // case msMask } // switch (a_Strategy) LOGWARNING("Unknown block area merge strategy: %d", a_Strategy); ASSERT(!"Unknown block area merge strategy"); return; }