diff --git a/doc/content/source/problems/output_solution.md b/doc/content/source/problems/output_solution.md index 8bf42c4d8..549798bd6 100644 --- a/doc/content/source/problems/output_solution.md +++ b/doc/content/source/problems/output_solution.md @@ -20,6 +20,9 @@ This output feature is used by specifying the fields to be output with the - `scalar01` (which creates a MOOSE variable named `scalar01`) - `scalar02` (which creates a MOOSE variable named `scalar02`) - `scalar03` (which creates a MOOSE variable named `scalar03`) +- `ros_tensor` (which creates MOOSE variables named `ros_s11`, `ros_s22`,..,`ros_s13`) +- `wall_shear` (which creates a MOOSE variable named `wall_shear`) +- `traction` (which creates MOOSE variables named `traction_x`,`traction_y`,`traction_z`) For NekRS simulations that are coupled to MOOSE, the temperature will already be output because it is used as part of the physics transfers. diff --git a/include/base/CardinalEnums.h b/include/base/CardinalEnums.h index 7aad767ee..a8ee31bef 100644 --- a/include/base/CardinalEnums.h +++ b/include/base/CardinalEnums.h @@ -97,6 +97,17 @@ enum NekFieldEnum scalar01, scalar02, scalar03, + wall_shear, + traction, + traction_x, + traction_y, + traction_z, + ros_s11, + ros_s22, + ros_s33, + ros_s12, + ros_s23, + ros_s13, unity }; diff --git a/include/base/NekInterface.h b/include/base/NekInterface.h index 8338756f3..774fd0f6b 100644 --- a/include/base/NekInterface.h +++ b/include/base/NekInterface.h @@ -47,6 +47,15 @@ namespace nekrs static int build_only; +/// initialize wall shear stress variable +void initializeWallShear(); + +/// initialize traction variable for FSI or standalone traction calculations +void initializeTraction(); + +/// initialize rate of strain tensor components +void initializeRateOfStrainTensor(); + /// Allocate memory for the host mesh parameters void initializeHostMeshParameters(); @@ -55,6 +64,9 @@ void updateHostMeshParameters(); dfloat * getSgeo(); dfloat * getVgeo(); +double * getWallShear(); +double * getTraction(); +double * getRateOfStrainTensor(); /** * Set the absolute tolerance for checking energy conservation in data transfers to Nek @@ -556,6 +568,41 @@ void limitTemperature(const double * min_T, const double * max_T); void gradient(const int offset, const double * f, double * grad_f, const nek_mesh::NekMeshEnum pp_mesh); +/** + * Compute the direct stiffness sum (dssum) and then average at element boundaries. Similar to the dsavg subroutine from Nek5000 + * @param[in] u field to perform the dssum and average on + * @param[in] pp_mesh NekRS mesh to operate on + */ +void nekDirectStiffnessAvg(double * u, const nek_mesh::NekMeshEnum pp_mesh); + +/** + * Compute the rate of strain tensor on the Nek mesh + * @param[in] S_ij pointer to store the rate of strain tensor + * @param[in] pp_mesh NekRS mesh to operate on + */ +void computeRateOfStrainTensor(double * S_ij, const nek_mesh::NekMeshEnum pp_mesh); + +/** + * Compute the stress tensor on the Nek mesh + * @param[in] Tau_ij pointer to store the stress tensor + * @param[in] pp_mesh NekRS mesh to operate on + */ +void computeStressTensor(double * Tau_ij,const nek_mesh::NekMeshEnum pp_mesh); + +/** + * Compute the wall shear stress on a given boundary + * @param[in] wall_shear pointer to store the wall shear + * @param[in] pp_mesh NekRS mesh to operate on + */ +void computeWallShearStress(double * wall_shear, const nek_mesh::NekMeshEnum pp_mesh); + +/** + * Compute the traction vectors on the solid-fluid boundary on the Nek mesh + * @param[in] traction pointer to store the 3 traction components + * @param[in] pp_mesh NekRS mesh to operate on + */ +void computeTraction(double * traction, const nek_mesh::NekMeshEnum pp_mesh); + /** * Find the extreme value of a given field over the entire nekRS domain * @param[in] field field to find the minimum value of @@ -821,6 +868,83 @@ double velocity_z(const int id); */ double velocity(const int id); +/** + * Get the wall shear at given GLL index + * @param[in] id GLL index + * @return wall shear at index + */ +double wall_shear(const int id); + +/** + * Get the traction at given GLL index + * @param[in] id GLL index + * @return traction at index + */ +double traction(const int id); + +/** + * Get the x-traction at given GLL index + * @param[in] id GLL index + * @return x-traction at index + */ +double traction_x(const int id); + +/** + * Get the y-traction at given GLL index + * @param[in] id GLL index + * @return y-traction at index + */ +double traction_y(const int id); + +/** + * Get the z-traction at given GLL index + * @param[in] id GLL index + * @return z-traction at index + */ +double traction_z(const int id); + +/** + * Get the magnitude of the rate-of-strain tensor component S_{11} at given GLL index + * @param[in] id GLL index + * @return S_{11} magnitude at index + */ +double ros_s11(const int id); + +/** + * Get the magnitude of the rate-of-strain tensor component S_{22} at given GLL index + * @param[in] id GLL index + * @return S_{22} magnitude at index + */ +double ros_s22(const int id); + +/** + * Get the magnitude of the rate-of-strain tensor component S_{33} at given GLL index + * @param[in] id GLL index + * @return S_{33} magnitude at index + */ +double ros_s33(const int id); + +/** + * Get the magnitude of the rate-of-strain tensor component S_{12} at given GLL index + * @param[in] id GLL index + * @return S_{12} magnitude at index + */ +double ros_s12(const int id); + +/** + * Get the magnitude of the rate-of-strain tensor component S_{23} at given GLL index + * @param[in] id GLL index + * @return S_{23} magnitude at index + */ +double ros_s23(const int id); + +/** + * Get the magnitude of the rate-of-strain tensor component S_{13} at given GLL index + * @param[in] id GLL index + * @return S_{13} magnitude at index + */ +double ros_s13(const int id); + /** * Write a value into the user scratch space that holds the flux * @param[in] id index diff --git a/src/base/CardinalEnums.C b/src/base/CardinalEnums.C index 7928a2b81..05724dd3a 100644 --- a/src/base/CardinalEnums.C +++ b/src/base/CardinalEnums.C @@ -46,7 +46,9 @@ MooseEnum getNekFieldEnum() { return MooseEnum( - "velocity_component velocity_x velocity_y velocity_z velocity temperature pressure scalar01 scalar02 scalar03 unity"); + "velocity_component velocity_x velocity_y velocity_z velocity temperature" + " pressure scalar01 scalar02 scalar03 wall_shear traction traction_x traction_y traction_z" + " ros_s11 ros_s22 ros_s33 ros_s12 ros_s23 ros_s13 unity"); } MooseEnum diff --git a/src/base/NekInterface.C b/src/base/NekInterface.C index 762602cda..529e1000a 100644 --- a/src/base/NekInterface.C +++ b/src/base/NekInterface.C @@ -20,6 +20,8 @@ #include "NekInterface.h" #include "CardinalUtils.h" +#include + static nekrs::characteristicScales scales; static dfloat * sgeo; @@ -34,6 +36,24 @@ static double setup_time; static double abs_tol; static double rel_tol; +/// traction variable for FSI or standalone traction calculations +static double * _traction = NULL; + +/// wall shear stress variable +static double * _wall_shear = NULL; + +/** 6 components of the rate-of-strain tensor variable calculated in Nek. + * Each component is the size of the velocity field, and the component + * order is as follows + * _ros_tensor[0*velocityFieldOffset()] is the S_{11} component + * _ros_tensor[1*velocityFieldOffset()] is the S_{22} component + * _ros_tensor[2*velocityFieldOffset()] is the S_{33} component + * _ros_tensor[3*velocityFieldOffset()] is the S_{12} component + * _ros_tensor[4*velocityFieldOffset()] is the S_{23} component + * _ros_tensor[5*velocityFieldOffset()] is the S_{13} component + */ +static double * _ros_tensor = NULL; + void setAbsoluteTol(double tol) { @@ -637,6 +657,24 @@ initializeHostMeshParameters() vgeo = (dfloat *)calloc(mesh->o_vgeo.size(), sizeof(dfloat)); } +void +initializeRateOfStrainTensor() +{ + nekrs::_ros_tensor = (double *)calloc(6*velocityFieldOffset(), sizeof(double)); +} + +void +initializeTraction() +{ + nekrs::_traction = (double *)calloc(3*velocityFieldOffset(), sizeof(double)); +} + +void +initializeWallShear() +{ + nekrs::_wall_shear = (double *)calloc(velocityFieldOffset(), sizeof(double)); +} + void updateHostMeshParameters() { @@ -657,6 +695,24 @@ getVgeo() return vgeo; } +double * +getTraction() +{ + return _traction; +} + +double * +getWallShear() +{ + return _wall_shear; +} + +double * +getRateOfStrainTensor() +{ + return _ros_tensor; +} + double sideExtremeValue(const std::vector & boundary_id, const field::NekFieldEnum & field, const nek_mesh::NekMeshEnum pp_mesh, const bool max) @@ -1277,6 +1333,263 @@ gradient(const int offset, const double * f, double * grad_f, const nek_mesh::Ne } } + +void +nekDirectStiffnessAvg(double * u, const nek_mesh::NekMeshEnum pp_mesh) +{ +#define nrsCheck(_nrsCheckCond, _nrsCheckComm, _nrsCheckExitCode, _nrsCheckMessage, ...) \ + do { \ + int _nrsCheckErr = 0; \ + if(_nrsCheckCond) _nrsCheckErr = 1; \ + if(_nrsCheckComm != MPI_COMM_SELF) MPI_Allreduce(MPI_IN_PLACE, &_nrsCheckErr, 1, MPI_INT, MPI_SUM, _nrsCheckComm); \ + if(_nrsCheckErr) { \ + int rank = 0; \ + MPI_Comm_rank(_nrsCheckComm, &rank); \ + if(rank == 0) { \ + fprintf(stderr, "Error in %s: ", __func__);\ + fprintf(stderr, _nrsCheckMessage, __VA_ARGS__); \ + } \ + fflush(stderr); \ + fflush(stdout); \ + MPI_Barrier(_nrsCheckComm); \ + MPI_Abort(MPI_COMM_WORLD, _nrsCheckExitCode); \ + } \ + } while (0) + +#define fname(s) (strcpy(func, (s)), strcat(func, us), func) + + mesh_t * mesh = getMesh(pp_mesh); + nrs_t * nrs = (nrs_t *)nrsPtr(); + + static void (*nek_dssum_ptr)(double *); + + std::string usrname; + platform->options.getArgs("CASENAME", usrname); + + const char * session_in = usrname.c_str(); + + std::string cache_dir(getenv("NEKRS_CACHE_DIR")); + if (platform->cacheBcast) + cache_dir = platform->tmpDir; + + const std::string lib = cache_dir + "/nek5000/lib" + session_in + ".so"; + + if(platform->comm.mpiRank == 0 && platform->verbose) + std::cout << "\nloading " << lib << std::endl; + void *handle = dlopen(lib.c_str(), RTLD_NOW | RTLD_LOCAL); + + nek::nrsCheck(!handle, MPI_COMM_SELF, EXIT_FAILURE, + "%s\n", dlerror()); + + // check if we need to append an underscore + auto us = [handle] + { + (void (*)(void))dlsym(handle, "usrdat_"); + if(handle) + return "_"; + else + return ""; + } (); + dlerror(); /* Clear any existing error */ + + char func[100]; + + nek_dssum_ptr = (void (*)(double *))dlsym(handle, nek::fname("nekf_dssum")); + (*nek_dssum_ptr)(u); + + double * mult = (double *)nek::ptr("vmult"); // velocity connectivity map + + for (int e = 0; e < mesh->Nelements; ++e) + { + for (int n = 0; n < mesh->Np; ++n) + { + int id = e * mesh->Np + n; + u[id] *= mult[id]; + } + } + +} + +void +computeRateOfStrainTensor(double * S_ij, const nek_mesh::NekMeshEnum pp_mesh) +{ + mesh_t * mesh = getMesh(pp_mesh); + nrs_t * nrs = (nrs_t *)nrsPtr(); + + // calculate velocity gradients + const int offset = nrs->fieldOffset; + + double * grad_u = (double *) calloc(3*offset, sizeof(double)); + double * grad_v = (double *) calloc(3*offset, sizeof(double)); + double * grad_w = (double *) calloc(3*offset, sizeof(double)); + + gradient(offset, &nrs->U[0*offset], grad_u, pp_mesh); + gradient(offset, &nrs->U[1*offset], grad_v, pp_mesh); + gradient(offset, &nrs->U[2*offset], grad_w, pp_mesh); + + for (int i = 0; i < 3; ++i) + { + nekDirectStiffnessAvg(&grad_u[i*offset], pp_mesh); + nekDirectStiffnessAvg(&grad_v[i*offset], pp_mesh); + nekDirectStiffnessAvg(&grad_w[i*offset], pp_mesh); + } + + // calculating the six S_ij components + for (int e = 0; e < mesh->Nelements; ++e) + { + for (int n = 0; n < mesh->Np; ++n) + { + int id = e * mesh->Np + n; + + S_ij[0*offset + id] = grad_u[0*offset + id]; // 0.5*(du/dx+du/dx) = S_11 + S_ij[1*offset + id] = grad_v[1*offset + id]; // 0.5*(dv/dy+dv/dy) = S_22 + S_ij[2*offset + id] = grad_w[2*offset + id]; // 0.5*(dw/dz+dw/dz) = S_33 + S_ij[3*offset + id] = 0.5*(grad_u[1*offset + id] + grad_v[0*offset + id]); // 0.5*(du/dy+dv/dx) = S_12 + S_ij[4*offset + id] = 0.5*(grad_v[2*offset + id] + grad_w[1*offset + id]); // 0.5*(dv/dz+dw/dy) = S_23 + S_ij[5*offset + id] = 0.5*(grad_u[2*offset + id] + grad_w[0*offset + id]); // 0.5*(du/dz+dw/dx) = S_13 + } + } + + freePointer(grad_u); + freePointer(grad_v); + freePointer(grad_w); +} + +void +computeStressTensor(double * Tau_ij,const nek_mesh::NekMeshEnum pp_mesh) +{ + mesh_t * mesh = getMesh(pp_mesh); + nrs_t * nrs = (nrs_t *)nrsPtr(); + + // add pressure to diagonal components + // TODO: enable variable viscosity + + int offset = nrs->fieldOffset; + + computeRateOfStrainTensor(Tau_ij,pp_mesh); + +// multiply by 2 * viscosity + for (int i = 0; i < 6; ++i) + { + for (int e = 0; e < mesh->Nelements; ++e) + { + for (int n = 0; n < mesh->Np; ++n) + { + int id = e * mesh->Np + n; + + Tau_ij[i*offset + id] *= 2.0 * viscosity(); + if (i < 3) + Tau_ij[i*offset + id ] -= nrs->P[id]; // subtract pressure from diagonal components + } + } + } +} + +void +computeTraction(double * traction, const nek_mesh::NekMeshEnum pp_mesh) +{ + mesh_t * mesh = getMesh(pp_mesh); + nrs_t * nrs = (nrs_t *)nrsPtr(); + + // get full stress tensor + int nrs_offset = nrs->fieldOffset; + double * Tau_ij = (double *) calloc(6*nrs_offset, sizeof(double)); + double traction_x, traction_y, traction_z, unx, uny, unz; + + computeStressTensor(Tau_ij,pp_mesh); + + // multiply with normal on moving boundary + for (int i = 0; i < mesh->Nelements; ++i) + { + for (int j = 0; j < mesh->Nfaces; ++j) + { + int face_bdry_id = mesh->EToB[i * mesh->Nfaces + j]; +// if (std::find(boundary_id.begin(), boundary_id.end(), face_bdry_id) != boundary_id.end()) + if (face_bdry_id > 0) + { + int offset = i * mesh->Nfaces * mesh->Nfp + j * mesh->Nfp; + + for (int v = 0; v < mesh->Nfp; ++v) + { + int vol_id = mesh->vmapM[offset + v]; + int surf_offset = mesh->Nsgeo * (offset + v); + + double nx = sgeo[surf_offset + NXID]; + double ny = sgeo[surf_offset + NYID]; + double nz = sgeo[surf_offset + NZID]; + + traction[nrs_offset*0 + vol_id] = Tau_ij[0*nrs_offset + vol_id] * nx + + Tau_ij[3*nrs_offset + vol_id] * ny + + Tau_ij[5*nrs_offset + vol_id] * nz; + + traction[nrs_offset*1 + vol_id] = Tau_ij[3*nrs_offset + vol_id] * nx + + Tau_ij[1*nrs_offset + vol_id] * ny + + Tau_ij[4*nrs_offset + vol_id] * nz; + + traction[nrs_offset*2 + vol_id] = Tau_ij[5*nrs_offset + vol_id] * nx + + Tau_ij[4*nrs_offset + vol_id] * ny + + Tau_ij[2*nrs_offset + vol_id] * nz; + + } + } + } + } + freePointer(Tau_ij); +} + +void +computeWallShearStress(double * tau_wall, const nek_mesh::NekMeshEnum pp_mesh) +{ + mesh_t * mesh = getMesh(pp_mesh); + nrs_t * nrs = (nrs_t *)nrsPtr(); + + // get full stress tensor + int nrs_offset = nrs->fieldOffset; + double * Tau_ij = (double *) calloc(6*nrs_offset, sizeof(double)); + + computeRateOfStrainTensor(Tau_ij,pp_mesh); + + // multiply with normal on moving boundary + for (int i = 0; i < mesh->Nelements; ++i) + { + for (int j = 0; j < mesh->Nfaces; ++j) + { + int face_bdry_id = mesh->EToB[i * mesh->Nfaces + j]; +// if (std::find(boundary_id.begin(), boundary_id.end(), face_bdry_id) != boundary_id.end()) + if (face_bdry_id > 0) + { + int offset = i * mesh->Nfaces * mesh->Nfp + j * mesh->Nfp; + + for (int v = 0; v < mesh->Nfp; ++v) + { + int vol_id = mesh->vmapM[offset + v]; + int surf_offset = mesh->Nsgeo * (offset + v); + + double visc_stress_vector_x = -2.0 * viscosity() * + ( Tau_ij[0*nrs_offset + vol_id] * sgeo[surf_offset + NXID] + + Tau_ij[3*nrs_offset + vol_id] * sgeo[surf_offset + NYID] + + Tau_ij[5*nrs_offset + vol_id] * sgeo[surf_offset + NZID]); + + double visc_stress_vector_y = -2.0 * viscosity() * + ( Tau_ij[3*nrs_offset + vol_id] * sgeo[surf_offset + NXID] + + Tau_ij[1*nrs_offset + vol_id] * sgeo[surf_offset + NYID] + + Tau_ij[4*nrs_offset + vol_id] * sgeo[surf_offset + NZID]); + + double visc_stress_vector_z = -2.0 * viscosity() * + ( Tau_ij[5*nrs_offset + vol_id] * sgeo[surf_offset + NXID] + + Tau_ij[4*nrs_offset + vol_id] * sgeo[surf_offset + NYID] + + Tau_ij[2*nrs_offset + vol_id] * sgeo[surf_offset + NZID]); + + tau_wall[vol_id]= visc_stress_vector_x * sgeo[surf_offset + T1XID] + + visc_stress_vector_y * sgeo[surf_offset + T1YID] + + visc_stress_vector_z * sgeo[surf_offset + T1ZID] ; + } + } + } + } + freePointer(Tau_ij); +} + bool isHeatFluxBoundary(const int boundary) { @@ -1443,6 +1756,84 @@ velocity(const int id) nrs->U[id + 2 * offset] * nrs->U[id + 2 * offset]); } +double +wall_shear(const int id) +{ + nrs_t * nrs = (nrs_t *)nrsPtr(); + return _wall_shear[id]; +} + +double +traction(const int id) +{ + nrs_t * nrs = (nrs_t *)nrsPtr(); + return _traction[id+ 3 * nrs->fieldOffset]; //TODO: decide whether to keep this or not +} + +double +traction_x(const int id) +{ + nrs_t * nrs = (nrs_t *)nrsPtr(); + return _traction[id + 0 * nrs->fieldOffset]; +} + +double +traction_y(const int id) +{ + nrs_t * nrs = (nrs_t *)nrsPtr(); + return _traction[id + 1 * nrs->fieldOffset]; +} + +double +traction_z(const int id) +{ + nrs_t * nrs = (nrs_t *)nrsPtr(); + return _traction[id + 2 * nrs->fieldOffset]; +} + +double +ros_s11(const int id) +{ + nrs_t * nrs = (nrs_t *)nrsPtr(); + return _ros_tensor[id + 0 * nrs->fieldOffset]; +} + + +double +ros_s22(const int id) +{ + nrs_t * nrs = (nrs_t *)nrsPtr(); + return _ros_tensor[id + 1 * nrs->fieldOffset]; +} + +double +ros_s33(const int id) +{ + nrs_t * nrs = (nrs_t *)nrsPtr(); + return _ros_tensor[id + 2 * nrs->fieldOffset]; +} + +double +ros_s12(const int id) +{ + nrs_t * nrs = (nrs_t *)nrsPtr(); + return _ros_tensor[id + 3 * nrs->fieldOffset]; +} + +double +ros_s23(const int id) +{ + nrs_t * nrs = (nrs_t *)nrsPtr(); + return _ros_tensor[id + 4 * nrs->fieldOffset]; +} + +double +ros_s13(const int id) +{ + nrs_t * nrs = (nrs_t *)nrsPtr(); + return _ros_tensor[id + 5 * nrs->fieldOffset]; +} + void flux(const int id, const dfloat value) { @@ -1548,6 +1939,39 @@ double (*solutionPointer(const field::NekFieldEnum & field))(int) "because your Nek case files do not have a scalar03 variable!"); f = &scalar03; break; + case field::wall_shear: + f = &wall_shear; + break; + case field::traction: + f = &traction; + break; + case field::traction_x: + f = &traction_x; + break; + case field::traction_y: + f = &traction_y; + break; + case field::traction_z: + f = &traction_z; + break; + case field::ros_s11: + f = &ros_s11; + break; + case field::ros_s22: + f = &ros_s22; + break; + case field::ros_s33: + f = &ros_s33; + break; + case field::ros_s12: + f = &ros_s12; + break; + case field::ros_s23: + f = &ros_s23; + break; + case field::ros_s13: + f = &ros_s13; + break; case field::unity: f = &unity; break; @@ -1684,6 +2108,39 @@ dimensionalize(const field::NekFieldEnum & field, double & value) case field::scalar03: // no dimensionalization needed break; + case field::wall_shear: + value = value * scales.rho_ref * scales.U_ref * scales.U_ref; + break; + case field::traction: + value = value * scales.rho_ref * scales.U_ref * scales.U_ref; + break; + case field::traction_x: + value = value * scales.rho_ref * scales.U_ref * scales.U_ref; + break; + case field::traction_y: + value = value * scales.rho_ref * scales.U_ref * scales.U_ref; + break; + case field::traction_z: + value = value * scales.rho_ref * scales.U_ref * scales.U_ref; + break; + case field::ros_s11: + value = value * scales.rho_ref * scales.U_ref * scales.U_ref; + break; + case field::ros_s22: + value = value * scales.rho_ref * scales.U_ref * scales.U_ref; + break; + case field::ros_s33: + value = value * scales.rho_ref * scales.U_ref * scales.U_ref; + break; + case field::ros_s12: + value = value * scales.rho_ref * scales.U_ref * scales.U_ref; + break; + case field::ros_s23: + value = value * scales.rho_ref * scales.U_ref * scales.U_ref; + break; + case field::ros_s13: + value = value * scales.rho_ref * scales.U_ref * scales.U_ref; + break; case field::unity: // no dimensionalization needed break; diff --git a/src/base/NekRSProblem.C b/src/base/NekRSProblem.C index 5e3e3b45f..660e1199e 100644 --- a/src/base/NekRSProblem.C +++ b/src/base/NekRSProblem.C @@ -687,6 +687,11 @@ NekRSProblem::syncSolutions(ExternalProblem::Direction direction) _console << " Interpolated temperature min/max values: " << minInterpolatedTemperature() << ", " << maxInterpolatedTemperature() << std::endl; + if (isParamValid("output") && _outputs->contains("traction") ) + nekrs::computeTraction(nekrs::getTraction(), nek_mesh::fluid); + + if (isParamValid("output") && _outputs->contains("wall_shear") ) + nekrs::computeWallShearStress(nekrs::getWallShear(), nek_mesh::fluid); // extract all outputs (except temperature, which we did separately here). We could // have simply called the base class NekRSProblemBase::syncSolutions to do this, but // putting this here lets us use a consistent setting for the minimize transfers feature, diff --git a/src/base/NekRSProblemBase.C b/src/base/NekRSProblemBase.C index fae84e6fa..8f29a538a 100644 --- a/src/base/NekRSProblemBase.C +++ b/src/base/NekRSProblemBase.C @@ -70,7 +70,7 @@ NekRSProblemBase::validParams() params.addRangeCheckedParam( "Cp_0", 1.0, "Cp_0 > 0.0", "Heat capacity parameter value for non-dimensional solution"); - MultiMooseEnum nek_outputs("temperature pressure velocity scalar01 scalar02 scalar03"); + MultiMooseEnum nek_outputs("temperature pressure velocity scalar01 scalar02 scalar03 traction ros_tensor wall_shear"); params.addParam( "output", nek_outputs, "Field(s) to output from NekRS onto the mesh mirror"); @@ -751,7 +751,6 @@ void NekRSProblemBase::syncSolutions(ExternalProblem::Direction direction) { auto & solution = _aux->solution(); - if (!isDataTransferHappening(direction)) return; @@ -777,6 +776,16 @@ NekRSProblemBase::syncSolutions(ExternalProblem::Direction direction) } case ExternalProblem::Direction::FROM_EXTERNAL_APP: { + + if(isParamValid("output") && _outputs->contains("traction")) + nekrs::computeTraction(nekrs::getTraction(), nek_mesh::fluid); + + if(isParamValid("output") && _outputs->contains("wall_shear")) + nekrs::computeWallShearStress(nekrs::getWallShear(), nek_mesh::fluid); + + if(isParamValid("output") && _outputs->contains("ros_tensor")) + nekrs::computeRateOfStrainTensor(nekrs::getRateOfStrainTensor(), nek_mesh::fluid); + // extract the NekRS solution onto the mesh mirror, if specified extractOutputs(); break; @@ -901,6 +910,28 @@ NekRSProblemBase::extractOutputs() field_enum = field::scalar02; else if (_var_names[i] == "scalar03") field_enum = field::scalar03; + else if (_var_names[i] == "wall_shear") + field_enum = field::wall_shear; + else if (_var_names[i] == "traction") + field_enum = field::traction; + else if (_var_names[i] == "traction_x") + field_enum = field::traction_x; + else if (_var_names[i] == "traction_y") + field_enum = field::traction_y; + else if (_var_names[i] == "traction_z") + field_enum = field::traction_z; + else if (_var_names[i] == "ros_s11") + field_enum = field::ros_s11; + else if (_var_names[i] == "ros_s22") + field_enum = field::ros_s22; + else if (_var_names[i] == "ros_s33") + field_enum = field::ros_s33; + else if (_var_names[i] == "ros_s12") + field_enum = field::ros_s12; + else if (_var_names[i] == "ros_s23") + field_enum = field::ros_s23; + else if (_var_names[i] == "ros_s13") + field_enum = field::ros_s13; else mooseError("Unhandled NekFieldEnum in NekRSProblemBase!"); @@ -975,6 +1006,29 @@ NekRSProblemBase::addExternalVariables() _var_names.push_back("scalar02"); else if (output == "scalar03") _var_names.push_back("scalar03"); + else if (output == "wall_shear") + { + _var_names.push_back("wall_shear"); + nekrs::initializeWallShear(); + } + else if (output == "traction") + { + _var_names.push_back("traction"); + _var_names.push_back("traction_x"); + _var_names.push_back("traction_y"); + _var_names.push_back("traction_z"); + nekrs::initializeTraction(); + } + else if (output == "ros_tensor") + { + _var_names.push_back("ros_s11"); + _var_names.push_back("ros_s22"); + _var_names.push_back("ros_s33"); + _var_names.push_back("ros_s12"); + _var_names.push_back("ros_s23"); + _var_names.push_back("ros_s13"); + nekrs::initializeRateOfStrainTensor(); + } } _var_string = ""; @@ -983,7 +1037,6 @@ NekRSProblemBase::addExternalVariables() checkDuplicateVariableName(name); addAuxVariable("MooseVariable", name, var_params); _external_vars.push_back(_aux->getFieldVariable(0, name).number()); - _var_string += " " + name + ","; } diff --git a/test/tests/traction/rate_of_strain_x/gold/nek_out.csv b/test/tests/traction/rate_of_strain_x/gold/nek_out.csv new file mode 100644 index 000000000..b3918876e --- /dev/null +++ b/test/tests/traction/rate_of_strain_x/gold/nek_out.csv @@ -0,0 +1,2 @@ +time,ros_s11_error,ros_s11_vavg,ros_s12_error,ros_s12_vavg,ros_s13_error,ros_s13_vavg,ros_s22_error,ros_s22_vavg,ros_s23_error,ros_s23_vavg,ros_s33_error,ros_s33_vavg +0.02,2.3268218478618e-08,2.1169696121773e-13,4.2767723580912e-06,2.8834432303227e-08,4.2751943381446e-06,3.3221517139728e-08,1.6235016770492e-08,-1.9101063453238e-14,1.0114682258635e-08,-6.7063481309453e-15,1.885344578528e-08,5.0755011085241e-15 diff --git a/test/tests/traction/rate_of_strain_x/nek.i b/test/tests/traction/rate_of_strain_x/nek.i new file mode 100644 index 000000000..680318ab0 --- /dev/null +++ b/test/tests/traction/rate_of_strain_x/nek.i @@ -0,0 +1,119 @@ +[Mesh] + type = NekRSMesh + order = SECOND + volume = true + parallel_type = replicated +[] + +[Problem] + type = NekRSStandaloneProblem + output = "ros_tensor" + casename = 'pipe' +[] + +[Functions] + [s_11_exact] + type = ParsedFunction + expression = 0.0 + [] + [s_22_exact] + type = ParsedFunction + expression = 0.0 + [] + [s_33_exact] + type = ParsedFunction + expression = 0.0 + [] + [s_23_exact] + type = ParsedFunction + expression = 0.0 + [] + [s_12_exact] + type = ParsedFunction + expression = '-y*u0/R/R' + symbol_names = 'R u0' + symbol_values = '0.01 2.0' + [] + [s_13_exact] + type = ParsedFunction + expression = '-z*u0/R/R' + symbol_names = 'R u0' + symbol_values = '0.01 2.0' + [] +[] + +[Executioner] + type = Transient + + [TimeStepper] + type = NekTimeStepper + [] + + [Quadrature] + type = GAUSS_LOBATTO + order = FIFTH + [] +[] + +[Postprocessors] + [ros_s11_error] + type = ElementL2Error + variable = ros_s11 + function = s_11_exact + [] + [ros_s22_error] + type = ElementL2Error + variable = ros_s22 + function = s_22_exact + [] + [ros_s33_error] + type = ElementL2Error + variable = ros_s33 + function = s_33_exact + [] + [ros_s12_error] + type = ElementL2Error + variable = ros_s12 + function = s_12_exact + [] + [ros_s23_error] + type = ElementL2Error + variable = ros_s23 + function = s_23_exact + [] + [ros_s13_error] + type = ElementL2Error + variable = ros_s13 + function = s_13_exact + [] + [ros_s11_vavg] + type = NekVolumeAverage + field = ros_s11 + [] + [ros_s22_vavg] + type = NekVolumeAverage + field = ros_s22 + [] + [ros_s33_vavg] + type = NekVolumeAverage + field = ros_s33 + [] + [ros_s12_vavg] + type = NekVolumeAverage + field = ros_s12 + [] + [ros_s13_vavg] + type = NekVolumeAverage + field = ros_s13 + [] + [ros_s23_vavg] + type = NekVolumeAverage + field = ros_s23 + [] +[] + +[Outputs] + exodus = false + csv = true + execute_on = 'final' +[] diff --git a/test/tests/traction/rate_of_strain_x/pipe.par b/test/tests/traction/rate_of_strain_x/pipe.par new file mode 100644 index 000000000..3f261580e --- /dev/null +++ b/test/tests/traction/rate_of_strain_x/pipe.par @@ -0,0 +1,22 @@ +[GENERAL] + polynomialOrder = 3 + numSteps = 200 + dt = 1e-4 + timeStepper = tombo2 + constFlowRate = meanVelocity=1.0 + direction=X + writeInterval = 201 + +[MESH] + file = "turbPipe.re2" + +[PRESSURE] + residualTol = 1e-10 + +[VELOCITY] + density = 1.0 + viscosity = -100.0 + boundaryTypeMap = wall + residualTol = 1e-12 + +[TEMPERATURE] + solver = none diff --git a/test/tests/traction/rate_of_strain_x/pipe.udf b/test/tests/traction/rate_of_strain_x/pipe.udf new file mode 100644 index 000000000..0eae5e3c2 --- /dev/null +++ b/test/tests/traction/rate_of_strain_x/pipe.udf @@ -0,0 +1,41 @@ +// +// nekRS User Defined File +// +#include +#include "udf.hpp" + +#ifdef __okl__ + +#endif + +/* UDF Functions */ + +void UDF_LoadKernels(occa::properties& kernelInfo) +{ +} + + +void UDF_Setup(nrs_t *nrs) +{ + mesh_t* mesh = nrs->cds->mesh[0]; + int num_quadrature_points = mesh->Np * mesh->Nelements; + + float Rsq = 1.e-2*1.e-2; + float u0 = 2.0; + + for (int n = 0; n < num_quadrature_points; n++) { + float yy = mesh->y[n]; + float zz = mesh->z[n]; + + float rr = zz*zz + yy*yy; + nrs->U[n + 0 * nrs->fieldOffset] = u0*(1.0-(rr/Rsq)); + nrs->U[n + 1 * nrs->fieldOffset] = 0.0; + nrs->U[n + 2 * nrs->fieldOffset] = 0.0; + + nrs->cds->S[n + 0 * nrs->cds->fieldOffset[0]] = 0.0; + } +} + +void UDF_ExecuteStep(nrs_t *nrs, dfloat time, int tstep) +{ +} diff --git a/test/tests/traction/rate_of_strain_x/pipe.usr b/test/tests/traction/rate_of_strain_x/pipe.usr new file mode 100644 index 000000000..b251d6fb8 --- /dev/null +++ b/test/tests/traction/rate_of_strain_x/pipe.usr @@ -0,0 +1,53 @@ +c----------------------------------------------------------------------- + subroutine userchk + implicit none + include 'SIZE' + include 'TOTAL' + + return + end +c----------------------------------------------------------------------- + subroutine usrdat + + return + end +c----------------------------------------------------------------------- + subroutine usrdat2 + implicit none + include 'SIZE' + include 'TOTAL' + + integer iel, ifc, i, ntot + real theta, xx, zz, fac + + do iel=1,nelt + do ifc=1,2*ndim + if (cbc(ifc,iel,1) .eq. 'W ') boundaryID(ifc,iel) = 1 + enddo + enddo + + theta = pi/2.0 + ntot = lx1*ly1*lz1*nelv + do i = 1, ntot + xx = xm1(i,1,1,1) + zz = zm1(i,1,1,1) + xm1(i,1,1,1) = xx*cos(theta) - zz*sin(theta) + 6.0 + zm1(i,1,1,1) = xx*sin(theta) + zz*cos(theta) + enddo + + fac = 2.0e-2 + + call cmult(xm1,fac,ntot) + call cmult(ym1,fac,ntot) + call cmult(zm1,fac,ntot) + + return + end +c----------------------------------------------------------------------- + subroutine usrdat3 + + include 'SIZE' + include 'TOTAL' + + return + end diff --git a/test/tests/traction/rate_of_strain_x/tests b/test/tests/traction/rate_of_strain_x/tests new file mode 100644 index 000000000..b75a73e3e --- /dev/null +++ b/test/tests/traction/rate_of_strain_x/tests @@ -0,0 +1,12 @@ +[Tests] + [test] + type = CSVDiff + input = nek.i + csvdiff = nek_out.csv + min_parallel = 64 + requirement = "Cardinal shall be able to calculate the rate-of-strain tensor components" + "to an acceptable tolerance for a pipe with laminar flow along the x-axis." + required_objects = 'NekRSStandaloneProblem' + max_time = 500 + [] +[] diff --git a/test/tests/traction/rate_of_strain_x/turbPipe.re2 b/test/tests/traction/rate_of_strain_x/turbPipe.re2 new file mode 120000 index 000000000..0092b032d --- /dev/null +++ b/test/tests/traction/rate_of_strain_x/turbPipe.re2 @@ -0,0 +1 @@ +/home/achaube/repos/cardinal/install/examples/turbPipePeriodic/turbPipe.re2 \ No newline at end of file diff --git a/test/tests/traction/rate_of_strain_y/gold/nek_out.csv b/test/tests/traction/rate_of_strain_y/gold/nek_out.csv new file mode 100644 index 000000000..773bcfd8d --- /dev/null +++ b/test/tests/traction/rate_of_strain_y/gold/nek_out.csv @@ -0,0 +1,2 @@ +time,ros_s11_error,ros_s11_vavg,ros_s12_error,ros_s12_vavg,ros_s13_error,ros_s13_vavg,ros_s22_error,ros_s22_vavg,ros_s23_error,ros_s23_vavg,ros_s33_error,ros_s33_vavg +0.02,9.3263294195597e-09,1.1318856562756e-17,3.9467715205893e-07,1.4013465592343e-08,3.7765186167758e-09,-2.6227298322257e-16,4.3153147977142e-08,8.6957743183345e-13,4.006298982627e-07,1.1556920422438e-08,3.8203089050921e-09,-1.2236402134721e-15 diff --git a/test/tests/traction/rate_of_strain_y/nek.i b/test/tests/traction/rate_of_strain_y/nek.i new file mode 100644 index 000000000..db4df4d91 --- /dev/null +++ b/test/tests/traction/rate_of_strain_y/nek.i @@ -0,0 +1,119 @@ +[Mesh] + type = NekRSMesh + order = SECOND + volume = true + parallel_type = replicated +[] + +[Problem] + type = NekRSStandaloneProblem + output = "ros_tensor" + casename = 'pipe' +[] + +[Functions] + [s_11_exact] + type = ParsedFunction + expression = 0.0 + [] + [s_22_exact] + type = ParsedFunction + expression = 0.0 + [] + [s_33_exact] + type = ParsedFunction + expression = 0.0 + [] + [s_13_exact] + type = ParsedFunction + expression = 0.0 + [] + [s_12_exact] + type = ParsedFunction + expression = '-x*u0/R/R' + symbol_names = 'R u0' + symbol_values = '0.01 2.0' + [] + [s_23_exact] + type = ParsedFunction + expression = '-z*u0/R/R' + symbol_names = 'R u0' + symbol_values = '0.01 2.0' + [] +[] + +[Executioner] + type = Transient + + [TimeStepper] + type = NekTimeStepper + [] + + [Quadrature] + type = GAUSS_LOBATTO + order = FIFTH + [] +[] + +[Postprocessors] + [ros_s11_error] + type = ElementL2Error + variable = ros_s11 + function = s_11_exact + [] + [ros_s22_error] + type = ElementL2Error + variable = ros_s22 + function = s_22_exact + [] + [ros_s33_error] + type = ElementL2Error + variable = ros_s33 + function = s_33_exact + [] + [ros_s12_error] + type = ElementL2Error + variable = ros_s12 + function = s_12_exact + [] + [ros_s23_error] + type = ElementL2Error + variable = ros_s23 + function = s_23_exact + [] + [ros_s13_error] + type = ElementL2Error + variable = ros_s13 + function = s_13_exact + [] + [ros_s11_vavg] + type = NekVolumeAverage + field = ros_s11 + [] + [ros_s22_vavg] + type = NekVolumeAverage + field = ros_s22 + [] + [ros_s33_vavg] + type = NekVolumeAverage + field = ros_s33 + [] + [ros_s12_vavg] + type = NekVolumeAverage + field = ros_s12 + [] + [ros_s13_vavg] + type = NekVolumeAverage + field = ros_s13 + [] + [ros_s23_vavg] + type = NekVolumeAverage + field = ros_s23 + [] +[] + +[Outputs] + exodus = false + csv = true + execute_on = 'final' +[] diff --git a/test/tests/traction/rate_of_strain_y/pipe.par b/test/tests/traction/rate_of_strain_y/pipe.par new file mode 100644 index 000000000..4ec42c21c --- /dev/null +++ b/test/tests/traction/rate_of_strain_y/pipe.par @@ -0,0 +1,22 @@ +[GENERAL] + polynomialOrder = 5 + numSteps = 200 + dt = 1e-4 + timeStepper = tombo2 + constFlowRate = meanVelocity=1.0 + direction=Y + writeInterval = 201 + +[MESH] + file = "turbPipe.re2" + +[PRESSURE] + residualTol = 1e-10 + +[VELOCITY] + density = 1.0 + viscosity = -100.0 + boundaryTypeMap = wall + residualTol = 1e-12 + +[TEMPERATURE] + solver = none diff --git a/test/tests/traction/rate_of_strain_y/pipe.udf b/test/tests/traction/rate_of_strain_y/pipe.udf new file mode 100644 index 000000000..16d2dd1fe --- /dev/null +++ b/test/tests/traction/rate_of_strain_y/pipe.udf @@ -0,0 +1,41 @@ +// +// nekRS User Defined File +// +#include +#include "udf.hpp" + +#ifdef __okl__ + +#endif + +/* UDF Functions */ + +void UDF_LoadKernels(occa::properties& kernelInfo) +{ +} + + +void UDF_Setup(nrs_t *nrs) +{ + mesh_t* mesh = nrs->cds->mesh[0]; + int num_quadrature_points = mesh->Np * mesh->Nelements; + + float Rsq = 1.e-2*1.e-2; + float u0 = 2.0; + + for (int n = 0; n < num_quadrature_points; n++) { + float xx = mesh->x[n]; + float zz = mesh->z[n]; + + float rr = xx*xx + zz*zz; + nrs->U[n + 0 * nrs->fieldOffset] = 0.0; + nrs->U[n + 1 * nrs->fieldOffset] = u0*(1.0-(rr/Rsq)); + nrs->U[n + 2 * nrs->fieldOffset] = 0.0; + + nrs->cds->S[n + 0 * nrs->cds->fieldOffset[0]] = 0.0; + } +} + +void UDF_ExecuteStep(nrs_t *nrs, dfloat time, int tstep) +{ +} diff --git a/test/tests/traction/rate_of_strain_y/pipe.usr b/test/tests/traction/rate_of_strain_y/pipe.usr new file mode 100644 index 000000000..8f65acb8d --- /dev/null +++ b/test/tests/traction/rate_of_strain_y/pipe.usr @@ -0,0 +1,53 @@ +c----------------------------------------------------------------------- + subroutine userchk + implicit none + include 'SIZE' + include 'TOTAL' + + return + end +c----------------------------------------------------------------------- + subroutine usrdat + + return + end +c----------------------------------------------------------------------- + subroutine usrdat2 + implicit none + include 'SIZE' + include 'TOTAL' + + integer iel, ifc, i, ntot + real theta, yy, zz, fac + + do iel=1,nelt + do ifc=1,2*ndim + if (cbc(ifc,iel,1) .eq. 'W ') boundaryID(ifc,iel) = 1 + enddo + enddo + + theta = pi/2.0 + ntot = lx1*ly1*lz1*nelv + do i = 1, ntot + yy = ym1(i,1,1,1) + zz = zm1(i,1,1,1) + ym1(i,1,1,1) = yy*cos(theta) - zz*sin(theta) + 6.0 + zm1(i,1,1,1) = yy*sin(theta) + zz*cos(theta) + enddo + + fac = 2.0e-2 + + call cmult(xm1,fac,ntot) + call cmult(ym1,fac,ntot) + call cmult(zm1,fac,ntot) + + return + end +c----------------------------------------------------------------------- + subroutine usrdat3 + + include 'SIZE' + include 'TOTAL' + + return + end diff --git a/test/tests/traction/rate_of_strain_y/tests b/test/tests/traction/rate_of_strain_y/tests new file mode 100644 index 000000000..a2b3e38fb --- /dev/null +++ b/test/tests/traction/rate_of_strain_y/tests @@ -0,0 +1,12 @@ +[Tests] + [test] + type = CSVDiff + input = nek.i + csvdiff = nek_out.csv + min_parallel = 64 + requirement = "Cardinal shall be able to calculate the rate-of-strain tensor components" + "to an acceptable tolerance for a pipe with laminar flow along the y-axis." + required_objects = 'NekRSStandaloneProblem' + max_time = 500 + [] +[] diff --git a/test/tests/traction/rate_of_strain_y/turbPipe.re2 b/test/tests/traction/rate_of_strain_y/turbPipe.re2 new file mode 120000 index 000000000..0092b032d --- /dev/null +++ b/test/tests/traction/rate_of_strain_y/turbPipe.re2 @@ -0,0 +1 @@ +/home/achaube/repos/cardinal/install/examples/turbPipePeriodic/turbPipe.re2 \ No newline at end of file diff --git a/test/tests/traction/rate_of_strain_z/gold/nek_out.csv b/test/tests/traction/rate_of_strain_z/gold/nek_out.csv new file mode 100644 index 000000000..bfe11ba38 --- /dev/null +++ b/test/tests/traction/rate_of_strain_z/gold/nek_out.csv @@ -0,0 +1,2 @@ +time,ros_s11_error,ros_s11_vavg,ros_s12_error,ros_s12_vavg,ros_s13_error,ros_s13_vavg,ros_s22_error,ros_s22_vavg,ros_s23_error,ros_s23_vavg,ros_s33_error,ros_s33_vavg +0.02,9.3263303418705e-09,6.1024077184947e-17,3.7765141299345e-09,-3.4494839706871e-17,3.9467713505069e-07,1.4009379607922e-08,3.8203133372565e-09,-1.5859733485176e-16,4.0062995509953e-07,1.1553868336591e-08,4.3153063908273e-08,-2.583699863214e-12 diff --git a/test/tests/traction/rate_of_strain_z/nek.i b/test/tests/traction/rate_of_strain_z/nek.i new file mode 100644 index 000000000..2e8905e4d --- /dev/null +++ b/test/tests/traction/rate_of_strain_z/nek.i @@ -0,0 +1,119 @@ +[Mesh] + type = NekRSMesh + order = SECOND + volume = true + parallel_type = replicated +[] + +[Problem] + type = NekRSStandaloneProblem + output = "ros_tensor" + casename = 'pipe' +[] + +[Functions] + [s_11_exact] + type = ParsedFunction + expression = 0.0 + [] + [s_22_exact] + type = ParsedFunction + expression = 0.0 + [] + [s_33_exact] + type = ParsedFunction + expression = 0.0 + [] + [s_12_exact] + type = ParsedFunction + expression = 0.0 + [] + [s_13_exact] + type = ParsedFunction + expression = '-x*u0/R/R' + symbol_names = 'R u0' + symbol_values = '0.01 2.0' + [] + [s_23_exact] + type = ParsedFunction + expression = '-y*u0/R/R' + symbol_names = 'R u0' + symbol_values = '0.01 2.0' + [] +[] + +[Executioner] + type = Transient + + [TimeStepper] + type = NekTimeStepper + [] + + [Quadrature] + type = GAUSS_LOBATTO + order = FIFTH + [] +[] + +[Postprocessors] + [ros_s11_error] + type = ElementL2Error + variable = ros_s11 + function = s_11_exact + [] + [ros_s22_error] + type = ElementL2Error + variable = ros_s22 + function = s_22_exact + [] + [ros_s33_error] + type = ElementL2Error + variable = ros_s33 + function = s_33_exact + [] + [ros_s12_error] + type = ElementL2Error + variable = ros_s12 + function = s_12_exact + [] + [ros_s23_error] + type = ElementL2Error + variable = ros_s23 + function = s_23_exact + [] + [ros_s13_error] + type = ElementL2Error + variable = ros_s13 + function = s_13_exact + [] + [ros_s11_vavg] + type = NekVolumeAverage + field = ros_s11 + [] + [ros_s22_vavg] + type = NekVolumeAverage + field = ros_s22 + [] + [ros_s33_vavg] + type = NekVolumeAverage + field = ros_s33 + [] + [ros_s12_vavg] + type = NekVolumeAverage + field = ros_s12 + [] + [ros_s13_vavg] + type = NekVolumeAverage + field = ros_s13 + [] + [ros_s23_vavg] + type = NekVolumeAverage + field = ros_s23 + [] +[] + +[Outputs] + exodus = false + csv = true + execute_on = 'final' +[] diff --git a/test/tests/traction/rate_of_strain_z/pipe.par b/test/tests/traction/rate_of_strain_z/pipe.par new file mode 100644 index 000000000..e3e6404d0 --- /dev/null +++ b/test/tests/traction/rate_of_strain_z/pipe.par @@ -0,0 +1,22 @@ +[GENERAL] + polynomialOrder = 5 + numSteps = 200 + dt = 1e-4 + timeStepper = tombo2 + constFlowRate = meanVelocity=1.0 + direction=Z + writeInterval = 201 + +[MESH] + file = "turbPipe.re2" + +[PRESSURE] + residualTol = 1e-10 + +[VELOCITY] + density = 1.0 + viscosity = -100.0 + boundaryTypeMap = wall + residualTol = 1e-12 + +[TEMPERATURE] + solver = none diff --git a/test/tests/traction/rate_of_strain_z/pipe.udf b/test/tests/traction/rate_of_strain_z/pipe.udf new file mode 100644 index 000000000..7f46169a7 --- /dev/null +++ b/test/tests/traction/rate_of_strain_z/pipe.udf @@ -0,0 +1,41 @@ +// +// nekRS User Defined File +// +#include +#include "udf.hpp" + +#ifdef __okl__ + +#endif + +/* UDF Functions */ + +void UDF_LoadKernels(occa::properties& kernelInfo) +{ +} + + +void UDF_Setup(nrs_t *nrs) +{ + mesh_t* mesh = nrs->cds->mesh[0]; + int num_quadrature_points = mesh->Np * mesh->Nelements; + + float Rsq = 1.e-2*1.e-2; + float u0 = 2.0; + + for (int n = 0; n < num_quadrature_points; n++) { + float xx = mesh->x[n]; + float yy = mesh->y[n]; + + float rr = xx*xx + yy*yy; + nrs->U[n + 0 * nrs->fieldOffset] = 0.0; + nrs->U[n + 1 * nrs->fieldOffset] = 0.0; + nrs->U[n + 2 * nrs->fieldOffset] = u0*(1.0-(rr/Rsq)); + + nrs->cds->S[n + 0 * nrs->cds->fieldOffset[0]] = 0.0; + } +} + +void UDF_ExecuteStep(nrs_t *nrs, dfloat time, int tstep) +{ +} diff --git a/test/tests/traction/rate_of_strain_z/pipe.usr b/test/tests/traction/rate_of_strain_z/pipe.usr new file mode 100644 index 000000000..543de50d6 --- /dev/null +++ b/test/tests/traction/rate_of_strain_z/pipe.usr @@ -0,0 +1,46 @@ +c----------------------------------------------------------------------- + subroutine userchk + implicit none + include 'SIZE' + include 'TOTAL' + + return + end +c----------------------------------------------------------------------- + subroutine usrdat + + return + end +c----------------------------------------------------------------------- + subroutine usrdat2 + implicit none + include 'SIZE' + include 'TOTAL' + + integer iel, ifc, i, ntot + real theta, xx, zz, fac + + do iel=1,nelt + do ifc=1,2*ndim + if (cbc(ifc,iel,1) .eq. 'W ') boundaryID(ifc,iel) = 1 + enddo + enddo + + ntot = lx1*ly1*lz1*nelv + + fac = 2.0e-2 + + call cmult(xm1,fac,ntot) + call cmult(ym1,fac,ntot) + call cmult(zm1,fac,ntot) + + return + end +c----------------------------------------------------------------------- + subroutine usrdat3 + + include 'SIZE' + include 'TOTAL' + + return + end diff --git a/test/tests/traction/rate_of_strain_z/tests b/test/tests/traction/rate_of_strain_z/tests new file mode 100644 index 000000000..f14101b3a --- /dev/null +++ b/test/tests/traction/rate_of_strain_z/tests @@ -0,0 +1,12 @@ +[Tests] + [test] + type = CSVDiff + input = nek.i + csvdiff = nek_out.csv + min_parallel = 64 + requirement = "Cardinal shall be able to calculate the rate-of-strain tensor components" + "to an acceptable tolerance for a pipe with laminar flow along the z-axis." + required_objects = 'NekRSStandaloneProblem' + max_time = 500 + [] +[] diff --git a/test/tests/traction/rate_of_strain_z/turbPipe.re2 b/test/tests/traction/rate_of_strain_z/turbPipe.re2 new file mode 120000 index 000000000..0092b032d --- /dev/null +++ b/test/tests/traction/rate_of_strain_z/turbPipe.re2 @@ -0,0 +1 @@ +/home/achaube/repos/cardinal/install/examples/turbPipePeriodic/turbPipe.re2 \ No newline at end of file diff --git a/test/tests/traction/wall_shear/cylinder.par b/test/tests/traction/wall_shear/cylinder.par new file mode 100644 index 000000000..285e61387 --- /dev/null +++ b/test/tests/traction/wall_shear/cylinder.par @@ -0,0 +1,20 @@ +[GENERAL] + polynomialOrder = 4 + stopAt = endTime #numSteps + endTime = 1 + dt = 1.0e-2 + timeStepper = tombo2 + writeControl = simulationTime + writeInterval = 12 + +[PRESSURE] + residualTol = 1e-12 + +[VELOCITY] + density = 1.0 + viscosity = -104.0 + boundaryTypeMap = inlet,outlet,wall,sym,sym + residualTol = 1e-14 + +[TEMPERATURE] + solver = none diff --git a/test/tests/traction/wall_shear/cylinder.re2 b/test/tests/traction/wall_shear/cylinder.re2 new file mode 100644 index 000000000..46a9da3c6 Binary files /dev/null and b/test/tests/traction/wall_shear/cylinder.re2 differ diff --git a/test/tests/traction/wall_shear/cylinder.udf b/test/tests/traction/wall_shear/cylinder.udf new file mode 100644 index 000000000..781181bcd --- /dev/null +++ b/test/tests/traction/wall_shear/cylinder.udf @@ -0,0 +1,38 @@ +// +// nekRS User Defined File +// +#include "udf.hpp" + +#ifdef __okl__ + +void velocityDirichletConditions(bcData *bc) +{ + if (bc->id==1) + { + bc->u = 1.0; + bc->v = 0.0; + bc->w = 0.0; + } +} + +#endif + +/* UDF Functions */ + +void UDF_Setup(nrs_t *nrs) +{ + mesh_t* mesh = nrs->cds->mesh[0]; + int num_quadrature_points = mesh->Np * mesh->Nelements; + + for (int n = 0; n < num_quadrature_points; n++) { + nrs->U[n + 0 * nrs->fieldOffset] = 0.001; + nrs->U[n + 1 * nrs->fieldOffset] = 0.001; + nrs->U[n + 2 * nrs->fieldOffset] = 0.001; + + nrs->cds->S[n + 0 * nrs->cds->fieldOffset[0]] = 0.0; + } +} + +void UDF_ExecuteStep(nrs_t *nrs, dfloat time, int tstep) +{ +} diff --git a/test/tests/traction/wall_shear/cylinder.usr b/test/tests/traction/wall_shear/cylinder.usr new file mode 100644 index 000000000..ab57a0ebd --- /dev/null +++ b/test/tests/traction/wall_shear/cylinder.usr @@ -0,0 +1,40 @@ +c----------------------------------------------------------------------- + subroutine userchk + implicit none + include 'SIZE' + include 'TOTAL' + + + return + end +c----------------------------------------------------------------------- + subroutine usrdat + + return + end +c----------------------------------------------------------------------- + subroutine usrdat2 + implicit none + include 'SIZE' + include 'TOTAL' + + integer e, f + + do e = 1, nelv + do f = 1, 2*ndim + if (boundaryID(f,e).ge.6) boundaryID(f,e) = 0 ! periodic sideset + enddo + enddo + + + + return + end +c----------------------------------------------------------------------- + subroutine usrdat3 + + include 'SIZE' + include 'TOTAL' + + return + end diff --git a/test/tests/traction/wall_shear/gold/nek_out.csv b/test/tests/traction/wall_shear/gold/nek_out.csv new file mode 100644 index 000000000..10ee1c62b --- /dev/null +++ b/test/tests/traction/wall_shear/gold/nek_out.csv @@ -0,0 +1,2 @@ +time,avg_theta01,avg_theta02,avg_theta03,avg_theta04,avg_theta05,avg_theta06,avg_theta07,avg_theta08,avg_theta09,avg_theta10,avg_theta11,avg_theta12,avg_theta13,avg_theta14,avg_theta15,avg_theta16,avg_theta17,avg_theta18,avg_theta19,avg_theta20,avg_theta21,avg_theta22,avg_theta23,avg_theta24,avg_theta25,avg_theta26,avg_theta27,avg_theta28,avg_theta29,avg_theta30,avg_theta31,avg_theta32,avg_theta33,avg_theta34,avg_theta35 +1,0.039028878352681,0.077474602996629,0.11762920609738,0.14618494906744,0.17905753442241,0.2157879525474,0.23487495551671,0.25732346184855,0.27972234052635,0.28755586582247,0.30499027495266,0.29152304561331,0.2874541584449,0.29192293144022,0.27137774089827,0.25696954112047,0.24470565390564,0.21564454288983,0.19285319010959,0.18036565474334,0.15211242644685,0.12990309778542,0.11265922570782,0.089131208618649,0.070365905734458,0.052382776615498,0.032864055324468,0.017979634722945,0.0071109254915994,-0.00085193325614683,-0.005667305204335,-0.0078363093795934,-0.0065490377577147,-0.0033683266829063,9.6049712134015e-06 diff --git a/test/tests/traction/wall_shear/nek.i b/test/tests/traction/wall_shear/nek.i new file mode 100644 index 000000000..c4e28b238 --- /dev/null +++ b/test/tests/traction/wall_shear/nek.i @@ -0,0 +1,749 @@ +# The test compares the wall shear data from Dimopoulos & Hanratty, 1968, J.Fluid.Mech +# vs. wall shear from Cardinal. The test is coarse-grid and has a short run time to keep it lightweight. +# It reproduces the experimental data well. When the simulation is run for a few flow-throughs with a finer mesh, +# averaging the shear data after the vortex shedding starts (~100 non-dimensional time units) further +# improves agreement with the experimental data. + +# The wall shear data was chosen from the Re=104 experiment, and non-dimensionalized with the dynamic pressure +# i.e density * U * U + +[Mesh] + type = NekRSMesh + order = FIRST + volume = true + exact = true + parallel_type = replicated +[] + +[Problem] + type = NekRSStandaloneProblem + casename = 'cylinder' + output = 'wall_shear' + synchronization_interval = constant +[] + +[Outputs] + exodus = false + csv = true + execute_on = 'FINAL' + show = "avg_theta01 avg_theta02 avg_theta03 avg_theta04 avg_theta05 avg_theta06 avg_theta07 " + "avg_theta08 avg_theta09 avg_theta10 avg_theta11 avg_theta12 avg_theta13 avg_theta14 " + "avg_theta15 avg_theta16 avg_theta17 avg_theta18 avg_theta19 avg_theta20 avg_theta21 " + "avg_theta22 avg_theta23 avg_theta24 avg_theta25 avg_theta26 avg_theta27 avg_theta28 " + "avg_theta29 avg_theta30 avg_theta31 avg_theta32 avg_theta33 avg_theta34 avg_theta35 " +[] + +[Executioner] + type = Transient + + [TimeStepper] + type = NekTimeStepper + [] +[] + +# the postprocessors were generated for each of the 35 experimental data points +# using a python script + +[Postprocessors] + + [sim_theta01] + type = PointValue + point = '-0.498097349 0.043577871 0.5' + variable = wall_shear + execution_order_group = 0 + [] + [int_theta01] + type = TimeIntegratedPostprocessor + value = sim_theta01 + execution_order_group = 1 + [] + [avg_theta01] + type = ParsedPostprocessor + expression = 'int_theta01/t' + pp_names = 'int_theta01' + execute_on = 'FINAL' + use_t = true + execution_order_group = 2 + [] + + [sim_theta02] + type = PointValue + point = '-0.492403877 0.086824089 0.5' + variable = wall_shear + execution_order_group = 0 + [] + [int_theta02] + type = TimeIntegratedPostprocessor + value = sim_theta02 + execution_order_group = 1 + [] + [avg_theta02] + type = ParsedPostprocessor + expression = 'int_theta02/t' + pp_names = 'int_theta02' + execute_on = 'FINAL' + use_t = true + execution_order_group = 2 + [] + + [sim_theta03] + type = PointValue + point = '-0.482962913 0.129409523 0.5' + variable = wall_shear + execution_order_group = 0 + [] + [int_theta03] + type = TimeIntegratedPostprocessor + value = sim_theta03 + execution_order_group = 1 + [] + [avg_theta03] + type = ParsedPostprocessor + expression = 'int_theta03/t' + pp_names = 'int_theta03' + execute_on = 'FINAL' + use_t = true + execution_order_group = 2 + [] + + [sim_theta04] + type = PointValue + point = '-0.46984631 0.171010072 0.5' + variable = wall_shear + execution_order_group = 0 + [] + [int_theta04] + type = TimeIntegratedPostprocessor + value = sim_theta04 + execution_order_group = 1 + [] + [avg_theta04] + type = ParsedPostprocessor + expression = 'int_theta04/t' + pp_names = 'int_theta04' + execute_on = 'FINAL' + use_t = true + execution_order_group = 2 + [] + + [sim_theta05] + type = PointValue + point = '-0.453153894 0.211309131 0.5' + variable = wall_shear + execution_order_group = 0 + [] + [int_theta05] + type = TimeIntegratedPostprocessor + value = sim_theta05 + execution_order_group = 1 + [] + [avg_theta05] + type = ParsedPostprocessor + expression = 'int_theta05/t' + pp_names = 'int_theta05' + execute_on = 'FINAL' + use_t = true + execution_order_group = 2 + [] + + [sim_theta06] + type = PointValue + point = '-0.433012702 0.25 0.5' + variable = wall_shear + execution_order_group = 0 + [] + [int_theta06] + type = TimeIntegratedPostprocessor + value = sim_theta06 + execution_order_group = 1 + [] + [avg_theta06] + type = ParsedPostprocessor + expression = 'int_theta06/t' + pp_names = 'int_theta06' + execute_on = 'FINAL' + use_t = true + execution_order_group = 2 + [] + + [sim_theta07] + type = PointValue + point = '-0.409576022 0.286788218 0.5' + variable = wall_shear + execution_order_group = 0 + [] + [int_theta07] + type = TimeIntegratedPostprocessor + value = sim_theta07 + execution_order_group = 1 + [] + [avg_theta07] + type = ParsedPostprocessor + expression = 'int_theta07/t' + pp_names = 'int_theta07' + execute_on = 'FINAL' + use_t = true + execution_order_group = 2 + [] + + [sim_theta08] + type = PointValue + point = '-0.383022222 0.321393805 0.5' + variable = wall_shear + execution_order_group = 0 + [] + [int_theta08] + type = TimeIntegratedPostprocessor + value = sim_theta08 + execution_order_group = 1 + [] + [avg_theta08] + type = ParsedPostprocessor + expression = 'int_theta08/t' + pp_names = 'int_theta08' + execute_on = 'FINAL' + use_t = true + execution_order_group = 2 + [] + + [sim_theta09] + type = PointValue + point = '-0.353553391 0.353553391 0.5' + variable = wall_shear + execution_order_group = 0 + [] + [int_theta09] + type = TimeIntegratedPostprocessor + value = sim_theta09 + execution_order_group = 1 + [] + [avg_theta09] + type = ParsedPostprocessor + expression = 'int_theta09/t' + pp_names = 'int_theta09' + execute_on = 'FINAL' + use_t = true + execution_order_group = 2 + [] + + [sim_theta10] + type = PointValue + point = '-0.321393805 0.383022222 0.5' + variable = wall_shear + execution_order_group = 0 + [] + [int_theta10] + type = TimeIntegratedPostprocessor + value = sim_theta10 + execution_order_group = 1 + [] + [avg_theta10] + type = ParsedPostprocessor + expression = 'int_theta10/t' + pp_names = 'int_theta10' + execute_on = 'FINAL' + use_t = true + execution_order_group = 2 + [] + + [sim_theta11] + type = PointValue + point = '-0.25 0.433012702 0.5' + variable = wall_shear + execution_order_group = 0 + [] + [int_theta11] + type = TimeIntegratedPostprocessor + value = sim_theta11 + execution_order_group = 1 + [] + [avg_theta11] + type = ParsedPostprocessor + expression = 'int_theta11/t' + pp_names = 'int_theta11' + execute_on = 'FINAL' + use_t = true + execution_order_group = 2 + [] + + [sim_theta12] + type = PointValue + point = '-0.211309131 0.453153894 0.5' + variable = wall_shear + execution_order_group = 0 + [] + [int_theta12] + type = TimeIntegratedPostprocessor + value = sim_theta12 + execution_order_group = 1 + [] + [avg_theta12] + type = ParsedPostprocessor + expression = 'int_theta12/t' + pp_names = 'int_theta12' + execute_on = 'FINAL' + use_t = true + execution_order_group = 2 + [] + + [sim_theta13] + type = PointValue + point = '-0.171010072 0.46984631 0.5' + variable = wall_shear + execution_order_group = 0 + [] + [int_theta13] + type = TimeIntegratedPostprocessor + value = sim_theta13 + execution_order_group = 1 + [] + [avg_theta13] + type = ParsedPostprocessor + expression = 'int_theta13/t' + pp_names = 'int_theta13' + execute_on = 'FINAL' + use_t = true + execution_order_group = 2 + [] + + [sim_theta14] + type = PointValue + point = '-0.129409523 0.482962913 0.5' + variable = wall_shear + execution_order_group = 0 + [] + [int_theta14] + type = TimeIntegratedPostprocessor + value = sim_theta14 + execution_order_group = 1 + [] + [avg_theta14] + type = ParsedPostprocessor + expression = 'int_theta14/t' + pp_names = 'int_theta14' + execute_on = 'FINAL' + use_t = true + execution_order_group = 2 + [] + + [sim_theta15] + type = PointValue + point = '-0.086824089 0.492403877 0.5' + variable = wall_shear + execution_order_group = 0 + [] + [int_theta15] + type = TimeIntegratedPostprocessor + value = sim_theta15 + execution_order_group = 1 + [] + [avg_theta15] + type = ParsedPostprocessor + expression = 'int_theta15/t' + pp_names = 'int_theta15' + execute_on = 'FINAL' + use_t = true + execution_order_group = 2 + [] + + [sim_theta16] + type = PointValue + point = '-0.043577871 0.498097349 0.5' + variable = wall_shear + execution_order_group = 0 + [] + [int_theta16] + type = TimeIntegratedPostprocessor + value = sim_theta16 + execution_order_group = 1 + [] + [avg_theta16] + type = ParsedPostprocessor + expression = 'int_theta16/t' + pp_names = 'int_theta16' + execute_on = 'FINAL' + use_t = true + execution_order_group = 2 + [] + + [sim_theta17] + type = PointValue + point = '-3.06162e-17 0.5 0.5' + variable = wall_shear + execution_order_group = 0 + [] + [int_theta17] + type = TimeIntegratedPostprocessor + value = sim_theta17 + execution_order_group = 1 + [] + [avg_theta17] + type = ParsedPostprocessor + expression = 'int_theta17/t' + pp_names = 'int_theta17' + execute_on = 'FINAL' + use_t = true + execution_order_group = 2 + [] + + [sim_theta18] + type = PointValue + point = '0.043577871 0.498097349 0.5' + variable = wall_shear + execution_order_group = 0 + [] + [int_theta18] + type = TimeIntegratedPostprocessor + value = sim_theta18 + execution_order_group = 1 + [] + [avg_theta18] + type = ParsedPostprocessor + expression = 'int_theta18/t' + pp_names = 'int_theta18' + execute_on = 'FINAL' + use_t = true + execution_order_group = 2 + [] + + [sim_theta19] + type = PointValue + point = '0.086824089 0.492403877 0.5' + variable = wall_shear + execution_order_group = 0 + [] + [int_theta19] + type = TimeIntegratedPostprocessor + value = sim_theta19 + execution_order_group = 1 + [] + [avg_theta19] + type = ParsedPostprocessor + expression = 'int_theta19/t' + pp_names = 'int_theta19' + execute_on = 'FINAL' + use_t = true + execution_order_group = 2 + [] + + [sim_theta20] + type = PointValue + point = '0.129409523 0.482962913 0.5' + variable = wall_shear + execution_order_group = 0 + [] + [int_theta20] + type = TimeIntegratedPostprocessor + value = sim_theta20 + execution_order_group = 1 + [] + [avg_theta20] + type = ParsedPostprocessor + expression = 'int_theta20/t' + pp_names = 'int_theta20' + execute_on = 'FINAL' + use_t = true + execution_order_group = 2 + [] + + [sim_theta21] + type = PointValue + point = '0.171010072 0.46984631 0.5' + variable = wall_shear + execution_order_group = 0 + [] + [int_theta21] + type = TimeIntegratedPostprocessor + value = sim_theta21 + execution_order_group = 1 + [] + [avg_theta21] + type = ParsedPostprocessor + expression = 'int_theta21/t' + pp_names = 'int_theta21' + execute_on = 'FINAL' + use_t = true + execution_order_group = 2 + [] + + [sim_theta22] + type = PointValue + point = '0.211309131 0.453153894 0.5' + variable = wall_shear + execution_order_group = 0 + [] + [int_theta22] + type = TimeIntegratedPostprocessor + value = sim_theta22 + execution_order_group = 1 + [] + [avg_theta22] + type = ParsedPostprocessor + expression = 'int_theta22/t' + pp_names = 'int_theta22' + execute_on = 'FINAL' + use_t = true + execution_order_group = 2 + [] + + [sim_theta23] + type = PointValue + point = '0.25 0.433012702 0.5' + variable = wall_shear + execution_order_group = 0 + [] + [int_theta23] + type = TimeIntegratedPostprocessor + value = sim_theta23 + execution_order_group = 1 + [] + [avg_theta23] + type = ParsedPostprocessor + expression = 'int_theta23/t' + pp_names = 'int_theta23' + execute_on = 'FINAL' + use_t = true + execution_order_group = 2 + [] + + [sim_theta24] + type = PointValue + point = '0.286788218 0.409576022 0.5' + variable = wall_shear + execution_order_group = 0 + [] + [int_theta24] + type = TimeIntegratedPostprocessor + value = sim_theta24 + execution_order_group = 1 + [] + [avg_theta24] + type = ParsedPostprocessor + expression = 'int_theta24/t' + pp_names = 'int_theta24' + execute_on = 'FINAL' + use_t = true + execution_order_group = 2 + [] + + [sim_theta25] + type = PointValue + point = '0.321393805 0.383022222 0.5' + variable = wall_shear + execution_order_group = 0 + [] + [int_theta25] + type = TimeIntegratedPostprocessor + value = sim_theta25 + execution_order_group = 1 + [] + [avg_theta25] + type = ParsedPostprocessor + expression = 'int_theta25/t' + pp_names = 'int_theta25' + execute_on = 'FINAL' + use_t = true + execution_order_group = 2 + [] + + [sim_theta26] + type = PointValue + point = '0.353553391 0.353553391 0.5' + variable = wall_shear + execution_order_group = 0 + [] + [int_theta26] + type = TimeIntegratedPostprocessor + value = sim_theta26 + execution_order_group = 1 + [] + [avg_theta26] + type = ParsedPostprocessor + expression = 'int_theta26/t' + pp_names = 'int_theta26' + execute_on = 'FINAL' + use_t = true + execution_order_group = 2 + [] + + [sim_theta27] + type = PointValue + point = '0.383022222 0.321393805 0.5' + variable = wall_shear + execution_order_group = 0 + [] + [int_theta27] + type = TimeIntegratedPostprocessor + value = sim_theta27 + execution_order_group = 1 + [] + [avg_theta27] + type = ParsedPostprocessor + expression = 'int_theta27/t' + pp_names = 'int_theta27' + execute_on = 'FINAL' + use_t = true + execution_order_group = 2 + [] + + [sim_theta28] + type = PointValue + point = '0.409576022 0.286788218 0.5' + variable = wall_shear + execution_order_group = 0 + [] + [int_theta28] + type = TimeIntegratedPostprocessor + value = sim_theta28 + execution_order_group = 1 + [] + [avg_theta28] + type = ParsedPostprocessor + expression = 'int_theta28/t' + pp_names = 'int_theta28' + execute_on = 'FINAL' + use_t = true + execution_order_group = 2 + [] + + [sim_theta29] + type = PointValue + point = '0.433012702 0.25 0.5' + variable = wall_shear + execution_order_group = 0 + [] + [int_theta29] + type = TimeIntegratedPostprocessor + value = sim_theta29 + execution_order_group = 1 + [] + [avg_theta29] + type = ParsedPostprocessor + expression = 'int_theta29/t' + pp_names = 'int_theta29' + execute_on = 'FINAL' + use_t = true + execution_order_group = 2 + [] + + [sim_theta30] + type = PointValue + point = '0.453153894 0.211309131 0.5' + variable = wall_shear + execution_order_group = 0 + [] + [int_theta30] + type = TimeIntegratedPostprocessor + value = sim_theta30 + execution_order_group = 1 + [] + [avg_theta30] + type = ParsedPostprocessor + expression = 'int_theta30/t' + pp_names = 'int_theta30' + execute_on = 'FINAL' + use_t = true + execution_order_group = 2 + [] + + [sim_theta31] + type = PointValue + point = '0.46984631 0.171010072 0.5' + variable = wall_shear + execution_order_group = 0 + [] + [int_theta31] + type = TimeIntegratedPostprocessor + value = sim_theta31 + execution_order_group = 1 + [] + [avg_theta31] + type = ParsedPostprocessor + expression = 'int_theta31/t' + pp_names = 'int_theta31' + execute_on = 'FINAL' + use_t = true + execution_order_group = 2 + [] + + [sim_theta32] + type = PointValue + point = '0.482962913 0.129409523 0.5' + variable = wall_shear + execution_order_group = 0 + [] + [int_theta32] + type = TimeIntegratedPostprocessor + value = sim_theta32 + execution_order_group = 1 + [] + [avg_theta32] + type = ParsedPostprocessor + expression = 'int_theta32/t' + pp_names = 'int_theta32' + execute_on = 'FINAL' + use_t = true + execution_order_group = 2 + [] + + [sim_theta33] + type = PointValue + point = '0.492403877 0.086824089 0.5' + variable = wall_shear + execution_order_group = 0 + [] + [int_theta33] + type = TimeIntegratedPostprocessor + value = sim_theta33 + execution_order_group = 1 + [] + [avg_theta33] + type = ParsedPostprocessor + expression = 'int_theta33/t' + pp_names = 'int_theta33' + execute_on = 'FINAL' + use_t = true + execution_order_group = 2 + [] + + [sim_theta34] + type = PointValue + point = '0.498097349 0.043577871 0.5' + variable = wall_shear + execution_order_group = 0 + [] + [int_theta34] + type = TimeIntegratedPostprocessor + value = sim_theta34 + execution_order_group = 1 + [] + [avg_theta34] + type = ParsedPostprocessor + expression = 'int_theta34/t' + pp_names = 'int_theta34' + execute_on = 'FINAL' + use_t = true + execution_order_group = 2 + [] + + [sim_theta35] + type = PointValue + point = '0.5 6.12323e-17 0.5' + variable = wall_shear + execution_order_group = 0 + [] + [int_theta35] + type = TimeIntegratedPostprocessor + value = sim_theta35 + execution_order_group = 1 + [] + [avg_theta35] + type = ParsedPostprocessor + expression = 'int_theta35/t' + pp_names = 'int_theta35' + execute_on = 'FINAL' + use_t = true + execution_order_group = 2 + [] + +[] diff --git a/test/tests/traction/wall_shear/tests b/test/tests/traction/wall_shear/tests new file mode 100644 index 000000000..5a765bca7 --- /dev/null +++ b/test/tests/traction/wall_shear/tests @@ -0,0 +1,13 @@ +[Tests] + [test] + type = CSVDiff + input = nek.i + csvdiff = 'nek_out.csv' + min_parallel = 1 + requirement = "Cardinal shall be able to calculate the wall shear around a cylinder" + "to match experimental data with reasonable accuracy expected of a coarse-" + "grid, short duration test." + required_objects = 'NekRSStandaloneProblem' + max_time = 800 + [] +[]