├── .gitignore
├── .gitmodules
├── CMakeLists.txt
├── LICENSE
├── README.md
├── ReadMe.txt
├── TuringPatternKernels
├── PatternDynamic.cu
├── PatternDynamic.cuh
├── PatternType.h
└── TuringPatternKernels.vcxproj
├── TuringPatterns.cpp
├── TuringPatterns.sln
├── TuringPatterns.vcxproj
├── TuringPatterns.vcxproj.filters
├── TuringPatterns.vcxproj.user
├── TuringPatterns
├── TuringPatterns.vcxproj
├── TuringPatterns.vcxproj.user
└── main.cu
├── _config.yml
├── bacteria2_compressed.gif
├── bacteria_compressed.gif
├── br_stripes_compressed.gif
├── coral2_compressed.gif
├── coral3_compressed.gif
├── coral_compressed.gif
├── fhn_compressed.gif
├── fhnb_compressed.gif
├── lines_compressed.gif
├── patternRunner.py
├── plotter.py
├── schnakenberg_compressed.gif
├── stdafx.cpp
├── stdafx.h
└── targetver.h
/.gitignore:
--------------------------------------------------------------------------------
1 | /home/raiden/programming/TuringPatterns/cmake/.gitignore.in
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "cmake"]
2 | path = cmake
3 | url = git@github.com:pmontalb/CmakeUtilities.git
4 | [submodule "PdeFiniteDifferenceSolver"]
5 | path = PdeFiniteDifferenceSolver
6 | url = git@github.com:pmontalb/PdeFiniteDifferenceSolver.git
7 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.14)
2 | project(TuringPatterns)
3 |
4 | include(cmake/All.cmake)
5 | set(LANGUAGES_USE_CUDA ON CACHE BOOL "" FORCE)
6 |
7 | # PdeFiniteDifference
8 | add_subdirectory(PdeFiniteDifferenceSolver ${CMAKE_BINARY_DIR}/PdeFiniteDifferenceSolver EXCLUDE_FROM_ALL)
9 |
10 | create_cuda_library(
11 | NAME
12 | TuringPatternKernels
13 | SOURCES
14 | TuringPatternKernels/PatternDynamic.cu
15 | DEPENDENCIES
16 | CudaLightKernels
17 | PUBLIC_INCLUDE_DIRECTORIES
18 | TuringPatternKernels
19 | )
20 |
21 | create_cuda_executable(
22 | NAME
23 | TuringPatterns
24 | SOURCES
25 | TuringPatterns/main.cu
26 | DEPENDENCIES
27 | TuringPatternKernels PdeFiniteDifferenceSolverManager
28 | PRIVATE_INCLUDE_DIRECTORIES
29 | PdeFiniteDifferenceSolver
30 | SYSTEM_DEPENDENCIES
31 | forge
32 | )
33 |
34 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Paolo Montalbano
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Turing Patterns: A C++/CUDA application for simulating 2D reaction-diffusion dynamics showing diffusion driven instability
2 |
3 | This repository implements the numerical schemes for simulating the most popular reaction diffusion dynamics that exhibits Turing instability.
4 |
5 | The general two-dimensional PDE is of the form:
6 |
7 |
8 |
9 | The numerical scheme implemented is a simple Forward Euler scheme, which is known to be unstable but easy to implement. As opposed to the usual stability condition, the introduciton of a source term makes it more unstable, although dt in the region of dx^2 seem to be a reasonable choice. An extension to this could be a Runge-Kutta solver or an IMEX scheme, where the source term is considered in the explicit portion.
10 |
11 | The Finite Difference schemes are implemented in CUDA. Since the non-linear nature of the dynamics I found it easier to implement without making use of CuBLAS.
12 |
13 | The dynamics that I've implemented are:
14 | - Gray-Scott
15 | - Brussellator
16 | - Schnakernberg
17 | - Thomas
18 | - Fitz-Hugh Nagumo
19 |
20 | I made a python script that calls the C++ executable and gather the numerical results and produce the color plot animation. I saved the resulting GIFs, which are shown below:
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/ReadMe.txt:
--------------------------------------------------------------------------------
1 | ========================================================================
2 | CONSOLE APPLICATION : TuringPatterns Project Overview
3 | ========================================================================
4 |
5 | AppWizard has created this TuringPatterns application for you.
6 |
7 | This file contains a summary of what you will find in each of the files that
8 | make up your TuringPatterns application.
9 |
10 |
11 | TuringPatterns.vcxproj
12 | This is the main project file for VC++ projects generated using an Application Wizard.
13 | It contains information about the version of Visual C++ that generated the file, and
14 | information about the platforms, configurations, and project features selected with the
15 | Application Wizard.
16 |
17 | TuringPatterns.vcxproj.filters
18 | This is the filters file for VC++ projects generated using an Application Wizard.
19 | It contains information about the association between the files in your project
20 | and the filters. This association is used in the IDE to show grouping of files with
21 | similar extensions under a specific node (for e.g. ".cpp" files are associated with the
22 | "Source Files" filter).
23 |
24 | TuringPatterns.cpp
25 | This is the main application source file.
26 |
27 | /////////////////////////////////////////////////////////////////////////////
28 | Other standard files:
29 |
30 | StdAfx.h, StdAfx.cpp
31 | These files are used to build a precompiled header (PCH) file
32 | named TuringPatterns.pch and a precompiled types file named StdAfx.obj.
33 |
34 | /////////////////////////////////////////////////////////////////////////////
35 | Other notes:
36 |
37 | AppWizard uses "TODO:" comments to indicate parts of the source code you
38 | should add to or customize.
39 |
40 | /////////////////////////////////////////////////////////////////////////////
41 |
--------------------------------------------------------------------------------
/TuringPatternKernels/PatternDynamic.cu:
--------------------------------------------------------------------------------
1 | #include "PatternDynamic.cuh"
2 |
3 | EXTERN_C
4 | {
5 | /**
6 | * [u, v]' += dt * [f(u,v); g(u,v)]'
7 | */
8 | EXPORT int _ApplyPatternDynamic(MemoryBuffer u, MemoryBuffer v, const PatternType type, const double dt, const double param1, const double param2)
9 | {
10 | #define APPLY_PATTERN_DYNAMIC(TYPE)\
11 | switch (u.mathDomain)\
12 | {\
13 | case MathDomain::Float:\
14 | CUDA_CALL_SINGLE(__##TYPE##__, (float*)u.pointer, (float*)v.pointer, (float)dt, (float)param1, (float)param2, u.size);\
15 | break;\
16 | case MathDomain::Double:\
17 | CUDA_CALL_SINGLE(__##TYPE##__, (double*)u.pointer, (double*)v.pointer, (double)dt, (double)param1, (double)param2, u.size);\
18 | break;\
19 | default:\
20 | return CudaKernelException::_NotImplementedException;\
21 | }
22 |
23 | switch (type)
24 | {
25 | case PatternType::FitzHughNagumo:
26 | APPLY_PATTERN_DYNAMIC(FitzHughNagumo);
27 | break;
28 | case PatternType::Thomas:
29 | APPLY_PATTERN_DYNAMIC(Thomas);
30 | break;
31 | case PatternType::Schnakenberg:
32 | APPLY_PATTERN_DYNAMIC(Schnakenberg);
33 | break;
34 | case PatternType::Brussellator:
35 | APPLY_PATTERN_DYNAMIC(Brussellator);
36 | break;
37 | case PatternType::GrayScott:
38 | APPLY_PATTERN_DYNAMIC(GrayScott);
39 | break;
40 | default:
41 | return CudaKernelException::_NotImplementedException;
42 | }
43 |
44 | #undef APPLY_PATTERN_DYNAMIC
45 | return cudaGetLastError();
46 | }
47 | }
48 |
49 | template
50 | GLOBAL void __FitzHughNagumo__(T* RESTRICT uNew, T* RESTRICT vNew, const T dt, const T param1, const T param2, const size_t sz)
51 | {
52 | CUDA_FUNCTION_PROLOGUE
53 |
54 | CUDA_FOR_LOOP_PROLOGUE
55 |
56 | const T u = uNew[i];
57 | const T v = vNew[i];
58 | uNew[i] += dt * (u * (1.0 - u * u) - v + param1);
59 | vNew[i] += dt * param2 * (u - v);
60 |
61 | CUDA_FOR_LOOP_EPILOGUE
62 | }
63 |
64 | template
65 | GLOBAL void __Thomas__(T* RESTRICT uNew, T* RESTRICT vNew, const T dt, const T param1, const T param2, const size_t sz)
66 | {
67 | static constexpr T rho = { 13.0 };
68 | static constexpr T K = { 0.05 };
69 | static constexpr T alpha = { 1.5 };
70 | static constexpr T gamma = { 200.0 };
71 |
72 | CUDA_FUNCTION_PROLOGUE
73 |
74 | CUDA_FOR_LOOP_PROLOGUE
75 | const T u = uNew[i];
76 | const T v = vNew[i];
77 |
78 | const T h = rho * u * v / (1.0 + u + K * u * u);
79 |
80 | uNew[i] += dt * gamma * (param1 - u - h);
81 | vNew[i] += dt * gamma * (alpha * (param2 - v) - h);
82 |
83 | CUDA_FOR_LOOP_EPILOGUE
84 | }
85 |
86 | template
87 | GLOBAL void __Schnakenberg__(T* RESTRICT uNew, T* RESTRICT vNew, const T dt, const T param1, const T param2, const size_t sz)
88 | {
89 | CUDA_FUNCTION_PROLOGUE
90 |
91 | CUDA_FOR_LOOP_PROLOGUE
92 | const T u = uNew[i];
93 | const T v = vNew[i];
94 | const T u2v = u * u * v;
95 |
96 | uNew[i] += dt * (param1 - u + u2v);
97 | vNew[i] += dt * (param2 - u2v);
98 |
99 | CUDA_FOR_LOOP_EPILOGUE
100 | }
101 |
102 | template
103 | GLOBAL void __Brussellator__(T* RESTRICT uNew, T* RESTRICT vNew, const T dt, const T param1, const T param2, const size_t sz)
104 | {
105 | CUDA_FUNCTION_PROLOGUE
106 |
107 | CUDA_FOR_LOOP_PROLOGUE
108 | const T u = uNew[i];
109 | const T v = vNew[i];
110 | const T u2v = u * u * v;
111 |
112 | uNew[i] += dt * (param1 - (param2 + 1.0) * u + u2v);
113 | vNew[i] += dt * (param2 * u - u2v);
114 |
115 | CUDA_FOR_LOOP_EPILOGUE
116 | }
117 |
118 | template
119 | GLOBAL void __GrayScott__(T* RESTRICT uNew, T* RESTRICT vNew, const T dt, const T param1, const T param2, const size_t sz)
120 | {
121 | CUDA_FUNCTION_PROLOGUE
122 |
123 | CUDA_FOR_LOOP_PROLOGUE
124 | const T u = uNew[i];
125 | const T v = vNew[i];
126 | const T uv2 = u * v * v;
127 |
128 | uNew[i] += dt * (-uv2 + param1 * (1.0 - u));
129 | vNew[i] += dt * (uv2 - (param1 + param2) * v);
130 |
131 | CUDA_FOR_LOOP_EPILOGUE
132 | }
--------------------------------------------------------------------------------
/TuringPatternKernels/PatternDynamic.cuh:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | //#include
4 | #include
5 | #include
6 |
7 | #include "PatternType.h"
8 |
9 | EXTERN_C
10 | {
11 | /**
12 | * [u, v]' += dt * [f(u,v); g(u,v)]'
13 | */
14 | EXPORT int _ApplyPatternDynamic(MemoryBuffer u, MemoryBuffer v, const PatternType type, const double dt, const double param1, const double param2);
15 | }
16 |
17 | template
18 | GLOBAL void __FitzHughNagumo__(T* RESTRICT u, T* RESTRICT v, const T dt, const T param1, const T param2, const size_t sz);
19 |
20 | template
21 | GLOBAL void __Thomas__(T* RESTRICT u, T* RESTRICT v, const T dt, const T param1, const T param2, const size_t sz);
22 |
23 | template
24 | GLOBAL void __Schnakenberg__(T* RESTRICT u, T* RESTRICT v, const T dt, const T param1, const T param2, const size_t sz);
25 |
26 | template
27 | GLOBAL void __Brussellator__(T* RESTRICT u, T* RESTRICT v, const T dt, const T param1, const T param2, const size_t sz);
28 |
29 | template
30 | GLOBAL void __GrayScott__(T* RESTRICT u, T* RESTRICT v, const T dt, const T param1, const T param2, const size_t sz);
31 |
--------------------------------------------------------------------------------
/TuringPatternKernels/PatternType.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | EXTERN_C
6 | {
7 | /**
8 | * Defines the time discretizer type
9 | */
10 | enum class PatternType
11 | {
12 | Null = 0,
13 |
14 | FitzHughNagumo = 1,
15 | Thomas = 2,
16 | Schnakenberg = 3,
17 | Brussellator = 4,
18 | GrayScott = 5,
19 | };
20 | }
--------------------------------------------------------------------------------
/TuringPatternKernels/TuringPatternKernels.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | x64
7 |
8 |
9 | Release
10 | x64
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | {3695B232-419E-46F9-98FE-8BDE862F6DC1}
22 | TuringPatternKernels
23 | 10.0.16299.0
24 |
25 |
26 |
27 | DynamicLibrary
28 | true
29 | MultiByte
30 | v141
31 |
32 |
33 | Application
34 | false
35 | true
36 | MultiByte
37 | v141
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | true
52 | $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\CudaLightKernels;$(SolutionDir)\TuringPatternKernels;
53 |
54 |
55 |
56 | Level3
57 | Disabled
58 | WIN32;WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
59 |
60 |
61 | true
62 | Console
63 | cudart.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
64 |
65 |
66 | echo copy "$(CudaToolkitBinDir)\cudart*.dll" "$(OutDir)"
67 | copy "$(CudaToolkitBinDir)\cudart*.dll" "$(OutDir)"
68 |
69 |
70 | 64
71 | $(SolutionDir)\..\CudaLightKernels;$(SolutionDir)\TuringPatternKernels;
72 |
73 |
74 |
75 |
76 | Level3
77 | MaxSpeed
78 | true
79 | true
80 | WIN32;WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
81 |
82 |
83 | true
84 | true
85 | true
86 | Console
87 | cudart.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
88 |
89 |
90 | echo copy "$(CudaToolkitBinDir)\cudart*.dll" "$(OutDir)"
91 | copy "$(CudaToolkitBinDir)\cudart*.dll" "$(OutDir)"
92 |
93 |
94 | 64
95 |
96 |
97 |
98 |
99 |
100 |
101 |
--------------------------------------------------------------------------------
/TuringPatterns.cpp:
--------------------------------------------------------------------------------
1 | // TuringPatterns.cpp : Defines the entry point for the console application.
2 | //
3 |
4 | #include "FiniteDifference\Parabolic.h"
5 | #include "FiniteDifference\Pattern.h"
6 | #include "cnpy.h"
7 | #include "stdafx.h"
8 | #include
9 | #include
10 | #include
11 |
12 | #include
13 | #include
14 |
15 | #pragma region Example parabolic PDE solvers
16 |
17 | void Example1D()
18 | {
19 | using namespace la;
20 |
21 | CVector grid = la::LinSpace(0.0, 1.0, 16);
22 | auto x = grid.Get();
23 | std::vector initialCondition(grid.size());
24 | for (size_t i = 0; i < initialCondition.size(); i++)
25 | initialCondition[i] = exp(-5 * (x[i] - .5) * (x[i] - .5));
26 |
27 | CVector ic(grid);
28 | ic.ReadFrom(initialCondition);
29 | fd::CParabolicData1D input(grid, ic, 1.0, EBoundaryCondition::ZeroFlux);
30 |
31 | double dt = 1e-4;
32 | fd::CParabolicSolver1D solver(input, dt);
33 |
34 | CVector solution(grid.size());
35 | solver.Initialize(solution);
36 |
37 | CMatrix toPlot(solution.size(), 100);
38 |
39 | toPlot.columns[0]->ReadFrom(solution);
40 | size_t nIterPerRound = 10;
41 | for (size_t n = 1; n < toPlot.nCols(); n++)
42 | {
43 | solver.Iterate(solution, nIterPerRound);
44 | toPlot.columns[n]->ReadFrom(solution);
45 | }
46 |
47 | cnpy::npy_save("results1D.npy", toPlot.Get(), "w");
48 | }
49 |
50 | void Example2D()
51 | {
52 | using namespace la;
53 | using namespace std::chrono;
54 |
55 | high_resolution_clock::time_point start = high_resolution_clock::now();
56 | high_resolution_clock::time_point t1 = high_resolution_clock::now();
57 |
58 | CVector xGrid = la::LinSpace(0.0, 1.0, 128);
59 | CVector yGrid = la::LinSpace(0.0, 1.0, 128);
60 |
61 | high_resolution_clock::time_point t2 = high_resolution_clock::now();
62 | std::cout << "Created grid in " << duration_cast>(t2 - t1).count() << " seconds." << std::endl;
63 |
64 | t1 = high_resolution_clock::now();
65 |
66 | auto x = xGrid.Get();
67 | auto y = yGrid.Get();
68 | std::vector initialCondition(xGrid.size() * yGrid.size());
69 | for (size_t j = 0; j < yGrid.size(); j++)
70 | for (size_t i = 0; i < xGrid.size(); i++)
71 | initialCondition[i + x.size() * j] = exp(-5 * ((x[i] - .5) * (x[i] - .5) + (y[j] - .5) * (y[j] - .5)));
72 |
73 | CMatrix ic(xGrid.size(), yGrid.size());
74 | ic.ReadFrom(initialCondition);
75 |
76 | t2 = high_resolution_clock::now();
77 | std::cout << "Created initial condition in " << duration_cast>(t2 - t1).count() << " seconds." << std::endl;
78 |
79 | fd::CParabolicData2D input(xGrid, yGrid, ic, 1.0, EBoundaryCondition::ZeroFlux);
80 |
81 | double dt = 1e-6;
82 | fd::CParabolicSolver2D solver(input, dt);
83 |
84 | CMatrix solution(xGrid.size(), yGrid.size());
85 | solver.Initialize(solution);
86 |
87 | CTensor toPlot(solution.nRows(), 100);
88 |
89 | toPlot.matrices[0]->ReadFrom(solution);
90 | size_t nIterPerRound = 1000;
91 | for (size_t n = 1; n < toPlot.nMatrices(); n++)
92 | {
93 | t1 = high_resolution_clock::now();
94 |
95 | solver.Iterate(solution, nIterPerRound);
96 |
97 | t2 = high_resolution_clock::now();
98 | std::cout << "Done " << nIterPerRound << " iterations in " << duration_cast>(t2 - t1).count() << " seconds." << std::endl;
99 |
100 | toPlot.matrices[n]->ReadFrom(solution);
101 | }
102 |
103 |
104 | t1 = high_resolution_clock::now();
105 | cnpy::npy_save("results2D.npy", &toPlot.Get()[0], { toPlot.nMatrices(), toPlot.nCols(), toPlot.nRows() }, "w");
106 | t2 = high_resolution_clock::now();
107 | std::cout << "Saved NPY in " << duration_cast>(t2 - t1).count() << " seconds." << std::endl;
108 |
109 | high_resolution_clock::time_point end = high_resolution_clock::now();
110 |
111 | std::cout << "Finished in " << duration_cast>(end - start).count() << " seconds." << std::endl;
112 | }
113 |
114 | #pragma endregion
115 |
116 | struct RunParameters
117 | {
118 | EPatternType patternType = EPatternType::GrayScott;
119 | EBoundaryCondition boundaryCondition = EBoundaryCondition::Periodic;
120 |
121 | size_t xDimension = 256;
122 | double xMin = 0.0;
123 | double xMax = 0.0;
124 |
125 | size_t yDimension = 256;
126 | double yMin = 0.0;
127 | double yMax = 0.0;
128 |
129 | /// Number of plots
130 | size_t nIter = 200;
131 |
132 | /// Number of iterations between each plot
133 | size_t nIterPerRound = 1000;
134 |
135 | double dt = 1.0;
136 |
137 | double whiteNoiseScale = .05;
138 |
139 | double uDiffusion = 0.0;
140 | double vDiffusion = 0.0;
141 |
142 | double patternParameter1 = 0.0;
143 | double patternParameter2 = 0.0;
144 |
145 | char* solutionFile = "";
146 | };
147 |
148 | #pragma region Implementation
149 |
150 | typedef void (*MakeInitialConditionDelegate)(la::CMatrix& uInitialCondition, la::CMatrix& vInitialCondition, const RunParameters& params);
151 |
152 | double BinarySearch(const std::function& f, double a, double b, const double tolerance = 1e-8)
153 | {
154 | double fa = f(a);
155 | double fb = f(b);
156 |
157 | if (fa * fb > 0)
158 | throw std::exception("f doesn't change sign");
159 |
160 | double c = 0;
161 | for (size_t i = 0; i < 1000; i++)
162 | {
163 | c = .5 * (a + b);
164 | const double fc = f(c);
165 | fa = f(a);
166 | fb = f(b);
167 |
168 | if (fabs(fc) < tolerance)
169 | return c;
170 |
171 | if (fa * fc > 0)
172 | a = c;
173 | else
174 | b = c;
175 | }
176 |
177 | std::cout << "CONVERGENCE ERROR" << std::endl;
178 | throw;
179 | }
180 |
181 | template
182 | void MakeInitialCondition(la::CMatrix& uInitialCondition, la::CMatrix& vInitialCondition, const RunParameters& params)
183 | {
184 | switch (patternType)
185 | {
186 | case EPatternType::FitzHughNagumo:
187 | uInitialCondition.Set(0.0);
188 | vInitialCondition.Set(0.0);
189 | break;
190 | case EPatternType::Thomas:
191 | {
192 | auto f = [&](const double v) {
193 | const double u = -1.5 * (params.patternParameter2 - v) + params.patternParameter1;
194 | const double h = 13.0 * u * v / (1.0 + u + 0.05 * u * u);
195 | return h - (params.patternParameter1 - u);
196 | };
197 | const double v0 = BinarySearch(f, 0.0, 100.0);
198 | const double u0 = -1.5 * (params.patternParameter2 - v0) + params.patternParameter1;
199 |
200 | uInitialCondition.Set(u0);
201 | vInitialCondition.Set(v0);
202 | }
203 | break;
204 | case EPatternType::Schnakernberg:
205 | uInitialCondition.Set(params.patternParameter1 + params.patternParameter2);
206 | vInitialCondition.Set(params.patternParameter2 / ((params.patternParameter1 + params.patternParameter2) * (params.patternParameter1 + params.patternParameter2)));
207 | break;
208 | case EPatternType::Brussellator:
209 | uInitialCondition.Set(params.patternParameter1);
210 | vInitialCondition.Set(params.patternParameter2 / params.patternParameter1);
211 | break;
212 | case EPatternType::GrayScott:
213 | {
214 | uInitialCondition.Set(1.0);
215 | vInitialCondition.Set(0.0);
216 |
217 | std::vector uCenteredSquare(uInitialCondition.size());
218 | std::vector vCenteredSquare(uInitialCondition.size());
219 | size_t squareStartX = uInitialCondition.nRows() * 2 / 5;
220 | size_t squareEndX = uInitialCondition.nRows() * 3 / 5;
221 | size_t squareStartY = uInitialCondition.nCols() * 2 / 5;
222 | size_t squareEndY = uInitialCondition.nCols() * 3 / 5;
223 | for (size_t j = squareStartY; j < squareEndY; j++)
224 | {
225 | for (size_t i = squareStartX; i < squareEndX; i++)
226 | {
227 | uCenteredSquare[i + uInitialCondition.nRows() * j] = -.5;
228 | vCenteredSquare[i + uInitialCondition.nRows() * j] = .25;
229 | }
230 | }
231 | la::CMatrix uAddition(uInitialCondition);
232 | uAddition.ReadFrom(uCenteredSquare);
233 | la::CMatrix vAddition(vInitialCondition);
234 | vAddition.ReadFrom(vCenteredSquare);
235 |
236 | uInitialCondition.AddEqual(uAddition);
237 | vInitialCondition.AddEqual(vAddition);
238 | }
239 | break;
240 | default:
241 | break;
242 | }
243 | }
244 |
245 | void RunDelegate(MakeInitialConditionDelegate makeInitialCondition, const RunParameters& params)
246 | {
247 | using namespace la;
248 | using namespace std::chrono;
249 |
250 | high_resolution_clock::time_point start = high_resolution_clock::now();
251 | high_resolution_clock::time_point t1 = high_resolution_clock::now();
252 |
253 | // ************ Make Grid ************
254 | CVector xGrid = la::LinSpace(params.xMin, params.xMax, params.xDimension);
255 | CVector yGrid = la::LinSpace(params.yMin, params.yMax, params.yDimension);
256 |
257 | high_resolution_clock::time_point t2 = high_resolution_clock::now();
258 |
259 | std::cout << "Created grid in " << duration_cast>(t2 - t1).count() << " seconds." << std::endl; // ***********************************
260 |
261 | // ***************** Make Initial Condition ******************
262 | t1 = high_resolution_clock::now();
263 |
264 | CMatrix whiteNoise = la::RandomGaussian(xGrid.size(), yGrid.size());
265 | whiteNoise.Scale(params.whiteNoiseScale);
266 |
267 | CMatrix uInitialCondition(xGrid.size(), yGrid.size());
268 | CMatrix vInitialCondition(xGrid.size(), yGrid.size());
269 | makeInitialCondition(uInitialCondition, vInitialCondition, params);
270 |
271 | uInitialCondition.AddEqual(whiteNoise);
272 | vInitialCondition.AddEqual(whiteNoise);
273 |
274 | t2 = high_resolution_clock::now();
275 | std::cout << "Created initial condition in " << duration_cast>(t2 - t1).count() << " seconds." << std::endl;
276 | // ***************************************************************
277 |
278 | // **************** Initialize Solver ***************
279 | t1 = high_resolution_clock::now();
280 |
281 | fd::CPatternData2D input(xGrid, yGrid, uInitialCondition, vInitialCondition, params.uDiffusion, params.vDiffusion, params.patternType, params.boundaryCondition);
282 | fd::CPatternSolver2D solver(input, params.dt);
283 |
284 | CMatrix uSolution(xGrid.size(), yGrid.size());
285 | CMatrix vSolution(xGrid.size(), yGrid.size());
286 | solver.Initialize(uSolution, vSolution);
287 |
288 | CTensor toPlot(uSolution.nRows(), uSolution.nCols(), params.nIter);
289 |
290 | toPlot.matrices[0]->ReadFrom(uSolution);
291 | std::cout << "Solver setup in " << duration_cast>(t2 - t1).count() << " seconds." << std::endl;
292 | // ****************************************************
293 |
294 |
295 | // ************** Iterate solver ***************
296 | for (size_t n = 1; n < toPlot.nMatrices(); n++)
297 | {
298 | t1 = high_resolution_clock::now();
299 |
300 | solver.Iterate(uSolution, vSolution, params.nIterPerRound, params.patternParameter1, params.patternParameter2);
301 |
302 | t2 = high_resolution_clock::now();
303 | std::cout << "Done " << params.nIterPerRound << " iterations in " << duration_cast>(t2 - t1).count() << " seconds." << std::endl;
304 |
305 | toPlot.matrices[n]->ReadFrom(uSolution);
306 | }
307 | // *********************************************
308 |
309 | // ************** Save solution to CSV ************
310 | t1 = high_resolution_clock::now();
311 | cnpy::npy_save(params.solutionFile, &toPlot.Get()[0], { toPlot.nMatrices(), toPlot.nCols(), toPlot.nRows() }, "w");
312 | t2 = high_resolution_clock::now();
313 | std::cout << "Saved csv in " << duration_cast>(t2 - t1).count() << " seconds." << std::endl;
314 |
315 | high_resolution_clock::time_point end = high_resolution_clock::now();
316 |
317 | std::cout << "Finished in " << duration_cast>(end - start).count() << " seconds." << std::endl;
318 | // *************************************************
319 | }
320 |
321 | #pragma endregion
322 |
323 | void Run(const RunParameters& params)
324 | {
325 | MakeInitialConditionDelegate makeInitialCondition = nullptr;
326 |
327 | switch (params.patternType)
328 | {
329 | case EPatternType::FitzHughNagumo:
330 | makeInitialCondition = MakeInitialCondition;
331 | break;
332 | case EPatternType::Thomas:
333 | makeInitialCondition = MakeInitialCondition;
334 | break;
335 | case EPatternType::Schnakernberg:
336 | makeInitialCondition = MakeInitialCondition;
337 | break;
338 | case EPatternType::Brussellator:
339 | makeInitialCondition = MakeInitialCondition;
340 | break;
341 | case EPatternType::GrayScott:
342 | makeInitialCondition = MakeInitialCondition;
343 | break;
344 | default:
345 | break;
346 | }
347 |
348 | RunDelegate(makeInitialCondition, params);
349 | }
350 |
351 | int main(int argc, char** argv)
352 | {
353 | RunParameters params;
354 |
355 | #define PARSE(PARAM, TYPE) \
356 | if (!strcmp(argv[c], "-" #PARAM)) \
357 | params.##PARAM = std::ato##TYPE(argv[++c]);
358 |
359 | for (size_t c = 1; c < argc; c++)
360 | {
361 | if (!strcmp(argv[c], "-pattern"))
362 | {
363 | ++c;
364 | if (!strcmp(argv[c], "GrayScott"))
365 | params.patternType = EPatternType::GrayScott;
366 | else if (!strcmp(argv[c], "Brussellator"))
367 | params.patternType = EPatternType::Brussellator;
368 | else if (!strcmp(argv[c], "Schnakenberg"))
369 | params.patternType = EPatternType::Schnakernberg;
370 | else if (!strcmp(argv[c], "Thomas"))
371 | params.patternType = EPatternType::Thomas;
372 | else if (!strcmp(argv[c], "FitzHughNagumo"))
373 | params.patternType = EPatternType::FitzHughNagumo;
374 | }
375 | if (!strcmp(argv[c], "-boundaryCondition"))
376 | {
377 | ++c;
378 | if (!strcmp(argv[c], "Periodic"))
379 | params.boundaryCondition = EBoundaryCondition::Periodic;
380 | else if (!strcmp(argv[c], "ZeroFlux"))
381 | params.boundaryCondition = EBoundaryCondition::ZeroFlux;
382 | }
383 | if (!strcmp(argv[c], "-solutionFile"))
384 | {
385 | params.solutionFile = argv[++c];
386 | }
387 | PARSE(xDimension, i);
388 | PARSE(xMin, f);
389 | PARSE(xMax, f);
390 | PARSE(yDimension, i);
391 | PARSE(yMin, f);
392 | PARSE(yMax, f);
393 | PARSE(nIter, i);
394 | PARSE(nIterPerRound, i);
395 | PARSE(dt, f);
396 | PARSE(whiteNoiseScale, f);
397 | PARSE(uDiffusion, f);
398 | PARSE(vDiffusion, f);
399 | PARSE(patternParameter1, f);
400 | PARSE(patternParameter2, f);
401 | }
402 |
403 | if (params.xMin == params.xMax)
404 | {
405 | params.xMin = 0;
406 | params.xMax = params.xDimension - 1;
407 | }
408 | if (params.yMin == params.yMax)
409 | {
410 | params.yMin = 0;
411 | params.yMax = params.yDimension - 1;
412 | }
413 |
414 | Run(params);
415 |
416 | return 0;
417 | }
418 |
--------------------------------------------------------------------------------
/TuringPatterns.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.27004.2008
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CudaLight", "..\CudaLight\CudaLight\CudaLight.vcxproj", "{ACB311A5-3BB8-41F4-AA98-552FFCA078F2}"
7 | EndProject
8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CudaLightKernels", "..\CudaLightKernels\CudaLightKernels.vcxproj", "{FEB675FC-E9C3-40FD-B987-CC8BF85888EC}"
9 | EndProject
10 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Npy++", "..\Npy++\Npy++.vcxproj", "{014413C8-BE38-48A4-9F99-9C98A08BC668}"
11 | EndProject
12 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PdeFiniteDifferenceKernels", "..\PdeFiniteDifferenceKernels\PdeFiniteDifferenceKernels.vcxproj", "{61B7561F-1E85-4A06-8ABA-74E4F0EEEF34}"
13 | EndProject
14 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TuringPatterns", "TuringPatterns\TuringPatterns.vcxproj", "{8A5AA9D0-27A7-4A8A-A389-1ED29AF7F08C}"
15 | EndProject
16 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PdeFiniteDifferenceSolverManager", "..\PdeFiniteDifferenceSolver\PdeFiniteDifferenceSolverManager\PdeFiniteDifferenceSolverManager.vcxproj", "{55A522FB-4950-488F-9B8A-2CD625A9AA15}"
17 | EndProject
18 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TuringPatternKernels", "TuringPatternKernels\TuringPatternKernels.vcxproj", "{3695B232-419E-46F9-98FE-8BDE862F6DC1}"
19 | EndProject
20 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "forge", "..\forge\build\src\backend\opengl\forge.vcxproj", "{8F7F5DD3-9DD7-3108-BC1F-477092B67281}"
21 | EndProject
22 | Global
23 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
24 | Debug|x64 = Debug|x64
25 | Debug|x86 = Debug|x86
26 | MinSizeRel|x64 = MinSizeRel|x64
27 | MinSizeRel|x86 = MinSizeRel|x86
28 | Release|x64 = Release|x64
29 | Release|x86 = Release|x86
30 | RelWithDebInfo|x64 = RelWithDebInfo|x64
31 | RelWithDebInfo|x86 = RelWithDebInfo|x86
32 | EndGlobalSection
33 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
34 | {ACB311A5-3BB8-41F4-AA98-552FFCA078F2}.Debug|x64.ActiveCfg = Debug|x64
35 | {ACB311A5-3BB8-41F4-AA98-552FFCA078F2}.Debug|x64.Build.0 = Debug|x64
36 | {ACB311A5-3BB8-41F4-AA98-552FFCA078F2}.Debug|x86.ActiveCfg = Debug|Win32
37 | {ACB311A5-3BB8-41F4-AA98-552FFCA078F2}.Debug|x86.Build.0 = Debug|Win32
38 | {ACB311A5-3BB8-41F4-AA98-552FFCA078F2}.MinSizeRel|x64.ActiveCfg = Release|x64
39 | {ACB311A5-3BB8-41F4-AA98-552FFCA078F2}.MinSizeRel|x64.Build.0 = Release|x64
40 | {ACB311A5-3BB8-41F4-AA98-552FFCA078F2}.MinSizeRel|x86.ActiveCfg = Release|Win32
41 | {ACB311A5-3BB8-41F4-AA98-552FFCA078F2}.MinSizeRel|x86.Build.0 = Release|Win32
42 | {ACB311A5-3BB8-41F4-AA98-552FFCA078F2}.Release|x64.ActiveCfg = Release|x64
43 | {ACB311A5-3BB8-41F4-AA98-552FFCA078F2}.Release|x64.Build.0 = Release|x64
44 | {ACB311A5-3BB8-41F4-AA98-552FFCA078F2}.Release|x86.ActiveCfg = Release|Win32
45 | {ACB311A5-3BB8-41F4-AA98-552FFCA078F2}.Release|x86.Build.0 = Release|Win32
46 | {ACB311A5-3BB8-41F4-AA98-552FFCA078F2}.RelWithDebInfo|x64.ActiveCfg = Release|x64
47 | {ACB311A5-3BB8-41F4-AA98-552FFCA078F2}.RelWithDebInfo|x64.Build.0 = Release|x64
48 | {ACB311A5-3BB8-41F4-AA98-552FFCA078F2}.RelWithDebInfo|x86.ActiveCfg = Release|Win32
49 | {ACB311A5-3BB8-41F4-AA98-552FFCA078F2}.RelWithDebInfo|x86.Build.0 = Release|Win32
50 | {FEB675FC-E9C3-40FD-B987-CC8BF85888EC}.Debug|x64.ActiveCfg = Debug|x64
51 | {FEB675FC-E9C3-40FD-B987-CC8BF85888EC}.Debug|x64.Build.0 = Debug|x64
52 | {FEB675FC-E9C3-40FD-B987-CC8BF85888EC}.Debug|x86.ActiveCfg = Debug|x64
53 | {FEB675FC-E9C3-40FD-B987-CC8BF85888EC}.MinSizeRel|x64.ActiveCfg = Release|x64
54 | {FEB675FC-E9C3-40FD-B987-CC8BF85888EC}.MinSizeRel|x64.Build.0 = Release|x64
55 | {FEB675FC-E9C3-40FD-B987-CC8BF85888EC}.MinSizeRel|x86.ActiveCfg = Release|x64
56 | {FEB675FC-E9C3-40FD-B987-CC8BF85888EC}.MinSizeRel|x86.Build.0 = Release|x64
57 | {FEB675FC-E9C3-40FD-B987-CC8BF85888EC}.Release|x64.ActiveCfg = Release|x64
58 | {FEB675FC-E9C3-40FD-B987-CC8BF85888EC}.Release|x64.Build.0 = Release|x64
59 | {FEB675FC-E9C3-40FD-B987-CC8BF85888EC}.Release|x86.ActiveCfg = Release|x64
60 | {FEB675FC-E9C3-40FD-B987-CC8BF85888EC}.RelWithDebInfo|x64.ActiveCfg = Release|x64
61 | {FEB675FC-E9C3-40FD-B987-CC8BF85888EC}.RelWithDebInfo|x64.Build.0 = Release|x64
62 | {FEB675FC-E9C3-40FD-B987-CC8BF85888EC}.RelWithDebInfo|x86.ActiveCfg = Release|x64
63 | {FEB675FC-E9C3-40FD-B987-CC8BF85888EC}.RelWithDebInfo|x86.Build.0 = Release|x64
64 | {014413C8-BE38-48A4-9F99-9C98A08BC668}.Debug|x64.ActiveCfg = Debug|x64
65 | {014413C8-BE38-48A4-9F99-9C98A08BC668}.Debug|x64.Build.0 = Debug|x64
66 | {014413C8-BE38-48A4-9F99-9C98A08BC668}.Debug|x86.ActiveCfg = Debug|Win32
67 | {014413C8-BE38-48A4-9F99-9C98A08BC668}.Debug|x86.Build.0 = Debug|Win32
68 | {014413C8-BE38-48A4-9F99-9C98A08BC668}.MinSizeRel|x64.ActiveCfg = Release|x64
69 | {014413C8-BE38-48A4-9F99-9C98A08BC668}.MinSizeRel|x64.Build.0 = Release|x64
70 | {014413C8-BE38-48A4-9F99-9C98A08BC668}.MinSizeRel|x86.ActiveCfg = Release|Win32
71 | {014413C8-BE38-48A4-9F99-9C98A08BC668}.MinSizeRel|x86.Build.0 = Release|Win32
72 | {014413C8-BE38-48A4-9F99-9C98A08BC668}.Release|x64.ActiveCfg = Release|x64
73 | {014413C8-BE38-48A4-9F99-9C98A08BC668}.Release|x64.Build.0 = Release|x64
74 | {014413C8-BE38-48A4-9F99-9C98A08BC668}.Release|x86.ActiveCfg = Release|Win32
75 | {014413C8-BE38-48A4-9F99-9C98A08BC668}.Release|x86.Build.0 = Release|Win32
76 | {014413C8-BE38-48A4-9F99-9C98A08BC668}.RelWithDebInfo|x64.ActiveCfg = Release|x64
77 | {014413C8-BE38-48A4-9F99-9C98A08BC668}.RelWithDebInfo|x64.Build.0 = Release|x64
78 | {014413C8-BE38-48A4-9F99-9C98A08BC668}.RelWithDebInfo|x86.ActiveCfg = Release|Win32
79 | {014413C8-BE38-48A4-9F99-9C98A08BC668}.RelWithDebInfo|x86.Build.0 = Release|Win32
80 | {61B7561F-1E85-4A06-8ABA-74E4F0EEEF34}.Debug|x64.ActiveCfg = Debug|x64
81 | {61B7561F-1E85-4A06-8ABA-74E4F0EEEF34}.Debug|x64.Build.0 = Debug|x64
82 | {61B7561F-1E85-4A06-8ABA-74E4F0EEEF34}.Debug|x86.ActiveCfg = Debug|x64
83 | {61B7561F-1E85-4A06-8ABA-74E4F0EEEF34}.MinSizeRel|x64.ActiveCfg = Release|x64
84 | {61B7561F-1E85-4A06-8ABA-74E4F0EEEF34}.MinSizeRel|x64.Build.0 = Release|x64
85 | {61B7561F-1E85-4A06-8ABA-74E4F0EEEF34}.MinSizeRel|x86.ActiveCfg = Release|x64
86 | {61B7561F-1E85-4A06-8ABA-74E4F0EEEF34}.MinSizeRel|x86.Build.0 = Release|x64
87 | {61B7561F-1E85-4A06-8ABA-74E4F0EEEF34}.Release|x64.ActiveCfg = Release|x64
88 | {61B7561F-1E85-4A06-8ABA-74E4F0EEEF34}.Release|x64.Build.0 = Release|x64
89 | {61B7561F-1E85-4A06-8ABA-74E4F0EEEF34}.Release|x86.ActiveCfg = Release|x64
90 | {61B7561F-1E85-4A06-8ABA-74E4F0EEEF34}.RelWithDebInfo|x64.ActiveCfg = Release|x64
91 | {61B7561F-1E85-4A06-8ABA-74E4F0EEEF34}.RelWithDebInfo|x64.Build.0 = Release|x64
92 | {61B7561F-1E85-4A06-8ABA-74E4F0EEEF34}.RelWithDebInfo|x86.ActiveCfg = Release|x64
93 | {61B7561F-1E85-4A06-8ABA-74E4F0EEEF34}.RelWithDebInfo|x86.Build.0 = Release|x64
94 | {8A5AA9D0-27A7-4A8A-A389-1ED29AF7F08C}.Debug|x64.ActiveCfg = Debug|x64
95 | {8A5AA9D0-27A7-4A8A-A389-1ED29AF7F08C}.Debug|x64.Build.0 = Debug|x64
96 | {8A5AA9D0-27A7-4A8A-A389-1ED29AF7F08C}.Debug|x86.ActiveCfg = Debug|x64
97 | {8A5AA9D0-27A7-4A8A-A389-1ED29AF7F08C}.MinSizeRel|x64.ActiveCfg = Release|x64
98 | {8A5AA9D0-27A7-4A8A-A389-1ED29AF7F08C}.MinSizeRel|x64.Build.0 = Release|x64
99 | {8A5AA9D0-27A7-4A8A-A389-1ED29AF7F08C}.MinSizeRel|x86.ActiveCfg = Release|x64
100 | {8A5AA9D0-27A7-4A8A-A389-1ED29AF7F08C}.MinSizeRel|x86.Build.0 = Release|x64
101 | {8A5AA9D0-27A7-4A8A-A389-1ED29AF7F08C}.Release|x64.ActiveCfg = Release|x64
102 | {8A5AA9D0-27A7-4A8A-A389-1ED29AF7F08C}.Release|x64.Build.0 = Release|x64
103 | {8A5AA9D0-27A7-4A8A-A389-1ED29AF7F08C}.Release|x86.ActiveCfg = Release|x64
104 | {8A5AA9D0-27A7-4A8A-A389-1ED29AF7F08C}.RelWithDebInfo|x64.ActiveCfg = Release|x64
105 | {8A5AA9D0-27A7-4A8A-A389-1ED29AF7F08C}.RelWithDebInfo|x64.Build.0 = Release|x64
106 | {8A5AA9D0-27A7-4A8A-A389-1ED29AF7F08C}.RelWithDebInfo|x86.ActiveCfg = Release|x64
107 | {8A5AA9D0-27A7-4A8A-A389-1ED29AF7F08C}.RelWithDebInfo|x86.Build.0 = Release|x64
108 | {55A522FB-4950-488F-9B8A-2CD625A9AA15}.Debug|x64.ActiveCfg = Debug|x64
109 | {55A522FB-4950-488F-9B8A-2CD625A9AA15}.Debug|x64.Build.0 = Debug|x64
110 | {55A522FB-4950-488F-9B8A-2CD625A9AA15}.Debug|x86.ActiveCfg = Debug|Win32
111 | {55A522FB-4950-488F-9B8A-2CD625A9AA15}.Debug|x86.Build.0 = Debug|Win32
112 | {55A522FB-4950-488F-9B8A-2CD625A9AA15}.MinSizeRel|x64.ActiveCfg = Release|x64
113 | {55A522FB-4950-488F-9B8A-2CD625A9AA15}.MinSizeRel|x64.Build.0 = Release|x64
114 | {55A522FB-4950-488F-9B8A-2CD625A9AA15}.MinSizeRel|x86.ActiveCfg = Release|Win32
115 | {55A522FB-4950-488F-9B8A-2CD625A9AA15}.MinSizeRel|x86.Build.0 = Release|Win32
116 | {55A522FB-4950-488F-9B8A-2CD625A9AA15}.Release|x64.ActiveCfg = Release|x64
117 | {55A522FB-4950-488F-9B8A-2CD625A9AA15}.Release|x64.Build.0 = Release|x64
118 | {55A522FB-4950-488F-9B8A-2CD625A9AA15}.Release|x86.ActiveCfg = Release|Win32
119 | {55A522FB-4950-488F-9B8A-2CD625A9AA15}.Release|x86.Build.0 = Release|Win32
120 | {55A522FB-4950-488F-9B8A-2CD625A9AA15}.RelWithDebInfo|x64.ActiveCfg = Release|x64
121 | {55A522FB-4950-488F-9B8A-2CD625A9AA15}.RelWithDebInfo|x64.Build.0 = Release|x64
122 | {55A522FB-4950-488F-9B8A-2CD625A9AA15}.RelWithDebInfo|x86.ActiveCfg = Release|Win32
123 | {55A522FB-4950-488F-9B8A-2CD625A9AA15}.RelWithDebInfo|x86.Build.0 = Release|Win32
124 | {3695B232-419E-46F9-98FE-8BDE862F6DC1}.Debug|x64.ActiveCfg = Debug|x64
125 | {3695B232-419E-46F9-98FE-8BDE862F6DC1}.Debug|x64.Build.0 = Debug|x64
126 | {3695B232-419E-46F9-98FE-8BDE862F6DC1}.Debug|x86.ActiveCfg = Debug|x64
127 | {3695B232-419E-46F9-98FE-8BDE862F6DC1}.MinSizeRel|x64.ActiveCfg = Release|x64
128 | {3695B232-419E-46F9-98FE-8BDE862F6DC1}.MinSizeRel|x64.Build.0 = Release|x64
129 | {3695B232-419E-46F9-98FE-8BDE862F6DC1}.MinSizeRel|x86.ActiveCfg = Release|x64
130 | {3695B232-419E-46F9-98FE-8BDE862F6DC1}.MinSizeRel|x86.Build.0 = Release|x64
131 | {3695B232-419E-46F9-98FE-8BDE862F6DC1}.Release|x64.ActiveCfg = Release|x64
132 | {3695B232-419E-46F9-98FE-8BDE862F6DC1}.Release|x64.Build.0 = Release|x64
133 | {3695B232-419E-46F9-98FE-8BDE862F6DC1}.Release|x86.ActiveCfg = Release|x64
134 | {3695B232-419E-46F9-98FE-8BDE862F6DC1}.RelWithDebInfo|x64.ActiveCfg = Release|x64
135 | {3695B232-419E-46F9-98FE-8BDE862F6DC1}.RelWithDebInfo|x64.Build.0 = Release|x64
136 | {3695B232-419E-46F9-98FE-8BDE862F6DC1}.RelWithDebInfo|x86.ActiveCfg = Release|x64
137 | {3695B232-419E-46F9-98FE-8BDE862F6DC1}.RelWithDebInfo|x86.Build.0 = Release|x64
138 | {8F7F5DD3-9DD7-3108-BC1F-477092B67281}.Debug|x64.ActiveCfg = Debug|x64
139 | {8F7F5DD3-9DD7-3108-BC1F-477092B67281}.Debug|x64.Build.0 = Debug|x64
140 | {8F7F5DD3-9DD7-3108-BC1F-477092B67281}.Debug|x86.ActiveCfg = Debug|x64
141 | {8F7F5DD3-9DD7-3108-BC1F-477092B67281}.MinSizeRel|x64.ActiveCfg = MinSizeRel|x64
142 | {8F7F5DD3-9DD7-3108-BC1F-477092B67281}.MinSizeRel|x64.Build.0 = MinSizeRel|x64
143 | {8F7F5DD3-9DD7-3108-BC1F-477092B67281}.MinSizeRel|x86.ActiveCfg = MinSizeRel|x64
144 | {8F7F5DD3-9DD7-3108-BC1F-477092B67281}.Release|x64.ActiveCfg = Release|x64
145 | {8F7F5DD3-9DD7-3108-BC1F-477092B67281}.Release|x64.Build.0 = Release|x64
146 | {8F7F5DD3-9DD7-3108-BC1F-477092B67281}.Release|x86.ActiveCfg = Release|x64
147 | {8F7F5DD3-9DD7-3108-BC1F-477092B67281}.RelWithDebInfo|x64.ActiveCfg = RelWithDebInfo|x64
148 | {8F7F5DD3-9DD7-3108-BC1F-477092B67281}.RelWithDebInfo|x64.Build.0 = RelWithDebInfo|x64
149 | {8F7F5DD3-9DD7-3108-BC1F-477092B67281}.RelWithDebInfo|x86.ActiveCfg = RelWithDebInfo|x64
150 | EndGlobalSection
151 | GlobalSection(SolutionProperties) = preSolution
152 | HideSolutionNode = FALSE
153 | EndGlobalSection
154 | GlobalSection(ExtensibilityGlobals) = postSolution
155 | SolutionGuid = {44180EE1-DC91-4D3C-8F90-5808CB4D5D40}
156 | EndGlobalSection
157 | EndGlobal
158 |
--------------------------------------------------------------------------------
/TuringPatterns.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 | Debug
14 | x64
15 |
16 |
17 | Release
18 | x64
19 |
20 |
21 |
22 | {D3FD5FD6-F74C-496C-9E03-43B4285F5370}
23 | Win32Proj
24 | TuringPatterns
25 | 10.0.16299.0
26 |
27 |
28 |
29 | Application
30 | true
31 | v141
32 | Unicode
33 |
34 |
35 | Application
36 | false
37 | v141
38 | true
39 | Unicode
40 |
41 |
42 | Application
43 | true
44 | v141
45 | Unicode
46 |
47 |
48 | Application
49 | false
50 | v141
51 | true
52 | Unicode
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 | true
74 |
75 |
76 | true
77 | $(SolutionDir)\..\Npy++;$(SolutionDir)\..\CudaLightKernels;$(SolutionDir)..\CudaLight;$(IncludePath)
78 |
79 |
80 | false
81 |
82 |
83 | false
84 |
85 |
86 |
87 | Use
88 | Level3
89 | Disabled
90 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
91 | true
92 |
93 |
94 | Console
95 | true
96 |
97 |
98 |
99 |
100 | Use
101 | Level4
102 | Disabled
103 | _DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
104 | true
105 | false
106 | true
107 | $(SolutionDir)\..\Npy++;$(SolutionDir)\..\CudaLightKernels;$(SolutionDir)..\CudaLight;
108 |
109 |
110 | Console
111 | true
112 | $(SolutionDir)$(Platform)\$(Configuration)\
113 | CudaManager.lib;FiniteDifference.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
114 |
115 |
116 |
117 |
118 | Level3
119 | Use
120 | MaxSpeed
121 | true
122 | true
123 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
124 | true
125 |
126 |
127 | Console
128 | true
129 | true
130 | true
131 |
132 |
133 |
134 |
135 | EnableAllWarnings
136 | Use
137 | Full
138 | true
139 | true
140 | NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
141 | true
142 | false
143 | true
144 | AnySuitable
145 | Speed
146 | true
147 |
148 |
149 | Console
150 | true
151 | true
152 | true
153 | CudaManager.lib;FiniteDifference.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
154 | $(SolutionDir)$(Platform)\$(Configuration)\
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 | Create
167 | Create
168 | Create
169 | Create
170 |
171 |
172 |
173 |
174 |
175 |
176 |
--------------------------------------------------------------------------------
/TuringPatterns.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | Header Files
23 |
24 |
25 | Header Files
26 |
27 |
28 |
29 |
30 | Source Files
31 |
32 |
33 | Source Files
34 |
35 |
36 |
--------------------------------------------------------------------------------
/TuringPatterns.vcxproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -pattern Thomas -xDimension 64 -yDimension 64 -nIter 100 -nIterPerRound 10 -dt 1.0 -whiteNoiseScale .05 -patternParameter1 4.5 -patternParameter2 6.75 -solutionFile "br.csv" -uDiffusion 2 -vDiffusion 16
5 | WindowsLocalDebugger
6 |
7 |
8 | -pattern Thomas -xDimension 64 -yDimension 64 -nIter 100 -nIterPerRound 10 -dt 1.0 -whiteNoiseScale .05 -patternParameter1 4.5 -patternParameter2 6.75 -solutionFile "br.csv" -uDiffusion 2 -vDiffusion 16
9 | WindowsLocalDebugger
10 |
11 |
--------------------------------------------------------------------------------
/TuringPatterns/TuringPatterns.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | x64
7 |
8 |
9 | Release
10 | x64
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | {8f7f5dd3-9dd7-3108-bc1f-477092b67281}
19 |
20 |
21 |
22 | {8A5AA9D0-27A7-4A8A-A389-1ED29AF7F08C}
23 | TuringPatterns
24 | 10.0.16299.0
25 |
26 |
27 |
28 | Application
29 | true
30 | MultiByte
31 | v141
32 |
33 |
34 | Application
35 | false
36 | true
37 | MultiByte
38 | v141
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 | true
53 | $(SolutionDir)\..\CudaLight\CudaLight;$(SolutionDir)\..\CudaLightKernels;$(SolutionDir)\..\PdeFiniteDifferenceSolver\PdeFiniteDifferenceSolverManager;$(SolutionDir)\..\PdeFiniteDifferenceKernels;$(SolutionDir)\..\forge\build\include;$(SolutionDir)\..\forge\include;$(SolutionDir)\..\forge;$(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)\..\Npy++\Npy++;$(SolutionDir)\..\Npy++\MemoryMapping;$(SolutionDir)\..\Npy++\zlib-1.2.7.f-win64-v1\;$(SolutionDir)\TuringPatternKernels
54 |
55 |
56 |
57 | Level3
58 | Disabled
59 | WIN32;WIN64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
60 |
61 |
62 | true
63 | Console
64 | TuringPatternKernels.lib;Npy++.lib;CudaLight.lib;CudaLightKernels.lib;PdeFiniteDifferenceSolverManager.lib;PdeFiniteDifferenceKernels.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;opengl32.lib;cudart.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
65 | %(AdditionalLibraryDirectories);$(CudaToolkitLibDir);$(OutDir);;
66 |
67 |
68 | echo copy "$(CudaToolkitBinDir)\cudart*.dll" "$(OutDir)"
69 | copy "$(CudaToolkitBinDir)\cudart*.dll" "$(OutDir)"
70 |
71 |
72 | 64
73 | $(SolutionDir)\..\CudaLight\CudaLight;$(SolutionDir)\..\CudaLightKernels;$(SolutionDir)\..\PdeFiniteDifferenceSolver\PdeFiniteDifferenceSolverManager;$(SolutionDir)\..\PdeFiniteDifferenceKernels;$(SolutionDir)\..\forge\build\include;$(SolutionDir)\..\forge\include;$(SolutionDir)\..\forge;$(SolutionDir)\TuringPatternKernels
74 | _WINDOWS;OS_WIN;WIN32_MEAN_AND_LEAN;FGDLL;CMAKE_INTDIR="Debug";%(Defines)
75 | false
76 | false
77 |
78 |
79 |
80 |
81 | Level3
82 | MaxSpeed
83 | true
84 | true
85 | WIN32;WIN64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
86 |
87 |
88 | true
89 | true
90 | true
91 | Console
92 | cudart.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
93 |
94 |
95 | echo copy "$(CudaToolkitBinDir)\cudart*.dll" "$(OutDir)"
96 | copy "$(CudaToolkitBinDir)\cudart*.dll" "$(OutDir)"
97 |
98 |
99 | 64
100 |
101 |
102 |
103 |
104 |
105 |
106 |
--------------------------------------------------------------------------------
/TuringPatterns/TuringPatterns.vcxproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -pattern GrayScott -bc ZeroFlux -dt 1 -nIter 4096 -nIterPerRound 10 -xd 100 -yd 100 -wns 0.05 -ud 0.16 -vd 0.08 -p1 0.035 -p2 0.065
5 | WindowsLocalDebugger
6 |
7 |
--------------------------------------------------------------------------------
/TuringPatterns/main.cu:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | #include
6 | #include
7 |
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 |
16 | #include
17 | #include
18 | #include
19 |
20 | #include
21 | #define USE_FORGE_CUDA_COPY_HELPERS
22 | #include
23 |
24 | //#define PLOT_3D
25 | #define SAVE_TO_FILE
26 |
27 | namespace ep
28 | {
29 | #define PARSE(E, X)\
30 | if (!strcmp(text.c_str(), #X))\
31 | return E::X;
32 |
33 | PatternType ParsePatternType(const std::string &text)
34 | {
35 | #define PARSE_WORKER(X) PARSE(PatternType, X);
36 |
37 | PARSE_WORKER(FitzHughNagumo);
38 | PARSE_WORKER(Thomas);
39 | PARSE_WORKER(Schnakenberg);
40 | PARSE_WORKER(Brussellator);
41 | PARSE_WORKER(GrayScott);
42 |
43 | #undef PARSE_WORKER
44 |
45 | return PatternType::Null;
46 | }
47 |
48 | #undef PARSE
49 | }
50 |
51 | template
52 | using vector = cl::Vector;
53 |
54 | template
55 | using matrix = cl::ColumnWiseMatrix;
56 |
57 | template
58 | using sType = typename vector::stdType;
59 |
60 | struct RunParameters
61 | {
62 | PatternType patternType = PatternType::GrayScott;
63 | BoundaryConditionType boundaryCondition = BoundaryConditionType::Periodic;
64 |
65 | size_t xDimension = 64;
66 | double xMin = 0.0;
67 | double xMax = 1.0;
68 |
69 | size_t yDimension = 64;
70 | double yMin = 0.0;
71 | double yMax = 1.0;
72 |
73 | /// Number of plots
74 | size_t nIter = 2000;
75 | size_t nIterPerRound = 10;
76 |
77 | double dt = 1.0;
78 |
79 | double whiteNoiseScale = .05;
80 |
81 | double uDiffusion = 0.16;
82 | double vDiffusion = 0.08;
83 |
84 | double patternParameter1 = 0.035;
85 | double patternParameter2 = 0.065;
86 |
87 | double zMin = 0.1;
88 | double zMax = 1.5;
89 |
90 | std::string outputFile = "";
91 | };
92 |
93 | template
94 | void MakeInitialCondition(matrix& uInitialCondition, matrix& vInitialCondition, const RunParameters& params)
95 | {
96 | switch (patternType)
97 | {
98 | case PatternType::FitzHughNagumo:
99 | uInitialCondition.Set(0.0);
100 | vInitialCondition.Set(0.0);
101 | break;
102 | case PatternType::Thomas:
103 | {
104 | auto f = [&](const double v)
105 | {
106 | const double u = -1.5 * (params.patternParameter2 - v) + params.patternParameter1;
107 | const double h = 13.0 * u * v / (1.0 + u + 0.05 * u * u);
108 | return h - (params.patternParameter1 - u);
109 | };
110 | auto binarySearch = [&](double a, double b, const double tolerance = 1e-8)
111 | {
112 | double fa = f(a);
113 | double fb = f(b);
114 |
115 | if (fa * fb > 0)
116 | throw std::logic_error("f doesn't change sign");
117 |
118 | double c = 0;
119 | for (size_t i = 0; i < 1000; i++)
120 | {
121 | c = .5 * (a + b);
122 | const double fc = f(c);
123 | fa = f(a);
124 | fb = f(b);
125 |
126 | if (fabs(fc) < tolerance)
127 | return c;
128 |
129 | if (fa * fc > 0)
130 | a = c;
131 | else
132 | b = c;
133 | }
134 |
135 | std::cout << "CONVERGENCE ERROR" << std::endl;
136 | throw;
137 | };
138 |
139 | const double v0 = binarySearch(0.0, 100.0);
140 | const double u0 = -1.5 * (params.patternParameter2 - v0) + params.patternParameter1;
141 |
142 | uInitialCondition.Set(u0);
143 | vInitialCondition.Set(v0);
144 | }
145 | break;
146 | case PatternType::Schnakenberg:
147 | uInitialCondition.Set(params.patternParameter1 + params.patternParameter2);
148 | vInitialCondition.Set(params.patternParameter2 / ((params.patternParameter1 + params.patternParameter2) * (params.patternParameter1 + params.patternParameter2)));
149 | break;
150 | case PatternType::Brussellator:
151 | uInitialCondition.Set(params.patternParameter1);
152 | vInitialCondition.Set(params.patternParameter2 / params.patternParameter1);
153 | break;
154 | case PatternType::GrayScott:
155 | {
156 | uInitialCondition.Set(1.0);
157 | vInitialCondition.Set(0.0);
158 |
159 | std::vector> uCenteredSquare(uInitialCondition.size());
160 | std::vector> vCenteredSquare(vInitialCondition.size());
161 | size_t squareStartX = uInitialCondition.nRows() * 2 / 5;
162 | size_t squareEndX = uInitialCondition.nRows() * 3 / 5;
163 | size_t squareStartY = uInitialCondition.nCols() * 2 / 5;
164 | size_t squareEndY = uInitialCondition.nCols() * 3 / 5;
165 | for (size_t j = squareStartY; j < squareEndY; j++)
166 | {
167 | for (size_t i = squareStartX; i < squareEndX; i++)
168 | {
169 | uCenteredSquare[i + uInitialCondition.nRows() * j] = -.5;
170 | vCenteredSquare[i + uInitialCondition.nRows() * j] = .25;
171 | }
172 | }
173 | matrix uAddition(uCenteredSquare, uInitialCondition.nRows(), uInitialCondition.nCols());
174 | matrix vAddition(vCenteredSquare, vInitialCondition.nRows(), vInitialCondition.nCols());
175 |
176 | uInitialCondition += uAddition;
177 | vInitialCondition += vAddition;
178 | }
179 | break;
180 | default:
181 | break;
182 | }
183 | }
184 |
185 | template
186 | void runner(const RunParameters& params)
187 | {
188 | std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now();
189 |
190 | // ************ Make Grid ************
191 | vector xGrid = vector::LinSpace(params.xMin, params.xMax, params.xDimension);
192 | vector yGrid = vector::LinSpace(params.yMin, params.yMax, params.yDimension);
193 |
194 | std::chrono::high_resolution_clock::time_point t2 = std::chrono::high_resolution_clock::now(); \
195 |
196 | std::cout << "Created grid in " << std::chrono::duration_cast>(t2 - t1).count() << " seconds." << std::endl; \
197 | // ***********************************
198 |
199 | // ***************** Make Initial Condition ******************
200 | t1 = std::chrono::high_resolution_clock::now();
201 |
202 | matrix whiteNoise(xGrid.size(), yGrid.size());
203 | whiteNoise.RandomGaussian(1234);
204 | whiteNoise.Scale(params.whiteNoiseScale);
205 |
206 | matrix uInitialCondition(xGrid.size(), yGrid.size());
207 | matrix vInitialCondition(xGrid.size(), yGrid.size());
208 | MakeInitialCondition(uInitialCondition, vInitialCondition, params);
209 |
210 | uInitialCondition += whiteNoise;
211 | vInitialCondition += whiteNoise;
212 |
213 | t2 = std::chrono::high_resolution_clock::now();
214 | std::cout << "Created initial condition in " << std::chrono::duration_cast>(t2 - t1).count() << " seconds." << std::endl;
215 | // ***************************************************************
216 |
217 | // **************** Initialize Solver ***************
218 | t1 = std::chrono::high_resolution_clock::now();
219 |
220 | BoundaryCondition leftBc(params.boundaryCondition, 0.0);
221 | BoundaryCondition rightBc(params.boundaryCondition, 0.0);
222 | BoundaryCondition downBc(params.boundaryCondition, 0.0);
223 | BoundaryCondition upBc(params.boundaryCondition, 0.0);
224 | BoundaryCondition2D bc(leftBc, rightBc, downBc, upBc);
225 |
226 | pde::PdeInputData2D uData(uInitialCondition, xGrid, yGrid, 0.0, 0.0, params.uDiffusion, params.dt, SolverType::ImplicitEuler, SpaceDiscretizerType::Centered, bc);
227 | pde::PdeInputData2D vData(vInitialCondition, xGrid, yGrid, 0.0, 0.0, params.vDiffusion, params.dt, SolverType::ImplicitEuler, SpaceDiscretizerType::Centered, bc);
228 |
229 | pde::AdvectionDiffusionSolver2D uSolver(std::move(uData));
230 | pde::AdvectionDiffusionSolver2D vSolver(std::move(vData));
231 |
232 | std::cout << "Solver setup in " << std::chrono::duration_cast>(t2 - t1).count() << " seconds." << std::endl;
233 | // ****************************************************
234 |
235 | auto _xGrid = xGrid.Get();
236 | auto _yGrid = yGrid.Get();
237 |
238 | #ifndef SAVE_TO_FILE
239 | // solution matrix is a collection of flattened solutions over time
240 | forge::Window wnd(1024, 768, "Pattern");
241 | wnd.makeCurrent();
242 |
243 | #ifdef PLOT_3D
244 | forge::Chart chart(FG_CHART_3D);
245 |
246 | auto _ic = uInitialCondition.Get();
247 | chart.setAxesLimits(_xGrid.front(), _xGrid.back(), _yGrid.front(), _yGrid.back(), params.zMin, params.zMax);
248 | chart.setAxesTitles("x-axis", "y-axis", "z-axis");
249 |
250 | forge::Surface surf = chart.surface(_xGrid.size(), _yGrid.size(), forge::f32);
251 | surf.setColor(FG_BLUE);
252 |
253 | GfxHandle* handle;
254 | createGLBuffer(&handle, surf.vertices(), FORGE_VERTEX_BUFFER);
255 | #else
256 | forge::Image img(_xGrid.size(), _yGrid.size(), FG_RGBA, forge::f32);
257 |
258 | GfxHandle* handle = 0;
259 | createGLBuffer(&handle, img.pixels(), FORGE_IMAGE_BUFFER);
260 | #endif
261 |
262 | bool toDo = true;
263 |
264 | #ifdef PLOT_3D
265 | cl::Vector xyzTriple(3 * uInitialCondition.size());
266 | #else
267 | MemoryBuffer colorMap(0, 4 * uInitialCondition.size(), MemorySpace::Device, MathDomain::Float);
268 | dm::detail::Alloc(colorMap);
269 |
270 | vector uNormalised(uInitialCondition.size());
271 | vector minDummy(uNormalised.size(), 1.0);
272 | #endif
273 |
274 | do
275 | {
276 | if (toDo)
277 | {
278 | for (unsigned m = 0; m < params.nIter; ++m)
279 | {
280 | for (unsigned n = 0; n < params.nIterPerRound; ++n)
281 | {
282 | uSolver.Advance(1);
283 | vSolver.Advance(1);
284 | _ApplyPatternDynamic(uSolver.solution->columns[0]->GetBuffer(), vSolver.solution->columns[0]->GetBuffer(), type, params.dt, params.patternParameter1, params.patternParameter2);
285 | }
286 |
287 | #ifdef PLOT_3D
288 | matrix::MakeTriple(xyzTriple, xGrid, yGrid, *uSolver.solution->columns[0]);
289 | copyToGLBuffer(handle, reinterpret_cast(xyzTriple.GetBuffer().pointer), surf.verticesSize());
290 | wnd.draw(chart);
291 | #else
292 | double min = uSolver.solution->columns[0]->Minimum();
293 | minDummy.Set(min);
294 | uNormalised.AddEqual(minDummy, -1.0);
295 |
296 | double max = uSolver.solution->columns[0]->AbsoluteMaximum();
297 | uNormalised.ReadFrom(*uSolver.solution->columns[0]);
298 | uNormalised.Scale(1.0 / max);
299 | _MakeRgbaJetColorMap(colorMap, uNormalised.GetBuffer());
300 | copyToGLBuffer(handle, (ComputeResourceHandle)colorMap.pointer, img.size());
301 | wnd.draw(img);
302 | #endif
303 | }
304 | }
305 |
306 | #ifdef PLOT_3D
307 | wnd.draw(chart);
308 | #else
309 | wnd.draw(img);
310 | #endif
311 | toDo = false;
312 | }
313 | while (!wnd.close());
314 |
315 | releaseGLBuffer(handle);
316 | #else
317 | std::vector> solutionMatrix;
318 |
319 | for (unsigned m = 0; m < params.nIter; ++m)
320 | {
321 | t1 = std::chrono::high_resolution_clock::now();
322 |
323 | for (unsigned n = 0; n < params.nIterPerRound; ++n)
324 | {
325 | uSolver.Advance(1);
326 | vSolver.Advance(1);
327 | _ApplyPatternDynamic(uSolver.solution->columns[0]->GetBuffer(), vSolver.solution->columns[0]->GetBuffer(), type, params.dt, params.patternParameter1, params.patternParameter2);
328 | }
329 |
330 | t2 = std::chrono::high_resolution_clock::now();
331 | std::cout << "Step " << m << " done in " << std::chrono::duration_cast>(t2 - t1).count() << " seconds." << std::endl;
332 |
333 | const auto solution = uSolver.solution->columns[0]->Get();
334 | solutionMatrix.insert(solutionMatrix.end(), solution.begin(), solution.end());
335 | }
336 |
337 | cl::MatrixToBinaryFile>(solutionMatrix, params.nIter, uSolver.solution->columns[0]->size(), params.outputFile, false);
338 | #endif
339 | }
340 |
341 | int main(int argc, char** argv)
342 | {
343 | clp::CommandLineArgumentParser ap(argc, argv);
344 |
345 | auto mathDomain = ep::ParseMathDomain(ap.GetArgumentValue("-md", "Float"));
346 | auto patternType = ep::ParsePatternType(ap.GetArgumentValue("-pattern", "GrayScott"));
347 |
348 | RunParameters rp;
349 | std::string bc = ap.GetArgumentValue("-bc", "Periodic");
350 | if (bc == "Periodic")
351 | rp.boundaryCondition = BoundaryConditionType::Periodic;
352 | if (bc == "ZeroFlux")
353 | rp.boundaryCondition = BoundaryConditionType::Neumann;
354 | rp.dt = ap.GetArgumentValue("-dt", rp.dt);
355 | rp.nIter = ap.GetArgumentValue("-nIter", rp.nIter);
356 | rp.nIterPerRound = ap.GetArgumentValue("-nIterPerRound", rp.nIterPerRound);
357 | rp.xDimension = ap.GetArgumentValue("-xd", rp.xDimension);
358 | rp.yDimension = ap.GetArgumentValue("-yd", rp.yDimension);
359 | rp.xMin = ap.GetArgumentValue("-xm", rp.xMin);
360 | rp.xMax = ap.GetArgumentValue("-xM", 0.0);
361 | if (rp.xMax == 0)
362 | rp.xMax = rp.xDimension - 1.0;
363 | rp.yDimension = ap.GetArgumentValue("-yd", rp.yDimension);
364 | rp.yMin = ap.GetArgumentValue("-ym", rp.yMin);
365 | rp.yMax = ap.GetArgumentValue("-yM", 0.0);
366 | if (rp.yMax == 0)
367 | rp.yMax = rp.yDimension - 1.0;
368 | rp.zMin = ap.GetArgumentValue("-zm", rp.zMin);
369 | rp.zMax = ap.GetArgumentValue("-zM", rp.zMax);
370 |
371 | rp.whiteNoiseScale = ap.GetArgumentValue("-wns", rp.whiteNoiseScale);
372 | rp.uDiffusion = ap.GetArgumentValue("-ud", rp.uDiffusion);
373 | rp.vDiffusion = ap.GetArgumentValue("-vd", rp.vDiffusion);
374 | rp.patternParameter1 = ap.GetArgumentValue("-p1", rp.patternParameter1);
375 | rp.patternParameter2 = ap.GetArgumentValue("-p2", rp.patternParameter2);
376 | rp.outputFile = ap.GetArgumentValue("-of", "sol.cl");
377 |
378 | switch (mathDomain)
379 | {
380 | case MathDomain::Float:
381 | switch (patternType)
382 | {
383 | case PatternType::FitzHughNagumo:
384 | runner(rp);
385 | break;
386 | case PatternType::Thomas:
387 | runner(rp);
388 | break;
389 | case PatternType::Schnakenberg:
390 | runner(rp);
391 | break;
392 | case PatternType::Brussellator:
393 | runner(rp);
394 | break;
395 | case PatternType::GrayScott:
396 | runner(rp);
397 | break;
398 | default:
399 | break;
400 | }
401 | break;
402 | case MathDomain::Double:
403 | switch (patternType)
404 | {
405 | case PatternType::FitzHughNagumo:
406 | runner(rp);
407 | break;
408 | case PatternType::Thomas:
409 | runner(rp);
410 | break;
411 | case PatternType::Schnakenberg:
412 | runner(rp);
413 | break;
414 | case PatternType::Brussellator:
415 | runner(rp);
416 | break;
417 | case PatternType::GrayScott:
418 | runner(rp);
419 | break;
420 | default:
421 | break;
422 | }
423 | default:
424 | throw NotImplementedException();
425 | }
426 |
427 | return 0;
428 | }
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-minimal
--------------------------------------------------------------------------------
/bacteria2_compressed.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pmontalb/TuringPatterns/64cb1bc66a00a9c50d33ea08da143403cbf98bbe/bacteria2_compressed.gif
--------------------------------------------------------------------------------
/bacteria_compressed.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pmontalb/TuringPatterns/64cb1bc66a00a9c50d33ea08da143403cbf98bbe/bacteria_compressed.gif
--------------------------------------------------------------------------------
/br_stripes_compressed.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pmontalb/TuringPatterns/64cb1bc66a00a9c50d33ea08da143403cbf98bbe/br_stripes_compressed.gif
--------------------------------------------------------------------------------
/coral2_compressed.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pmontalb/TuringPatterns/64cb1bc66a00a9c50d33ea08da143403cbf98bbe/coral2_compressed.gif
--------------------------------------------------------------------------------
/coral3_compressed.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pmontalb/TuringPatterns/64cb1bc66a00a9c50d33ea08da143403cbf98bbe/coral3_compressed.gif
--------------------------------------------------------------------------------
/coral_compressed.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pmontalb/TuringPatterns/64cb1bc66a00a9c50d33ea08da143403cbf98bbe/coral_compressed.gif
--------------------------------------------------------------------------------
/fhn_compressed.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pmontalb/TuringPatterns/64cb1bc66a00a9c50d33ea08da143403cbf98bbe/fhn_compressed.gif
--------------------------------------------------------------------------------
/fhnb_compressed.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pmontalb/TuringPatterns/64cb1bc66a00a9c50d33ea08da143403cbf98bbe/fhnb_compressed.gif
--------------------------------------------------------------------------------
/lines_compressed.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pmontalb/TuringPatterns/64cb1bc66a00a9c50d33ea08da143403cbf98bbe/lines_compressed.gif
--------------------------------------------------------------------------------
/patternRunner.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | from subprocess import Popen
3 | import os
4 | from plotter import animate_colormap
5 |
6 | CWD = os.getcwd()
7 | if os.name == 'nt':
8 | debugBin = "{}\\x64\\Debug\\TuringPatterns.exe".format(CWD)
9 | releaseBin = "{}\\x64\\Release\\TuringPatterns.exe".format(CWD)
10 |
11 | GRID_FILE = "{}\\grid.npy".format(CWD)
12 | INITIAL_CONDITION_FILE = "{}\\ic.npy".format(CWD)
13 |
14 | X_GRID_FILE = "{}\\x_grid.npy".format(CWD)
15 | Y_GRID_FILE = "{}\\y_grid.npy".format(CWD)
16 | else:
17 | debugBin = "{}/cmake-build-gcc-debug/TuringPatterns".format(CWD)
18 | releaseBin = "{}/cmake-build-gcc-release/TuringPatterns".format(CWD)
19 |
20 | GRID_FILE = "{}/grid.npy".format(CWD)
21 | INITIAL_CONDITION_FILE = "{}/ic.npy".format(CWD)
22 |
23 | X_GRID_FILE = "{}/x_grid.npy".format(CWD)
24 | Y_GRID_FILE = "{}/y_grid.npy".format(CWD)
25 |
26 | chosenBin = debugBin
27 |
28 | def read_solution(file_name, N, N_x, N_y):
29 | _tensor = np.load(file_name).flatten()
30 | tensor = []
31 | for n in range(N):
32 | m = np.zeros((N_x, N_y))
33 | for i in range(N_x):
34 | for j in range(N_y):
35 | m[j, i] = _tensor[i + j * N_x + n * N_x * N_y]
36 | tensor.append(m)
37 | return np.array(tensor)
38 |
39 |
40 | def run_gray_scott_bacteria(run=True, save=False):
41 | N = 100
42 | N_x = 64
43 | N_y = 64
44 | if run:
45 | p = Popen([chosenBin] +
46 | ["-pattern", "GrayScott"] +
47 | ["-bc", "Periodic"] +
48 | ["-xd", str(N_x)] +
49 | ["-yd", str(N_y)] +
50 | ["-nIter", str(N)] +
51 | ["-nIterPerRound", "100"] +
52 | ["-dt", "1.0"] +
53 | ["-wns", ".05"] +
54 | ["-ud", ".16"] +
55 | ["-vd", ".08"] +
56 | ["-p1", "0.035"] +
57 | ["-p2", ".065"] +
58 | ["-of", "bacteria.npy"])
59 | p.communicate()
60 |
61 | tensor = read_solution("bacteria.npy", N, N_x, N_y)
62 |
63 | animate_colormap(tensor,
64 | np.linspace(0.0, 1.0, N_x),
65 | np.linspace(0.0, 1.0, N_y),
66 | cmap='RdBu',
67 | show=not save,
68 | save=save,
69 | name="bacteria.gif")
70 |
71 |
72 | def run_gray_scott_bacteria2(run=True, save=False):
73 | N = 100
74 | N_x = 64
75 | N_y = 64
76 | if run:
77 | p = Popen([chosenBin] +
78 | ["-pattern", "GrayScott"] +
79 | ["-bc", "Periodic"] +
80 | ["-xd", str(N_x)] +
81 | ["-yd", str(N_y)] +
82 | ["-nIter", str(N)] +
83 | ["-nIterPerRound", "100"] +
84 | ["-dt", "1.0"] +
85 | ["-wns", ".05"] +
86 | ["-ud", ".14"] +
87 | ["-vd", ".06"] +
88 | ["-p1", "0.035"] +
89 | ["-p2", ".065"] +
90 | ["-of", "bacteria2.npy"])
91 | p.communicate()
92 |
93 | tensor = read_solution("bacteria2.npy", N, N_x, N_y)
94 |
95 | animate_colormap(tensor,
96 | np.linspace(0.0, 1.0, tensor.shape[2]),
97 | np.linspace(0.0, 1.0, tensor.shape[1]),
98 | cmap='RdBu',
99 | show=not save,
100 | save=save,
101 | name="bacteria2.gif")
102 |
103 |
104 | def run_gray_scott_coral(run=True, save=False):
105 | N = 100
106 | N_x = 100
107 | N_y = 100
108 | if run:
109 | p = Popen([chosenBin] +
110 | ["-pattern", "GrayScott"] +
111 | ["-bc", "Periodic"] +
112 | ["-xd", str(N_x)] +
113 | ["-yd", str(N_y)] +
114 | ["-nIter", str(N)] +
115 | ["-nIterPerRound", "100"] +
116 | ["-dt", ".5"] +
117 | ["-wns", ".05"] +
118 | ["-ud", ".19"] +
119 | ["-vd", ".05"] +
120 | ["-p1", ".06"] +
121 | ["-p2", ".02"] +
122 | ["-of", "coral.npy"])
123 | p.communicate()
124 |
125 | tensor = read_solution("coral.npy", N, N_x, N_y)
126 |
127 | animate_colormap(tensor,
128 | np.linspace(0.0, 1.0, tensor.shape[2]),
129 | np.linspace(0.0, 1.0, tensor.shape[1]),
130 | cmap='RdBu',
131 | show=not save,
132 | save=save,
133 | name="coral.gif")
134 |
135 |
136 | def run_gray_scott_coral2(run=True, save=False):
137 | N = 100
138 | N_x = 100
139 | N_y = 100
140 | if run:
141 | p = Popen([chosenBin] +
142 | ["-pattern", "GrayScott"] +
143 | ["-bc", "ZeroFlux"] +
144 | ["-xd", str(N_x)] +
145 | ["-yd", str(N_y)] +
146 | ["-nIter", str(N)] +
147 | ["-nIterPerRound", "100"] +
148 | ["-dt", ".5"] +
149 | ["-wns", ".05"] +
150 | ["-ud", ".19"] +
151 | ["-vd", ".05"] +
152 | ["-p1", ".01"] +
153 | ["-p2", ".015"] +
154 | ["-of", "coral2.npy"])
155 | p.communicate()
156 |
157 | tensor = read_solution("coral2.npy", N, N_x, N_y)
158 |
159 | animate_colormap(tensor,
160 | np.linspace(0.0, 1.0, tensor.shape[2]),
161 | np.linspace(0.0, 1.0, tensor.shape[1]),
162 | cmap='RdBu',
163 | show=not save,
164 | save=save,
165 | name="coral2.gif")
166 |
167 |
168 | def run_gray_scott_coral3(run=True, save=False):
169 | N = 100
170 | N_x = 100
171 | N_y = 100
172 | if run:
173 | p = Popen([chosenBin] +
174 | ["-pattern", "GrayScott"] +
175 | ["-bc", "Periodic"] +
176 | ["-xd", str(N_x)] +
177 | ["-yd", str(N_x)] +
178 | ["-nIter", "100"] +
179 | ["-nIterPerRound", "100"] +
180 | ["-dt", ".5"] +
181 | ["-wns", ".05"] +
182 | ["-ud", ".19"] +
183 | ["-vd", ".05"] +
184 | ["-p1", ".03"] +
185 | ["-p2", ".025"] +
186 | ["-of", "coral3.npy"])
187 | p.communicate()
188 |
189 | tensor = read_solution("coral3.npy", N, N_x, N_y)
190 |
191 | animate_colormap(tensor,
192 | np.linspace(0.0, 1.0, tensor.shape[2]),
193 | np.linspace(0.0, 1.0, tensor.shape[1]),
194 | cmap='RdBu',
195 | show=not save,
196 | save=save,
197 | name="coral3.gif")
198 |
199 |
200 | def run_gray_scott_lines(run=True, save=False):
201 | N = 100
202 | N_x = 100
203 | N_y = 100
204 | if run:
205 | p = Popen([chosenBin] +
206 | ["-pattern", "GrayScott"] +
207 | ["-bc", "Periodic"] +
208 | ["-xd", str(N_x)] +
209 | ["-yd", str(N_x)] +
210 | ["-nIter", "100"] +
211 | ["-nIterPerRound", "100"] +
212 | ["-dt", "1"] +
213 | ["-wns", ".05"] +
214 | ["-ud", ".16"] +
215 | ["-vd", ".08"] +
216 | ["-p1", ".05"] +
217 | ["-p2", ".065"] +
218 | ["-of", "lines.npy"])
219 | p.communicate()
220 |
221 | tensor = read_solution("lines.npy", N, N_x, N_y)
222 |
223 | animate_colormap(tensor,
224 | np.linspace(0.0, 1.0, tensor.shape[2]),
225 | np.linspace(0.0, 1.0, tensor.shape[1]),
226 | cmap='RdBu',
227 | show=not save,
228 | save=save,
229 | name="lines.gif")
230 |
231 |
232 | def run_brussellator_stripes(run=True, save=False):
233 | N = 100
234 | N_x = 64
235 | N_y = 64
236 | if run:
237 | p = Popen([chosenBin] +
238 | ["-pattern", "Brussellator"] +
239 | ["-bc", "ZeroFlux"] +
240 | ["-xd", str(N_x)] +
241 | ["-yd", str(N_y)] +
242 | ["-nIter", str(N)] +
243 | ["-nIterPerRound", "100"] +
244 | ["-dt", "0.01"] +
245 | ["-wns", ".05"] +
246 | ["-ud", "2"] +
247 | ["-vd", "16"] +
248 | ["-p1", "4.5"] +
249 | ["-p2", "7.5"] +
250 | ["-of", "br_stripes.npy"])
251 | p.communicate()
252 |
253 | tensor = read_solution("br_stripes.npy", N, N_x, N_y)
254 |
255 | animate_colormap(tensor,
256 | np.linspace(0.0, 1.0, tensor.shape[2]),
257 | np.linspace(0.0, 1.0, tensor.shape[1]),
258 | cmap='RdBu',
259 | show=not save,
260 | save=save,
261 | name="br_stripes.gif")
262 |
263 |
264 | def run_brussellator_dots(run=True, save=False):
265 | N = 100
266 | N_x = 100
267 | N_y = 100
268 | if run:
269 | p = Popen([chosenBin] +
270 | ["-pattern", "Brussellator"] +
271 | ["-bc", "Periodic"] +
272 | ["-xd", str(N_x)] +
273 | ["-yd", str(N_x)] +
274 | ["-nIter", str(N)] +
275 | ["-nIterPerRound", "100"] +
276 | ["-dt", "0.005"] +
277 | ["-wns", ".05"] +
278 | ["-ud", "2"] +
279 | ["-vd", "16"] +
280 | ["-p1", "4.5"] +
281 | ["-p2", "12"] +
282 | ["-of", "br_dots.npy"])
283 | p.communicate()
284 |
285 | tensor = read_solution("br_dots.npy", N, N_x, N_y)
286 |
287 | animate_colormap(tensor,
288 | np.linspace(0.0, 1.0, tensor.shape[2]),
289 | np.linspace(0.0, 1.0, tensor.shape[1]),
290 | cmap='Spectral',
291 | show=not save,
292 | save=save,
293 | name="br_dots.gif")
294 |
295 |
296 | def run_schnakenberg(run=True, save=False):
297 | N = 100
298 | N_x = 64
299 | N_y = 64
300 | if run:
301 | p = Popen([chosenBin] +
302 | ["-pattern", "Schnakenberg"] +
303 | ["-bc", "ZeroFlux"] +
304 | ["-xd", str(N_x)] +
305 | ["-yd", str(N_x)] +
306 | ["-nIter", str(N)] +
307 | ["-nIterPerRound", "200"] +
308 | ["-dt", "0.01"] +
309 | ["-wns", ".05"] +
310 | ["-ud", "1.0"] +
311 | ["-vd", "10"] +
312 | ["-p1", ".1"] +
313 | ["-p2", ".9"] +
314 | ["-of", "schnakenberg.npy"])
315 | p.communicate()
316 |
317 | tensor = read_solution("schnakenberg.npy", N, N_x, N_y)
318 |
319 | animate_colormap(tensor,
320 | np.linspace(0.0, 1.0, tensor.shape[2]),
321 | np.linspace(0.0, 1.0, tensor.shape[1]),
322 | cmap='seismic',
323 | show=not save,
324 | save=save,
325 | name="schnakenberg.gif")
326 |
327 |
328 | def run_thomas(run=True, save=False):
329 | N = 100
330 | N_x = 64
331 | N_y = 64
332 | if run:
333 | p = Popen([chosenBin] +
334 | ["-pattern", "Thomas"] +
335 | ["-bc", "ZeroFlux"] +
336 | ["-xd", str(N_x)] +
337 | ["-yd", str(N_x)] +
338 | ["-nIter", str(N)] +
339 | ["-nIterPerRound", "100"] +
340 | ["-dt", "0.0005"] +
341 | ["-wns", ".1"] +
342 | ["-ud", "1.0"] +
343 | ["-vd", "28"] +
344 | ["-p1", "150"] +
345 | ["-p2", "100"] +
346 | ["-of", "thomas.npy"])
347 | p.communicate()
348 |
349 | tensor = read_solution("thomas.npy", N, N_x, N_y)
350 |
351 | animate_colormap(tensor,
352 | np.linspace(0.0, 1.0, tensor.shape[2]),
353 | np.linspace(0.0, 1.0, tensor.shape[1]),
354 | cmap='seismic',
355 | show=not save,
356 | save=save,
357 | name="schnakenberg.gif")
358 |
359 |
360 | def run_fitz_hugh_nagumo(run=True, save=False):
361 | N = 100
362 | N_x = 64
363 | N_y = 64
364 | if run:
365 | p = Popen([chosenBin] +
366 | ["-pattern", "FitzHughNagumo"] +
367 | ["-bc", "ZeroFlux"] +
368 | ["-xd", str(N_x)] +
369 | ["-yd", str(N_x)] +
370 | ["-nIter", str(N)] +
371 | ["-nIterPerRound", "1000"] +
372 | ["-dt", "0.001"] +
373 | ["-wns", ".05"] +
374 | ["-ud", "1"] +
375 | ["-vd", "100"] +
376 | ["-p1", "-0.005"] +
377 | ["-p2", "10.0"] +
378 | ["-of", "fhn.npy"])
379 | p.communicate()
380 |
381 | tensor = read_solution("fhn.npy", N, N_x, N_y)
382 |
383 | animate_colormap(tensor,
384 | np.linspace(0.0, 1.0, tensor.shape[2]),
385 | np.linspace(0.0, 1.0, tensor.shape[1]),
386 | cmap='RdBu',
387 | show=not save,
388 | save=save,
389 | name="fhn.gif")
390 |
391 |
392 | def run_fitz_hugh_nagumo_low_beta(run=True, save=False):
393 | N = 100
394 | N_x = 100
395 | N_y = 100
396 | if run:
397 | p = Popen([chosenBin] +
398 | ["-pattern", "FitzHughNagumo"] +
399 | ["-bc", "ZeroFlux"] +
400 | ["-xd", str(N_x)] +
401 | ["-yd", str(N_x)] +
402 | ["-nIter", "100"] +
403 | ["-nIterPerRound", "1000"] +
404 | ["-dt", "0.001"] +
405 | ["-wns", ".05"] +
406 | ["-ud", "1"] +
407 | ["-vd", "100"] +
408 | ["-p1", "0.01"] +
409 | ["-p2", ".25"] +
410 | ["-of", "fhnb.npy"])
411 | p.communicate()
412 |
413 | tensor = read_solution("fhnb.npy", N, N_x, N_y)
414 |
415 | animate_colormap(tensor,
416 | np.linspace(0.0, 1.0, tensor.shape[2]),
417 | np.linspace(0.0, 1.0, tensor.shape[1]),
418 | cmap='RdBu',
419 | show=not save,
420 | save=save,
421 | name="fhnb.gif")
422 |
423 |
424 | def run_fitz_hugh_nagumo_spatial(run=True, save=False):
425 | N = 100
426 | N_x = 100
427 | N_y = 100
428 | if run:
429 | p = Popen([chosenBin] +
430 | ["-pattern", "FitzHughNagumo"] +
431 | ["-bc", "ZeroFlux"] +
432 | ["-xd", str(N_x)] +
433 | ["-yd", str(N_x)] +
434 | ["-nIter", "100"] +
435 | ["-nIterPerRound", "1000"] +
436 | ["-dt", "0.001"] +
437 | ["-wns", ".05"] +
438 | ["-ud", "1"] +
439 | ["-vd", "100"] +
440 | ["-p1", "0.01"] +
441 | ["-p2", "10"] +
442 | ["-of", "fhns.npy"])
443 | p.communicate()
444 |
445 | tensor = read_solution("fhns.npy", N, N_x, N_y)
446 |
447 | animate_colormap(tensor,
448 | np.linspace(0.0, 1.0, tensor.shape[2]),
449 | np.linspace(0.0, 1.0, tensor.shape[1]),
450 | cmap='RdBu',
451 | show=not save,
452 | save=save,
453 | name="fhns.gif")
454 |
455 |
456 | if __name__ == "__main__":
457 | run_gray_scott_bacteria(run=True, save=False)
458 | # run_gray_scott_bacteria2(run=True, save=False)
459 | # run_gray_scott_coral(run=True, save=False)
460 | # run_gray_scott_coral2(run=True, save=False)
461 | # run_gray_scott_coral3(run=False, save=False)
462 | # run_gray_scott_lines(run=True, save=False)
463 | # run_brussellator_stripes(run=True, save=False)
464 | # run_brussellator_dots(run=True, save=False)
465 | # run_schnakenberg(run=True, save=False)
466 | # run_thomas(run=True, save=False)
467 | # run_fitz_hugh_nagumo(run=True, save=False)
--------------------------------------------------------------------------------
/plotter.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | from mpl_toolkits.mplot3d import Axes3D
3 | from matplotlib import cm
4 | import matplotlib.pyplot as plt
5 | import matplotlib.animation as animation
6 | from subprocess import Popen
7 | import os
8 |
9 | debugDll = os.getcwd() + "\\x64\\Debug\\TuringPatterns.exe"
10 | releaseDll = os.getcwd() + "\\x64\\Release\\TuringPatterns.exe"
11 |
12 |
13 | def __ax_formatter(ax, title="", x_label="", y_label="", show_legend=False):
14 | ax.set_title(title)
15 | ax.set_xlabel(x_label)
16 | ax.set_ylabel(y_label)
17 |
18 | if show_legend:
19 | ax.legend(loc='best')
20 |
21 |
22 | def surf(z, x, y, title="", x_label="", y_label="", show_legend=False, show=False):
23 | fig = plt.figure()
24 | ax = fig.gca(projection='3d')
25 |
26 | # Create X and Y data
27 | x_grid, y_grid = np.meshgrid(x, y)
28 |
29 | ax.plot_surface(x_grid, y_grid, z, cmap=cm.coolwarm, rstride=16, cstride=16, antialiased=True)
30 |
31 | __ax_formatter(ax, title, x_label, y_label, show_legend)
32 |
33 | if show:
34 | plt.show()
35 |
36 |
37 | def plot(z, x, title="", x_label="", y_label="", show_legend=False, show=False):
38 | fig = plt.figure()
39 | ax = fig.add_subplot(111)
40 |
41 | for i in range(len(x)):
42 | ax.plot(z[:, i])
43 |
44 | __ax_formatter(ax, title, x_label, y_label, show_legend)
45 |
46 | if show:
47 | plt.show()
48 |
49 |
50 | def animate(z, x, show=False, save=False, name=""):
51 | fig, ax = plt.subplots()
52 |
53 | line, = ax.plot(x, z[:, 0])
54 |
55 | def update_line(i):
56 | if i >= z.shape[1]:
57 | return line,
58 | line.set_ydata(z[:, i]) # update the data
59 | return line,
60 |
61 | # Init only required for blitting to give a clean slate.
62 | def init():
63 | line.set_ydata(z[:, 0])
64 | return line,
65 |
66 | ani = animation.FuncAnimation(fig, update_line, np.arange(1, 200), init_func=init, interval=25, blit=True)
67 |
68 | if show:
69 | plt.show()
70 |
71 | if save:
72 | ani.save(name, writer='imagemagick', fps=60)
73 |
74 |
75 | def animate_3D(z, x, y, rstride=1, cstride=1, cmap=cm.coolwarm, show=False, save=False, name=""):
76 | fig = plt.figure()
77 | ax = fig.gca(projection='3d')
78 |
79 | # Create X and Y data
80 | x_grid, y_grid = np.meshgrid(x, y)
81 |
82 | line = ax.plot_surface(x_grid, y_grid, z[0], cmap=cmap, rstride=rstride, cstride=cstride, antialiased=True)
83 |
84 | def update_line(i):
85 | if i >= z.shape[0]:
86 | return line,
87 | ax.clear()
88 | l = ax.plot_surface(x_grid, y_grid, z[i], cmap=cm.coolwarm,rstride=rstride, cstride=cstride, antialiased=True)
89 | return l,
90 |
91 | ani = animation.FuncAnimation(fig, update_line, np.arange(1, 200), interval=25, blit=False)
92 |
93 | if show:
94 | plt.show()
95 |
96 | if save:
97 | ani.save(name, writer='imagemagick', fps=60)
98 |
99 |
100 | def animate_colormap(z, x, y, cmap='PuBu_r', shading='gouraud', show=False, save=False, name=""):
101 | fig, ax = plt.subplots()
102 | x, y = np.meshgrid(x, y)
103 | ax.pcolormesh(x, y, z[0], shading=shading, cmap=cmap)
104 |
105 | def update_line(i):
106 | if i >= z.shape[0]:
107 | return None,
108 | ax.clear()
109 | ax.pcolormesh(x, y, z[i], shading=shading, cmap=cmap)
110 | return None,
111 |
112 | ani = animation.FuncAnimation(fig, update_line, np.arange(1, 200), interval=25, blit=False)
113 |
114 | if show:
115 | plt.show()
116 |
117 | if save:
118 | ani.save(name, writer='imagemagick', fps=60)
119 |
120 |
121 |
122 |
--------------------------------------------------------------------------------
/schnakenberg_compressed.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pmontalb/TuringPatterns/64cb1bc66a00a9c50d33ea08da143403cbf98bbe/schnakenberg_compressed.gif
--------------------------------------------------------------------------------
/stdafx.cpp:
--------------------------------------------------------------------------------
1 | // stdafx.cpp : source file that includes just the standard includes
2 | // TuringPatterns.pch will be the pre-compiled header
3 | // stdafx.obj will contain the pre-compiled type information
4 |
5 | #include "stdafx.h"
6 |
7 | // TODO: reference any additional headers you need in STDAFX.H
8 | // and not in this file
9 |
--------------------------------------------------------------------------------
/stdafx.h:
--------------------------------------------------------------------------------
1 | // stdafx.h : include file for standard system include files,
2 | // or project specific include files that are used frequently, but
3 | // are changed infrequently
4 | //
5 |
6 | #pragma once
7 |
8 | #include "targetver.h"
9 |
10 | #include
11 | #include
12 | #include
13 |
--------------------------------------------------------------------------------
/targetver.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | // Including SDKDDKVer.h defines the highest available Windows platform.
4 |
5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
7 |
8 | #include
9 |
--------------------------------------------------------------------------------