Доброго времени суток!
Совсем недавно появилась задача по аэродинамическому расчету на высотах 60-70 км (скорость М=25). Для учета проскальзывания потока на стенке необходимо написать UDF для Fluent'a, чем я сейчас и занимаюсь. В связи с тем, что до этого такими делами я никогда не занимался, то возникает непонятная для меня ошибка при компиляции кода: Error: rpgetvar: battery/enabled?: undefined variable. В хелпе читал про rp_get_var, правда не могу до конца понять, куда его можно пристроить, т.к. у меня по сути просто идет считывание производных скоростей и нормалей. Может кто-нибудь знает в чем проблема?
Код:
#include "udf.h"
#define LAMBDA 1.0994e-3DEFINE_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);
}
Здравствуйте!
Во-первых, такие ГУ уже реализованы во флюенте (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);
}
Доброе утро!
Спасибо Вам за ответ! Да, мне говорили, что Slip wall реализован для PB, но, к сожалению, для моей задачи он не подходит, т.к. разваливаются уравнения неразрывности и энергии, ну и по этой причине возникла необходимость в написании UDF. Насчет информации о Георгие Шоеве отдельное спасибо, непременно напишу ему!
1) У меня летательный аппарат разделен на три секции: фюзеляж, крыло, оперение и я думал, что нужно будет указывать отдельные ID ГУ и поэтому ввел Lookup_Thread, предполагая, что по указанным ГУ, компилятор будет понимать, сколько граней у него есть. В общем, еще раз в таком случае буду перечитывать UDF Manual.
Ещё раз на всякий случай - указатель на тред граней передается флюентом в качестве аргумента при вызове вашей функции автоматически, вам не нужно ничего делать. Назначите UDF в граничном условии фюзеляжа - переменная t (в моем варианте кода) будет "ссылаться" на грани фюзеляжа, и то же самое будет с крылом и оперением. Если же вы жестко пропишите ID конкретной границы, то ваш код будет правильно работать только для этой границы.
Все, теперь понял. Спасибо Вам!
Добавить комментарий