#include "analysis/distance.h" /****************************************************************** * A fast distance calculation * ******************************************************************/ template void CalcDist( Array &Distance, const Array &ID, const Domain &Dm, const std::array& periodic, const std::array& dx ) { ASSERT( Distance.size() == ID.size() ); std::array n = { Dm.Nx-2, Dm.Ny-2, Dm.Nz-2 }; fillHalo fillData( Dm.Comm, Dm.rank_info, n, {1,1,1}, 50, 1, {true,false,false}, periodic ); Array id(ID.size()); Array vecDist(Distance.size()); for (size_t i=0; i &d, const Array &ID, double dx, double dy, double dz ) { d.fill( Vec( 1e50, 1e50, 1e50 ) ); const double dx0 = 0.5*dx; const double dy0 = 0.5*dy; const double dz0 = 0.5*dz; //const double dxy0 = 0.25*sqrt( dx*dx + dy*dy ); //const double dxz0 = 0.25*sqrt( dx*dx + dz*dz ); //const double dyz0 = 0.25*sqrt( dy*dy + dz*dz ); //const double dxyz0 = sqrt( dx*dx + dy*dy + dz*dz ); int Nx = d.size(0); int Ny = d.size(1); int Nz = d.size(2); for (int k=1; k &d, double dx, double dy, double dz ) { double err = 0; int Nx = d.size(0); int Ny = d.size(1); int Nz = d.size(2); // Propagate (+,+,+) for (int k=1; k=0; k--) { for (int j=Ny-2; j>=0; j--) { for (int i=Nx-2; i>=0; i--) { auto vx = d(i+1,j,k); auto vy = d(i,j+1,k); auto vz = d(i,j,k+1); vx.x -= dx; vy.y -= dy; vz.z -= dz; auto v = std::min( std::min(vx,vy), vz ); double d1 = v.norm2(); double d2 = d(i,j,k).norm2(); if ( d1 < d2 ) { d(i,j,k) = v; err = std::max( err, sqrt(d2)-sqrt(d1) ); } } } } return err; } /****************************************************************** * Vector-based distance calculation * ******************************************************************/ void CalcVecDist( Array &d, const Array &ID0, const Domain &Dm, const std::array& periodic, const std::array& dx ) { std::array N = { Dm.Nx, Dm.Ny, Dm.Nz }; std::array n = { Dm.Nx-2, Dm.Ny-2, Dm.Nz-2 }; // Create ID with ghosts Array ID(N[0],N[1],N[2]); fillHalo fillDataID( Dm.Comm, Dm.rank_info, n, {1,1,1}, 50, 1, {true,true,true}, periodic ); fillDataID.copy( ID0, ID ); // Fill ghosts with nearest neighbor for (int k=1; k fillData( Dm.Comm, Dm.rank_info, n, {1,1,1}, 50, 1, {true,false,false}, periodic ); // Calculate the local distances calcVecInitialize( d, ID, dx[0], dx[1], dx[2] ); double err = 1e100; double tol = 0.5 * std::min( std::min(dx[0],dx[1]), dx[2] ); for (int it=0; it<=50 && err>tol; it++) { err = calcVecUpdateInterior( d, dx[0], dx[1], dx[2] ); } // Calculate the global distances int N_it = Dm.nprocx() + Dm.nprocy() + Dm.nprocz() + 100; for ( int it=0; it( Array&, const Array&, const Domain&, const std::array&, const std::array& ); template void CalcDist( Array&, const Array&, const Domain&, const std::array&, const std::array& );