#include "grid.hh" #include "turing_vtk.hh" #include "parallel_grid.hh" #include #include #include #include const int TAG_OVERLAP_A = 42; const int TAG_OVERLAP_B = 43; class turing_problem { public: // domain const parallel_structured_grid & grid; // data const std::vector & a; const std::vector & b; private: // parameters double Da, Db; double eps0, eps1; double q, f, m; public: // constructor turing_problem(const parallel_structured_grid & _g, const std::vector & _a, const std::vector & _b, double _Da, double _Db, double _e0, double _e1, double _q, double _f, double _m) : grid(_g), a(_a), b(_b), Da(_Da), Db(_Db), eps0(_e0), eps1(_e1), q(_q), f(_f), m(_m) {} // problem description void compute_local_update(unsigned int i[3], double & da, double & db) const { unsigned int idx = grid.index(i); da = db = 0.0; // laplace with neumann boundary conditions std::vector neighbors = grid.neighbors(i); for (unsigned int n=0; n & da, std::vector & db, double & dt) { unsigned int i[3]; // parallel: nur für eigene Knoten das Update aufrufen for (i[0]=p.grid.overlap(0,0); i[0] 0.0); dt = std::min( dt, std::abs(p.a[idx]/da[idx]) ); } if (db[idx] < 0.0) { assert(p.b[idx] > 0.0); dt = std::min( dt, std::abs(p.b[idx]/db[idx]) ); } } // parallel: global minimales dt berechnen double dt_global_min; MPI_Allreduce (&dt, &dt_global_min, 1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD ); dt = dt_global_min; } void getOverlap(const turing_problem & p, unsigned int d, bool posDir, const std::vector & data, double *overlap) { unsigned int dims[2]; switch (d) { case 0: dims[0]=1; dims[1]=2; break; case 1: dims[0]=0; dims[1]=2; break; case 2: dims[0]=0; dims[1]=1; break; } unsigned int i[3]; i[d] = p.grid.overlap(d,posDir); if (posDir) i[d] = p.grid.size(d)-1-i[d]; for (i[dims[0]]=0; i[dims[0]] & data, double *overlap) { unsigned int dims[2]; switch (d) { case 0: dims[0]=1; dims[1]=2; break; case 1: dims[0]=0; dims[1]=2; break; case 2: dims[0]=0; dims[1]=1; break; } unsigned int i[3]; i[d] = posDir? p.grid.size(d)-p.grid.overlap(d,posDir) : 0; for (i[dims[0]]=0; i[dims[0]] & data, unsigned int rank, int TAG) { unsigned int i[3], n[3]; for (int d=0; d<3; d++) { i[d] = proc_grid.index(rank,d); n[d] = i[d]; } for (int k=0; k<6; k++) { int d=k/2; bool posDir=k%2; if (p.grid.overlap(d,posDir)) { n[d]+=posDir?1:-1; // retrieve own overlap unsigned int count=(p.grid.size()/p.grid.size(d))*p.grid.overlap(d,posDir); double soverlap[count]; getOverlap(p,d,posDir,data,soverlap); unsigned int to = proc_grid.index(n); // send it to neighbor if (MPI_SUCCESS!=MPI_Send(soverlap,count,MPI_DOUBLE, to, TAG, MPI_COMM_WORLD)) std::cout<<"sending failed"< a(grid.size()); std::vector b(grid.size()); // initialize data srand48(42*rank); for (unsigned int i=0; i da(grid.size()); std::vector db(grid.size()); // setup problem description turing_problem p(grid, a, b, 1.0, 10.0, 2.2, 0.02, 2e-4, f, 7e-4); // vtk writer vtk_writer vtk_a("turing_a",grid,proc_grid,a,rank); vtk_writer vtk_b("turing_b",grid,proc_grid,b,rank); // time loop double t = 0.0; double v = vt; vtk_a.write(); vtk_b.write(); // std::cout<