GPGPU labor XIII. Folyadék szimuláció. Kezdeti teendők Tantárgy honlapja, Folyadék szimuláció A labor kiindulási alapjának letöltése (lab13_base.zip),

Slides:



Advertisements
Similar presentations
Lecture Computer Science I - Martin Hardwick The Programming Process rUse an editor to create a program file (source file). l contains the text of.
Advertisements

#include void main() { float x = 1.66, y = 1.75; printf(%f%f,ceil(x), floor(y)); }
GPGPU labor IV. Scatter és gather. Kezdeti teendők Tantárgy honlapja, Scatter és gather A labor kiindulási alapjának letöltése (lab4_base.zip), kitömörítés.
Kezdeti teendők Letöltés: OgreBillboardParticles.zip Kicsomagol Futtat: OgreBillboardParticles.sln Include és library útvonalak beállítása Working directory.
Displacement mapping.
GPGPU labor VI. Rekurzív algoritmusok labirintus.
GPGPU labor VIII. OpenCL bevezetés. Kezdeti teendők Tantárgy honlapja, OpenCL bevezetés II. A labor kiindulási alapjának letöltése (lab8_base.zip), kitömörítés.
GPGPU labor XI. Monte Carlo szimuláció. Kezdeti teendők Tantárgy honlapja, Monte Carlo szimuláció A labor kiindulási alapjának letöltése (lab11_base.zip),
GPGPU labor IV. Scatter és gather. Kezdeti teendők Tantárgy honlapja, Scatter és gather A labor kiindulási alapjának letöltése (lab4_base.zip), kitömörítés.
GPGPU Labor 8.. CLWrapper OpenCL Framework primitívek – ClWrapper(cl_device_type _device_type); – cl_device_id device_id() – cl_context context() – cl_command_queue.
Senem Kumova Metin Spring2009 STACKS AND QUEUES Chapter 10 in A Book on C.
Dynamic Memory Allocation in C.  What is Memory What is Memory  Memory Allocation in C Memory Allocation in C  Difference b\w static memory allocation.
Lecture 5 Rendering lines 1.Steps of line rendering 2.Scan-conversion for line segments 3.A1 tutorial CP411 Computer Graphics Fall 2007 Wilfrid Laurier.
The lines of this object appear continuous However, they are made of pixels 2April 13, 2015.
Recursion October 5, Reading Read pp in the text.
Example 20 Fuzzy Control Lecture L10.2.
1 Class Vehicle #include #define N 10../.. 2 Class Vehicle class vehicle { public: float speed; char colour[N+1]; char make[N+1];
Lab 2 Variables in C.
Reference1. [OpenGL course slides by Rasmus Stenholt]
CS380 LAB I OpenGL Donghyuk Kim Reference1. [OpenGL course slides by Rasmus Stenholt] Reference2. [
Real-time Systems Lab, Computer Science and Engineering, ASU Linux Input Systems (ESP – Fall 2014) Computer Science & Engineering Department Arizona State.
C Tokens Identifiers Keywords Constants Operators Special symbols.
OpenCL Introduction AN EXAMPLE FOR OPENCL LU OCT
Practice 1 Seoul National University Graphics & Media Lab.
OpenCL Programming James Perry EPCC The University of Edinburgh.
CS-321 Dr. Mark L. Hornick 1 Line Drawing Algorithms.
Data Structure and c K.S.Prabhu Lecturer All Deaf Educational Technology.
Motor III. Merev test animáció Szécsi László. Letöltés diák: //l08-engine3.ppt.
Variables in C Topics  Naming Variables  Declaring Variables  Using Variables  The Assignment Statement Reading  Sections
© David Kirk/NVIDIA and Wen-mei W. Hwu, ECE408, University of Illinois, Urbana-Champaign 1 Programming Massively Parallel Processors Lecture.
CMSC 104, Version 8/061L09VariablesInC.ppt Variables in C Topics Naming Variables Declaring Variables Using Variables The Assignment Statement Reading.
Structures CSE 2031 Fall March Basics of Structures (6.1) struct point { int x; int y; }; keyword struct introduces a structure declaration.
Texture Mapping What is texture mapping? - a method for adding detail, surface texture (a bitmap or raster image), or color to a computer-generated graphic.
C syntax (simplified) BNF. Program ::= [ ] Directives ::= [ ] ::= | |… ::=#include > ::=#define.
Introduction to CUDA Programming Introduction to OpenCL Andreas Moshovos Spring 2011 Based on:
Heterogeneous Computing using openCL lecture 2 F21DP Distributed and Parallel Technology Sven-Bodo Scholz.
LESSON 3 IO, Variables and Operators
Linux 202 Training Module Program and Process.
What are Range Images?.
مبانی کامپیوتر و برنامه سازی
CMSC 104, Section 4 Richard Chang
Reserved Words.
Basic Graphics Drawing Shapes 1.
Gate Delay, Power, Scaling
ساختار ها در زبان C Structures in C.
null, true, and false are also reserved.
Folyadékszimuláció.
درس برنامه‌سازي کامپيوتر
Variables in C Topics Naming Variables Declaring Variables
Govt. Polytechnic,Dhangar
Variables in C Topics Naming Variables Declaring Variables
Local Variables, Global Variables and Variable Scope
JavaScript Reserved Words
Default Arguments.
Variables in C Declaring , Naming, and Using Variables.
Seoul National University
Programming for Art: Images
Monte Carlo simulation
2 types of scale factor problems
Function Overloading.
Programming Language C Language.
Monte Carlo simulation
Building Blocks of C Programming Language
Volumes by Cylindrical Shells Rita Korsunsky.
C Language B. DHIVYA 17PCA140 II MCA.
Variables in C Topics Naming Variables Declaring Variables
Variables in C Topics Naming Variables Declaring Variables
Seoul National University
Data in a C++ Program Numeric data and character data
Variables in C Topics Naming Variables Declaring Variables
Presentation transcript:

GPGPU labor XIII. Folyadék szimuláció

Kezdeti teendők Tantárgy honlapja, Folyadék szimuláció A labor kiindulási alapjának letöltése (lab13_base.zip), kitömörítés a GPGPU\Labs könyvtárba

Sebesség vektormező létrehozása Main.cpp, globális: int inputVelocityBuffer = 0; cl_mem velocityBuffer[2]; InitSimulation(): // simulation velocityBuffer[0] = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(cl_float2) * gridResolution * gridResolution, NULL, NULL); velocityBuffer[1] = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(cl_float2) * gridResolution * gridResolution, NULL, NULL);... // visualization kernels visualizationVelocityKernel = createKernel(simulationProgram, "visualizationVelocity");

Reset Globális: cl_kernel resetSimulationKernel; initSimulation() resetSimulationKernel = createKernel(simulationProgram, "resetSimulation"); keyUp(): case 'r': resetSimulation(); break;

Reset void resetSimulation() { CL_SAFE_CALL( clSetKernelArg(resetSimulationKernel, 0, sizeof(int), &gridResolution) ); CL_SAFE_CALL( clSetKernelArg(resetSimulationKernel, 1, sizeof(cl_mem), &velocityBuffer[inputVelocityBuffer]) ); CL_SAFE_CALL( clEnqueueNDRangeKernel(commands, resetSimulationKernel, 2, NULL, problemSize, NULL, 0, NULL, NULL) ); clFinish(commands); }

Programs.cl __kernel void resetSimulation(const int gridResolution, __global float2* velocityBuffer) { int2 id = (int2)(get_global_id(0), get_global_id(1)); if( id.x < gridResolution && id.y < gridResolution){ velocityBuffer[id.x + id.y * gridResolution] = (float2)(0.0f); }

Kezdeti reset initSimulation() { … resetSimulation(); }

Jelenítsük meg! Globális: cl_kernel visualizationVelocityKernel; visualizationStep(): CL_SAFE_CALL( clSetKernelArg(visualizationVelocityKernel, 0, sizeof(int), &width) ); CL_SAFE_CALL( clSetKernelArg(visualizationVelocityKernel, 1, sizeof(int), &height) ); CL_SAFE_CALL( clSetKernelArg(visualizationVelocityKernel, 2, sizeof(cl_mem), &visualizationBufferGPU) ); CL_SAFE_CALL( clSetKernelArg(visualizationVelocityKernel, 3, sizeof(int), &gridResolution) ); CL_SAFE_CALL( clSetKernelArg(visualizationVelocityKernel, 4, sizeof(cl_mem), &velocityBuffer[inputVelocityBuffer]) ); CL_SAFE_CALL( clEnqueueNDRangeKernel(commands, visualizationVelocityKernel, 2, NULL, visualizationSize, NULL, 0, NULL, NULL) ); clFinish(commands); //... //drawing

Programs.cl // TODO // MAP velocityBuffer TO visualizationBuffer // visualizationBuffer[x,y] := (1.0 + velocity) / 2.0 __kernel void visualizationVelocity(const int width, const int height, __global float4* visualizationBuffer, const int gridResolution, __global float2* velocityBuffer){ int2 id = (int2)(get_global_id(0), get_global_id(1)); if( id.x < width && id.y < height){ // TODO }

Próba

Erő hozzáadása void addForce(int x, int y, cl_float2 force){ float fx = (float)x / width; float fy = (float)y / height; CL_SAFE_CALL( clSetKernelArg(addForceKernel, 0, sizeof(float), &fx) ); CL_SAFE_CALL( clSetKernelArg(addForceKernel, 1, sizeof(float), &fy) ); CL_SAFE_CALL( clSetKernelArg(addForceKernel, 2, sizeof(cl_float2), &force)) ; CL_SAFE_CALL( clSetKernelArg(addForceKernel, 3, sizeof(int), &gridResolution) ); CL_SAFE_CALL( clSetKernelArg(addForceKernel, 4, sizeof(cl_mem), &velocityBuffer[inputVelocityBuffer]) ); CL_SAFE_CALL( clEnqueueNDRangeKernel(commands, addForceKernel,2, NULL, problemSize, NULL, 0, NULL, NULL) ); clFinish(commands); }

Erő hozzáadása Gloabális. cl_kernel addForceKernel; initSimulation() // simulation kernels addForceKernel = createKernel(simulationProgram, "addForce");

Programs.cl // TODO // // Add force to velocityBuffer // Add matter to densityBuffer // // Example: // dx := global_id(0) / gridResolution - x // dy := global_id(1) / gridResolution - y // radius := // c := e^(-(dx^2 + dy^2) / radius) * dt // // velocityBuffer[x,y] += c * force // densityBuffer[x,y] += c * density __kernel void addForce(const float x, const float y, const float2 force, const int gridResolution, __global float2* velocityBuffer, const float4 density, __global float4* densityBuffer){ int2 id = (int2)(get_global_id(0), get_global_id(1)); // TODO }

Próba

Advekció Global: cl_kernel advectionKernel; initSimulation(): advectionKernel = createKernel(simulationProgram, "advection"); simulationStep(): simulateAdvection();

Advekció void simulateAdvection() { CL_SAFE_CALL( clSetKernelArg(advectionKernel, 0, sizeof(int), &gridResolution) ); CL_SAFE_CALL( clSetKernelArg(advectionKernel, 1, sizeof(cl_mem), &velocityBuffer[inputVelocityBuffer]) ); CL_SAFE_CALL( clSetKernelArg(advectionKernel, 2, sizeof(cl_mem), &velocityBuffer[(inputVelocityBuffer + 1) % 2]) ); CL_SAFE_CALL( clEnqueueNDRangeKernel(commands, advectionKernel, 2, NULL, problemSize, NULL, 0, NULL, NULL) ); clFinish(commands); inputVelocityBuffer = (inputVelocityBuffer + 1) % 2; }

Programs.cl // TODO // // Inner parts: // velocity := inputVelocityBuffer[x,y] // p := id.xy - velocity.xy * dt // outputVelocity[x,y] = getBil(p, gridResolution, inputVelocityBuffer) // // Border: // outputVelocity = -inputVelocity (nearest neighbour) __kernel void advection(const int gridResolution, __global float2* inputVelocityBuffer, __global float2* outputVelocityBuffer){ int2 id = (int2)(get_global_id(0), get_global_id(1)); // TODO }

Próba

Diffúzió void simulateDiffusion(){ for(int i = 0; i < 10; ++i){ CL_SAFE_CALL( clSetKernelArg(diffusionKernel, 0, sizeof(int), &gridResolution) ); CL_SAFE_CALL( clSetKernelArg(diffusionKernel, 1, sizeof(cl_mem), &velocityBuffer[inputVelocityBuffer]) ); CL_SAFE_CALL( clSetKernelArg(diffusionKernel, 2, sizeof(cl_mem), &velocityBuffer[(inputVelocityBuffer + 1) % 2]) ); CL_SAFE_CALL( clEnqueueNDRangeKernel(cl.cqueue(), diffusionKernel, 2, NULL, problemSize, NULL, 0, NULL, NULL) ); clFinish(cl.cqueue()); inputVelocityBuffer = (inputVelocityBuffer + 1) % 2; }

Diffúzió // TODO // // Inner parts: // alpha := 1.0 / (viscousity * dt) // beta := 1.0 / (4.0 + alpha) // // vL := inputVelocityBuffer[x - 1, y] // vR := inputVelocityBuffer[x + 1, y] // vB := inputVelocityBuffer[x, y - 1] // vT := inputVelocityBuffer[x, y + 1] // // velocity := inputVelocityBuffer[x,y] // // outputVelocityBuffer[x,y] := (vL + vR + vB + vT + alpha * velocity) * beta // // Border: // outputVelocityBuffer[x,y] := inputVelocityBuffer[x,y] __kernel void diffusion(const int gridResolution, __global float2* inputVelocityBuffer, __global float2* outputVelocityBuffer){ int2 id = (int2)(get_global_id(0), get_global_id(1)); // TODO }

Divergencia, nyomás, projekció Global: int inputPressureBuffer = 0; cl_mem pressureBuffer[2]; cl_mem divergenceBuffer; cl_kernel divergenceKernel; cl_kernel pressureJacobiKernel; cl_kernel projectionKernel; initSimulation(): pressureBuffer[0] = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(float) * gridResolution * gridResolution, NULL, NULL); pressureBuffer[1] = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(float) * gridResolution * gridResolution, NULL, NULL); divergenceBuffer = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(float) * gridResolution * gridResolution, NULL, NULL); divergenceKernel = createKernel(simulationProgram, "divergence"); pressureJacobiKernel = createKernel(simulationProgram, "pressureJacobi"); projectionKernel = createKernel(simulationProgram, "projection");

Nyomás-reset resetSimulation(): CL_SAFE_CALL( clSetKernelArg(resetSimulationKernel, 2, sizeof(cl_mem), &pressureBuffer[inputPressureBuffer]) ); Reset kernel: void resetSimulation(const int gridResolution, __global float2* velocityBuffer, __global float* pressureBuffer) {... pressureBuffer[id.x + id.y * gridResolution] = 0.0f;...

nyomás - reset void resetPressure(){ CL_SAFE_CALL( clSetKernelArg(resetSimulationKernel, 0, sizeof(int), &gridResolution) ); CL_SAFE_CALL( clSetKernelArg(resetSimulationKernel, 1, sizeof(cl_mem), &velocityBuffer[(inputVelocityBuffer+1)%2]) ); CL_SAFE_CALL( clSetKernelArg(resetSimulationKernel, 2, sizeof(cl_mem), &pressureBuffer[inputPressureBuffer]) ); CL_SAFE_CALL( clEnqueueNDRangeKernel(commands, resetSimulationKernel, 2, NULL,problemSize, NULL,0, NULL, NULL) ); clFinish(commands); }

Projekció void simulationStep() { simulateAdvection(); projection(); }

Projekció- divergencia void projection(){ CL_SAFE_CALL( clSetKernelArg(divergenceKernel, 0, sizeof(int), &gridResolution) ); CL_SAFE_CALL( clSetKernelArg(divergenceKernel, 1, sizeof(cl_mem), &velocityBuffer[inputVelocityBuffer]) ); CL_SAFE_CALL( clSetKernelArg(divergenceKernel, 2, sizeof(cl_mem), &divergenceBuffer) ); CL_SAFE_CALL( clEnqueueNDRangeKernel(commands, divergenceKernel, 2, NULL, problemSize, NULL, 0, NULL, NULL) ); clFinish(commands); resetPressure();...

Projekció- Jacobi iteráció for(int i = 0; i < 10; ++i){ CL_SAFE_CALL( clSetKernelArg(pressureJacobiKernel, 0, sizeof(int), &gridResolution) ); CL_SAFE_CALL( clSetKernelArg(pressureJacobiKernel, 1, sizeof(cl_mem), &pressureBuffer[inputPressureBuffer]) ); CL_SAFE_CALL( clSetKernelArg(pressureJacobiKernel, 2, sizeof(cl_mem), &pressureBuffer[(inputPressureBuffer + 1) % 2]) ); CL_SAFE_CALL( clSetKernelArg(pressureJacobiKernel, 3, sizeof(cl_mem), &divergenceBuffer) ); CL_SAFE_CALL( clEnqueueNDRangeKernel(commands, pressureJacobiKernel, 2, NULL, problemSize, NULL, 0, NULL, NULL) ); clFinish(commands); inputPressureBuffer = (inputPressureBuffer + 1) % 2; }...

Projekció CL_SAFE_CALL( clSetKernelArg(projectionKernel, 0, sizeof(int), &gridResolution) ); CL_SAFE_CALL( clSetKernelArg(projectionKernel, 1, sizeof(cl_mem), &velocityBuffer[inputVelocityBuffer]) ); CL_SAFE_CALL( clSetKernelArg(projectionKernel, 2, sizeof(cl_mem), &pressureBuffer[inputPressureBuffer]) ); CL_SAFE_CALL( clSetKernelArg(projectionKernel, 3, sizeof(cl_mem), &velocityBuffer[(inputVelocityBuffer + 1) % 2]) ); CL_SAFE_CALL( clEnqueueNDRangeKernel(commands, projectionKernel, 2, NULL, problemSize, NULL, 0, NULL, NULL) ); clFinish(commands); inputVelocityBuffer = (inputVelocityBuffer + 1) % 2; }

Programs.cl // TODO // // Inner parts: // vL := velocityBuffer[x - 1, y] // vR := velocityBuffer[x + 1, y] // vB := velocityBuffer[x, y - 1] // vT := velocityBuffer[x, y + 1] // divergenceBuffer[x,y] := 0.5 * ((vR.x - vL.x) + (vT.y - vB.y)) // // Border: // divergenceBuffer[x,y] := 0.0 __kernel void divergence(const int gridResolution, __global float2* velocityBuffer, __global float* divergenceBuffer){ int2 id = (int2)(get_global_id(0), get_global_id(1)); // TODO }

Programs.cl // TODO // // Inner parts: //alpha := -1.0 //beta := 0.25 //vL := inputPressureBuffer[x - 1, y] //vR := inputPressureBuffer[x + 1, y] //vB := inputPressureBuffer[x, y - 1] //vT := inputPressureBuffer[x, y + 1] //divergence := divergenceBuffer[x,y] // //ouputPressure := (vL + vR + vB + vT + divergence * alpha) * beta // // Border: // ouputPressure[x,y] = inputPressureBuffer (nearest neighbour) __kernel void pressureJacobi(const int gridResolution, __global float* inputPressureBuffer, __global float* outputPressureBuffer, __global float* divergenceBuffer){ int2 id = (int2)(get_global_id(0), get_global_id(1)); // TODO }

Programs.cl // TODO // // Inner parts: // pL := pressureBuffer[x - 1, y] // pR := pressureBuffer[x + 1, y] // pB := pressureBuffer[x, y - 1] // pT := pressureBuffer[x, y + 1] // velocity := inputVelocityBuffer[x,y] // // outputVelocity[x,y] = velocity - (pR - pL, pT - pB) // // Border: // outputVelocity = -inputVelocity (nearest neighbour) __kernel void projection(const int gridResolution, __global float2* inputVelocityBuffer, __global float* pressureBuffer, __global float2* outputVelocityBuffer){ int2 id = (int2)(get_global_id(0), get_global_id(1)); // TODO }

Próba

Denzitás Globális int inputDensityBuffer = 0; cl_mem densityBuffer[2]; cl_float4 densityColor = {1,0,1,1}; cl_kernel advectionDensityKernel; cl_kernel visualizationDensityKernel; initSimulation() densityBuffer[0] = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(cl_float4) * gridResolution * gridResolution, NULL, NULL); densityBuffer[1] = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(cl_float4) * gridResolution * gridResolution, NULL, NULL); advectionDensityKernel = createKernel(simulationProgram, "advectionDensity"); visualizationDensityKernel = createKernel(simulationProgram, "visualizationDensity");

Reset resetSimulation() CL_SAFE_CALL( clSetKernelArg(resetSimulationKernel, 3, sizeof(cl_mem), &densityBuffer[inputDensityBuffer]) ); resetPressure(): CL_SAFE_CALL( clSetKernelArg(resetSimulationKernel, 3, sizeof(cl_mem), &densityBuffer[(inputDensityBuffer+1)%2]) ); Reset kernel:... __global float4* densityBuffer... densityBuffer[id.x + id.y * gridResolution] = (float4)(0.0f);

Anyag hozzáadása void addForce(int x, int y, cl_float2 force):... CL_SAFE_CALL( clSetKernelArg(addForceKernel, 5, sizeof(cl_float4), &densityColor) ); CL_SAFE_CALL( clSetKernelArg(addForceKernel, 6, sizeof(cl_mem), &densityBuffer[inputDensityBuffer]) ); addForce kernel: const float4 density, __global float4* densityBuffer... densityBuffer[id.x + id.y * gridResolution] += c * density;

Denzitás advekció simulation Step(): projection() simulateDensityAdvection(); void simulateDensityAdvection() { CL_SAFE_CALL( clSetKernelArg(advectionDensityKernel, 0, sizeof(int), &gridResolution) ); CL_SAFE_CALL( clSetKernelArg(advectionDensityKernel, 1, sizeof(cl_mem), &velocityBuffer[inputVelocityBuffer]) ); CL_SAFE_CALL( clSetKernelArg(advectionDensityKernel, 2, sizeof(cl_mem), &densityBuffer[inputDensityBuffer]) ); CL_SAFE_CALL( clSetKernelArg(advectionDensityKernel, 3, sizeof(cl_mem), &densityBuffer[(inputDensityBuffer + 1) % 2]) ); CL_SAFE_CALL( clEnqueueNDRangeKernel(commands, advectionDensityKernel, 2, NULL, problemSize, NULL, 0, NULL, NULL) ); clFinish(commands); inputDensityBuffer = (inputDensityBuffer + 1) % 2; }

Programs.cl // TODO // // Inner parts: // velocity := velocityBuffer[x,y] // p := id.xy - velocity.xy * dt // outputDensityBuffer[x,y] := getBil4(p, gridResolution, inputDensityBuffer) __kernel void advectionDensity(const int gridResolution, __global float2* velocityBuffer, __global float4* inputDensityBuffer, __global float4* outputDensityBuffer){ int2 id = (int2)(get_global_id(0), get_global_id(1)); // TODO }

megjelenítés void visualizationStep(){ switch(visualizationMethod){ case 0: CL_SAFE_CALL( clSetKernelArg(visualizationDensityKernel, 0, sizeof(int), &width) ); CL_SAFE_CALL( clSetKernelArg(visualizationDensityKernel, 1, sizeof(int), &height) ); CL_SAFE_CALL( clSetKernelArg(visualizationDensityKernel, 2, sizeof(cl_mem), &visualizationBufferGPU) ); CL_SAFE_CALL( clSetKernelArg(visualizationDensityKernel, 3, sizeof(int), &gridResolution) ); CL_SAFE_CALL( clSetKernelArg(visualizationDensityKernel, 4, sizeof(cl_mem), &densityBuffer[inputDensityBuffer]) ); CL_SAFE_CALL( clEnqueueNDRangeKernel(commands, visualizationDensityKernel, 2, NULL, visualizationSize, NULL, 0, NULL, NULL) ); break; case 1: CL_SAFE_CALL( clSetKernelArg(visualizationVelocityKernel, 0, sizeof(int), &width) ); CL_SAFE_CALL( clSetKernelArg(visualizationVelocityKernel, 1, sizeof(int), &height) ); CL_SAFE_CALL( clSetKernelArg(visualizationVelocityKernel, 2, sizeof(cl_mem), &visualizationBufferGPU) ); CL_SAFE_CALL( clSetKernelArg(visualizationVelocityKernel, 3, sizeof(int), &gridResolution) ); CL_SAFE_CALL( clSetKernelArg(visualizationVelocityKernel, 4, sizeof(cl_mem), &velocityBuffer[inputVelocityBuffer]) ); CL_SAFE_CALL( clEnqueueNDRangeKernel(commands, visualizationVelocityKernel, 2, NULL, visualizationSize, NULL, 0, NULL, NULL) ); break; } clFinish(commands);…

megjelenítés void keyUp(unsigned char key, int x, int y){... case 'd': visualizationMethod = 0; break; case 'v': visualizationMethod = 1; break;

Programs.cl // TODO // MAP densityBuffer TO visualizationBuffer // visualizationBuffer[x,y] := density __kernel void visualizationDensity(const int width, const int height, __global float4* visualizationBuffer, const int gridResolution, __global float4* densityBuffer){ int2 id = (int2)(get_global_id(0), get_global_id(1)); if( id.x < width && id.y < height){ // TODO }

Próba

Önálló feladat 1,2,3,4 stb. gombokra más-más színű anyagot adjunk hozzá Ne a középpontban, hanem az egér aktuális pozíciójában adjuk hozzá az erőt és az anyagot (Megjeleníthetjük a nyomást, divergenciát is) Sebesség diffúzió – Jacobi iteráció – A kernel hasonlít a nyomás számításánál használt Jacobi iterációs kernelre, csak a paraméterek mások (lásd elméleti anyag)

Vorticity Global: cl_mem vorticityBuffer; cl_kernel vorticityKernel; cl_kernel addVorticityForceKernel; initSimulation(): vorticityBuffer = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(float) * gridResolution * gridResolution, NULL, NULL); vorticityKernel = createKernel(simulationProgram, "vorticity"); addVorticityForceKernel = createKernel(simulationProgram, "addVorticity"); simulationStep(): simulateVorticity(); projection();

Vorticity void simulateVorticity() { CL_SAFE_CALL( clSetKernelArg(vorticityKernel, 0, sizeof(int), &gridResolution) ); CL_SAFE_CALL( clSetKernelArg(vorticityKernel, 1, sizeof(cl_mem), &velocityBuffer[inputVelocityBuffer]) ); CL_SAFE_CALL( clSetKernelArg(vorticityKernel, 2, sizeof(cl_mem), &vorticityBuffer) ); CL_SAFE_CALL( clEnqueueNDRangeKernel(commands, vorticityKernel,2, NULL, problemSize, NULL, 0, NULL, NULL) ); clFinish(commands); CL_SAFE_CALL( clSetKernelArg(addVorticityForceKernel, 0, sizeof(int), &gridResolution) ); CL_SAFE_CALL( clSetKernelArg(addVorticityForceKernel, 1, sizeof(cl_mem), &vorticityBuffer) ); CL_SAFE_CALL( clSetKernelArg(addVorticityForceKernel, 2, sizeof(cl_mem), &velocityBuffer[inputVelocityBuffer]) ); CL_SAFE_CALL( clEnqueueNDRangeKernel(commands, addVorticityForceKernel, 2, NULL, problemSize, NULL,0, NULL, NULL) ); clFinish(commands); }

Programs.cl __kernel void vorticity(const int gridResolution, __global float2* velocityBuffer, __global float* vorticityBuffer) { int2 id = (int2)(get_global_id(0), get_global_id(1)); if(id.x > 0 && id.x < gridResolution - 1 && id.y > 0 && id.y < gridResolution - 1){ float2 vL = velocityBuffer[id.x id.y * gridResolution]; float2 vR = velocityBuffer[id.x id.y * gridResolution]; float2 vB = velocityBuffer[id.x + (id.y - 1) * gridResolution]; float2 vT = velocityBuffer[id.x + (id.y + 1) * gridResolution]; vorticityBuffer[id.x + id.y * gridResolution] = (vR.y - vL.y) - (vT.x - vB.x); } else { vorticityBuffer[id.x + id.y * gridResolution] = 0.0f; }

Programs.cl __kernel void addVorticity(const int gridResolution, __global float* vorticityBuffer, __global float2* velocityBuffer) { int2 id = (int2)(get_global_id(0), get_global_id(1)); const float scale = 0.2f; if(id.x > 0 && id.x < gridResolution - 1 && id.y > 0 && id.y < gridResolution - 1){ float vL = vorticityBuffer[id.x id.y * gridResolution]; float vR = vorticityBuffer[id.x id.y * gridResolution]; float vB = vorticityBuffer[id.x + (id.y - 1) * gridResolution]; float vT = vorticityBuffer[id.x + (id.y + 1) * gridResolution]; float2 force = (float2)(fabs(vT) - fabs(vB), fabs(vR) – fabs(vL)); force = normalize(force); force *= scale * vorticityBuffer[id.x + id.y * gridResolution] * (float2)(1.0f, -1.0f); velocityBuffer[id.x + id.y * gridResolution] += force.xy * dt; }

Próba

Vége