├── include ├── Request ├── field │ ├── Var │ ├── Boundary │ ├── Boundary.hpp │ └── Var.hpp ├── grid │ ├── Cell │ ├── Face │ ├── Grid │ ├── Vertex │ ├── Face.hpp │ ├── Line.hpp │ ├── Block1.hpp │ ├── Scheme.hpp │ ├── Quad.hpp │ ├── Vertex.hpp │ ├── Cell.hpp │ └── Search_grid.hpp ├── VecX ├── linSolve │ ├── MatX │ ├── LinSys │ ├── LinSys.hpp │ └── MatY.hpp ├── MathExp ├── girdap ├── Request.hpp ├── LinSys.hpp └── base │ └── Interp.hpp ├── src ├── Makefile.am ├── CMakeLists.txt ├── grid │ ├── Block1.cpp │ ├── Hexa.cpp │ ├── Grid.cpp │ └── Line.cpp └── field │ └── Var.cpp ├── .gitignore ├── log └── notes ├── mk ├── FINAL ├── CMakeLists.txt ├── LICENSE.md ├── example ├── unclassified │ ├── main_morph2.cpp │ ├── main_ls_amr_coarse.cpp │ ├── main_heateq.cpp │ ├── main_heattime.cpp │ ├── main_ls_amr.cpp │ ├── main3.cpp │ ├── main_heatt.cpp │ ├── main_shear.cpp │ ├── main_cavity.cpp │ ├── main_amr.cpp │ ├── main2.cpp │ ├── main_triint.cpp │ ├── main_testint.cpp │ ├── main1.cpp │ ├── main_cavity2.cpp │ ├── main_morph.cpp │ ├── main_sod.cpp │ ├── main_rise.cpp │ └── main.cpp └── div │ └── main.cpp └── README.md /include/Request: -------------------------------------------------------------------------------- 1 | #include "Request.hpp" -------------------------------------------------------------------------------- /include/field/Var: -------------------------------------------------------------------------------- 1 | #include "Var.hpp" -------------------------------------------------------------------------------- /include/grid/Cell: -------------------------------------------------------------------------------- 1 | #include "Cell.hpp" -------------------------------------------------------------------------------- /include/grid/Face: -------------------------------------------------------------------------------- 1 | #include "Face.hpp" -------------------------------------------------------------------------------- /include/grid/Grid: -------------------------------------------------------------------------------- 1 | #include "Grid.hpp" -------------------------------------------------------------------------------- /include/VecX: -------------------------------------------------------------------------------- 1 | #include "base/VecX.hpp" 2 | -------------------------------------------------------------------------------- /include/grid/Vertex: -------------------------------------------------------------------------------- 1 | #include "Vertex.hpp" -------------------------------------------------------------------------------- /include/linSolve/MatX: -------------------------------------------------------------------------------- 1 | #include "MatX.hpp" -------------------------------------------------------------------------------- /include/field/Boundary: -------------------------------------------------------------------------------- 1 | #include "Boundary.hpp" -------------------------------------------------------------------------------- /include/linSolve/LinSys: -------------------------------------------------------------------------------- 1 | #include "LinSys.hpp" -------------------------------------------------------------------------------- /include/MathExp: -------------------------------------------------------------------------------- 1 | #include 2 | -------------------------------------------------------------------------------- /include/girdap: -------------------------------------------------------------------------------- 1 | #include 2 | #include "grid/Grid.hpp" 3 | #include "grid/Block1.hpp" 4 | -------------------------------------------------------------------------------- /src/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CXXFLAGS = -I$(top_srcdir)/include -std=c++0x @AM_CXXFLAGS@ 2 | bin_PROGRAMS = cart3dadapt 3 | cart3dadapt_SOURCES = main1.cpp 4 | cart3dadapt_LDADD = $(top_srcdir)/include/grid/grid.a $(AM_LDFLAGS) 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | cart3* 2 | *~ 3 | *.o 4 | ._* 5 | \#*\# 6 | .#* 7 | tmp/ 8 | include/parse 9 | build/ 10 | CMakeFiles/ 11 | CMakeCache.txt 12 | cmake_install.cmake 13 | Makefile 14 | lib/* 15 | bin/* 16 | debug/ 17 | install_manifest.txt 18 | _site 19 | run 20 | Makefile 21 | */Makefile 22 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(SOURCES field/Var.cpp 2 | grid/Cell.cpp 3 | grid/Quad.cpp 4 | grid/Grid.cpp 5 | grid/operator.cpp 6 | grid/operator2.cpp 7 | grid/Vertex.cpp 8 | grid/Line.cpp 9 | grid/Block1.cpp 10 | ) 11 | 12 | add_library(girdapcore STATIC ${SOURCES}) 13 | set(LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/lib) 14 | -------------------------------------------------------------------------------- /log/notes: -------------------------------------------------------------------------------- 1 | @17-08-2016: EU : Reconfiguring directory structure and cmake; so that static library is produced. Then the command line to link it is as follows: 2 | g++ -o test main_div.cpp ../girdap/lib/libgirdap.a -I ../girdap/include -std=c++11 3 | 4 | @11-20-2015: EU : Internal corner cells are not yet supported (see Vertex.cpp) 5 | Boundary cells are defined for only quad in Vertex.cpp 6 | -- This can be extended through a new virtual function (in Cells) 7 | @2-2-2016: EU : * Grid coarsening algorithm with master cell approach is 8 | working with some exceptions (needs to be investigated) 9 | * Level set (vortex stretching) is now producing better results 10 | 11 | -------------------------------------------------------------------------------- /mk: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | SOURCES='src/main_lsp.cpp 3 | include/field/Var.cpp 4 | include/grid2/Cell.cpp 5 | include/grid2/Quad.cpp 6 | include/grid2/Grid.cpp 7 | include/grid2/operator.cpp 8 | include/grid2/Vertex.cpp 9 | include/grid2/Line.cpp' 10 | # include/grid1/Hexa.cpp' 11 | # include/grid2/Vertex.cpp 12 | # include/grid2/Cell.cpp 13 | # include/grid2/Grid.cpp' 14 | # include/grid/type/Line.cpp include/grid/type/Tri.cpp 15 | # include/grid/type/Hexa.cpp' 16 | #c++ -g -I include/ -std=c++0x src/main1.cpp include/grid/Vertex.cpp include/grid/Cell.cpp include/grid/quad/Quad.cpp -o cart3 17 | #c++ -I include/ -std=c++11 $SOURCES -o cart3 18 | clang++ -g -std=c++11 -stdlib=libc++ -I include $SOURCES -o cart3 19 | -------------------------------------------------------------------------------- /FINAL: -------------------------------------------------------------------------------- 1 | Accuracy questions exist; 2 | 1) Continuity of grid refinement; possible solution is to avoid island adaptation; if it is the only cell to be adapted avoid; not for boundary cells; (check north - south , east - west independently; also if it is the only cell not to be adapted - refine it as well. 3 | 2) Criteria; vorticity is not giving good performance; 4 | 3) Coarsening algorithm needs to be there; 5 | 4) FOU is not giving good performance; 6 | 5) Time step needs to be arranged. 7 | 8 | 9 | 10 | OLD!!!! 11 | Try keeping facelist attached to Vertex 12 | Refine addFace 13 | 14 | ****** Tried weak_ptr; but it is extremely inefficient;********* 15 | grid keeps track of nearest vertex to a vertex; that's best; 16 | ***** IMPORTANT ***** 17 | Everyting in Vertex and Cell, ngbr etc. should be maintained as 18 | integers; and shared_ptr should be accessed through get methods 19 | ******** 20 | 21 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | project(girdap) 3 | 4 | 5 | if (CMAKE_VERSION VERSION_LESS "3.1") 6 | if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") 7 | set (CMAKE_CXX_FLAGS "--std=gnu++11 ${CMAKE_CXX_FLAGS}") 8 | endif () 9 | else () 10 | set (CMAKE_CXX_STANDARD 11) 11 | endif () 12 | 13 | include_directories(include) 14 | 15 | add_subdirectory(src) 16 | #add_library(girdap STATIC ${SOURCES}) 17 | set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/bin) 18 | add_executable(girdap src/main.cpp) 19 | target_link_libraries(girdap girdapcore) 20 | install(TARGETS girdap DESTINATION bin) 21 | #install(TARGETS girdap DESTINATION girdap) 22 | #install(DIRECTORY include/ DESTINATION include/girdap PATTERN "*cpp" EXCLUDE) 23 | 24 | set(EXMPS div lsp) 25 | foreach(EX ${EXMPS}) 26 | add_executable(${EX} EXCLUDE_FROM_ALL example/${EX}/main.cpp) 27 | target_link_libraries(${EX} girdapcore) 28 | endforeach(EX) 29 | 30 | 31 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | /* 2 | *************************************************************************** 3 | * Copyright (C) 2015, Eray Uzgoren * 4 | * * 5 | * This program is free software: you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License as published by * 7 | * the Free Software Foundation, either version 3 of the License, or * 8 | * (at your option) any later version. * 9 | * * 10 | * This program is distributed in the hope that it will be useful, * 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 | * GNU General Public License for more details. * 14 | * * 15 | * You should have received a copy of the GNU General Public License * 16 | * along with this program. If not, see . * 17 | *************************************************************************** 18 | */ 19 | -------------------------------------------------------------------------------- /include/Request.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | *************************************************************************** 3 | * Copyright (C) 2015, Eray Uzgoren * 4 | * * 5 | * This program is free software: you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License as published by * 7 | * the Free Software Foundation, either version 3 of the License, or * 8 | * (at your option) any later version. * 9 | * * 10 | * This program is distributed in the hope that it will be useful, * 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 | * GNU General Public License for more details. * 14 | * * 15 | * You should have received a copy of the GNU General Public License * 16 | * along with this program. If not, see . * 17 | *************************************************************************** 18 | */ 19 | #ifndef REQUEST 20 | #define REQUEST 21 | 22 | class Request { 23 | public: 24 | // vector bndSrf; 25 | 26 | 27 | }; 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /include/grid/Face.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | *************************************************************************** 3 | * Copyright (C) 2015, Eray Uzgoren * 4 | * * 5 | * This program is free software: you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License as published by * 7 | * the Free Software Foundation, either version 3 of the License, or * 8 | * (at your option) any later version. * 9 | * * 10 | * This program is distributed in the hope that it will be useful, * 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 | * GNU General Public License for more details. * 14 | * * 15 | * You should have received a copy of the GNU General Public License * 16 | * along with this program. If not, see . * 17 | *************************************************************************** 18 | */ 19 | #ifndef FACE 20 | #define FACE 21 | 22 | class Cell; 23 | 24 | class Face { 25 | public: 26 | typedef unsigned long int uint_8; 27 | vector node; 28 | Cell* parent; 29 | 30 | Face(Cell* c, unsigned short int k) { 31 | parent = c; 32 | } 33 | 34 | }; 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /include/grid/Line.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | *************************************************************************** 3 | * Copyright (C) 2015, Eray Uzgoren * 4 | * * 5 | * This program is free software: you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License as published by * 7 | * the Free Software Foundation, either version 3 of the License, or * 8 | * (at your option) any later version. * 9 | * * 10 | * This program is distributed in the hope that it will be useful, * 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 | * GNU General Public License for more details. * 14 | * * 15 | * You should have received a copy of the GNU General Public License * 16 | * along with this program. If not, see . * 17 | *************************************************************************** 18 | */ 19 | #ifndef LINE 20 | #define LINE 21 | 22 | class Line: public Cell { 23 | protected: 24 | const int_2 map[2] = {1, 0}; 25 | public: 26 | Line(initializer_list l):Cell(l) { 27 | setType(3); 28 | } 29 | 30 | void assignCelltoNode(); 31 | void convertToSimpleBlock(initializer_list n, bool debug=false); 32 | //bool refine(); 33 | void refine(int dir); 34 | 35 | Vec3 vol() { 36 | Vec3 a = edge(); 37 | return Vec3(-a.data[1], a.data[0], 0); 38 | } 39 | Vec3 edge(int_2 i=0) { return (**getVertex(1)) - (**getVertex(0));} 40 | // Vec3 grad(shared_ptr phi); 41 | //void getBCPhi(shared_ptr phi, double &a, double &b); 42 | }; 43 | 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /include/field/Boundary.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | *************************************************************************** 3 | * Copyright (C) 2015, Eray Uzgoren * 4 | * * 5 | * This program is free software: you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License as published by * 7 | * the Free Software Foundation, either version 3 of the License, or * 8 | * (at your option) any later version. * 9 | * * 10 | * This program is distributed in the hope that it will be useful, * 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 | * GNU General Public License for more details. * 14 | * * 15 | * You should have received a copy of the GNU General Public License * 16 | * along with this program. If not, see . * 17 | *************************************************************************** 18 | */ 19 | #ifndef BOUNDARY 20 | #define BOUNDARY 21 | 22 | 23 | class Boundary { 24 | public: 25 | int type; // 0: Dirichlet and 1: Neumann 26 | double a_val, b_val; // Linearized a_val*phi_p + b_val; 27 | 28 | Boundary():type(1), b_val(0), a_val(0) {} 29 | Boundary(int t) :type(t), b_val(0), a_val(0) {} 30 | Boundary(int t, double b) : type(t), b_val(b), a_val(0) {} 31 | Boundary(int t, double b, double a) : type(t), b_val(b), a_val(a){} 32 | 33 | void setBC() { 34 | type = 1; a_val = 0; b_val = 0; 35 | }; 36 | 37 | void setBC(int t) { 38 | type = t; b_val = 0; a_val = 0; 39 | }; 40 | 41 | void setBC(int t, double b, double a=0) { 42 | type = t; b_val = b; a_val = a; 43 | }; 44 | 45 | }; 46 | 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /include/grid/Block1.hpp: -------------------------------------------------------------------------------- 1 | #ifndef BLOCK1 2 | 3 | #include "Grid.hpp" 4 | #include 5 | 6 | class Geo1 { 7 | public: 8 | double s0, s1; 9 | int_8 nx; 10 | std::function f; 11 | Geo1() { 12 | s0=0.0; s1=1.0; 13 | f = [&] (double t) -> Vec3 {return Vec3(0.0) + t*Vec3(1.0, 1.0);}; 14 | } 15 | virtual ~Geo1() {}; 16 | }; 17 | 18 | class Geo1Line: public Geo1 { 19 | public: 20 | Geo1Line():Geo1() {}; 21 | Geo1Line(Vec3 x0, Vec3 x1) { 22 | f = [=] (double t) -> Vec3 {return x0 + t*(x1-x0);}; 23 | }; 24 | }; 25 | 26 | class Geo1Sine: public Geo1 { 27 | public: 28 | Geo1Sine():Geo1() {}; 29 | Geo1Sine(Vec3 x0, Vec3 x1, double a, double freq) { 30 | Vec3 norm(x0[1]-x1[1], x1[0]-x0[0]); 31 | norm = norm/norm.abs(); 32 | Vec3 del = x1-x0; double pi = 4*atan(1.0); 33 | f = [=] (double t) -> Vec3 {return x0 + t*del + a*sin(freq*t*pi)*norm;}; 34 | }; 35 | }; 36 | 37 | class Geo1Circle: public Geo1 { 38 | public: 39 | Geo1Circle():Geo1() {}; 40 | Geo1Circle(Vec3 x0, double r0, double a0=0.0, double a1=360.0) { 41 | double pi = 4*atan(1.0); 42 | if (a0 == a1) a1 = a0 + 360; 43 | if (a1 > a0+360) a1 = a0+360; 44 | if (a1 < a0-360) a1 = a0-360; 45 | s0 = a0/180.0*pi; s1 = a1/180.0*pi; 46 | f = [=] (double t) -> Vec3 {return x0 + r0*Vec3(cos(t), sin(t));}; 47 | }; 48 | }; 49 | 50 | // CONTENTS in src/grid/Block1.cpp 51 | class Block1: public Grid { 52 | public: 53 | Block1():Grid() {}; 54 | Block1(Vec3 n1, Vec3 n2, int_4 nx); 55 | Block1(Geo1* a, int_4 nx); 56 | Block1(initializer_list n1, initializer_list n2, int_4 nx):Block1(Vec3(n1), Vec3(n2), nx){} 57 | 58 | Block1(initializer_list > pt, double del); 59 | Block1(double s0, double s1, int_8 nx 60 | , std::function f); 61 | 62 | void resolve(double del); 63 | 64 | void add(Geo1* a, int_4 nx); 65 | void add(Block1& o); 66 | void add( double s0, double s1, int_8 nx 67 | , std::function f); 68 | 69 | // mergers 70 | void addVol(Block1& o); 71 | void subVol(Block1& o); 72 | 73 | // modify self 74 | void trans(Vec3 dir, double dist); 75 | void rot(Vec3 x0, Vec3 norm, double angle); 76 | 77 | // Create 1D higher 78 | Block2 rotate(Vec3 x0, Vec3 norm, int_8 nx); 79 | Block2 extrude(Vec3 norm, double dist, int_8 nx); 80 | 81 | }; 82 | 83 | 84 | 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /example/unclassified/main_morph2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | *************************************************************************** 3 | * Copyright (C) 2015, Eray Uzgoren * 4 | * * 5 | * This program is free software: you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License as published by * 7 | * the Free Software Foundation, either version 3 of the License, or * 8 | * (at your option) any later version. * 9 | * * 10 | * This program is distributed in the hope that it will be useful, * 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 | * GNU General Public License for more details. * 14 | * * 15 | * You should have received a copy of the GNU General Public License * 16 | * along with this program. If not, see . * 17 | *************************************************************************** 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | int main() { 30 | double pi = 4.0*atan(1); 31 | 32 | Block2* grid = new Block2({0, 0, 0}, {1, 1, 0}, 10, 10); 33 | 34 | grid->addVar({"T"}); 35 | auto T = grid->getVar("T"); 36 | T->set(0); 37 | 38 | // Indicator for a circle; 39 | for (auto j = 0; j < 5; ++j) { 40 | for (auto i = 0; i < grid->listCell.size(); ++i) { 41 | auto x = grid->listCell[i]->getCoord(); 42 | auto r = (grid->listCell[i]->getCoord() - Vec3(0.5, 0.5)).abs(); 43 | T->set(i, 1.0/(1.0 + exp(-2.0*80*(0.15-r)))); 44 | } 45 | grid->solBasedAdapt2(grid->getError(T)); 46 | grid->adapt(); 47 | } 48 | 49 | // Create a surface grid at T = 0.5 50 | auto surf = contour(T, 0.5); 51 | 52 | // Solves for Laplacian(x) = 0; and Laplacian(y) = 0; 53 | // interface location and adapts; 54 | grid->subtract(surf); 55 | 56 | T->setBC("east", "val", 100); 57 | T->setBC("west", "val", 160); 58 | T->setBC("north", "grad", 250*20, -250); 59 | 60 | for (auto itt = 0; itt< 3; ++itt) { 61 | grid->lockBC(T); 62 | T->solve(grid->laplace(2.0) + grid->source(0,1000)); 63 | grid->unlockBC(); 64 | 65 | grid->writeVTK("reg"); 66 | 67 | grid->solBasedAdapt2(grid->getError(T)); 68 | grid->adapt(); 69 | } 70 | grid->writeVTK("reg"); 71 | 72 | delete(grid); 73 | 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /src/grid/Block1.cpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include 4 | 5 | // Block1():Grid() {}; //in include 6 | Block1::Block1(Vec3 n1, Vec3 n2, int_4 nx):Block1::Block1() { 7 | Geo1* tmp = new Geo1Line(n1, n2); 8 | add(tmp, nx); 9 | delete(tmp); 10 | return; 11 | } 12 | 13 | Block1::Block1(Geo1* a, int_4 nx) { 14 | add(a, nx); 15 | } 16 | 17 | void Block1::add(Geo1* a, int_4 nx) { 18 | double del = (a->s1 - a->s0)/(double)nx; 19 | double eps = (a->f(a->s0 + del) - a->f(a->s0)).abs(); 20 | int_8 nVertex=listVertex.size(), i0 = 0; 21 | if (nVertex > 0 && (a->f(a->s0) - **listVertex.rbegin()).abs() < eps*0.1) {i0 = 1; --nVertex;} 22 | bool loop = false; 23 | for (auto i = i0; i < nx+1; ++i) { 24 | // basic closure catch; 25 | auto pt = a->f(a->s0 + (double)(i) * del); 26 | if (i > 0 && (pt - *listVertex[nVertex]).abs() < 0.9*eps) { 27 | loop = true; 28 | break; 29 | } 30 | addVertex(pt); 31 | } 32 | if (loop) { 33 | addCell({(*listVertex.rbegin())->id, nVertex}); 34 | } 35 | for (auto i = nVertex; i < listVertex.size()-1; ++i) { 36 | addCell({i, i+1}); 37 | } 38 | } 39 | 40 | // Block1(initializer_list n1, initializer_list n2, int_4 nx):Block1((Vec3)n1, Vec3(n2), nx){} // in include 41 | 42 | Block1::Block1(initializer_list > pt, double del):Block1::Block1() { 43 | auto itend = pt.end()-1; bool loop = false; 44 | if (Vec3(*pt.begin()) == Vec3(*(pt.end()-1))) {loop = true; --itend;} 45 | for (auto it = pt.begin(); it != itend; ++it) { 46 | Geo1* tmp = new Geo1Line(Vec3(*it), Vec3(*(it+1))); 47 | add(tmp, 1); 48 | delete(tmp); 49 | } 50 | if (loop) addCell({(int_8)listVertex.size()-1, 0}); 51 | resolve(del); 52 | } 53 | 54 | Block1::Block1(double s0, double s1, int_8 nx 55 | , std::function f) { 56 | add(s0, s1, nx, f); 57 | } 58 | 59 | void Block1::resolve(double del) { 60 | bool isadapt=true; 61 | while (isadapt) { 62 | isadapt = false; int nold = listCell.size(); 63 | for (auto c: listCell) { 64 | if (c->level[0] == levelHighBound[0]) continue; 65 | if (c->vol().abs() > del) { 66 | c->adapt[0] = 1; 67 | isadapt = true; 68 | } 69 | } 70 | if (isadapt) adapt(); 71 | if (nold == listCell.size()) break; 72 | } 73 | setCurrentLevels(); 74 | } 75 | 76 | void Block1::add(Block1& o) { 77 | // SIMPLE add; 78 | auto noldv = listVertex.size(); 79 | for (auto v : o.listVertex) { 80 | addVertex(*v); 81 | } 82 | for (auto c : o.listCell) { 83 | addCell({c->node[0] + (int_8)noldv, c->node[1] + (int_8)noldv}); 84 | } 85 | } 86 | 87 | // Parametric add; 88 | void Block1::add(double s0, double s1, int_8 nx 89 | , std::function f) { 90 | double del = (s1 - s0)/(double)nx; 91 | int ncell = listCell.size(); 92 | for (auto i = 0; i < nx+1; ++i) { 93 | addVertex(f(s0 + (double)i * del)); 94 | } 95 | if (listCell.size() > ncell) addCell({ncell-1, ncell}); 96 | for (auto i = 0; i < nx; ++i) { 97 | addCell({ncell+i, ncell+i+1}); 98 | } 99 | } 100 | 101 | 102 | -------------------------------------------------------------------------------- /example/unclassified/main_ls_amr_coarse.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | *************************************************************************** 3 | * Copyright (C) 2015, Eray Uzgoren * 4 | * * 5 | * This program is free software: you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License as published by * 7 | * the Free Software Foundation, either version 3 of the License, or * 8 | * (at your option) any later version. * 9 | * * 10 | * This program is distributed in the hope that it will be useful, * 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 | * GNU General Public License for more details. * 14 | * * 15 | * You should have received a copy of the GNU General Public License * 16 | * along with this program. If not, see . * 17 | *************************************************************************** 18 | */ 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | 29 | 30 | int main() { 31 | auto dt = 0.5; auto writeTime = 0.02; 32 | auto t = clock(); 33 | Block2* grid = new Block2({0, 0, 0}, {1, 1, 0}, 10, 10); 34 | 35 | grid->addVar({"T"}); 36 | auto T = grid->getVar("T"); 37 | 38 | auto u = grid->getVar("u"); 39 | auto v = grid->getVar("v"); 40 | 41 | int filecnt = 0; int it = 0, writeInt = 1; 42 | ofstream myfile; 43 | std::string flname; 44 | 45 | flname="heat"+std::to_string(filecnt++)+".vtk"; 46 | grid->writeAMRdata(flname); 47 | // myfile.open(flname); 48 | // myfile << grid << endl; 49 | // myfile.close(); 50 | int ref = 5; 51 | 52 | double pi = 4.0*atan(1); 53 | for (auto j0 = 0; j0 < ref; ++j0) { 54 | for (auto i = 0; i < grid->listCell.size(); ++i) { 55 | auto r = (grid->listCell[i]->getCoord() - Vec3(0.5, 0.75)).abs(); 56 | T->set(i, 1.0/(1.0 + exp(-2.0*80*(0.15-r)))); 57 | } 58 | auto err = grid->getError(T); 59 | u->set(err.comp(0)); 60 | v->set(err.comp(1)); 61 | 62 | grid->solBasedAdapt2(err); 63 | 64 | flname="heat"+std::to_string(filecnt++)+".vtk"; 65 | grid->writeAMRdata(flname); 66 | // myfile.open(flname); 67 | // myfile << grid << endl; 68 | // myfile.close(); 69 | 70 | grid->adapt(); 71 | 72 | // // write file 73 | flname="heat"+std::to_string(filecnt++)+".vtk"; 74 | grid->writeAMRdata(flname); 75 | // myfile.open(flname); 76 | // myfile << grid << endl; 77 | // myfile.close(); 78 | } 79 | 80 | for (auto j0 = 0; j0 < ref; ++j0) { 81 | for (auto i = 0; i < grid->listCell.size(); ++i) { 82 | auto c = grid->listCell[i]; 83 | if (c->level[0] > 0) c->adapt[0]=-1; 84 | if (c->level[1] > 0) c->adapt[1]=-1; 85 | } 86 | grid->adapt(); 87 | 88 | flname="heat"+std::to_string(filecnt++)+".vtk"; 89 | grid->writeAMRdata(flname); 90 | // myfile.open(flname); 91 | // myfile << grid << endl; 92 | // myfile.close(); 93 | } 94 | 95 | delete(grid); 96 | 97 | return 0; 98 | } 99 | -------------------------------------------------------------------------------- /example/unclassified/main_heateq.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | *************************************************************************** 3 | * Copyright (C) 2015, Eray Uzgoren * 4 | * * 5 | * This program is free software: you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License as published by * 7 | * the Free Software Foundation, either version 3 of the License, or * 8 | * (at your option) any later version. * 9 | * * 10 | * This program is distributed in the hope that it will be useful, * 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 | * GNU General Public License for more details. * 14 | * * 15 | * You should have received a copy of the GNU General Public License * 16 | * along with this program. If not, see . * 17 | *************************************************************************** 18 | */ 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | 29 | 30 | int main() { 31 | auto k = 2.0; auto qdot = 5e3; auto h = 50; auto Tinf = 20; 32 | Block2* grid = new Block2({0, 0, 0}, {1, 1, 0}, 10, 10); 33 | grid->levelHighBound = {2, 2}; 34 | grid->addVar("T"); 35 | 36 | Block2* uni = new Block2({0, 0, 0}, {1, 1, 0}, 40, 40); 37 | uni->levelHighBound[0] = {0, 0}; 38 | uni->addVar("T"); 39 | 40 | auto Tref = uni->getVar("T"); 41 | Tref->solver = "BiCGSTAB"; 42 | Tref->itmax = 1000; 43 | 44 | Tref->set(100); 45 | 46 | Tref->setBC("south", "grad", 0); 47 | Tref->setBC("north", "grad", h/k*Tinf, -h/k); 48 | Tref->setBC("east", "val", 200); 49 | Tref->setBC("west", "val", 100); 50 | 51 | uni->lockBC(Tref); // for boundary conditions 52 | Tref->solve( uni->laplace(k) // thermal conductivity as gamma 53 | + uni->source(0, qdot) ); 54 | uni->unlockBC(); 55 | uni->writeVTK("heat_ref"); 56 | 57 | auto T = grid->getVar("T"); 58 | auto u = grid->getVar("u"); 59 | auto v = grid->getVar("v"); 60 | T->solver = "BiCGSTAB"; 61 | T->itmax = 1000; 62 | 63 | T->set(100); 64 | 65 | T->setBC("south", "grad", 0); 66 | T->setBC("north", "grad", h/k*Tinf, -h/k); 67 | T->setBC("east", "val", 200); 68 | T->setBC("west", "val", 100); 69 | 70 | for (auto i = 0; i< 7; ++i) { 71 | grid->solBasedAdapt2(grid->getError2(T), 2e-3, 2e-1); 72 | grid->adapt(); 73 | 74 | grid->lockBC(T); // for boundary conditions 75 | T->solve( grid->laplace(k) // thermal conductivity as gamma 76 | + grid->source(0, qdot) ); 77 | grid->unlockBC(); 78 | 79 | auto sum = 0; 80 | for (auto v : grid->listVertex) { 81 | auto T0 = uni->interp(Tref, *v); 82 | auto T1 = v->evalPhi(T); 83 | sum += pow(T1-T0, 2); 84 | } 85 | cout << " Error: " << sqrt(sum)/grid->listVertex.size() << endl; 86 | auto err = grid->getError2(T); 87 | u->set(err.comp(0)); 88 | v->set(err.comp(1)); 89 | 90 | grid->writeVTK("heat"); 91 | } 92 | 93 | delete(grid); 94 | 95 | return 0; 96 | } 97 | -------------------------------------------------------------------------------- /include/field/Var.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | *************************************************************************** 3 | * Copyright (C) 2015, Eray Uzgoren * 4 | * * 5 | * This program is free software: you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License as published by * 7 | * the Free Software Foundation, either version 3 of the License, or * 8 | * (at your option) any later version. * 9 | * * 10 | * This program is distributed in the hope that it will be useful, * 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 | * GNU General Public License for more details. * 14 | * * 15 | * You should have received a copy of the GNU General Public License * 16 | * along with this program. If not, see . * 17 | *************************************************************************** 18 | */ 19 | #ifndef VAR 20 | #define VAR 21 | 22 | #include 23 | #include "../linSolve/LinSys.hpp" 24 | #include "Boundary.hpp" 25 | 26 | class Grid; 27 | //template class Scheme; 28 | 29 | class Var { 30 | public: 31 | std::string name; 32 | VecX data; 33 | VecX laplace, div; 34 | //vector > grad; 35 | VecX grad; 36 | VecX error; 37 | // LinSys mat; 38 | Grid *grid; 39 | int_2 loc; // 0 for cell center; 1 for vertex; 2 for faces [faces are difficult] 40 | bool isVec; 41 | double dt; 42 | vector > listBC; 43 | 44 | 45 | string solver; 46 | int itmax; 47 | double tol; 48 | 49 | 50 | Var(std::string a): name(a), isVec(false) { dt = 1.0; loc = 0; solver = "BiCGSTAB"; itmax = -1; tol = -1; } 51 | Var(std::string a, int b) :Var(a) { if (b<0 && b>2) b=0; loc = b; } 52 | 53 | VecX get() {return data;} 54 | double get(int_8 i); 55 | double* operator[](int_8 const &index); 56 | 57 | void changeName(std::string a) { name = a;} 58 | void set(double a) { data.data.assign(data.size(), a); } 59 | void set(VecX a) { data.data.assign(a.data.begin(), a.data.end()); } 60 | void set(int_8 i, double a) { 61 | if (i >=0 && i < data.data.size()) data.data[i] = a; 62 | else { 63 | cout << "Var " << name << " failed to set " << i << " to " << a << endl; 64 | exit(1); 65 | } 66 | } 67 | void set(initializer_list vname, std::string exp); 68 | 69 | void resize(int_8 n) { 70 | if (n <= 0) data.data.clear(); 71 | else data.data.resize(n); 72 | } 73 | 74 | void initBC() { 75 | listBC.resize(6); 76 | auto icnt =0; 77 | for (auto i = 0; i(new Boundary()); 79 | } 80 | } 81 | 82 | void setBC(string id, string t, double b, double a=0) { 83 | int i; int type; 84 | if (id.compare("south") == 0) i = 0; 85 | else if (id.compare("north") == 0) i = 1; 86 | else if (id.compare("west") == 0) i = 2; 87 | else if (id.compare("east") == 0) i = 3; 88 | else return; 89 | if (t.compare("val") == 0) type = 0; 90 | else if (t.compare("grad") == 0) type = 1; 91 | else return; 92 | 93 | if (listBC[i]) { 94 | listBC[i]->setBC(type, b, a); 95 | } 96 | } 97 | 98 | 99 | void solve(LinSys a); 100 | }; 101 | 102 | 103 | #endif 104 | -------------------------------------------------------------------------------- /include/grid/Scheme.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | *************************************************************************** 3 | * Copyright (C) 2015, Eray Uzgoren * 4 | * * 5 | * This program is free software: you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License as published by * 7 | * the Free Software Foundation, either version 3 of the License, or * 8 | * (at your option) any later version. * 9 | * * 10 | * This program is distributed in the hope that it will be useful, * 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 | * GNU General Public License for more details. * 14 | * * 15 | * You should have received a copy of the GNU General Public License * 16 | * along with this program. If not, see . * 17 | *************************************************************************** 18 | */ 19 | #ifndef SCHEME 20 | #define SCHEME 21 | 22 | class Var; 23 | 24 | template class Scheme { 25 | public: 26 | vector ind; 27 | vector val; 28 | T c; 29 | int_2 type; // 0: cell center, 1: vertex, 2: face center; 30 | 31 | Scheme(): type(0), c(0.0) {} 32 | Scheme(int_2 t): type(t), c(0.0) {} 33 | 34 | void resize(int n) { 35 | ind.resize(n); val.resize(n); 36 | } 37 | 38 | int size() { 39 | return ind.size(); 40 | } 41 | 42 | bool isDuplicate(int_8 i) { 43 | return (std::find(ind.begin(), ind.end(), i) != ind.end()); 44 | } 45 | 46 | // int_8 varSize() { 47 | // if (type == 0) return listCell.size(); 48 | // else if (type == 1) return listVertex.size(); 49 | // else if (type == 2) return listFace.size(); 50 | // else { 51 | // cout << "Scheme:varSize(): type is not understood! "<< type << endl; 52 | // return 0; 53 | // } 54 | // } 55 | 56 | void push_pair(int_8 i, T v) { 57 | // auto it = std::find(ind.begin(), ind.end(), i); 58 | // if (it == ind.end()) { 59 | ind.emplace_back(i); 60 | val.emplace_back(v); 61 | // } else { 62 | // auto i = it - ind.begin(); 63 | // val[i] += v; 64 | // } 65 | } 66 | void push_constant(T d) { 67 | c += d; 68 | } 69 | 70 | T eval(shared_ptr phi) { 71 | return eval(phi->data); 72 | } 73 | 74 | T eval(VecX phi) { 75 | // if (phi.size() != varSize()) { 76 | // cout << "Scheme:eval(): Size and location pointer do not match"<& operator/=(T a) { 88 | if (a == 0) {cout << "Scheme:operator/: div by zero!"<< endl; exit(1);} 89 | for (auto i =0; i< size(); ++i) val[i] /= a; 90 | return *this; 91 | } 92 | 93 | Scheme& operator*=(T a) { 94 | if (a == 0) {cout << "Scheme:operator*: mult by zero!"<< endl; exit(1);} 95 | for (auto i =0; i< size(); ++i) val[i] *= a; 96 | return *this; 97 | } 98 | 99 | Scheme& operator=(T const &a) { 100 | ind.assign(a.ind.begin(), a.ind.end()); 101 | val.assign(a.val.begin(), a.val.end()); 102 | c = a.c; 103 | return *this; 104 | } 105 | 106 | Scheme& operator+=(Scheme const &a) { 107 | for (auto i =0; i < a.ind.size(); ++i) { 108 | push_pair(a.ind[i], a.val[i]); 109 | } 110 | push_constant(a.c); 111 | return *this; 112 | } 113 | 114 | 115 | 116 | }; 117 | 118 | 119 | #endif 120 | -------------------------------------------------------------------------------- /include/grid/Quad.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | *************************************************************************** 3 | * Copyright (C) 2015, Eray Uzgoren * 4 | * * 5 | * This program is free software: you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License as published by * 7 | * the Free Software Foundation, either version 3 of the License, or * 8 | * (at your option) any later version. * 9 | * * 10 | * This program is distributed in the hope that it will be useful, * 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 | * GNU General Public License for more details. * 14 | * * 15 | * You should have received a copy of the GNU General Public License * 16 | * along with this program. If not, see . * 17 | *************************************************************************** 18 | */ 19 | #ifndef QUAD 20 | #define QUAD 21 | 22 | class Quad: public Cell { 23 | protected: 24 | const int_2 map[4] = {2, 3, 0, 1}; 25 | public: 26 | // short int type; 27 | Quad(initializer_list l):Cell(l) { 28 | setType(9); 29 | } 30 | 31 | void assignCelltoNode(); 32 | void convertToSimpleBlock(initializer_list n, bool debug=false); 33 | bool refine(); 34 | void refine(int dir); 35 | bool coarsen(int dir); 36 | // // initNodeList assigns this cell to all vertices (hanging nodes hang) 37 | // void initNodeList(shared_ptr c) { 38 | // } 39 | // // assignHangingNode updates the 40 | int_8 hangingVertexOnFace(int_2 i, int_2 j=0) { 41 | shared_ptr *v0, *v1; 42 | int i0=(i+1)%4; int i1=(i0+1)%4; 43 | v0 = getVertex(i); v1 = getVertex(i0); 44 | if (v0 && v1) { 45 | if ((*v0)->cell[i0] >= 0 && ((*v0)->cell[i0] != (*v1)->cell[i])) { 46 | return (*((*v0)->getCell(i0)))->node[i1]; 47 | } 48 | } 49 | return -1; 50 | } 51 | Vec3 edge(int_2 i=0) { 52 | int_2 j, k; 53 | if (i == 0) {j = 1; k = 0; } 54 | else if (i == 1) {j = 2; k = 1; } 55 | else if (i == 2) {j = 2; k = 3; } 56 | else if (i == 3) {j = 3; k = 0; } 57 | auto v1 = getVertex(j); 58 | auto v0 = getVertex(k); 59 | if ((*v1) && (*v0)) return **v1 - **v0; 60 | cout << "Error: Edge do not exist for Quad: "<< i < ngbrCellList(); 76 | void checkIslandLevels(int dir); 77 | void checkNgbrLevel(int dir); 78 | // // shared_ptr makeFace(int_2 i=0) { 79 | // // vector > tmp; 80 | // // if (i >= 4) {cout << "Quad: makeFace(i): i is out of bounds "< c = shared_ptr(new Line(tmp)); 85 | // // return c; 86 | // //} 87 | bool isPointIn(Vec3 a) { 88 | double sum = 0; 89 | for (auto i = 0; i < 4; ++i) { 90 | sum += 0.5*((a - **getVertex(i))^(**getVertex((i+1)%4) - a)).abs(); 91 | } 92 | if (abs(sum - vol().abs()) < 1e-3) return true; 93 | else return false; 94 | } 95 | }; 96 | 97 | 98 | 99 | 100 | #endif 101 | -------------------------------------------------------------------------------- /src/grid/Hexa.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | *************************************************************************** 3 | * Copyright (C) 2015, Eray Uzgoren * 4 | * * 5 | * This program is free software: you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License as published by * 7 | * the Free Software Foundation, either version 3 of the License, or * 8 | * (at your option) any later version. * 9 | * * 10 | * This program is distributed in the hope that it will be useful, * 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 | * GNU General Public License for more details. * 14 | * * 15 | * You should have received a copy of the GNU General Public License * 16 | * along with this program. If not, see . * 17 | *************************************************************************** 18 | */ 19 | #include "Grid.hpp" 20 | 21 | void Hexa::split(initializer_list n) { 22 | int n1 = 1; int n2 = 1; int n3 = 1; 23 | if (n.size() >= 3) {n1 = *(n.begin()); n2 = *(n.begin()+1); n3 = *(n.begin()+2); } 24 | else if (n.size() == 2) {n1 = *(n.begin()); n2 = *(n.begin()+1);} 25 | else if (n.size() == 1) {n1 = *(n.begin());} 26 | else { return; } 27 | 28 | Vec3 dx1, dx2, dx3, dx4, dy1, dy2, dz, dx, dy, dxa, dxb; 29 | vector kk, ll(8,-1); 30 | for (auto v :node) { 31 | kk.push_back(v->id); 32 | } 33 | 34 | dx1 = edge(0)/double(n1); 35 | dx2 = edge(2)/double(n1); 36 | dx3 = edge(4)/double(n1); 37 | dx4 = edge(6)/double(n1); 38 | dy1 = edge(3)/double(n2); 39 | dy2 = edge(7)/double(n2); 40 | dz = edge(8)/double(n3); 41 | 42 | int_8 ind[n1+1][n2+1][n3+1]; 43 | for (auto k = 0; k < n3+1 ; ++k) { 44 | for (auto j = 0; j < n2+1 ; ++j) { 45 | for (auto i = 0; i < n1+1 ; ++i) { 46 | ind[i][j][k] = -1; 47 | if (i == 0 && j == 0 && k == 0) { 48 | ind[i][j][k] = kk[0]; 49 | } else if (i == 0 && j == n2 && k == 0) { 50 | ind[i][j][k] = kk[3]; 51 | } else if (i == n1 && j == n2 && k == 0) { 52 | ind[i][j][k] = kk[2]; 53 | } else if (i == n1 && j == 0 && k == 0) { 54 | ind[i][j][k] = kk[1]; 55 | } else if (i == 0 && j == 0 && k == n3) { 56 | ind[i][j][k] = kk[4]; 57 | } else if (i == 0 && j == n2 && k == n3) { 58 | ind[i][j][k] = kk[7]; 59 | } else if (i == n1 && j == n2 && k == n3) { 60 | ind[i][j][k] = kk[6]; 61 | } else if (i == n1 && j == 0 && k == n3) { 62 | ind[i][j][k] = kk[5]; 63 | } else { 64 | dy = dy1 + (dy2 - dy1)*double(k)/double(n3); 65 | dxa = dx1 + (dx3 - dx1)*double(k)/double(n3); 66 | dxb = dx2 + (dx4 - dx2)*double(k)/double(n3); 67 | dx = dxa + (dxb - dxa)*double(j)/double(n2); 68 | grid->addVertex(*(node.at(0)) + double(i)*dx + double(j)*dy +double(k)*dz); 69 | (*grid->vbegin())->grid = grid; 70 | ind[i][j][k] = (grid->listVertex.size())-1; 71 | } 72 | } 73 | } 74 | } 75 | 76 | for (auto k = 0; k < n3; ++k) { 77 | for (auto j = 0; j < n2; ++j) { 78 | for (auto i = 0; i < n1; ++i) { 79 | ll[0] = ind[i][j][k]; 80 | ll[1] = ind[i+1][j][k]; 81 | ll[2] = ind[i+1][j+1][k]; 82 | ll[3] = ind[i][j+1][k]; 83 | ll[4] = ind[i][j][k+1]; 84 | ll[5] = ind[i+1][j][k+1]; 85 | ll[6] = ind[i+1][j+1][k+1]; 86 | ll[7] = ind[i][j+1][k+1]; 87 | if (i == 0 && j == 0 && k == 0) { 88 | int_4 icnt = 0; 89 | for (auto v = node.begin(); v !=node.end(); ++v) { 90 | (*v) = grid->listVertex.at(ll[icnt]); ++icnt; 91 | } 92 | initNodeList(*(grid->listCell.begin() + id)); 93 | } else { 94 | grid->addCell(ll); 95 | } 96 | } 97 | } 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /include/LinSys.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | *************************************************************************** 3 | * Copyright (C) 2015, Eray Uzgoren * 4 | * * 5 | * This program is free software: you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License as published by * 7 | * the Free Software Foundation, either version 3 of the License, or * 8 | * (at your option) any later version. * 9 | * * 10 | * This program is distributed in the hope that it will be useful, * 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 | * GNU General Public License for more details. * 14 | * * 15 | * You should have received a copy of the GNU General Public License * 16 | * along with this program. If not, see . * 17 | *************************************************************************** 18 | */ 19 | #ifndef LINSYS 20 | #define LINSYS 21 | 22 | #include 23 | 24 | class LinSys { 25 | private: 26 | typedef unsigned long int uint_8; 27 | uint_8 N; 28 | double tol; 29 | unsigned int itmax; 30 | 31 | public: 32 | MatX A; 33 | VecX b; 34 | VecX *x; 35 | 36 | //------------------------- 37 | // Constructor 38 | //------------------------- 39 | LinSys() { setLimits(); } 40 | 41 | LinSys(uint_8 const &a) { 42 | setLimits(); 43 | N = a; 44 | resize(a); 45 | } 46 | 47 | 48 | //------------------------- 49 | // Methods 50 | //------------------------- 51 | void resize(uint_8 const &a) { 52 | N = a; 53 | A.resize(a); 54 | b.resize(a); 55 | } 56 | void clear() { 57 | A.empty(); 58 | b.empty(); 59 | } 60 | void setLimits(double t=1e-6, unsigned int imax = 1000) { 61 | tol = t; itmax = imax; 62 | } 63 | 64 | void setMATX(MatXconst &MAT){ 65 | A=MAT; 66 | } 67 | 68 | void setVECX(VecXconst &VEC){ 69 | b=VEC; 70 | } 71 | 72 | 73 | //------------------------ 74 | // Operators 75 | //------------------------ 76 | VecX solve() { 77 | return b; 78 | } 79 | 80 | void CG() { 81 | unsigned int iter; 82 | double alpha, rsold, rsnew; 83 | VecX r(N), p(N), q(N); 84 | 85 | cout << "askdkjasda" <::rowiter rit=A.data.begin(); rit!=A.data.end(); ++rit, ++r) { 119 | sigma = 0; 120 | for (VecX::it_cmap cit=rit->px.begin(); cit!=rit->px.end(); ++cit) { 121 | if (cit->first == r) continue; 122 | sigma += cit->second * (*x)[cit->first]; 123 | } 124 | sigma = (b[r] - sigma)/rit->px[r]; 125 | err += ((sigma-(*x)[r])); err *= err; 126 | (*x)[r] = sigma; 127 | } 128 | err = sqrt(err/A.rows); 129 | if (err < tol) break; 130 | // cout << "GS: " << iter << "->" << log10(err) < 6 | 7 | class Interp { 8 | public: 9 | // Matrix for trilinear coordinate transformation 10 | MatX AI; 11 | 12 | Interp() { 13 | // initialize matrix; 14 | AI.resize(8); 15 | AI = { { 1, 0, 0, 0, 0, 0, 0, 0}, 16 | {-1, 1, 0, 0, 0, 0, 0, 0}, 17 | {-1, 0, 0, 1, 0, 0, 0, 0}, 18 | {-1, 0, 0, 0, 1, 0, 0, 0}, 19 | { 1,-1, 1,-1, 0, 0, 0, 0}, 20 | { 1,-1, 0, 0,-1, 1, 0, 0}, 21 | { 1, 0, 0,-1,-1, 0, 0, 1}, 22 | {-1, 1,-1, 1, 1,-1, 1,-1} }; 23 | } 24 | 25 | // Coefficients are in the form of tri-linear interpolation 26 | // 8 values based on hexa-ordering should be given 27 | VecX getCoef(VecX &phi) { 28 | return AI*phi; 29 | }; 30 | 31 | // Function itself 32 | double linFunc(Vec3 xhat, VecX &coef) { 33 | return coef[0] + coef[1]*xhat.x() + coef[2]*xhat.y() + coef[3]*xhat.z() 34 | + coef[4]*xhat.x()*xhat.y() + coef[5]*xhat.x()*xhat.z() 35 | + coef[6]*xhat.y()*xhat.z() + coef[7]*xhat.x()*xhat.y()*xhat.z(); 36 | } 37 | 38 | // Partial derivative with respect to xhat 39 | double linDX(Vec3 xhat, VecX &coef) { 40 | return coef[1] + coef[4]*xhat.y() + coef[5]*xhat.z() + coef[7]*xhat.y()*xhat.z(); 41 | } 42 | 43 | // Partial derivative with respect to yhat 44 | double linDY(Vec3 xhat, VecX &coef) { 45 | return coef[2] + coef[4]*xhat.x() + coef[6]*xhat.z() + coef[7]*xhat.x()*xhat.z(); 46 | } 47 | 48 | // Partial derivative with respect to zhat 49 | double linDZ(Vec3 xhat, VecX &coef) { 50 | return coef[3] + coef[5]*xhat.x() + coef[6]*xhat.y() + coef[7]*xhat.x()*xhat.y(); 51 | } 52 | 53 | bool isIn(Vec3 xhat) { 54 | for (auto i=0; i < 3; ++i) { 55 | if (xhat[i] < -0.5) return false; 56 | if (xhat[i] > 1.5) return false; 57 | } 58 | return true; 59 | } 60 | 61 | Vec3 findXhat(Vec3 x, VecX &xcoef, VecX &ycoef, VecX &zcoef) { 62 | Vec3 xhat(0.5, 0.5, 0); //INITIAL GUESS; 63 | Vec3 dx(0, 0, 0); // needed if not updated! 64 | double err = 1, err1; 65 | int it = 0, bnd=0; 66 | 67 | while (it < 20) { 68 | it++; 69 | double dxx = linDX(xhat, xcoef); 70 | double dxy = linDY(xhat, xcoef); 71 | double dxz = linDZ(xhat, xcoef); 72 | 73 | if (std::abs(dxx) > 1e-10) { 74 | dx[0] = (x[0] - linFunc(xhat, xcoef) - dx[1]*dxy - dx[2]*dxz)/dxx; 75 | } 76 | 77 | auto dyx = linDX(xhat, ycoef); 78 | auto dyy = linDY(xhat, ycoef); 79 | auto dyz = linDZ(xhat, ycoef); 80 | 81 | if (std::abs(dyy) > 1e-10) { 82 | dx[1] = (x[1] - linFunc(xhat, ycoef) - dx[0]*dyx - dx[2]*dyz)/dyy; 83 | } 84 | 85 | auto dzx = linDX(xhat, zcoef); 86 | auto dzy = linDY(xhat, zcoef); 87 | auto dzz = linDZ(xhat, zcoef); 88 | 89 | if (std::abs(dzz) > 1e-10) { 90 | dx[2] = (x[2] - linFunc(xhat, zcoef) - dx[0]*dzx - dx[1]*dzy)/dzz; 91 | } 92 | xhat += dx; 93 | 94 | // if (!isIn(xhat)) ++bnd; 95 | // if (bnd > 3) break; 96 | err1 = abs(dx[0]) + abs(dx[1]) + abs(dx[2]); //sqrt(pow(dx[0],2) + pow(dx[1],2) + pow(dx[2],2)); 97 | if (err1 > err) ++bnd; 98 | err = err1; 99 | if (err < 1e-6) break; 100 | if (bnd > 2) break; 101 | 102 | } 103 | // if (xhat[0] < 0 || xhat[0] > 1 || xhat[1] < 0 || xhat[1] > 1 || xhat[2] < 0 || xhat[2] > 1) { 104 | // cout << "not a good value" < &coef) { 114 | auto res = linDX(xhat, coef); 115 | if (abs(res) < 1e-6) return 0; 116 | else return 1./res; 117 | } 118 | 119 | double invDY(Vec3 xhat, VecX &coef) { 120 | auto res = linDY(xhat, coef); 121 | if (abs(res) < 1e-6) return 0; 122 | else return 1./res; 123 | } 124 | 125 | double invDZ(Vec3 xhat, VecX &coef) { 126 | auto res = linDZ(xhat, coef); 127 | if (abs(res) < 1e-6) return 0; 128 | else return 1./res; 129 | } 130 | 131 | }; 132 | 133 | #endif 134 | -------------------------------------------------------------------------------- /example/unclassified/main_heattime.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | *************************************************************************** 3 | * Copyright (C) 2015, Eray Uzgoren * 4 | * * 5 | * This program is free software: you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License as published by * 7 | * the Free Software Foundation, either version 3 of the License, or * 8 | * (at your option) any later version. * 9 | * * 10 | * This program is distributed in the hope that it will be useful, * 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 | * GNU General Public License for more details. * 14 | * * 15 | * You should have received a copy of the GNU General Public License * 16 | * along with this program. If not, see . * 17 | *************************************************************************** 18 | */ 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | 29 | 30 | int main() { 31 | auto dt = 1; 32 | auto t = clock(); 33 | //Block2* grid = new Block2({0, 0, 0}, {0.5, 0.3, 0}, 50, 30); 34 | Block2* grid = new Block2({0, 0, 0}, {1.0, 1.0, 0}, 5, 5); 35 | grid->setDt(dt); 36 | double time= 0; double endTime = 2; //dt*50; 37 | 38 | // Field variables; 39 | double rho=10000, cp=1000, k=10; 40 | 41 | grid->addVar({"T"}); 42 | 43 | auto T = grid->getVar("T"); 44 | auto u = grid->getVar("u"); 45 | auto v = grid->getVar("v"); 46 | 47 | T->set(0.0); 48 | 49 | T->setBC("west", "val", 100); 50 | T->setBC("east", "grad", 100); 51 | T->setBC("south", "grad", -250*20, 250); 52 | T->itmax = 1000; 53 | T->tol = 1e-6; 54 | 55 | // u->set(0.01); 56 | // v->set(0.03); 57 | 58 | int filecnt = 0; int it = 0, writeInt = 1; 59 | ofstream myfile; 60 | // while (time < endTime) { 61 | cout << setiosflags(ios::fixed) << setprecision(6); 62 | cout << "------------- Processing TIME = "<< time << " ------------------"<getVel(); 65 | 66 | grid->lockBC(T); 67 | T->solve( 68 | //grid->ddt(1.0) 69 | // + grid->div(vel, 1.0) 70 | - grid->laplace(1.0) 71 | // - grid->source(0, 10000/cp/rho) 72 | ); 73 | grid->unlockBC(); 74 | 75 | // auto gt = grid->valGrad(T); 76 | // grid->solBasedAdapt(gt, 1); 77 | // grid->refine2(); 78 | 79 | time += grid->dt; 80 | // grid->setDt(dt); 81 | 82 | //if (( it % writeInt) == 0) { 83 | std::string flname="heat"+std::to_string(filecnt++)+".vtk"; 84 | myfile.open(flname); 85 | myfile << grid << endl; 86 | myfile.close(); 87 | //} 88 | 89 | cout << "---------------------------------------------------"<writeFace(); 98 | 99 | // grid->writeFace(); 100 | 101 | delete(grid); 102 | 103 | 104 | // LinSys ls(6); 105 | // VecX x(6); x.uncompress(); 106 | // ls.A = { 107 | // { 2, -1, 0, 0, 0, 0}, 108 | // {-1, 2, -1, 0, 0, 0}, 109 | // { 0, -1, 2, -1, 0, 0}, 110 | // { 0, 0, -1, 2, -1, 0}, 111 | // { 0, 0, 0, -1, 2, -1}, 112 | // { 0, 0, 0, 0, -1, 2} 113 | // }; 114 | // // ls.A[5] = 115 | // // //vel.A[5][4] = -0.5; 116 | 117 | // ls.A.info(); 118 | // ls.b.info(); 119 | 120 | // x = {1, -2, 3, -4, 9, 3}; 121 | // cout << ls.A << endl; 122 | // cout << ls.b << endl; 123 | // cout << x<. * 17 | *************************************************************************** 18 | */ 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | 29 | 30 | int main() { 31 | auto dt = 0.5; auto writeTime = 0.02; 32 | auto t = clock(); 33 | Block2* grid = new Block2({0, 0, 0}, {1, 1, 0}, 10, 10); 34 | //Block2* grid = new Block2({0, 0, 0}, {0.02, 0.02, 0}, 10, 1); 35 | double time= 0; double endTime = 8; //dt*50; 36 | 37 | grid->addVar({"T"}); 38 | 39 | auto T = grid->getVar("T"); 40 | T->setBC("west", "val", 0); 41 | T->setBC("south", "val", 0); 42 | T->setBC("east", "val", 0); 43 | T->setBC("north", "val", 0); 44 | 45 | auto u = grid->getVar("u"); 46 | auto v = grid->getVar("v"); 47 | 48 | int filecnt = 0; int it = 0, writeInt = 1; 49 | ofstream myfile; 50 | std::string flname; 51 | 52 | flname="heat"+std::to_string(filecnt++)+".vtk"; 53 | myfile.open(flname); 54 | myfile << grid << endl; 55 | myfile.close(); 56 | 57 | double pi = 4.0*atan(1); 58 | for (auto k = 0; k < 60; ++k) { 59 | for (auto j0 = 0; j0 < 6; ++j0) { 60 | for (auto i = 0; i < grid->listCell.size(); ++i) { 61 | auto xc = 0.5 + 0.25*cos(pi/2 - k*pi/60); 62 | auto yc = 0.5 + 0.25*sin(pi/2 - k*pi/60); 63 | auto r = (grid->listCell[i]->getCoord() - Vec3(xc, yc)).abs(); 64 | T->set(i, 1.0/(1.0 + exp(-2.0*80*(0.15-r)))); 65 | } 66 | auto err = grid->getError(T); 67 | u->set(err.comp(0)); 68 | v->set(err.comp(1)); 69 | 70 | flname="heat"+std::to_string(filecnt++)+".vtk"; 71 | myfile.open(flname); 72 | myfile << grid << endl; 73 | myfile.close(); 74 | 75 | // auto gt = grid->valGrad(T); 76 | grid->solBasedAdapt2(err); 77 | 78 | flname="heat"+std::to_string(filecnt++)+".vtk"; 79 | myfile.open(flname); 80 | myfile << grid << endl; 81 | myfile.close(); 82 | 83 | grid->adapt(); 84 | 85 | // // write file 86 | flname="heat"+std::to_string(filecnt++)+".vtk"; 87 | myfile.open(flname); 88 | myfile << grid << endl; 89 | myfile.close(); 90 | } 91 | 92 | // for (auto j0 = 0; j0 < 5; ++j0) { 93 | // for (auto i = 0; i < grid->listCell.size(); ++i) { 94 | // auto r = (grid->listCell[i]->getCoord() - Vec3(0.75, 0.5)).abs(); 95 | // T->set(i, 1.0/(1.0 + exp(-2.0*80*(0.15-r)))); 96 | // } 97 | // auto err = grid->getError(T); 98 | // u->set(err.comp(0)); 99 | // v->set(err.comp(1)); 100 | 101 | // flname="heat"+std::to_string(filecnt++)+".vtk"; 102 | // myfile.open(flname); 103 | // myfile << grid << endl; 104 | // myfile.close(); 105 | 106 | // // auto gt = grid->valGrad(T); 107 | // grid->solBasedAdapt2(err); 108 | 109 | // // // write file 110 | // flname="heat"+std::to_string(filecnt++)+".vtk"; 111 | // myfile.open(flname); 112 | // myfile << grid << endl; 113 | // myfile.close(); 114 | 115 | // grid->adapt(); 116 | 117 | // flname="heat"+std::to_string(filecnt++)+".vtk"; 118 | // myfile.open(flname); 119 | // myfile << grid << endl; 120 | // myfile.close(); 121 | 122 | 123 | // } 124 | } 125 | 126 | delete(grid); 127 | 128 | return 0; 129 | } 130 | -------------------------------------------------------------------------------- /example/unclassified/main3.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | *************************************************************************** 3 | * Copyright (C) 2015, Eray Uzgoren * 4 | * * 5 | * This program is free software: you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License as published by * 7 | * the Free Software Foundation, either version 3 of the License, or * 8 | * (at your option) any later version. * 9 | * * 10 | * This program is distributed in the hope that it will be useful, * 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 | * GNU General Public License for more details. * 14 | * * 15 | * You should have received a copy of the GNU General Public License * 16 | * along with this program. If not, see . * 17 | *************************************************************************** 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | int main() { 30 | auto t = clock(); 31 | //Block2* grid = new Block2({0, 0, 0}, {0.5, 0.3, 0}, 50, 30); 32 | Block2* grid = new Block2({0, 0, 0}, {1, 1, 0}, 50, 50); 33 | 34 | grid->adaptCriteria(); 35 | 36 | grid->addVar({"dx", "dy"}); 37 | auto dx = grid->getVar("dx"); 38 | auto dy = grid->getVar("dy"); 39 | 40 | for (auto v: grid->listVertex) { 41 | for (auto i =0; i< 2; ++i) { 42 | if (v->face[i]) { 43 | auto x = v->face[i]->getCoord().x(); 44 | auto y = v->face[i]->getCoord().y(); 45 | auto theta = atan2(y-0.5, x-0.5); 46 | auto r = sqrt(2.0); 47 | if (v->face[i]->prev < 0) { 48 | dx->listBC.push_back(shared_ptr(new Boundary())); 49 | (*(dx->listBC.rbegin()))->setBC(0, (r*cos(theta)+0.5)); 50 | v->face[i]->prev = -(dx->listBC.size()); 51 | 52 | dy->listBC.push_back(shared_ptr(new Boundary())); 53 | (*(dy->listBC.rbegin()))->setBC(0, (r*sin(theta)+0.5)); 54 | v->face[i]->prev = -(dy->listBC.size()); 55 | 56 | } else if (v->face[i]->next < 0) { 57 | dx->listBC.push_back(shared_ptr(new Boundary())); 58 | (*(dx->listBC.rbegin()))->setBC(0, (r*cos(theta)+0.5)); 59 | v->face[i]->next = -(dx->listBC.size()); 60 | 61 | dy->listBC.push_back(shared_ptr(new Boundary())); 62 | (*(dy->listBC.rbegin()))->setBC(0, (r*sin(theta)+0.5)); 63 | v->face[i]->next = -(dy->listBC.size()); 64 | } 65 | } 66 | } 67 | } 68 | 69 | dx->set(0.0); 70 | // dx->setBC("north", "val", 0); 71 | // dx->setBC("south", "val", 0); 72 | dy->set(0.0); 73 | // dy->setBC("east", "val", 0); 74 | // dy->setBC("west", "val", 0); 75 | dx->solver = "CG"; 76 | dy->solver = "CG"; 77 | dx->itmax = 1000; 78 | dx->tol = 1e-6; 79 | dy->itmax = 1000; 80 | dy->tol = 1e-6; 81 | 82 | 83 | grid->lockBC(dx); 84 | dx->solve( 85 | grid->laplace(1) 86 | // - grid->source(0, 10000) 87 | ); 88 | grid->unlockBC(); 89 | 90 | grid->lockBC(dy); 91 | dy->solve( 92 | grid->laplace(1) 93 | // - grid->source(0, 10000) 94 | ); 95 | grid->unlockBC(); 96 | 97 | for (auto v: grid->listVertex) { 98 | double sumx = 0, sumy = 0; double icnt = 0; double jcnt = 0; 99 | for (auto c : v->cell) { 100 | if (c >=0 ) { 101 | sumx += dx->data[c]; ++icnt; 102 | sumy += dy->data[c]; ++jcnt; 103 | } 104 | } 105 | v->data[0] = sumx/icnt; 106 | v->data[1] = sumy/icnt; 107 | } 108 | //grid->listVar.clear(); 109 | 110 | grid->makeFace(); 111 | grid->addVar({"T"}); 112 | auto T = grid->getVar("T"); 113 | T->solver = "CG"; 114 | T->itmax =1000; 115 | T->tol = 1e-6; 116 | 117 | T->setBC("east", "val", 100); 118 | T->setBC("west", "val", 160); 119 | T->setBC("north", "grad", 250*20, -250); 120 | 121 | grid->lockBC(T); 122 | T->solve(grid->laplace(2.0) + grid->source(0,1000)); 123 | grid->unlockBC(); 124 | 125 | // grid->lockBC(dx); 126 | // dx->solve( 127 | // grid->laplace(1) 128 | // // - grid->source(0, 10000) 129 | // ); 130 | // grid->unlockBC(); 131 | 132 | ofstream myfile; 133 | myfile.open("reg.vtk"); 134 | myfile << grid << endl; 135 | myfile.close(); 136 | 137 | 138 | delete(grid); 139 | 140 | return 0; 141 | } 142 | -------------------------------------------------------------------------------- /src/grid/Grid.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | *************************************************************************** 3 | * Copyright (C) 2015, Eray Uzgoren * 4 | * * 5 | * This program is free software: you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License as published by * 7 | * the Free Software Foundation, either version 3 of the License, or * 8 | * (at your option) any later version. * 9 | * * 10 | * This program is distributed in the hope that it will be useful, * 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 | * GNU General Public License for more details. * 14 | * * 15 | * You should have received a copy of the GNU General Public License * 16 | * along with this program. If not, see . * 17 | *************************************************************************** 18 | */ 19 | #include 20 | 21 | // --- SECTION 1 -- Constructors; 22 | // Base constructor for setting defaults; 23 | Grid::Grid() { 24 | nCellSize = 0; 25 | for (auto i = 0; i<3; ++i) { 26 | levelLowBound[i] = 0; levelHighBound[i] = 4; cfl = 0.5; 27 | } 28 | filecnt=0; 29 | } 30 | 31 | // For large grids; better to start with reserved memory; 32 | // Note it can go beyond cap; 33 | Grid::Grid(int_8 cap):Grid::Grid() { 34 | listCell.reserve(cap); 35 | listVertex.reserve(cap); 36 | } 37 | 38 | // Start with a single vertex ??? 39 | Grid::Grid(initializer_list pts):Grid::Grid() { 40 | addVertex(pts); 41 | } 42 | // Vec3 form 43 | Grid::Grid(Vec3 pts): Grid::Grid() { 44 | addVertex(pts); 45 | } 46 | 47 | // Start with many vertices; size adjusted; 48 | Grid::Grid(initializer_list > pts):Grid::Grid() { 49 | listCell.reserve(2*pts.size()); 50 | listVertex.reserve(2*pts.size()); 51 | addVertex(pts); 52 | } 53 | 54 | // Start with vertices; and cells 55 | Grid::Grid(initializer_list > pts, 56 | initializer_list > cell): Grid::Grid(pts) { 57 | addCell(cell); 58 | setCurrentLevels(); 59 | makeFace(); 60 | //setQuadBoundary(); 61 | cout << "Block2: Cells: " << listCell.size(); 62 | cout << " Faces: " << nFace << endl; 63 | addVec("u"); 64 | } 65 | // -- End section constructors; 66 | 67 | 68 | // Section 2 - Deconstructors 69 | Grid::~Grid() { 70 | listFace.clear(); 71 | listCell.clear(); 72 | listVertex.clear(); 73 | otherVertex.clear(); 74 | } 75 | // End section 2 - Deconstructors 76 | 77 | // Section 3 - Copy 78 | // Grid::Grid(const Grid& copy) { 79 | // filecnt = copy.filecnt; 80 | 81 | // } 82 | 83 | 84 | 85 | void Grid::addVar(std::string n, int t) { 86 | if (!getVar(n)) { 87 | listVar.emplace_back(shared_ptr(new Var(n, t))); 88 | if (t == 1) { 89 | (*listVar.rbegin())->data.resize(listVertex.size()); 90 | } else if (t == 2) { 91 | (*listVar.rbegin())->data.resize(listFace.size()); 92 | } else { 93 | (*listVar.rbegin())->data.resize(listCell.size()); 94 | } 95 | (*listVar.rbegin())->grid = this; 96 | (*listVar.rbegin())->solver = "BiCGSTAB"; 97 | (*listVar.rbegin())->initBC(); 98 | } else 99 | cout << "Skipping " << n << " as it exists"<< endl; 100 | } 101 | 102 | void Grid::addVar(initializer_list nl, int t) { 103 | for (auto n: nl) addVar(n, t); 104 | } 105 | 106 | void Grid::addVec(std::string n, int t) { 107 | if (n == "u") { 108 | addVar({"u", "v", "w"}, t); 109 | getVar("u")->isVec = true; 110 | getVar("v")->isVec = true; 111 | getVar("w")->isVec = true; 112 | } else { 113 | addVar(n+"x", t); getVar(n+"x")->isVec = true; 114 | addVar(n+"y", t); getVar(n+"y")->isVec = true; 115 | addVar(n+"z", t); getVar(n+"z")->isVec = true; 116 | } 117 | } 118 | 119 | void Grid::addVec(initializer_list nl, int t) { 120 | for (auto n: nl) addVec(n, t); 121 | } 122 | 123 | shared_ptr Grid::getVar(std::string n) { 124 | auto matching_iter = std::find_if(listVar.begin(), listVar.end(), 125 | [&n](const shared_ptr p) { 126 | return n == p->name; 127 | }); 128 | return (matching_iter!=listVar.end()) ? *matching_iter : NULL; 129 | } 130 | 131 | void Grid::lockBC(shared_ptr v) { 132 | thisVar = v; 133 | v->grad = valGrad(v); 134 | // v->grad.assign(listCell.size(), 0) 135 | // v->grad.clear(); 136 | // v->grad.resize(listCell.size()); 137 | // for (auto i = 0; i < listCell.size(); ++i) { 138 | // v->grad[i] = listCell[i]->grad(v); //v->grad = valGrad(v); 139 | // } 140 | } 141 | void Grid::unlockBC() { 142 | thisVar.reset(); 143 | } 144 | -------------------------------------------------------------------------------- /example/unclassified/main_heatt.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | *************************************************************************** 3 | * Copyright (C) 2015, Eray Uzgoren * 4 | * * 5 | * This program is free software: you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License as published by * 7 | * the Free Software Foundation, either version 3 of the License, or * 8 | * (at your option) any later version. * 9 | * * 10 | * This program is distributed in the hope that it will be useful, * 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 | * GNU General Public License for more details. * 14 | * * 15 | * You should have received a copy of the GNU General Public License * 16 | * along with this program. If not, see . * 17 | *************************************************************************** 18 | */ 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | 29 | 30 | int main() { 31 | auto dt = 0.01; 32 | auto t = clock(); 33 | Block2* grid = new Block2({0, 0, 0}, {1, 1, 0}, 20, 20); 34 | 35 | //Block2* grid = new Block2({0, 0, 0}, {0.02, 0.02, 0}, 10, 1); 36 | grid->setDt(dt); 37 | double time= 0; double endTime = 4; //dt*50; 38 | 39 | // Field variables; 40 | double rho=10000, cp=1000, k=1; 41 | 42 | grid->addVar({"T", "p"}); 43 | 44 | auto T = grid->getVar("T"); 45 | auto u = grid->getVar("u"); 46 | auto v = grid->getVar("v"); 47 | auto p = grid->getVar("p"); 48 | 49 | // for (auto j = 0; j < 3; ++j) { 50 | // for (auto i = 0; i < grid->listCell.size(); ++i) { 51 | // auto x=grid->listCell[i]->getCoord(); 52 | // p->set(i, 20 + 80*cosh(5*(1-x[0]))/cosh(5)); //(100/0.02+1e6*(0.02 - x[0]))*x[0] + 100); 53 | // } 54 | // auto gt = grid->valGrad(p); 55 | // grid->solBasedAdapt(gt); 56 | // grid->refine2(); 57 | // } 58 | 59 | T->set(150); 60 | 61 | T->setBC("west", "grad", 100); 62 | T->setBC("east", "val", 200); 63 | T->setBC("south", "grad", 0); 64 | T->setBC("north", "grad", 0); 65 | T->itmax = 10000; 66 | T->tol = 1e-6; 67 | // T->solver = "CG"; 68 | 69 | // u->set(0.01); 70 | // v->set(0.03); 71 | 72 | int filecnt = 0; int it = 0, writeInt = 10; 73 | ofstream myfile; 74 | while (time < endTime) { 75 | cout << setiosflags(ios::fixed) << setprecision(2); 76 | cout << "------------- Processing TIME = "<< time << " ------------------"<getError(T); 79 | 80 | auto Tmin = T->data.min(); 81 | auto Tmax = T->data.max(); 82 | 83 | 84 | grid->solBasedAdapt2(gt, 0.005, 0.1); 85 | grid->adapt(); 86 | 87 | 88 | // auto vel = grid->getVel(); 89 | 90 | grid->lockBC(T); 91 | T->solve( 92 | //grid->ddt(1.0) 93 | //+ grid->div(vel, 1.0) 94 | //- grid->laplace(k/cp/rho) 95 | //- grid->source(0, 100000/cp/rho) 96 | - grid->laplace(1.0) 97 | - grid->source(-25, 500) //-25, 25*20) 98 | ); 99 | grid->unlockBC(); 100 | 101 | time += endTime/5; //grid->dt; 102 | //grid->setDt(dt); 103 | 104 | grid->writeVTK("heat"); 105 | 106 | // if (( it % writeInt) == 0) { 107 | // std::string flname="heat"+std::to_string(filecnt++)+".vtk"; 108 | // myfile.open(flname); 109 | // myfile << grid << endl; 110 | // myfile.close(); 111 | // // } 112 | 113 | cout << "---------------------------------------------------"<writeFace(); 122 | 123 | //grid->writeFace(); 124 | 125 | delete(grid); 126 | 127 | 128 | // LinSys ls(6); 129 | // VecX x(6); x.uncompress(); 130 | // ls.A = { 131 | // { 2, -1, 0, 0, 0, 0}, 132 | // {-1, 2, -1, 0, 0, 0}, 133 | // { 0, -1, 2, -1, 0, 0}, 134 | // { 0, 0, -1, 2, -1, 0}, 135 | // { 0, 0, 0, -1, 2, -1}, 136 | // { 0, 0, 0, 0, -1, 2} 137 | // }; 138 | // // ls.A[5] = 139 | // // //vel.A[5][4] = -0.5; 140 | 141 | // ls.A.info(); 142 | // ls.b.info(); 143 | 144 | // x = {1, -2, 3, -4, 9, 3}; 145 | // cout << ls.A << endl; 146 | // cout << ls.b << endl; 147 | // cout << x<. * 17 | *************************************************************************** 18 | */ 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | 28 | int main() { 29 | auto dt = 0.01; auto writeTime = dt; 30 | auto t = clock(); 31 | Block2* grid = new Block2({0, 0, 0}, {1, 1, 0}, 20, 20); 32 | //Block2* grid = new Block2({0, 0, 0}, {0.02, 0.02, 0}, 10, 1); 33 | double time= 0; double endTime = 4; //dt*50; 34 | 35 | // Field variables; 36 | double rho=10000, cp=1000, k=1; 37 | 38 | grid->addVar({"T", "p"}); 39 | 40 | auto T = grid->getVar("T"); 41 | auto u = grid->getVar("u"); 42 | auto v = grid->getVar("v"); 43 | 44 | //T->solver = "Gauss"; 45 | 46 | T->set(0); 47 | 48 | for (auto j = 0; j < 2; ++j) { 49 | double pi = 4.0*atan(1); 50 | for (auto i = 0; i < grid->listCell.size(); ++i) { 51 | auto x = grid->listCell[i]->getCoord(); 52 | if (x[0] > 0.12 && x[0] < 0.32 && x[1] > 0.12 && x[1]< 0.32 ) { 53 | T->set(i, sin(pi*(x[0]-0.12)/0.2)*sin(pi*(x[1]-0.12)/0.2)); 54 | } 55 | } 56 | auto gt = grid->valGrad(T); 57 | grid->solBasedAdapt(gt); 58 | grid->refine2(); 59 | } 60 | 61 | int filecnt = 0; int it = 0, writeInt = 1; 62 | ofstream myfile; 63 | std::string flname="heat"+std::to_string(filecnt++)+".vtk"; 64 | myfile.open(flname); 65 | myfile << grid << endl; 66 | myfile.close(); 67 | 68 | T->setBC("west", "val", 0); 69 | T->setBC("south", "val", 0); 70 | T->setBC("east", "val", 0); 71 | T->setBC("north", "val", 0); 72 | // T->setBC("south", "grad", -20, 100); 73 | // T->setBC("north", "grad", -20, 100); 74 | T->itmax = 1000; 75 | T->tol = 1e-6; 76 | 77 | u->set(1); 78 | v->set(1); 79 | grid->setDt(dt); 80 | 81 | auto writeCnt = writeTime; 82 | while (time < endTime) { 83 | cout << setiosflags(ios::fixed) << setprecision(6); 84 | cout << "------------- Processing TIME = "<< time << " ------------------"<getVel(); 87 | 88 | grid->lockBC(T); 89 | T->solve (grid->ddt(1.0) 90 | +grid->divRK2E(vel, 1.0) 91 | //- grid->laplace(k/cp/rho) 92 | //- grid->source(0, 100000/cp/rho) 93 | //- grid->laplace(1.0) 94 | //- grid->source(-25, 25*20) 95 | ); 96 | grid->unlockBC(); 97 | 98 | auto gt = grid->valGrad(T); 99 | grid->solBasedAdapt(gt); 100 | grid->refine2(); 101 | 102 | time += grid->dt; 103 | writeCnt -= grid->dt; 104 | grid->setDt(dt); 105 | 106 | if (writeCnt <= 0) { 107 | std::string flname="heat"+std::to_string(filecnt++)+".vtk"; 108 | myfile.open(flname); 109 | myfile << grid << endl; 110 | myfile.close(); 111 | writeCnt = writeTime; 112 | } 113 | 114 | cout << "---------------------------------------------------"<writeFace(); 123 | 124 | //grid->writeFace(); 125 | 126 | delete(grid); 127 | 128 | 129 | // LinSys ls(6); 130 | // VecX x(6); x.uncompress(); 131 | // ls.A = { 132 | // { 2, -1, 0, 0, 0, 0}, 133 | // {-1, 2, -1, 0, 0, 0}, 134 | // { 0, -1, 2, -1, 0, 0}, 135 | // { 0, 0, -1, 2, -1, 0}, 136 | // { 0, 0, 0, -1, 2, -1}, 137 | // { 0, 0, 0, 0, -1, 2} 138 | // }; 139 | // // ls.A[5] = 140 | // // //vel.A[5][4] = -0.5; 141 | 142 | // ls.A.info(); 143 | // ls.b.info(); 144 | 145 | // x = {1, -2, 3, -4, 9, 3}; 146 | // cout << ls.A << endl; 147 | // cout << ls.b << endl; 148 | // cout << x<. * 17 | *************************************************************************** 18 | */ 19 | #ifndef VERTEX 20 | #define VERTEX 21 | 22 | #include "Scheme.hpp" 23 | 24 | // Classes to be define later, but needed 25 | class Grid; 26 | class Cell; 27 | 28 | // Vertex 29 | class Vertex : public Vec3 { 30 | protected: 31 | 32 | public: 33 | vector cell; 34 | // Cell contains structured array 35 | // many constains node shared by many cells; unstructured 36 | vector many; 37 | // --- NOT IMPLEMENTED -- // 38 | // When both cell and many has elements it is a mixed node; 39 | // Mixed nodes should be dealt specifically 40 | // --- NOT IMPLEMENTED -- // 41 | 42 | // Coefficients of a bilinear equation - used for mapping from x to xhat 43 | // i.e. for quad: 44 | // x = xcoef(0) + xcoef(1)*xhat0 + xcoef(2)*xhat1 + xcoef(3)*xhat0*xhat1 45 | bool coefUpdate; 46 | VecX xcoef, ycoef, zcoef; 47 | 48 | // Weights are computed using trasformed coordinate xhat; 49 | Vec3 xhat; 50 | // i.e. for quad: 51 | // p_v = (1-xhat1)*(1-xhat0)*p_0 + xhat0*(1-xhat1)*p_1+.. 52 | // xhat0*xhat1*p_2 + (1-xhat0)*xhat1*p_3; 53 | 54 | // For gradients we need to fit p into a different bilinear equation; 55 | // but we only need weigths, which are computed from xhat again; 56 | // OR we can simply calculate using gauss formula! Not sure yet; 57 | 58 | int_2 isBndr; 59 | 60 | int_8 id; 61 | Grid* grid; 62 | 63 | Vertex():Vec3() { coefUpdate = true;} 64 | Vertex(double const & a, double const & b, double const & c) : Vec3 (a, b, c) {coefUpdate = true;} 65 | Vertex(initializer_list a) : Vec3( a ) {coefUpdate = true; } 66 | Vertex(Vec3 a) : Vec3(a) {coefUpdate = true;} 67 | 68 | // ~Vertex() { cout<< "Delete vertex"< l) {cell.assign(l.begin(), l.end()); coefUpdate = true;} 79 | 80 | // 02 Change number of cells (structure of a node) 81 | void cellResize(int_2 size); 82 | // 03a assigns cell at a prescribed loc; Quad 0-1-2-3 (CCW) Hexa 0-1..7-8 (CCW-CCW) 83 | // given that it doesn't have a meaningful value (<0) 84 | void setCell(int_2 ind, int_8 value); 85 | // 03b replaces whole structure based on list given; 86 | void setCell(initializer_list l) { 87 | cellResize(l.size()); 88 | for (auto i = 0; i < l.size(); ++i) 89 | {if (cell[i] < 0) cell[i] = *(l.begin()+i); } 90 | } 91 | 92 | // 03c replace ind with another cell -- Not a duplicate of setcell 93 | // (it overrides existing cell) 94 | void replaceCell(int_2 ind, int_8 value); 95 | 96 | // 04 gets a pointer to the cell object at ind 97 | shared_ptr *getCell(int_2 ind, bool debug=0); 98 | 99 | // 05 gets a pointer to an immediate neighboring vertex (IMPORTANT); 100 | // d stands for direction; and 1 represents x1, 2 for x2 and 3 for x3; 101 | // negative values of 1, 2, 3 reverses the direction. 102 | // NOTE: ngbr should not be used during grid generation/adaptation 103 | // it is only made available after faces are created! 104 | shared_ptr *ngbr(int_2 d); 105 | shared_ptr getFace(int_2 order); 106 | 107 | bool isHanging() { 108 | if (cell.size() == 4) { 109 | for (auto i = 0; i < cell.size(); ++i) { 110 | if (cell[i] == cell[(i+1)%4]) return true; 111 | } 112 | } 113 | return false; 114 | } 115 | 116 | // 06 interpolation scheme of a Field variable 117 | Scheme phi(vector > const &bc, int_2 bias=0); 118 | Scheme phi(shared_ptr var, int_2 bias=0); 119 | 120 | double evalPhi(shared_ptr &var, Vec3 *x=NULL); 121 | double evalPhi(VecX &phi, vector > const &bc, Vec3* x=NULL); 122 | 123 | bool setInterpCoef(); 124 | //vector getIntWeight(); 125 | vector getIntWeight(Vec3* x = NULL); 126 | 127 | bool isIn(Vec3 x); 128 | Vec3 getXhat(Vec3 x); 129 | 130 | 131 | // Scheme pi(shared_ptr &var, Vec3 *x=NULL, int method=0); 132 | // Scheme pi(VecX &phi, vector > const &bc, ... 133 | // Vec3* x=NULL, int method=0); 134 | 135 | // double getIntVal(shared_ptr var); 136 | // double getIntVal(shared_ptr var, Vec3 x); 137 | 138 | 139 | 140 | }; 141 | 142 | #endif 143 | -------------------------------------------------------------------------------- /src/field/Var.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | *************************************************************************** 3 | * Copyright (C) 2015, Eray Uzgoren * 4 | * * 5 | * This program is free software: you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License as published by * 7 | * the Free Software Foundation, either version 3 of the License, or * 8 | * (at your option) any later version. * 9 | * * 10 | * This program is distributed in the hope that it will be useful, * 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 | * GNU General Public License for more details. * 14 | * * 15 | * You should have received a copy of the GNU General Public License * 16 | * along with this program. If not, see . * 17 | *************************************************************************** 18 | */ 19 | #include 20 | #include 21 | #include 22 | //#include 23 | 24 | #include 25 | 26 | double Var::get(int_8 i) { 27 | if (i >= 0 && i < data.size()) return data[i]; 28 | else { 29 | cout << "Var: "<listCell.size() << endl; 32 | else if (loc == 1) cout << grid->listVertex.size() << endl; 33 | else cout << " unknown "<< endl ; 34 | exit(1); 35 | } 36 | } 37 | 38 | double* Var::operator[](int_8 const &index) { 39 | if (index>=0 && indexlistCell.size() << endl; 44 | else if (loc == 1) cout << grid->listVertex.size() << endl; 45 | else cout << " unknown "<< endl ; 46 | exit(1); 47 | } 48 | } 49 | 50 | void Var::solve(LinSys a) { 51 | 52 | // cout << "Size: " << a.b.size() << endl; //listBC.size() <listBNDR.size() << endl; 53 | // Set BC; 54 | a.x = &data; 55 | a.error = &error; 56 | 57 | auto t = clock(); 58 | // double d; 59 | // for (auto row = 0; row < a.b.size(); ++row) { 60 | // d = 1.0/a.A[row][row]; 61 | // a.A[row] = a.A[row]*d; 62 | // a.b[row] = a.b[row]*d; 63 | // } 64 | //t = clock()-t; 65 | // cout << " --> Normalization took "<< t/(double) CLOCKS_PER_SEC << " secs"<< endl; 66 | //cout << a.A << endl; 67 | //cout << a.b << endl; 68 | a.setLimits(tol/dt, itmax); 69 | t = clock(); 70 | if (solver.compare("BiCGSTAB") == 0) { 71 | a.BiCGSTAB(); 72 | } else if (solver.compare("CG") == 0) { 73 | a.CG(); 74 | } else { 75 | a.Gauss_Seidel(); 76 | } 77 | t = clock() - t; 78 | cout << " + " << name << " " << setw(10)<< data.min() << setw(1); 79 | cout << ":" << setw(10) << data.max() ; 80 | cout < vname, std::string exp) { 86 | // typedef exprtk::symbol_table< double > symbol_table_t; 87 | // typedef exprtk::expression< double > expression_t; 88 | // typedef exprtk::parser< double > parser_t; 89 | // typedef exprtk::parser_error::type error_t; 90 | 91 | // int nVar = vname.size(); // size of the variables 92 | // vector< VecX > phi(nVar); 93 | // vector< double > expval(nVar); 94 | 95 | // symbol_table_t symbol_table; 96 | // symbol_table.add_constants(); 97 | 98 | // VecX d; 99 | 100 | // int i = 0; 101 | // for (auto v : vname) { 102 | // if (v.compare("x")) { 103 | // d = grid->getCoord(0); 104 | // } else if (v.compare("y")) { 105 | // d = grid->getCoord(1); 106 | // } else if (v.compare("z")) { 107 | // d = grid->getCoord(2); 108 | // } else if (auto vr = grid->getVar(v)) { 109 | // d = vr->get(); 110 | // } else { 111 | // cout << "Var::set. Variable name not recognized!"<(j), 133 | // static_cast(error.token.position), 134 | // exprtk::parser_error::to_str(error.mode).c_str(), 135 | // error.diagnostic.c_str(), 136 | // exp.c_str()); 137 | // } 138 | // exit(1); 139 | // } 140 | 141 | // for (auto i = 0; i < data.size(); ++i) { 142 | // for (auto j = 0; j < nVar; ++j) { 143 | // expval[j] = phi[j].data.at(i); 144 | // } 145 | // data[i] = expression.value(); 146 | // } 147 | 148 | // //data.data.assign(phi[i].begin(), phi[i].end()); 149 | 150 | // } 151 | -------------------------------------------------------------------------------- /include/linSolve/LinSys.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | *************************************************************************** 3 | * Copyright (C) 2015, Eray Uzgoren * 4 | * * 5 | * This program is free software: you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License as published by * 7 | * the Free Software Foundation, either version 3 of the License, or * 8 | * (at your option) any later version. * 9 | * * 10 | * This program is distributed in the hope that it will be useful, * 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 | * GNU General Public License for more details. * 14 | * * 15 | * You should have received a copy of the GNU General Public License * 16 | * along with this program. If not, see . * 17 | *************************************************************************** 18 | */ 19 | #ifndef LINSYS 20 | #define LINSYS 21 | 22 | #include "MatX.hpp" 23 | 24 | class LinSys { 25 | private: 26 | int_8 N; 27 | double tol; 28 | int itmax; 29 | 30 | public: 31 | MatX A; 32 | VecX b; 33 | VecX *x; 34 | VecX *error; 35 | 36 | double err; 37 | int it; 38 | 39 | //------------------------- 40 | // Constructor 41 | //------------------------- 42 | LinSys() { setLimits(); } 43 | 44 | LinSys(int_8 const &a) { 45 | setLimits(); 46 | N = a; 47 | resize(a); 48 | } 49 | 50 | 51 | //------------------------- 52 | // Methods 53 | //------------------------- 54 | void resize(int_8 const &a) { 55 | N = a; 56 | A.resize(a); 57 | b.resize(a); 58 | } 59 | void clear() { 60 | A.empty(); 61 | b.empty(); 62 | } 63 | void setLimits(double t=1e-6, unsigned int imax = 1000) { 64 | if (t>0) tol = t; 65 | if (imax>0) itmax = imax; 66 | } 67 | 68 | void setMATX(MatXconst &MAT){ 69 | A=MAT; 70 | } 71 | 72 | void setVECX(VecXconst &VEC){ 73 | b=VEC; 74 | } 75 | 76 | 77 | //------------------------ 78 | // Operators 79 | //------------------------ 80 | VecX solve() { 81 | return b; 82 | } 83 | 84 | void CG() { 85 | int iter = 0; 86 | double alpha, rsold, rsnew; 87 | VecX p(A.data.size()), q(A.data.size()); 88 | 89 | err = 0; 90 | *error = (b - A*(*x)); 91 | cout << p.abs() << endl; 92 | rsold = *error*(*error); 93 | for (; iter < itmax; ++iter) { 94 | q = A*p; 95 | alpha = rsold/(q*p); 96 | *x += alpha*p; 97 | *error -= alpha*q; 98 | rsnew = (*error)*(*error); 99 | if (sqrt(rsnew) < tol) break; 100 | p = *error + rsnew/rsold*p; 101 | rsold = rsnew; 102 | //if (iter%50 == 0) 103 | // cout << "CG: " << iter << ": "<< log10(rsnew) << endl; 104 | } 105 | it = iter; 106 | err = sqrt(rsold); 107 | //cout << "CG: " << iter << ": " << log10(rsnew) << " DONE!" << endl; 108 | } 109 | 110 | 111 | void Gauss_Seidel() { 112 | int iter; 113 | double sigma; 114 | 115 | iter = 0; 116 | while (iter::rowiter rit=A.data.begin(); rit!=A.data.end(); ++rit, ++r) { 120 | sigma = 0; 121 | for (VecX::it_cmap cit=rit->px.begin(); cit!=rit->px.end(); ++cit) { 122 | if (cit->first == r) continue; 123 | sigma += cit->second * (*x)[cit->first]; 124 | } 125 | sigma = (b[r] - sigma)/rit->px[r]; 126 | err += ((sigma-(*x)[r])); //err *= err; 127 | (*x)[r] = sigma; 128 | } 129 | err = sqrt(err/A.rows); 130 | if (err < tol) break; 131 | // cout << "GS: " << iter << "->" << log10(err) < r(A.data.size()), r0(A.data.size()), p(A.data.size()); 142 | VecX t(A.data.size()), v(A.data.size()), s(A.data.size()); 143 | 144 | err = 0; 145 | //check if t is initialized as zero; 146 | //cout<< t << endl; 147 | 148 | *error = (b - A*(*x)); 149 | if (error->abs() < tol) { err = tol; it = 0; return; } 150 | r0 = *error; 151 | rho = 1; alpha = 1; omega = 1; 152 | for (; iter < itmax; ++iter) { 153 | rho_new = r0*(*error); 154 | beta = (rho_new/rho)*(alpha/omega); 155 | rho = rho_new; 156 | p = (*error) + beta*(p - omega*v); 157 | v = A*p; 158 | //cout << " r0v: " << r0*v << " p: " << p << endl; 159 | alpha = rho/(r0*v); 160 | s = *error - alpha*v; 161 | t = A*s; 162 | //cout << " t: " << t << " s: " << s << endl; 163 | omega = (t*s)/(t*t); 164 | (*x) = (*x) + alpha*p + omega*s; 165 | *error = s - omega*t; 166 | err = sqrt(*error*(*error)); 167 | if (err < tol) break; 168 | //if (iter%50 == 0) 169 | //cout << "BiCGstab: " << iter << ": "<< log10(err) << endl; 170 | } 171 | it = iter; 172 | //err = sqrt(rsnew); 173 | //cout << "BiCGstab: " << iter << ": " << log10(err) << " DONE!" << endl; 174 | } 175 | 176 | 177 | 178 | 179 | LinSys operator+(LinSys const &a) { 180 | LinSys c; 181 | c.A = A + a.A; 182 | c.b = b + a.b; 183 | return c; 184 | } 185 | 186 | LinSys operator-(const LinSys& a) { 187 | LinSys c; 188 | c.A = A - a.A; 189 | c.b = b - a.b; 190 | return c; 191 | } 192 | 193 | LinSys operator-() { 194 | A = -A; 195 | b = -b; 196 | return *this; 197 | } 198 | 199 | }; 200 | 201 | 202 | #endif 203 | -------------------------------------------------------------------------------- /example/unclassified/main_shear.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | *************************************************************************** 3 | * Copyright (C) 2015, Eray Uzgoren * 4 | * * 5 | * This program is free software: you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License as published by * 7 | * the Free Software Foundation, either version 3 of the License, or * 8 | * (at your option) any later version. * 9 | * * 10 | * This program is distributed in the hope that it will be useful, * 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 | * GNU General Public License for more details. * 14 | * * 15 | * You should have received a copy of the GNU General Public License * 16 | * along with this program. If not, see . * 17 | *************************************************************************** 18 | */ 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | 29 | 30 | int main() { 31 | auto dt = 0.5; auto writeTime = 0.01; 32 | auto t = clock(); 33 | Block2* grid = new Block2({0, 0, 0}, {1, 1, 0}, 20, 20); 34 | //Block2* grid = new Block2({0, 0, 0}, {0.02, 0.02, 0}, 10, 1); 35 | double time= 0; double endTime = 4; //dt*50; 36 | 37 | // Field variables; 38 | double rho=10000, cp=1000, k=1; 39 | 40 | grid->addVar({"T", "p"}); 41 | 42 | auto T = grid->getVar("T"); 43 | auto u = grid->getVar("u"); 44 | auto v = grid->getVar("v"); 45 | 46 | //T->solver = "Gauss"; 47 | 48 | v->set(0); 49 | T->set(0); 50 | double pi = 4.0*atan(1); 51 | 52 | for (auto j = 0; j < 5; ++j) { 53 | for (auto i = 0; i < grid->listCell.size(); ++i) { 54 | auto x = grid->listCell[i]->getCoord(); // - Vec3(0.5, 0.5); 55 | u->set(i, 2*x[1]-1.0); //-2*sin(pi*x[1])*cos(pi*x[1])*sin(pi*x[0])*sin(pi*x[0])); 56 | 57 | // auto r = (grid->listCell[i]->getCoord() - Vec3(0.5, 0.5)).abs(); 58 | 59 | //T->set(i, 1.0/(1.0 + exp(-2.0*80*(0.15-r)))); 60 | if (x[0] > 0.35 && x[0] < 0.65 && x[1] > 0.35 && x[1]< 0.65 ) { 61 | T->set(i, 1); 62 | } 63 | } 64 | auto gt = grid->valGrad(T); 65 | grid->solBasedAdapt(gt, 0.5); 66 | grid->refine2(); 67 | } 68 | 69 | int filecnt = 0; int it = 0, writeInt = 1; 70 | ofstream myfile; 71 | std::string flname="heat"+std::to_string(filecnt++)+".vtk"; 72 | myfile.open(flname); 73 | myfile << grid << endl; 74 | myfile.close(); 75 | 76 | cin.ignore().get(); 77 | 78 | T->setBC("west", "val", 0); 79 | T->setBC("south", "val", 0); 80 | T->setBC("east", "val", 0); 81 | T->setBC("north", "val", 0); 82 | // T->setBC("south", "grad", -20, 100); 83 | // T->setBC("north", "grad", -20, 100); 84 | T->itmax = 1000; 85 | T->tol = 1e-6; 86 | 87 | // u->set(1); 88 | // v->set(1); 89 | 90 | 91 | auto writeCnt = writeTime; 92 | while (time < endTime) { 93 | for (auto i = 0; i < grid->listCell.size(); ++i) { 94 | auto x = grid->listCell[i]->getCoord(); // - Vec3(0.5, 0.5); 95 | u->set(i, 2*x[1]-1.0); 96 | // u->set(i, -2*sin(pi*x[1])*cos(pi*x[1])*sin(pi*x[0])*sin(pi*x[0])*cos(pi*time/endTime)); 97 | // v->set(i, 2*sin(pi*x[0])*cos(pi*x[0])*sin(pi*x[1])*sin(pi*x[1])*cos(pi*time/endTime)); 98 | } 99 | grid->setDt(dt); 100 | 101 | 102 | cout << setiosflags(ios::fixed) << setprecision(6); 103 | cout << "------------- Processing TIME = "<< time << " ------------------"<getVel(); 106 | 107 | grid->lockBC(T); 108 | T->solve (grid->ddt(1.0) 109 | +grid->divRK2E(vel, 1.0) 110 | //- grid->laplace(k/cp/rho) 111 | //- grid->source(0, 100000/cp/rho) 112 | //- grid->laplace(1.0) 113 | //- grid->source(-25, 25*20) 114 | ); 115 | grid->unlockBC(); 116 | 117 | auto gt = grid->valGrad(T); 118 | grid->solBasedAdapt(gt, 0.5); 119 | grid->refine2(); 120 | 121 | 122 | time += grid->dt; 123 | writeCnt -= grid->dt; 124 | grid->setDt(dt); 125 | 126 | if (writeCnt <= 0) { 127 | std::string flname="heat"+std::to_string(filecnt++)+".vtk"; 128 | myfile.open(flname); 129 | myfile << grid << endl; 130 | myfile.close(); 131 | writeCnt = writeTime; 132 | } 133 | 134 | cout << "---------------------------------------------------"<writeFace(); 143 | 144 | //grid->writeFace(); 145 | 146 | delete(grid); 147 | 148 | 149 | // LinSys ls(6); 150 | // VecX x(6); x.uncompress(); 151 | // ls.A = { 152 | // { 2, -1, 0, 0, 0, 0}, 153 | // {-1, 2, -1, 0, 0, 0}, 154 | // { 0, -1, 2, -1, 0, 0}, 155 | // { 0, 0, -1, 2, -1, 0}, 156 | // { 0, 0, 0, -1, 2, -1}, 157 | // { 0, 0, 0, 0, -1, 2} 158 | // }; 159 | // // ls.A[5] = 160 | // // //vel.A[5][4] = -0.5; 161 | 162 | // ls.A.info(); 163 | // ls.b.info(); 164 | 165 | // x = {1, -2, 3, -4, 9, 3}; 166 | // cout << ls.A << endl; 167 | // cout << ls.b << endl; 168 | // cout << x<. * 17 | *************************************************************************** 18 | */ 19 | #ifndef CELL 20 | #define CELL 21 | 22 | #include "Vertex.hpp" 23 | 24 | class Var; 25 | //class Grid; 26 | //class Vertex; 27 | 28 | class Cell { 29 | protected: 30 | short int type; 31 | public: 32 | int_8 id; 33 | Grid* grid; 34 | bool isAlive; 35 | vector node; 36 | vector face; 37 | int_2 orient; // x-0; y-1; z-2; no particular dir-3; 38 | int_8 next; 39 | int_8 prev; 40 | vector level; 41 | vector adapt; 42 | vector masterx, mastery, masterz; 43 | bool cmx, cmy, cmz; 44 | 45 | Cell(initializer_list l, initializer_list a={0,0,0}) { 46 | node.assign(l.begin(), l.end()); 47 | level.assign(a.begin(), a.end()); 48 | adapt.assign(3, 0); 49 | next = -1; prev = -1; 50 | isAlive = true; 51 | } 52 | 53 | short int getType() { return type;} 54 | void setType(short int a) { type = a;} 55 | 56 | shared_ptr *getVertex(int_2 i); 57 | void setVertex(int_2 i, int_8 v) { node[i] = v; } 58 | 59 | void reset() {node.clear();} 60 | void reset(initializer_list l) {node.assign(l.begin(), l.end()); assignCelltoNode();} 61 | 62 | void virtual assignCelltoNode() {} 63 | bool virtual refine() {return false;} 64 | void virtual refine(int dir) {return;} 65 | bool virtual coarsen(int dir) {return false;} 66 | void virtual convertToSimpleBlock(initializer_list n, bool debug=false) {}; 67 | int_8 virtual hangingVertexOnFace(int_2 i, int_2 j=0) { return -1;} 68 | 69 | // Vec3 virtual grad(shared_ptr phi) {return Vec3(); } 70 | void virtual getBCPhi(shared_ptr phi, double &a, double &b) {}; 71 | //Scheme virtual phi(int_2 bias = 0) {}; 72 | 73 | double phiVal_iface(VecX &phi, int_2 const &bias); 74 | double phiVal_bcface(VecX &phi, vector > const &bc, int_2 const &bias); 75 | double phiVal(VecX &phi, vector > const &bc, int_2 bias=0); 76 | double phiVal(VecX &phi, int_2 bias=0); 77 | double phiVal(shared_ptr &var, int_2 bias=0); 78 | 79 | Scheme phi(vector > const &bc, int_2 bias=0); 80 | Scheme grad(vector > const &bc); 81 | Scheme normGrad(vector > const &bc); 82 | 83 | Scheme phi(shared_ptr var, int_2 bias=0); 84 | Scheme grad(shared_ptr var); 85 | Scheme normGrad(shared_ptr var); 86 | 87 | // Scheme virtual getGrad() {}; 88 | // void virtual makeSimpleBlock(initializer_list n) { } 89 | 90 | // void virtual split(initializer_list n, bool debug=false) { } 91 | // void virtual splitAndExpand(initializer_list n, bool debug=false) { } 92 | // void virtual extrude(int dir, vector > jnd) { } 93 | Vec3 virtual edge(int_2 i=0) { return Vec3(0); } 94 | // int_2 virtual ngbrLevel(int_2 dir=0) { return 0; } 95 | // vector > virtual edgeVertexList(int_2 i) { 96 | // vector > l; return l; 97 | // } 98 | // shared_ptr virtual ngbrCell(int_2 i, int_2 j) { 99 | // shared_ptr c; return c; 100 | // } 101 | vector virtual ngbrCellList() { return vector(); } 102 | void virtual checkIslandLevels(int dir) {}; 103 | void virtual checkNgbrLevel(int dir) {}; 104 | 105 | Vec3 virtual vol() { return Vec3(1,0,0); } 106 | double virtual dx() { return 0; } 107 | double virtual dy() { return 0; } 108 | double virtual dz() { return 0; } 109 | bool virtual isPointIn(Vec3 a) { return false; } 110 | 111 | Vec3 getCoord() { 112 | Vec3 sum(0,0,0); double icnt = 0; 113 | for (auto i = 0; i const &a){ 122 | if (a) { 123 | out << (a)->node.size() << " "; 124 | for (auto e = (a)->node.begin(); e != (a)->node.end(); ++e) { 125 | if (*e >= 0) out << *e << " "; 126 | } 127 | out << endl; 128 | return out; 129 | } else { 130 | return out << "NULL" << endl; 131 | } 132 | }; 133 | virtual ~Cell() {}; 134 | }; 135 | 136 | #include "Line.hpp" 137 | 138 | class Tri: public Cell { 139 | public: 140 | Tri(initializer_list l):Cell(l) { 141 | setType(5); 142 | } 143 | }; 144 | 145 | #include "Quad.hpp" 146 | 147 | class Hexa: public Cell { 148 | protected: 149 | const int_2 map[8] = {6, 7, 4, 5, 2, 3, 0, 1}; 150 | public: 151 | // short int type; 152 | Hexa(initializer_list l):Cell(l) { 153 | setType(12); 154 | } 155 | 156 | 157 | }; 158 | 159 | 160 | 161 | 162 | #endif 163 | -------------------------------------------------------------------------------- /example/unclassified/main_cavity.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | *************************************************************************** 3 | * Copyright (C) 2015, Eray Uzgoren * 4 | * * 5 | * This program is free software: you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License as published by * 7 | * the Free Software Foundation, either version 3 of the License, or * 8 | * (at your option) any later version. * 9 | * * 10 | * This program is distributed in the hope that it will be useful, * 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 | * GNU General Public License for more details. * 14 | * * 15 | * You should have received a copy of the GNU General Public License * 16 | * along with this program. If not, see . * 17 | *************************************************************************** 18 | */ 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | 29 | 30 | int main() { 31 | 32 | //CAVITY FLOW 33 | auto dt = 0.01; 34 | auto t = clock(); 35 | 36 | // GRID 37 | Block2* grid = new Block2({0, 0, 0}, {1.0, 1.0, 0}, 10, 10); 38 | // grid->adaptCriteria(); 39 | 40 | // CONST variables; 41 | double rho = 1; double mu = 0.01; 42 | 43 | // FIELD variables; 44 | grid->addVar({"p", "vor"}); 45 | 46 | // initial and bc values; 47 | auto u = grid->getVar("u"); 48 | u->set(0.0); 49 | u->setBC("west", "val", 0); u->setBC("east", "val", 0); 50 | u->setBC("south", "val", 0); u->setBC("north", "val", 1); 51 | auto v = grid->getVar("v"); 52 | v->set(0.0); 53 | v->setBC("west", "val", 0); v->setBC("east", "val", 0); 54 | v->setBC("south", "val", 0); v->setBC("north", "val", 0); 55 | 56 | auto p = grid->getVar("p"); 57 | p->setBC("south", "val", 0); 58 | p->set(0.0); 59 | 60 | auto vor = grid->getVar("vor"); 61 | 62 | // solver behavior 63 | u->solver = "BiCGSTAB"; u->itmax = 20; u->tol = 1e-4; 64 | v->solver = "BiCGSTAB"; v->itmax = 20; v->tol = 1e-4; 65 | p->solver = "BiCGSTAB"; p->itmax = 2000; p->tol = 1e-6; 66 | 67 | auto gp = grid->valGrad(p); 68 | 69 | 70 | // Time control 71 | grid->setDt(dt); 72 | double time= 0; double endTime = 30; //dt*50; 73 | int filecnt = 0; int it = 0, writeInt = 1; 74 | ofstream myfile; 75 | while (time < endTime) { 76 | cout << setiosflags(ios::scientific) << setprecision(2); 77 | cout << "------------- Processing TIME = "<< time << " ------------------"<getVel(); 80 | auto diverge = grid->valDiv(vel); 81 | cout << "+ div=("<valDiv(vel) << endl; 85 | 86 | vor->set(grid->valGrad(v).comp(0) - grid->valGrad(u).comp(1)); 87 | auto gu = grid->valGrad(u); 88 | auto gv = grid->valGrad(v); 89 | 90 | grid->lockBC(u); 91 | u->solve( 92 | grid->ddt(rho) 93 | + grid->div(vel, rho, {0.5}) 94 | - grid->laplace(mu, {0.5}) 95 | - grid->source(0, -gp.comp(0)) // gradX is not defined; 96 | ); 97 | grid->unlockBC(); 98 | 99 | grid->lockBC(v); 100 | v->solve( 101 | grid->ddt(rho) 102 | + grid->div(vel, rho, {0.5}) 103 | - grid->laplace(mu, {0.5}) 104 | - grid->source(0, -gp.comp(1)) 105 | ); 106 | grid->unlockBC(); 107 | 108 | // grid->solBasedAdapt(vor->data); 109 | // grid->solBasedAdapt(gp); 110 | if ((it == 1) || (it % writeInt) == 0) { 111 | //grid->solBasedAdapt(gu, 1.0); 112 | // grid->solBasedAdapt(grid->valGrad(vor), 0.4); 113 | grid->solBasedAdapt(vor->data, 0.9); 114 | // for (auto i = 0; i < grid->listCell.size(); ++i) 115 | // for (auto j = 0; j< 3; ++j) 116 | // grid->listCell[i]->checkNgbrLevel(j); 117 | grid->refine2(); 118 | } 119 | 120 | // if (periodic) grid->adapt(); 121 | auto velstar = grid->getVel(); 122 | 123 | auto vsdiv = grid->valDiv(velstar); 124 | cout << "+ div=("<valDiv(velstar) << endl; 126 | //cin.ignore().get(); 127 | 128 | grid->lockBC(p); 129 | p->solve(grid->laplace(dt/rho) - grid->source(0, grid->valDiv(velstar))); 130 | double pref = p->data.min(); 131 | for (auto i = 0; i < grid->listCell.size(); ++i) { 132 | p->data[i] = p->data[i] - pref; 133 | } 134 | grid->unlockBC(); 135 | 136 | gp = grid->valGrad(p); 137 | //cout << gp <set(velstar.comp(0)-dt/rho*gp.comp(0)); // 139 | v->set(velstar.comp(1)-dt/rho*gp.comp(1)); // 140 | //grid->correctVel(velstar, dt/rho); 141 | 142 | grid->setDt(dt); 143 | time += grid->dt; 144 | 145 | //grid->solBasedAdapt(vor->data); 146 | // grid->solBasedAdapt(gv); 147 | //grid->refine2(); 148 | if (( it++ % writeInt) == 0) { 149 | //grid->writeFace("face"+std::to_string(filecnt)+".vtk"); 150 | std::string flname="cav"+std::to_string(filecnt++)+".vtk"; 151 | myfile.open(flname); 152 | myfile << grid << endl; 153 | myfile.close(); 154 | 155 | } 156 | 157 | cout << "---------------------------------------------------"<. * 17 | *************************************************************************** 18 | */ 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | 30 | int main() { 31 | ofstream myfile; 32 | ifstream input; 33 | int filecnt = 0; 34 | 35 | std::default_random_engine gen; 36 | std::bernoulli_distribution incx(0.3); 37 | std::bernoulli_distribution incy(0.5); 38 | std::bernoulli_distribution decx(0.7); 39 | std::bernoulli_distribution decy(0.7); 40 | bool prod = false; 41 | // GRID 42 | Block2* grid = new Block2({0, 0, 0}, {1.0, 1.0, 0}, 5, 5); 43 | // Block2* grid2 = new Block2({0, 0, 0}, {1.0, 1.0, 0}, 3, 3); 44 | // grid->adaptCriteria(); 45 | 46 | auto u = grid->getVar("u"); 47 | auto v = grid->getVar("v"); 48 | 49 | for (auto pass = 0; pass < 4; ++pass) { 50 | std::string flname="op"+std::to_string(pass)+".dat"; 51 | if (prod) { 52 | myfile.open(flname); 53 | for (auto c : grid->listCell) { 54 | c->adapt[0] = 0; 55 | c->adapt[1] = 0; 56 | if (incx(gen) && c->level[0] != grid->levelHighBound[0]) { c->adapt[0]=1;} 57 | if (incy(gen) && c->level[1] != grid->levelHighBound[1]) { c->adapt[1]=1;} 58 | if (c->adapt[0] == 0 && c->adapt[1] == 0) { 59 | if (decx(gen) && c->level[0] != grid->levelLowBound[0]) { c->adapt[0]=-1;} 60 | if (decy(gen) && c->level[1] != grid->levelLowBound[1]) { c->adapt[1]=-1;} 61 | } 62 | myfile << c->adapt[0] << " " << c->adapt[1] << endl; 63 | } 64 | myfile.close(); 65 | } else { 66 | input.open(flname); 67 | if (input.is_open()) { 68 | for (auto c : grid->listCell) { 69 | input >> c->adapt[0]; 70 | input >> c->adapt[1]; 71 | // c->adapt[0] = max(short(0), c->adapt[0]); 72 | // c->adapt[1] = max(short(0), c->adapt[1]); 73 | } 74 | input.close(); 75 | } else { 76 | cout << "cannot read data"<< endl; 77 | exit(1); 78 | } 79 | } 80 | 81 | cout << filecnt << " pass: " << pass << " random " << endl; 82 | flname="grid"+std::to_string(filecnt++)+".vtk"; 83 | myfile.open(flname); 84 | myfile << grid << endl; 85 | myfile.close(); 86 | 87 | 88 | for (auto i = 0; i < grid->listCell.size(); ++i) { 89 | grid->listCell[i]->checkNgbrLevel(0); 90 | grid->listCell[i]->checkNgbrLevel(1); 91 | grid->listCell[i]->checkNgbrLevel(2); 92 | } 93 | 94 | cout << filecnt << " pass: " << pass << " corrected " << endl; 95 | flname="grid"+std::to_string(filecnt++)+".vtk"; 96 | myfile.open(flname); 97 | myfile << grid << endl; 98 | myfile.close(); 99 | 100 | 101 | grid->refine2(); 102 | // auto lmin = **(std::min_element(&(grid->levelMin), &(grid->levelMin)+3)); 103 | // auto lmax = **(std::max_element(&(grid->levelMax), &(grid->levelMax)+3)); 104 | // for (auto j = 0; j < 2; ++j) { 105 | // for (auto l = grid->levelMin[j]; l < grid->levelMax[j]+1; ++l) { 106 | // auto nCell = grid->listCell.size(); 107 | // for (auto i = 0; i < nCell; ++i) { 108 | // auto c = grid->listCell[i]; 109 | // if (c->level[j] != l) continue; 110 | // if (c->adapt[j] == 0) continue; 111 | // c->refine(j); 112 | // // if (j == 0) 113 | // // c->convertToSimpleBlock({2,1}); 114 | // // else 115 | // // c->convertToSimpleBlock({1,2}); 116 | // // c->adapt[j]--; c->level[j]++; 117 | // // for (auto k=0; k< 2; ++k) { 118 | // // grid->listCell[k]->adapt.assign(c->adapt.begin(), c->adapt.end()); 119 | // // grid->listCell[k]->level.assign(c->level.begin(), c->level.end()); 120 | // // } 121 | // } 122 | // grid->setCurrentLevels(); 123 | // cout << "("<levelMin[0] << "-"<< grid->levelMax[0] <<")-"; 124 | // cout << "("<levelMin[1] << "-"<< grid->levelMax[1] <<")"; 125 | // cout << filecnt << " pass: " << pass << " l: " << l << " dir: "<< j << endl; 126 | // for (auto i = 0; ilistCell.size(); ++i) { 127 | // u->set(i, grid->listCell[i]->adapt[0]); 128 | // v->set(i, grid->listCell[i]->adapt[1]); 129 | // } 130 | // flname="grid"+std::to_string(filecnt++)+".vtk"; 131 | // myfile.open(flname); 132 | // myfile << grid << endl; 133 | // myfile.close(); 134 | // } 135 | // } 136 | flname="grid"+std::to_string(filecnt++)+".vtk"; 137 | myfile.open(flname); 138 | myfile << grid << endl; 139 | myfile.close(); 140 | } 141 | 142 | string flname="grid"+std::to_string(filecnt++)+".vtk"; 143 | myfile.open(flname); 144 | myfile << grid << endl; 145 | myfile.close(); 146 | // flname="grid"+std::to_string(filecnt++)+".vtk"; 147 | // myfile.open(flname); 148 | // myfile << grid2 << endl; 149 | // myfile.close(); 150 | 151 | delete(grid); 152 | 153 | return 0; 154 | } 155 | -------------------------------------------------------------------------------- /example/unclassified/main2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | *************************************************************************** 3 | * Copyright (C) 2015, Eray Uzgoren * 4 | * * 5 | * This program is free software: you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License as published by * 7 | * the Free Software Foundation, either version 3 of the License, or * 8 | * (at your option) any later version. * 9 | * * 10 | * This program is distributed in the hope that it will be useful, * 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 | * GNU General Public License for more details. * 14 | * * 15 | * You should have received a copy of the GNU General Public License * 16 | * along with this program. If not, see . * 17 | *************************************************************************** 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | int main() { 26 | // Grid grid; 27 | // cout << "1" << &grid << endl; 28 | // grid.addVertex({ {0, 0, 0}, {1, 0, 0} 29 | // , {1, 1, 0}, {0, 1, 0}, {0, 2, 0}, {1, 2, 0}}); 30 | // cout << "2" << &grid << endl; 31 | 32 | // grid.addCell({ { 3, 2, 5, 4} }); 33 | // cout << "3" << &grid << endl; 34 | // grid.addVertex({ 35 | // {2, 0, 0}, {2, 1, 0}, {2.1, 2.2, 0}, {0.5, 0, 0} 36 | // , {0, 0.5, 0}, {1, 0.5, 0} 37 | // , {0.5, 1, 0}, {0.5, 0.5, 0} 38 | // , {1.5,1,0},{2,1.5,0},{1.5,2,0} 39 | // ,{1,1.5,0}, {1.4, 1.6, 0} }); 40 | // cout << "4" << &grid << endl; 41 | // grid.addCell({ {2,14,18,17}, {14,7,15,18}, {1,6, 7, 2} 42 | // , {18,15,8,16}, {17,18, 16,5} 43 | // , {0, 9, 13, 10} , {9, 1, 11, 13}, {10, 13, 12, 3}, {13, 11, 2, 12} }); 44 | // cout << "5" << &grid << endl; 45 | //Grid* dummy = new Grid(); 46 | //Grid* dummy2 = new Grid(); 47 | // dummy = new shared_ptr(&grid); 48 | //dummy2 = dummy; 49 | // dummy2.reset(); 50 | // cout << &dummy << " " << dummy->cbegin()->grid << endl; 51 | //cout << &grid << " " << grid.cbegin()->grid << endl; 52 | //Grid dummy3 = grid; 53 | //cout << &dummy3 << " " << dummy3.cbegin()->grid << endl; 54 | 55 | cout << "1" << endl; 56 | Grid* block = new Block3({0,0,0}, {1,1,1}, 10, 9, 5); 57 | 58 | if (block->listCell.capacity() < (block->listCell.size() + 30)) {block->listCell.reserve(max(block->listCell.capacity()*2,block->listCell.size() + 30));} 59 | (block->cbegin())->splitHexa(5,3,2); 60 | //cout << "3" << endl; 61 | //(block->cbegin())->splitHexa(2,2,2); 62 | // cout << "4" << endl; 63 | 64 | // Grid* d2 = new Grid(); 65 | // d2->addVertex({ {0,0,0}, {1,0,0}, {1,1,0}, {0, 1, 0}}); 66 | // d2->addCell({0,1,2,3}); 67 | // (d2->cbegin())->splitQuad(10,10); 68 | 69 | ofstream myfile; 70 | myfile.open("grid3d.vtk"); 71 | myfile << *block << endl; 72 | myfile.close(); 73 | 74 | // myfile.open("block.vtk"); 75 | // myfile << d2 <splitQuad(6,10); 79 | // (grid.cbegin()+3)->splitQuad(2, 4); 80 | // (grid.cbegin()+1)->splitQuad(2, 10); 81 | // (grid.cbegin()+2)->splitQuad(2, 10); 82 | // (grid.cbegin()+4)->splitQuad(2, 10); 83 | // (grid.cbegin()+5)->splitQuad(2, 10); 84 | 85 | // (grid.cbegin()+6)->splitQuad(3, 1); 86 | // (grid.cbegin()+7)->splitQuad(3, 1); 87 | // (grid.cbegin()+8)->splitQuad(3, 1); 88 | // (grid.cbegin()+9)->splitQuad(6, 1); 89 | 90 | 91 | //(*(grid->listFace.begin()))->slice(0, 4);//, 4); 92 | short int map1[4][2]={{1,2},{0,3},{2,3},{0,1}}; 93 | 94 | // cout << "Vertex List" << endl; 95 | // for (auto p = grid.vbegin(); p != grid.vend(); ++p) { 96 | // cout << *p << " ["; 97 | // for (const auto& l : p->node) { 98 | // cout << l << " "; 99 | // } 100 | // cout << "] " < faces; 106 | for (auto f = block->cbegin(); f != block->cend(); ++f) { 107 | cout << *f << " "; 108 | cout << "faces "; 109 | faces = f->ngbrAllFaces(); 110 | cout << "[" << faces.size() << "] ("; 111 | for (auto c = faces.begin(); c != faces.end(); ++c) { 112 | cout << *c << " ("<Area()<<") - "; 113 | } 114 | cout << ") "<< endl; 115 | faces.clear(); 116 | } 117 | cout << endl; 118 | 119 | myfile.open("grid2d.vtk"); 120 | myfile << grid <cend()-1; 125 | // cout << "-----------"<< endl << *(c) << endl; 126 | // faces = c->ngbrFaces(2); 127 | // cout<< *(c->ngbr(0,3)) << endl << *(c->ngbr(3,0)) << endl; 128 | // for (auto f = faces.begin(); f != faces.end(); ++f) { 129 | // cout << *f << endl; 130 | // } 131 | // cout << "===========" < ma(5000); //ma.uncompress(); 135 | // ma[4999][250] = 1; 136 | 137 | // ma.info(); 138 | 139 | LinSys vel(6); 140 | VecX x(6); x.uncompress(); 141 | vel.A = { 142 | { 2, -1, 0, 0, 0, 0}, 143 | {-1, 2, -1, 0, 0, 0}, 144 | { 0, -1, 2, -1, 0, 0}, 145 | { 0, 0, -1, 2, -1, 0}, 146 | { 0, 0, 0, -1, 2, -1} 147 | }; 148 | vel.A[5] = { 0, 0, 0, 0, -1, 2} ; 149 | //vel.A[5][4] = -0.5; 150 | 151 | //vel.A.info(); 152 | 153 | x = {1, -2, 3, -4, 9, 3}; 154 | vel.b = vel.A*x; 155 | cout << vel.b << endl; 156 | x = {0, 0, 0, 0, 0, 0}; 157 | 158 | vel.x = &x; 159 | vel.setLimits(1e-8); 160 | 161 | //vel.Gauss_Seidel(); 162 | vel.CG(); 163 | cout <<"x: "<< x<< endl; 164 | 165 | 166 | Vec3 a({1, 1, 0}); 167 | Vec3 b({-1, 1, 0}); 168 | cout << endl; 169 | cout << 0.5*abs(a^b) << endl; 170 | 171 | return 0; 172 | }; 173 | -------------------------------------------------------------------------------- /src/grid/Line.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | *************************************************************************** 3 | * Copyright (C) 2015, Eray Uzgoren * 4 | * * 5 | * This program is free software: you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License as published by * 7 | * the Free Software Foundation, either version 3 of the License, or * 8 | * (at your option) any later version. * 9 | * * 10 | * This program is distributed in the hope that it will be useful, * 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 | * GNU General Public License for more details. * 14 | * * 15 | * You should have received a copy of the GNU General Public License * 16 | * along with this program. If not, see . * 17 | *************************************************************************** 18 | */ 19 | #include 20 | 21 | void Line::assignCelltoNode() { 22 | // check size first; if this is the first time assign only current nodes; 23 | for (int_2 i = 0; i<2; ++i) { 24 | if (auto v = getVertex(i)) { 25 | if ((*v)->cell.size() != 2) (*v)->reset(2); 26 | (*v)->replaceCell(int(i+1)%2, id); 27 | } 28 | } 29 | } 30 | 31 | void Line::convertToSimpleBlock(initializer_list n, bool debug) { 32 | int n1=1; 33 | // First find the existing vertex if non then proceed; 34 | if (n.size() >= 1) {n1 = *(n.begin());} 35 | else { return; } 36 | if (debug) cout << "Converting cell: "< ind; 39 | ind.assign(n1+1, -1); 40 | 41 | ind[0] = node[0]; 42 | ind[n1] = node[1]; 43 | 44 | Vec3 dx, x0,x1; 45 | x0 = Vec3(**getVertex(0)); 46 | dx = edge()/double(n1); 47 | 48 | // Fill in non-existing Vertices 49 | for (auto i = 0; i < n1+1 ; ++i) { 50 | if (debug) cout << "Processing i = "<< i << " using index "<< ind[i] << endl; 51 | if (ind[i]>=0) { 52 | if (debug) 53 | cout<< "Existing vertex: " << ind[i] << " ("<< *(*(grid->listVertex.begin()+ind[i])) <<")"<< endl; 54 | //(*(grid->listVertex.begin()+ind[i][j]))->reset(4); 55 | continue; 56 | } 57 | grid->addVertex(x0 + double(i)*dx); 58 | ind[i] = grid->listVertex.size()-1; 59 | (*(grid->listVertex.rbegin()))->reset(4); 60 | if (debug) 61 | cout<< "New vertex: " << ind[i] << " ("<< *(*(grid->listVertex.begin()+ind[i])) <<")"<< endl; 62 | // boundary 63 | // (*(grid->listVertex.rbegin()))->setCell(0, (j-1)*n1+i-1+nCell); 64 | } 65 | 66 | auto nCell = grid->listCell.size()-1; 67 | for (auto i = 0; i < n1+1; ++i) { 68 | auto v = (*(grid->listVertex.begin()+ind[i])); 69 | int_8 i0 = i-1; i0 = (i0 == 0) ? id : i0+nCell; 70 | int_8 i1 = i; i1 = (i1 == 0) ? id : i1+nCell; 71 | 72 | if (i > 0 && i < n1) { 73 | v->setCell({i0, i1}); 74 | } else if (i == 0) { 75 | auto v0 = grid->listVertex.begin() + ind[i]; 76 | v->setCell({(*v0)->cell[0], i1}); 77 | } else if (i == n1) { 78 | auto v0 = grid->listVertex.begin() + ind[i]; 79 | v->setCell({i0, (*v0)->cell[1]}); 80 | } 81 | } 82 | 83 | for (auto i = 0; i < n1; ++i) { 84 | if (i == 0) { 85 | reset({ind[i], ind[i+1]}); 86 | } else { 87 | grid->addCell({ind[i], ind[i+1]}); 88 | auto x = (*grid->listCell.rbegin())->getCoord(); 89 | for (auto k = 0; k < grid->listVar.size(); ++k) { 90 | grid->listVar[k]->set(grid->listCell.size()-1,grid->listVar[k]->get(id)); // oldv[k] + (x-xcold)*oldg[k]); 91 | } 92 | } 93 | } 94 | 95 | return; 96 | } 97 | 98 | 99 | void Line::refine(int dir) { 100 | dir =0; 101 | if (adapt[0] < 1) return; 102 | if (level[0] == grid->levelHighBound[0]) return; 103 | convertToSimpleBlock({2}); 104 | 105 | adapt[dir]--; level[dir]++; 106 | (*(grid->listCell.rbegin()))->masterx.assign(masterx.begin(), masterx.end()); 107 | (*(grid->listCell.rbegin()))->mastery.assign(mastery.begin(), mastery.end()); 108 | (*(grid->listCell.rbegin()))->masterz.assign(masterz.begin(), masterz.end()); 109 | 110 | if (dir == 0) masterx[level[dir]] = true; 111 | if (dir == 1) mastery[level[dir]] = true; 112 | if (dir == 2) masterz[level[dir]] = true; 113 | 114 | (*(grid->listCell.rbegin()))->adapt.assign(adapt.begin(), adapt.end()); 115 | (*(grid->listCell.rbegin()))->level.assign(level.begin(), level.end()); 116 | } 117 | 118 | 119 | 120 | 121 | 122 | // Vec3 Line::grad(shared_ptr phi) { 123 | // auto c0 = (prev>=0) ? &(**(grid->listCell.begin() + prev)) : this; 124 | // auto c1 = (next>=0) ? &(**(grid->listCell.begin() + next)) : this; 125 | // Vec3 dx = 1./(c1->getCoord() - c0->getCoord()); 126 | // if (next >= 0 && prev >= 0) { 127 | // return (phi->data[next] - phi->data[prev])*dx; 128 | // } else { 129 | // double a=0, b=0; 130 | // getBCPhi(phi, a, b); 131 | // return (next >=0) ? (phi->data[next] - a*(phi->data[next] + b))*dx 132 | // : (a*(phi->data[prev] + b) - phi->data[prev])*dx; 133 | // } 134 | // } 135 | 136 | 137 | // void Line::getBCPhi(shared_ptr phi, double &a, double &b) { 138 | // a = 0; b = 0; 139 | // auto bndr = (prev >= 0) ? -next-1 : -prev-1; 140 | // if (bndr < 0 || bndr >= phi->listBC.size() || !(phi->listBC[bndr])) { 141 | // cout << "Something wrong with bndr : Value "<< bndr <listBC[bndr]->type == 0) { 145 | // a = phi->listBC[bndr]->a_val; 146 | // b = phi->listBC[bndr]->b_val; 147 | // } else if (phi->listBC[bndr]->type == 1) { 148 | // auto row = (prev >= 0) ? prev : next; 149 | // auto c0 = *(grid->listCell.begin() + row); 150 | // auto norm = vol(); norm = norm/norm.abs(); 151 | // double dx = norm*(getCoord() - c0->getCoord()); 152 | // a = (1.0 + dx*phi->listBC[bndr]->a_val); 153 | // b = dx*phi->listBC[bndr]->b_val; 154 | // } 155 | // return; 156 | // } 157 | -------------------------------------------------------------------------------- /example/unclassified/main_triint.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | *************************************************************************** 3 | * Copyright (C) 2015, Eray Uzgoren * 4 | * * 5 | * This program is free software: you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License as published by * 7 | * the Free Software Foundation, either version 3 of the License, or * 8 | * (at your option) any later version. * 9 | * * 10 | * This program is distributed in the hope that it will be useful, * 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 | * GNU General Public License for more details. * 14 | * * 15 | * You should have received a copy of the GNU General Public License * 16 | * along with this program. If not, see . * 17 | *************************************************************************** 18 | */ 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | 28 | int main(int argc, char* argv[]) { 29 | double x=0.6, y=0.0, z=0.0; 30 | Grid* grid = new Block2({0, 0, 0}, {1, 1, 0}, 2, 2); 31 | 32 | if (argc >= 2) x = atof(argv[1]); 33 | if (argc >= 3) y = atof(argv[2]); 34 | 35 | auto pt = Vec3(x, y, z); 36 | 37 | grid->listCell[0]->adapt[0] = 1; 38 | grid->listCell[0]->adapt[1] = 1; 39 | grid->listCell[1]->adapt[0] = 1; 40 | grid->listCell[2]->adapt[1] = 1; 41 | grid->adapt(); 42 | grid->levelHighBound[0]=6; 43 | grid->levelHighBound[1]=6; 44 | 45 | for (auto c : grid->listCell) { 46 | if (c->isPointIn(pt)) 47 | cout << "cell " << c->id << " contains pt= " << pt << endl; 48 | } 49 | // exit(1); 50 | 51 | auto i0 = grid->searchVertexbyCoords(pt); 52 | cout << "Vertex " << i0 << " : " << *grid->listVertex[i0] << endl; 53 | for (auto ci : grid->listVertex[i0]->cell) { 54 | if (ci < 0) continue; 55 | cout << "Cells: " << ci << endl; 56 | } 57 | 58 | //exit(1); 59 | 60 | 61 | grid->addVar({"T"}); 62 | 63 | auto T = grid->getVar("T"); 64 | T->setBC("west", "grad", 1); 65 | T->setBC("south", "grad", 2); 66 | T->setBC("east", "grad", 1); 67 | T->setBC("north", "grad", 2); 68 | 69 | double pi = 4.0*atan(1); 70 | for (auto i = 0; i < grid->listCell.size(); ++i) { 71 | auto c = grid->listCell[i]; 72 | auto x = c->getCoord(); 73 | T->set(i, x[0] + 2*x[1]); 74 | //T->set(i, sin(x[0]*2*pi)*sin(x[1]*2*pi)); // + cos(x[0]*4*pi)*sin(x[1]*2*pi)); 75 | } 76 | 77 | for (auto k = 0; k < 2; ++k) { 78 | for (auto i = 0; i < grid->listCell.size(); i++) { 79 | grid->listCell[i]->adapt[0] = 1; 80 | grid->listCell[i]->adapt[1] = 1; 81 | } 82 | grid->adapt(); 83 | } 84 | 85 | 86 | Grid* other = new Block2({0.05, 0.05, 0}, {0.95, 0.95, 0}, 51, 78); 87 | other->addVar({"T"}); 88 | auto Tn = other->getVar("T"); 89 | 90 | for (auto c:other->listCell) { 91 | auto x = c->getCoord(); 92 | Tn->set(c->id, grid->interp(T, x)); 93 | } 94 | 95 | grid->writeVTK("int2_"); 96 | other->writeVTK("oth_"); 97 | 98 | //exit(1); 99 | 100 | for (auto k = 0; k < 2; ++k) { 101 | for (auto i = 0; i < grid->listCell.size(); i++) { 102 | grid->listCell[i]->adapt[0] = -1; 103 | // grid->listCell[i]->adapt[1] = -1; 104 | } 105 | grid->adapt(); 106 | } 107 | 108 | // for (auto i = 0; i < grid->listCell.size(); ++i) { 109 | // auto c = grid->listCell[i]; 110 | // auto x = c->getCoord(); 111 | // //T->set(i, x[0] + 2*x[1]); 112 | // T->set(i, sin(x[0]*2*pi)*sin(x[1]*2*pi)); // + cos(x[0]*4*pi)*sin(x[1]*2*pi)); 113 | // } 114 | 115 | for (auto c:other->listCell) { 116 | auto x = c->getCoord(); 117 | auto i0 = grid->searchVertexbyCoords(x); //grid->searchInterpPoint(x, grid->searchVertexbyCoords(x)); 118 | if (i0 < 0) { 119 | // cout << "search of << " << x << " failed " << endl; 120 | // cout << "result of init search " << grid->searchVertexbyCoords(x) << endl; 121 | } else { 122 | Tn->set(c->id, grid->listVertex[i0]->evalPhi(T, &x)); 123 | } 124 | } 125 | 126 | grid->writeVTK("int2_"); 127 | other->writeVTK("oth_"); 128 | 129 | ofstream out; 130 | out.open("interp.vtk"); 131 | 132 | 133 | int_8 nCell = grid->listVertex.size(); 134 | int t; // = listCell[0]->node.size()+1; 135 | out << "# vtk DataFile Version 2.0" << endl; 136 | out << "Unstructure Grid" << endl; 137 | out << "ASCII"<< endl; 138 | out << endl << "DATASET UNSTRUCTURED_GRID"<< endl; 139 | out << "POINTS " << 4*nCell << " float" << endl; 140 | for (auto v : grid->listVertex) { 141 | out << grid->int3D.linFunc(Vec3(0,0,0), v->xcoef) << " "; 142 | out << grid->int3D.linFunc(Vec3(0,0,0), v->ycoef) << " "; 143 | out << grid->int3D.linFunc(Vec3(0,0,0), v->zcoef) << endl; 144 | out << grid->int3D.linFunc(Vec3(1,0,0), v->xcoef) << " "; 145 | out << grid->int3D.linFunc(Vec3(1,0,0), v->ycoef) << " "; 146 | out << grid->int3D.linFunc(Vec3(1,0,0), v->zcoef) << endl; 147 | out << grid->int3D.linFunc(Vec3(1,1,0), v->xcoef) << " "; 148 | out << grid->int3D.linFunc(Vec3(1,1,0), v->ycoef) << " "; 149 | out << grid->int3D.linFunc(Vec3(1,1,0), v->zcoef) << endl; 150 | out << grid->int3D.linFunc(Vec3(0,1,0), v->xcoef) << " "; 151 | out << grid->int3D.linFunc(Vec3(0,1,0), v->ycoef) << " "; 152 | out << grid->int3D.linFunc(Vec3(0,1,0), v->zcoef) << endl; 153 | } 154 | auto icnt = 0; 155 | out << endl << "CELLS "<< nCell << " " << nCell*5 << endl; 156 | for (auto v : grid->listVertex) { 157 | out << "4 " << icnt << " " << icnt+1 << " " << icnt+2 << " " << icnt+3 << endl; 158 | icnt += 4; 159 | } 160 | out << endl << "CELL_TYPES " << nCell <listVertex) { 162 | out << "9 "<< endl; 163 | } 164 | out.close(); 165 | return 0; 166 | } 167 | -------------------------------------------------------------------------------- /include/grid/Search_grid.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SEARCHGRID 2 | #define SEARCHGRID 3 | 4 | 5 | double phi(shared_ptr &q, Vec3 x, int_8 i0=0) { 6 | auto n = searchVertexbyCoords(x, i0); 7 | if (n >= 0) return listVertex[n]->evalPhi(q, &x); 8 | else return 0; 9 | } 10 | 11 | 12 | 13 | int_8 searchVertexbyCoords(Vec3 a, int_8 i0=0) { 14 | if (i0 >= listVertex.size() && i0 < 0) { 15 | cout << "Initial vertex do not exists" << endl; 16 | exit(-1); 17 | } 18 | // for (auto v : listVertex) { 19 | // if (v->isIn(a)) return v->id; 20 | // } 21 | // return -1; 22 | 23 | // cout << endl << " ---------- " << " Searching for " << a << " -------- " << endl; 24 | 25 | auto v = listVertex[i0]; 26 | vector blist(listVertex.size(), false); 27 | int_8 i1 = i0; 28 | // else search 29 | while (v.get()) { 30 | //cout << " + Try: "<< i0 << " @ ( " << *v << " ) " << endl; 31 | if (v->isIn(a)) { 32 | //cout << "[OK] " << endl; 33 | return v->id; 34 | } 35 | //cout << "[!] blisted " << endl; 36 | blist[v->id] = true; 37 | 38 | // Search for next node; 39 | double rmin = 100*(*v-a).abs(); 40 | //cout << " + dist: " << rmin << endl; 41 | for (auto idir = -2; idir < 3; ++idir) { 42 | if (idir == 0) continue; 43 | //cout << " - dir : " << idir << " " ; 44 | if (auto vnptr = v->ngbr(idir)) { 45 | auto vn = *vnptr; 46 | //cout << vn->id << " "; 47 | if (blist[vn->id]) { 48 | //cout << " [!] blist "<< endl; 49 | continue; 50 | } 51 | // if (vn->isIn(a)) { cout << " [OK] " << endl; return vn->id; } 52 | // else measure distance; 53 | auto r = (*vn-a).abs(); 54 | // cout << "dist: " << r << " ( " << rmin << ") "; 55 | if (r < rmin) { 56 | i1 = vn->id; 57 | rmin = r; 58 | //cout << " next cand v @ " << *v << endl; 59 | } else { 60 | //cout << " [!] try next dir " <id]) { cout << "Search failed!!!!" << endl; cin.ignore().get(); return -1;} 71 | } 72 | 73 | return -1; 74 | 75 | 76 | 77 | 78 | // while (v.get()) { 79 | 80 | // bool isMinFound = false; 81 | // auto rmin = (*v-a).abs(); 82 | // if (v->cell.size() == 4) { 83 | // for (auto ci : v->cell) { 84 | // if (ci < 0 || ci >= listCell.size()) continue; 85 | // for (auto vi : listCell[ci]->node) { 86 | // if (vi < 0 || vi >= listVertex.size()) continue; 87 | // if (listVertex[vi]->isIn(a)) { 88 | // return vi; 89 | // } else { 90 | // //if (listVertex[vi]->isHanging()) continue; 91 | // auto r = (*listVertex[vi] - a).abs(); 92 | // if (r < rmin) { 93 | // isMinFound = true; v = listVertex[vi]; rmin = r; 94 | // } 95 | // } 96 | // } 97 | // if (!isMinFound) { 98 | // if (v->isIn(a)) { 99 | // break; 100 | // } else { 101 | // rmin = 100*rmin; 102 | // vblacklist.emplace_back(v->id); 103 | // continue; 104 | // } 105 | // } 106 | // } 107 | // } 108 | 109 | // // minimum distance does not guarantee connectivity 110 | // // another search should be addressed! 111 | // // if (!isFound) { 112 | 113 | // // // check 114 | // // } 115 | 116 | 117 | // if (v.get()) return v->id; 118 | // else return -1; 119 | } 120 | 121 | 122 | int_8 searchInterpPoint(Vec3 a, int_8 i0) { 123 | if (i0 >= listVertex.size() && i0 < 0) { 124 | cout << "Initial vertex do not exists" << endl; 125 | exit(-1); 126 | } 127 | auto v = listVertex[i0]; 128 | cout << endl << "---------" << endl << "Search: " << a << " from nearby vertex " << i0 << " @ " << *v << endl; 129 | for (auto ci : v->cell) { 130 | if (ci < 0 || ci >= listCell.size()) continue; 131 | for (auto vi : listCell[ci]->node) { 132 | if (vi < 0 || vi >= listVertex.size()) continue; 133 | cout << "+ vertex " << vi << " @ "<< *listVertex[vi] << " CoefUpdate " << listVertex[vi]->coefUpdate << endl; 134 | if (listVertex[vi]->coefUpdate) continue; 135 | auto xhat = int3D.findXhat(a, listVertex[vi]->xcoef, listVertex[vi]->ycoef, listVertex[vi]->zcoef); 136 | cout << " xhat = " << xhat ; 137 | if (int3D.isIn(xhat)) { cout << " [FOUND] " << vi << endl; return vi; } 138 | cout << " [NOT FOUND] continue " << endl; 139 | } 140 | } 141 | cout << " @ NOT FOUND " << endl; 142 | cin.ignore().get(); 143 | return -1; 144 | } 145 | 146 | int_8 searchCellbyCoords(Vec3 a, int_8 i0=0, bool isVertex=false) { 147 | auto j0 = isVertex ? i0 : listCell[i0]->node[0]; 148 | auto vi = searchVertexbyCoords(a, j0); 149 | if (vi < 0) return -1; 150 | auto v = listVertex[vi]; 151 | 152 | int_8 vc = -1; int_8 bc = 0; 153 | for (auto ic = 0; ic < v->cell.size(); ++ic) { 154 | if (v->cell[ic] < 0) {bc = v->cell[ic]; continue;} 155 | // Not correct for curvilinear // 156 | auto xmin = Vec3(*listVertex[listCell[v->cell[ic]]->node[0]]); 157 | auto xmax = Vec3(*listVertex[listCell[v->cell[ic]]->node[2]]); 158 | if (a[0] < xmin[0]) continue; 159 | if (a[1] < xmin[1]) continue; 160 | if (a[0] > xmax[0]) continue; 161 | if (a[1] > xmax[1]) continue; 162 | vc = v->cell[ic]; 163 | } 164 | if (vc >= 0) return vc; 165 | else if (bc < 0) return bc; 166 | else { 167 | cout << " Cell not found! vc = " << vc; 168 | cout << " vi = " << vi << " a="<< a<< endl; 169 | exit(-1); 170 | } 171 | // auto xhat = int3D.findXhat(a, v->xcoef, v->ycoef, v->zcoef); 172 | // if (xhat[0] <= 0.5 && xhat[1] <= 0.5) return v->cell[0]; 173 | // else if (xhat[0] > 0.5 && xhat[1] <= 0.5) return v->cell[1]; 174 | // else if (xhat[0] > 0.5 && xhat[1] > 0.5) return v->cell[2]; 175 | // else if (xhat[0] <= 0.5 && xhat[1] > 0.5) return v->cell[3]; 176 | // else return -1; 177 | } 178 | 179 | // int_8 searchInterpVertexbyCoords(Vec3 a, int_8 i0=0) { 180 | // auto vi = searchVertexbyCoords(a, i0); 181 | // if (vi < 0) return -1; 182 | // auto v = listVertex[vi]; 183 | // auto xhat = int3D.findXhat(a, v->xcoef, v->ycoef, v->zcoef); 184 | // if (xhat[0] <= 0.5 && xhat[1] <= 0.5) return v->cell[0]; 185 | // else if (xhat[0] > 0.5 && xhat[1] <= 0.5) return v->cell[1]; 186 | // else if (xhat[0] > 0.5 && xhat[1] > 0.5) return v->cell[2]; 187 | // else if (xhat[0] <= 0.5 && xhat[1] > 0.5) return v->cell[3]; 188 | // else return v->cell[0]; 189 | // } 190 | 191 | 192 | #endif 193 | -------------------------------------------------------------------------------- /example/unclassified/main_testint.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | *************************************************************************** 3 | * Copyright (C) 2015, Eray Uzgoren * 4 | * * 5 | * This program is free software: you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License as published by * 7 | * the Free Software Foundation, either version 3 of the License, or * 8 | * (at your option) any later version. * 9 | * * 10 | * This program is distributed in the hope that it will be useful, * 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 | * GNU General Public License for more details. * 14 | * * 15 | * You should have received a copy of the GNU General Public License * 16 | * along with this program. If not, see . * 17 | *************************************************************************** 18 | */ 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | 29 | 30 | int main() { 31 | std::string flname; 32 | int filecnt = 0; 33 | ofstream myfile; 34 | 35 | // GRID 36 | Block2* grid = new Block2({0, 0, 0}, {1.0, 1.0, 0}, 20, 20); 37 | 38 | // FIELD variables; 39 | grid->addVar({"p", "gpx", "gpy", "cgpx", "cgpy"}); 40 | grid->addVar("fgpx", 2); 41 | grid->addVar("fgpy", 2); 42 | 43 | auto p = grid->getVar("p"); 44 | auto gpx = grid->getVar("gpx"); 45 | auto gpy = grid->getVar("gpy"); 46 | auto cgpx = grid->getVar("cgpx"); 47 | auto cgpy = grid->getVar("cgpy"); 48 | auto u = grid->getVar("u"); 49 | auto v = grid->getVar("v"); 50 | auto w = grid->getVar("w"); 51 | auto fgpx = grid->getVar("fgpx"); 52 | auto fgpy = grid->getVar("fgpy"); 53 | 54 | // set the field variable 55 | // write face, node based and cell based to a file; 56 | auto t = clock(); 57 | for (auto i = 0; i < grid->listCell.size(); ++i) { 58 | auto c = grid->listCell[i]; 59 | auto x = c->getCoord(); 60 | double pi = 3.1456; 61 | p->set(i, sin(x[0]*4*pi)*cos(x[1]*2*pi)); // + cos(x[0]*4*pi)*sin(x[1]*2*pi)); 62 | gpx->set(i, 4*pi*cos(x[0]*4*pi)*cos(x[1]*2*pi)); 63 | gpy->set(i, 2*pi*sin(x[0]*4*pi)*sin(x[1]*2*pi)); 64 | } 65 | t = clock() - t; 66 | cout << " Exact time: "<< t/(double) CLOCKS_PER_SEC << " secs"<< endl; 67 | 68 | t = clock(); 69 | for (auto j = 0; j< 2; ++j) { 70 | grid->solBasedAdapt(gpx->data, 1.0); 71 | grid->solBasedAdapt(gpy->data, 1.5); 72 | grid->refine2(); 73 | for (auto i = 0; i < grid->listCell.size(); ++i) { 74 | auto c = grid->listCell[i]; 75 | auto x = c->getCoord(); 76 | double pi = 3.1456; 77 | p->set(i, sin(x[0]*4*pi)*cos(x[1]*2*pi)); // + cos(x[0]*4*pi)*sin(x[1]*2*pi)); 78 | gpx->set(i, 4*pi*cos(x[0]*4*pi)*cos(x[1]*2*pi)); 79 | gpy->set(i, -2*pi*sin(x[0]*4*pi)*sin(x[1]*2*pi)); 80 | } 81 | } 82 | t = clock() - t; 83 | cout << " Adaptation time: "<< t/(double) CLOCKS_PER_SEC << " secs"<< endl; 84 | 85 | 86 | auto ix = 186; 87 | cout << "exact: " << gpx->get(ix) << " " << gpy->get(ix) << " 0 " << endl; 88 | auto res = grid->listCell[ix]->grad(p).eval(p); 89 | cout << "method: " << res << endl; 90 | 91 | t = clock(); 92 | for (auto i = 0; i < grid->listCell.size(); ++i) { 93 | auto c = grid->listCell[i]; 94 | auto gp = c->grad(p).eval(p); 95 | cgpx->set(i, gp[0]); 96 | cgpy->set(i, gp[1]); 97 | // w->set(c->id, gp[2]); 98 | if (i == ix) cout << "cgps: " << gp << endl; 99 | } 100 | t = clock() - t; 101 | cout << " Cell grad time: "<< t/(double) CLOCKS_PER_SEC << " secs"<< endl; 102 | 103 | 104 | t = clock(); 105 | grid->lockBC(p); 106 | for (auto i = 0; i < grid->listFace.size(); ++i) { 107 | auto f = grid->listFace[i]; 108 | auto gp = f->grad(p).eval(p); 109 | fgpx->set(i, gp[0]); fgpy->set(i, gp[1]); 110 | } 111 | t = clock() - t; 112 | cout << " Face grad time: "<< t/(double) CLOCKS_PER_SEC << " secs"<< endl; 113 | 114 | 115 | grid->writeFace("face.vtk"); 116 | 117 | 118 | cout << " -------------------------- " << endl; 119 | t=clock(); 120 | // for (auto i = 0; i < grid->listFace.size(); ++i) { 121 | // auto f = grid->listFace[i]; 122 | // auto pf = f->phi(p).eval(p); 123 | // auto flux = pf*f->vol(); 124 | // if (f->next >= 0) { 125 | // u->data[f->next] -= flux[0]; 126 | // v->data[f->next] -= flux[1]; 127 | // w->data[f->next] -= flux[2]; 128 | // if (f->next == ix) { 129 | // cout << " Face: " << f->id << " orient: " << f->orient << " next: " << f->next; 130 | // cout << " prev: " << f->prev << " flux " << -flux << endl; 131 | // } 132 | // } 133 | // if (f->prev >= 0) { 134 | // u->data[f->prev] += flux[0]; 135 | // v->data[f->prev] += flux[1]; 136 | // w->data[f->prev] += flux[2]; 137 | // if (f->prev == ix) { 138 | // cout << " Face: " << f->id << " orient: " << f->orient << " next: " << f->next; 139 | // cout << " prev: " << f->prev << " flux " << flux << endl; 140 | // } 141 | // } 142 | // } 143 | 144 | for (auto i = 0; i listCell.size(); ++i) { 145 | auto c = grid->listCell[i]; 146 | double phix=0, phiy=0, sx=0, sy=0; 147 | for (auto j :c->face) { 148 | auto f = grid->listFace[j]; 149 | auto area = f->vol().abs(); 150 | if (f->orient == 1) { 151 | phix += (f->grad(p).eval(p).x())*area; 152 | sx += area; 153 | } else if(f->orient == 0) { 154 | phiy += (f->grad(p).eval(p).y())*area; 155 | sy += area; 156 | } 157 | } 158 | u->data[i] = phix/sx; 159 | v->data[i] = phiy/sy; 160 | } 161 | t = clock() - t; 162 | cout << " thru average time: "<< t/(double) CLOCKS_PER_SEC << " secs"<< endl; 163 | 164 | 165 | cout << "cool: " << u->data[ix] << " " << v->data[ix] << " " << w->data[ix] << endl; 166 | grid->unlockBC(); 167 | 168 | 169 | // calculate the gradient of p; 170 | // write face, node based and cell based to a file; 171 | 172 | 173 | 174 | // adapt grid randomly and redo above; 175 | 176 | flname = "cav"+std::to_string(filecnt++)+".vtk"; 177 | myfile.open(flname); 178 | myfile << grid << endl; 179 | myfile.close(); 180 | 181 | 182 | delete(grid); 183 | 184 | return 0; 185 | } 186 | -------------------------------------------------------------------------------- /example/unclassified/main1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | *************************************************************************** 3 | * Copyright (C) 2015, Eray Uzgoren * 4 | * * 5 | * This program is free software: you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License as published by * 7 | * the Free Software Foundation, either version 3 of the License, or * 8 | * (at your option) any later version. * 9 | * * 10 | * This program is distributed in the hope that it will be useful, * 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 | * GNU General Public License for more details. * 14 | * * 15 | * You should have received a copy of the GNU General Public License * 16 | * along with this program. If not, see . * 17 | *************************************************************************** 18 | */ 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | 29 | 30 | int main() { 31 | auto dt = 0.5; 32 | auto t = clock(); 33 | //Block2* grid = new Block2({0, 0, 0}, {0.5, 0.3, 0}, 50, 30); 34 | Block2* grid = new Block2({0, 0, 0}, {0.02, 0.02, 0}, 5, 5); 35 | grid->setDt(dt); 36 | double time= 0; double endTime = 10; //dt*50; 37 | 38 | // Field variables; 39 | double rho=10000, cp=1000, k=10; 40 | 41 | // auto y = grid->getCoord(1); 42 | // for (auto i = 0; i < grid->listCell.size(); ++i) { 43 | // if (y[i] < 0.05) { 44 | // grid->listCell[i]->adapt[1] = 2; 45 | // } else if (y[i] < 0.1) { 46 | // grid->listCell[i]->adapt[1] = 1; 47 | // } 48 | // } 49 | 50 | // grid->adaptCriteria(); 51 | 52 | // cout<< "pt: 1430 dir 0 and 1" << endl; // west 53 | // grid->debugFace(1430, 0); grid->debugFace(1430, 1); 54 | // //cout<< "pt: 1431 dir 0 and 1" << endl; // internal 55 | // //grid->debugFace(1431, 1); 56 | // cout<< "pt: 25 dir 0 and 1" << endl; // south 57 | // grid->debugFace(25, 0); grid->debugFace(25, 1); 58 | // cout<< "pt: 1480 dir 0 and 1" << endl; // east 59 | // grid->debugFace(1480, 0); grid->debugFace(1480, 1); 60 | // // cout<< "pt: 3302 dir 0 and 1" << endl; // problem 61 | // // grid->debugFace(3302, 0); grid->debugFace(3302, 1); 62 | // // cout<< "pt: 3301 dir 0 and 1" << endl; // problem 63 | // // grid->debugFace(3301, 0); grid->debugFace(3301, 1); 64 | // //cout<< "pt: 2760 dir 0 and 1" << endl; // problem 65 | // //grid->debugFace(2760, 0); grid->debugFace(2760, 1); 66 | 67 | grid->addVar({"T", "p"}); 68 | 69 | auto u = grid->getVar("u"); 70 | auto v = grid->getVar("v"); 71 | auto w = grid->getVar("w"); 72 | auto p = grid->getVar("p"); 73 | auto T = grid->getVar("T"); 74 | 75 | T->set(250); 76 | 77 | // T->setBC("west", "val", 250); 78 | T->setBC("west", "val", 0); 79 | // T->setBC("north", "grad", 250*20, -250); 80 | T->setBC("south", "grad", -250*20, 250); 81 | // T->setBC("north", "grad", 0); 82 | // T->setBC("south", "grad", 0); 83 | T->itmax = 10; 84 | 85 | u->set(0.01); 86 | v->set(0.03); 87 | 88 | 89 | // if (auto u = grid->getVar("u")) { 90 | // u->set({"x", "y"}, "sqrt(x^2 + y^2)*sin(atan2(y-0.5, x-0.5))"); 91 | // } 92 | 93 | // if (auto v = grid->getVar("v")) { 94 | // v->set({"x", "y"}, "-sqrt(x^2 + y^2)*cos(atan2(y-0.5, x-0.5))"); 95 | // } 96 | 97 | 98 | // for (auto c: grid->listCell) {c->adapt[0] = 1; c->adapt[1] = 1;} 99 | // grid->refine(); 100 | while (time < endTime) { 101 | cout << setiosflags(ios::fixed) << setprecision(2); 102 | cout << "------------- Processing TIME = "<< time << " ------------------"<getVel(); 105 | // cout << grid->valDiv(vel) << endl; 106 | 107 | 108 | // if (ibmGrid) { 109 | // vel2 = grid->passTo(ibmGrid, vel); 110 | // ibmGrid->move(vel2, 'RK4'); 111 | // surfTen = ibmGrid->getNorm(); 112 | // force = ibmGrid->passTo(grid, surfTen); 113 | // } else { 114 | // force = 0; 115 | // } 116 | // auto axb = grid->laplace(1.0); 117 | // cout << axb.A << endl; 118 | // cout << axb.b << endl; 119 | // u->solve( 120 | // grid->ddt(rho) 121 | // + grid->div(rho*vel, {0, 1.5, -0.5}) 122 | // grid->laplace(1.0) //rho/mu), {0.5, 0.5}) 123 | // + grid->source(0, gradX(p) - rho*aVec + force.x()) 124 | // ); 125 | 126 | // v->solve(grid->ddt(rho) 127 | // + (grid->div(rho*vel), {0, 1.5, -0.5}) 128 | // - grid->laplace(rho/mu, {0.5, 0.5}) 129 | // + matSource(0, gradY(p) - rho*aVec + force.y()) ); 130 | 131 | // if (periodic) grid->adapt(); 132 | 133 | // p->solve(grid->laplace(1./rho) - grid->div(rho)); 134 | 135 | // u->update(p); 136 | // v->update(p); 137 | 138 | grid->lockBC(T); 139 | // T->solver="CG"; 140 | T->solve( 141 | grid->ddt(1.0) 142 | + grid->div(vel, 1.0) 143 | - grid->laplace(k/cp/rho) 144 | - grid->source(0, 10000/cp/rho) 145 | ); 146 | grid->unlockBC(); 147 | time += grid->dt; 148 | grid->setDt(dt); 149 | // cin.ignore().get(); 150 | cout << "---------------------------------------------------"<adaptCriteria(); 153 | 154 | ofstream myfile; 155 | myfile.open("reg.vtk"); 156 | myfile << grid << endl; 157 | myfile.close(); 158 | 159 | //grid->writeFace(); 160 | 161 | grid->writeFace(); 162 | 163 | delete(grid); 164 | 165 | 166 | // LinSys ls(6); 167 | // VecX x(6); x.uncompress(); 168 | // ls.A = { 169 | // { 2, -1, 0, 0, 0, 0}, 170 | // {-1, 2, -1, 0, 0, 0}, 171 | // { 0, -1, 2, -1, 0, 0}, 172 | // { 0, 0, -1, 2, -1, 0}, 173 | // { 0, 0, 0, -1, 2, -1}, 174 | // { 0, 0, 0, 0, -1, 2} 175 | // }; 176 | // // ls.A[5] = 177 | // // //vel.A[5][4] = -0.5; 178 | 179 | // ls.A.info(); 180 | // ls.b.info(); 181 | 182 | // x = {1, -2, 3, -4, 9, 3}; 183 | // cout << ls.A << endl; 184 | // cout << ls.b << endl; 185 | // cout << x<. * 17 | *************************************************************************** 18 | */ 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | 29 | 30 | int main() { 31 | 32 | //CAVITY FLOW 33 | auto dt = 0.1; 34 | auto t = clock(); 35 | 36 | // GRID 37 | Block2* grid = new Block2({0, 0, 0}, {10, 1, 0}, 20, 20); 38 | grid->levelHighBound[0] = 0; 39 | grid->levelHighBound[1] = 0; 40 | // grid->adaptCriteria(); 41 | 42 | // CONST variables; 43 | double rho = 1; double mu = 0.01; 44 | 45 | // FIELD variables; 46 | grid->addVar({"p", "vor"}); 47 | // grid->addVar({"ustar", "vstar"}); 48 | 49 | // initial and bc values; 50 | auto u = grid->getVar("u"); 51 | u->set(0.0); 52 | // u->setBC("west", "val", 0); u->setBC("east", "val", 0); 53 | u->setBC("west", "val", 1.0); u->setBC("east", "grad", 0); 54 | u->setBC("south", "val", 0); u->setBC("north", "val", 0); 55 | auto v = grid->getVar("v"); 56 | v->set(0.0); 57 | v->setBC("west", "val", 0); v->setBC("east", "grad", 0); 58 | v->setBC("south", "val", 0); v->setBC("north", "val", 0); 59 | 60 | auto p = grid->getVar("p"); 61 | p->set(0.0); 62 | p->setBC("south", "grad", 0); 63 | p->setBC("west", "grad", 0); 64 | p->setBC("north", "grad", 0); 65 | p->setBC("east", "val", 0); 66 | 67 | auto vor = grid->getVar("vor"); 68 | // auto ustar = grid->getVar("ustar"); 69 | // ustar->set(0.0); 70 | // ustar->setBC("west", "val", 0); ustar->setBC("east", "val", 0); 71 | // ustar->setBC("south", "val", 0); ustar->setBC("north", "val", 1); 72 | 73 | // auto vstar = grid->getVar("vstar"); 74 | // vstar->set(0.0); 75 | // vstar->setBC("west", "val", 0); vstar->setBC("east", "val", 0); 76 | // vstar->setBC("south", "val", 0); vstar->setBC("north", "val", 0); 77 | 78 | // solver behavior 79 | u->solver = "Gauss"; u->itmax = 20; u->tol = 1e-4; 80 | v->solver = "Gauss"; v->itmax = 20; v->tol = 1e-4; 81 | p->solver = "BiCGSTAB"; p->itmax = 10000; p->tol = 1e-6; 82 | 83 | auto gp = grid->valGrad(p); 84 | 85 | 86 | // Time control 87 | grid->setDt(dt); 88 | double time= 0; double endTime = 30; //dt*50; 89 | int filecnt = 0; int it = 0, writeInt = 4; 90 | ofstream myfile; 91 | while (time < endTime) { 92 | cout << setiosflags(ios::scientific) << setprecision(2); 93 | cout << "------------- Processing TIME = "<< time << " ------------------"<getVel(); 96 | auto diverge = grid->valDiv(vel); 97 | cout << "+ div=("<valDiv(vel) << endl; 101 | //if (it == 1 || (it % writeInt == 0)) { 102 | // grid->solBasedAdapt2(grid->getError(u)); 103 | // grid->solBasedAdapt2(grid->getError(v)); 104 | // } 105 | 106 | vor->set(grid->valGrad(v).comp(0) - grid->valGrad(u).comp(1)); 107 | auto gu = grid->valGrad(u); 108 | auto gv = grid->valGrad(v); 109 | 110 | grid->lockBC(u); 111 | u->solve( 112 | grid->ddt(rho) 113 | + grid->div(vel, rho) 114 | - grid->laplace(mu) 115 | // + grid->source(0, gp.comp(0)) // gradX is not defined; 116 | ); 117 | grid->unlockBC(); 118 | 119 | grid->lockBC(v); 120 | v->solve( 121 | grid->ddt(rho) 122 | + grid->div(vel, rho) 123 | - grid->laplace(mu) 124 | // + grid->source(0, gp.comp(1)) 125 | ); 126 | grid->unlockBC(); 127 | 128 | // grid->solBasedAdapt(vor->data); 129 | // grid->solBasedAdapt(gp); 130 | //if ((it == 1) || (it % writeInt) == 0) { 131 | //grid->solBasedAdapt(gu, 1.0); 132 | // grid->solBasedAdapt(grid->valGrad(vor), 0.4); 133 | 134 | // for (auto i = 0; i < grid->listCell.size(); ++i) 135 | // for (auto j = 0; j< 3; ++j) 136 | // grid->listCell[i]->checkNgbrLevel(j); 137 | //grid->refine2(); 138 | 139 | if (it == 1 || (it % writeInt == 0)) { 140 | // grid->solBasedAdapt(vor->data, 0.9); 141 | // grid->solBasedAdapt2(grid->getError(vor), 0.0001, 0.005); 142 | grid->solBasedAdapt2(grid->getError(u), 0.00005, 0.005); 143 | // grid->solBasedAdapt2(grid->getError(v), 0.00001, 0.001); 144 | grid->adapt(); 145 | } 146 | 147 | // if (periodic) grid->adapt(); 148 | auto velstar = grid->getVel(); 149 | 150 | auto vsdiv = grid->valDiv(velstar); 151 | cout << "+ div=("<valDiv(velstar) << endl; 153 | //cin.ignore().get(); 154 | 155 | grid->lockBC(p); 156 | p->solve(grid->laplace(1.0/rho) - grid->source(0, grid->valDiv(velstar)/dt)); 157 | grid->unlockBC(); 158 | 159 | // double pref = p->get(0); 160 | // for (auto i = 0; i < grid->listCell.size(); ++i) { 161 | // p->data[i] = p->data[i] - pref; 162 | // } 163 | 164 | // gp = grid->valGrad(p); 165 | // //cout << gp <set(velstar.comp(0)-dt/rho*gp.comp(0)); // 167 | // v->set(velstar.comp(1)-dt/rho*gp.comp(1)); // 168 | grid->correctVel(dt/rho); 169 | 170 | grid->setDt(dt); 171 | time += grid->dt; 172 | 173 | //grid->solBasedAdapt(vor->data); 174 | // grid->solBasedAdapt(gv); 175 | //grid->refine2(); 176 | if ( ( it++ % writeInt) == 0) { 177 | //grid->writeFace("face"+std::to_string(filecnt)+".vtk"); 178 | std::string flname="cav"+std::to_string(filecnt++)+".vtk"; 179 | myfile.open(flname); 180 | myfile << grid << endl; 181 | myfile.close(); 182 | } 183 | 184 | cout << "---------------------------------------------------"<. * 17 | *************************************************************************** 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | int main() { 30 | auto t = clock(); 31 | //Block2* grid = new Block2({0, 0, 0}, {0.5, 0.3, 0}, 50, 30); 32 | Block2* grid = new Block2({0, 0, 0}, {1, 1, 0}, 10, 10); 33 | 34 | //grid->adaptCriteria(); 35 | grid->addVar({"T"}); 36 | auto T = grid->getVar("T"); 37 | 38 | T->set(0); 39 | double pi = 4.0*atan(1); 40 | 41 | for (auto j = 0; j < 5; ++j) { 42 | for (auto i = 0; i < grid->listCell.size(); ++i) { 43 | auto x = grid->listCell[i]->getCoord(); // - Vec3(0.5, 0.5); 44 | auto r = (grid->listCell[i]->getCoord() - Vec3(0.5, 0.5)).abs(); 45 | 46 | T->set(i, 1.0/(1.0 + exp(-2.0*80*(0.15-r)))); 47 | } 48 | // auto gt = grid->valGrad(T); 49 | //grid->solBasedAdapt(gt); 50 | grid->solBasedAdapt2(grid->getError(T)); 51 | grid->adapt(); 52 | } 53 | 54 | 55 | grid->addVar({"dx", "dy"}); 56 | auto dx = grid->getVar("dx"); 57 | auto dy = grid->getVar("dy"); 58 | 59 | for (auto c: grid->listCell) { 60 | if ((c->getCoord() - Vec3(0.5, 0.5)).abs() < 0.14) { 61 | for (auto i = 0; i < c->node.size() ; ++i) 62 | grid->listVertex[c->node[i]]->cell[(i+2)%4] = -1; 63 | 64 | c->isAlive = false; 65 | } 66 | } 67 | 68 | grid->cleanGrid(); 69 | grid->checkGrid(); 70 | grid->setCurrentLevels(); 71 | grid->makeFace(); 72 | 73 | for (auto f: grid->listFace) { 74 | auto fr = f->getCoord(); 75 | auto x = fr.x(); 76 | auto y = fr.y(); 77 | auto theta = atan2(y-0.5, x-0.5); 78 | auto r = 0.15; 79 | 80 | if (f->prev < 0) { 81 | 82 | dx->listBC.push_back(shared_ptr(new Boundary())); 83 | if (abs((fr-Vec3(0.5,0.5)).abs()-r) < 0.1) { 84 | (*(dx->listBC.rbegin()))->setBC(0, (r*cos(theta)+0.5)); 85 | } else { 86 | (*(dx->listBC.rbegin()))->setBC(0, x); //(r*cos(theta)+0.5)); 87 | } 88 | f->prev = -(dx->listBC.size()); 89 | 90 | dy->listBC.push_back(shared_ptr(new Boundary())); 91 | if (abs((fr-Vec3(0.5,0.5)).abs()-r) < 0.1) { 92 | (*(dy->listBC.rbegin()))->setBC(0, (r*sin(theta)+0.5)); 93 | } else { 94 | (*(dy->listBC.rbegin()))->setBC(0, y); //(r*sin(theta)+0.5)); 95 | } 96 | f->prev = -(dy->listBC.size()); 97 | 98 | } else if (f->next < 0) { 99 | dx->listBC.push_back(shared_ptr(new Boundary())); 100 | if (abs((fr-Vec3(0.5,0.5)).abs()-r) < 0.1) { 101 | (*(dx->listBC.rbegin()))->setBC(0, (r*cos(theta)+0.5)); 102 | } else { 103 | (*(dx->listBC.rbegin()))->setBC(0, x); //(r*cos(theta)+0.5)); 104 | } 105 | f->next = -(dx->listBC.size()); 106 | 107 | dy->listBC.push_back(shared_ptr(new Boundary())); 108 | if (abs((fr-Vec3(0.5,0.5)).abs()-r) < 0.1) { 109 | (*(dy->listBC.rbegin()))->setBC(0, (r*sin(theta)+0.5)); 110 | } else { 111 | (*(dy->listBC.rbegin()))->setBC(0, y); //(r*sin(theta)+0.5)); 112 | } 113 | f->next = -(dy->listBC.size()); 114 | } 115 | 116 | } 117 | 118 | dx->set(0.0); 119 | // dx->setBC("north", "val", 0); 120 | // dx->setBC("south", "val", 0); 121 | dy->set(0.0); 122 | // dy->setBC("east", "val", 0); 123 | // dy->setBC("west", "val", 0); 124 | dx->solver = "CG"; 125 | dy->solver = "CG"; 126 | dx->itmax = 1000; 127 | dx->tol = 1e-6; 128 | dy->itmax = 1000; 129 | dy->tol = 1e-6; 130 | 131 | 132 | grid->lockBC(dx); 133 | dx->solve( 134 | grid->laplace(1) 135 | ); 136 | grid->unlockBC(); 137 | 138 | grid->lockBC(dy); 139 | dy->solve( 140 | grid->laplace(1) 141 | ); 142 | grid->unlockBC(); 143 | 144 | // update vertex 145 | auto icount = 0; 146 | for (auto v: grid->listVertex) { 147 | double sumx = 0, sumy = 0; double icnt = 0; double jcnt = 0; 148 | for (auto c : v->cell) { 149 | if (c >=0 ) { 150 | sumx += dx->data[c]; ++icnt; 151 | sumy += dy->data[c]; ++jcnt; 152 | } 153 | } 154 | v->data[0] = sumx/icnt; 155 | v->data[1] = sumy/jcnt; 156 | auto thet = atan2(v->data[1]-0.5, v->data[0]-0.5); 157 | for (auto ic = 0; ic < 4; ++ic) { 158 | if (v->cell[ic] < 0) { 159 | if (abs((v->getCoord()-Vec3(0.5, 0.5)).abs()-0.15)< 0.2) { 160 | v->data[0] = 0.5 + 0.15*cos(thet); 161 | v->data[1] = 0.5 + 0.15*sin(thet); 162 | break; 163 | } 164 | } 165 | } 166 | } 167 | 168 | // update hanging nodes; 169 | 170 | for (auto v: grid->listVertex) { 171 | for (auto iv = 0; iv < 4; ++iv) { 172 | if (v->cell[iv] >= 0 && v->cell[iv] == v->cell[(iv+1)%4]) { 173 | auto vb = grid->listCell[v->cell[iv]]->getVertex((iv+3)%4); 174 | auto vn = grid->listCell[v->cell[iv]]->getVertex((iv+2)%4); 175 | if (vn && vb) { 176 | v->set(0.5*(**vn + **vb)); 177 | } 178 | } 179 | } 180 | } 181 | 182 | grid->listVar.clear(); 183 | 184 | grid->makeFace(); 185 | 186 | 187 | grid->addVar({"T"}); 188 | T = grid->getVar("T"); 189 | T->solver = "CG"; 190 | T->itmax =1000; 191 | T->tol = 1e-6; 192 | 193 | T->setBC("east", "val", 100); 194 | T->setBC("west", "val", 160); 195 | T->setBC("north", "grad", 250*20, -250); 196 | 197 | for (auto itt = 0; itt< 3; ++itt) { 198 | 199 | grid->lockBC(T); 200 | T->solve(grid->laplace(2.0) + grid->source(0,1000)); 201 | grid->unlockBC(); 202 | 203 | // grid->lockBC(dx); 204 | // dx->solve( 205 | // grid->laplace(1) 206 | // // - grid->source(0, 10000) 207 | // ); 208 | // grid->unlockBC(); 209 | 210 | grid->writeVTK("reg"); 211 | 212 | grid->solBasedAdapt2(grid->getError(T)); 213 | grid->adapt(); 214 | 215 | } 216 | grid->writeVTK("reg"); 217 | 218 | // ofstream myfile; 219 | // myfile.open("reg.vtk"); 220 | // myfile << grid << endl; 221 | // myfile.close(); 222 | 223 | 224 | delete(grid); 225 | 226 | return 0; 227 | } 228 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #girdap 2 | 3 | Please refer to https://uzgoren.github.io/girdap for more information. 4 | 5 | This project's aim is to develop object-oriented c++ libraries for solving conservation equations on a self-managed grid. 6 | 7 | This project is still in progress. Please give us feedback for the bugs you encountered or new bright ideas you may think of. 8 | 9 | ###REQUIREMENTs 10 | 11 | C++ compiler that accepts C++11 standards 12 | 13 | ###COMPILE 14 | 15 | An executable installer is still being prepared, however compiling from the source is very easy and straightforward. Installation guidelines for Linux and MacOS are provided and tested. Even though Girdap is capable of running on Windows, the installation requires different tools and guide for the installation will be announced later. 16 | 17 | ####_Linux Operating Systems and MacOS_ 18 |
  • The First thing you need to do is make sure that you installed cmake and gcc compiler. 19 |
  • Download the source codes (it should be in *.zip format). 20 |
  • Extract into a folder you want. i.e. "unzip girdap-master.zip -d /home/username/Documents/girdap" 21 |
  • Get into the folder you created and run 'cmake' code. 22 |
  • After cmake code type 'make' to compile the codes. 23 |
  • Girdap is ready to use. One important thing is while you are using Girdap, you do not need to run 'cmake' code again and again. 'make' is all you need to type. 24 | 25 | ###FAQ 26 | ####_What is girdap?_ 27 | _girdap_ provides building blocks for numerical simulations of complex transport equations. Tools are built around a grid management platform connected to finite volume method based differential operators. girdap’s primary goals are (1) _flexibility_ and (2) _accuracy_. 28 | 29 | Flexible tools allow researchers to develop new numerical algorithms and educators to teach students existing algorithms. Tools provided aim to shift programming focus more on physics and numerical method to avoid time consuming programming details. 30 | 31 | The accuracy is handled by automated grid refinement and coarsening based on the solution field. 32 | 33 | _girdap_ does not target audiences who would like to get immediate results for an engineering project. It involves a numerical algorithm development phase. Those who would like to skip such a development can refer to a commercial CFD/multiphysics software. 34 | 35 | ####_Isn’t this done before?_ 36 | Similar projects do exist. OpenFOAM is one example; and another one is FEniCS. Please check them out. They are really good projects. girdap just offers another flavor. 37 | 38 | ####_What does girdap mean?_ 39 | _girdap_ is not an acronym. It means whirlpool in Turkish. 40 | 41 | ####_What operators are included?_ 42 | Time derivative, divergence, gradient, Laplacian, and source terms can be defined for a differential equation. 43 | 44 | ####_How can I install/use girdap?_ 45 | You can retrieve the source code (written in c++ following c++11 standards) at github. You can see examples of main_*.cpp files under src directory so that you can compile and use it in the way you like. Use the script provided in the main directory to compile. Note that our focus is mainly on the development of girdap’s skeleton rather than its transportability so you may experience problems while compiling your first application. This is of course going to change with its first release. 46 | 47 | ####_Can you provide an example?_ 48 | A typical numerical simulation involve the following steps;
      49 |
    1. Create a new grid 50 |
    2. Declare your own field variables (defined on cell centers) 51 |
    3. State initial and boundary conditions for each variable 52 |
    4. Start a time loop
        53 |
      1. Solve for var_1 governed by a partial differential equation 54 |
      2. Solve for var_2 governed by algebraic equations 55 |
      3. Grid adaptation/movement 56 |
      4. Write an output to screen/file
      57 |
    5. Exit
    58 | 59 | _girdap_ provides tools for each step above. In addition, you can have as many grids and as many variables together governed by different set of equations; and interacting with each other. Such a flexibility allows developing various algorithms for fluid-structure interactions and multiphase flows. 60 | 61 | Furthermore, through a driver code (as main.cpp); one can add a custom source term or decide on how to linearize non-linear equations; or how to manage inner and outer loops; how to handle adaptation and many more. It is also possible to link 1D/2D domain with a 3D domain using interpolators between grids. Cell movements can be controlled as well. 62 | 63 | Boundary conditions can be defined as a linear function for Dirichlet and Neumann type conditions. This flexibility allows convective heat transfer coefficient to be specified at the boundaries. 64 | 65 | Initial conditions can be defined easily through cell iterators on grid. 66 | 67 | So a thin long rod interacting with 3D incompressible flow can be declared as follows: 68 |
    1. Create grid1 and grid2 69 |
    2. Declare velocity, pressure and temperature for grid1 (3D); temperature for grid2 (1D) 70 |
    3. State initial and boundary conditions 71 |
    4. Start a time loop
        72 |
      1. Link temperature field of grid1 to grid2 as a boundary condition 73 |
      2. Solve heat diffusion equation on grid 2 74 |
      3. Adapt grid2 based on its temperature field 75 |
      4. Solve flow velocity on grid1 76 |
      5. Adapt grid1 based on its velocity field 77 |
      6. Solve pressure equation on grid1 78 |
      7. Correct flow velocity on grid1 79 |
      8. Link temperature field of grid2 to grid1 as a dummy variable 80 |
      9. Solve energy equation with a source term (dummy var) on grid1 81 |
      10. Write an output to screen/file
      82 |
    5. Exit
    83 | 84 | For those who are familiar, this is quite similar to scripting in Matlab. 85 | 86 | ####_What is grid adaptation?_ 87 | Grid adaptation is used in problem with multiple length scales; so that computational time is used wisely. Regions with less interaction handled with coarse resolution; and regions influence the field are handled with fine resolution. So automated grid handling is the key for accuracy and speed. 88 | 89 | ####_How is grid adaptation handled?_ 90 | It relies on splitting a cell into two and merging two neighboring cells. This leads to anisotropic grid refinement. Grid refinement is based on error estimation (before it is available). It is widely reported that indicators based on gradients do not produce quality mesh; and hence we use other indicators for refinement and coarsening. 91 | 92 | At the moment, grid focuses on quad cells. While underlying structure for hexa, tri and tetra cells are available, automated adaptive grid refinement and coarsening is available for quad cells. These overall form the envelope of girdap’s skeleton. 93 | 94 | ####_What about parallel computing, MPI, OpenMP?_ 95 | It is not yet considered; but it is within our future plans. 96 | 97 | ####ACKNOWLEDGEMENT 98 | This work is part of a research project supported by a Marie Curie International Reintegration Grant within the 7th European Community Framework Programme. 99 | 100 | 112 | 113 | -------------------------------------------------------------------------------- /include/linSolve/MatY.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | *************************************************************************** 3 | * Copyright (C) 2015, Eray Uzgoren * 4 | * * 5 | * This program is free software: you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License as published by * 7 | * the Free Software Foundation, either version 3 of the License, or * 8 | * (at your option) any later version. * 9 | * * 10 | * This program is distributed in the hope that it will be useful, * 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 | * GNU General Public License for more details. * 14 | * * 15 | * You should have received a copy of the GNU General Public License * 16 | * along with this program. If not, see . * 17 | *************************************************************************** 18 | */ 19 | #ifndef MATY 20 | #define MATY 21 | 22 | //------------------------------------------- 23 | // Matrix storage scheme 24 | // Defines: basic matrix operations (not all) 25 | // Vec*Matrix addition 26 | //------------------------------------------- 27 | 28 | #include 29 | 30 | class Triplet { 31 | public: 32 | int_8 row; 33 | int_8 col; 34 | double val; 35 | 36 | Triplet(int_8 i, int_8 j, double a) { row = i; col = j; val = a;} 37 | 38 | // Operators 39 | // sum; 40 | }; 41 | 42 | class Triplets { 43 | public: 44 | vector data; 45 | 46 | Triplets() {}; 47 | 48 | Triplets& operator+=(const initializer_list a) { 49 | data.emplace_back(Triplet((int_8)*(a.begin()), (int_8)*(a.begin()+1), 50 | *(a.begin()+2))); 51 | return *this; 52 | } 53 | 54 | Triplets& operator+=(const initializer_list > a) { 55 | for (auto it = a.begin(); it < a.end(); ++it) 56 | *this += *it; 57 | return *this; 58 | } 59 | 60 | Triplets& operator+=(Triplets &b) { 61 | this->data.reserve(this->data.size() + b.data.size()); 62 | std::move(b.data.begin(), b.data.end(), std::back_inserter(this->data)); 63 | b.data.clear(); 64 | return *this; 65 | } 66 | 67 | Triplets& operator+(vector &b) { 68 | this->data.reserve(this->data.size() + b.size()); 69 | std::move(b.begin(), b.end(), std::back_inserter(this->data)); 70 | b.clear(); 71 | return *this; 72 | } 73 | 74 | Triplets& operator+(Triplets &b) { 75 | *this = *this + b.data; 76 | return *this; 77 | } 78 | 79 | Triplets& operator*(double a) { 80 | for (auto c=data.begin(); c < data.end(); ++c) 81 | c->val = a*c->val; 82 | return *this; 83 | } 84 | 85 | friend Triplets& operator*(double a, Triplets& b) { 86 | return b*a; 87 | } 88 | 89 | // friend Triplets& operator*(double a, vector< 90 | 91 | Triplets& operator/(double a) { 92 | return *this*(1/a); 93 | } 94 | 95 | friend Triplets& operator/(double a, Triplets &b) { 96 | return b*(1.0/a); 97 | } 98 | 99 | Triplets& operator-() { 100 | return *this*(-1); 101 | } 102 | 103 | Triplets& operator-(Triplets &b) { 104 | return *this + (-b); 105 | } 106 | 107 | double& operator()(int_8 i, int_8 j) { 108 | data.emplace_back(Triplet(i, j, 0)); 109 | return (data.rbegin()->val); 110 | } 111 | }; 112 | 113 | 114 | class Sparse { 115 | public: 116 | vector aij; 117 | vector val; 118 | int_8 rank; 119 | 120 | VecX operator*(VecX &right) { 121 | VecX tmp(right.size()); 122 | for (auto i = 0; i < tmp.size(); ++i) { 123 | tmp[i] = val[i]*right[i]; 124 | // cout << i << " " << aij[i] << "-" << aij[i+1]-1 << endl; 125 | for (auto j = aij[i]; j < aij[i+1]; ++j) { 126 | auto col = aij[j]; 127 | tmp[i] += val[j]*right[col]; 128 | } 129 | } 130 | return tmp; 131 | } 132 | 133 | }; 134 | 135 | 136 | class triLinSys { 137 | private: 138 | int_8 N; 139 | double tol; 140 | int itmax; 141 | 142 | public: 143 | Triplets A; 144 | Sparse S; 145 | VecX b; 146 | VecX *x; 147 | VecX *error; 148 | 149 | double err; 150 | int it; 151 | 152 | triLinSys() {}; // setLimits(); S.rank = 0;}; 153 | triLinSys(int_8 const &N) { S.rank = N; b.resize(N); setLimits(); }; 154 | 155 | 156 | void setLimits(double t=1e-6, unsigned int imax = 1000) { 157 | if (t>0) tol = t; 158 | if (imax>0) itmax = imax; 159 | } 160 | 161 | 162 | void setMat(Triplets &vtr) { 163 | if (vtr.data.empty()) { 164 | if (S.rank > 0) { 165 | S.aij.assign(S.rank+1, S.rank+1); 166 | S.val.assign(S.rank+1, 0); 167 | } 168 | return; 169 | } 170 | // first sort a (1st col then row); 171 | sort(vtr.data.begin(), vtr.data.end(), 172 | [](const Triplet & a, const Triplet & b) -> bool 173 | { 174 | return (a.row < b.row) || ((a.row == b.row) && (a.col < b.col)); 175 | }); 176 | S.rank = max(S.rank, vtr.data.rbegin()->row + 1); 177 | 178 | //cout << " ------------------ " <row; 191 | 192 | for (auto c : vtr.data) { 193 | // c.row == c.col 194 | if (c.row == c.col) { 195 | S.val[c.row] += c.val; 196 | continue; 197 | } 198 | if (c.row != oldrow) { 199 | S.aij[c.row+1] = S.aij[c.row]; 200 | oldrow = c.row; 201 | } 202 | 203 | // check if col exist at the last location 204 | if (*(S.aij.rbegin()) == c.col) { 205 | *(S.val.rbegin()) += c.val; 206 | continue; 207 | } 208 | 209 | S.aij.emplace_back(c.col); 210 | S.val.emplace_back(c.val); 211 | S.aij[c.row+1]++; 212 | 213 | } 214 | vtr.data.clear(); 215 | //cout << " Size: " << A.aij.size() << " " << A.val.size() < r(S.rank), r0(S.rank), p(S.rank); 225 | VecX t(S.rank), v(S.rank), s(S.rank); 226 | 227 | err = 0; 228 | //check if t is initialized as zero; 229 | //cout<< t << endl; 230 | 231 | *error = (b - S*(*x)); 232 | // cout << error->abs() << endl; 233 | if (error->abs() < tol) { err = tol; it = 0; return; } 234 | r0 = *error; 235 | rho = 1; alpha = 1; omega = 1; 236 | for (; iter < itmax; ++iter) { 237 | rho_new = r0*(*error); 238 | beta = (rho_new/rho)*(alpha/omega); 239 | rho = rho_new; 240 | p = (*error) + beta*(p - omega*v); 241 | v = S*p; 242 | //cout << " r0v: " << r0*v << " p: " << p << endl; 243 | alpha = rho/(r0*v); 244 | s = *error - alpha*v; 245 | t = S*s; 246 | //cout << " t: " << t << " s: " << s << endl; 247 | omega = (t*s)/(t*t); 248 | (*x) = (*x) + alpha*p + omega*s; 249 | *error = s - omega*t; 250 | err = sqrt(*error*(*error)); 251 | if (err < tol) break; 252 | //if (iter%50 == 0) 253 | //cout << "BiCGstab: " << iter << ": "<< log10(err) << endl; 254 | } 255 | it = iter; 256 | //err = sqrt(rsnew); 257 | //cout << "BiCGstab: " << iter << ": " << log10(err) << " DONE!" << endl; 258 | } 259 | 260 | triLinSys& operator+(triLinSys &T) { 261 | A += T.A; 262 | return *this; 263 | } 264 | 265 | triLinSys& operator-(triLinSys &T) { 266 | T.A = -T.A; 267 | A += T.A; 268 | return *this; 269 | } 270 | 271 | 272 | 273 | }; 274 | 275 | 276 | 277 | 278 | #endif 279 | -------------------------------------------------------------------------------- /example/unclassified/main_sod.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | *************************************************************************** 3 | * Copyright (C) 2015, Eray Uzgoren * 4 | * * 5 | * This program is free software: you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License as published by * 7 | * the Free Software Foundation, either version 3 of the License, or * 8 | * (at your option) any later version. * 9 | * * 10 | * This program is distributed in the hope that it will be useful, * 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 | * GNU General Public License for more details. * 14 | * * 15 | * You should have received a copy of the GNU General Public License * 16 | * along with this program. If not, see . * 17 | *************************************************************************** 18 | */ 19 | 20 | //************************************************************* 21 | // Codelet: Performance analysis of Linear system construction 22 | //************************************************************* 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include /* clock_t, clock, CLOCKS_PER_SEC */ 34 | 35 | 36 | 37 | double heavy(double x, double e) { 38 | if (x/e <= -1) 39 | return 0; 40 | else if (x/e <= 0) 41 | return 0.5 + x/e + 0.5*pow(x/e,2); 42 | else if (x/e <= 1) 43 | return 0.5 + x/e - 0.5*pow(x/e,2); 44 | else 45 | return 1; 46 | } 47 | 48 | double heavy(Vec3 x, Vec3 xp, double e) { 49 | return heavy((x - xp).abs(), e); 50 | } 51 | 52 | 53 | int main(int argc,char *argv[]) { 54 | int_8 N, l; 55 | float cfl = 0.5; 56 | clock_t t; 57 | 58 | if (argc == 1) { N = 20; l = 0;} 59 | else if (argc == 2) {N = atoi(argv[1]); l = 0;} 60 | else if (argc == 3) {N = atoi(argv[1]); l = atoi(argv[2]);} 61 | else {N = atoi(argv[1]); l = atoi(argv[2]); cfl = atof(argv[3]); } 62 | 63 | Block2* grid = new Block2({0, 0, 0}, {1, 1, 0}, N, 1); 64 | grid->cfl = cfl; 65 | grid->levelHighBound[0] = l; 66 | grid->levelHighBound[1] = 0; 67 | grid->levelHighBound[2] = 0; 68 | 69 | grid->addVar({"rho", "E", "p", "pu"}); 70 | 71 | auto rho = grid->getVar("rho"); 72 | auto E = grid->getVar("E"); 73 | auto u = grid->getVar("u"); 74 | auto p = grid->getVar("p"); 75 | auto pu = grid->getVar("p"); 76 | 77 | rho->setBC("west", "val", 1); 78 | rho->setBC("east", "val", 0.125); 79 | p->setBC("west", "val", 1); 80 | p->setBC("east", "val", 0.1); 81 | E->setBC("west", "val", 2.5); 82 | E->setBC("east", "val", 0.25); 83 | u->setBC("west", "val", 0); 84 | u->setBC("east", "val", 0); 85 | pu->setBC("west", "val", 0); 86 | pu->setBC("east", "val", 0); 87 | 88 | pu->set(0); 89 | u->set(0); 90 | 91 | for (auto j = 0; j < l; ++j) { 92 | for (auto i = 0; i < grid->listCell.size(); ++i) { 93 | auto x = grid->listCell[i]->getCoord(); 94 | if (x[0] <= 0.5) { 95 | rho->set(i, 1.0); 96 | p->set(i, 1.0); 97 | E->set(i, 2.5); 98 | } else { 99 | rho->set(i, 0.125); 100 | p->set(i, 0.1); 101 | E->set(i, 0.25); 102 | } 103 | } 104 | grid->solBasedAdapt(grid->valGrad(rho)); 105 | grid->adapt(); 106 | } 107 | 108 | grid->writeVTK("H"); 109 | 110 | double endTime = 0.1; //0.8/u->data.max(); 111 | 112 | auto vel = grid->getVel(); 113 | double time = 0; 114 | auto writeTime = 0.0; 115 | auto writeCnt = writeTime; 116 | while (time <= tend) { 117 | grid->setDt(0.001); 118 | 119 | time += grid->dt; 120 | cout << "Time: " << time << " " << grid->dt << " --> " << "xp: " << xp << "xm: "<< xm << endl; 121 | // Density 122 | grid->advectDiv(vel, 1); 123 | 124 | grid->lockBC(u); 125 | u->solve( grid->ddt(1) + grid->divRK2E(vel*rho, 1) 126 | + grid->source(0, grid->valGrad(p).comp(0) ) ); 127 | grid->unlockBC(); 128 | 129 | pu->set(p->data*u->data); 130 | 131 | grid->lockBC(E); 132 | E->solve( grid->ddt(1.0) + grid->divRK2E(vel, 1.0) 133 | + grid->source(0, grid->valGrad(pu).comp(0) ) ); 134 | grid->unlockBC(); 135 | 136 | grid->solBasedAdapt(grid->valGrad(rho)); 137 | grid->solBasedAdapt(grid->valGrad(E)); 138 | grid->solBasedAdapt(grid->valGrad(u)); 139 | grid->adapt(); 140 | 141 | for (auto c: grid->listCell) { 142 | p->set(c->id, 0.4*(E->get(c->id) 143 | - 0.5*rho->get(c->id)*pow(u->get(c->id), 2.0))); 144 | } 145 | 146 | if (writeCnt <= 0 || time >= endTime) { 147 | grid->writeVTK("sod_"); 148 | writeCnt = writeTime; 149 | } 150 | 151 | } 152 | 153 | // NEW 154 | // for (auto f:grid->listFace) { 155 | // int n = f->next; 156 | // int p = f->prev; 157 | 158 | // auto xf = f->getCoord(); 159 | // double uf, phif; 160 | // auto nid = grid->searchVertexbyCoords(xf, f->node[0]); 161 | // uf = grid->listVertex[nid]->evalPhi(u, &xf); 162 | // Vec3 x0 = xf - Vec3(0.5*grid->dt*uf,0,0); 163 | // nid = grid->searchVertexbyCoords(x0, nid); 164 | // phif = grid->listVertex[nid]->evalPhi(phi, &x0); 165 | // cout << phif << " "; 166 | // } 167 | 168 | 169 | 170 | // // Speed test: Matrix construction and solution old and new techniques 171 | // LinSys old(N); VecX x0(N); VecX err0(N); 172 | // old.x = &x0; 173 | // old.error = &err0; 174 | 175 | // t = clock(); 176 | // for (auto i =0; i < N; ++i) { 177 | // old.A[i][i] = 4; 178 | // if (i > 0) old.A[i][i-1] = -1; 179 | // if (i < N-1) old.A[i][i+1] = -1; 180 | // if (i-N >= 0) old.A[i][i-N] = -1; 181 | // if (i+N < N) old.A[i][i+N] = -1; 182 | // old.b[i] = 3*i+1; 183 | // } 184 | // old.setVECX(old.A*old.b); 185 | // t = clock() - t; 186 | // float setup0 = float(t)/CLOCKS_PER_SEC; 187 | 188 | // t = clock(); 189 | // old.BiCGSTAB(); 190 | // t = clock() - t; 191 | // float solve0 = float(t)/CLOCKS_PER_SEC; 192 | 193 | // //cout << *old.x << endl; 194 | // cout << old.error->abs() << endl; 195 | 196 | // triLinSys sp(N); VecX x1(N); VecX err1(N); 197 | // sp.x = &x1; 198 | // sp.error = &err1; 199 | 200 | // t = clock(); 201 | // for (auto i =0; i < N; ++i) { 202 | // sp.A += {(double)i, (double)i, 4}; //old.A[i][i] = 2; 203 | // if (i > 0) sp.A += {(double)i, (double)i-1, -1}; //old.A[i][i-1] = -1; 204 | // if (i < N-1) sp.A += {(double)i, (double)i+1, -1}; //old.A[i][i+1] = -1; 205 | // if (i-N >= 0) sp.A += {(double)i, (double)i-N, -1}; //old.A[i][i-1] = -1; 206 | // if (i+N < N) sp.A += {(double)i, (double)i+N, -1}; //old.A[i][i+1] = -1; 207 | 208 | // sp.b[i] = 3*i+1; 209 | // } 210 | // sp.setMat(sp.A); 211 | // sp.b = sp.S*sp.b; 212 | // t = clock()-t; 213 | // float setup1 = float(t)/CLOCKS_PER_SEC; 214 | 215 | // t = clock(); 216 | // sp.BiCGSTAB(); 217 | // t = clock()-t; 218 | // float solve1 = float(t)/CLOCKS_PER_SEC; 219 | // cout << " ----------- " << endl ; 220 | // //cout << *sp.x << endl; 221 | // cout << sp.error->abs() << endl; 222 | 223 | // cout << "OLD: setup-> " << setup0 << " sec, solve-> " << solve0 << "sec."< " << setup1 << " sec, solve-> " << solve1 << "sec."< b(5); 243 | // // cout << "----"<< endl<< Ab.A.rank << " " << b.size() << endl; 244 | // // for (auto i = 0; i < Ab.A.rank; ++i) b[i] = i+1; 245 | 246 | // // Ab.b = Ab.A*b; 247 | // // old.setVECX(Ab.b); 248 | 249 | // // VecX x(b.size()); 250 | // // Ab.error = &b; 251 | // // Ab.x = &x; 252 | // // Ab.BiCGSTAB(); 253 | 254 | // // cout << *Ab.x << endl; 255 | // // cout << Ab.error->abs() << endl; 256 | 257 | // // cout << old.A<abs() << endl; 266 | 267 | 268 | 269 | return 0; 270 | }; 271 | 272 | 273 | 274 | 275 | -------------------------------------------------------------------------------- /example/unclassified/main_rise.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | *************************************************************************** 3 | * Copyright (C) 2015, Eray Uzgoren * 4 | * * 5 | * This program is free software: you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License as published by * 7 | * the Free Software Foundation, either version 3 of the License, or * 8 | * (at your option) any later version. * 9 | * * 10 | * This program is distributed in the hope that it will be useful, * 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 | * GNU General Public License for more details. * 14 | * * 15 | * You should have received a copy of the GNU General Public License * 16 | * along with this program. If not, see . * 17 | *************************************************************************** 18 | */ 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | 29 | 30 | int main() { 31 | 32 | //CAVITY FLOW 33 | auto dt = 0.0005; 34 | auto t = clock(); 35 | 36 | // GRID 37 | // Block2* grid = new Block2({0, 0, 0}, {1.0, 2.0, 0}, 10, 20); 38 | Block2* grid = new Block2({0, 0, 0}, {1.0, 1.0, 0}, 10, 10); 39 | // grid->adaptCriteria(); 40 | 41 | // CONST variables; sv->specific volume 42 | double sv1 = 0.1; double mu1 = 0.067; double g = 0; //-1; 43 | double sv2 = 1; double mu2 = 0.00067; double sigma = 1; 44 | 45 | // FIELD variables; 46 | grid->addVar({"p", "vor", "I"}); 47 | 48 | // initial and bc values; say this is rho*u then divide it by rho 49 | auto u = grid->getVar("u"); 50 | u->set(0.0); 51 | u->setBC("west", "val", 0); u->setBC("east", "val", 0); 52 | u->setBC("south", "val", 0); u->setBC("north", "val", 0); 53 | auto v = grid->getVar("v"); 54 | v->set(0.0); 55 | v->setBC("west", "val", 0); v->setBC("east", "val", 0); 56 | v->setBC("south", "val", 0); v->setBC("north", "val", 0); 57 | 58 | 59 | auto p = grid->getVar("p"); 60 | p->setBC("south", "val", 0); 61 | p->setBC("north", "val", 0); 62 | p->setBC("west", "val", 0); 63 | p->setBC("east", "val", 0); 64 | p->set(0.0); 65 | 66 | grid->levelHighBound[0] = 3; 67 | grid->levelHighBound[1] = 3; 68 | grid->levelHighBound[2] = 0; 69 | 70 | auto I = grid->getVar("I"); 71 | I->set(0.0); 72 | double pi = 4.0*atan(1); 73 | for (auto j = 0; j < 4; ++j) { 74 | for (auto i = 0; i < grid->listCell.size(); ++i) { 75 | auto x = grid->listCell[i]->getCoord(); // - Vec3(0.5, 0.5); 76 | double r = 0.125 - (x - Vec3(0.5, 0.5)).abs(); 77 | I->set(i, 1.0/(1.0 + exp(-2.0*80*(r)))); 78 | r = 0.125 - (x - Vec3(0.5, 0.625)).abs(); 79 | // I->set(i, max(0.0, min(1.0, I->get(i) + 1.0/(1.0 + exp(-2.0*80*(r)))))); 80 | } 81 | grid->solBasedAdapt2(grid->getError(I)); 82 | grid->adapt(); 83 | } 84 | auto gI = grid->valGrad(I); 85 | auto gp = grid->valGrad(p); 86 | // grid->addVec("st"); 87 | // auto stx = grid->getVar("stx"); 88 | // auto sty = grid->getVar("sty"); 89 | grid->writeVTK("rise"); 90 | 91 | // exit(1); 92 | auto vor = grid->getVar("vor"); 93 | 94 | // solver behavior 95 | u->solver = "Gauss"; u->itmax = 200; u->tol = 1e-4; 96 | v->solver = "Gauss"; v->itmax = 200; v->tol = 1e-4; 97 | p->itmax = 2000; p->tol = 1e-5; 98 | 99 | I->solver = "Gauss"; I->itmax = 100; I->tol = 1e-6; 100 | 101 | VecX rho; 102 | VecX mu; 103 | 104 | dt=0.0001; 105 | // Time control 106 | grid->setDt(dt); 107 | double time= 0; double endTime = 10.0; 108 | int filecnt = 0; int it = 0, writeInt = 1; auto adaptInt = 10; 109 | ofstream myfile; 110 | while (time < endTime) { 111 | cout << setiosflags(ios::scientific) << setprecision(2); 112 | cout << "------------- Processing TIME = "<< time << " ------------------"<getVel(); 115 | auto diverge = grid->valDiv(vel); 116 | cout << "+ div=("<valDiv(vel) << endl; 120 | 121 | // Interface move 122 | grid->lockBC(I); 123 | I->solve (grid->ddt(1.0) 124 | +grid->divRK2E(vel, 1.0) 125 | ); 126 | grid->unlockBC(); 127 | 128 | gI = grid->valGrad(I); 129 | // for (auto i = 0; i < gI.comp(0).size(); ++i) { 130 | // double mag = 1.0/gI.abs(); 131 | // gI[i][0] *= mag; 132 | // gI[i][1] *= mag; 133 | // gI[i][2] *= mag; 134 | // } 135 | 136 | // auto gK = grid->valDiv(gI); 137 | 138 | // double mingk = 100; double maxgk = -100; 139 | // for (auto i = 0; i < gK.size(); ++i) { 140 | // if (gK[i] > maxgk) maxgk = gK[i]; 141 | // if (gK[i] < mingk) mingk = gK[i]; 142 | // } 143 | 144 | // cout << " curv=(" << mingk<<":"<listCell.size(); ++i) { 149 | // gI[i][0] *= gK[i]; 150 | // gI[i][1] *= gK[i]; //sigma*(sv1 + I->get(i) * (sv2 - sv1)); 151 | // } 152 | 153 | vor->set(grid->valGrad(v).comp(0) - grid->valGrad(u).comp(1)); 154 | auto gu = grid->valGrad(u); 155 | auto gv = grid->valGrad(v); 156 | 157 | // rho*d(u)/dt + rho*u*d(u)/dx = -dp/dx + mu*d2u/dx2 + rho*g + sigma*nx; 158 | // u : rhou & v : rhov 159 | 160 | for (auto i = 0; i < grid->listCell.size(); ++i) { 161 | rho[i] = 1.0/(sv1 + I->get(i) * (sv2 - sv1)); 162 | vel[i][0] *= rho[i]; 163 | vel[i][1] *= rho[i]; 164 | } 165 | mu = mu1 + I->data * (mu2 - mu1); 166 | 167 | grid->lockBC(u); 168 | u->solve( 169 | grid->ddt(rho) 170 | + grid->div(vel, 1, {0.5}) 171 | - grid->laplace(mu, {0.5}) 172 | - grid->source(0, sigma*gI.comp(0)) //*(sv1 + I->data *(sv2 - sv1))) // gradX is not defined; 173 | ); 174 | grid->unlockBC(); 175 | 176 | grid->lockBC(v); 177 | v->solve( 178 | grid->ddt(rho) 179 | + grid->div(vel, 1, {0.5}) 180 | - grid->laplace(mu, {0.5}) 181 | - grid->source(0, sigma*gI.comp(1) - rho*g) //*(sv1 + I->data *(sv2 - sv1))) 182 | ); 183 | grid->unlockBC(); 184 | 185 | // grid->solBasedAdapt(vor->data); 186 | // grid->solBasedAdapt(gp); 187 | if ((it == 1) || (it % adaptInt) == 0) { 188 | //grid->solBasedAdapt(gu, 1.0); 189 | // grid->solBasedAdapt(grid->valGrad(vor), 0.4); 190 | grid->solBasedAdapt2(grid->getError(I)); 191 | grid->solBasedAdapt(vor->data, 0.9); 192 | // for (auto i = 0; i < grid->listCell.size(); ++i) 193 | // for (auto j = 0; j< 3; ++j) 194 | // grid->listCell[i]->checkNgbrLevel(j); 195 | grid->adapt(); 196 | } 197 | 198 | // if (periodic) grid->adapt(); 199 | auto velstar = grid->getVel(); 200 | 201 | auto vsdiv = grid->valDiv(velstar); 202 | cout << "+ div=("<valDiv(velstar) << endl; 204 | //cin.ignore().get(); 205 | 206 | // d(rhou)/dt = -dp/dx 207 | // div(rhou(n+1))/dt-div(u(n))/dt = -d2p/dx2 208 | // dt/den*d2p/dx2 = 209 | grid->lockBC(p); 210 | p->solve(grid->laplace(dt*(sv1 + I->data *(sv2 - sv1))) 211 | - grid->source(0, grid->valDiv(velstar)) 212 | ); 213 | grid->unlockBC(); 214 | 215 | gp = grid->valGrad(p); 216 | for (auto i = 0; i < grid->listCell.size(); ++i) { 217 | gp[i][0] *= dt*(sv1 + I->get(i) *(sv2 - sv1) ); 218 | gp[i][1] *= dt*(sv1 + I->get(i) *(sv2 - sv1) ); 219 | } 220 | //cout << gp <set(velstar.comp(0)-gp.comp(0)); // 222 | v->set(velstar.comp(1)-gp.comp(1)); // 223 | //grid->correctVel(velstar, dt/rho1); 224 | 225 | grid->setDt(dt); 226 | time += dt; 227 | 228 | //grid->solBasedAdapt(vor->data); 229 | // grid->solBasedAdapt(gv); 230 | //grid->refine2(); 231 | if (( it++ % writeInt) == 0) { 232 | //grid->writeFace("face"+std::to_string(filecnt)+".vtk"); 233 | std::string flname="rise"+std::to_string(filecnt++)+".vtk"; 234 | myfile.open(flname); 235 | myfile << grid << endl; 236 | myfile.close(); 237 | 238 | } 239 | 240 | cout << "---------------------------------------------------"<. * 17 | *************************************************************************** 18 | */ 19 | 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | 26 | int main() { 27 | // Grid* grid = new Grid(); 28 | // grid->addVertex({ {0, 0, 0}, {1, 0, 0}, {1, 1, 0}, {0, 1, 0} }); 29 | 30 | // grid->addCell( {0, 1, 2, 3} ) ; 31 | 32 | // for (auto i =0; i<3; ++i) { 33 | // grid->listCell[0]->adapt = {1, 1}; 34 | // grid->adapt(); 35 | // grid->writeVTK("myFirstGrid_"); 36 | // } 37 | 38 | // delete(grid); 39 | 40 | // Block2* volgrid = new Block2({0,0,0}, {1,1,0}, 10, 10); 41 | // Grid* surf = new Grid(); 42 | 43 | // surf->addVertex({{0.5,0.4}, {0.6,0.5}, {0.5,0.6}, {0.4,0.5}}); 44 | // surf->addCell({{0,1}, {1,2}, {2,3}, {3,0}}); 45 | 46 | // volgrid->writeVTK("vol"); 47 | // surf->writeVTK("surf"); 48 | 49 | // delete(volgrid); 50 | // delete(surf); 51 | double pi = 4*atan(1.0); 52 | 53 | // Block2* volgrid = new Block2({0,0,0}, {1,1,0}, 5, 5); 54 | 55 | // // add a new variable 56 | // volgrid->addVar("f"); 57 | // auto f = volgrid->getVar("f"); // variable handle 58 | 59 | // f->setBC("east", "grad", 0); // This is the default 60 | // f->setBC("north", "val", 1); // 61 | 62 | // for (auto i=0; i < 4; ++i) { 63 | // for (auto c : volgrid->listCell) { 64 | // auto x = c->getCoord(); // cell-centers 65 | // f->set(c->id, sin(3*pi*x[0])*cos(2*pi*x[1])); 66 | // } 67 | // volgrid->solBasedAdapt2(volgrid->getError(f)); 68 | // volgrid->adapt(); 69 | // volgrid->writeVTK("field_"); 70 | // } 71 | 72 | // delete(volgrid); 73 | 74 | 75 | Block2* volgrid = new Block2({0,0,0}, {1,1,0}, 50, 50); 76 | 77 | // Velocity field 78 | auto uv = volgrid->getVar("u"); auto vv = volgrid->getVar("v"); 79 | uv->set(1.0); // set velocity 80 | vv->set(-0.5); // set velocity 81 | // New variable at cell center 82 | volgrid->addVar("f"); auto f = volgrid->getVar("f"); 83 | 84 | Grid* surf = new Grid(); 85 | 86 | surf->addVertex({{0.55,0.32}, {0.58,0.5}, {0.45,0.68}, {0.42,0.46}}); 87 | surf->addCell({{0,1}, {1,2}, {2,3}, {3,0}}); 88 | // Refine cell; 89 | for (auto i=0; i<4; ++i) { 90 | for (auto c: surf->listCell) if (c->vol().abs() > 0.02) c->adapt[0] = 1; 91 | surf->adapt(); 92 | } 93 | volgrid->updateOtherVertex(surf); 94 | // mark location of this surface 95 | volgrid->indicator(surf, f); 96 | 97 | // Assign velocity variables to surface at vertex 98 | surf->addVec("u",1); 99 | 100 | // Get velocity on the surface 101 | auto us = surf->getVar("u"); auto vs = surf->getVar("v"); 102 | volgrid->passVar(surf, uv, us); 103 | volgrid->passVar(surf, vv, vs); 104 | 105 | volgrid->writeVTK("vol"); 106 | surf->writeVTK("surf"); 107 | 108 | delete(volgrid); 109 | delete(surf); 110 | 111 | // // Problem parameters 112 | // auto k = 2.0; auto qdot = 5e3; auto h = 50; auto Tinf = 20; 113 | // // Grid 114 | // Block2* grid = new Block2({0, 0, 0}, {1, 1, 0}, 10, 10); 115 | // grid->levelHighBound[0] = 2; 116 | // grid->levelHighBound[1] = 2; 117 | // grid->addVar("T"); 118 | // // Variables 119 | // auto T = grid->getVar("T"); 120 | // // Linear solver 121 | // T->solver = "BiCGSTAB"; 122 | // T->itmax = 1000; 123 | // T->set(100); 124 | // // Boundary conditions 125 | // T->setBC("south", "grad", 0); 126 | // T->setBC("north", "grad", h/k*Tinf, -h/k); 127 | // T->setBC("east", "val", 200); 128 | // T->setBC("west", "val", 100); 129 | 130 | // for (auto i = 0; i< 4; ++i) { 131 | // grid->solBasedAdapt2(grid->getError2(T), 2e-3, 2e-1); 132 | // grid->adapt(); 133 | 134 | // // Equation 135 | // grid->lockBC(T); 136 | // T->solve( grid->laplace(k) 137 | // + grid->source(0, qdot) ); 138 | // grid->unlockBC(); 139 | 140 | // grid->writeVTK("heat"); 141 | // } 142 | 143 | // delete(grid); 144 | 145 | // Block2* grid = new Block2({0, 0, 0}, {1, 1, 0}, 10, 10); 146 | // double time= 0; double endTime = 1; //dt*50; 147 | // // Problem constants 148 | // auto k = 2.0; auto qdot = 5e4; auto h = 20; auto Tinf = 20; 149 | // auto rho=1000, cp=4000; 150 | // // Field variables, velocity already defined 151 | // grid->addVar("T"); 152 | 153 | // auto u = grid->getVar("u"); 154 | // auto v = grid->getVar("v"); 155 | // auto T = grid->getVar("T"); 156 | 157 | // T->set(100); 158 | // T->setBC("west", "val", 20); 159 | // T->setBC("south", "val", 20); 160 | // T->itmax = 50; 161 | 162 | // u->set(1); 163 | // v->set(0.2); 164 | 165 | // grid->cfl = 0.5; 166 | // int it = 0; 167 | // while (time < endTime) { 168 | // grid->setDt(0.5); // CFL condition 169 | // auto vel = grid->getVel(); // freeze velocity! 170 | 171 | // // Advection-diffusion equation --- 172 | // grid->lockBC(T); 173 | // T->solve( 174 | // grid->ddt(1.0) 175 | // + grid->div(vel, 1.0) 176 | // - grid->laplace(k/rho/cp) 177 | // - grid->source(0, qdot/rho/cp) 178 | // ); 179 | // grid->unlockBC(); 180 | // grid->writeVTK("heattime_"); 181 | 182 | // if (it++ % 5 == 0) { 183 | // grid->solBasedAdapt(grid->valGrad(T)); 184 | // grid->adapt(); 185 | // } 186 | 187 | // time += grid->dt; 188 | // } 189 | 190 | 191 | // // GRID 192 | // Block2* grid = new Block2({0, 0, 0}, {10, 1, 0}, 20, 20); 193 | 194 | // // CONST variables; 195 | // double rho = 1; double mu = 0.01; 196 | 197 | // // FIELD variables; Vorticity to appear in the output 198 | // grid->addVar({"p", "vor"}); 199 | 200 | // // initial and bc values; 201 | // auto u = grid->getVar("u"); 202 | // u->set(0.0); 203 | // u->setBC("west", "val", 1.0); u->setBC("east", "val", 0); 204 | // u->setBC("south", "val", 0); u->setBC("north", "val", 0); 205 | 206 | // auto v = grid->getVar("v"); 207 | // v->set(0.0); 208 | // v->setBC("west", "val", 0); v->setBC("east", "val", 0); 209 | // v->setBC("south", "val", 0); v->setBC("north", "val", 0); 210 | 211 | // auto p = grid->getVar("p"); 212 | // p->set(0.0); 213 | 214 | // auto vor = grid->getVar("vor"); 215 | 216 | // // Solver behavior 217 | // u->solver = "Gauss"; u->itmax = 20; u->tol = 1e-4; 218 | // v->solver = "Gauss"; v->itmax = 20; v->tol = 1e-4; 219 | // p->solver = "BiCGSTAB"; p->itmax = 10000; p->tol = 1e-6; 220 | 221 | // auto gp = grid->valGrad(p); 222 | 223 | // // Time control 224 | // grid->setDt(1.0); 225 | // double time= 0; double endTime = 10; 226 | // int it = 0, writeInt = 4; 227 | 228 | // while (time < endTime) { 229 | // auto vel = grid->getVel(); 230 | // // Compute vorticity; 231 | // vor->set(grid->valGrad(v).comp(0) - grid->valGrad(u).comp(1)); 232 | 233 | // // Solve for u* 234 | // grid->lockBC(u); 235 | // u->solve(grid->ddt(rho) + grid->div(vel, rho) - grid->laplace(mu) ); 236 | // grid->unlockBC(); 237 | 238 | // // Solve for v* 239 | // grid->lockBC(v); 240 | // v->solve(grid->ddt(rho) + grid->div(vel, rho) - grid->laplace(mu) ); 241 | // grid->unlockBC(); 242 | 243 | // // Adapt grid using vorticity (0.9 sigma up/down for refine/coarsen); 244 | // if (it == 1 || (it % writeInt == 0)) { 245 | // grid->solBasedAdapt(vor->data, 0.9); 246 | // grid->adapt(); 247 | // } 248 | 249 | // // Get Vel* 250 | // auto velstar = grid->getVel(); 251 | 252 | // // Solve for pressure Poisson equation 253 | // grid->lockBC(p); 254 | // p->solve(grid->laplace(1.0/rho) - grid->source(0, grid->valDiv(velstar)/dt)); 255 | // grid->unlockBC(); 256 | 257 | // // Correct velocities; 258 | // u->set(velstar.comp(0)-dt/rho*gp.comp(0)); // 259 | // v->set(velstar.comp(1)-dt/rho*gp.comp(1)); // 260 | 261 | // // Set new time step 262 | // grid->setDt(dt); 263 | // time += grid->dt; 264 | 265 | // //Write output at intervals; 266 | // if ( ( it++ % writeInt) == 0) { 267 | // grid->writeVTK(); // 268 | // } 269 | 270 | // } 271 | 272 | 273 | // delete(grid); 274 | 275 | 276 | 277 | return 0; 278 | }; 279 | --------------------------------------------------------------------------------