|
[Sponsors] |
How to access to the solid body motion state from a custom interDyMFoam.C ? |
|
LinkBack | Thread Tools | Search this Thread | Display Modes |
June 24, 2015, 17:07 |
How to access to the solid body motion state from a custom interDyMFoam.C ?
|
#1 |
Member
Jean-Michel FONTAINE
Join Date: Aug 2009
Location: Orleans - France
Posts: 55
Rep Power: 17 |
Hi every body
I'm stuck on this coding problem since weeks My target is to expose the solid body motion caracteristics to the solver, for instance v() or a(). I tried many ways, without success. Here is the current state of my attempts. The idea is to expose motionPtr_ via a public function. This is the modified dynamicMotionSolverFvMesh.H : Code:
#ifndef dynamicMotionSolverFvMesh_H #define dynamicMotionSolverFvMesh_H #include "dynamicFvMesh.H" namespace Foam { class motionSolver; class dynamicMotionSolverFvMesh: public dynamicFvMesh { // Private data autoPtr<motionSolver> motionPtr_; // Private Member Functions //- Disallow default bitwise copy construct dynamicMotionSolverFvMesh(const dynamicMotionSolverFvMesh&); //- Disallow default bitwise assignment void operator=(const dynamicMotionSolverFvMesh&); public: //- Runtime type information TypeName("dynamicMotionSolverFvMesh"); // Constructors //- Construct from IOobject dynamicMotionSolverFvMesh(const IOobject& io); //- Destructor ~dynamicMotionSolverFvMesh(); // Member Functions //- Update the mesh for both mesh motion and topology change virtual bool update(); // this is the additionnal public function <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Foam::motionSolver* motionSolverPtr() { return motionPtr_.ptr(); }; }; #endif Code:
Application interDyMFoam #include "fvCFD.H" #include "dynamicFvMesh.H" #include "CMULES.H" #include "subCycle.H" #include "immiscibleIncompressibleTwoPhaseMixture.H" #include "turbulenceModel.H" #include "pimpleControl.H" #include "fvIOoptionList.H" #include "fixedFluxPressureFvPatchScalarField.H" #include "dynamicMotionSolverFvMesh.H" // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< int main(int argc, char *argv[]) { #include "setRootCase.H" #include "createTime.H" #include "createDynamicFvMesh.H" #include "initContinuityErrs.H" // this is the attempt to call motionSolverPtr() <<<<<<<<<<<<<<<<<<<<<<< Foam::motionSolver* motionPtr; //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< motionPtr = Foam::dynamicMotionSolverFvMesh::motionSolverPtr(); //<<<<<< Info<< "motionPtr->v() = " << motionPtr->v() << nl << endl; //<<<<<<<<<< pimpleControl pimple(mesh); #include "createFields.H" #include "readTimeControls.H" #include "createPrghCorrTypes.H" volScalarField rAU ( IOobject ( "rAU", runTime.timeName(), mesh, IOobject::READ_IF_PRESENT, IOobject::AUTO_WRITE ), mesh, dimensionedScalar("rAUf", dimTime/rho.dimensions(), 1.0) ); #include "correctPhi.H" #include "createUf.H" #include "CourantNo.H" #include "setInitialDeltaT.H" Info<< "\nStarting time loop\n" << endl; while (runTime.run()) { #include "readControls.H" #include "alphaCourantNo.H" #include "CourantNo.H" #include "setDeltaT.H" runTime++; Info<< "Time = " << runTime.timeName() << nl << endl; // --- Pressure-velocity PIMPLE corrector loop while (pimple.loop()) { if (pimple.firstIter() || moveMeshOuterCorrectors) { scalar timeBeforeMeshUpdate = runTime.elapsedCpuTime(); mesh.update(); if (mesh.changing()) { Info<< "Execution time for mesh.update() = " << runTime.elapsedCpuTime() - timeBeforeMeshUpdate << " s" << endl; gh = g & mesh.C(); ghf = g & mesh.Cf(); } if (mesh.changing() && correctPhi) { // Calculate absolute flux from the mapped surface velocity phi = mesh.Sf() & Uf; #include "correctPhi.H" // Make the flux relative to the mesh motion fvc::makeRelative(phi, U); mixture.correct(); } if (mesh.changing() && checkMeshCourantNo) { #include "meshCourantNo.H" } } #include "alphaControls.H" #include "alphaEqnSubCycle.H" mixture.correct(); #include "UEqn.H" // --- Pressure corrector loop while (pimple.correct()) { #include "pEqn.H" } if (pimple.turbCorr()) { turbulence->correct(); } } runTime.write(); Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s" << " ClockTime = " << runTime.elapsedClockTime() << " s" << nl << endl; } Info<< "End\n" << endl; return 0; } Code:
interDyMFoam.C: In function ‘int main(int, char**)’: interDyMFoam.C:57:17: error: ‘motionSolverPtr’ is not a member of ‘Foam::dynamicMotionSolverFvMesh’ interDyMFoam.C:58:54: error: invalid use of incomplete type ‘class Foam::motionSolver’ In file included from interDyMFoam.C:44:0: /home/nous/OpenFOAM/OpenFOAM-2.3.x/src/dynamicFvMesh/lnInclude/dynamicMotionSolverFvMesh.H:45:7: error: forward declaration of ‘class Foam::motionSolver’ And furthermore the next question is : would motionPtr->v() give something ? I would appreciate any help Best regards Jean-Michel |
|
November 19, 2016, 08:09 |
[Solved] How to access to the solid body motion state from interDyMFoam.C ?
|
#2 |
Member
Jean-Michel FONTAINE
Join Date: Aug 2009
Location: Orleans - France
Posts: 55
Rep Power: 17 |
Hi
The solution for me was to use dictionaries in the object registry. Some example here after. Create the dictionary and write something: Code:
/* interDyMFoam.C */ // Creates the exchange dictionary in the registry dictionary dataDict; mesh.thisDb().store ( new IOdictionary ( IOobject ( "motion", runTime.timeName(), mesh, IOobject::NO_READ, IOobject::AUTO_WRITE ), dataDict ) ); // Open and write const dictionary& motionDict = mesh.thisDb().lookupObject<IOdictionary>("motion"); // Update for the motion solver dictionary updateDbDictionary = &motionDict; updateDbDictionary.set("centreOfRotation", initalCentreOfMass_); const_cast<dictionary& > (motionDict) = updateDbDictionary ; Code:
/* sixDoFRigidBodyMotionSolver.C */ if ( mesh().thisDb().foundObject<IOdictionary >("motion")) { const dictionary& dbDictionary = mesh().thisDb().lookupObject <IOdictionary >("motion"); point centreOfRotation = dbDictionary.lookupOrDefault("centreOfRotation", point(0, 0, 0)); } The const_cast trick allows overwriting everywhere. It come from the post #14 of this thread: http://www.cfd-online.com/Forums/ope...rfield-bc.html Without an access to time or mesh, for instance in sixDoFRigidBodyMotion.C, I did not found better solution than adding setter and getter functions, which is hassle. It a pity that not all the classes have access to registry. Hope this will be useful Jean-Michel Last edited by jmf; November 19, 2016 at 08:52. Reason: Added [Solved] |
|
February 23, 2017, 08:33 |
|
#3 |
New Member
Yu Han
Join Date: Nov 2014
Posts: 3
Rep Power: 12 |
Hi! Thank you for your contribution,I also need to get the solid body motion state in the main Foam-solver to calculate the quaternion . But I didn't make it work when I did what you say.Could you please help me?
I added the following code into myinterDyMFoam.C: Code:
#include "sixDoFRigidBodyMotion.H" #include "dynamicMotionSolverFvMesh.H" ... // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // Info<< "\nStarting time loop\n" << endl; while (runTime.run()) { ... // Creates the exchange dictionary in the registry dictionary dataDict; mesh.thisDb().store ( new IOdictionary ( IOobject ( "motion", runTime.timeName(), mesh, IOobject::NO_READ, IOobject::AUTO_WRITE ), dataDict ) ); // Open and write const dictionary& motionDict = mesh.thisDb().lookupObject<IOdictionary>("motion"); // Update for the motion solver dictionary updateDbDictionary = &motionDict; updateDbDictionary.set("centreOfRotation", initalCentreOfMass_); const_cast<dictionary& > (motionDict) = updateDbDictionary ; Code:
error: ‘initialCentreOfMass_’ was not declared in this scope updateDbDictionary.set("centreOfRotation", initialCentreOfMass_); ^ make: *** [Make/linux64GccDPInt32Opt/myinterDyMFoam.o] Error 1 I also put the second part of codes into sixDoFRigidBodyMotionStateIO.C(in void Foam::sixDoFRigidBodyMotionState::write(Ostream& os) const ,because I thought that the motion state would be exported with the sixDoFRigidBodyMotionState ) Code:
void Foam::sixDoFRigidBodyMotionState::write(Ostream& os) const { os.writeKeyword("centreOfRotation") << centreOfRotation_ << token::END_STATEMENT << nl; os.writeKeyword("orientation") << Q_ << token::END_STATEMENT << nl; os.writeKeyword("velocity") << v_ << token::END_STATEMENT << nl; os.writeKeyword("acceleration") << a_ << token::END_STATEMENT << nl; os.writeKeyword("angularMomentum") << pi_ << token::END_STATEMENT << nl; os.writeKeyword("torque") << tau_ << token::END_STATEMENT << nl; if ( mesh().thisDb().foundObject<IOdictionary >("motion")) { const dictionary& dbDictionary = mesh().thisDb().lookupObject <IOdictionary >("motion"); point centreOfRotation = dbDictionary.lookupOrDefault("centreOfRotation", point(0, 0, 0)); } } Code:
sixDoFRigidBodyMotion/sixDoFRigidBodyMotionStateIO.C:59:15: error: ‘mesh’ was not declared in this scope if ( mesh().thisDb().foundObject<IOdictionary >("motion")) ^ sixDoFRigidBodyMotion/sixDoFRigidBodyMotionStateIO.C:59:38: error: ‘IOdictionary’ was not declared in this scope if ( mesh().thisDb().foundObject<IOdictionary >("motion")) Last edited by yuhan1991; February 23, 2017 at 09:41. |
|
February 25, 2017, 13:23 |
How to access to the solid body motion state from interDyMFoam.C
|
#4 |
Member
Jean-Michel FONTAINE
Join Date: Aug 2009
Location: Orleans - France
Posts: 55
Rep Power: 17 |
Hi
First you have to declare and initialize initialCentreOfMass_, possibly from dynamicMeshDict, like this : Code:
IOdictionary dynamicMeshDict ( IOobject ( "dynamicMeshDict", runTime.constant(), mesh, IOobject::MUST_READ, IOobject::NO_WRITE ) ); dictionary subDict = dynamicMeshDict.subDict("tightBodyMotionCoeffs"); vector initalCentreOfMass_ = subDict.lookup("centreOfMass"); But I'm afraid that like sixDoFRigidBodyMotion, sixDoFRigidBodyMotionStateIO doesnt have any access to mesh(), mesh, neither to time or time(), which carry the registry. If you really need to exchange data with them, a inelegant way is to write setter and getter methods in sixDoFRigidBodyMotionStateIO.C. Here is an example you will have to adapt to your needs : Code:
void Foam::sixDoFRigidBodyMotion::set_v0(Foam::vector v) { v0_ = v;} Foam::vector Foam::sixDoFRigidBodyMotion::get_v0() { return v0_;} Jean-Michel Last edited by jmf; February 25, 2017 at 13:30. Reason: Was unclear |
|
March 6, 2017, 10:07 |
|
#5 |
New Member
Yu Han
Join Date: Nov 2014
Posts: 3
Rep Power: 12 |
Hi Fontaine! Thank you for your help again! Recently I have already made this work successfully . Now I can get the 6dof motion of the body from sixDofRigidBodyDisplacementPointPatchVectorField:: updateCoeffs() and write them to a dictionary in the main solver . So you can use them anywhere while the program is running(but the user must be able to access the object registry).This is the code snippet in the main solver:
Code:
dictionary dataDict; runTime.store ( new IOdictionary ( IOobject ( "motion", runTime.timeName(), runTime, IOobject::NO_READ, IOobject::AUTO_WRITE ), dataDict ) ); const dictionary& dbDictionary = runTime.lookupObject <IOdictionary >("motion"); Info <<"Get centreOfRotation from database:"<< dbDictionary.lookupOrDefault("centreOfRotation", point(0, 0, 0)) <<endl; Info <<"Get initialCentreOfRotation from database:"<< dbDictionary.lookupOrDefault("initialCentreOfRotation", point(0, 0, 0)) <<endl; Info <<"Get orientation from database:"<< dbDictionary.lookupOrDefault("orientation", tensor(0, 0, 0, 0, 0, 0, 0, 0, 0)) <<endl; Info <<"Get initialOrientation from database:"<< dbDictionary.lookupOrDefault("initialOrientation", tensor(0, 0, 0, 0, 0, 0, 0, 0, 0)) <<endl; Code:
void sixDoFRigidBodyDisplacementPointPatchVectorField::updateCoeffs() { ........ ....... if ( t.foundObject<IOdictionary >("motion")) { const dictionary& motionDict = t.lookupObject<IOdictionary>("motion"); dictionary updateDbDictionary = &motionDict; updateDbDictionary.set("centreOfRotation", motion_.state().centreOfRotation()); updateDbDictionary.set("initialCentreOfRotation", motion_.getinitialCentreOfRotation()); updateDbDictionary.set("orientation", motion_.orientation()); updateDbDictionary.set("initialOrientation", motion_.getinitialQ()); const_cast<dictionary& > (motionDict) = updateDbDictionary ; //without this code the result will still be ZERO!!! } Thank you for you help again Fontaine ! |
|
February 26, 2019, 21:45 |
|
#6 | |
Member
Dongxu Wang
Join Date: Sep 2018
Location: China
Posts: 33
Rep Power: 8 |
Quote:
I am facing a very similar problem recently. I have accessed the motion state by your method and I want to use it as a judgement of the stop of the PIMPLE outer loop. For example: I change the code: Code:
while(pimple.loop()) { /* pimpleloop */ } Code:
while(true) { /* pimpleloop */ if(condition) // condition is the parameter of rigid body that { // calculated in sixDOFSolver and obtained from break; // your method. In other words, the pimple outer } // loop will stop if the condition becomes true. } Code:
[1] --> FOAM FATAL IO ERROR: [1] error in IOstream "IOstream" for operation operator>>(Istream&, List<T>&) : reading first token [1] [1] file: IOstream at line 0. [1] [1] From function void Foam::IOstream::fatalCheck(const char*) const [1] in file db/IOstreams/IOstreams/IOstream.C at line 109. [1] FOAM parallel run exiting Code:
fvc::surfaceSum(mag(phi))().primitiveField() wdx |
||
March 2, 2019, 10:04 |
Works in serial mode, and not in paralle
|
#7 |
Member
Jean-Michel FONTAINE
Join Date: Aug 2009
Location: Orleans - France
Posts: 55
Rep Power: 17 |
Hi
In parallel each processor do its own job, ignoring the existence of the other procs. You have to ensure the consistency of the data that are used for your stop condition, and after that, to publish the condition to all the processors at the same time. So you may be interested in functions like this, to build your condition and publish it : Code:
if (Pstream::master()) { x = 1; } Pout<< x << endl; Pstream::scatter(x); Pout<< x << endl; Code:
Pstream::listCombineGather(force_, plusEqOp<vectorField>()); J-Michel |
|
March 3, 2019, 22:17 |
|
#8 | |
Member
Dongxu Wang
Join Date: Sep 2018
Location: China
Posts: 33
Rep Power: 8 |
Quote:
Thank you for your advice! I will try it recently and I will publish the result here. Thanks a lot. wdx. |
||
September 19, 2019, 21:59 |
|
#9 | |
New Member
Join Date: Jan 2018
Posts: 19
Rep Power: 8 |
Hi,yuhan! I don't know if you could get this message after long time. I am using your method, but the output was always zero. I found maybe my "motion" in my dyfoamsolver is not connected to the "motion" in sixDoFRigidBodyDisplacementPointPatchVectorField.C . Because if I change "motion" to "motion1" in my solver, it also compile. Do anyone knows why?
Best regards, ZHI CHENG Quote:
|
||
January 29, 2022, 20:31 |
|
#10 | |
Senior Member
TWB
Join Date: Mar 2009
Posts: 414
Rep Power: 19 |
Quote:
So do I add this: Code:
dictionary dataDict; runTime.store ( new IOdictionary ( IOobject ( "motion", runTime.timeName(), runTime, IOobject::NO_READ, IOobject::AUTO_WRITE ), dataDict ) ); const dictionary& dbDictionary = runTime.lookupObject <IOdictionary >("motion"); Info <<"Get centreOfRotation from database:"<< dbDictionary.lookupOrDefault("centreOfRotation", point(0, 0, 0)) <<endl; Info <<"Get initialCentreOfRotation from database:"<< dbDictionary.lookupOrDefault("initialCentreOfRotation", point(0, 0, 0)) <<endl; Info <<"Get orientation from database:"<< dbDictionary.lookupOrDefault("orientation", tensor(0, 0, 0, 0, 0, 0, 0, 0, 0)) <<endl; Info <<"Get initialOrientation from database:"<< dbDictionary.lookupOrDefault("initialOrientation", tensor(0, 0, 0, 0, 0, 0, 0, 0, 0)) <<endl; And also add: Code:
void sixDoFRigidBodyDisplacementPointPatchVectorField::updateCoeffs() { ........ ....... if ( t.foundObject<IOdictionary >("motion")) { const dictionary& motionDict = t.lookupObject<IOdictionary>("motion"); dictionary updateDbDictionary = &motionDict; updateDbDictionary.set("centreOfRotation", motion_.state().centreOfRotation()); updateDbDictionary.set("initialCentreOfRotation", motion_.getinitialCentreOfRotation()); updateDbDictionary.set("orientation", motion_.orientation()); updateDbDictionary.set("initialOrientation", motion_.getinitialQ()); const_cast<dictionary& > (motionDict) = updateDbDictionary ; //without this code the result will still be ZERO!!! } Lastly, how can i access the orientatio tensor from my modified oscillatingDisplacement mesh routine? Sorry, I am a Fortran programmer so my knowledge of c++ is limited. Thanks for the help. |
||
Tags |
custom solver, motion, state |
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Calculation of the Governing Equations | Mihail | CFX | 7 | September 7, 2014 07:27 |
[DesignModeler] Question about converting surface body to solid body in DesignModeler | lnk | ANSYS Meshing & Geometry | 2 | November 24, 2013 01:02 |
[DesignModeler] how to subtract a surface body from a solid body? | yahya | ANSYS Meshing & Geometry | 4 | January 7, 2013 12:00 |
cooling a solid body | Ralf Schmidt | FLUENT | 1 | April 16, 2007 11:54 |
Two-Phase Buoyant Flow Issue | Miguel Baritto | CFX | 4 | August 31, 2006 13:02 |