Консультация № 191190
26.06.2017, 16:17
0.00 руб.
0 11 0
Здравствуйте, уважаемые эксперты! Прошу вас ответить на следующий вопрос:
У меня такое условие. Имеется Np- количество частиц.1) Мне их нужно разбить на группы. 2) Нужно создать цикл который перебирал все частицы. 3) Цикл по перебору соседних частиц. Например у меня имеется Np - частиц = 124567 штук. Мне нужно разбить их на М= 256 групп. Каждая частица обладает своим идентификатором - idr. Я разбила частицы на группы я номер группы определила так n0=id*Np/M. Мне нужен цикл по перебору частиц внутри группы я его записала так for n=(n0+Np/M). Цикл по перебору всех частиц я написала так for (np=0;Np-1; np++) где np - номер частицы. А цикл по перебору соседних частиц таким образом for (nn=0;Np-1;nn++) где nn - номер соседней частицы. Уважаемые эксперты помогите пожалуйста мне найти ошибки в моих циклах. Большое вам спасибо за помощь.

Обсуждение

давно
Старший Модератор
31795
6196
26.06.2017, 16:51
общий
Адресаты:
У Вас в группах получается разное количество частиц, т.к. 124567/256=486.58984375.


Если идентификатор частиц определить по такому правилу idr=256*numInGrup+numGrup, то можно легко перабрать все частицы, и путаницы меньше. Правда скорость паждает, но тем не мение.
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Посетитель
401233
6
26.06.2017, 17:03
общий
Адресаты:
Здравствуйте! Здесь количество частиц примерное их нужно будет выбрать так чтобы они делились нацело. А что вы скажите относительно других циклов по частицам правильно ли я их записала?
давно
Старший Модератор
31795
6196
26.06.2017, 17:13
общий
26.06.2017, 17:14
Адресаты:
Не видя всего кода сказать трудно.
Цикл перебора всех частиц:
Код:
for(inGrup=0;InGrupCount-1;inGrup++){
for(iGrup=0;GrupCount-1;iGrup++){
idr=inGrup*256+iGrup;
. . .
}
}

где
InGrupCount - количество частиц в одной группе;
GrupCount - количество групп.
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Посетитель
401233
6
26.06.2017, 17:28
общий
Адресаты:
У меня есть алгоритм но он для частиц которые находятся в ячейках. И там перебираются ближайщие ячейки а мне нужно его переделать так чтобы частицы не были привязаны к ячейкам. Спасибо вам!
давно
Старший Модератор
31795
6196
26.06.2017, 17:37
общий
Адресаты:
Цитата: Anzhela
У меня есть алгоритм

Покажите этот код.
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Посетитель
401233
6
26.06.2017, 17:42
общий
Адресаты:
Получается моя задача заключается в том чтобы переделать данный алгоритм так чтобы частицы не были привязаны к ячейкам а принцип работы его сохранился.
Прикрепленные файлы:
a81bda86b85e74c56fd92954f41922ad.docx
давно
Старший Модератор
31795
6196
28.06.2017, 18:50
общий
Адресаты:
Писать в ВОРДе код на С - супер.

Код:
kernelvoidPointWaves(//ОбъявлениеядраPointWaves
const int Np,//объявление и инициализация константы типа int с именем Np – число частиц.
сonst int Nm,//объявление и инициализация константы типа int с именем Nm – число материалов.
const int Nd,//объявление и инициализация константы типа int с именем Nd – расстояние
const int Nx,//Количество ячеек по оси х
const int Ny,//Количество ячеек по оси y
const int Nz,//Количество ячеек по оси z
__global float* CRD,//Глобальная переменная доступная всем функциям, объявленным в данном файле CRD – массив содержащий координаты и скорости частиц.
__global char* MTR,//объявление массива MTR – массив содержащий тип материала каждой частицы
__global float* FRC,//объявление массива FRC – массив, описывающий силу взаимодействия между частицами в зависимости от расстояний
__global unsigned int* ID3,//объявление массива ID3 – массив, содержащий идентификаторы частицв каждой ячейке
__global unsigned int* ID0,//Массив, содержащий идентификационный номер каждой частицы в трехмерном массиве ячеек Nx*Ny*Nz в начальный момент времени
const float d,//период решетки
const float dt)//шаг по времени
{
Const int idr=get_global_id(0);//переменная idr являющаяся константой=глобальному идентификатору процесса
if (idr>=Nz) return;//если (idr>=Nz) выход где Nz – количество ячеек по оси z
int nx,ny,nz,nnx,nny,nnz,n,nn,size,np,nnp,nr,mtr,mtrr,nF;//объявлениепеременных типом int
float x,y,z,x0,y0,z0,xx,yy,zz,vx,vy,vz,r,F,Fx,Fy,Fz,nr_,kr,r1,d2,krf,d9;//объявлениепеременных типом float
nz=idr;//идентификатор частицы
size=Nx*Ny*Nz;//размер расчетной сетки
d2=d*0.5;//расстояние при котором частица не покидает пределы ячейки.
d9=d2*0.99;//расстояние до границы области моделирования
krf=1.0/(7*d);//коэффициент пространственного масштаба для пересчёта на дискретную сетку
n=nz*Nx*Ny;//номер ячейки
for(ny=0;ny<Ny;ny++)//Цикл по номеру ячейки по оси Y
for(nx=0;nx<Nx;nx++)//Цикл по номеру ячейки по оси X
{
if(ID0[n]!=0)//если ID0 не равен нулю.Где ID0 - массив, содержащий старый идентификационный номер каждой частицы
{
np=ID0[n];//номер частицы определяется идентификационным номер содержащимся в массиве ID0[n]
x=CRD[np*10+3];//координата частицы х
y=CRD[np*10+4];//координата частицы у
z=CRD[np*10+5];//координата частицы z
vx=CRD[np*10+6];//скорость частиц вдоль оси х
vy=CRD[np*10+7];//скорость частицы вдоль оси у
vz=CRD[np*10+8];//скорость частицы вдоль оси z
mtr=MTR[np];//материал определяется из массива MTR
Fx=0;Fy=0;Fz=0;//обнуляем силовое воздействие
for(nnz=-4;nnz<=4;nnz++)//производим опрос соседних ячеек на наличие частицы в них по оси z
for(nny=-4;nny<=4;nny++)//производим опрос соседних ячеек на наличие частицы в них по оси у
for(nnx=-4;nnx<=4;nnx++)//производим опрос соседних ячеек на наличие частицы в них по оси х
{
nn=n+nnx+nny*Nx+nnz*Nx*Ny;//номер соседней частицы
if((nn>=0)&&(nn<size)&&(nn!=n))//Если соседняя частица не выходит за пределы массива и не равна по номеру текущей частице.
{
if(ID0[nn]!=0)//Проверка является ли соседняя ячейка пустой по ID
{
nnp=ID0[nn];//текущий номер соседней частицы в соседней ячейке
mtrr=MTR[nnp];//материал соседней частицы
x0=CRD[nnp*10+3]+nnx*d;//координаты соседней частицы
y0=CRD[nnp*10+4]+nny*d;//координаты соседней частицы
z0=CRD[nnp*10+5]+nnz*d;//координаты соседней частицы
r=sqrt((x-x0)*(x-x0)+(y-y0)*(y-y0)+(z-z0)*(z-z0));//расстояние между текущей частицей и соседней
if(r>0)
{
r1=1/r;
nr_=r*Nd*krf;//вычисление численного расстояния между текущей частицей и соседней
if(nr_>Nd-2)nr_=Nd-2;//проверка на условие не выхода за пределы массива
nr=nr_;//вычисление целочисленного расстояния между текущей частицей и соседней
kr=nr_-nr;//коэффициент интерполяции
nF=(mtr+mtrr*Nm)*Nd+nr+Nm;//выбор силового графика для конкретного сочетания материалов
F=FRC[nF]*(1-kr)+FRC[nF+1]*kr;//определение силы взаимодействия между текущей частицей и соседней
Fx=Fx-F*(x-x0)*r1;//силовое воздействие вдоль оси х
Fy=Fy-F*(y-y0)*r1;//силовое воздействие вдоль оси у
Fz=Fz-F*(z-z0)*r1;
}//силовое воздействие вдоль оси z
}
}
}
Fx=Fx/FRC[mtr];//Force devide by mass
Fy=Fy/FRC[mtr];//Force devide by mass
Fz=Fz/FRC[mtr];//Force devide by mass
ktr=0.05//коэффициент трения
vx=vx+(Fx-vx*ktr)*dt;//скорость частиц через промежуток времени dt с учетом коэффициента трения
vy=vy+(Fy-vy*ktr)*dt;//скорость частиц
vz=vz+(Fz-vz*ktr)*dt;//скорость частиц
CRD[np*10+6]=vx;//скорость частиц в массиве CRD
CRD[np*10+7]=vy;//скорость частиц в массиве CRD
CRD[np*10+8]=vz;//скорость частиц в массиве CRD
x=x+vx*dt;//определение координат частиц
y=y+vy*dt;//определение координат частиц
z=z+vz*dt;//определение координат частиц
//Ограничение координаты частицы при выходе на границу области моделирования:
if((x<-d2)&&(nx==0))x=-d2;
if((y<-d2)&&(ny==0))y=-d2;
if((z<-d2)&&(nz==0))z=-d2;
if((x>d9)&&(nx==Nx-1))x=d9;
if((y>d9)&&(ny==Ny-1))y=d9;
if((z>d9)&&(nz==Nz-1))z=d9;
//обнулить шаг перехода в соседнюю ячейку
nnx=0;nny=0;nnz=0;
//Если коодината частицы выходит за пределы ячейки, то изменить номер ячейки:
if(x<-d2)nnx=-1;if(y<-d2)nny=-1;if(z<-d2)nnz=-1;
if(y>=d2)nny=1;if(x>=d2)nnx=1;if(z>=d2)nnz=1;
x=x-nnx*d;//определение новых координат частиц в новой ячейке
y=y-nny*d;//определение новых координат частиц в новой ячейке
z=z-nnz*d;//определение новых координат частиц в новой ячейке
nn=n+nnx+nny*Nx+nnz*Nx*Ny;//определение соседней частицы
ID3[n]=0;//обнуляем массив, содержащий идентификационный номер каждой частицы в 3D-массиве
ID3[nn]=np;//определяем текущий номер частицы в массиве ID3
CRD[np*10+9]=*((float*)(&nn));//транспонируем массив из int в float
CRD[np*10+0]=x;//определяем координату частицы в массиве CRD
CRD[np*10+1]=y;//определяем координату частицы в массиве CRD
CRD[np*10+2]=z;//определяем координату частицы в массиве CRD
}
n++;
}
};


Отформатированный код функции.
Судя по коду получасется, что эти ячейки нужны для упрощения 3D-моделирования - непонятно каких частиц, имеющих массу и скорость. Вокруг текущей частицы создается 3D-куб, который позволяет, после своего заполнения систиматизировать ближайшие частицы по растоянию и степени взаимодействия - ну это и все. Зачем убирать ячейки этого куба не понятно.

Вам бы в разведке работать: каждую деталь приходится "с пытками" вырывать.

Тематика вопроса не известна.
Что происходит с массивами вне функции не известно.
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Посетитель
401233
6
03.07.2017, 21:25
общий
вы правы ячейки нужны для упрощения моделирования. Моя задача состоит в том чтобы расширить возможность применения алгоритма
давно
Посетитель
401233
6
04.07.2017, 04:51
общий
Адресаты:
Здравствуйте! Я переписала код в форме которой я бы хотела его видеть но у меня не работают циклы я не могу понять как их правильно записать.
Прикрепленные файлы:
afe8d391f4dda47ebb11b28daf4cef82.docx
давно
Старший Модератор
31795
6196
05.07.2017, 09:03
общий
Адресаты:
Цитата: Зенченко Константин Николаевич
Вам бы в разведке работать:

Мюллер:Штирлиц, Вы что издеваетесь?
Штрилиц:Нет, что Вы.
Мюлер:Тогда снимите буденовку.



1)Для, того, чтобы убрать этот 3D-куб, нужно будет весь переписывать код, который, кстати безобразно написан, к примеру:
Код:
                    x=CRD[np*10+3];//координата частицы х
y=CRD[np*10+4];//координата частицы у
z=CRD[np*10+5];//координата частицы z

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

2)
Цитата: Anzhela
Моя задача состоит в том чтобы расширить возможность применения алгоритма

Т.е. нужно будет прерписывать код(весь или почти весь), а для этого нужно знать как называется этот алгоритм(если это не секретно )
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Посетитель
401233
6
05.07.2017, 17:05
общий
Адресаты:
Здравствуйте не секретно. Это алгоритм по методу частиц в ячейках, который очень идеализированный. Для него выполняется условия наличия только одной частицы в ячейке. Он предназначен для моделирования твердого тела с кубической решеткой внутри которого распространяется возмущение в форме волны. Он предназначен для моделирования волн в твердых телах. Нужно расширить его возможности применения. Просто это только часть кода которую я вам скидывала только одно ядро а весь код достаточно длинный. В данном алгоритме используется технология OpenCL (для распараллеливания операций) а сам код написан на с++ в программе codeblocks.
Сейчас мне нужно сделать алгоритм который будет выполнять те же функции ну уже без ячеек.
Для будущего алгоритма: имеется некоторое количество частиц. Эти частицы нужно разбить на группы. Внутри каждой группы после разбиения будет находится некоторое количество частиц. Каждая частица обладает координатами х,у, z, и скоростями vx, vy, vz. В каждой группе находятся частицы которые взаимодействуют между собой после действия возмущающего воздействия. Для каждой частицы нужно 1) провести проверку на возможность установления связей с другими частицами из исходной группы. 2) Провести проверку на возможность установления связей частиц из данной группы с частицами из соседней группы.
Я хочу использовать приближение о том что область разбитая на ячейки можно условно считать как область разбитую на группы.
nz=idr; // идентификатор частицы
size=Ng; // размер расчетной области я приравняла к числу групп
n=nz*Ng; // номер
ng=nz*(Np/Ng) \\ разбиение частиц на группы
for(ng=o; ng<Ng; ng++) //цикл по номеру группы
далее я вычисляю координаты и скорости частиц
затем
for(np=0; np<ng; ng+Np/Ng) //цикл по числу частиц внутри группы
for (nng=-4;nng<=4;nng++) // производим перебор частиц в соседних группах
nn=n+ng*Ng;\n\ Номер соседней частицы
Я просто хочу понять правильно ли я записываю циклы приведенные выше.
Форма ответа