Все ответы об инженерном анализе

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

Моделирование течения с проскальзыванием через UDF

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

Доброго времени суток!

Совсем недавно появилась задача по аэродинамическому расчету на высотах 60-70 км (скорость М=25). Для учета проскальзывания потока на стенке необходимо написать UDF для Fluent'a, чем я сейчас и занимаюсь. В связи с тем, что до этого такими делами я никогда не занимался, то возникает непонятная для меня ошибка при компиляции кода: Error: rpgetvar: battery/enabled?: undefined variable. В хелпе читал про rp_get_var, правда не могу до конца понять, куда его можно пристроить, т.к. у меня по сути просто идет считывание производных скоростей и нормалей. Может кто-нибудь знает в чем проблема?

Код:

#include "udf.h"
#define LAMBDA 1.0994e-3

DEFINE_PROFILE(slip_velocity_x,t,i)
{
    int t_id=24;
    face_t f;
    cell_t c;
    Thread *thread=Lookup_Thread(domain, t_id);
    
    real A[ND_ND];
    real AA;

    real dudx, dudy, dudz, dwdx, dvdx;
    real nx, ny, nz;
    real uw_x;

    int j;

    begin_f_loop(f,thread)
    {
        c=F_C0(f,thread);
        ND_SET(dudx,dudy,dudz,C_DUDX(c,thread),C_DUDY(c,thread),C_DUDZ(c,thread));
        ND_SET(dudx,dvdx,dwdx,C_DUDX(c,thread),C_DVDX(c,thread),C_DVDX(c,thread));
        F_AREA(A,f,thread);
        AA=sqrt(ND_SUM(A[0]*A[0],A[1]*A[1]*A[1],A[2]*A[2]));
        //Normal components
        ND_SET(nx,ny,nz,-1.0*A[0]/AA,-1.0*A[1]/AA,-1.0*A[2]/AA);
        uw_x=ND_SUM(nx*dudx,0.5*ny*(dudy+dvdx),0.5*nz(dudz+dwdx));
        F_PROFILE(f,thread,i)=LAMBDA*uw_x;
    }
    end_f_loop(f,thread);
}

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

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

Во-первых, такие ГУ уже реализованы во флюенте (7.2.3. Slip Boundary Formulation for Low-Pressure Gas Systems), правда, для PB-солвера. Это так, на всякий случай. Я понимаю, что вы аэродинамику, скорее всего, считаете на DB. Для DB такие ГУ через UDF реализовывал Георгий Шоев из Новосибирска - можете поискать его публикации или написать ему, если знакомы.

По сути вопроса - я не представляю, почему он вдруг пытается при компиляции обратиться к переменной, отвечающей за подключение батареечного модуля. Попробовал просто скомпилить ваш код как есть, но у меня компилятор выдал вполне объяснимую (ниже) ошибку C2065. В общем, на меня не подействовало ваше колдовство, возможно сработал резист. Зато у вас в коде есть некоторые странности с указателями: 

1) DEFINE_PROFILE уже получает в качестве второго аргумента указатель на тред граничного условия, на которое вы повесили UDF, а вы зачем-то его ещё раз вытаскиваете через Lookup_Thread. Причем на месте его первого аргумента стоит необъявленный domain - отсюда C2065.

2) Даже если предположить, что кажущееся мне странностью решение из 1) служит какой-то благой цели, и вы скопировали не последнюю версию кода (а в последней domain объявлен и инициализирован), переменная thread у вас является указателем на тред граней, а вы внутри цикла используете её так, как будто она указывает на тред ячеек (например C_DUDX(c,thread) ищет ячейку с индексом c в треде граней). Вам нужен указатель на тред ячеек, и он достается макросом THREAD_T0.

Чтобы проверить свои предположения, я немного поправил код (чисто механически, не вникая в формулы), и он скомпилился. Дальше я не проверял, может ещё чего не заметил.

#include "udf.h"
#define LAMBDA 1.0994e-3

DEFINE_PROFILE(slip_velocity_x,t,i)
{
    int t_id=24;
    face_t f;
    cell_t c;
    Thread *thread;
    
    real A[ND_ND];
    real AA;

    real dudx, dudy, dudz, dwdx, dvdx;
    real nx, ny, nz;
    real uw_x;

    //int j;

    begin_f_loop(f,t)
    {
        c=F_C0(f,t);
        thread = THREAD_T0(t);
        ND_SET(dudx,dudy,dudz,C_DUDX(c,thread),C_DUDY(c,thread),C_DUDZ(c,thread));
        ND_SET(dudx,dvdx,dwdx,C_DUDX(c,thread),C_DVDX(c,thread),C_DVDX(c,thread));
        F_AREA(A,f,t);
        AA=sqrt(ND_SUM(A[0]*A[0],A[1]*A[1]*A[1],A[2]*A[2]));
        //Normal components
        ND_SET(nx,ny,nz,-1.0*A[0]/AA,-1.0*A[1]/AA,-1.0*A[2]/AA);
        uw_x=ND_SUM(nx*dudx,0.5*ny*(dudy+dvdx),0.5*nz(dudz+dwdx));
        F_PROFILE(f,t,i)=LAMBDA*uw_x;
    }
    end_f_loop(f,t);
}

 

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

Доброе утро! 

Спасибо Вам за ответ! Да, мне говорили, что Slip wall реализован для PB, но, к сожалению, для моей задачи он не подходит, т.к. разваливаются уравнения неразрывности и энергии, ну и по этой причине возникла необходимость в написании UDF. Насчет информации о Георгие Шоеве отдельное спасибо, непременно напишу ему!

1) У меня летательный аппарат разделен на три секции: фюзеляж, крыло, оперение и я думал, что нужно будет указывать отдельные ID ГУ и поэтому ввел Lookup_Thread, предполагая, что по указанным ГУ, компилятор будет понимать, сколько граней у него есть. В общем, еще раз в таком случае буду перечитывать UDF Manual.

 

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

Ещё раз на всякий случай - указатель на тред граней передается флюентом в качестве аргумента при вызове вашей функции автоматически, вам не нужно ничего делать. Назначите UDF в граничном условии фюзеляжа - переменная t (в моем варианте кода) будет "ссылаться" на грани фюзеляжа, и то же самое будет с крылом и оперением. Если же вы жестко пропишите ID конкретной границы, то ваш код будет правильно работать только для этой границы.

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

Все, теперь понял. Спасибо Вам!

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

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

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