CFD Online Logo CFD Online URL
www.cfd-online.com
[Sponsors]
Home > Forums > Software User Forums > OpenFOAM > OpenFOAM Programming & Development

OpenFoam ensure same values across processor patches

Register Blogs Community New Posts Updated Threads Search

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old   January 2, 2018, 18:58
Unhappy OpenFoam ensure same values across processor patches
  #1
Member
 
Join Date: Oct 2013
Posts: 92
Rep Power: 13
fedvasu is on a distinguished road
Hi,

I am calculating averages on physical boundaries of my domain. However when I am calculating these things in parallel my solver crashes.

Because, my calculation happens on processor patches too. As my calculation has some stochastic component to it, the values across processor patches are never exactly same.

For example face values on procBoundary0to1 on processor 0 won't be same as procBoundary1to0 on processor 1.

I tried keeping my face values at procBoundary* to 0 and even tried not doing anything at all. However it seems I need proper values there.

So How can I ensure procBoundary0to1 on processor 0 = procBoundary1to0 on processor 1.

It seems i can't reduce or synchronize fvPatchScalarField&.
fedvasu is offline   Reply With Quote

Old   January 2, 2018, 19:12
Default Simplified code snippet
  #2
Member
 
Join Date: Oct 2013
Posts: 92
Rep Power: 13
fedvasu is on a distinguished road
Here is a simplified code snippet

Code:
forAll(T_.mesh().boundary(), patchi)
{
//here patchi also includes procBoundary, I can get it's patchid and name just fine
const fvPatchScalarField& pZ    = Z_.boundaryField()[patchi];
    forAll(pZ , facei)
    {
          if(pZ<MIN_VAL)
          {
             // do deterministic calculation
          }

         else
         {
            //do stochastic calcuation
         }

    }
           
}
fedvasu is offline   Reply With Quote

Old   January 7, 2018, 11:26
Default
  #3
Senior Member
 
Hrvoje Jasak
Join Date: Mar 2009
Location: London, England
Posts: 1,907
Rep Power: 33
hjasak will become famous soon enough
You should not be doing this. The processor0To1 and processor1To0 actually rerepsent the same face, on two processors. If they are inconsistent in ANY WAY, this is no longer the same face.

Think of this as 1 single internal mesh face: you need to repeat the exact same operation, but fetching the data in a different way - using patchInternalField() and patchNeighbourField()

If you do anything else, the code may appear to work, but you will break the linear algebra package.

Hope this helps,

Hrv
__________________
Hrvoje Jasak
Providing commercial FOAM/OpenFOAM and CFD Consulting: http://wikki.co.uk
hjasak is offline   Reply With Quote

Old   January 10, 2018, 21:20
Default
  #4
Member
 
Join Date: Oct 2013
Posts: 92
Rep Power: 13
fedvasu is on a distinguished road
Quote:
Originally Posted by hjasak View Post
You should not be doing this. The processor0To1 and processor1To0 actually rerepsent the same face, on two processors. If they are inconsistent in ANY WAY, this is no longer the same face.

Think of this as 1 single internal mesh face: you need to repeat the exact same operation, but fetching the data in a different way - using patchInternalField() and patchNeighbourField()

If you do anything else, the code may appear to work, but you will break the linear algebra package.

Hope this helps,

Hrv
Thank You Dr Jasak, I tried using patchInternalField() and patchNeighbourField() for procBoundary but it didn't work, so I am not sure what you meant by that. I am bit confused.

Here is a simplified code snippet THIS DOESN"T WORK!

Code:
forAll(T_.mesh().boundary(), patchi)
{
const fvPatchScalarField& pZ    = Z_.boundaryField()[patchi];
const fvPatch& curPatch = T_.mesh().boundary()[patchi];
std::string patchName   = curPatch.name();

//if (isA<processorPolyPatch>(curPatch))
if(patchName.rfind("procBoundary",0) == 0)
{
    const scalarField ppZ    = pZ.patchNeighbourField(); //pZ.patchInternalField(); 
    forAll(ppZ, facei)
    {
        if(ppZ<MIN_VAL)
          {
             // do deterministic calculation
          }

         else
         {
            //do stochastic calcuation
         }
    }
    
}

else
{
    forAll(pZ , facei)
    {
          if(pZ<MIN_VAL)
          {
             // do deterministic calculation
          }

         else
         {
            //do stochastic calcuation
         }

    }
}          
}
However this DOES WORK.

Code:
forAll(T_.mesh().boundary(), patchi)
{
const fvPatchScalarField& pZ    = Z_.boundaryField()[patchi];
const fvPatch& curPatch = T_.mesh().boundary()[patchi];
std::string patchName   = curPatch.name();

//if (isA<processorPolyPatch>(curPatch))
if(patchName.rfind("procBoundary",0) == 0)
{
   pT.evaluate(); //or  pT.evaluate(Pstream::blocking);
  //all other patchFields follow
}

else
{
    forAll(pZ , facei)
    {
          if(pZ<MIN_VAL)
          {
             // do deterministic calculation
          }

         else
         {
            //do stochastic calcuation
         }

    }
}          
}

Last edited by fedvasu; January 10, 2018 at 21:27. Reason: remove superflous detail
fedvasu is offline   Reply With Quote

Old   January 10, 2018, 21:25
Default Final solution
  #5
Member
 
Join Date: Oct 2013
Posts: 92
Rep Power: 13
fedvasu is on a distinguished road
I would like to post THIS WORKING solution again for clarity.

Code:
forAll(T_.mesh().boundary(), patchi)
{
const fvPatchScalarField& pZ    = Z_.boundaryField()[patchi];
const fvPatch& curPatch = T_.mesh().boundary()[patchi];
std::string patchName   = curPatch.name();

//if (isA<processorPolyPatch>(curPatch))
if(patchName.rfind("procBoundary",0) == 0)
{
  pT.evaluate(); //or  pT.evaluate(Pstream::blocking);
  //all other patchFields follow 
}

else
{
    forAll(pZ , facei)
    {
          if(pZ<MIN_VAL)
          {
             // do deterministic calculation
          }

         else
         {
            //do stochastic calcuation
         }

    }
}          
}
I still don't understand how exactly the evaluate() communicates across processor boundary, but this solves my problem.

Anyone knows exactly what evaluate() does and how it avoids my problem feel free to add to this thread. I will keep this thread unsolved till then.
fedvasu is offline   Reply With Quote

Reply

Tags
openfoam-2.4.0, parallel, random perturbation.


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
How to contribute to the community of OpenFOAM users and to the OpenFOAM technology wyldckat OpenFOAM 17 November 10, 2017 16:54
OpenFOAM Training Jan-Jul 2017, Virtual, London, Houston, Berlin CFDFoundation OpenFOAM Announcements from Other Sources 0 January 4, 2017 07:15
OpenFOAM v3.0.1 Training, London, Houston, Berlin, Jan-Mar 2016 cfd.direct OpenFOAM Announcements from Other Sources 0 January 5, 2016 04:18
chtmultiregionsimplefoam: different pressure values in openFoam and Fluent vasava OpenFOAM Running, Solving & CFD 0 November 7, 2014 04:35
OpenFoam output to CSV; correlate coordinates to internal values CoolKau OpenFOAM Post-Processing 0 October 29, 2014 09:03


All times are GMT -4. The time now is 16:13.