Skip to content
Snippets Groups Projects
Select Git revision
  • master default protected
  • feature/add-fft-interface
  • feature/expose-rnumber-from-simulations
  • feature/particle_state_generation_with_variable_box_size
  • feature/forcing-unit-test
  • feature/dealias-check2
  • bugfix/check_field_exists
  • feature/dealias-check
  • v3.x
  • feature/particles-vectorization
  • 6.2.4
  • 6.2.3
  • 6.2.2
  • 6.2.1
  • 6.2.0
  • 6.1.0
  • 6.0.0
  • 5.8.1
  • 5.8.0
  • 5.7.2
  • 5.7.1
  • 5.7.0
  • 5.6.0
  • 5.5.1
  • 5.5.0
  • 5.4.7
  • 5.4.6
  • 5.4.5
  • 5.4.4
  • 5.4.3
30 results

rFFTW_interpolator.cpp

Blame
  • rFFTW_interpolator.cpp 7.46 KiB
    /**********************************************************************
    *                                                                     *
    *  Copyright 2015 Max Planck Institute                                *
    *                 for Dynamics and Self-Organization                  *
    *                                                                     *
    *  This file is part of bfps.                                         *
    *                                                                     *
    *  bfps is free software: you can redistribute it and/or modify       *
    *  it under the terms of the GNU General Public License as published  *
    *  by the Free Software Foundation, either version 3 of the License,  *
    *  or (at your option) any later version.                             *
    *                                                                     *
    *  bfps is distributed in the hope that it will be useful,            *
    *  but WITHOUT ANY WARRANTY; without even the implied warranty of     *
    *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      *
    *  GNU General Public License for more details.                       *
    *                                                                     *
    *  You should have received a copy of the GNU General Public License  *
    *  along with bfps.  If not, see <http://www.gnu.org/licenses/>       *
    *                                                                     *
    * Contact: Cristian.Lalescu@ds.mpg.de                                 *
    *                                                                     *
    **********************************************************************/
    
    
    
    #define NDEBUG
    
    #include <cmath>
    #include "rFFTW_interpolator.hpp"
    #include "scope_timer.hpp"
    
    template <class rnumber, int interp_neighbours>
    rFFTW_interpolator<rnumber, interp_neighbours>::rFFTW_interpolator(
            fluid_solver_base<rnumber> *fs,
            base_polynomial_values BETA_POLYS,
            rnumber *FIELD_POINTER) : interpolator_base<rnumber, interp_neighbours>(fs, BETA_POLYS)
    {
        this->field = FIELD_POINTER;
    
    
        // generate compute array
        this->compute = new bool[this->descriptor->sizes[0]];
        std::fill_n(this->compute, this->descriptor->sizes[0], false);
        for (int iz = this->descriptor->starts[0]-interp_neighbours-1;
                iz <= this->descriptor->starts[0]+this->descriptor->subsizes[0]+interp_neighbours;
                iz++)
            this->compute[((iz + this->descriptor->sizes[0]) % this->descriptor->sizes[0])] = true;
    }
    
    template <class rnumber, int interp_neighbours>
    rFFTW_interpolator<rnumber, interp_neighbours>::rFFTW_interpolator(
            vorticity_equation<rnumber, FFTW> *fs,
            base_polynomial_values BETA_POLYS,
            rnumber *FIELD_POINTER) : interpolator_base<rnumber, interp_neighbours>(fs, BETA_POLYS)
    {
    //    this->field = FIELD_POINTER;
    //
    //
    //    // generate compute array
    //    this->compute = new bool[this->descriptor->sizes[0]];
    //    std::fill_n(this->compute, this->descriptor->sizes[0], false);
    //    for (int iz = this->descriptor->starts[0]-interp_neighbours-1;
    //            iz <= this->descriptor->starts[0]+this->descriptor->subsizes[0]+interp_neighbours;
    //            iz++)
    //        this->compute[((iz + this->descriptor->sizes[0]) % this->descriptor->sizes[0])] = true;
    }
    
    template <class rnumber, int interp_neighbours>
    rFFTW_interpolator<rnumber, interp_neighbours>::~rFFTW_interpolator()
    {
        delete[] this->compute;
    }
    
    template <class rnumber, int interp_neighbours>
    bool rFFTW_interpolator<rnumber, interp_neighbours>::get_rank_info(double z, int &maxz_rank, int &minz_rank)
    {
        int zg = int(floor(z/this->dz));
        minz_rank = this->descriptor->rank[MOD(
                 zg - interp_neighbours,
                this->descriptor->sizes[0])];
        maxz_rank = this->descriptor->rank[MOD(
                zg + 1 + interp_neighbours,
                this->descriptor->sizes[0])];
        bool is_here = false;
        for (int iz = -interp_neighbours; iz <= interp_neighbours+1; iz++)
            is_here = (is_here ||
                       (this->descriptor->myrank ==
                        this->descriptor->rank[MOD(zg+iz, this->descriptor->sizes[0])]));
        return is_here;
    }
    
    template <class rnumber, int interp_neighbours>
    void rFFTW_interpolator<rnumber, interp_neighbours>::sample(
            const int nparticles,
            const int pdimension,
            const double *__restrict__ x,
            double *__restrict__ y,
            const int *deriv)
    {
        TIMEZONE("rFFTW_interpolator::sample");
        /* get grid coordinates */
        int *xg = new int[3*nparticles];
        double *xx = new double[3*nparticles];
        double *yy =  new double[3*nparticles];
        std::fill_n(yy, 3*nparticles, 0.0);
        this->get_grid_coordinates(nparticles, pdimension, x, xg, xx);
        /* perform interpolation */
        for (int p=0; p<nparticles; p++)
            if (this->compute[xg[p*3+2]])
                this->operator()(xg + p*3, xx + p*3, yy + p*3, deriv);
        MPI_Allreduce(
                yy,
                y,
                3*nparticles,
                MPI_DOUBLE,
                MPI_SUM,
                this->descriptor->comm);
        delete[] yy;
        delete[] xg;
        delete[] xx;
    }
    
    template <class rnumber, int interp_neighbours>
    void rFFTW_interpolator<rnumber, interp_neighbours>::operator()(
            const int *xg,
            const double *xx,
            double *dest,
            const int *deriv)
    {
        TIMEZONE("rFFTW_interpolator::operator()");
        double bx[interp_neighbours*2+2], by[interp_neighbours*2+2], bz[interp_neighbours*2+2];
        if (deriv == NULL)
        {
            this->compute_beta(0, xx[0], bx);
            this->compute_beta(0, xx[1], by);
            this->compute_beta(0, xx[2], bz);
        }
        else
        {
            this->compute_beta(deriv[0], xx[0], bx);
            this->compute_beta(deriv[1], xx[1], by);
            this->compute_beta(deriv[2], xx[2], bz);
        }
        std::fill_n(dest, 3, 0);
        ptrdiff_t bigiz, bigiy, bigix;
        for (int iz = -interp_neighbours; iz <= interp_neighbours+1; iz++)
        {
            bigiz = ptrdiff_t(((xg[2]+iz) + this->descriptor->sizes[0]) % this->descriptor->sizes[0]);
            if (this->descriptor->myrank == this->descriptor->rank[bigiz])
            {
                for (int iy = -interp_neighbours; iy <= interp_neighbours+1; iy++)
                {
                    bigiy = ptrdiff_t(MOD(xg[1]+iy, this->descriptor->sizes[1]));
                    for (int ix = -interp_neighbours; ix <= interp_neighbours+1; ix++)
                    {
                        bigix = ptrdiff_t(MOD(xg[0]+ix, this->descriptor->sizes[2]));
                        ptrdiff_t tindex = (((bigiz-this->descriptor->starts[0])*this->descriptor->sizes[1] +
                                             bigiy)*(this->descriptor->sizes[2]+2) +
                                             bigix)*3;
                        for (int c=0; c<3; c++)
                            dest[c] += this->field[tindex+c]*(bz[iz+interp_neighbours]*
                                                              by[iy+interp_neighbours]*
                                                              bx[ix+interp_neighbours]);
                    }
                }
            }
        }
    }
    
    template class rFFTW_interpolator<float, 1>;
    template class rFFTW_interpolator<float, 2>;
    template class rFFTW_interpolator<float, 3>;
    template class rFFTW_interpolator<float, 4>;
    template class rFFTW_interpolator<float, 5>;
    template class rFFTW_interpolator<float, 6>;
    template class rFFTW_interpolator<double, 1>;
    template class rFFTW_interpolator<double, 2>;
    template class rFFTW_interpolator<double, 3>;
    template class rFFTW_interpolator<double, 4>;
    template class rFFTW_interpolator<double, 5>;
    template class rFFTW_interpolator<double, 6>;