Напрягаем мозги

Алгоритмы: от сортировки пузырьком до численных методов

Модераторы: C_O_D_E, DeeJayC

Ответить
SC
Сообщения: 5
Зарегистрирован: 04 мар 2005, 18:18

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



/*Следующий абзац можно пропустить, если вопрос непонятен тогда советую прочитать*/
Я хочу сделать так:
Создать класс Частица, который будет содержать номер,координаты частицы(2-х или 3-х мерная модель), направление движения (это тоже координаты куда частица переместится,проще куда направлена скорость) и скорость.
Методы: графическое отображение частицы, моделирование столкновения с другой частицей(соответственно меняется скорость, направление движения) и перемещение(изменение начальной координаты ), еще создать класс Броуновская Частица(БЧ), наследующий от класса Частица, в нем поменяются только координаты, это будет массив содержащий координаты оболочки частицы. И еще мне нужен массив для координат сосуда(молекулы и БЧ с ним сталкиваются).


/*Вопрос*/
В итоге у меня есть координаты молекул, частицы и сосуда. Вопрос в том, что когда я буду моделировать перемещение молекулы или частицы я должен буду перебирать координаты всех молекул для того чтобы узнать столкнется она с кем нибудь или нет, а это грустно и долго...


/*Как можно решить*/
И подходящего алгоритма на ум не приходит, можно конечно разделить сосуд на части и соответственно все молекулы по группам,находящимся в той или иной части. Т е взять самые крайние координаты сосуда(например х1 и х2), также для у (у1 и у2), и наложить своеобразную сетку.
Тогда в класс надо будет добавить номер ячейки в котором находить молекула .Теперь при перемещении мне достаточно проверять на совпадение координат только те молекулы которые находятся с моей в одной ячейке, и еще проверять ячейки окружающие мою(тк молекула может перелететь из одной ячейки в другую),причем перемещение(т е один "шаг ") будет не больше чем размер ячейки . Вот так можно решить, вроде понятно обьяснил.



Может кто-нибудь предложит другой алгоритм, лучше чем мой? Буду благодарен.
mm
Сообщения: 34
Зарегистрирован: 19 фев 2004, 10:36
Контактная информация:

Алгоритм не предложу. Посоветую физику почитать...
Фейнмановские лекции например...
Бум
Сообщения: 2
Зарегистрирован: 18 июн 2005, 11:59

задача очень интересна, неплохо учесть в решении этой задачи силы вязкости(не столкновения считать а молекулярное взаимодействие).
Вопрос: сколько времини (приблизительно) заемет моделирование такого движения на ПК?
Если есть полезная информация по теме или ссылки скинте на мыло, зарание благодарен.
Anton Tyo
Сообщения: 10
Зарегистрирован: 29 июн 2005, 20:54

"направление движения (это тоже координаты куда частица переместится,проще куда направлена скорость) и скорость" можно заменить проекцией вектора скорости на оси x,y и z.
Учитывается только одна сила, сила возникающая при столкновении двух частиц.
Большую частицу сделать не из кучи маленьких, а виде одной с массой и большим радиусом. У маленьких частиц впрочем тоже должна быть масса и радиус.
С сосудом посложнее может быть его форму задавать в виде аглебраической формулы? Можно оставить в виде частиц.
Чтобы не перебирать каждую частицу, это ты хорошо придумал, разбить пространство на кубы. У каждого куба список частиц. И проверять взаимодействия между частицами только в выбраном кубе, хотя нет, с прилежащими кубами тоже нужно делать проверку. Когда частица вылетает из куба, исключать её из списка куба, от куда частица вылетает, и включить её в список куба куда частица влетает.
Плохо то, что будет динамическая память сильно мачалиться, когда будет добавление и удаление из списка. Может для каждого куба выделить динамический массив, и сделать эмуляцию связанного списка. Ссылки не виде указателей, а в виде индексных ссылок. Удалять частицы просто менять ссылки,

A.n = A[A.n].n (где А - массив, n - индексная ссылка, удаляется i-ый элемент)

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

В общем на object pascal я это вижу вот так.

TParticle = class
P, V: TVector; // координаты и скорость
M: Real; // масса
R: Real; // радиус
I, J, K: Integer; // координаты кубов
end;

// метод определяет положение частицы относительно сосуда
procedure GetVesslN(P: TVector; var V: TVector; var S: Integer); // P - координата частицы, V вектор к ближайщей точке стенки
//сосуда, если S < 0 то частица погрузилась в стенку сосуда
TCub = array of record
P: TParticle;
N: Integer; // сылка на следующую частицу.
end;

TWorld = class
dT: Real; // шаг интегрирования
Ps: array of TParticle;
Cubs: array [0..MaxC - 1, 0..MaxC - 1, 0..MaxC - 1] of TCub;
procedure Pack; // упаковка массива
procedure Step; // осуществляет движение всех частиц
procedure StepP(P: TParticle); // осуществляет движение одной частицы
procedure CheckCub(P: TParticle); // осуществляем перенос частицы из одного куба в другой, если надо
end;

implementation

procedure TWorld.Step;
var
I: Integer;
begin
for I := 0 to High(Ps) do
StepP(Ps);
// если прошло досточно много времени то производим упаковку массива вызовом метода Pack
end;

procedure TWorld.StepP(P: TParticle);
var
I, J, K: Integer;
begin
for I := Max(0, P.I - 1) to Min(MaxC - 1, P.I + 1) do
for J := Max(0, P.J - 1) to Min(MaxC - 1, P.J + 1) do
for K := Max(0, P.K - 1) to Min(MaxC - 1, P.K + 1) do
begin
// осуществляем взаимодействие с частицами
end;
// осуществляем взаимодействие со стеной сосуда
CheckCub(P);
end;
Ну, вот что-то типа того.
Ответить