[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/idefix-code/idefix/master/src/dataBlock/makeGeometry.cpp [Back]  [Original]

// ***********************************************************************************
// Idefix MHD astrophysical code
//
// Source file src/dataBlock/makeGeometry.cpp
//
// Last modified : 10/2023
//
// Copyright(C) by :
// - Geoffroy Lesur  (IPAG/UGA/CNRS - 2020 - 2023)
// - Soufiane Baghdadi  (IPAG/UGA/CNRS - 2020)
// - Clment Robert  (IPAG/UGA/CNRS - 2021)
// and other code contributors
//
// Licensed under CeCILL 2.1 License, see COPYING for more information
// ***********************************************************************************

#include "../idefix.hpp"
#include "dataBlock.hpp"

/**
 * Compute the geometrical terms for the grid.
 * This function computes all of the geometrical terms
 * (cell volumes, faces surfaces, trigonometric functions)
*/
void DataBlock::MakeGeometry() {
  idfx::pushRegion("DataBlock::MakeGeometry()");


  // Initialize grid coarsening if needed
  if(mygrid->haveGridCoarsening != GridCoarsening::disabled) {
    this->haveGridCoarsening = mygrid->haveGridCoarsening;
    this->coarseningDirection = mygrid->coarseningDirection;

    for(int dir = 0 ; dir < 3 ; dir++) {
      if(coarseningDirection[dir]) {
        const int Xt = (dir == IDIR ? JDIR : IDIR);
        const int Xb = (dir == KDIR ? JDIR : KDIR);

        // Allocate coarsening level arrays
        coarseningLevel[dir] = IdefixArray2D(
                                  "DataBlock_corseLevel",
                                  np_tot[Xb],
                                  np_tot[Xt]);
        // Make a local reference
        IdefixArray2D coarseInit = coarseningLevel[dir];
        // Init coarsening level array to one everywhere
        idefix_for("init_coarsening", 0, np_tot[Xb], 0, np_tot[Xt],
                KOKKOS_LAMBDA(int j, int i) {
                  coarseInit(j,i) = 1;
                });
      }
    }
  }

  // Compute Volumes
  IdefixArray3D dV  = this->dV;
  IdefixArray1D dx1 = this->dx[IDIR];
  IdefixArray1D dx2 = this->dx[JDIR];
  IdefixArray1D dx3 = this->dx[KDIR];
  IdefixArray1D x1  = this->x[IDIR];
  IdefixArray1D x2  = this->x[JDIR];
  IdefixArray1D x3  = this->x[KDIR];
  IdefixArray1D x1p = this->xr[IDIR];
  IdefixArray1D x2p = this->xr[JDIR];
  IdefixArray1D x3p = this->xr[KDIR];
  IdefixArray1D x1m = this->xl[IDIR];
  IdefixArray1D x2m = this->xl[JDIR];
  IdefixArray1D x3m = this->xl[KDIR];
  IdefixArray1D rt  = this->rt;
  IdefixArray1D sinx2m  = this->sinx2m;
  IdefixArray1D tanx2m  = this->tanx2m;
  IdefixArray1D sinx2   = this->sinx2;
  IdefixArray1D tanx2   = this->tanx2;
  IdefixArray1D dmu = this->dmu;

  idefix_for("Volumes",0,this->np_tot[KDIR],0,this->np_tot[JDIR],0,this->np_tot[IDIR],
    KOKKOS_LAMBDA (int k, int j, int i) {
#if GEOMETRY == CARTESIAN
      dV(k,j,i) = D_EXPAND(dx1(i), *dx2(j), *dx3(k));   // = dx*dy*dz

#elif GEOMETRY == CYLINDRICAL
      real dVr = FABS(x1p(i)*x1p(i) - x1m(i)*x1m(i))/2.0;
      dV(k,j,i) = D_EXPAND( dVr, *dx2(j), *ONE_F);
             // = |r|*dr*dz  (more accurately (x1p**2-x1m**2)/2*dphi*dz)

#elif GEOMETRY == POLAR
      real dVr = FABS(x1p(i)*x1p(i) - x1m(i)*x1m(i))/2.0;
      dV(k,j,i) = D_EXPAND( dVr, *dx2(j), *dx3(k));    // = |r|*dr*dphi*dz

#elif GEOMETRY == SPHERICAL
      real dVr = FABS(x1p(i)*x1p(i)*x1p(i) - x1m(i)*x1m(i)*x1m(i))/3.0;
      real dmu = FABS(cos(x2m(j)) - cos(x2p(j)));
      dV(k,j,i) = D_EXPAND( dVr, *dmu, *dx3(k));
#endif
    }
  );

  // Compute Geometrical cell centers
  IdefixArray1D x1gc = this->xgc[IDIR];
  IdefixArray1D x2gc = this->xgc[JDIR];
  IdefixArray1D x3gc = this->xgc[KDIR];

  // X1 direction
  idefix_for("GeometricalCentersX1",0,np_tot[IDIR],
    KOKKOS_LAMBDA (int i) {
#if GEOMETRY == CARTESIAN
      x1gc(i) = x1(i);

#elif GEOMETRY == CYLINDRICAL || GEOMETRY == POLAR
      x1gc(i) = x1(i) + dx1(i)*dx1(i)/(12.0*x1(i));

#elif GEOMETRY == SPHERICAL
      x1gc(i) = x1(i) + 2.0*x1(i)*dx1(i)*dx1(i)
                / (12.0*x1(i)*x1(i) + dx1(i)*dx1(i));
      rt(i)   = (x1p(i)*x1p(i)*x1p(i) - x1m(i)*x1m(i)*x1m(i))
                / (x1p(i)*x1p(i)-x1m(i)*x1m(i)) / 1.5;
#endif
    }
  );

  // X2
  idefix_for("GeometricalCentersX2",0,np_tot[JDIR],
    KOKKOS_LAMBDA (int j) {
#if GEOMETRY != SPHERICAL
      x2gc(j) = x2(j);
#else
      real xL = x2m(j);
      real xR = x2p(j);
      x2gc(j)  = (sin(xR) - sin(xL)+ xL*cos(xL) - xR*cos(xR)) / (cos(xL)-cos(xR));
      sinx2m(j) = sin(xL);
      tanx2m(j) = tan(xL);
      sinx2(j) = sin(x2(j));
      tanx2(j) = tan(x2(j));
      dmu(j) = FABS(cos(xL)-cos(xR));
#endif
    }
  );

  // X3
  idefix_for("GeometricalCentersX3",0,np_tot[KDIR],
    KOKKOS_LAMBDA (int k) {
      x3gc(k) = x3(k);
    }
  );

  // Compute Areas
  IdefixArray3D Ax1 = this->A[IDIR];
  IdefixArray3D Ax2 = this->A[JDIR];
  IdefixArray3D Ax3 = this->A[KDIR];

  // X1 direction
  int end = this->np_tot[IDIR];
  idefix_for("AreaX1",0,this->np_tot[KDIR],0,this->np_tot[JDIR],0,this->np_tot[IDIR]+IOFFSET,
    KOKKOS_LAMBDA (int k, int j, int i) {
#if GEOMETRY == CARTESIAN
      Ax1(k,j,i) = D_EXPAND(1.0, *dx2(j), *dx3(k));         // = dy*dz

#elif GEOMETRY == CYLINDRICAL
      if(i == end) {
        Ax1(k,j,i) = D_EXPAND(FABS(x1p(i-1)), *dx2(j), *ONE_F);
      } else {
        Ax1(k,j,i) = D_EXPAND(FABS(x1m(i)), *dx2(j), *ONE_F); // r*dz
      }

#elif GEOMETRY == POLAR
      if(i == end) {
        Ax1(k,j,i) = D_EXPAND(FABS(x1p(i-1)), *dx2(j), *dx3(k));
      } else {
        Ax1(k,j,i) = D_EXPAND(FABS(x1m(i)), *dx2(j), *dx3(k)); // r*dphi*dz
      }

#elif GEOMETRY == SPHERICAL
      real dmu = FABS(cos(x2m(j)) - cos(x2p(j)));
      if(i == end) {
        Ax1(k,j,i) = D_EXPAND(x1p(i-1)*x1p(i-1), *dmu, *dx3(k));
      } else {
        Ax1(k,j,i) = D_EXPAND(x1m(i)*x1m(i), *dmu, *dx3(k)); // r^2*dmu*dphi
      }
#endif
    }
  );

  // X2 direction
  end = this->np_tot[JDIR];
  idefix_for("AreaX2",0,this->np_tot[KDIR],0,this->np_tot[JDIR]+JOFFSET,0,this->np_tot[IDIR],
    KOKKOS_LAMBDA (int k, int j, int i) {
#if GEOMETRY == CARTESIAN
      Ax2(k,j,i) = D_EXPAND(dx1(i), *ONE_F, *dx3(k));        // = dx*dz

#elif GEOMETRY == CYLINDRICAL
      Ax2(k,j,i) = D_EXPAND(FABS(x1(i)), *dx1(i), *ONE_F);   // = r*dr

#elif GEOMETRY == POLAR
      Ax2(k,j,i) = D_EXPAND(dx1(i), *ONE_F, *dx3(k));        // = dr*dz

#elif GEOMETRY == SPHERICAL
      if (j == end) {
        Ax2(k,j,i) = D_EXPAND(x1(i)*dx1(i), *FABS(sin(x2p(j-1))), *dx3(k));
      } else {
        Ax2(k,j,i) = D_EXPAND(x1(i)*dx1(i), *FABS(sin(x2m(j))), *dx3(k)); // = r*dr*sin(thp)*dphi
      }
#endif
    }
  );

  // X3 direction
  end = this->np_tot[KDIR];
  idefix_for("AreaX3",0,this->np_tot[KDIR]+KOFFSET,0,this->np_tot[JDIR],0,this->np_tot[IDIR],
    KOKKOS_LAMBDA (int k, int j, int i) {
  #if GEOMETRY == CARTESIAN
      Ax3(k,j,i) = D_EXPAND(dx1(i), *dx2(j), *ONE_F);          // = dx*dy

  #elif GEOMETRY == CYLINDRICAL
      Ax3(k,j,i) = ONE_F;   // No 3rd direction in cylindrical coords

  #elif GEOMETRY == POLAR
      Ax3(k,j,i) = D_EXPAND(x1(i)*dx1(i), *dx2(j), *ONE_F);   // = r*dr*dphi

  #elif GEOMETRY == SPHERICAL
      Ax3(k,j,i) = D_EXPAND(x1(i)*dx1(i), *dx2(j), *ONE_F);   // = r*dr*dth
  #endif
    }
  );

  idfx::popRegion();
}

void DataBlock::ExtractSubdomain() {
  idfx::pushRegion("DataBlock::ExtractSubdomain");
  // Copy the relevant part of the coordinate system to the datablock
  for(int dir = 0 ; dir < 3 ; dir++) {
    int offset=gbeg[dir]-beg[dir];

    IdefixArray1D x_input = mygrid->x[dir];
    IdefixArray1D x_output= x[dir];
    IdefixArray1D xr_input = mygrid->xr[dir];
    IdefixArray1D xr_output= xr[dir];
    IdefixArray1D xl_input = mygrid->xl[dir];
    IdefixArray1D xl_output= xl[dir];
    IdefixArray1D dx_input = mygrid->dx[dir];
    IdefixArray1D dx_output= dx[dir];

    idefix_for("coordinates",0,np_tot[dir],
      KOKKOS_LAMBDA (int i) {
        x_output(i)  = x_input(i+offset);
        xr_output(i) = xr_input(i+offset);
        xl_output(i) = xl_input(i+offset);
        dx_output(i) = dx_input(i+offset);
      }
    );
  }

  idfx::popRegion();
}

Web Proxy Viewer  |  New URL  |  Original Page