Перед началом работы настоятельно рекомендуем ознакомиться с правилами форума.

Снова нужна помощь с UDF

EvgeniiRylkov
Аватар пользователя EvgeniiRylkov

Добрый день, помогите разобраться с еще одним вопросом касающимся UDF.
Вкратце опишу задачу: перемешивание двух фаз (VOF).  Нужно задать тепловой поток на определенной поверхности, которая контактирует сразу с двумя фазами. Значение теплового потока на поверхности ячейки зависит от фазы,с которой она контактирует. Для задания теплового потока использую макрос define_profile. Как определить к кокой фазе относится данная поверхность ячейки? Я попробовал сделать цикл sub_domain_loop, но ничего не вышло(структура кода ниже). Как сделать правильно? Сильно не ругайте, я еще новичок))

DEFINE_PROFILE(heat,ft,var){

int phase_domain_index;
face_t f;
cell_t c;
Thread *ct;
Domain *subdomain;
Domain *mixture_domain;
.....
sub_domain_loop(subdomain, mixture_domain, phase_domain_index){
    if (DOMAIN_ID(subdomain) == 2){
        begin_f_loop(f,ft){
             q = ((const1 + const2)*const3)/const4;
             F _PROFILE(f,ft,var) = q;
         }end_f_loop(f,ft)
    }
}

}

dvolkind
Аватар пользователя dvolkind

Здравствуйте! Поверхность ячейки не относится к какой-либо фазе. А тепловой поток, на мой взгляд, логичнее сделать зависимым от объемной доли нужной фазы.

EvgeniiRylkov
Аватар пользователя EvgeniiRylkov

Спасибо! Правильно я понимаю, чтобы так сделать сначала надо получить ячейку командой F_C0(f,face_t) и cell thread командой THREAD_T0(face_t), а потом запросить C_VOF(c, cell_t)? Возращенный результат сравнивать.

dvolkind
Аватар пользователя dvolkind

Ну да.

EvgeniiRylkov
Аватар пользователя EvgeniiRylkov

Попробовал, не получилось. Может быть из-за того, что в C_VOF(c,t), должен быть указатель на phase thread? Как его получить? Я попробовал так:
Thread *mixture_thread;
Thread *subthread = THREAD_SUB_THREAD(mixture_thread,phase_domain_index);
А далее C_VOF(c,subthread), но снова не получилось.

dvolkind
Аватар пользователя dvolkind

Индекс подставьте руками. Насколько я помню: 0 - смесь, 1 - первая фаза, 2 - вторая фаза и т.д.

EvgeniiRylkov
Аватар пользователя EvgeniiRylkov

Не работает. Ругается на неверный тип аргумента.
Сейчас код выглядит примерно, так:

DEFINE_PROFILE(heat,ft,var)
{
    double vof_prim_phase;
    /*int phase_domain_index = 1;*/
    face_t f;
    cell_t c;
    Thread *mixture_thread = THREAD_SUPER_THREAD(ft);
    Thread *subthread = THREAD_SUB_THREAD(mixture_thread,1);

    begin_f_loop(f,ft){
        ct = THREAD_T0(ft);
        c = F_C0(f,ft);
        vof_prim_phase = C_VOF(c, subthread);
        if(vof_prim_phase > 0){
        F_PROFILE(f,ft,var) = vof_prim_phase*10500;

    }
    }end_f_loop(f,ft)
}

В хелпе нашел макрос mp_thread_loop_f, но пока не понимаю, как им воспользоваться и нужен ли он. Пожскадите, может есть какая-нибудь спец. программа, чтобы удобно дебажить код, отслеживания значение переменных?

dvolkind
Аватар пользователя dvolkind

Здесь первый косяк:

Thread *mixture_thread = THREAD_SUPER_THREAD(ft)

Вы подставляете указатель на тред граней туда, где должен быть указатель на тред фазы. Но вы этод тред на данном этапе не знаете, он вам в конечном итоге и нужен в качестве аргумента для C_VOF. Посмотрите в хелпе раздел Multiphase Looping Macros.

EvgeniiRylkov
Аватар пользователя EvgeniiRylkov

Добрый день.
Посмотрел раздел Multiphase Looping Macros, но возникло еще больше вопросов. Буду признателен, если поможете с ними разобраться.
1.В случае макроса DEFINE_PROFILE(name,t,i) для многофазных моделей , t - это указатель на что? Нa mixture_thread?
Также в хелпе прочитал "The mixture thread is automatically passed to your UDF by the FLUENT solver when you use a DEFINE macro that contains a thread variable argument (e.g., DEFINE PROFILE) and your UDF is hooked to the mixture." Правильно я понимаю, что в случает DEFINE_PROFILE, не надо объявлять mixture_thread?(строка Thread *mixture_thread; получается бессмысленна?)
2.Так же не понятен принцип работы. THREAD_SUB_THREAD. Если в DEFINE_PROFILE(n,t,i), t - это указатель на mixter_thread, то почему не работает такой код:
Thread *subthread = THREAD_SUB_THREAD(t,0); 

dvolkind
Аватар пользователя dvolkind

Здравствуйте!

Цитата:
В случае макроса DEFINE_PROFILE(name,t,i) для многофазных моделей , t - это указатель на что? Нa mixture_thread?

Смотря куда вы его повесите в интерфейсе Fluent. Какие-то граничные условия задаются на уровне фаз (например, объемная доля), другие - на уровне смеси (например, тепловой поток на стенке или скорость на входе). Вы, насколько я понял, будете использовать UDF для задания плотности теплового потока, которая задается на уровне смеси, поэтому в вашем случае да, t будет содержать указатель на mixture thread.

Цитата:
Правильно я понимаю, что в случает DEFINE_PROFILE, не надо объявлять mixture_thread?(строка Thread *mixture_thread; получается бессмысленна?)

Опять же, если DEFINE_PROFILE используется на уровне смеси, то да, строка бессмысленна, т.к. ft уже содержит указатель на тред граней на уровне смеси.

Цитата:
почему не работает такой код: Thread *subthread = THREAD_SUB_THREAD(t,0); 

Если t содержит указатель на mixture thread, то не вижу в этой строке проблемы. Возможно, косяк в другом месте.

Еще поправлю себя:

Цитата:
Индекс подставьте руками. Насколько я помню: 0 - смесь, 1 - первая фаза, 2 - вторая фаза и т.д.

Правильно так: 0 - первичная фаза, 1 - первая вторичная, 2 - вторая вторичная и т.д.

Цитата:
Вы подставляете указатель на тред граней туда, где должен быть указатель на тред фазы.

Я должен был написать "вы подставляете указатель на тред граней на уровне смеси туда, где должен быть указатель на тред граней на уровне фазы". А лучше - срезу предположить бессмысленность этой строки, что вы и написали потом.

Прошу прощения за невнимательность.

Так попробуйте, у меня скомпилилось, протестировать не успел:

# include "udf.h"

DEFINE_PROFILE(heat,mix_ft,var)
{
    real vof_prim_phase;
    face_t f;
    Thread *sec_phase_ft = THREAD_SUB_THREAD(mix_ft,1);

    begin_f_loop(f,sec_phase_ft){
        vof_prim_phase = F_VOF(f, sec_phase_ft);
        if(vof_prim_phase > 0.0){
            F_PROFILE(f,mix_ft,var) = vof_prim_phase*10500;
        }
        else
        {
            F_PROFILE(f,mix_ft,var) = 0.0;
        }
    }end_f_loop(f,sec_phase_ft)
}

EvgeniiRylkov
Аватар пользователя EvgeniiRylkov

Дмитрий, спасибо! Вроде работает как надо, извеняюсь, что забыл сразу отписаться.

Добавить комментарий

Войдите или зарегистрируйтесь, чтобы отправлять комментарии
Приложить файл

Максимальный размер файла: 128 МБ.
Допустимые типы файлов: txt doc docx xls xlsx pdf rar zip 7zip tar.