|
[Sponsors] |
July 25, 2018, 04:31 |
|
#61 |
New Member
Artem
Join Date: Apr 2014
Posts: 29
Rep Power: 12 |
Dear Philip,
Sorry to bother you. It seems that I stuck again but right now with tangential laplacian. So tangential laplacian is: = (( - nn)( - nn)) That means that we want to take a divergence operation, from this line Code:
/ Get tangential component of gradPotE at the boundary vectorField tangGradPotE = ((I - sqr(nf)) & (I - sqr(nf)) & gradPotE.boundaryFieldRef()[patchID].patchInternalField()); So considering the above it seems that:
That's why I don't understand what to do in this case. Any help will be appreciated. Thanks in advance. Best regards, Tar |
|
July 25, 2018, 10:39 |
|
#62 |
New Member
Artem
Join Date: Apr 2014
Posts: 29
Rep Power: 12 |
Small update.
I tried to go the second way and take laplacian after the projection. I am not sure that this was the right way, but it was worth to try. Right now it looks something like this: Code:
// Calculate project tensor surfaceTensorField pp = (I - sqr(mesh.Sf())) & (I - sqr(mesh.Sf())); // Calculate lpalacian with projection volScalarField lp = fvc::laplacian(pp, PotE); fixedGradientFvPatchScalarField& PotEpatch = refCast<fixedGradientFvPatchScalarField> ( PotE.boundaryFieldRef()[patchID] ); // Choose laplacian at the boundary scalarField lps = lp.boundaryFieldRef()[patchID].patchInternalField(); // Set the normal gradient equal to the lpalacian forAll(PotEpatch, faceI) { PotEpatch.gradient()[faceI] = lps[faceI]; } Code:
sqr(mesh.Sf()) Best regards, Tar |
|
July 25, 2018, 10:45 |
|
#63 |
Super Moderator
Philip Cardiff
Join Date: Mar 2009
Location: Dublin, Ireland
Posts: 1,093
Rep Power: 34 |
Hi Tar,
I am not quite sure what a tangential Laplacian operator is (maybe it is like div(grad(PotE).T() ...?), but your proposed formulae/code look very strange to me. I suggest you examine how others in literature have performed this discretisation, to be clear on what coefficients you expect etc. Philip |
|
July 25, 2018, 12:46 |
|
#64 | |
New Member
Artem
Join Date: Apr 2014
Posts: 29
Rep Power: 12 |
Quote:
The tangential laplacian means that we use only the tangential part of the gradient (along the wall) when we calculate the laplacian: = ( ) Unfortunately I couldn't find any information about tangential laplacian so let me explain my formula by myself: A vector has a normal and a tangential component.A tangential component of any vector is a full vector minus the normal one: = - = - () = (I - ) That means that (I - ) is a projection tensor. Laplacian is a dot product of two vectors: = So, we want to use only the tangential part. That means that we have to project our gradients before taking the laplacian. = ((I - )) ((I - ) ) = ((I - )(I - )) I understand how to calculate the whole right part besides a divergence: ((I - )(I - )) I do not understand how to take a divergence of this term, because we store this part in vectorField: Code:
vectorField tangGradPotE = ((I - sqr(nf))&(I – sqr(nf)) & gradPotE.boundaryFieldRef()[patchID].patchInternalField()); Best regards, Tar |
||
July 26, 2018, 05:33 |
|
#65 | |
Super Moderator
Philip Cardiff
Join Date: Mar 2009
Location: Dublin, Ireland
Posts: 1,093
Rep Power: 34 |
Hi Tar,
OK, I understand a bit better now. Quote:
You can explicitly calculate the term as: Code:
volScalarField divTangGrad = fvc::div ( Sf & ( (I - sqr(n)) & (I - sqr(n)) & fvc::interpolate(fvc::grad(phi)) ) ); Code:
const surfaceVectorField& Sf = mesh.Sf(); const surfaceVectorField n = mesh.Sf()/mesh.magSf(); I think this makes sense but please double check it. Philip |
||
July 26, 2018, 11:22 |
|
#66 | |
New Member
Artem
Join Date: Apr 2014
Posts: 29
Rep Power: 12 |
Quote:
Thank you very much for your answer. I have checked it and concluded that this part is not right: Code:
Sf & ((I - sqr(n)) & (I - sqr(n)) & fvc::interpolate(fvc::grad(phi)) (I - sqr(n)) & (I - sqr(n)) & fvc::interpolate(fvc::grad(phi)) - projected vector Sf - normal vector That means that we have a scalar multiplication between two orthogonal vectors and it equals to zero. I also tried this in openFoam and got zero everywhere. Can we do some tricks and change area normal with something else? |
||
July 26, 2018, 11:33 |
|
#67 |
Super Moderator
Philip Cardiff
Join Date: Mar 2009
Location: Dublin, Ireland
Posts: 1,093
Rep Power: 34 |
Ah yes, that makes sense. The projection removes the normal component but then the divergence takes only the normal component.
Hmnn actually, we can note the following equivalence: . And then also we can note that the divergence of the tangential component of the gradient of a scalar is always zero: . So now I realise that I once again don't understand what exactly this tangential Laplacian operator is meant to be :O I guess if you know what you want to do for a simple structured grid, then generalising it to unstructured grids in OpenFOAM should not be an issue if you can explain the behaviour you want for the simple case. Philip |
|
July 27, 2018, 06:44 |
|
#68 |
New Member
Artem
Join Date: Apr 2014
Posts: 29
Rep Power: 12 |
Dear Philip,
Thank you very much for your effort. Anyway, I learned a lot from this topic. I will try to do something and if I succeed I will share my ideas in this topic. Best regards, Tar |
|
September 9, 2018, 14:29 |
|
#69 | |
Member
Pavan
Join Date: Jan 2016
Posts: 53
Rep Power: 10 |
Quote:
Can you let me know the function which can be called to force a boundary update during the iteration witina time loop |
||
September 7, 2020, 10:50 |
Updating the B.C. implicitly
|
#70 | |
New Member
shiyu
Join Date: Mar 2018
Location: london
Posts: 9
Rep Power: 8 |
Hi Philip,
Hope you are well. I found that you have provided several answers about updating the boundary conditions inside the OpenFOAM solver. I have also tried the code in your replies, which is working quite well. Thanks for your help. However, I have a question related to the code (I quoted) below. Does the value we extract from the boundary cell or face is based on the last timestep? I am wondering if you know how to update them at the same iteration (implicitly), like the fixedGradient B.C. ? What I mean is as below, U_f = a*U_c + b where the U_f and Uc are the boundary face values and boundary cell values, and most importantly, they are required to updated at the same time/iteration. The a and b are constant coefficients. That is to say, we need to implement this updating implicitly, rather than explicitly(if I am right). Many thanks, Shiyu Quote:
|
||
September 7, 2020, 11:18 |
|
#71 |
Super Moderator
Philip Cardiff
Join Date: Mar 2009
Location: Dublin, Ireland
Posts: 1,093
Rep Power: 34 |
Hi Shiyu,
In the code you have shown, the boundary value is updated explicitly using the latest value of the internal field. So when the equation is solved after this, the boundary value does not change and so this approach would be explicit rather than implicit. To make it implicit, you could do one of two things:
Philip |
|
December 13, 2021, 04:55 |
|
#72 | |
Senior Member
mohammad
Join Date: Sep 2015
Posts: 281
Rep Power: 12 |
Quote:
Hi Philip, I know it is a while that you are answering to the questions. But for me, this kind of BC update, every iteration for the fixedValue velocity, does not work. So, I hope you can help me to figure out what is going on here: Code:
// find ID of patch label patchID = mesh.boundaryMesh().findPatchID("sphere"); // check patch has been found if(patchID == -1) { FatalError << "patch not found!" << exit(FatalError); } Info<<"patchID: "<<patchID<<U.boundaryField()[patchID].type()<<endl; vectorField newPatchValues(U.boundaryField()[patchID].size(), vector::zero); forAll(U.boundaryField()[patchID],i) { newPatchValues[i] = vector(0, -0.1, 0); } U.boundaryField()[patchID] == newPatchValues; As I see, the patch velocity does not change through the iterations and the 0/fixedValue remains unchanged. Cheers, Mohammad |
||
December 13, 2021, 09:06 |
|
#73 |
Super Moderator
Philip Cardiff
Join Date: Mar 2009
Location: Dublin, Ireland
Posts: 1,093
Rep Power: 34 |
What U boundary condition are you using for the "sphere" patch?
Where in your solver do you call this code? You can check the current boundary condition and its values in the code, by printing it to the standard output, e.g. Code:
Info<< " U.boundaryField()[patchID] = " << U.boundaryField()[patchID] << endl; |
|
December 13, 2021, 18:49 |
|
#74 | |
Senior Member
mohammad
Join Date: Sep 2015
Posts: 281
Rep Power: 12 |
Quote:
By this printing output, it gives me the following lines: Code:
U.boundaryField()[patchID] = type fixedValue; value uniform (0 0 0); Code:
while (runTime.loop()) { Info<< "Time = " << runTime.timeName() << nl << endl; #include "CourantNo.H" label patchID = mesh.boundaryMesh().findPatchID("sphere"); if(patchID == -1) { FatalError << "patch not found!" << exit(FatalError); } vectorField newPatchValues(U.boundaryField()[patchID].size(), vector::zero); forAll(U.boundaryField()[patchID],i) { newPatchValues[i] = vector(0, -0.1, 0); } U.boundaryField()[patchID] == newPatchValues; Info<< " U.boundaryField()[patchID] = " << U.boundaryField()[patchID] << endl; // Pressure-velocity PISO corrector { #include "UEqn.H" // --- PISO loop while (piso.correct()) { #include "pEqn.H" } } laminarTransport.correct(); turbulence->correct(); runTime.write(); Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s" << " ClockTime = " << runTime.elapsedClockTime() << " s" << nl << endl; } Last edited by mostanad; December 13, 2021 at 20:26. |
||
December 14, 2021, 07:09 |
|
#75 |
Super Moderator
Philip Cardiff
Join Date: Mar 2009
Location: Dublin, Ireland
Posts: 1,093
Rep Power: 34 |
Which version of OpenFOAM are you using?
Maybe the "==" operator has been redefined, and the values need to be set using another approach. |
|
December 14, 2021, 07:48 |
|
#76 | |
Senior Member
mohammad
Join Date: Sep 2015
Posts: 281
Rep Power: 12 |
Quote:
Code:
template<class Type, template<class> class PatchField, class GeoMesh> void Foam::GeometricField<Type, PatchField, GeoMesh>::operator== ( const tmp<GeometricField<Type, PatchField, GeoMesh>>& tgf ) { const GeometricField<Type, PatchField, GeoMesh>& gf = tgf(); checkField(*this, gf, "=="); // Only assign field contents not ID ref() = gf(); boundaryFieldRef() == gf.boundaryField(); tgf.clear(); } template<class Type, template<class> class PatchField, class GeoMesh> void Foam::GeometricField<Type, PatchField, GeoMesh>::operator== ( const dimensioned<Type>& dt ) { ref() = dt; boundaryFieldRef() == dt.value(); } |
||
December 14, 2021, 08:45 |
|
#77 |
Super Moderator
Philip Cardiff
Join Date: Mar 2009
Location: Dublin, Ireland
Posts: 1,093
Rep Power: 34 |
Both of those functions refer to GeometricFields, however, in your case you are calling the "==" operator for a fvPatchField. From a quick check of the OF 5 Github code (https://github.com/OpenFOAM/OpenFOAM...fvPatchField.C) this should work; I am not sure what the problem is; however, instead you could try set the values face by face:
Code:
forAll(U.boundaryField()[patchID], faceI) { U.boundaryField()[patchID][faceI] = vector(0, -0.1, 0); } Info<< "U.boundaryField()[patchID] = " << U.boundaryField()[patchID] << endl; |
|
December 14, 2021, 09:09 |
|
#78 | |
Senior Member
mohammad
Join Date: Sep 2015
Posts: 281
Rep Power: 12 |
Quote:
I have tried this as well. But nothing changed. Can you please just try it on a titorial case and see what happens? I really need to have this changing BC option. Thank you for your help. |
||
December 14, 2021, 09:28 |
|
#79 |
Super Moderator
Philip Cardiff
Join Date: Mar 2009
Location: Dublin, Ireland
Posts: 1,093
Rep Power: 34 |
The following works in OpenFOAM-7 (I don't have OF-5), where I edited icoFoam.C:
Code:
Info<< "\nStarting time loop\n" << endl; while (runTime.loop()) { Info<< "Time = " << runTime.timeName() << nl << endl; #include "CourantNo.H" const label patchID = mesh.boundaryMesh().findPatchID("movingWall"); if (patchID == -1) { FatalError << "patch not found!" << exit(FatalError); } U.boundaryFieldRef()[patchID] == vector(0.001, 0, 0); Info<< "U.boundaryField()[patchID] = " << U.boundaryField()[patchID] << endl; // Momentum predictor fvVectorMatrix UEqn ( fvm::ddt(U) + fvm::div(phi, U) - fvm::laplacian(nu, U) ); ... The output on the cavity case for the last time-step is: Code:
Time = 0.5 Courant Number mean: 0.000222305 max: 0.000852393 U.boundaryField()[patchID] = type fixedValue; value uniform (0.001 0 0); smoothSolver: Solving for Ux, Initial residual = 2.41821e-07, Final residual = 2.41821e-07, No Iterations 0 smoothSolver: Solving for Uy, Initial residual = 5.28524e-07, Final residual = 5.28524e-07, No Iterations 0 DICPCG: Solving for p, Initial residual = 9.68699e-07, Final residual = 9.68699e-07, No Iterations 0 time step continuity errors : sum local = 8.74098e-12, global = -3.24571e-22, cumulative = 1.37819e-21 DICPCG: Solving for p, Initial residual = 1.02537e-06, Final residual = 8.70812e-07, No Iterations 1 time step continuity errors : sum local = 7.96321e-12, global = -7.50117e-22, cumulative = 6.28071e-22 ExecutionTime = 0.08 s ClockTime = 0 s End |
|
December 14, 2021, 18:23 |
|
#80 | |
Senior Member
mohammad
Join Date: Sep 2015
Posts: 281
Rep Power: 12 |
Quote:
Thanks Philip, Your are the master of OpenFOAM coding. Now it is working for OF5.x with U.boundaryFieldRef. I just insert the code to be in access for everybody working with this version: Code:
label patchID = mesh.boundaryMesh().findPatchID("sphere"); // check patch has been found if(patchID == -1) { FatalError << "patch not found!" << exit(FatalError); } vectorField newPatchValues(U.boundaryField()[patchID].size(), vector::zero); forAll(U.boundaryField()[patchID],i) { newPatchValues[i] = vector(0, -0.1, 0); } U.boundaryFieldRef()[patchID] == newPatchValues |
||
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Impinging Jet Boundary Conditions | Anindya | Main CFD Forum | 25 | February 27, 2016 13:58 |
OpenFOAM Variable Velocity Boundary Conditions | NickolasPl | OpenFOAM Programming & Development | 2 | May 19, 2011 06:37 |
Concentric tube heat exchanger (Air-Water) | Young | CFX | 5 | October 7, 2008 00:17 |
[Commercial meshers] Trimmed cell and embedded refinement mesh conversion issues | michele | OpenFOAM Meshing & Mesh Conversion | 2 | July 15, 2005 05:15 |
A problem about setting boundary conditions | lyang | Main CFD Forum | 0 | September 19, 1999 19:29 |