|
[Sponsors] |
December 21, 2013, 14:59 |
Creating time/temp dependant variable
|
#1 |
Member
Join Date: Aug 2013
Posts: 60
Rep Power: 12 |
I am trying to create a time and temperature dependant variable within the solidDisplacementFoam solver, currently the value is defined as a constant volScalarField as shown:
volScalarField mu("mu", E/(2.0*(1.0 + nu))); I need this to change in the following way: When reaching a certain temperature it should start increasing at a constant rate in time up till reaching a final value at which it stops increasing. I attempted to do this by adding the following code into the main .C file: Code:
forAll(mu.internalField(), cellI) { if(T.internalField()[cellI]>330){ mu.internalField()[cellI] = 10e+06; } } mu.correctBoundaryConditions(); Any help at all with this problem would be greatly appreciated. Thank you. Last edited by sur4j; December 22, 2013 at 06:07. |
|
December 22, 2013, 06:20 |
|
#2 |
Senior Member
Join Date: Jan 2012
Posts: 166
Rep Power: 14 |
hi,
I am not sure if it will work like this, but my idea would be something like this: Code:
forAll(mu.internalField(), cellI) { if(T.internalField()[cellI]>330 && T.internalField()[cellI]< LIMITTEMPERATURE ) { mu.internalField()[cellI] = FUNCTION FOR mu DEPENDENT ON TEMPERATURE T; } else { mu("mu", E/(2.0*(1.0 + nu))); } } mu.correctBoundaryConditions(); greetings maybee |
|
December 22, 2013, 07:11 |
|
#3 |
Member
Join Date: Aug 2013
Posts: 60
Rep Power: 12 |
Thank you for the reply. For this simulations I need to make it time dependant, there is no upper limit for the temperature. What I am trying to do is find out how to make the "FUNCTION OF mu DEPENDANT ON TIME", so that when the point reaches the specified temperature in the IF statement the variable increases at a certain rate in time for example:
IF "this point reaches 330K"{ "start increasing mu at this point at some rate for the next x seconds"} or you could even say something such as "start increasing mu at this point at some rate until reaching the value of mu=x at which point stop any further increase in mu" I attempted to program the temperature dependence in the IF statement I had wrote but don't know where to start with the time dependence. |
|
December 22, 2013, 07:51 |
|
#4 |
Senior Member
Join Date: Jan 2012
Posts: 166
Rep Power: 14 |
hi,
ok I think I have understood you now. Since the time loop is the master loop of every solver, you will have to tell the compiler by your code that after "T => 330" is reached mu takes for the next X seconds the value Code:
mu.OldTime() + specified value e.g. funciton The next problem will be the time you have to arrange. For example if you want to do this procedure shown in the above code for 5 seconds and the time step is 1 second you will have to tell the compiler something like Code:
if the temperature 330 was reached do the above for the next 5 seconds (5 time steps) My basic idea is to work with the GLOBAL variables "bool TempReached" and some kind of "count variable TempReachedTime" under which you save the time when T >= 330 was reached plus the time you want to increase mu (in the example 5 seconds). Afterwards you add some code like Code:
if (TempReached) //TempReached is to be set true when T >= 330 is reached { //and after the time your increasing has to be finished to be //set false again if (actualTime <= (TempReachedTime + Time to increase mu) ) { forAll(mu.internalField(), cellI) { mu.internalField()[cellI] = mu of internalField of oldTime + specified value; } mu.correctBoundaryConditions(); } } else { forAll(mu.internalField(), cellI) { other value for mu } mu.correctBoundaryConditions(); } Hope this helps you a little. |
|
December 22, 2013, 13:27 |
|
#5 |
Member
Join Date: Aug 2013
Posts: 60
Rep Power: 12 |
hi maybee,
Thank you so much for your help. I am a beginner in programming so am still trying to get my head around how the code works and how to add it to the solver. Just to confirm, will this code do the following: wait until a point inside the body reaches 330K temperature then starts increasing mu at that point at a set rate for say 5 seconds and then stop increasing mu an further? You mentioned I would have to store the mu field, this has not already been done, does this mean that I will have to create an array to store all of the values? Will the following link cover most of what I need to know? http://www.cplusplus.com/doc/tutorial/ |
|
December 22, 2013, 14:50 |
|
#6 | ||
Senior Member
Join Date: Jan 2012
Posts: 166
Rep Power: 14 |
hi again.
Quote:
Code:
mu = mu.OldTime() + specified value e.g. funciton Code:
If in a CELL the temperature 330 is reached do the above for this CELL the next 5 seconds (5 time steps) Code:
forAll(mu.internalField(), celli) { if (TempReached [celli]) //TempReached is to be set true when T >= 330 is reached { //and after the time your increasing has to be finished to be //set false again if (actualTime <= (TempReachedTime[celli] + Time to increase mu) ) { if (Temp [cellI] >= 330) //this assures that the temp is still equal/above 330 { mu.internalField()[cellI] = mu of internalField of oldTime + specified value; mu.correctBoundaryConditions(); } } else { mu.internalField()[celli] = other value } } -> for every cell you need a own bool TempReached, therefore a List of bools (or an arrat like you would say) -> for every cell you need variable TempReachedTime, therefore a List of Times -> I guess the List of temperatures for each cell already exists. [Should be a GeometricField] Quote:
For you link: The link covers the basics of c++ programming. It is absolutely necessary to understand the most of it. In the OpenFOAM code can be found much more, but this you should search for if needed for your project and after you know about the basics of programming. Please note that the basic solution idea I have given is probably just one way and perhaps not even the best. I am not a computer scientist, nor I am an expert when it comes to the OpenFOAM code, but I think my idea or something similar to it could work. |
|||
December 23, 2013, 14:01 |
|
#7 |
Member
Join Date: Aug 2013
Posts: 60
Rep Power: 12 |
hi Maybee,
Again, thank you for the very helpful detailed reply, I greatly appreciate the time you are spending with me on this. I think that I have gained a better understanding for the code now and have attempted to write the global variable arrays for TempReached and TimeTempReached: Code:
int TempReached [size];//how to get the maximum value for cellI to get the "size" value? int TempReachedTime [size]; forAll(mu.internalField(), cellI) { if(T.internalField()[cellI]>330){ TempReached [cellI] = true; TempReachedTime [cellI] = currentTime;//how to get the current time? } } Code:
if ((actualTime - TempReachedTime[cellI]) => Time to increase mu){ TempReached [cellI] = false; } Thanks. |
|
December 23, 2013, 14:59 |
|
#8 | |||||
Senior Member
Join Date: Jan 2012
Posts: 166
Rep Power: 14 |
Quote:
If you are lucky a method for getting the number of cells is already existing within the class, if not you have to find a own code solution... Quote:
Quote:
Code:
forAll(mu.internalField(), celli) { if (Temp[celli] >= 330) { TempReached [celli] = true; // added mechanism to set cell bool of bool array true ! } if (TempReached [celli]) //TempReached is to be set true when T >= 330 is reached { //and after the time your increasing has to be finished to be //set false again if (actualTime <= (TempReachedTime[celli] + Time to increase mu) ) { if (Temp [cellI] >= 330) //this assures that the temp is still equal/above 330 { mu.internalField()[cellI] = mu of internalField of oldTime + specified value; mu.correctBoundaryConditions(); } else { TempReached [celli] = false; mu.internalField()[celli] = other value } } else { mu.internalField()[celli] = other value } } Quote:
Aside from what I have posted you will surely have to check all the names I used in the basic IDEA, e.g. the object "actualTime" probably does not exist in this way -> you will have to search in the class Time object for it with something like "runTime.getTime" (in the solver I am working with the time object is called runTime -> look up your solver file). Quote:
Code:
//GLOBAL VARIABLES HERE DECLARED while(runTime.loop) { ..... } Code:
#include <iostream> int main() { int i = 0; int GLOBAL = 5; while (i < 10) { GLOBAL ++; i ++; } std::cout << GLOBAL << std::endl; std::cout << i << std::endl; return 0; } About the array see what I have written above. |
||||||
December 23, 2013, 15:21 |
|
#9 |
Member
Join Date: Aug 2013
Posts: 60
Rep Power: 12 |
Thanks for the fast and VERY helpful reply. Quick question, the simulations I plan on running with this solver are simple heat transfer simulations where a constant temperature BC is set at the walls therefore, I think that the temperature should only reach 330 once. For this simulation would the two dimensional array you mentioned above be necessary or could I continue using a simple 1D array?
|
|
December 23, 2013, 15:32 |
|
#10 | |
Senior Member
Join Date: Jan 2012
Posts: 166
Rep Power: 14 |
Quote:
Aside from this note, that you will have to define a mechanism that stores the time when temp >= 330 is reached, but exactly the time when it is reached the first time, since you want to use the "first occure time" for "TempReachedTime[celli]" within Code:
if (actualTime <= (TempReachedTime[celli] + Time to increase mu) |
||
December 23, 2013, 17:03 |
|
#11 |
Member
Join Date: Aug 2013
Posts: 60
Rep Power: 12 |
Is [cellI] an array? If so to find the size of the [cellI] could I not use the following simple code?
(sizeof((celli))/sizeof((celli[0]))) Where the size of the entire array is found in bytes and then divided by the size of a single element of that array to get the total number of elements? and then maybe to stay safe I could add a bit to it to make sure that there is enough elements. Or if not could the following be used? int a;//this sits outside the time loop forAll(mu.internalField(), celli) {a++;} Then use the value for "a" to define the size? |
|
December 24, 2013, 08:21 |
|
#12 | |
Senior Member
Join Date: Jan 2012
Posts: 166
Rep Power: 14 |
Quote:
Code:
int TempReachedTime [size]; Furthermore the forAll loop shows how you can access the different elements of the array and therefore an iterator (with the name celli) is used which number is increased with every loop pass, e.g. in the first pass celli is 0 therefore the first element of the array "TempReachedTime" is accessed, in the second pass celli is 1 therefore the second element of the array "TempReachedTime" is accessed and so on. But these all are c++ basics, if you can't understand it from tutorials use a c++ forum or a good book. See: https://www.google.com.tr/search?q=c...glish&safe=off You can also switch between tutorials if one doesn 't explain a content good enough for you... greetings maybee |
||
December 24, 2013, 10:24 |
|
#13 | ||
Member
Join Date: Aug 2013
Posts: 60
Rep Power: 12 |
Thank you for the reply. I did not realise that you could define a dynamic array by simply leaving the brackets empty, this will make things much simpler for me. I have started learning more about C++, I had read a lot about it in the past but never really understood it, I think this was because I never written the code and only looked at examples done by others therefore, I am going to write some code, to start off I wanted to see if an alternative method I had a while back to program this solver would work.
In my third post on this thread I had said: Quote:
Quote:
Code:
int deltaMu = the amount to increase mu each time step forAll(mu.internalField(), cellI) { if(T.internalField()[cellI]>330){ if(mu.internalField()[cellI]<(mu+(deltaMu*5))){ mu.internalField()[cellI]+=deltaMu mu.correctBoundaryConditions(); } } else{ mu.internalField()[cellI] = mu;//mu defined in previous code mu.correctBoundaryConditions(); } } EDIT: I added this code into the solver and it seems to work, do you notice anything that has been missed in this code? Would you suggest any improvements? Thanks Last edited by sur4j; December 24, 2013 at 11:55. |
|||
December 24, 2013, 11:13 |
|
#14 |
Senior Member
Join Date: Jan 2012
Posts: 166
Rep Power: 14 |
Your code:
Code:
int deltaMu = the amount to increase mu each time step forAll(mu.internalField(), cellI) { if(T.internalField()[cellI]>330){ if(mu.internalField()[cellI]<(mu+(deltaMu*5))){ mu.internalField()[cellI]+=deltaMu mu.correctBoundaryConditions(); } } else{ mu.internalField()[cellI] = mu;//mu defined in previous code mu.correctBoundaryConditions(); } } 1. Temp goes up to >=330 and mu.internalField() is increased like you want to for a specific time in every timestep. 2. Now the specific time is over -> what possibilities do we have: 2.1 The temperature is still >= 330 -> mu is increased again 2.2 The temperature is under 330 (e.g.325) -> mu instantly "jumps back" to another value -> from physical view strange My idea would be now : why not develop a mathematical function for mu in dependence of the temperature -> With this you could achieve a much more logical solution from a physical view (which is the important view here ). For example: Code:
int muMAX = yourvalue; forAll(mu.internalField(), cellI) { if(mu.internalField()[cellI]< muMAX) //checks if final value for mu is reached { mu.internalField()[cellI]+= muBASIS + (mu per Kelvin) * Temperature // 1Grade Function mu.correctBoundaryConditions(); } } else //in this else: mu for the limittemperature must be defined { mu.internalField()[cellI] =muMAX // in other words "maximal mu" mu.correctBoundaryConditions(); } } Plus you won't need any any other variables like arrays ... |
|
December 24, 2013, 12:05 |
|
#15 |
Member
Join Date: Aug 2013
Posts: 60
Rep Power: 12 |
Thanks for the improvements. Just out of interest, I had a problem when running the code I had previously written. When I use the following part of my code for example the solver compiles fine:
if(mu.internalField()[cellI]<(9e+06+(deltaMu*3))) However, when I change the constant to the defined value mu as shown, I get an error: if(mu.internalField()[cellI]<(mu+(deltaMu*3))) This is strange because it is defined the same way in the equations inside of the same file, for example in the DEqun: fvm::laplacian(2*mu + lambda, D, "laplacian(DD,D)") mu itself is defined as shown in another header file as shown below. This header file is included at the start of the main code. volScalarField mu("mu", E/(2.0*(1.0 + nu))); If it helps, the error I am getting when using wmake on the solver is the following: Code:
Making dependency list for source file cureFoam.C SOURCE=cureFoam.C ; g++ -m32 -Dlinux -DWM_DP -Wall -Wextra -Wno-unused-parameter -Wold-style-cast -O3 -DNoRepository -ftemplate-depth-100 -I/opt/openfoam222/src/finiteVolume/lnInclude -ItractionDisplacement/lnInclude -IlnInclude -I. -I/opt/openfoam222/src/OpenFOAM/lnInclude -I/opt/openfoam222/src/OSspecific/POSIX/lnInclude -fPIC -c $SOURCE -o Make/linuxGccDPOpt/cureFoam.o cureFoam.C: In function ‘int main(int, char**)’: cureFoam.C:82:46: error: no match for ‘operator<’ in ‘(& mu.Foam::GeometricField<Type, PatchField, GeoMesh>::internalField [with Type = double, PatchField = Foam::fvPatchField, GeoMesh = Foam::volMesh, Foam::GeometricField<Type, PatchField, GeoMesh>::InternalField = Foam::Field<double>]())->Foam::Field<double>::<anonymous>.Foam::List<double>::<anonymous>.Foam::UList<T>::operator[] [with T = double, Foam::label = int](cellI) < Foam::operator+(const Foam::GeometricField<double, PatchField, GeoMesh>&, const scalar&) [with PatchField = Foam::fvPatchField, GeoMesh = Foam::volMesh, Foam::scalar = double]((* &(Foam::scalar)(deltaMu * 3)))’ cureFoam.C:82:46: note: candidates are: /opt/openfoam222/src/OpenFOAM/lnInclude/dimensionedType.C:586:6: note: template<class Type> bool Foam::operator<(const Foam::dimensioned<Type>&, const Foam::dimensioned<Type>&) /opt/openfoam222/src/OpenFOAM/lnInclude/VectorSpaceI.H:677:13: note: template<class Form, class Cmpt, int nCmpt> bool Foam::operator<(const Foam::VectorSpace<Form, Cmpt, nCmpt>&, const Foam::VectorSpace<Form, Cmpt, nCmpt>&) readSolidDisplacementFoamControls.H:3:11: warning: unused variable ‘nCorr’ [-Wunused-variable] readSolidDisplacementFoamControls.H:5:8: warning: unused variable ‘convergenceTolerance’ [-Wunused-variable] make: *** [Make/linuxGccDPOpt/cureFoam.o] Error 1 |
|
December 24, 2013, 13:46 |
|
#16 |
Senior Member
Join Date: Jan 2012
Posts: 166
Rep Power: 14 |
hi,
I am not sure, but when you look at Code:
mu.internalField()[cellI] Code:
fvm::laplacian(2*mu + lambda, D, "laplacian(DD,D)") Code:
mu+(deltaMu*3) However, this is my guess . |
|
December 24, 2013, 14:01 |
|
#17 |
Member
Join Date: Aug 2013
Posts: 60
Rep Power: 12 |
Thanks for your help, I have a few more questions but will dedicate a new thread to them.
Last edited by sur4j; December 26, 2013 at 07:39. |
|
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Possible Bug in pimpleFoam (or createPatch) (or fluent3DMeshToFoam) | cfdonline2mohsen | OpenFOAM | 3 | October 21, 2013 09:28 |
emag beta feature: charge density | charlotte | CFX | 4 | March 22, 2011 09:14 |
error in COMSOL:'ERROR:6164 Duplicate Variable' | bhushas | COMSOL | 1 | May 30, 2008 04:35 |
Env variable not set | gruber2 | OpenFOAM Installation | 5 | December 30, 2005 04:27 |
Replace periodic by inlet-outlet pair | lego | CFX | 3 | November 5, 2002 20:09 |