// *********************************************************************************** // 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) // - Clément 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(); }