|
[Sponsors] |
Accessing local cell index with global cell index in functionObject |
|
LinkBack | Thread Tools | Search this Thread | Display Modes |
|
May 16, 2021, 16:53 |
Accessing local cell index with global cell index in functionObject
|
#1 |
Member
Join Date: Feb 2020
Posts: 90
Rep Power: 6 |
Hello to all,
In a functionObject I am coding, I need to access the values of pressure of cellID {20, 70, 30, 50, 90}, in this order. I using a 2D square domain with 10x10 cells for testing decomposed in 2 processors. I have the following code. Code:
List<scalar> cellIds{20, 70, 30, 50, 90}; List<scalar> pValues(cellIds.size() ); const volScalarField& sField = lookupObject<volScalarField>("p"); forAll(cellIds, cellI) { pValues[cellI] = sField [ cellIds [cellI] ]; } sField[70], it will give me the following error: Code:
[1] [1] [1] --> FOAM FATAL ERROR: (openfoam-2012) [1] index 70 out of range [0,50] [1] [1] From void Foam::UList<T>::checkIndex(Foam::label) const [with T = double; Foam::label = int] [1] in file /home/pc/OpenFOAM/OpenFOAM-v2012/src/OpenFOAM/lnInclude/UListI.H at line 138. [1] FOAM parallel run aborting [1] [0] [0] [0] --> FOAM FATAL ERROR: (openfoam-2012) [0] index 70 out of range [0,50] [0] [0] From void Foam::UList<T>::checkIndex(Foam::label) const [with T = double; Foam::label = int] [0] in file /home/pc/OpenFOAM/OpenFOAM-v2012/src/OpenFOAM/lnInclude/UListI.H at line 138. [0] FOAM parallel run aborting Is it possible of access the local cellID on each processor based on the global cellID? Any builtin function to do this? Best Regards |
|
May 18, 2021, 07:20 |
|
#2 | |
Senior Member
Mark Olesen
Join Date: Mar 2009
Location: https://olesenm.github.io/
Posts: 1,689
Rep Power: 40 |
Quote:
Let us give it a bit more consideration to what you are attempting. You have some cellIDs known in serial based on a particular geometry. If you change your mesh resolution (coarser/fine mesh), or swap the corners of the origination blockMesh you will have completely different cellIDs (in serial!). If you decompose onto multiple processors, which cells land where will depend on your decomposition method. To be really nasty about things, let us assume we are using the "random" decomposition method. This is my personal favourite. It is likely the worst possible decomposition you can imagine since each cell is randomly redistributed: horrible for calculation, great for debugging. I hope by now you see where all of this is going. Working with some arbitrary cellIDs that you have specified in serial is never going to work. Instead it would make sense to work directly with how you obtained these IDs in the first place. I would assume that you picked them out based on some x/y/z positions. From these sample points (starting to look a lot like sampledSets) you can find the nearest location in mesh on each processor and reduce the result to find the best location. I guess you could also do things by hand, define an ijkMesh based on the global mesh bounding box and use that as a voxel type of selection. You'll have to see what fits best for you. |
||
May 18, 2021, 11:16 |
|
#3 |
Member
Join Date: Feb 2020
Posts: 90
Rep Power: 6 |
Hello Mr. Olesen,
Thanks for the reply. I will give more context into what I am trying to do. OpenFoam has the runTimeControl function object (https://www.openfoam.com/documentati...e-control.html) which I would like to make work for defining a steady state criteria based on the difference of properties between iterations i.e., at several locations x,y,z when the velocity and pressure difference between iterations is less than 1e-5 stop the simulation (steady criteria). The intent is to make this work with probes. But for now, I am asking the user to specify a number of random cells to keep track of some properties , e.g., pressure. The random points are selected with: Code:
// Get numbers of cells in the domain const scalar nCells = returnReduce(this->mesh_.C().size(), sumOp<label>()); // Function to generate integer random numbers based on the number of cells Random::uniformGeneratorOp<label> randVal(0,nCells-1); // Vector to store the cellID values. Resized to the user input and initialized with -1. nPointVector_.resize(nRandomPoints_, -1); // Get n randomly selected cells // Create a vector from 0-nCells for random selection of cells List<label> cellIDList(nCells); forAll(cellIDList, i) { cellIDList[i]=i; } // Shuffles the vector to randomly select cells in the domain unsigned seed = std::chrono::system_clock::now().time_since_epoch().count(); std::default_random_engine e(seed); std::shuffle(cellIDList.begin(), cellIDList.end(), e); // Assigns the random cells to the nPointVector for(label i = 0 ; i < nRandomPoints_; i++) { nPointVector_[i] = cellIDList[i]; } // Vector to store the value of properties for 2 iterations. Resized to user input and initialized with -1 twoIterationStorage_.resize(2, List<scalar> (nRandomPoints_, -1.0)); Afterwards in the execute() function of the funtionObject. Code:
bool Foam::functionObjects::steadyStateCheck::execute() { // Creates files to store data. createFiles(); // Looks for the pressure field. fieldSet is a user input which for the time being is pressure const volScalarField& sField = lookupObject<volScalarField>(fieldSet_[0]); // Populates the storage vector with the values of the field from the randomly generated cells forAll(twoIterationStorage_[rowNumber_], cellI) { twoIterationStorage_[rowNumber_][cellI] = sField[ nPointVector_[cellI] ]; } // Function to switch the rowNumber of the storage vector (wither 0 or 1) updateRowNumber(); // Compute the maximum difference between all randomly selected cells const scalar maxDifference = gMax(mag(twoIterationStorage_[0]-twoIterationStorage_[1])); // write information to file if(writeToFile() && Pstream::master() ) { writeCurrentTime(coeffFilePtr_()); coeffFilePtr_() << tab << maxDifference << tab << endl; } // write randomly selected cellIDS to fill in case I want to check them in paraview if(writeCellIDs_ && Pstream::master() ) { forAll(nPointVector_, cellI) { cellIDFilePtr_() << tab << label(nPointVector_[cellI]) << tab << endl; } writeCellIDs_ = false; } firstIter_=false; // Write state/results information { setResult("Cd", maxDifference); } return true; } This procedure works in serial with: Code:
runTimeControl1 { type runTimeControl; libs ("libutilityFunctionObjects.so"); conditions { condition1 { type average; functionObject mySteadyState; fields (Cd); tolerance 1e-5; window 10; groupID 1; } Do you know if OF 2012 has any feature that already performs this task? Best regards. |
|
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
time step continuity problem in VAWT simulation | lpz_michele | OpenFOAM Running, Solving & CFD | 5 | February 22, 2018 19:50 |
pimpleDyMFoam computation randomly stops | babapeti | OpenFOAM Running, Solving & CFD | 5 | January 24, 2018 05:28 |
dynamic Mesh is faster than MRF???? | sharonyue | OpenFOAM Running, Solving & CFD | 14 | August 26, 2013 07:47 |
[blockMesh] BlockMeshmergePatchPairs | hjasak | OpenFOAM Meshing & Mesh Conversion | 11 | August 15, 2008 07:36 |
Convergence moving mesh | lr103476 | OpenFOAM Running, Solving & CFD | 30 | November 19, 2007 14:09 |