CFD Online Discussion Forums

CFD Online Discussion Forums (https://www.cfd-online.com/Forums/)
-   Fluent UDF and Scheme Programming (https://www.cfd-online.com/Forums/fluent-udf/)
-   -   User defined time step - Possible to put variable time stepping in it? (https://www.cfd-online.com/Forums/fluent-udf/201579-user-defined-time-step-possible-put-variable-time-stepping.html)

maccheese May 4, 2018 07:44

User defined time step - Possible to put variable time stepping in it?
 
Hi,

i am working on a simulation which contains the motion of a rigid wall zone defined by a profile.

The motion is divided into 3 phases:

1. Translation from A to B
2. Certain time span without motion
3. Translation from B back to A

I want to solve the simulation with a variable time step. At the beginning of my simulation, due to the movement of the wall zones a quite small initial time step is needed (to prevent mesh folding), which is 1e-6 in this case.

During phase 2, Fluent automatically increases the time step to sizes up to a few hundreths, which is fine and contributes to an acceptable calculation time.

The transition from phase 2 to 3 is where my problem is. Fluent would need to decrease the time step size to ~ 1e-6 for the wall zones to move back again. The variable time stepping can not cope with this and the simulation stops with negative cell volume error due to mesh folding. Although I defined a really small minimum time change factor, which would allow Fluent to reduce the time step size from one time step to the next to a size small enough for the mesh to not fold, Fluent fails with this.

So it looks like I need to use a user defined time step.

My question is if I can define a udf in the following way:

Fixed time step for certain amount of time at the beginning.

Use Variable Time stepping for Phase 2 of the simulation

Fixed time step for certain amount of time at the end.

So in other words, can I define the usage of the variable time stepping method in a user defined time step?

Thanks in advance!

AlexanderZ May 7, 2018 21:47

Ansys FLuent Customization Manual

2.2.2. DEFINE_DELTAT

best regards

maccheese May 8, 2018 07:51

Thanks Alexander, I know this chapter and it doensnīt answer my question.

I know well that user defined time stepping is possible.

I donīt know if it is possible to define automatic variable time stepping during a certain period of simulation time in a udf.

Like I wrote above, I would like to define a udf in this way:

1. Time period at the beginning with fixed time step size

2. Time period in the middle where automatic variable time stepping is desired

3. Time period at the end with fixed time step size

Best Regards

AlexanderZ May 8, 2018 21:16

if you know "time period" then take a look into tutorial example 2.2.2.3
Code:

/*********************************************************************
UDF that changes the time step value for a time-dependent solution
**********************************************************************/
#include "udf.h"
DEFINE_DELTAT(mydeltat,d)
{
real time_step;
real flow_time = CURRENT_TIME;
if (flow_time < 0.5)
time_step = 0.1;
else
time_step = 0.2;
return time_step;
}

best regards

maccheese May 15, 2018 14:12

Thank you for your reply Alexander.

The udf manuel provides an example for a changing time step size regarding the criteria of a certain point of time.

This doesnīt answer my question. I want to know if it is possible to define the use of variable time stepping in a udf.

Lets take a look on the example from the udf manuel:

#include "udf.h"
DEFINE_DELTAT(mydeltat,d)
{
real time_step;
real flow_time = CURRENT_TIME;
if (flow_time < 0.5)
time_step = 0.1;
else
time_step = 0.2;
return time_step;
}

So there is written that the time step size is 0.1 s if the simulation time is < 0.5 seconds. Otherwise it is 0.2 s.

But what if I wanted to change the time step 0.2 s into a variable time step size?

So under the else condition, thus the flow time not being < 0.5 s, Fluent should use a variable time step size which Fluent should automatically change regarding the criteria of the Courant Number. Like exactly what Fluent does when you define variable time stepping within limits you can define in the variable time step settings (which is named adaptive time step settings in older Fluent versions). There you define a minimum and a maximum time step size. Fluent will automatically increase the time step if the circumstances of the simulation allow it.

Can I put THIS mechanism in a udf file? Or is it only possible to use fixed time step sizes with user defined time steps?

In my simulation there is a certain period of time, where I would really need variable time stepping for a fast calculation time. This is "phase 2" which I mentioned in my original post. At some points during the beginning of this "phase 2", there is still a quite small time step size needed. Later on, the time step size increases significantly, which contributes to a quite fast calculation time. Thats exactly where I need variable time stepping. I cannot define a timely economic fixed time step size during this phase, because the Courant Number gets to big at some point and the calculation stops. On the other hand, I cannot define a really small fixed time step which would please the Courant Number fine but would increase my simulation time to the matter of weeks if not months.

AlexanderZ May 15, 2018 21:36

you may put in UDF everything you want, any criteria, algorithm and so on

best regards

pakk May 16, 2018 05:42

Quote:

The udf manual provides an example for a changing time step size regarding the criteria of a certain point of time.

This doesnīt answer my question. I want to know if it is possible to define the use of variable time stepping in a udf.
Variable time stepping = a changing time step size. So the udf manual provides a (very simple) example where variable time stepping is used in a udf. And you got an answer to what you asked.

But you wanted to know something else. In my words: how to sometimes set the time step, and other times use the one that Fluents wants to use.

My suggestion: try
Code:

return(CURRENT_TIMESTEP);
I did not try if it works, but it is worth a try.

maccheese May 16, 2018 07:52

I explained my question three times, and I think I explained it pretty detailed.

I know that any user defined time step represents a variable time step after all. Otherwise the idea of a user defined time step would be completely pointless.

I think I already made it clear in my original post, that I my question adresses the use of "automatic variable time stepping method" for a defined time span in an user defined time step. I provided the explanation of my intention along with my original post. It may still have been misunderstandable in my original post, but my second post should have made my intention very clear.

So yeah, if you just read "is variable time setting possible in user defined time step" you might think "of course, thats what user defined time steps are all about". But this is not the point of my question and I think I made that clear with my second post, where I wrote that I desire to define the automatic variable time stepping for a certain time span in a user defined time step.

Anyways, thank you for your answers.

pakk May 16, 2018 08:08

Well, I'm sorry if you feel offended, but your first question clearly says:

Quote:

My question is if I can define a udf in the following way:

Fixed time step for certain amount of time at the beginning.

Use Variable Time stepping for Phase 2 of the simulation

Fixed time step for certain amount of time at the end.
For me, this is solved by for example the following UDF, a slight modification of what is in the manual:

Code:

#include "udf.h"
DEFINE_DELTAT(mydeltat,d)
{
real time_step;
real flow_time = CURRENT_TIME;
if (flow_time < 0.5) {
 /*Fixed time step for certain amount of time at the beginning */
 time_step = 1e6;
} else if (flow_time < 2.5) {
 /*Use Variable Time stepping for Phase 2 of the simulation */
 time_step = 1e-2*(2+cos(flow_time));
} else {
 /*Fixed time step for certain amount of time at the end. */
 time_step = 1e6;
}
return time_step;
}

Only in your third post, I find out that you mean something else with 'automatic variable time stepping'. I don't know how I could have guessed that from the title or your initial two posts.

And to be clear, because I now realize that my previous post could have been written more 'tactful': the reason that I pointed out your inconsistency was not to make a fool of you, but to help other Fluent-users who come here from Google to be able to use the proper words for the mechanism that you describe.
I did not understand you the first two posts, and only after the third post I understood what you really meant, and I think it was only a matter of vague definitions, so I tried to make that clear. No offense meant.

maccheese May 16, 2018 08:45

Sorry, I didnīt mean to be feisty.

I am fairly new to Fluent and I have overcome quite a few obstacles in the past months on my way to get my simulation to work out.

The udf topic is quite a difficult one when you have no background in programming. You donīt learn C++ overnight, so I try to collect examples of udfs in the web and try to learn from their functions and their structure to realize my own udfs.

This problem I have right now may be the only one left for my simulation to finally complete its calculation. After that, I will (hopefully) be able to add more functions and details to my model and struggle my way further to success.

So this is why my question is of rather primitive nature. Experienced users may say: "Of course, everything is possible, just try it." But as a non-udf-experienced user, and a not really Fluent-experienced user besides, I canīt just try things because for that I always need examples from which I can derive the needed semantic and syntax to transfer it to my application. There are not too many examples of user defined time steps out there, so this is gonna be pretty difficult.

Your modified uts from the udf manual is one more example from which I can learn from, so thank you for that. I already have a question regarding the following expression:

time_step = 1e-2*(2+cos(flow_time))

From that I see that the time step size depends on the flow time. But what has cos to do with it? I recall having seen this kind of expression, but I canīt remember what the context was.

pakk May 16, 2018 09:03

First of all: you don't have to learn C++ to program UDFs. UDFs are written in C, not in C++. (I mention this because if you ever get stuck and get a book for cplusplus, you will get completely confused.)

Quote:

So this is why my question is of rather primitive nature.
No, your question was not of primitive nature. It is a completely reasonable thing to want to have, and it is something that should be possible to program, and it is not easy to find in the help how to do it, even though it should be.
Believe me: there are much more primitive questions here. On the level of 'Fluent says there is a semicolon missing on the end of line 19, what should I do about that?', where the obvious answer is 'add a semicolon at the end of line 19'. Your question is many levels higher.

Regarding my example,
Code:

time_step = 1e-2*(2+cos(flow_time));
This was just an example of a time step that varies between 0.01s and 0.03s. There was no special reason to choose cosine.

obscureed May 16, 2018 10:15

Hi maccheese,

You're welcome to ignore this if it derails the discussion, but I would not do it this way at all.
(1) To change from one set of time-step settings to another, I would typically use a journal file to change the settings and run. This is especially true here, where you can predict the time where you want to make the change.
(2) I have had no luck at all with adaptive time-stepping in Fluent, to the extent that I never even try it now. (I accept that adaptive time-stepping is a really good idea elsewhere, but there is some logic in not using it in CFD: the numerics are typically iterated inside each time-step, so a challenging time-step takes more effort than a small one, with more chance of diverging.)

To flesh this out a bit:
(1) Here is a journal file that sets up one timestep, runs for 1000 steps (with max iterations 20 per time-step), then changes and continues:
Code:

/solve/set/time-step 1e-6
/solve/dual-time-it 1000 20
;;; Maybe /file/write-case-data "runXYZ_end-phase1.cas" y
/solve/set/time-step 1e-3
/solve/dual-time-it 100 20
;;; Maybe /file/write-case-data "runXYZ_end-phase2.cas" y
;;; etc

(2) If you get good results with the automatic adaptive time-stepping, then you can find the journal command for it. To do this, don't bother with the Text Command List manual (or if you do work out how to use it, please tell me). Instead, find the command by exploring the text menu in the Fluent command window. Then answer each question, for example as follows:
Code:

/solve/set> adaptive-time-step Adaptive Time Stepping? [no] y
 Use user-defined time-step? [no] n
 Truncation Error Tolerance [0.01] 0.01
 Ending Time (s) [1000] 1000
 Minimum Time Step (s) [1e-05] 1e-7
 Maximum Time Step (s) [10] 2e-6
 Minimum Step Change Factor [0.5] 0.8
 Maximum Step Change Factor [5] 1.2
 Number of Fixed Time Steps [1] 1

The values in square brackets are defaults suggested by Fluent -- some of them are clearly inappropriate. I've tried to guess some conservative settings -- your answers may vary. So now you know the command is:
Code:

/solve/set/adaptive-time-step y n 0.01 1000 1e-7 2e-6 0.8 1.2 1
And you can put that in a journal file and run (with "/sol/dual 1000 10" etc -- commands can be abbreviated).

I hope this helps. Good luck!
Ed

obscureed May 16, 2018 10:39

Sorry, I forgot to point out some basics about journal files. (Apologies if these are obvious already.)

You save these commands into a text file with a suffix .jou. Put this file in the working directory (same as the Fluent .cas file). [I'm assuming you're not doing anything weird like running inside Workbench.] Then to run the commands, you go to the File menu and Read...journal. Or you can type the equivalent command into the text window: /file/read-journal "blah.jou".

You cannot simultaneously record one journal and run another journal. You can write a transcript, though, and I generally do, when I remember. You probably can put a "/file/read-journal blah2.jou" inside a journal -- this changed a few versions back.

You should be aware that journal commands are, in general, model-dependent. This makes sense: if you are setting the boundary conditions of a wall, say, then you will have to answer a whole lot more questions for a transient-, energy-, species-, reaction-solving case than for a simple one. This makes it difficult or impossible to write general-purpose journal files, and is frustrating.

One context-dependent example: a command such as
/file/write-case-data "phase1.cas"
will run fine the first time. But if phase1.cas already exists, Fluent will ask "OK to overwrite?", and then it will keep swallowing more and more of your journal until it finds something that it recognises as a yes or a no. Then it will resume reading. This can be a complete mess, so EVERY time I write a write command, I append " yes" to the command (without the quote marks):
/file/write-case-data "phase1.cas" y
If the " y" is not needed, I get a warning message "invalid command [y]", which I ignore. (This assumes that I am happy with over-writing. If not, I hide in the corner and refuse to use journal commands.)

You can apply a default answer to questions using a comma. Comments start with semicolons and last for the rest of the line. I like to give the full path for each command: for example "/dis/set/win/tex/dat NO". Other people don't, but other people are strange.

Learning journal files is a whole new world of running Fluent. It is powerful but remarkably painful. (And let's not mention Scheme or cortex yet.) Good luck!
Ed

maccheese May 16, 2018 11:52

Awesome, thats a whole lot of new input for me.

I hoped that there would be another way than using a user defined time step. I already struggled with the motion definition of some rigid walls in my model via udf and finally ended up using a profile which turned out to be much easier for my case.

Now I will look into the concept of journals in Fluent and try to solve my time step problem this way.

Thank you guys very much so far! I will keep you informed about the whether or not progress.

Best regards

maccheese May 23, 2018 07:45

Hi,

I tried to work out the basic concept of journal files and I think I got an overview on the topic.

There is one problem with this journal approach: I can not really predict the number of time steps for which the variable time stepping should be active. I know the time period, for which it should be active, but since the time step size is variable, I canīt predict the definite number of time steps.

I will try to re-run my simulation, look at how much time steps he uses during my "phase 2", and use that amount of time steps.

It is still very imprecise nonetheless...

Seems to me that the journal approach isnīt quite suited for my application because of that.

obscureed May 23, 2018 10:19

Hi maccheese,


Yes, I forgot about that aspect of variable/adaptive time-steps. For me, this is just another reason to avoid them entirely.


I would suggest that your Plan A is a journal with small, fixed timestep; then large, fixed; then small, fixed again. I don't really have a Plan B. If Plan A doesn't work, try Plan A with a smaller timestep. This, honestly, is the state of the art.



In theory, you could use Scheme to decide when to switch back to small, fixed timesteps -- but unless the adaptive time-stepping saves you days (compared to Plan A), which I doubt, then it's not worth the pain.


Tell us how it goes, please -- I would like to see my past experience updated. Good luck!
Ed

pakk May 23, 2018 10:44

Well, here is a bad idea that might do what you want:

Code:

(define doiteration
 (if (< (rpgetvar 'flow-time) 0.2)
  (begin (ti-menu-load-string "//solve/iterate 1") doiteration)
  (display "reached stage 3")))

(Not tested, so there might be some scheme-bugs here.)

Translated to c-like code:
Code:

/*note: don't use this, it does not work, it is just meant as example */
float flow_time; /*global variable for flow-time */

void doiteration() {
 if (flow_time<0.2) {
  run_one_iteration(); /*and this updates flow-time */
  doiteration();
 } else {
  echo "reached stage 3"; /*and end this function*/
 }
}

This is a recursive version of this:
Code:

/*note: don't use this, it does not work, it is just meant as example */
while (flow_time<0.2) {
 run_one_iteration;
}
echo "reached stage 3";

I say it is a bad idea because it will start and stop your simulation many times. But this might inspire you or somebody else to get a better idea.

AlexanderZ May 23, 2018 20:42

Quote:

Originally Posted by maccheese (Post 693295)
Hi,

I tried to work out the basic concept of journal files and I think I got an overview on the topic.

There is one problem with this journal approach: I can not really predict the number of time steps for which the variable time stepping should be active. I know the time period, for which it should be active, but since the time step size is variable, I canīt predict the definite number of time steps.

I will try to re-run my simulation, look at how much time steps he uses during my "phase 2", and use that amount of time steps.

It is still very imprecise nonetheless...

Seems to me that the journal approach isnīt quite suited for my application because of that.

what is your criteria for phase2 ? than for phase 3?

control this criteria (for instance temperature, pressure or whatever) and switch timestep accordingly using UDF, you do not need scheme for this problem

best regards

obscureed May 24, 2018 05:29

Hi AlexanderZ,

This gets back to the original question: is it possible to use Fluent's built-in adaptive timestepping inside a User-Defined Function timestep definition (DEFINE_DELTAT)? The answer to that question is no (I'm fairly sure).

So, if we are determined to try adaptive timestepping, but we want it to stop at a defined flow-time, how should we proceed? One available approach is Scheme -- something similar to what Pakk has proposed. As usual with Scheme, this will take some debugging, and it raises some concerns (Will the recursion eventually fill up the stack? Is it possible to interrupt the loop with CTRL-C or whatever?)

I would recommend Plan A compared to the pain of wrangling Scheme. But this is dodging the question. I would be interested to see other solutions that answer the question: adaptive timestepping, changing to fixed timestepping at a specified flow-time. And then I would be interested to hear whether it was worth the effort.

Once we have dodged the question and changed to fixed timesteps, there is a choice between journal and UDF to change the timestep. I would choose journal -- significantly more flexible, in my experience, with possibly lower traceability -- but again I'm interested to hear alternative views.

Cheers,
Ed

maccheese June 4, 2018 09:49

Hi guys,

just a short update: I use another method to solve my problem of the time step transition phase 2 to phase 3. I let Fluent calculate the simulation with variable time stepping until the exact point of time where phase 3 sets in. When this is completed, I switch to a fixed time step size which is small enough to cope with the speed of the rigids.

Not very elegant, but it works for now.

Thank you all for your answers, I have learned quite a bit from this thread.


All times are GMT -4. The time now is 22:09.