Purposes of updateCoeffs, initEvaluate and evaluate....?
Hello and a Good Evening to everyone :-)!
The year has mandered through its time and almost reached the end! Must say, it was a fast one this time (have a weird feeling I say that each year :-)!) I have been trying (still am) too figure out the implementation of the GGI interface in OpenFOAM-1.6-ext (Git version), and have one quick question.... ** In the context of Boundary Conditions - Patches and Fields, What are the purposes of the following functions / methods? 1. updateCoeffs 2. initEvaluate 3. evaluate I see some implementations of the boundary conditions (fields) using only updateCoeffs, some using only a combination of initEvaluate and evaluate, and some with only initEvaluate and the evaluate function calling a "this->updateCoeffs()" (P.S.... Has anyone tried out Source Navigator NG?? Its quite a cool tool which can be used for browsing through code) Have a great evening ahead! Philippose |
initEvaluate / evaluate functions are used for boundary field evaluations that are interleaved with inter-processor communication. Take a look at GeometricBoundaryField.C to see how this works..
updateCoeffs basically ensures that boundaryField arrays are up-to-date when the next BC update during the matrix multiply takes place. |
Hi Sandeep :-)!
Thanks for your reply... yes, I had looked at the code in GeomtetricBoundaryField over the last few days. My specific question is, how come some of the implementations of specific boundary conditions (the derived ones) used "updateCoeffs" and some of them use "evaluate" or a combination of "initEvaluate / evaluate" in order to update the boundary conditions? How does one decide when to use "updateCoeffs" and when to use "initEvaluate" / "evaluate" ? ** I was looking a little deeper, and now that you mention it, it looks like only the "basic" and "constraint" fvPatchField boundary conditions implement an "evaluate" method ** All the fvPatchFields under the "derived" category implement only an "updateCoeffs" method but no "evaluate" method. So does this mean, that "evaluate" and "initEvaluate" are only meant of updating boundary conditions at a low level and specifically for parallel communications, and all derived boundary conditions need to use only the "updateCoeffs" function to update the BCs? One other thing..... is there anywhere I can get something like a flow of events when a solver is executed, as in.... which are all the functions, and which order they are called when a boundary condition is being created and later solved / updated? I know that these are all very basic questions, but I think in order to figure out how the GGI works, and whether there is any way I can modify it to handle uncovered faces, I do need to understand this basic flow. Thanks once again! Philippose |
Yup - the evaluate / initEvaluate members are intended for low-level use, such as inter-processor comms and/or fancy constraints. It is expected that this can be abstracted away for higher-level functionality.
For order-of-operations, you can always set the debug flags in etc/controlDict, and then you will get any info that falls under an "if (debug)" condition. You may have to add your own and recompile, if necessary. |
Hello FOAMers!
...just to complete the above discussion, I have a questions: Is evaluate() - and so correctBoundaryConditions() - intended for creating point of synchronization in parallel execution? Thanks!! :) |
The initEvaluate and evaluate functions are being called in correctBoundaryConditions(). I have successfully used this correctBoundaryConditions in my solver. Attached below is a peudo code
Do iter = 1 to niter calculate fluxes for internal faces /// Exchange the field variable "1" across processors fieldVariable1.correctBoundaryConditions(); applyBC for fieldVariable1 /// Exchange the field variable "2" across processors fieldVariable2.correctBoundaryConditions(); applyBC for fieldVariable 2 .... End This works perfectly fine. But when I try to do someting like this below it fails and do know why ? Can someone point out the mistake I am making ?? Do iter = 1 to niter /// Start the transfer for all field variables forAll patches in boundaryField { fieldVariable1.boundaryField()[ipatch].initEvaluate(); fieldVariable2.boundaryField()[ipatch].initEvaluate(); } calculate fluxes for internal faces /// Confirm the exchange of variable "1" forAll patches in boundaryField { fieldVariable1.boundaryField()[ipatch].evaluate(); } applyBC for fieldVariable1 /// Confirm the exchange of variable "2" forAll patches in boundaryField { fieldVariable2.boundaryField()[ipatch].evaluate(); } applyBC for fieldVariable2 .... End |
Hi
I have figured out the mistake it should have been the following to make it non-blocking communication implementation Do iter = 1 to niter /// Start the transfer for all field variables forAll patches in boundaryField that are of type "processor" { fieldVariable1.boundaryField()[ipatch].initEvaluate(); fieldVariable2.boundaryField()[ipatch].initEvaluate(); } calculate fluxes for internal faces /// Confirm the exchange of variable "1" forAll patches in boundaryField that are of type "processor" { fieldVariable1.boundaryField()[ipatch].evaluate(); } applyBC for fieldVariable1 /// Confirm the exchange of variable "2" forAll patches in boundaryField that are of type "processor" { fieldVariable2.boundaryField()[ipatch].evaluate(); } applyBC for fieldVariable2 .... End So basically if you use correctBoundaryConditions it will be a blocking implementation since you will wait till the data is send/recv. But if you use the one shown above you will have a non-blocking implementation using which you can hide communication latency. |
correctBoundaryConditions
you write
/// Exchange the field variable "1" across processors fieldVariable1.correctBoundaryConditions(); the correctBoundaryConditions() applies also for other types of patch, not only processor ones. If I want only to exchange information for the field variable "1" across processors do i need to use the non blocking formulation ? |
Quote:
forAll patches in boundaryField that are of type "processor" { fieldVariable1.boundaryField()[ipatch].evaluate(Pstream::blocking); } |
Dear FOAMers,
I'm trying to create a new boundary condition (fvPatchField) that tries to interpolate cell values from another (background) mesh to the patch faces which cut across the mesh. I'd require parallel communication to obtain the necessary data from other processors before the boundary condition can be evaluated. Can I just do the parallel communication in updateCoeffs function itself or do I have to do something about the initEvaluate function? Thanks in advance!:) Best, USV |
All times are GMT -4. The time now is 23:18. |