From 8794cc3fcd5c66b5e1f0509f1328fbe354a6673a Mon Sep 17 00:00:00 2001 From: iyamazaki Date: Thu, 27 Oct 2022 12:37:59 -0600 Subject: [PATCH 01/17] FROSch : move symbolic factorization of kII to symbolic phase, and use Kokkos for "detectLinearDependencies - Push-back" --- .../CoarseSpaces/FROSch_CoarseSpace_def.hpp | 6 +- ...ROSch_AlgebraicOverlappingOperator_def.hpp | 6 +- .../FROSch_CoarseOperator_decl.hpp | 1 + .../FROSch_HarmonicCoarseOperator_decl.hpp | 116 +++++++++++ .../FROSch_HarmonicCoarseOperator_def.hpp | 190 ++++++++++++++---- .../FROSch_SchwarzOperator_decl.hpp | 1 + .../Tools/FROSch_ExtractSubmatrices_decl.hpp | 6 + .../Tools/FROSch_ExtractSubmatrices_def.hpp | 35 ++-- 8 files changed, 308 insertions(+), 53 deletions(-) diff --git a/packages/shylu/shylu_dd/frosch/src/CoarseSpaces/FROSch_CoarseSpace_def.hpp b/packages/shylu/shylu_dd/frosch/src/CoarseSpaces/FROSch_CoarseSpace_def.hpp index 260e5d33af6e..3ce7b3714a59 100644 --- a/packages/shylu/shylu_dd/frosch/src/CoarseSpaces/FROSch_CoarseSpace_def.hpp +++ b/packages/shylu/shylu_dd/frosch/src/CoarseSpaces/FROSch_CoarseSpace_def.hpp @@ -238,7 +238,7 @@ namespace FROSch { // count number of nonzeros per row UN numLocalRows = rowMap->getLocalNumElements(); - rowptr_type Rowptr ("Rowptr", numLocalRows+1); + rowptr_type Rowptr (Kokkos::ViewAllocateWithoutInitializing("Rowptr"), numLocalRows+1); Kokkos::deep_copy(Rowptr, 0); Kokkos::parallel_for( "FROSch_CoarseSpace::countGlobalBasisMatrix", policy_row, @@ -268,8 +268,8 @@ namespace FROSch { (1+numLocalRows, Rowptr); // fill into the local matrix - indices_type Indices ("Indices", nnz); - values_type Values ("Values", nnz); + indices_type Indices (Kokkos::ViewAllocateWithoutInitializing("Indices"), nnz); + values_type Values (Kokkos::ViewAllocateWithoutInitializing("Values"), nnz); auto AssembledBasisLocalMap = AssembledBasisMap_->getLocalMap(); Kokkos::parallel_for( "FROSch_CoarseSpace::fillGlobalBasisMatrix", policy_row, diff --git a/packages/shylu/shylu_dd/frosch/src/SchwarzOperators/FROSch_AlgebraicOverlappingOperator_def.hpp b/packages/shylu/shylu_dd/frosch/src/SchwarzOperators/FROSch_AlgebraicOverlappingOperator_def.hpp index ebfd489a9ff0..c82bad4affe0 100644 --- a/packages/shylu/shylu_dd/frosch/src/SchwarzOperators/FROSch_AlgebraicOverlappingOperator_def.hpp +++ b/packages/shylu/shylu_dd/frosch/src/SchwarzOperators/FROSch_AlgebraicOverlappingOperator_def.hpp @@ -294,7 +294,7 @@ namespace FROSch { FROSCH_DETAILTIMER_START_LEVELID(updateLocalOverlappingMatricesTime,"AlgebraicOverlappingOperator::updateLocalOverlappingMatrices"); if (this->ExtractLocalSubdomainMatrix_Symbolic_Done_) { // using original K_ as input - ExtractLocalSubdomainMatrix_Compute(this->K_, this->subdomainMatrix_, this->localSubdomainMatrix_); + ExtractLocalSubdomainMatrix_Compute(this->subdomainScatter_, this->K_, this->subdomainMatrix_, this->localSubdomainMatrix_); this->OverlappingMatrix_ = this->localSubdomainMatrix_.getConst(); } else { if (this->IsComputed_) { @@ -322,8 +322,8 @@ namespace FROSch { FROSCH_DETAILTIMER_START_LEVELID(AlgebraicOverlappin_extractLocalSubdomainMatrix_SymbolicTime,"AlgebraicOverlappinOperator::extractLocalSubdomainMatrix_Symbolic"); // buid sudomain matrix this->subdomainMatrix_ = MatrixFactory::Build(this->OverlappingMap_, this->OverlappingMatrix_->getGlobalMaxNumRowEntries()); - RCP > scatter = ImportFactory::Build(this->OverlappingMatrix_->getRowMap(), this->OverlappingMap_); - this->subdomainMatrix_->doImport(*(this->OverlappingMatrix_), *scatter, ADD); + this->subdomainScatter_ = ImportFactory::Build(this->OverlappingMatrix_->getRowMap(), this->OverlappingMap_); + this->subdomainMatrix_->doImport(*(this->OverlappingMatrix_), *(this->subdomainScatter_), ADD); // build local subdomain matrix RCP > SerialComm = rcp(new MpiComm(MPI_COMM_SELF)); diff --git a/packages/shylu/shylu_dd/frosch/src/SchwarzOperators/FROSch_CoarseOperator_decl.hpp b/packages/shylu/shylu_dd/frosch/src/SchwarzOperators/FROSch_CoarseOperator_decl.hpp index 497c818dd557..1ea5213a7f24 100644 --- a/packages/shylu/shylu_dd/frosch/src/SchwarzOperators/FROSch_CoarseOperator_decl.hpp +++ b/packages/shylu/shylu_dd/frosch/src/SchwarzOperators/FROSch_CoarseOperator_decl.hpp @@ -204,6 +204,7 @@ namespace FROSch { bool coarseExtractLocalSubdomainMatrix_Symbolic_Done_ = false; XMatrixPtr coarseSubdomainMatrix_; XMatrixPtr coarseLocalSubdomainMatrix_; + XImportPtr coarseScatter_; // Temp Vectors for apply() mutable XMultiVectorPtr XTmp_; diff --git a/packages/shylu/shylu_dd/frosch/src/SchwarzOperators/FROSch_HarmonicCoarseOperator_decl.hpp b/packages/shylu/shylu_dd/frosch/src/SchwarzOperators/FROSch_HarmonicCoarseOperator_decl.hpp index fb7b13d12ff4..d66fcce52276 100644 --- a/packages/shylu/shylu_dd/frosch/src/SchwarzOperators/FROSch_HarmonicCoarseOperator_decl.hpp +++ b/packages/shylu/shylu_dd/frosch/src/SchwarzOperators/FROSch_HarmonicCoarseOperator_decl.hpp @@ -154,6 +154,122 @@ namespace FROSch { UN j_out; SCView data_out; }; + + + struct ScaleTag {}; + struct CountNnzTag {}; + struct TotalNnzTag {}; + struct FillNzEntriesTag {}; + template + struct detectLinearDependenciesFunctor + { + using Real = typename Teuchos::ScalarTraits::magnitudeType; + using STS = Kokkos::ArithTraits; + using RTS = Kokkos::ArithTraits; + + UN numRows; + UN numCols; + SCView scale; + localMVBasisType localMVBasis; + + SC tresholdDropping; + indicesView indicesGammaDofsAll; + localRowMapType localRowMap; + localRowMapType localRepeatedMap; + + RowptrType Rowptr; + IndicesType Indices; + ValuesType Values; + + // Constructor for ScaleTag + detectLinearDependenciesFunctor(UN numRows_, UN numCols_, SCView scale_, localMVBasisType localMVBasis_) : + numRows (numRows_), + numCols (numCols_), + scale (scale_), + localMVBasis (localMVBasis_) + {} + + // Constructor for CountNnzTag + detectLinearDependenciesFunctor(UN numRows_, UN numCols_, localMVBasisType localMVBasis_, SC tresholdDropping_, + indicesView indicesGammaDofsAll_, localRowMapType localRowMap_, localRowMapType localRepeatedMap_, + RowptrType Rowptr_) : + numRows (numRows_), + numCols (numCols_), + scale (), + localMVBasis (localMVBasis_), + tresholdDropping (tresholdDropping_), + indicesGammaDofsAll (indicesGammaDofsAll_), + localRowMap (localRowMap_), + localRepeatedMap (localRepeatedMap_), + Rowptr (Rowptr_) + {} + + // Constructor for FillNzEntriesTag + detectLinearDependenciesFunctor(UN numRows_, UN numCols_, SCView scale_, localMVBasisType localMVBasis_, + SC tresholdDropping_, indicesView indicesGammaDofsAll_, + localRowMapType localRowMap_, localRowMapType localRepeatedMap_, + RowptrType Rowptr_, IndicesType Indices_, ValuesType Values_) : + numRows (numRows_), + numCols (numCols_), + scale (scale_), + localMVBasis (localMVBasis_), + tresholdDropping (tresholdDropping_), + indicesGammaDofsAll (indicesGammaDofsAll_), + localRowMap (localRowMap_), + localRepeatedMap (localRepeatedMap_), + Rowptr (Rowptr_), + Indices (Indices_), + Values (Values_) + {} + + KOKKOS_INLINE_FUNCTION + void operator()(const ScaleTag &, const int j) const { + scale(j) = STS::zero(); + for (UN i = 0; i < numRows; i++) { + scale(j) += localMVBasis(i,j)*localMVBasis(i,j); + } + scale(j) = RTS::one()/RTS::sqrt(STS::abs(scale(j))); + } + + KOKKOS_INLINE_FUNCTION + void operator()(const CountNnzTag &, const int i) const { + LO rowID = indicesGammaDofsAll[i]; + GO iGlobal = localRepeatedMap.getGlobalElement(rowID); + LO iLocal = localRowMap.getLocalElement(iGlobal); + if (iLocal!=-1) { // This should prevent duplicate entries on the interface + for (UN j=0; jtresholdDropping) { + Rowptr(iLocal+1) ++; + } + } + } + } + + + KOKKOS_INLINE_FUNCTION + void operator()(const TotalNnzTag&, const size_t i, UN &lsum) const { + lsum += Rowptr[i]; + } + + KOKKOS_INLINE_FUNCTION + void operator()(const FillNzEntriesTag &, const int i) const { + LO rowID = indicesGammaDofsAll[i]; + GO iGlobal = localRepeatedMap.getGlobalElement(rowID); + LO iLocal = localRowMap.getLocalElement(iGlobal); + if (iLocal!=-1) { // This should prevent duplicate entries on the interface + UN nnz_i = Rowptr(iLocal); + for (UN j=0; jtresholdDropping) { + Indices(nnz_i) = j; //localBasisMap.getGlobalElement(j); + Values(nnz_i) = valueTmp*scale(j); + nnz_i ++; + } + } + } + } + }; #endif protected: diff --git a/packages/shylu/shylu_dd/frosch/src/SchwarzOperators/FROSch_HarmonicCoarseOperator_def.hpp b/packages/shylu/shylu_dd/frosch/src/SchwarzOperators/FROSch_HarmonicCoarseOperator_def.hpp index 3dbd51bcd7c2..e3e6223cb3ae 100644 --- a/packages/shylu/shylu_dd/frosch/src/SchwarzOperators/FROSch_HarmonicCoarseOperator_def.hpp +++ b/packages/shylu/shylu_dd/frosch/src/SchwarzOperators/FROSch_HarmonicCoarseOperator_def.hpp @@ -69,7 +69,8 @@ namespace FROSch { ConstXMapPtr repeatedMap; ConstXMatrixPtr repeatedMatrix; if (this->coarseExtractLocalSubdomainMatrix_Symbolic_Done_) { - ExtractLocalSubdomainMatrix_Compute(this->K_.getConst(), + ExtractLocalSubdomainMatrix_Compute(this->coarseScatter_, + this->K_.getConst(), this->coarseSubdomainMatrix_, this->coarseLocalSubdomainMatrix_); repeatedMap = this->coarseSubdomainMatrix_->getRowMap(); @@ -503,39 +504,125 @@ namespace FROSch { { FROSCH_DETAILTIMER_START_LEVELID(detectLinearDependenciesTime,"HarmonicCoarseOperator::detectLinearDependencies"); LOVecPtr linearDependentVectors(AssembledInterfaceCoarseSpace_->getBasisMap()->getLocalNumElements()); //if (this->Verbose_) cout << AssembledInterfaceCoarseSpace_->getAssembledBasis()->getNumVectors() << " " << AssembledInterfaceCoarseSpace_->getAssembledBasis()->getLocalLength() << " " << indicesGammaDofsAll.size() << endl; - if (AssembledInterfaceCoarseSpace_->getAssembledBasis()->getNumVectors()>0 && AssembledInterfaceCoarseSpace_->getAssembledBasis()->getLocalLength()>0) { - //Construct matrix phiGamma - XMatrixPtr phiGamma = MatrixFactory::Build(rowMap,AssembledInterfaceCoarseSpace_->getBasisMap()->getLocalNumElements()); - // Array for scaling the columns of PhiGamma (1/norm(PhiGamma(:,i))) - SCVec scale(AssembledInterfaceCoarseSpace_->getAssembledBasis()->getNumVectors(),0.0); - for (UN i = 0; i < AssembledInterfaceCoarseSpace_->getAssembledBasis()->getNumVectors(); i++) { - ConstSCVecPtr assembledInterfaceCoarseSpaceData = AssembledInterfaceCoarseSpace_->getAssembledBasis()->getData(i); - for (UN j = 0; j < AssembledInterfaceCoarseSpace_->getAssembledBasis()->getLocalLength(); j++) { - scale[i] += assembledInterfaceCoarseSpaceData[j]*assembledInterfaceCoarseSpaceData[j]; + auto asembledBasis = AssembledInterfaceCoarseSpace_->getAssembledBasis(); + auto basisMap = AssembledInterfaceCoarseSpace_->getBasisMap(); + auto basisMapUnique = AssembledInterfaceCoarseSpace_->getBasisMapUnique(); + UN numMVRows = asembledBasis->getLocalLength(); + UN numCols = asembledBasis->getNumVectors(); + if (numMVRows > 0 && numCols > 0) { + + XMatrixPtr phiGamma; +#if defined(HAVE_XPETRA_KOKKOS_REFACTOR) && defined(HAVE_XPETRA_TPETRA) + if (rowMap->lib() == UseTpetra) + { + using crsmat_type = typename Matrix::local_matrix_type; + using graph_type = typename crsmat_type::StaticCrsGraphType; + using rowptr_type = typename graph_type::row_map_type::non_const_type; + using indices_type = typename graph_type::entries_type::non_const_type; + using values_type = typename crsmat_type::values_type::non_const_type; + using local_mv_type = typename MultiVector::dual_view_type::t_dev_const_um; + using local_map_type = typename Map::local_map_type; + + UN numRows = rowMap->getLocalNumElements(); + + auto localRowMap = rowMap->getLocalMap(); + auto localRepeatedMap = repeatedMap->getLocalMap(); + auto localBasisMap = basisMap->getLocalMap(); + + auto localMVBasis = asembledBasis->getDeviceLocalView(Xpetra::Access::ReadOnly); + + // Array for scaling the columns of PhiGamma (1/norm(PhiGamma(:,i))) + using execution_space = typename Map::local_map_type::execution_space; + using SCView = Kokkos::View; + SCView scale(Kokkos::ViewAllocateWithoutInitializing("FROSch::HarmonicCoarseOperator::detectLinearDependencies::scale"), numCols); + detectLinearDependenciesFunctor + scale_functor(numMVRows, numCols, scale, localMVBasis); + Kokkos::RangePolicy policy_scale (0, numCols); + Kokkos::parallel_for( + "FROSch_HarmonicCoarseOperator::detectLinearDependencies::scale", policy_scale, scale_functor); + + // count nnz + rowptr_type Rowptr (Kokkos::ViewAllocateWithoutInitializing("Rowptr"), numRows+1); + Kokkos::deep_copy(Rowptr, 0); + detectLinearDependenciesFunctor + count_functor(numMVRows, numCols, localMVBasis, tresholdDropping, indicesGammaDofsAll, + localRowMap, localRepeatedMap, Rowptr); + Kokkos::RangePolicy policy_count (0, numMVRows); + Kokkos::parallel_for( + "FROSch_HarmonicCoarseOperator::detectLinearDependencies::countNnz", policy_count, count_functor); + Kokkos::fence(); + + // get Nnz + UN nnz = 0; + Kokkos::RangePolicy policy_nnz (0, 1+numRows); + Kokkos::parallel_reduce( + "FROSch_HarmonicCoarseOperator::detectLinearDependencies::reduceNnz", policy_nnz, count_functor, nnz); + Kokkos::fence(); + + // make it into offsets + KokkosKernels::Impl::kk_inclusive_parallel_prefix_sum + (1+numRows, Rowptr); + Kokkos::fence(); + + // allocate local matrix + indices_type Indices (Kokkos::ViewAllocateWithoutInitializing("Indices"), nnz); + values_type Values (Kokkos::ViewAllocateWithoutInitializing("Values"), nnz); + + // fill in all the nz entries + detectLinearDependenciesFunctor + fill_functor(numMVRows, numCols, scale, localMVBasis, tresholdDropping, indicesGammaDofsAll, + localRowMap, localRepeatedMap, Rowptr, Indices, Values); + Kokkos::RangePolicy policy_fill (0, numMVRows); + Kokkos::parallel_for( + "FROSch_HarmonicCoarseOperator::detectLinearDependencies::fillNz", policy_fill, fill_functor); + Kokkos::fence(); + + Teuchos::RCP params = Teuchos::rcp (new Teuchos::ParameterList()); + params->set("sorted", false); + params->set("No Nonlocal Changes", true); + + graph_type crsgraph (Indices, Rowptr); + crsmat_type crsmat = crsmat_type ("CrsMatrix", numRows, Values, crsgraph); + + phiGamma = MatrixFactory::Build(crsmat, rowMap, basisMap, basisMapUnique, rangeMap, + params); + } else +#endif + { + // Array for scaling the columns of PhiGamma (1/norm(PhiGamma(:,i))) + SCVec scale(numCols, 0.0); + for (UN j = 0; j < numCols; j++) { + ConstSCVecPtr assembledInterfaceCoarseSpaceData = asembledBasis->getData(j); + for (UN i = 0; i < numMVRows; i++) { + scale[j] += assembledInterfaceCoarseSpaceData[i]*assembledInterfaceCoarseSpaceData[i]; + } + scale[j] = 1.0/sqrt(scale[j]); } - scale[i] = 1.0/sqrt(scale[i]); - } - LO iD; - SC valueTmp; - for (UN i=0; igetAssembledBasis()->getLocalLength(); i++) { - GOVec indices; - SCVec values; - iD = repeatedMap->getGlobalElement(indicesGammaDofsAll[i]); - if (rowMap->getLocalElement(iD)!=-1) { // This should prevent duplicate entries on the interface - for (UN j=0; jgetAssembledBasis()->getNumVectors(); j++) { - valueTmp=AssembledInterfaceCoarseSpace_->getAssembledBasis()->getData(j)[i]; - if (fabs(valueTmp)>tresholdDropping) { - indices.push_back(AssembledInterfaceCoarseSpace_->getBasisMap()->getGlobalElement(j)); - values.push_back(valueTmp*scale[j]); + //Construct matrix phiGamma + phiGamma = MatrixFactory::Build(rowMap,basisMap->getLocalNumElements()); + LO iD; + SC valueTmp; + for (UN i=0; igetLocalLength(); i++) { + iD = repeatedMap->getGlobalElement(indicesGammaDofsAll[i]); + if (rowMap->getLocalElement(iD)!=-1) { // This should prevent duplicate entries on the interface + GOVec indices; + SCVec values; + for (UN j=0; jgetNumVectors(); j++) { + valueTmp=asembledBasis->getData(j)[i]; + if (fabs(valueTmp)>tresholdDropping) { + indices.push_back(basisMap->getGlobalElement(j)); + values.push_back(valueTmp*scale[j]); + } } + phiGamma->insertGlobalValues(iD,indices(),values()); } - - phiGamma->insertGlobalValues(iD,indices(),values()); } + RCP fillCompleteParams(new ParameterList); + fillCompleteParams->set("No Nonlocal Changes", true); + phiGamma->fillComplete(basisMapUnique,rangeMap,fillCompleteParams); } - phiGamma->fillComplete(AssembledInterfaceCoarseSpace_->getBasisMapUnique(),rangeMap); //Compute Phi^T * Phi RCP fancy = fancyOStream(rcpFromRef(cout)); @@ -756,10 +843,14 @@ namespace FROSch { // Jetzt der solver für kII if (indicesIDofsAll.size()>0) { - ExtensionSolver_ = SolverFactory::Build(kII, - sublist(this->ParameterList_,"ExtensionSolver"), - string("ExtensionSolver (Level ") + to_string(this->LevelID_) + string(")")); - ExtensionSolver_->initialize(); + if (this->coarseExtractLocalSubdomainMatrix_Symbolic_Done_) { + ExtensionSolver_->updateMatrix(kII, true); + } else { + ExtensionSolver_ = SolverFactory::Build(kII, + sublist(this->ParameterList_,"ExtensionSolver"), + string("ExtensionSolver (Level ") + to_string(this->LevelID_) + string(")")); + ExtensionSolver_->initialize(); + } ExtensionSolver_->compute(); ExtensionSolver_->apply(*mVtmp,*mVPhiI); } @@ -803,7 +894,7 @@ namespace FROSch { using GOIndView = Kokkos::View; UN numIndices = indicesIDofsAll.size(); GOIndViewHost indicesIDofsAllHostData(indicesIDofsAll.getRawPtr(), numIndices); - GOIndView indicesIDofsAllData ("indicesIDofsAllData", numIndices); + GOIndView indicesIDofsAllData (Kokkos::ViewAllocateWithoutInitializing("indicesIDofsAllData"), numIndices); Kokkos::deep_copy(indicesIDofsAllData, indicesIDofsAllHostData); using xTMVector = Xpetra::TpetraMultiVector; @@ -1080,8 +1171,8 @@ namespace FROSch { // buid sudomain matrix this->coarseSubdomainMatrix_ = MatrixFactory::Build(repeatedMap, repeatedMap, this->K_->getGlobalMaxNumRowEntries()); - RCP > scatter = ImportFactory::Build(this->K_->getRowMap(), repeatedMap); - this->coarseSubdomainMatrix_->doImport(*(this->K_.getConst()), *scatter,ADD); + this->coarseScatter_ = ImportFactory::Build(this->K_->getRowMap(), repeatedMap); + this->coarseSubdomainMatrix_->doImport(*(this->K_.getConst()), *(this->coarseScatter_),ADD); // build local subdomain matrix RCP > SerialComm = rcp(new MpiComm(MPI_COMM_SELF)); @@ -1094,6 +1185,37 @@ namespace FROSch { // turn flag on this->coarseExtractLocalSubdomainMatrix_Symbolic_Done_ = true; + + + // ------------------------------------------------------- + // symbolic for computeExtensions to factor kII + GOVec indicesGammaDofsAll(0); + GOVec indicesIDofsAll(0); + LO tmp = 0; + + for (UN i=0; icoarseLocalSubdomainMatrix_; + BuildSubmatrices(repeatedMatrix.getConst(),indicesIDofsAll(),kII,kIGamma,kGammaI,kGammaGamma); + + // perform symbolic on kII + ExtensionSolver_ = SolverFactory::Build(kII, + sublist(this->ParameterList_,"ExtensionSolver"), + string("ExtensionSolver (Level ") + to_string(this->LevelID_) + string(")")); + ExtensionSolver_->initialize(); } } diff --git a/packages/shylu/shylu_dd/frosch/src/SchwarzOperators/FROSch_SchwarzOperator_decl.hpp b/packages/shylu/shylu_dd/frosch/src/SchwarzOperators/FROSch_SchwarzOperator_decl.hpp index b303eb74c1d9..0b9ad2652a7c 100644 --- a/packages/shylu/shylu_dd/frosch/src/SchwarzOperators/FROSch_SchwarzOperator_decl.hpp +++ b/packages/shylu/shylu_dd/frosch/src/SchwarzOperators/FROSch_SchwarzOperator_decl.hpp @@ -236,6 +236,7 @@ namespace FROSch { bool ExtractLocalSubdomainMatrix_Symbolic_Done_ = false; XMatrixPtr subdomainMatrix_; XMatrixPtr localSubdomainMatrix_; + XImportPtr subdomainScatter_; bool Verbose_ = false; diff --git a/packages/shylu/shylu_dd/frosch/src/Tools/FROSch_ExtractSubmatrices_decl.hpp b/packages/shylu/shylu_dd/frosch/src/Tools/FROSch_ExtractSubmatrices_decl.hpp index 622dc06b7ef6..2e190a686e30 100644 --- a/packages/shylu/shylu_dd/frosch/src/Tools/FROSch_ExtractSubmatrices_decl.hpp +++ b/packages/shylu/shylu_dd/frosch/src/Tools/FROSch_ExtractSubmatrices_decl.hpp @@ -72,6 +72,12 @@ namespace FROSch { void ExtractLocalSubdomainMatrix_Compute(RCP > globalMatrix, RCP< Matrix > subdomainMatrix, RCP< Matrix > repeatedMatrix); + + template + void ExtractLocalSubdomainMatrix_Compute(RCP< Import > scatter, + RCP > globalMatrix, + RCP< Matrix > subdomainMatrix, + RCP< Matrix > repeatedMatrix); // ----------------------------------------------------------- // template diff --git a/packages/shylu/shylu_dd/frosch/src/Tools/FROSch_ExtractSubmatrices_def.hpp b/packages/shylu/shylu_dd/frosch/src/Tools/FROSch_ExtractSubmatrices_def.hpp index 39302b368811..c278e937a8e5 100644 --- a/packages/shylu/shylu_dd/frosch/src/Tools/FROSch_ExtractSubmatrices_def.hpp +++ b/packages/shylu/shylu_dd/frosch/src/Tools/FROSch_ExtractSubmatrices_def.hpp @@ -122,12 +122,21 @@ namespace FROSch { void ExtractLocalSubdomainMatrix_Compute(RCP > globalMatrix, RCP< Matrix > subdomainMatrix, RCP< Matrix > localSubdomainMatrix) + { + RCP > scatter = ImportFactory::Build(globalMatrix->getRowMap(), subdomainMatrix->getRowMap()); + ExtractLocalSubdomainMatrix_Compute(scatter, globalMatrix, subdomainMatrix, localSubdomainMatrix); + } + + template + void ExtractLocalSubdomainMatrix_Compute(RCP< Import > scatter, + RCP > globalMatrix, + RCP< Matrix > subdomainMatrix, + RCP< Matrix > localSubdomainMatrix) { FROSCH_DETAILTIMER_START(extractLocalSubdomainMatrixTime_compute, "ExtractLocalSubdomainMatrix_Compute"); const SC zero = ScalarTraits::zero(); auto subdomainRowMap = subdomainMatrix->getRowMap(); - RCP > scatter = ImportFactory::Build(globalMatrix->getRowMap(),subdomainRowMap); subdomainMatrix->setAllToScalar(zero); subdomainMatrix->resumeFill(); subdomainMatrix->doImport(*globalMatrix, *scatter, ADD); @@ -314,10 +323,10 @@ namespace FROSch { UN numRowsI = indI.size(); UN numRowsJ = indJ.size(); - rowptr_type RowptrII ("RowptrII", numRowsI+1); - rowptr_type RowptrIJ ("RowptrIJ", numRowsI+1); - rowptr_type RowptrJI ("RowptrJI", numRowsJ+1); - rowptr_type RowptrJJ ("RowptrJJ", numRowsJ+1); + rowptr_type RowptrII (Kokkos::ViewAllocateWithoutInitializing("RowptrII"), numRowsI+1); + rowptr_type RowptrIJ (Kokkos::ViewAllocateWithoutInitializing("RowptrIJ"), numRowsI+1); + rowptr_type RowptrJI (Kokkos::ViewAllocateWithoutInitializing("RowptrJI"), numRowsJ+1); + rowptr_type RowptrJJ (Kokkos::ViewAllocateWithoutInitializing("RowptrJJ"), numRowsJ+1); // count nnz on each blocks Kokkos::deep_copy(RowptrII, 0); @@ -388,17 +397,17 @@ namespace FROSch { (1+numRowsJ, RowptrJJ); // allocate kII block - indices_type IndicesII ("IndicesII", nnzII); - values_type ValuesII ("ValuesII", nnzII); + indices_type IndicesII (Kokkos::ViewAllocateWithoutInitializing("IndicesII"), nnzII); + values_type ValuesII (Kokkos::ViewAllocateWithoutInitializing("ValuesII"), nnzII); // allocate kIJ block - indices_type IndicesIJ ("IndicesIJ", nnzIJ); - values_type ValuesIJ ("ValuesIJ", nnzIJ); + indices_type IndicesIJ (Kokkos::ViewAllocateWithoutInitializing("IndicesIJ"), nnzIJ); + values_type ValuesIJ (Kokkos::ViewAllocateWithoutInitializing("ValuesIJ"), nnzIJ); // allocate kJI block - indices_type IndicesJI ("IndicesJI", nnzJI); - values_type ValuesJI ("ValuesJI", nnzJI); + indices_type IndicesJI (Kokkos::ViewAllocateWithoutInitializing("IndicesJI"), nnzJI); + values_type ValuesJI (Kokkos::ViewAllocateWithoutInitializing("ValuesJI"), nnzJI); // allocate kJJ block - indices_type IndicesJJ ("IndicesJJ", nnzJJ); - values_type ValuesJJ ("ValuesJJ", nnzJJ); + indices_type IndicesJJ (Kokkos::ViewAllocateWithoutInitializing("IndicesJJ"), nnzJJ); + values_type ValuesJJ (Kokkos::ViewAllocateWithoutInitializing("ValuesJJ"), nnzJJ); // fill in all the blocks Kokkos::parallel_for( From c9854ac41d75fae94e97a3a64f91d2841d8500ff Mon Sep 17 00:00:00 2001 From: iyamazaki Date: Thu, 27 Oct 2022 12:43:22 -0600 Subject: [PATCH 02/17] FROSch : re-allocate auxiliary vectors when the number of columns changes --- .../FROSch_CoarseOperator_def.hpp | 29 ++++++++++++++----- .../FROSch_OverlappingOperator_def.hpp | 10 +++++-- .../FROSch_SumOperator_def.hpp | 4 ++- .../FROSch_Amesos2SolverTpetra_def.hpp | 4 ++- 4 files changed, 34 insertions(+), 13 deletions(-) diff --git a/packages/shylu/shylu_dd/frosch/src/SchwarzOperators/FROSch_CoarseOperator_def.hpp b/packages/shylu/shylu_dd/frosch/src/SchwarzOperators/FROSch_CoarseOperator_def.hpp index ce3107647fcd..94b39ba25964 100644 --- a/packages/shylu/shylu_dd/frosch/src/SchwarzOperators/FROSch_CoarseOperator_def.hpp +++ b/packages/shylu/shylu_dd/frosch/src/SchwarzOperators/FROSch_CoarseOperator_def.hpp @@ -133,14 +133,21 @@ namespace FROSch { FROSCH_TIMER_START_LEVELID(applyTime,"CoarseOperator::apply"); static int i = 0; if (!Phi_.is_null() && this->IsComputed_) { - if (XTmp_.is_null()) XTmp_ = MultiVectorFactory::Build(x.getMap(),x.getNumVectors()); + if (XTmp_.is_null() || XTmp_->getNumVectors() != x.getNumVectors()) { + XTmp_ = MultiVectorFactory::Build(x.getMap(),x.getNumVectors()); + } *XTmp_ = x; if (!usePreconditionerOnly && mode == NO_TRANS) { this->K_->apply(x,*XTmp_,mode,ScalarTraits::one(),ScalarTraits::zero()); } - if (XCoarseSolve_.is_null()) XCoarseSolve_ = MultiVectorFactory::Build(GatheringMaps_[GatheringMaps_.size()-1],x.getNumVectors()); - else XCoarseSolve_->replaceMap(GatheringMaps_[GatheringMaps_.size()-1]); // The map is replaced in applyCoarseSolve(). If we do not build it from scratch, we should at least replace the map here. This may be important since the maps live on different communicators. - if (YCoarseSolve_.is_null()) YCoarseSolve_ = MultiVectorFactory::Build(GatheringMaps_[GatheringMaps_.size()-1],y.getNumVectors()); + if (XCoarseSolve_.is_null() || XCoarseSolve_->getNumVectors() != x.getNumVectors()) { + XCoarseSolve_ = MultiVectorFactory::Build(GatheringMaps_[GatheringMaps_.size()-1],x.getNumVectors()); + } else { + XCoarseSolve_->replaceMap(GatheringMaps_[GatheringMaps_.size()-1]); // The map is replaced in applyCoarseSolve(). If we do not build it from scratch, we should at least replace the map here. This may be important since the maps live on different communicators. + } + if (YCoarseSolve_.is_null() || YCoarseSolve_->getNumVectors() != y.getNumVectors()) { + YCoarseSolve_ = MultiVectorFactory::Build(GatheringMaps_[GatheringMaps_.size()-1],y.getNumVectors()); + } applyPhiT(*XTmp_,*XCoarseSolve_); applyCoarseSolve(*XCoarseSolve_,*YCoarseSolve_,mode); applyPhi(*YCoarseSolve_,*XTmp_); @@ -192,12 +199,18 @@ namespace FROSch { FROSCH_DETAILTIMER_START_LEVELID(applyCoarseSolveTime,"CoarseOperator::applyCoarseSolve"); if (OnCoarseSolveComm_) { x.replaceMap(CoarseSolveMap_); - if (YTmp_.is_null()) YTmp_ = MultiVectorFactory::Build(CoarseSolveMap_,x.getNumVectors()); - else YTmp_->replaceMap(CoarseSolveMap_); // The map is replaced later in this function. If we do not build it from scratch, we should at least replace the map here. This may be important since the maps live on different communicators. + if (YTmp_.is_null() || YTmp_->getNumVectors() != x.getNumVectors()) { + YTmp_ = MultiVectorFactory::Build(CoarseSolveMap_,x.getNumVectors()); + } else { + YTmp_->replaceMap(CoarseSolveMap_); // The map is replaced later in this function. If we do not build it from scratch, we should at least replace the map here. This may be important since the maps live on different communicators. + } CoarseSolver_->apply(x,*YTmp_,mode); } else { - if (YTmp_.is_null()) YTmp_ = MultiVectorFactory::Build(CoarseSolveMap_,x.getNumVectors()); - else YTmp_->replaceMap(CoarseSolveMap_); // The map is replaced later in this function. If we do not build it from scratch, we should at least replace the map here. This may be important since the maps live on different communicators. + if (YTmp_.is_null() || YTmp_->getNumVectors() != x.getNumVectors()) { + YTmp_ = MultiVectorFactory::Build(CoarseSolveMap_,x.getNumVectors()); + } else { + YTmp_->replaceMap(CoarseSolveMap_); // The map is replaced later in this function. If we do not build it from scratch, we should at least replace the map here. This may be important since the maps live on different communicators. + } } YTmp_->replaceMap(GatheringMaps_[GatheringMaps_.size()-1]); y = *YTmp_; diff --git a/packages/shylu/shylu_dd/frosch/src/SchwarzOperators/FROSch_OverlappingOperator_def.hpp b/packages/shylu/shylu_dd/frosch/src/SchwarzOperators/FROSch_OverlappingOperator_def.hpp index c415223891d8..1ce7847adf77 100644 --- a/packages/shylu/shylu_dd/frosch/src/SchwarzOperators/FROSch_OverlappingOperator_def.hpp +++ b/packages/shylu/shylu_dd/frosch/src/SchwarzOperators/FROSch_OverlappingOperator_def.hpp @@ -83,13 +83,15 @@ namespace FROSch { { FROSCH_TIMER_START_LEVELID(applyTime,"OverlappingOperator::apply"); FROSCH_ASSERT(this->IsComputed_,"FROSch::OverlappingOperator: OverlappingOperator has to be computed before calling apply()"); - if (XTmp_.is_null()) XTmp_ = MultiVectorFactory::Build(x.getMap(),x.getNumVectors()); + if (XTmp_.is_null() || XTmp_->getNumVectors() != x.getNumVectors()) { + XTmp_ = MultiVectorFactory::Build(x.getMap(),x.getNumVectors()); + } *XTmp_ = x; if (!usePreconditionerOnly && mode == NO_TRANS) { this->K_->apply(x,*XTmp_,mode,ScalarTraits::one(),ScalarTraits::zero()); } // AH 11/28/2018: For Epetra, XOverlap_ will only have a view to the values of XOverlapTmp_. Therefore, xOverlapTmp should not be deleted before XOverlap_ is used. - if (YOverlap_.is_null()) { + if (YOverlap_.is_null() || YOverlap_->getNumVectors() != x.getNumVectors()) { YOverlap_ = MultiVectorFactory::Build(OverlappingMatrix_->getDomainMap(),x.getNumVectors()); } else { YOverlap_->replaceMap(OverlappingMatrix_->getDomainMap()); @@ -97,7 +99,9 @@ namespace FROSch { // AH 11/28/2018: replaceMap does not update the GlobalNumRows. Therefore, we have to create a new MultiVector on the serial Communicator. In Epetra, we can prevent to copy the MultiVector. if (XTmp_->getMap()->lib() == UseEpetra) { #ifdef HAVE_SHYLU_DDFROSCH_EPETRA - if (XOverlapTmp_.is_null()) XOverlapTmp_ = MultiVectorFactory::Build(OverlappingMap_,x.getNumVectors()); + if (XOverlapTmp_.is_null() || XOverlap_->getNumVectors() != x.getNumVectors()) { + XOverlapTmp_ = MultiVectorFactory::Build(OverlappingMap_,x.getNumVectors()); + } XOverlapTmp_->doImport(*XTmp_,*Scatter_,INSERT); const RCP > xEpetraMultiVectorXOverlapTmp = rcp_dynamic_cast >(XOverlapTmp_); RCP epetraMultiVectorXOverlapTmp = xEpetraMultiVectorXOverlapTmp->getEpetra_MultiVector(); diff --git a/packages/shylu/shylu_dd/frosch/src/SchwarzOperators/FROSch_SumOperator_def.hpp b/packages/shylu/shylu_dd/frosch/src/SchwarzOperators/FROSch_SumOperator_def.hpp index 1aaa6910a45e..0f2f94143f2d 100644 --- a/packages/shylu/shylu_dd/frosch/src/SchwarzOperators/FROSch_SumOperator_def.hpp +++ b/packages/shylu/shylu_dd/frosch/src/SchwarzOperators/FROSch_SumOperator_def.hpp @@ -118,7 +118,9 @@ namespace FROSch { { FROSCH_TIMER_START_LEVELID(applyTime,"SumOperator::apply"); if (OperatorVector_.size()>0) { - if (XTmp_.is_null()) XTmp_ = MultiVectorFactory::Build(x.getMap(),x.getNumVectors()); + if (XTmp_.is_null() || XTmp_->getNumVectors() != x.getNumVectors()) { + XTmp_ = MultiVectorFactory::Build(x.getMap(),x.getNumVectors()); + } *XTmp_ = x; // Das brauche ich für den Fall das x=y UN itmp = 0; for (UN i=0; igetTpetra_MultiVector(); - if (Y_.is_null()) Y_ = XMultiVectorFactory::Build(y.getMap(),x.getNumVectors()); + if (Y_.is_null() || Y_->getNumVectors() != x.getNumVectors()) { + Y_ = XMultiVectorFactory::Build(y.getMap(),x.getNumVectors()); + } const TpetraMultiVector * xTpetraMultiVectorY = dynamic_cast *>(Y_.get()); FROSCH_ASSERT(xTpetraMultiVectorY,"FROSch::Amesos2SolverTpetra: dynamic_cast failed."); TMultiVectorPtr tpetraMultiVectorY = xTpetraMultiVectorY->getTpetra_MultiVector(); From a6eb3111956d85cd68e354dea3ba54b8056ffaac Mon Sep 17 00:00:00 2001 From: iyamazaki Date: Thu, 27 Oct 2022 12:45:18 -0600 Subject: [PATCH 03/17] FROSch : add "using initialize" --- .../SchwarzPreconditioners/FROSch_GDSWPreconditioner_decl.hpp | 1 + .../SchwarzPreconditioners/FROSch_RGDSWPreconditioner_decl.hpp | 1 + .../FROSch_TwoLevelPreconditioner_decl.hpp | 1 + 3 files changed, 3 insertions(+) diff --git a/packages/shylu/shylu_dd/frosch/src/SchwarzPreconditioners/FROSch_GDSWPreconditioner_decl.hpp b/packages/shylu/shylu_dd/frosch/src/SchwarzPreconditioners/FROSch_GDSWPreconditioner_decl.hpp index eab7c0f962ee..2642a4f46c5d 100644 --- a/packages/shylu/shylu_dd/frosch/src/SchwarzPreconditioners/FROSch_GDSWPreconditioner_decl.hpp +++ b/packages/shylu/shylu_dd/frosch/src/SchwarzPreconditioners/FROSch_GDSWPreconditioner_decl.hpp @@ -82,6 +82,7 @@ namespace FROSch { using GOVecPtr = typename SchwarzPreconditioner::GOVecPtr; public: + using AlgebraicOverlappingPreconditioner::initialize; GDSWPreconditioner(ConstXMatrixPtr k, ParameterListPtr parameterList); diff --git a/packages/shylu/shylu_dd/frosch/src/SchwarzPreconditioners/FROSch_RGDSWPreconditioner_decl.hpp b/packages/shylu/shylu_dd/frosch/src/SchwarzPreconditioners/FROSch_RGDSWPreconditioner_decl.hpp index 13ec9393815a..7fca55b7524e 100644 --- a/packages/shylu/shylu_dd/frosch/src/SchwarzPreconditioners/FROSch_RGDSWPreconditioner_decl.hpp +++ b/packages/shylu/shylu_dd/frosch/src/SchwarzPreconditioners/FROSch_RGDSWPreconditioner_decl.hpp @@ -81,6 +81,7 @@ namespace FROSch { using GOVecPtr = typename SchwarzPreconditioner::GOVecPtr; public: + using AlgebraicOverlappingPreconditioner::initialize; RGDSWPreconditioner(ConstXMatrixPtr k, ParameterListPtr parameterList); diff --git a/packages/shylu/shylu_dd/frosch/src/SchwarzPreconditioners/FROSch_TwoLevelPreconditioner_decl.hpp b/packages/shylu/shylu_dd/frosch/src/SchwarzPreconditioners/FROSch_TwoLevelPreconditioner_decl.hpp index 7a51284eabbe..01306d0d722d 100644 --- a/packages/shylu/shylu_dd/frosch/src/SchwarzPreconditioners/FROSch_TwoLevelPreconditioner_decl.hpp +++ b/packages/shylu/shylu_dd/frosch/src/SchwarzPreconditioners/FROSch_TwoLevelPreconditioner_decl.hpp @@ -83,6 +83,7 @@ namespace FROSch { using GOVecPtr = typename SchwarzPreconditioner::GOVecPtr; public: + using OneLevelPreconditioner::initialize; TwoLevelPreconditioner(ConstXMatrixPtr k, ParameterListPtr parameterList); From c3429bdc8e6c90f5a56d9db7e7c68b054e5fe1f6 Mon Sep 17 00:00:00 2001 From: iyamazaki Date: Thu, 14 Mar 2024 19:05:07 -0600 Subject: [PATCH 04/17] FROSch : fix maps --- .../FROSch_AlgebraicOverlappingOperator_def.hpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/shylu/shylu_dd/frosch/src/SchwarzOperators/FROSch_AlgebraicOverlappingOperator_def.hpp b/packages/shylu/shylu_dd/frosch/src/SchwarzOperators/FROSch_AlgebraicOverlappingOperator_def.hpp index c82bad4affe0..408e3a3482ba 100644 --- a/packages/shylu/shylu_dd/frosch/src/SchwarzOperators/FROSch_AlgebraicOverlappingOperator_def.hpp +++ b/packages/shylu/shylu_dd/frosch/src/SchwarzOperators/FROSch_AlgebraicOverlappingOperator_def.hpp @@ -322,8 +322,11 @@ namespace FROSch { FROSCH_DETAILTIMER_START_LEVELID(AlgebraicOverlappin_extractLocalSubdomainMatrix_SymbolicTime,"AlgebraicOverlappinOperator::extractLocalSubdomainMatrix_Symbolic"); // buid sudomain matrix this->subdomainMatrix_ = MatrixFactory::Build(this->OverlappingMap_, this->OverlappingMatrix_->getGlobalMaxNumRowEntries()); - this->subdomainScatter_ = ImportFactory::Build(this->OverlappingMatrix_->getRowMap(), this->OverlappingMap_); - this->subdomainMatrix_->doImport(*(this->OverlappingMatrix_), *(this->subdomainScatter_), ADD); + RCP > scatter = ImportFactory::Build(this->OverlappingMatrix_->getRowMap(), this->OverlappingMap_); + this->subdomainMatrix_->doImport(*(this->OverlappingMatrix_), *scatter, ADD); + + // Used to Map original K_ to overlapping suubdomainMatrix + this->subdomainScatter_ = ImportFactory::Build(this->K_->getRowMap(), this->OverlappingMap_); // build local subdomain matrix RCP > SerialComm = rcp(new MpiComm(MPI_COMM_SELF)); From d9b9741f063a80cd17dd0f1eb821a04b704828d0 Mon Sep 17 00:00:00 2001 From: Samuel Browne Date: Fri, 15 Mar 2024 07:40:58 -0600 Subject: [PATCH 05/17] Add a CUDA nightly all config Omit Epetra, as does the PR config. --- packages/framework/ini-files/config-specs.ini | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/framework/ini-files/config-specs.ini b/packages/framework/ini-files/config-specs.ini index f86ae8157dff..0370843b29ad 100644 --- a/packages/framework/ini-files/config-specs.ini +++ b/packages/framework/ini-files/config-specs.ini @@ -2318,6 +2318,10 @@ use CUDA11-RUN-SERIAL-TESTS opt-set-cmake-var Trilinos_ENABLE_TESTS BOOL FORCE : OFF +[rhel7_sems-cuda-11.4.2-sems-gnu-10.1.0-sems-openmpi-4.0.5_release_static_Volta70_no-asan_complex_no-fpic_mpi_pt_no-rdc_uvm_deprecated-on_all] +use rhel7_sems-cuda-11.4.2-sems-gnu-10.1.0-sems-openmpi-4.0.5_release_static_Volta70_no-asan_complex_no-fpic_mpi_pt_no-rdc_uvm_deprecated-on_no-package-enables +use PACKAGE-ENABLES|ALL-NO-EPETRA + [rhel7_sems-cuda-11.4.2-sems-gnu-10.1.0-sems-openmpi-4.0.5_release_static_Volta70_no-asan_complex_no-fpic_mpi_pt_rdc_uvm_deprecated-on_all] # uses sems-v2 modules use rhel7_sems-cuda-11.4.2-sems-gnu-10.1.0-sems-openmpi-4.0.5_release_static_Volta70_no-asan_complex_no-fpic_mpi_pt_no-rdc_uvm_deprecated-on_no-package-enables From afecfedb711e94adf9523db2718f9ce2422ffdd4 Mon Sep 17 00:00:00 2001 From: Maarten Arnst Date: Fri, 15 Mar 2024 16:25:46 +0100 Subject: [PATCH 06/17] Continue work to allow space instance to be passed to getValues --- .../Basis/Intrepid2_HCURL_TET_I1_FEM.hpp | 44 +++-- .../Basis/Intrepid2_HCURL_TET_I1_FEMDef.hpp | 41 ++--- .../Basis/Intrepid2_HCURL_TET_In_FEM.hpp | 53 +++--- .../Basis/Intrepid2_HCURL_TET_In_FEMDef.hpp | 34 +++- .../Basis/Intrepid2_HCURL_TRI_I1_FEM.hpp | 38 ++-- .../Basis/Intrepid2_HCURL_TRI_I1_FEMDef.hpp | 5 +- .../Basis/Intrepid2_HCURL_TRI_In_FEMDef.hpp | 22 ++- .../Basis/Intrepid2_HDIV_TET_In_FEMDef.hpp | 18 +- .../Basis/Intrepid2_HDIV_TRI_In_FEMDef.hpp | 20 ++- .../Basis/Intrepid2_HGRAD_HEX_C1_FEM.hpp | 38 ++-- .../Basis/Intrepid2_HGRAD_HEX_C1_FEMDef.hpp | 5 +- .../Basis/Intrepid2_HGRAD_HEX_C2_FEM.hpp | 65 ++++--- .../Basis/Intrepid2_HGRAD_HEX_C2_FEMDef.hpp | 5 +- .../Basis/Intrepid2_HGRAD_HEX_Cn_FEM.hpp | 54 +++--- .../Basis/Intrepid2_HGRAD_HEX_Cn_FEMDef.hpp | 7 +- .../Basis/Intrepid2_HGRAD_LINE_Cn_FEMDef.hpp | 2 +- .../Intrepid2_HGRAD_LINE_Cn_FEM_JACOBI.hpp | 47 ++--- .../Intrepid2_HGRAD_LINE_Cn_FEM_JACOBIDef.hpp | 59 +++--- .../Basis/Intrepid2_HGRAD_TET_COMP12_FEM.hpp | 74 ++++---- .../Intrepid2_HGRAD_TET_COMP12_FEMDef.hpp | 5 +- .../Basis/Intrepid2_HGRAD_TET_Cn_FEMDef.hpp | 8 +- .../Basis/Intrepid2_HGRAD_TET_Cn_FEM_ORTH.hpp | 39 ++-- .../Intrepid2_HGRAD_TET_Cn_FEM_ORTHDef.hpp | 8 +- .../Basis/Intrepid2_HGRAD_TRI_Cn_FEMDef.hpp | 6 +- .../Basis/Intrepid2_HGRAD_TRI_Cn_FEM_ORTH.hpp | 39 ++-- .../Intrepid2_HGRAD_TRI_Cn_FEM_ORTHDef.hpp | 8 +- .../Basis/Intrepid2_HVOL_LINE_Cn_FEMDef.hpp | 2 +- .../Basis/Intrepid2_HVOL_TET_Cn_FEMDef.hpp | 38 ++-- .../Basis/Intrepid2_HVOL_TRI_Cn_FEMDef.hpp | 6 +- .../Basis/HCURL_TET_I1_FEM/test_01.hpp | 150 +++++++--------- .../Basis/HCURL_TET_In_FEM/test_01.hpp | 58 +++--- .../Basis/HCURL_TRI_I1_FEM/test_01.hpp | 169 ++++++++---------- .../Basis/HGRAD_HEX_C1_FEM/test_01.hpp | 67 +++---- .../Basis/HGRAD_HEX_C2_FEM/test_01.hpp | 70 +++----- .../Basis/HGRAD_HEX_Cn_FEM/test_01.hpp | 78 +++----- .../HGRAD_LINE_Cn_FEM_JACOBI/test_01.hpp | 13 +- .../Basis/HGRAD_TET_COMP12_FEM/test_01.hpp | 11 +- .../Basis/HGRAD_TET_Cn_FEM_ORTH/test_01.hpp | 17 +- .../Basis/HGRAD_TRI_Cn_FEM_ORTH/test_01.hpp | 37 ++-- 39 files changed, 741 insertions(+), 719 deletions(-) diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HCURL_TET_I1_FEM.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HCURL_TET_I1_FEM.hpp index bb0b2dd8a39f..7b5f76c97b58 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HCURL_TET_I1_FEM.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HCURL_TET_I1_FEM.hpp @@ -128,7 +128,8 @@ namespace Intrepid2 { typename outputValueValueType, class ...outputValueProperties, typename inputPointValueType, class ...inputPointProperties> static void - getValues( Kokkos::DynRankView outputValues, + getValues( const typename DeviceType::execution_space& space, + Kokkos::DynRankView outputValues, const Kokkos::DynRankView inputPoints, const EOperator operatorType); @@ -178,25 +179,29 @@ namespace Intrepid2 { typename pointValueType = double> class Basis_HCURL_TET_I1_FEM : public Basis { public: - using OrdinalTypeArray1DHost = typename Basis::OrdinalTypeArray1DHost; - using OrdinalTypeArray2DHost = typename Basis::OrdinalTypeArray2DHost; - using OrdinalTypeArray3DHost = typename Basis::OrdinalTypeArray3DHost; + using BasisBase = Basis; + using typename BasisBase::ExecutionSpace; + + using typename BasisBase::OrdinalTypeArray1DHost; + using typename BasisBase::OrdinalTypeArray2DHost; + using typename BasisBase::OrdinalTypeArray3DHost; + + using typename BasisBase::OutputViewType; + using typename BasisBase::PointViewType ; + using typename BasisBase::ScalarViewType; /** \brief Constructor. */ Basis_HCURL_TET_I1_FEM(); - using OutputViewType = typename Basis::OutputViewType; - using PointViewType = typename Basis::PointViewType; - using ScalarViewType = typename Basis::ScalarViewType; - - using Basis::getValues; + using BasisBase::getValues; virtual void - getValues( OutputViewType outputValues, - const PointViewType inputPoints, - const EOperator operatorType = OPERATOR_VALUE ) const override { + getValues( const ExecutionSpace& space, + OutputViewType outputValues, + const PointViewType inputPoints, + const EOperator operatorType = OPERATOR_VALUE ) const override { #ifdef HAVE_INTREPID2_DEBUG // Verify arguments Intrepid2::getValues_HCURL_Args(outputValues, @@ -206,9 +211,10 @@ namespace Intrepid2 { this->getCardinality() ); #endif Impl::Basis_HCURL_TET_I1_FEM:: - getValues( outputValues, - inputPoints, - operatorType ); + getValues(space, + outputValues, + inputPoints, + operatorType); } virtual @@ -227,8 +233,8 @@ namespace Intrepid2 { #endif Kokkos::deep_copy(dofCoords, this->dofCoords_); } - - + + virtual void getDofCoeffs( ScalarViewType dofCoeffs ) const override { @@ -284,8 +290,8 @@ namespace Intrepid2 { BasisPtr getHostBasis() const override{ return Teuchos::rcp(new Basis_HCURL_TET_I1_FEM()); - } - + } + }; }// namespace Intrepid2 diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HCURL_TET_I1_FEMDef.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HCURL_TET_I1_FEMDef.hpp index 307c117bf3e2..50d2b116d4e6 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HCURL_TET_I1_FEMDef.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HCURL_TET_I1_FEMDef.hpp @@ -53,21 +53,21 @@ namespace Intrepid2 { // ------------------------------------------------------------------------------------- namespace Impl { - + template - template + template KOKKOS_INLINE_FUNCTION void Basis_HCURL_TET_I1_FEM::Serial:: - getValues( OutputViewType output, - const inputViewType input ) { + getValues( OutputViewType output, + const inputViewType input ) { switch (opType) { case OPERATOR_VALUE: { const auto x = input(0); const auto y = input(1); const auto z = input(2); - + // output is subview of a rank-3 array with dimensions (basisCardinality_, dim0, spaceDim), dim0 is iteration from range output.access(0, 0) = 2.0*(1.0 - y - z); output.access(0, 1) = 2.0*x; @@ -105,7 +105,7 @@ namespace Intrepid2 { output.access(1, 2) = 4.0; output.access(2, 0) =-4.0; - output.access(2, 1) = 0.0; + output.access(2, 1) = 0.0; output.access(2, 2) = 4.0; output.access(3, 0) =-4.0; @@ -123,18 +123,19 @@ namespace Intrepid2 { } default: { INTREPID2_TEST_FOR_ABORT( opType != OPERATOR_VALUE && - opType != OPERATOR_CURL, + opType != OPERATOR_CURL, ">>> ERROR: (Intrepid2::Basis_HCURL_TET_I1_FEM::Serial::getValues) operator is not supported"); } } } - template void Basis_HCURL_TET_I1_FEM:: - getValues( Kokkos::DynRankView outputValues, + getValues( const typename DT::execution_space& space, + Kokkos::DynRankView outputValues, const Kokkos::DynRankView inputPoints, const EOperator operatorType ) { typedef Kokkos::DynRankView outputValueViewType; @@ -143,20 +144,20 @@ namespace Intrepid2 { // Number of evaluation points = dim 0 of inputPoints const auto loopSize = inputPoints.extent(0); - Kokkos::RangePolicy > policy(0, loopSize); - + Kokkos::RangePolicy > policy(space, 0, loopSize); + switch (operatorType) { case OPERATOR_VALUE: { typedef Functor FunctorType; Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints) ); break; - } + } case OPERATOR_CURL: { typedef Functor FunctorType; Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints) ); break; - } + } case OPERATOR_DIV: { INTREPID2_TEST_FOR_EXCEPTION( (operatorType == OPERATOR_DIV), std::invalid_argument, ">>> ERROR (Basis_HCURL_TET_I1_FEM): DIV is invalid operator for HCURL Basis Functions"); @@ -225,16 +226,16 @@ namespace Intrepid2 { this->basisType_ = BASIS_FEM_DEFAULT; this->basisCoordinates_ = COORDINATES_CARTESIAN; this->functionSpace_ = FUNCTION_SPACE_HCURL; - + // initialize tags { // Basis-dependent intializations const ordinal_type tagSize = 4; // size of DoF tag - const ordinal_type posScDim = 0; // position in the tag, counting from 0, of the subcell dim + const ordinal_type posScDim = 0; // position in the tag, counting from 0, of the subcell dim const ordinal_type posScOrd = 1; // position in the tag, counting from 0, of the subcell ordinal const ordinal_type posDfOrd = 2; // position in the tag, counting from 0, of DoF ordinal relative to the subcell - - // An array with local DoF tags assigned to basis functions, in the order of their local enumeration + + // An array with local DoF tags assigned to basis functions, in the order of their local enumeration ordinal_type tags[24] = { 1, 0, 0, 1, 1, 1, 0, 1, @@ -242,10 +243,10 @@ namespace Intrepid2 { 1, 3, 0, 1, 1, 4, 0, 1, 1, 5, 0, 1 }; - + //host tags OrdinalTypeArray1DHost tagView(&tags[0], 24); - + // Basis-independent function sets tag and enum data in tagToOrdinal_ and ordinalToTag_ arrays: this->setOrdinalTagData(this->tagToOrdinal_, this->ordinalToTag_, diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HCURL_TET_In_FEM.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HCURL_TET_In_FEM.hpp index 126d9828c17e..4567f6a85d68 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HCURL_TET_In_FEM.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HCURL_TET_In_FEM.hpp @@ -59,14 +59,14 @@ namespace Intrepid2 { /** \class Intrepid2::Basis_HCURL_TET_In_FEM - \brief Implementation of the default H(curl)-compatible Nedelec (first kind) - basis of arbitrary degree on Tetrahedron cell. + \brief Implementation of the default H(curl)-compatible Nedelec (first kind) + basis of arbitrary degree on Tetrahedron cell. The lowest order space is indexted with 1 rather than 0. Implements nodal basis of degree n (n>=1) on the reference Tetrahedron cell. The basis has cardinality n*(n+2)*(n+3)/2 and spans an INCOMPLETE - polynomial space of degree n. Basis functions are dual + polynomial space of degree n. Basis functions are dual to a unisolvent set of degrees-of-freedom (DoF) defined by \li The tangential component of the vector field at n @@ -136,7 +136,9 @@ class Basis_HCURL_TET_In_FEM { typename inputPointValueType, class ...inputPointProperties, typename vinvValueType, class ...vinvProperties> static void - getValues( Kokkos::DynRankView outputValues, + getValues( + const typename DeviceType::execution_space& space, + Kokkos::DynRankView outputValues, const Kokkos::DynRankView inputPoints, const Kokkos::DynRankView vinv, const EOperator operatorType); @@ -204,30 +206,34 @@ template class Basis_HCURL_TET_In_FEM : public Basis { - public: - typedef typename Basis::OrdinalTypeArray1DHost OrdinalTypeArray1DHost; - typedef typename Basis::OrdinalTypeArray2DHost OrdinalTypeArray2DHost; - typedef typename Basis::OrdinalTypeArray3DHost OrdinalTypeArray3DHost; + public: + using BasisBase = Basis; + using typename BasisBase::ExecutionSpace; + + using typename BasisBase::OrdinalTypeArray1DHost; + using typename BasisBase::OrdinalTypeArray2DHost; + using typename BasisBase::OrdinalTypeArray3DHost; + + using typename BasisBase::OutputViewType; + using typename BasisBase::PointViewType ; + using typename BasisBase::ScalarViewType; /** \brief Constructor. */ Basis_HCURL_TET_In_FEM(const ordinal_type order, const EPointType pointType = POINTTYPE_EQUISPACED); - - using OutputViewType = typename Basis::OutputViewType; - using PointViewType = typename Basis::PointViewType; - using ScalarViewType = typename Basis::ScalarViewType; - typedef typename Basis::scalarType scalarType; - using Basis::getValues; + using BasisBase::getValues; virtual void - getValues( OutputViewType outputValues, - const PointViewType inputPoints, - const EOperator operatorType = OPERATOR_VALUE) const override { + getValues( + const ExecutionSpace& space, + OutputViewType outputValues, + const PointViewType inputPoints, + const EOperator operatorType = OPERATOR_VALUE) const override { #ifdef HAVE_INTREPID2_DEBUG Intrepid2::getValues_HCURL_Args(outputValues, inputPoints, @@ -237,10 +243,11 @@ class Basis_HCURL_TET_In_FEM #endif constexpr ordinal_type numPtsPerEval = Parameters::MaxNumPtsPerBasisEval; Impl::Basis_HCURL_TET_In_FEM:: - getValues( outputValues, - inputPoints, - this->coeffs_, - operatorType); + getValues(space, + outputValues, + inputPoints, + this->coeffs_, + operatorType); } virtual @@ -259,7 +266,7 @@ class Basis_HCURL_TET_In_FEM #endif Kokkos::deep_copy(dofCoords, this->dofCoords_); } - + virtual void getDofCoeffs( ScalarViewType dofCoeffs ) const override { @@ -321,7 +328,7 @@ class Basis_HCURL_TET_In_FEM BasisPtr getHostBasis() const override{ return Teuchos::rcp(new Basis_HCURL_TET_In_FEM(this->basisDegree_, pointType_)); - } + } private: diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HCURL_TET_In_FEMDef.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HCURL_TET_In_FEMDef.hpp index 3022bc288cfa..41b5c8bedfbf 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HCURL_TET_In_FEMDef.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HCURL_TET_In_FEMDef.hpp @@ -142,7 +142,9 @@ typename inputPointValueType, class ...inputPointProperties, typename vinvValueType, class ...vinvProperties> void Basis_HCURL_TET_In_FEM:: -getValues( Kokkos::DynRankView outputValues, +getValues( + const typename DT::execution_space& space, + Kokkos::DynRankView outputValues, const Kokkos::DynRankView inputPoints, const Kokkos::DynRankView coeffs, const EOperator operatorType) { @@ -155,7 +157,7 @@ getValues( Kokkos::DynRankView > policy(0, loopSize); + Kokkos::RangePolicy > policy(space, 0, loopSize); typedef typename inputPointViewType::value_type inputPointType; @@ -167,14 +169,14 @@ getValues( Kokkos::DynRankView FunctorType; Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints, coeffs, work) ); break; } case OPERATOR_CURL: { - workViewType work(Kokkos::view_alloc("Basis_HCURL_TET_In_FEM::getValues::work", vcprop), cardinality*(2*spaceDim+1), inputPoints.extent(0)); + workViewType work(Kokkos::view_alloc(space, "Basis_HCURL_TET_In_FEM::getValues::work", vcprop), cardinality*(2*spaceDim+1), inputPoints.extent(0)); typedef Functor FunctorType; Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints, coeffs, work) ); @@ -253,7 +255,11 @@ Basis_HCURL_TET_In_FEM( const ordinal_type order, // tabulate the scalar orthonormal basis at cubature points Kokkos::DynRankView phisAtCubPoints("Hcurl::Tet::In::phisAtCubPoints", cardPn , myCub.getNumPoints() ); - Impl::Basis_HGRAD_TET_Cn_FEM_ORTH::getValues(phisAtCubPoints, cubPoints, order, OPERATOR_VALUE); + Impl::Basis_HGRAD_TET_Cn_FEM_ORTH::getValues(typename Kokkos::HostSpace::execution_space{}, + phisAtCubPoints, + cubPoints, + order, + OPERATOR_VALUE); // Integrate (x psi_j, y psi_j, z psi_j) \times (phi_i, phi_{i+cardPn}, phi_{i+2 cardPn}) cross product. psi are homogeneous polynomials of order (n-1) for (ordinal_type i=0;ibasisCellTopology_); - Impl::Basis_HGRAD_TET_Cn_FEM_ORTH::getValues(phisAtEdgePoints , edgePts, order, OPERATOR_VALUE); + Impl::Basis_HGRAD_TET_Cn_FEM_ORTH::getValues(typename Kokkos::HostSpace::execution_space{}, + phisAtEdgePoints, + edgePts, + order, + OPERATOR_VALUE); // loop over points (rows of V2) for (ordinal_type j=0;jbasisCellTopology_ ); - Impl::Basis_HGRAD_TET_Cn_FEM_ORTH::getValues(phisAtFacePoints , facePts, order, OPERATOR_VALUE); + Impl::Basis_HGRAD_TET_Cn_FEM_ORTH::getValues(typename Kokkos::HostSpace::execution_space{}, + phisAtFacePoints, + facePts, + order, + OPERATOR_VALUE); // loop over points (rows of V2) for (ordinal_type j=0;j phisAtCellPoints("Hcurl::Tet::In::phisAtCellPoints", cardPn , numPtsPerCell ); - Impl::Basis_HGRAD_TET_Cn_FEM_ORTH::getValues( phisAtCellPoints , cellPoints , order, OPERATOR_VALUE ); + Impl::Basis_HGRAD_TET_Cn_FEM_ORTH::getValues(typename Kokkos::HostSpace::execution_space{}, + phisAtCellPoints, + cellPoints, + order, + OPERATOR_VALUE); // copy values into right positions of V2 for (ordinal_type j=0;j static void - getValues( Kokkos::DynRankView outputValues, + getValues( const typename DeviceType::execution_space& space, + Kokkos::DynRankView outputValues, const Kokkos::DynRankView inputPoints, const EOperator operatorType); @@ -181,23 +182,27 @@ namespace Intrepid2 { typename pointValueType = double > class Basis_HCURL_TRI_I1_FEM : public Basis { public: - using OrdinalTypeArray1DHost = typename Basis::OrdinalTypeArray1DHost; - using OrdinalTypeArray2DHost = typename Basis::OrdinalTypeArray2DHost; - using OrdinalTypeArray3DHost = typename Basis::OrdinalTypeArray3DHost; + using BasisBase = Basis; + using typename BasisBase::ExecutionSpace; + + using typename BasisBase::OrdinalTypeArray1DHost; + using typename BasisBase::OrdinalTypeArray2DHost; + using typename BasisBase::OrdinalTypeArray3DHost; + + using typename BasisBase::OutputViewType; + using typename BasisBase::PointViewType ; + using typename BasisBase::ScalarViewType; /** \brief Constructor. */ Basis_HCURL_TRI_I1_FEM(); - using OutputViewType = typename Basis::OutputViewType; - using PointViewType = typename Basis::PointViewType; - using ScalarViewType = typename Basis::ScalarViewType; - - using Basis::getValues; + using BasisBase::getValues; virtual void - getValues( OutputViewType outputValues, + getValues( const ExecutionSpace& space, + OutputViewType outputValues, const PointViewType inputPoints, const EOperator operatorType = OPERATOR_VALUE ) const override { #ifdef HAVE_INTREPID2_DEBUG @@ -209,9 +214,10 @@ namespace Intrepid2 { this->getCardinality() ); #endif Impl::Basis_HCURL_TRI_I1_FEM:: - getValues( outputValues, - inputPoints, - operatorType ); + getValues(space, + outputValues, + inputPoints, + operatorType); } virtual @@ -230,7 +236,7 @@ namespace Intrepid2 { #endif Kokkos::deep_copy(dofCoords, this->dofCoords_); } - + virtual void getDofCoeffs( ScalarViewType dofCoeffs ) const override { @@ -246,8 +252,8 @@ namespace Intrepid2 { ">>> ERROR: (Intrepid2::Basis_HCURL_TRI_I1_FEM::getDofCoeffs) incorrect reference cell (1st) dimension in dofCoeffs array"); #endif Kokkos::deep_copy(dofCoeffs, this->dofCoeffs_); - } - + } + virtual const char* diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HCURL_TRI_I1_FEMDef.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HCURL_TRI_I1_FEMDef.hpp index e2e6c4eaaf9d..bd87a8749c2b 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HCURL_TRI_I1_FEMDef.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HCURL_TRI_I1_FEMDef.hpp @@ -99,7 +99,8 @@ namespace Intrepid2 { typename inputPointValueType, class ...inputPointProperties> void Basis_HCURL_TRI_I1_FEM:: - getValues( Kokkos::DynRankView outputValues, + getValues( const typename DT::execution_space& space, + Kokkos::DynRankView outputValues, const Kokkos::DynRankView inputPoints, const EOperator operatorType ) { typedef Kokkos::DynRankView outputValueViewType; @@ -108,7 +109,7 @@ namespace Intrepid2 { // Number of evaluation points = dim 0 of inputPoints const auto loopSize = inputPoints.extent(0); - Kokkos::RangePolicy > policy(0, loopSize); + Kokkos::RangePolicy > policy(space, 0, loopSize); switch (operatorType) { case OPERATOR_VALUE: { diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HCURL_TRI_In_FEMDef.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HCURL_TRI_In_FEMDef.hpp index 0f06f692e40d..d2b6552f31f6 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HCURL_TRI_In_FEMDef.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HCURL_TRI_In_FEMDef.hpp @@ -85,7 +85,7 @@ namespace Intrepid2 { break; } } - + typedef typename Kokkos::DynRankView viewType; auto vcprop = Kokkos::common_view_alloc_prop(work); auto ptr = work.data(); @@ -210,7 +210,7 @@ namespace Intrepid2 { // Note: the only reason why equispaced can't support higher order than Parameters::MaxOrder appears to be the fact that the tags below get stored into a fixed-length array. // TODO: relax the maximum order requirement by setting up tags in a different container, perhaps directly into an OrdinalTypeArray1DHost (tagView, below). (As of this writing (1/25/22), looks like other nodal bases do this in a similar way -- those should be fixed at the same time; maybe search for Parameters::MaxOrder.) INTREPID2_TEST_FOR_EXCEPTION( order > Parameters::MaxOrder, std::invalid_argument, "polynomial order exceeds the max supported by this class"); - + // Basis-dependent initializations constexpr ordinal_type tagSize = 4; // size of DoF tag, i.e., number of fields in the tag constexpr ordinal_type maxCard = CardinalityHCurlTri(Parameters::MaxOrder); @@ -257,7 +257,11 @@ namespace Intrepid2 { // tabulate the scalar orthonormal basis at cubature points Kokkos::DynRankView phisAtCubPoints("Hcurl::Tri::In::phisAtCubPoints", cardPn , myCub.getNumPoints() ); - Impl::Basis_HGRAD_TRI_Cn_FEM_ORTH::getValues(phisAtCubPoints, cubPoints, order, OPERATOR_VALUE); + Impl::Basis_HGRAD_TRI_Cn_FEM_ORTH::getValues(typename Kokkos::HostSpace::execution_space{}, + phisAtCubPoints, + cubPoints, + order, + OPERATOR_VALUE); // now do the integration for (ordinal_type i=0;ibasisCellTopology_ ); - Impl::Basis_HGRAD_TRI_Cn_FEM_ORTH::getValues(phisAtEdgePoints , edgePts, order, OPERATOR_VALUE); + Impl::Basis_HGRAD_TRI_Cn_FEM_ORTH::getValues(typename Kokkos::HostSpace::execution_space{}, + phisAtEdgePoints, + edgePts, + order, + OPERATOR_VALUE); // loop over points (rows of V2) for (ordinal_type j=0;j phisAtInternalPoints("Hcurl::Tri::In::phisAtInternalPoints", cardPn , numPtsPerCell ); - Impl::Basis_HGRAD_TRI_Cn_FEM_ORTH::getValues( phisAtInternalPoints , internalPoints , order, OPERATOR_VALUE ); + Impl::Basis_HGRAD_TRI_Cn_FEM_ORTH::getValues(typename Kokkos::HostSpace::execution_space{}, + phisAtInternalPoints, + internalPoints, + order, + OPERATOR_VALUE); // copy values into right positions of V2 for (ordinal_type j=0;j phisAtCubPoints("Hdiv::Tet::In::phisAtCubPoints", cardPn , myCub.getNumPoints() ); - Impl::Basis_HGRAD_TET_Cn_FEM_ORTH::getValues(phisAtCubPoints, cubPoints, order, OPERATOR_VALUE); + Impl::Basis_HGRAD_TET_Cn_FEM_ORTH::getValues(typename Kokkos::HostSpace::execution_space{}, + phisAtCubPoints, + cubPoints, + order, + OPERATOR_VALUE); // now do the integration for (ordinal_type i=0;ibasisCellTopology_ ); // get phi values at face points - Impl::Basis_HGRAD_TET_Cn_FEM_ORTH::getValues(phisAtFacePoints, facePts, order, OPERATOR_VALUE); + Impl::Basis_HGRAD_TET_Cn_FEM_ORTH::getValues(typename Kokkos::HostSpace::execution_space{}, + phisAtFacePoints, + facePts, + order, + OPERATOR_VALUE); // loop over points (rows of V2) for (ordinal_type j=0;j phisAtInternalPoints("Hdiv::Tet::In::phisAtInternalPoints", cardPn , numPtsPerCell ); - Impl::Basis_HGRAD_TET_Cn_FEM_ORTH::getValues( phisAtInternalPoints , internalPoints , order, OPERATOR_VALUE ); + Impl::Basis_HGRAD_TET_Cn_FEM_ORTH::getValues(typename Kokkos::HostSpace::execution_space{}, + phisAtInternalPoints, + internalPoints, + order, + OPERATOR_VALUE ); // copy values into right positions of V2 for (ordinal_type j=0;j viewType; auto vcprop = Kokkos::common_view_alloc_prop(work); auto ptr = work.data(); @@ -254,7 +254,11 @@ Basis_HDIV_TRI_In_FEM( const ordinal_type order, // tabulate the scalar orthonormal basis at cubature points Kokkos::DynRankView phisAtCubPoints("Hdiv::Tri::In::phisAtCubPoints", cardPn , myCub.getNumPoints() ); - Impl::Basis_HGRAD_TRI_Cn_FEM_ORTH::getValues(phisAtCubPoints, cubPoints, order, OPERATOR_VALUE); + Impl::Basis_HGRAD_TRI_Cn_FEM_ORTH::getValues(typename Kokkos::HostSpace::execution_space{}, + phisAtCubPoints, + cubPoints, + order, + OPERATOR_VALUE); // now do the integration for (ordinal_type i=0;ibasisCellTopology_ ); - Impl::Basis_HGRAD_TRI_Cn_FEM_ORTH::getValues(phisAtEdgePoints , edgePts, order, OPERATOR_VALUE); + Impl::Basis_HGRAD_TRI_Cn_FEM_ORTH::getValues(typename Kokkos::HostSpace::execution_space{}, + phisAtEdgePoints, + edgePts, + order, + OPERATOR_VALUE); // loop over points (rows of V2) for (ordinal_type j=0;j phisAtInternalPoints("Hdiv::Tri::In::phisAtInternalPoints", cardPn , numPtsPerCell ); - Impl::Basis_HGRAD_TRI_Cn_FEM_ORTH::getValues( phisAtInternalPoints , internalPoints , order, OPERATOR_VALUE ); + Impl::Basis_HGRAD_TRI_Cn_FEM_ORTH::getValues(typename Kokkos::HostSpace::execution_space{}, + phisAtInternalPoints, + internalPoints, + order, + OPERATOR_VALUE); // copy values into right positions of V2 for (ordinal_type j=0;j static void - getValues( Kokkos::DynRankView outputValues, + getValues( const typename DeviceType::execution_space& space, + Kokkos::DynRankView outputValues, const Kokkos::DynRankView inputPoints, const EOperator operatorType); @@ -171,37 +172,42 @@ namespace Intrepid2 { typename pointValueType = double> class Basis_HGRAD_HEX_C1_FEM : public Basis { public: - using OrdinalTypeArray1DHost = typename Basis::OrdinalTypeArray1DHost; - using OrdinalTypeArray2DHost = typename Basis::OrdinalTypeArray2DHost; - using OrdinalTypeArray3DHost = typename Basis::OrdinalTypeArray3DHost; + using BasisBase = Basis; + using typename BasisBase::ExecutionSpace; + + using typename BasisBase::OrdinalTypeArray1DHost; + using typename BasisBase::OrdinalTypeArray2DHost; + using typename BasisBase::OrdinalTypeArray3DHost; + + using typename BasisBase::OutputViewType; + using typename BasisBase::PointViewType ; + using typename BasisBase::ScalarViewType; /** \brief Constructor. */ Basis_HGRAD_HEX_C1_FEM(); - using OutputViewType = typename Basis::OutputViewType; - using PointViewType = typename Basis::PointViewType; - using ScalarViewType = typename Basis::ScalarViewType; - - using Basis::getValues; + using BasisBase::getValues; virtual void - getValues( OutputViewType outputValues, - const PointViewType inputPoints, - const EOperator operatorType = OPERATOR_VALUE ) const override { + getValues( const ExecutionSpace& space, + OutputViewType outputValues, + const PointViewType inputPoints, + const EOperator operatorType = OPERATOR_VALUE ) const override { #ifdef HAVE_INTREPID2_DEBUG // Verify arguments Intrepid2::getValues_HGRAD_Args(outputValues, inputPoints, operatorType, this->getBaseCellTopology(), - this->getCardinality() ); + this->getCardinality()); #endif Impl::Basis_HGRAD_HEX_C1_FEM:: - getValues( outputValues, - inputPoints, - operatorType ); + getValues(space, + outputValues, + inputPoints, + operatorType); } virtual diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_HEX_C1_FEMDef.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_HEX_C1_FEMDef.hpp index ce7862801bc8..4457c622005b 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_HEX_C1_FEMDef.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_HEX_C1_FEMDef.hpp @@ -310,7 +310,8 @@ namespace Intrepid2 { typename inputPointValueType, class ...inputPointProperties> void Basis_HGRAD_HEX_C1_FEM:: - getValues( Kokkos::DynRankView outputValues, + getValues( const typename DT::execution_space& space, + Kokkos::DynRankView outputValues, const Kokkos::DynRankView inputPoints, const EOperator operatorType ) { typedef Kokkos::DynRankView outputValueViewType; @@ -319,7 +320,7 @@ namespace Intrepid2 { // Number of evaluation points = dim 0 of inputPoints const auto loopSize = inputPoints.extent(0); - Kokkos::RangePolicy > policy(0, loopSize); + Kokkos::RangePolicy > policy(space, 0, loopSize); switch (operatorType) { diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_HEX_C2_FEM.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_HEX_C2_FEM.hpp index 199371e9c771..42af457ed601 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_HEX_C2_FEM.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_HEX_C2_FEM.hpp @@ -57,8 +57,8 @@ namespace Intrepid2 { /** \class Intrepid2::Basis_HGRAD_HEX_DEG2_FEM \brief Implementation of the default H(grad)-compatible FEM basis of degree 2 on Hexahedron cell - Implements Lagrangian basis of degree 2 on the reference Hexahedron cell. - + Implements Lagrangian basis of degree 2 on the reference Hexahedron cell. + When the serendipity template argument is false, the basis has cardinality 27 and spans a COMPLETE tri-quadratic polynomial space. Note, Basis_HGRAD_HEX_C2_FEM = Basis_HGRAD_HEX_DEG2_FEM @@ -164,17 +164,18 @@ namespace Intrepid2 { static void getValues( OutputViewType output, const inputViewType input ); - + }; - - template static void - getValues( Kokkos::DynRankView outputValues, + getValues( const typename DeviceType::execution_space& space, + Kokkos::DynRankView outputValues, const Kokkos::DynRankView inputPoints, const EOperator operatorType); - + /** \brief See Intrepid2::Basis_HGRAD_HEX_DEG2_FEM */ @@ -184,12 +185,12 @@ namespace Intrepid2 { struct Functor { outputValueViewType _outputValues; const inputPointViewType _inputPoints; - + KOKKOS_INLINE_FUNCTION Functor( outputValueViewType outputValues_, inputPointViewType inputPoints_ ) : _outputValues(outputValues_), _inputPoints(inputPoints_) {} - + KOKKOS_INLINE_FUNCTION void operator()(const ordinal_type pt) const { switch (opType) { @@ -225,50 +226,56 @@ namespace Intrepid2 { }; }; } - + template class Basis_HGRAD_HEX_DEG2_FEM : public Basis { public: - using OrdinalTypeArray1DHost = typename Basis::OrdinalTypeArray1DHost; - using OrdinalTypeArray2DHost = typename Basis::OrdinalTypeArray2DHost; - using OrdinalTypeArray3DHost = typename Basis::OrdinalTypeArray3DHost; + using BasisBase = Basis; + using typename BasisBase::ExecutionSpace; + + using typename BasisBase::OrdinalTypeArray1DHost; + using typename BasisBase::OrdinalTypeArray2DHost; + using typename BasisBase::OrdinalTypeArray3DHost; + + using typename BasisBase::OutputViewType; + using typename BasisBase::PointViewType ; + using typename BasisBase::ScalarViewType; /** \brief Constructor. */ Basis_HGRAD_HEX_DEG2_FEM(); - using OutputViewType = typename Basis::OutputViewType; - using PointViewType = typename Basis::PointViewType; - using ScalarViewType = typename Basis::ScalarViewType; - - using Basis::getValues; + using BasisBase::getValues; virtual void - getValues( OutputViewType outputValues, - const PointViewType inputPoints, - const EOperator operatorType = OPERATOR_VALUE ) const override { + getValues( const ExecutionSpace& space, + OutputViewType outputValues, + const PointViewType inputPoints, + const EOperator operatorType = OPERATOR_VALUE ) const override { #ifdef HAVE_INTREPID2_DEBUG // Verify arguments Intrepid2::getValues_HGRAD_Args(outputValues, inputPoints, operatorType, this->getBaseCellTopology(), - this->getCardinality() ); + this->getCardinality()); #endif if constexpr (serendipity) Impl::Basis_HGRAD_HEX_DEG2_FEM:: - getValues( outputValues, - inputPoints, - operatorType ); - else + getValues(space, + outputValues, + inputPoints, + operatorType); + else Impl::Basis_HGRAD_HEX_DEG2_FEM:: - getValues( outputValues, - inputPoints, - operatorType ); + getValues(space, + outputValues, + inputPoints, + operatorType); } virtual diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_HEX_C2_FEMDef.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_HEX_C2_FEMDef.hpp index 7a2c562a524b..1596c9da27f3 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_HEX_C2_FEMDef.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_HEX_C2_FEMDef.hpp @@ -1481,7 +1481,8 @@ namespace Intrepid2 { typename inputPointValueType, class ...inputPointProperties> void Basis_HGRAD_HEX_DEG2_FEM:: - getValues( Kokkos::DynRankView outputValues, + getValues( const typename DT::execution_space& space, + Kokkos::DynRankView outputValues, const Kokkos::DynRankView inputPoints, const EOperator operatorType ) { typedef Kokkos::DynRankView outputValueViewType; @@ -1490,7 +1491,7 @@ namespace Intrepid2 { // Number of evaluation points = dim 0 of inputPoints const auto loopSize = inputPoints.extent(0); - Kokkos::RangePolicy > policy(0, loopSize); + Kokkos::RangePolicy > policy(space, 0, loopSize); switch (operatorType) { diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_HEX_Cn_FEM.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_HEX_Cn_FEM.hpp index 887aebe71561..35910c3034ea 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_HEX_Cn_FEM.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_HEX_Cn_FEM.hpp @@ -84,7 +84,8 @@ namespace Intrepid2 { typename inputPointValueType, class ...inputPointProperties, typename vinvValueType, class ...vinvProperties> static void - getValues( Kokkos::DynRankView outputValues, + getValues( const typename DeviceType::execution_space& space, + Kokkos::DynRankView outputValues, const Kokkos::DynRankView inputPoints, const Kokkos::DynRankView vinv, const EOperator operatorType ); @@ -111,9 +112,9 @@ namespace Intrepid2 { vinvViewType vinv_, workViewType work_, const ordinal_type opDn_ = 0 ) - : _outputValues(outputValues_), _inputPoints(inputPoints_), + : _outputValues(outputValues_), _inputPoints(inputPoints_), _vinv(vinv_), _work(work_), _opDn(opDn_) {} - + KOKKOS_INLINE_FUNCTION void operator()(const size_type iter) const { const auto ptBegin = Util::min(iter*numPtsEval, _inputPoints.extent(0)); @@ -149,16 +150,16 @@ namespace Intrepid2 { }; }; } - + /** \class Intrepid2::Basis_HGRAD_HEX_Cn_FEM - \brief Implementation of the default H(grad)-compatible FEM basis of degree 2 on Hexahedron cell - + \brief Implementation of the default H(grad)-compatible FEM basis of degree 2 on Hexahedron cell + Implements Lagrangian basis of degree n on the reference Hexahedron cell. The basis has - cardinality (n+1)^3 and spans a COMPLETE polynomial space. Basis functions are dual + cardinality (n+1)^3 and spans a COMPLETE polynomial space. Basis functions are dual to a unisolvent set of degrees-of-freedom (DoF) defined lexicographically on an array of input points. - - \endverbatim + + \endverbatim */ template { public: - using OrdinalTypeArray1DHost = typename Basis::OrdinalTypeArray1DHost; - using OrdinalTypeArray2DHost = typename Basis::OrdinalTypeArray2DHost; - using OrdinalTypeArray3DHost = typename Basis::OrdinalTypeArray3DHost; + using BasisBase = Basis; + using typename BasisBase::ExecutionSpace; + + using typename BasisBase::OrdinalTypeArray1DHost; + using typename BasisBase::OrdinalTypeArray2DHost; + using typename BasisBase::OrdinalTypeArray3DHost; - using OutputViewType = typename Basis::OutputViewType; - using PointViewType = typename Basis::PointViewType; - using ScalarViewType = typename Basis::ScalarViewType; + using typename BasisBase::OutputViewType; + using typename BasisBase::PointViewType ; + using typename BasisBase::ScalarViewType; private: /** \brief inverse of Generalized Vandermonde matrix (isotropic order) */ @@ -189,13 +193,14 @@ namespace Intrepid2 { Basis_HGRAD_HEX_Cn_FEM(const ordinal_type order, const EPointType pointType = POINTTYPE_EQUISPACED); - using Basis::getValues; + using BasisBase::getValues; virtual void - getValues( OutputViewType outputValues, - const PointViewType inputPoints, - const EOperator operatorType = OPERATOR_VALUE ) const override { + getValues( const ExecutionSpace& space, + OutputViewType outputValues, + const PointViewType inputPoints, + const EOperator operatorType = OPERATOR_VALUE ) const override { #ifdef HAVE_INTREPID2_DEBUG Intrepid2::getValues_HGRAD_Args(outputValues, inputPoints, @@ -205,10 +210,11 @@ namespace Intrepid2 { #endif constexpr ordinal_type numPtsPerEval = Parameters::MaxNumPtsPerBasisEval; Impl::Basis_HGRAD_HEX_Cn_FEM:: - getValues( outputValues, - inputPoints, - this->vinv_, - operatorType ); + getValues(space, + outputValues, + inputPoints, + this->vinv_, + operatorType); } @@ -262,7 +268,7 @@ namespace Intrepid2 { ordinal_type getWorkSizePerPoint(const EOperator operatorType) { - return 4*getPnCardinality<1>(this->basisDegree_); + return 4*getPnCardinality<1>(this->basisDegree_); } /** \brief returns the basis associated to a subCell. diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_HEX_Cn_FEMDef.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_HEX_Cn_FEMDef.hpp index e20ff590857a..89a6a1de4262 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_HEX_Cn_FEMDef.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_HEX_Cn_FEMDef.hpp @@ -198,7 +198,8 @@ namespace Intrepid2 { typename vinvValueType, class ...vinvProperties> void Basis_HGRAD_HEX_Cn_FEM:: - getValues( Kokkos::DynRankView outputValues, + getValues( const typename DT::execution_space& space, + Kokkos::DynRankView outputValues, const Kokkos::DynRankView inputPoints, const Kokkos::DynRankView vinv, const EOperator operatorType ) { @@ -211,7 +212,7 @@ namespace Intrepid2 { const auto loopSizeTmp1 = (inputPoints.extent(0)/numPtsPerEval); const auto loopSizeTmp2 = (inputPoints.extent(0)%numPtsPerEval != 0); const auto loopSize = loopSizeTmp1 + loopSizeTmp2; - Kokkos::RangePolicy > policy(0, loopSize); + Kokkos::RangePolicy > policy(space, 0, loopSize); typedef typename inputPointViewType::value_type inputPointType; @@ -221,7 +222,7 @@ namespace Intrepid2 { auto vcprop = Kokkos::common_view_alloc_prop(inputPoints); typedef typename Kokkos::DynRankView< inputPointType, typename inputPointViewType::memory_space> workViewType; - workViewType work(Kokkos::view_alloc("Basis_HGRAD_HEX_Cn_FEM::getValues::work", vcprop), workSize, inputPoints.extent(0)); + workViewType work(Kokkos::view_alloc(space, "Basis_HGRAD_HEX_Cn_FEM::getValues::work", vcprop), workSize, inputPoints.extent(0)); switch (operatorType) { case OPERATOR_VALUE: { diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_LINE_Cn_FEMDef.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_LINE_Cn_FEMDef.hpp index 56d6a8d1abf7..62b9e08f2e15 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_LINE_Cn_FEMDef.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_LINE_Cn_FEMDef.hpp @@ -249,7 +249,7 @@ namespace Intrepid2 { const double alpha = 0.0, beta = 0.0; Impl::Basis_HGRAD_LINE_Cn_FEM_JACOBI:: getValues - (vmat, dofCoords, order, alpha, beta, OPERATOR_VALUE); + (typename Kokkos::HostSpace::execution_space{}, vmat, dofCoords, order, alpha, beta, OPERATOR_VALUE); ordinal_type info = 0; Teuchos::LAPACK lapack; diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_LINE_Cn_FEM_JACOBI.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_LINE_Cn_FEM_JACOBI.hpp index ff587806eb20..40dad66b8788 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_LINE_Cn_FEM_JACOBI.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_LINE_Cn_FEM_JACOBI.hpp @@ -153,11 +153,12 @@ namespace Intrepid2 { const ordinal_type opDn = 0 ); }; - template static void - getValues( Kokkos::DynRankView outputValues, + getValues( const typename DeviceType::execution_space& space, + Kokkos::DynRankView outputValues, const Kokkos::DynRankView inputPoints, const ordinal_type order, const double alpha, @@ -232,27 +233,32 @@ namespace Intrepid2 { : public Basis { public: typedef double value_type; - using OrdinalTypeArray1DHost = typename Basis::OrdinalTypeArray1DHost; - using OrdinalTypeArray2DHost = typename Basis::OrdinalTypeArray2DHost; - using OrdinalTypeArray3DHost = typename Basis::OrdinalTypeArray3DHost; + + using BasisBase = Basis; + using typename BasisBase::ExecutionSpace; + + using typename BasisBase::OrdinalTypeArray1DHost; + using typename BasisBase::OrdinalTypeArray2DHost; + using typename BasisBase::OrdinalTypeArray3DHost; + + using typename BasisBase::OutputViewType; + using typename BasisBase::PointViewType ; + using typename BasisBase::ScalarViewType; /** \brief Constructor. */ Basis_HGRAD_LINE_Cn_FEM_JACOBI( const ordinal_type order, const double alpha = 0, - const double beta = 0 ); - - using OutputViewType = typename Basis::OutputViewType; - using PointViewType = typename Basis::PointViewType; - using ScalarViewType = typename Basis::ScalarViewType; + const double beta = 0 ); - using Basis::getValues; + using BasisBase::getValues; virtual void - getValues( OutputViewType outputValues, - const PointViewType inputPoints, - const EOperator operatorType = OPERATOR_VALUE ) const override { + getValues( const ExecutionSpace& space, + OutputViewType outputValues, + const PointViewType inputPoints, + const EOperator operatorType = OPERATOR_VALUE ) const override { #ifdef HAVE_INTREPID2_DEBUG Intrepid2::getValues_HGRAD_Args(outputValues, inputPoints, @@ -262,12 +268,13 @@ namespace Intrepid2 { #endif constexpr ordinal_type numPtsPerEval = 1; Impl::Basis_HGRAD_LINE_Cn_FEM_JACOBI:: - getValues( outputValues, - inputPoints, - this->getDegree(), - this->alpha_, - this->beta_, - operatorType ); + getValues(space, + outputValues, + inputPoints, + this->getDegree(), + this->alpha_, + this->beta_, + operatorType); } private: diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_LINE_Cn_FEM_JACOBIDef.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_LINE_Cn_FEM_JACOBIDef.hpp index fbdc0b44fe22..25efa624b21c 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_LINE_Cn_FEM_JACOBIDef.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_LINE_Cn_FEM_JACOBIDef.hpp @@ -54,7 +54,7 @@ namespace Intrepid2 { // ------------------------------------------------------------------------------------- namespace Impl { - + // output (N,P,D) // input (P,D) - assumes that it has a set of points to amortize the function call cost for jacobi polynomial. template @@ -86,11 +86,11 @@ namespace Intrepid2 { } break; } - case OPERATOR_GRAD: + case OPERATOR_GRAD: case OPERATOR_D1: { for (ordinal_type p=0;p - void + void Basis_HGRAD_LINE_Cn_FEM_JACOBI:: - getValues( Kokkos::DynRankView outputValues, + getValues( const typename DT::execution_space& space, + Kokkos::DynRankView outputValues, const Kokkos::DynRankView inputPoints, const ordinal_type order, const double alpha, @@ -160,19 +161,19 @@ namespace Intrepid2 { const auto loopSizeTmp1 = (inputPoints.extent(0)/numPtsPerEval); const auto loopSizeTmp2 = (inputPoints.extent(0)%numPtsPerEval != 0); const auto loopSize = loopSizeTmp1 + loopSizeTmp2; - Kokkos::RangePolicy > policy(0, loopSize); - + Kokkos::RangePolicy > policy(space, 0, loopSize); + switch (operatorType) { case OPERATOR_VALUE: { typedef Functor FunctorType; - Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints, + Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints, order, alpha, beta) ); break; } case OPERATOR_GRAD: case OPERATOR_D1: { typedef Functor FunctorType; - Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints, + Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints, order, alpha, beta) ); break; } @@ -186,7 +187,7 @@ namespace Intrepid2 { case OPERATOR_D9: case OPERATOR_D10: { typedef Functor FunctorType; - Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints, + Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints, order, alpha, beta, getOperatorOrder(operatorType)) ); break; @@ -210,19 +211,19 @@ namespace Intrepid2 { template Basis_HGRAD_LINE_Cn_FEM_JACOBI:: - Basis_HGRAD_LINE_Cn_FEM_JACOBI( const ordinal_type order, - const double alpha, + Basis_HGRAD_LINE_Cn_FEM_JACOBI( const ordinal_type order, + const double alpha, const double beta ) { this->basisCardinality_ = order+1; - this->basisDegree_ = order; + this->basisDegree_ = order; this->basisCellTopology_ = shards::CellTopology(shards::getCellTopologyData >() ); this->basisType_ = BASIS_FEM_HIERARCHICAL; this->basisCoordinates_ = COORDINATES_CARTESIAN; this->functionSpace_ = FUNCTION_SPACE_HGRAD; - // jacobi - this->alpha_ = alpha; - this->beta_ = beta; + // jacobi + this->alpha_ = alpha; + this->beta_ = beta; // initialize tags { @@ -231,20 +232,20 @@ namespace Intrepid2 { const ordinal_type posScDim = 0; // position in the tag, counting from 0, of the subcell dim const ordinal_type posScOrd = 1; // position in the tag, counting from 0, of the subcell ordinal const ordinal_type posDfOrd = 2; // position in the tag, counting from 0, of DoF ordinal relative to the subcell - + ordinal_type tags[Parameters::MaxOrder+1][4]; const ordinal_type card = this->basisCardinality_; for (ordinal_type i=0;isetOrdinalTagData(this->tagToOrdinal_, this->ordinalToTag_, tagView, diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TET_COMP12_FEM.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TET_COMP12_FEM.hpp index 4a45fd4954ef..221ea8eb1a78 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TET_COMP12_FEM.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TET_COMP12_FEM.hpp @@ -52,12 +52,12 @@ #include "Intrepid2_Basis.hpp" namespace Intrepid2 { - + /** \class Intrepid2::Basis_HGRAD_TET_COMP12_FEM \brief Implementation of the default H(grad)-compatible FEM basis of degree 2 on Tetrahedron cell - + Implements Lagrangian basis of degree 2 on the reference Tetrahedron cell. The basis has - cardinality 10 and spans a COMPLETE quadratic polynomial space. Basis functions are dual + cardinality 10 and spans a COMPLETE quadratic polynomial space. Basis functions are dual to a unisolvent set of degrees-of-freedom (DoF) defined and enumerated as follows: \verbatim @@ -90,8 +90,8 @@ namespace Intrepid2 { | MAX | maxScDim=0 | maxScOrd=3 | maxDfOrd=0 | - | | |=========|==============|==============|==============|=============|===========================| \endverbatim - - \remark Ordering of DoFs follows the node order in Tetrahedron<10> topology. Note that node order + + \remark Ordering of DoFs follows the node order in Tetrahedron<10> topology. Note that node order in this topology follows the natural order of k-subcells where the nodes are located, i.e., L_0 to L_3 correspond to 0-subcells (vertices) 0 to 3 and L_4 to L_9 correspond to 1-subcells (edges) 0 to 5. @@ -115,7 +115,7 @@ namespace Intrepid2 { getLocalSubTet( const pointValueType x, const pointValueType y, const pointValueType z ); - + /** \brief See Intrepid2::Basis_HGRAD_TET_COMP12_FEM */ @@ -127,17 +127,18 @@ namespace Intrepid2 { static void getValues( outputValueViewType outputValues, const inputPointViewType inputPoints ); - + }; - - template static void - getValues( Kokkos::DynRankView outputValues, + getValues( const typename DeviceType::execution_space& space, + Kokkos::DynRankView outputValues, const Kokkos::DynRankView inputPoints, const EOperator operatorType ); - + /** \brief See Intrepid2::Basis_HGRAD_TET_COMP12_FEM */ @@ -147,12 +148,12 @@ namespace Intrepid2 { struct Functor { outputValueViewType _outputValues; const inputPointViewType _inputPoints; - + KOKKOS_INLINE_FUNCTION Functor( outputValueViewType outputValues_, inputPointViewType inputPoints_ ) : _outputValues(outputValues_), _inputPoints(inputPoints_) {} - + KOKKOS_INLINE_FUNCTION void operator()(const ordinal_type pt) const { switch (opType) { @@ -186,37 +187,41 @@ namespace Intrepid2 { typename pointValueType = double> class Basis_HGRAD_TET_COMP12_FEM : public Basis { public: - using OrdinalTypeArray1DHost = typename Basis::OrdinalTypeArray1DHost; - using OrdinalTypeArray2DHost = typename Basis::OrdinalTypeArray2DHost; - using OrdinalTypeArray3DHost = typename Basis::OrdinalTypeArray3DHost; + using BasisBase = Basis; + using typename BasisBase::ExecutionSpace; + + using typename BasisBase::OrdinalTypeArray1DHost; + using typename BasisBase::OrdinalTypeArray2DHost; + using typename BasisBase::OrdinalTypeArray3DHost; + + using typename BasisBase::OutputViewType; + using typename BasisBase::PointViewType ; + using typename BasisBase::ScalarViewType; /** \brief Constructor. */ Basis_HGRAD_TET_COMP12_FEM(); - - using OutputViewType = typename Basis::OutputViewType; - using PointViewType = typename Basis::PointViewType; - using ScalarViewType = typename Basis::ScalarViewType; - using Basis::getValues; + using BasisBase::getValues; + + /** \brief FEM basis evaluation on a reference Tetrahedron cell. - /** \brief FEM basis evaluation on a reference Tetrahedron cell. - Returns values of operatorType acting on FEM basis functions for a set of - points in the reference Tetrahedron cell. For rank and dimensions of + points in the reference Tetrahedron cell. For rank and dimensions of I/O array arguments see Section \ref basis_md_array_sec . - + \param outputValues [out] - rank-2 or 3 array with the computed basis values - \param inputPoints [in] - rank-2 array with dimensions (P,D) containing reference points - \param operatorType [in] - operator applied to basis functions - + \param inputPoints [in] - rank-2 array with dimensions (P,D) containing reference points + \param operatorType [in] - operator applied to basis functions + For rank and dimension specifications of ArrayScalar arguments see \ref basis_array_specs */ virtual void - getValues( OutputViewType outputValues, - const PointViewType inputPoints, - const EOperator operatorType = OPERATOR_VALUE ) const override { + getValues( const ExecutionSpace& space, + OutputViewType outputValues, + const PointViewType inputPoints, + const EOperator operatorType = OPERATOR_VALUE ) const override { #ifdef HAVE_INTREPID2_DEBUG Intrepid2::getValues_HGRAD_Args(outputValues, inputPoints, @@ -225,9 +230,10 @@ namespace Intrepid2 { this->getCardinality() ); #endif Impl::Basis_HGRAD_TET_COMP12_FEM:: - getValues( outputValues, - inputPoints, - operatorType ); + getValues(space, + outputValues, + inputPoints, + operatorType); } /** \brief Returns spatial locations (coordinates) of degrees of freedom on a diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TET_COMP12_FEMDef.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TET_COMP12_FEMDef.hpp index a6aa40c9c986..692cea7f94aa 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TET_COMP12_FEMDef.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TET_COMP12_FEMDef.hpp @@ -321,7 +321,8 @@ namespace Intrepid2 { typename inputPointValueType, class ...inputPointProperties> void Basis_HGRAD_TET_COMP12_FEM:: - getValues( Kokkos::DynRankView outputValues, + getValues( const typename DT::execution_space& space, + Kokkos::DynRankView outputValues, const Kokkos::DynRankView inputPoints, const EOperator operatorType ) { typedef Kokkos::DynRankView outputValueViewType; @@ -330,7 +331,7 @@ namespace Intrepid2 { // Number of evaluation points = dim 0 of inputPoints const auto loopSize = inputPoints.extent(0); - Kokkos::RangePolicy > policy(0, loopSize); + Kokkos::RangePolicy > policy(space, 0, loopSize); switch (operatorType) { diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TET_Cn_FEMDef.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TET_Cn_FEMDef.hpp index 86948979154e..5b27697eea4c 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TET_Cn_FEMDef.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TET_Cn_FEMDef.hpp @@ -246,7 +246,7 @@ Basis_HGRAD_TET_Cn_FEM( const ordinal_type order, // Note: the only reason why equispaced can't support higher order than Parameters::MaxOrder appears to be the fact that the tags below get stored into a fixed-length array. // TODO: relax the maximum order requirement by setting up tags in a different container, perhaps directly into an OrdinalTypeArray1DHost (tagView, below). (As of this writing (1/25/22), looks like other nodal bases do this in a similar way -- those should be fixed at the same time; maybe search for Parameters::MaxOrder.) INTREPID2_TEST_FOR_EXCEPTION( order > Parameters::MaxOrder, std::invalid_argument, "polynomial order exceeds the max supported by this class"); - + // Basis-dependent initializations constexpr ordinal_type tagSize = 4; // size of DoF tag, i.e., number of fields in the tag constexpr ordinal_type maxCard = Intrepid2::getPnCardinality(); @@ -403,7 +403,11 @@ Basis_HGRAD_TET_Cn_FEM( const ordinal_type order, work("Hgrad::Tet::Cn::work", lwork), ipiv("Hgrad::Tet::Cn::ipiv", card); - Impl::Basis_HGRAD_TET_Cn_FEM_ORTH::getValues(vmat, dofCoords, order, OPERATOR_VALUE); + Impl::Basis_HGRAD_TET_Cn_FEM_ORTH::getValues(typename Kokkos::HostSpace::execution_space{}, + vmat, + dofCoords, + order, + OPERATOR_VALUE); ordinal_type info = 0; Teuchos::LAPACK lapack; diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TET_Cn_FEM_ORTH.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TET_Cn_FEM_ORTH.hpp index a38aa41991a2..151b9d21b1e1 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TET_Cn_FEM_ORTH.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TET_Cn_FEM_ORTH.hpp @@ -135,7 +135,8 @@ class Basis_HGRAD_TET_Cn_FEM_ORTH { typename outputValueValueType, class ...outputValueProperties, typename inputPointValueType, class ...inputPointProperties> static void - getValues( Kokkos::DynRankView outputValues, + getValues( const typename DeviceType::execution_space& space, + Kokkos::DynRankView outputValues, const Kokkos::DynRankView inputPoints, const ordinal_type order, const EOperator operatorType ); @@ -217,25 +218,30 @@ class Basis_HGRAD_TET_Cn_FEM_ORTH : public Basis { public: typedef double value_type; - typedef typename Basis::OrdinalTypeArray1DHost OrdinalTypeArray1DHost; - typedef typename Basis::OrdinalTypeArray2DHost OrdinalTypeArray2DHost; - typedef typename Basis::OrdinalTypeArray3DHost OrdinalTypeArray3DHost; + + using BasisBase = Basis; + using typename BasisBase::ExecutionSpace; + + using typename BasisBase::OrdinalTypeArray1DHost; + using typename BasisBase::OrdinalTypeArray2DHost; + using typename BasisBase::OrdinalTypeArray3DHost; + + using typename BasisBase::OutputViewType; + using typename BasisBase::PointViewType ; + using typename BasisBase::ScalarViewType; /** \brief Constructor. */ Basis_HGRAD_TET_Cn_FEM_ORTH( const ordinal_type order ); - - using OutputViewType = typename Basis::OutputViewType; - using PointViewType = typename Basis::PointViewType; - using ScalarViewType = typename Basis::ScalarViewType; - using Basis::getValues; + using BasisBase::getValues; virtual void - getValues( OutputViewType outputValues, - const PointViewType inputPoints, - const EOperator operatorType = OPERATOR_VALUE ) const override { + getValues( const ExecutionSpace& space, + OutputViewType outputValues, + const PointViewType inputPoints, + const EOperator operatorType = OPERATOR_VALUE ) const override { #ifdef HAVE_INTREPID2_DEBUG Intrepid2::getValues_HGRAD_Args(outputValues, inputPoints, @@ -245,10 +251,11 @@ class Basis_HGRAD_TET_Cn_FEM_ORTH #endif constexpr ordinal_type numPtsPerEval = Parameters::MaxNumPtsPerBasisEval; Impl::Basis_HGRAD_TET_Cn_FEM_ORTH:: - getValues( outputValues, - inputPoints, - this->getDegree(), - operatorType ); + getValues(space, + outputValues, + inputPoints, + this->getDegree(), + operatorType); } }; diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TET_Cn_FEM_ORTHDef.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TET_Cn_FEM_ORTHDef.hpp index 2a4eb627eb18..80f4f9e07c84 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TET_Cn_FEM_ORTHDef.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TET_Cn_FEM_ORTHDef.hpp @@ -415,7 +415,9 @@ typename outputValueValueType, class ...outputValueProperties, typename inputPointValueType, class ...inputPointProperties> void Basis_HGRAD_TET_Cn_FEM_ORTH:: -getValues( Kokkos::DynRankView outputValues, +getValues( + const typename DT::execution_space& space, + Kokkos::DynRankView outputValues, const Kokkos::DynRankView inputPoints, const ordinal_type order, const EOperator operatorType ) { @@ -427,7 +429,7 @@ getValues( Kokkos::DynRankView > policy(0, loopSize); + Kokkos::RangePolicy > policy(space, 0, loopSize); typedef typename inputPointViewType::value_type inputPointType; const ordinal_type cardinality = outputValues.extent(0); @@ -445,7 +447,7 @@ getValues( Kokkos::DynRankView FunctorType; Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints, work, order) ); break; diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TRI_Cn_FEMDef.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TRI_Cn_FEMDef.hpp index bd1b6c02bd13..22c586fc5fef 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TRI_Cn_FEMDef.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TRI_Cn_FEMDef.hpp @@ -287,7 +287,11 @@ Basis_HGRAD_TRI_Cn_FEM( const ordinal_type order, work("Hgrad::Tri::Cn::work", lwork), ipiv("Hgrad::Tri::Cn::ipiv", card); - Impl::Basis_HGRAD_TRI_Cn_FEM_ORTH::getValues(vmat, dofCoords, order, OPERATOR_VALUE); + Impl::Basis_HGRAD_TRI_Cn_FEM_ORTH::getValues(typename Kokkos::HostSpace::execution_space{}, + vmat, + dofCoords, + order, + OPERATOR_VALUE); ordinal_type info = 0; Teuchos::LAPACK lapack; diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TRI_Cn_FEM_ORTH.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TRI_Cn_FEM_ORTH.hpp index 03203517e32a..8c1d39e5f5d2 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TRI_Cn_FEM_ORTH.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TRI_Cn_FEM_ORTH.hpp @@ -138,7 +138,8 @@ class Basis_HGRAD_TRI_Cn_FEM_ORTH { typename outputValueValueType, class ...outputValueProperties, typename inputPointValueType, class ...inputPointProperties> static void - getValues( Kokkos::DynRankView outputValues, + getValues( const typename DeviceType::execution_space& space, + Kokkos::DynRankView outputValues, const Kokkos::DynRankView inputPoints, const ordinal_type order, const EOperator operatorType ); @@ -220,25 +221,30 @@ class Basis_HGRAD_TRI_Cn_FEM_ORTH : public Basis { public: typedef double value_type; - typedef typename Basis::OrdinalTypeArray1DHost OrdinalTypeArray1DHost; - typedef typename Basis::OrdinalTypeArray2DHost OrdinalTypeArray2DHost; - typedef typename Basis::OrdinalTypeArray3DHost OrdinalTypeArray3DHost; + + using BasisBase = Basis; + using typename BasisBase::ExecutionSpace; + + using typename BasisBase::OrdinalTypeArray1DHost; + using typename BasisBase::OrdinalTypeArray2DHost; + using typename BasisBase::OrdinalTypeArray3DHost; + + using typename BasisBase::OutputViewType; + using typename BasisBase::PointViewType ; + using typename BasisBase::ScalarViewType; /** \brief Constructor. */ Basis_HGRAD_TRI_Cn_FEM_ORTH( const ordinal_type order ); - using OutputViewType = typename Basis::OutputViewType; - using PointViewType = typename Basis::PointViewType; - using ScalarViewType = typename Basis::ScalarViewType; - - using Basis::getValues; + using BasisBase::getValues; virtual void - getValues( OutputViewType outputValues, - const PointViewType inputPoints, - const EOperator operatorType = OPERATOR_VALUE ) const override { + getValues( const ExecutionSpace& space, + OutputViewType outputValues, + const PointViewType inputPoints, + const EOperator operatorType = OPERATOR_VALUE ) const override { #ifdef HAVE_INTREPID2_DEBUG Intrepid2::getValues_HGRAD_Args(outputValues, inputPoints, @@ -248,10 +254,11 @@ class Basis_HGRAD_TRI_Cn_FEM_ORTH #endif constexpr ordinal_type numPtsPerEval = Parameters::MaxNumPtsPerBasisEval; Impl::Basis_HGRAD_TRI_Cn_FEM_ORTH:: - getValues( outputValues, - inputPoints, - this->getDegree(), - operatorType ); + getValues(space, + outputValues, + inputPoints, + this->getDegree(), + operatorType); } }; diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TRI_Cn_FEM_ORTHDef.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TRI_Cn_FEM_ORTHDef.hpp index 5efa2815aae9..0ce772e7db37 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TRI_Cn_FEM_ORTHDef.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TRI_Cn_FEM_ORTHDef.hpp @@ -335,7 +335,9 @@ typename outputValueValueType, class ...outputValueProperties, typename inputPointValueType, class ...inputPointProperties> void Basis_HGRAD_TRI_Cn_FEM_ORTH:: -getValues( Kokkos::DynRankView outputValues, +getValues( + const typename DT::execution_space& space, + Kokkos::DynRankView outputValues, const Kokkos::DynRankView inputPoints, const ordinal_type order, const EOperator operatorType ) { @@ -347,7 +349,7 @@ getValues( Kokkos::DynRankView > policy(0, loopSize); + Kokkos::RangePolicy > policy(space, 0, loopSize); typedef typename inputPointViewType::value_type inputPointType; const ordinal_type cardinality = outputValues.extent(0); @@ -365,7 +367,7 @@ getValues( Kokkos::DynRankView FunctorType; Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints, work, order) ); break; diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HVOL_LINE_Cn_FEMDef.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HVOL_LINE_Cn_FEMDef.hpp index 5d4252136dbe..a3c577c15275 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HVOL_LINE_Cn_FEMDef.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HVOL_LINE_Cn_FEMDef.hpp @@ -254,7 +254,7 @@ namespace Intrepid2 { const double alpha = 0.0, beta = 0.0; Impl::Basis_HGRAD_LINE_Cn_FEM_JACOBI:: getValues - (vmat, dofCoords, order, alpha, beta, OPERATOR_VALUE); + (typename Kokkos::HostSpace::execution_space{}, vmat, dofCoords, order, alpha, beta, OPERATOR_VALUE); ordinal_type info = 0; Teuchos::LAPACK lapack; diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HVOL_TET_Cn_FEMDef.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HVOL_TET_Cn_FEMDef.hpp index 3da254f516ce..e600120a66a8 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HVOL_TET_Cn_FEMDef.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HVOL_TET_Cn_FEMDef.hpp @@ -53,7 +53,7 @@ namespace Intrepid2 { // ------------------------------------------------------------------------------------- - + namespace Impl { template @@ -70,7 +70,7 @@ namespace Intrepid2 { const vinvViewType vinv ) { constexpr ordinal_type spaceDim = 3; - const ordinal_type + const ordinal_type card = vinv.extent(0), npts = input.extent(0); @@ -82,7 +82,7 @@ namespace Intrepid2 { break; } } - + typedef typename Kokkos::DynRankView viewType; auto vcprop = Kokkos::common_view_alloc_prop(work); auto ptr = work.data(); @@ -91,10 +91,10 @@ namespace Intrepid2 { case OPERATOR_VALUE: { const viewType phis(Kokkos::view_wrap(ptr, vcprop), card, npts); workViewType dummyView; - + Impl::Basis_HGRAD_TET_Cn_FEM_ORTH:: Serial::getValues(phis, input, dummyView, order); - + for (ordinal_type i=0;i inputPointViewType; typedef Kokkos::DynRankView vinvViewType; typedef typename ExecSpace::ExecSpaceType ExecSpaceType; - + // loopSize corresponds to cardinality const auto loopSizeTmp1 = (inputPoints.extent(0)/numPtsPerEval); const auto loopSizeTmp2 = (inputPoints.extent(0)%numPtsPerEval != 0); @@ -194,7 +194,7 @@ namespace Intrepid2 { break; } case OPERATOR_GRAD: - case OPERATOR_D1: { + case OPERATOR_D1: { auto bufferSize = Basis_HVOL_TET_Cn_FEM::Serial::getWorkSizePerPoint(order); workViewType work(Kokkos::view_alloc("Basis_HVOL_TET_Cn_FEM::getValues::work", vcprop), bufferSize, inputPoints.extent(0)); typedef Functor Basis_HVOL_TET_Cn_FEM:: @@ -245,14 +245,14 @@ namespace Intrepid2 { // points are computed in the host and will be copied Kokkos::DynRankView dofCoords("HVOL::Tet::Cn::dofCoords", card, spaceDim); - + // construct lattice (only internal nodes for HVOL element) const ordinal_type offset = 1; PointTools::getLattice( dofCoords, this->basisCellTopology_, order+spaceDim+offset, offset, pointType ); - + this->dofCoords_ = Kokkos::create_mirror_view(typename DT::memory_space(), dofCoords); Kokkos::deep_copy(this->dofCoords_, dofCoords); @@ -263,12 +263,16 @@ namespace Intrepid2 { vmat("HVOL::Tet::Cn::vmat", card, card), work("HVOL::Tet::Cn::work", lwork), ipiv("HVOL::Tet::Cn::ipiv", card); - - Impl::Basis_HGRAD_TET_Cn_FEM_ORTH::getValues(vmat, dofCoords, order, OPERATOR_VALUE); + + Impl::Basis_HGRAD_TET_Cn_FEM_ORTH::getValues(typename Kokkos::HostSpace::execution_space{}, + vmat, + dofCoords, + order, + OPERATOR_VALUE); ordinal_type info = 0; Teuchos::LAPACK lapack; - + lapack.GETRF(card, card, vmat.data(), vmat.stride_1(), (ordinal_type*)ipiv.data(), @@ -303,14 +307,14 @@ namespace Intrepid2 { { // Basis-dependent initializations constexpr ordinal_type tagSize = 4; // size of DoF tag, i.e., number of fields in the tag - const ordinal_type posScDim = 0; // position in the tag, counting from 0, of the subcell dim + const ordinal_type posScDim = 0; // position in the tag, counting from 0, of the subcell dim const ordinal_type posScOrd = 1; // position in the tag, counting from 0, of the subcell ordinal const ordinal_type posDfOrd = 2; // position in the tag, counting from 0, of DoF ordinal relative to the subcell - + constexpr ordinal_type maxCard = Intrepid2::getPnCardinality(); ordinal_type tags[maxCard][tagSize]; - const ordinal_type + const ordinal_type numElemDof = this->basisCardinality_; //all the degrees of freedom are internal. @@ -324,7 +328,7 @@ namespace Intrepid2 { } OrdinalTypeArray1DHost tagView(&tags[0][0], card*tagSize); - + // Basis-independent function sets tag and enum data in tagToOrdinal_ and ordinalToTag_ arrays: // tags are constructed on host this->setOrdinalTagData(this->tagToOrdinal_, diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HVOL_TRI_Cn_FEMDef.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HVOL_TRI_Cn_FEMDef.hpp index 2eeafbf959c3..4b72e8b92dce 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HVOL_TRI_Cn_FEMDef.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HVOL_TRI_Cn_FEMDef.hpp @@ -258,7 +258,11 @@ Basis_HVOL_TRI_Cn_FEM( const ordinal_type order, work("HVOL::Tri::Cn::work", lwork), ipiv("HVOL::Tri::Cn::ipiv", card); - Impl::Basis_HGRAD_TRI_Cn_FEM_ORTH::getValues(vmat, dofCoords, order, OPERATOR_VALUE); + Impl::Basis_HGRAD_TRI_Cn_FEM_ORTH::getValues(typename Kokkos::HostSpace::execution_space{}, + vmat, + dofCoords, + order, + OPERATOR_VALUE); ordinal_type info = 0; Teuchos::LAPACK lapack; diff --git a/packages/intrepid2/unit-test/Discretization/Basis/HCURL_TET_I1_FEM/test_01.hpp b/packages/intrepid2/unit-test/Discretization/Basis/HCURL_TET_I1_FEM/test_01.hpp index 2283058e3c59..a29276ae4d28 100644 --- a/packages/intrepid2/unit-test/Discretization/Basis/HCURL_TET_I1_FEM/test_01.hpp +++ b/packages/intrepid2/unit-test/Discretization/Basis/HCURL_TET_I1_FEM/test_01.hpp @@ -58,49 +58,29 @@ #include "Teuchos_RCP.hpp" #include "packages/intrepid2/unit-test/Discretization/Basis/Macros.hpp" +#include "packages/intrepid2/unit-test/Discretization/Basis/Setup.hpp" namespace Intrepid2 { namespace Test { + using HostSpaceType = Kokkos::DefaultHostExecutionSpace; + template int HCURL_TET_I1_FEM_Test01(const bool verbose) { - - Teuchos::RCP outStream; - Teuchos::oblackholestream bhs; // outputs nothing - - if (verbose) - outStream = Teuchos::rcp(&std::cout, false); - else - outStream = Teuchos::rcp(&bhs, false); - - Teuchos::oblackholestream oldFormatState; - oldFormatState.copyfmt(std::cout); - using DeviceSpaceType = typename DeviceType::execution_space; - typedef typename - Kokkos::DefaultHostExecutionSpace HostSpaceType ; - - *outStream << "DeviceSpace:: "; DeviceSpaceType().print_configuration(*outStream, false); - *outStream << "HostSpace:: "; HostSpaceType().print_configuration(*outStream, false); + //! Create an execution space instance. + const auto space = Kokkos::Experimental::partition_space(typename DeviceType::execution_space {}, 1)[0]; - *outStream - << "===============================================================================\n" - << "| |\n" - << "| Unit Test (Basis_HCURL_TET_I1_FEM) |\n" - << "| |\n" - << "| 1) Conversion of Dof tags into Dof ordinals and back |\n" - << "| 2) Basis values for VALUE and CURL operators |\n" - << "| |\n" - << "| Questions? Contact Pavel Bochev (pbboche@sandia.gov) or |\n" - << "| Denis Ridzal (dridzal@sandia.gov). |\n" - << "| Kara Peterson (kjpeter@sandia.gov). |\n" - << "| Kyungjoo Kim (kyukim@sandia.gov). |\n" - << "| |\n" - << "| Intrepid's website: http://trilinos.sandia.gov/packages/intrepid |\n" - << "| Trilinos website: http://trilinos.sandia.gov |\n" - << "| |\n" - << "===============================================================================\n"; + //! Setup test output stream. + Teuchos::RCP outStream = setup_output_stream( + verbose, "Basis_HCURL_TET_I1_FEM", { + "1) Conversion of Dof tags into Dof ordinals and back", + "2) Basis values for VALUE and CURL operators" + }); + + Teuchos::oblackholestream oldFormatState; + oldFormatState.copyfmt(std::cout); typedef Kokkos::DynRankView DynRankView; typedef Kokkos::DynRankView DynRankViewHost; @@ -122,7 +102,7 @@ namespace Intrepid2 { try{ ordinal_type nthrow = 0, ncatch = 0; -#ifdef HAVE_INTREPID2_DEBUG +#ifdef HAVE_INTREPID2_DEBUG DynRankView ConstructWithLabel( tetNodes, 10, 3 ); @@ -134,7 +114,7 @@ namespace Intrepid2 { vals = DynRankView("vals", cardinality, numPoints); { - // exception #1: GRAD cannot be applied to HCURL functions + // exception #1: GRAD cannot be applied to HCURL functions // resize vals to rank-3 container with dimensions (num. basis functions, num. points, arbitrary) INTREPID2_TEST_ERROR_EXPECTED( tetBasis.getValues(vals, tetNodes, OPERATOR_GRAD) ); } @@ -143,8 +123,8 @@ namespace Intrepid2 { // resize vals to rank-2 container with dimensions (num. basis functions, num. points) INTREPID2_TEST_ERROR_EXPECTED( tetBasis.getValues(vals, tetNodes, OPERATOR_DIV) ); } - { - // Exceptions 3-7: all bf tags/bf Ids below are wrong and should cause getDofOrdinal() and + { + // Exceptions 3-7: all bf tags/bf Ids below are wrong and should cause getDofOrdinal() and // getDofTag() to access invalid array elements thereby causing bounds check exception // exception #3 INTREPID2_TEST_ERROR_EXPECTED( tetBasis.getDofOrdinal(3,0,0) ); @@ -175,12 +155,12 @@ namespace Intrepid2 { // exception #11 output values must be of rank-3 for OPERATOR_CURL INTREPID2_TEST_ERROR_EXPECTED( tetBasis.getValues(badVals1,tetNodes,OPERATOR_CURL) ); } - { + { // exception #12 incorrect 0th dimension of output array (must equal number of basis functions) DynRankView ConstructWithLabel(badVals2, cardinality+1, numPoints, 3); INTREPID2_TEST_ERROR_EXPECTED( tetBasis.getValues(badVals2,tetNodes,OPERATOR_VALUE) ); } - { + { // exception #13 incorrect 1st dimension of output array (must equal number of points) DynRankView ConstructWithLabel(badVals3, cardinality, numPoints+1, 3); INTREPID2_TEST_ERROR_EXPECTED( tetBasis.getValues(badVals3,tetNodes,OPERATOR_VALUE) ); @@ -205,22 +185,22 @@ namespace Intrepid2 { *outStream << "-------------------------------------------------------------------------------" << "\n\n"; errorFlag = -1000; }; - + *outStream << "\n" << "===============================================================================\n" << "| TEST 2: correctness of tag to enum and enum to tag lookups |\n" << "===============================================================================\n"; - + // all tags are on host space try{ const auto allTags = tetBasis.getAllDofTags(); - + // Loop over all tags, lookup the associated dof enumeration and then lookup the tag again const ordinal_type dofTagSize = allTags.extent(0); for (ordinal_type i = 0; i < dofTagSize; ++i) { auto bfOrd = tetBasis.getDofOrdinal(allTags(i,0), allTags(i,1), allTags(i,2)); - + const auto myTag = tetBasis.getDofTag(bfOrd); if( !( (myTag(0) == allTags(i,0)) && (myTag(1) == allTags(i,1)) && @@ -228,19 +208,19 @@ namespace Intrepid2 { (myTag(3) == allTags(i,3)) ) ) { errorFlag++; *outStream << std::setw(70) << "^^^^----FAILURE!" << "\n"; - *outStream << " getDofOrdinal( {" - << allTags(i,0) << ", " - << allTags(i,1) << ", " - << allTags(i,2) << ", " - << allTags(i,3) << "}) = " << bfOrd <<" but \n"; + *outStream << " getDofOrdinal( {" + << allTags(i,0) << ", " + << allTags(i,1) << ", " + << allTags(i,2) << ", " + << allTags(i,3) << "}) = " << bfOrd <<" but \n"; *outStream << " getDofTag(" << bfOrd << ") = { " - << myTag(0) << ", " - << myTag(1) << ", " - << myTag(2) << ", " - << myTag(3) << "}\n"; + << myTag(0) << ", " + << myTag(1) << ", " + << myTag(2) << ", " + << myTag(3) << "}\n"; } } - + // Now do the same but loop over basis functions for( ordinal_type bfOrd = 0; bfOrd < tetBasis.getCardinality(); bfOrd++) { const auto myTag = tetBasis.getDofTag(bfOrd); @@ -249,13 +229,13 @@ namespace Intrepid2 { errorFlag++; *outStream << std::setw(70) << "^^^^----FAILURE!" << "\n"; *outStream << " getDofTag(" << bfOrd << ") = { " - << myTag(0) << ", " - << myTag(1) << ", " - << myTag(2) << ", " - << myTag(3) << "} but getDofOrdinal({" - << myTag(0) << ", " - << myTag(1) << ", " - << myTag(2) << ", " + << myTag(0) << ", " + << myTag(1) << ", " + << myTag(2) << ", " + << myTag(3) << "} but getDofOrdinal({" + << myTag(0) << ", " + << myTag(1) << ", " + << myTag(2) << ", " << myTag(3) << "} ) = " << myBfOrd << "\n"; } } @@ -264,15 +244,15 @@ namespace Intrepid2 { *outStream << err.what() << "\n\n"; errorFlag = -1000; }; - + *outStream << "\n" << "===============================================================================\n" << "| TEST 3: correctness of basis function values |\n" << "===============================================================================\n"; - + outStream -> precision(20); - + // VALUE: Each row pair gives the 6x3 correct basis set values at an evaluation point: (P,F,D) layout const ValueType basisValues[] = { // 4 vertices @@ -297,7 +277,7 @@ namespace Intrepid2 { 1.0,0.,0., -1.0,0.,0., -1.0,-2.0,-1.0, 0.,0.,1.0, 0.,0.,0., 0.,0.,1.0, - + 1.0,0.,0., 0.,0.,0., 0.,-1.0,0., 1.0,1.0,2.0, -1.0,0.,0., 0.,-1.0,0., @@ -307,9 +287,9 @@ namespace Intrepid2 { 0.,0.,0., -1.0,0.,0., -1.0,-1.0,-1.0, 1.0,1.0,1.0, -1.0,0.,0., 0.,-1.0,1.0 }; - + // CURL: each row pair gives the 3x12 correct values of the curls of the 12 basis functions: (P,F,D) layout - const ValueType basisCurls[] = { + const ValueType basisCurls[] = { // 4 vertices 0.,-4.0,4.0, 0.,0.,4.0, -4.0,0.,4.0, -4.0,4.0,0., 0.,-4.0,0., 4.0,0.,0., @@ -342,7 +322,7 @@ namespace Intrepid2 { 0.,-4.0,4.0, 0.,0.,4.0, -4.0,0.,4.0, -4.0,4.0,0., 0.,-4.0,0., 4.0,0.,0., }; - + try{ // Define array containing the 4 vertices of the reference TET and its 6 edge centers. DynRankViewHost ConstructWithLabel(tetNodesHost, 10, 3); @@ -360,22 +340,22 @@ namespace Intrepid2 { auto tetNodes = Kokkos::create_mirror_view(typename DeviceType::memory_space(), tetNodesHost); Kokkos::deep_copy(tetNodes, tetNodesHost); - + // Dimensions for the output arrays: const ordinal_type cardinality = tetBasis.getCardinality(); const ordinal_type numPoints = tetNodes.extent(0); const ordinal_type spaceDim = tetBasis.getBaseCellTopology().getDimension(); - - { + + { // Check VALUE of basis functions: resize vals to rank-3 container: DynRankView ConstructWithLabel(vals, cardinality, numPoints, spaceDim); - tetBasis.getValues(vals, tetNodes, OPERATOR_VALUE); + tetBasis.getValues(space, vals, tetNodes, OPERATOR_VALUE); auto vals_host = Kokkos::create_mirror_view(typename HostSpaceType::memory_space(), vals); Kokkos::deep_copy(vals_host, vals); for (ordinal_type i = 0; i < cardinality; ++i) { for (ordinal_type j = 0; j < numPoints; ++j) { for (ordinal_type k = 0; k < spaceDim; ++k) { - + // compute offset for (P,F,D) data layout: indices are P->j, F->i, D->k const ordinal_type l = k + i * spaceDim + j * spaceDim * cardinality; if (std::abs(vals_host(i,j,k) - basisValues[l]) > tol ) { @@ -392,16 +372,16 @@ namespace Intrepid2 { } } } - { + { // Check CURL of basis function: resize vals to rank-3 container DynRankView ConstructWithLabel(vals, cardinality, numPoints, spaceDim); - tetBasis.getValues(vals, tetNodes, OPERATOR_CURL); + tetBasis.getValues(space, vals, tetNodes, OPERATOR_CURL); auto vals_host = Kokkos::create_mirror_view(typename HostSpaceType::memory_space(), vals); Kokkos::deep_copy(vals_host, vals); for (ordinal_type i = 0; i < cardinality; ++i) { for (ordinal_type j = 0; j < numPoints; ++j) { for (ordinal_type k = 0; k < spaceDim; ++k) { - + // compute offset for (P,F,D) data layout: indices are P->j, F->i, D->k const ordinal_type l = k + i * spaceDim + j * spaceDim * cardinality; if (std::abs(vals_host(i,j,k) - basisCurls[l]) > tol ) { @@ -419,14 +399,14 @@ namespace Intrepid2 { } } - } - + } + // Catch unexpected errors catch (std::logic_error &err) { *outStream << err.what() << "\n\n"; errorFlag = -1000; }; - + *outStream << "\n" << "===============================================================================\n" @@ -466,7 +446,7 @@ namespace Intrepid2 { DynRankView ConstructWithLabel(dofCoeffs, cardinality, spaceDim); tetBasis.getDofCoords(cvals); tetBasis.getDofCoeffs(dofCoeffs); - tetBasis.getValues(bvals, cvals, OPERATOR_VALUE); + tetBasis.getValues(space, bvals, cvals, OPERATOR_VALUE); auto cvals_host = Kokkos::create_mirror_view(typename HostSpaceType::memory_space(), cvals); Kokkos::deep_copy(cvals_host, cvals); @@ -507,14 +487,14 @@ namespace Intrepid2 { << "===============================================================================\n" << "| TEST 5: Function Space is Correct |\n" << "===============================================================================\n"; - + try { const EFunctionSpace fs = tetBasis.getFunctionSpace(); - + if (fs != FUNCTION_SPACE_HCURL) { *outStream << std::setw(70) << "------------- TEST FAILURE! -------------" << "\n"; - + // Output the multi-index of the value where the error is: *outStream << " Expected a function space of FUNCTION_SPACE_HCURL (enum value " << FUNCTION_SPACE_HCURL << "),"; *outStream << " but got " << fs << "\n"; @@ -530,12 +510,12 @@ namespace Intrepid2 { *outStream << "-------------------------------------------------------------------------------" << "\n\n"; errorFlag = -1000; } - + if (errorFlag != 0) std::cout << "End Result: TEST FAILED\n"; else std::cout << "End Result: TEST PASSED\n"; - + // reset format state of std::cout std::cout.copyfmt(oldFormatState); return errorFlag; diff --git a/packages/intrepid2/unit-test/Discretization/Basis/HCURL_TET_In_FEM/test_01.hpp b/packages/intrepid2/unit-test/Discretization/Basis/HCURL_TET_In_FEM/test_01.hpp index f5dbb7b89415..e29545e8e25f 100644 --- a/packages/intrepid2/unit-test/Discretization/Basis/HCURL_TET_In_FEM/test_01.hpp +++ b/packages/intrepid2/unit-test/Discretization/Basis/HCURL_TET_In_FEM/test_01.hpp @@ -63,46 +63,28 @@ #include "Teuchos_RCP.hpp" #include "packages/intrepid2/unit-test/Discretization/Basis/Macros.hpp" +#include "packages/intrepid2/unit-test/Discretization/Basis/Setup.hpp" namespace Intrepid2 { namespace Test { +using HostSpaceType = Kokkos::DefaultHostExecutionSpace; + template int HCURL_TET_In_FEM_Test01(const bool verbose) { - Teuchos::RCP outStream; - Teuchos::oblackholestream bhs; // outputs nothing + //! Create an execution space instance. + const auto space = Kokkos::Experimental::partition_space(typename DeviceType::execution_space {}, 1)[0]; - if (verbose) - outStream = Teuchos::rcp(&std::cout, false); - else - outStream = Teuchos::rcp(&bhs, false); + //! Setup test output stream. + Teuchos::RCP outStream = setup_output_stream( + verbose, "HCURL_TET_In_FEM", { + }); Teuchos::oblackholestream oldFormatState; oldFormatState.copyfmt(std::cout); - using DeviceSpaceType = typename DeviceType::execution_space; - typedef typename - Kokkos::DefaultHostExecutionSpace HostSpaceType ; - - *outStream << "DeviceSpace:: "; DeviceSpaceType().print_configuration(*outStream, false); - *outStream << "HostSpace:: "; HostSpaceType().print_configuration(*outStream, false); - - *outStream - << "===============================================================================\n" - << "| |\n" - << "| Unit Test HCURL_TET_In_FEM |\n" - << "| |\n" - << "| Questions? Contact Pavel Bochev (pbboche@sandia.gov), |\n" - << "| Robert Kirby (robert.c.kirby@ttu.edu), |\n" - << "| Denis Ridzal (dridzal@sandia.gov), |\n" - << "| Kara Peterson (kjpeter@sandia.gov), |\n" - << "| Kyungjoo Kim (kyukim@sandia.gov), |\n" - << "| Mauro Perego (mperego@sandia.gov). |\n" - << "| |\n" - << "===============================================================================\n"; - typedef Kokkos::DynRankView DynRankViewPointValueType; typedef Kokkos::DynRankView DynRankViewOutValueType; typedef typename ScalarTraits::scalar_type scalar_type; @@ -144,7 +126,7 @@ int HCURL_TET_In_FEM_Test01(const bool verbose) { tetBasis.getDofCoeffs(dofCoeffs); DynRankViewOutValueType ConstructWithLabelOutView(basisAtDofCoords, cardinality , cardinality, dim); - tetBasis.getValues(basisAtDofCoords, dofCoords, OPERATOR_VALUE); + tetBasis.getValues(space, basisAtDofCoords, dofCoords, OPERATOR_VALUE); auto h_basisAtDofCoords = Kokkos::create_mirror_view(basisAtDofCoords); Kokkos::deep_copy(h_basisAtDofCoords, basisAtDofCoords); @@ -191,7 +173,7 @@ int HCURL_TET_In_FEM_Test01(const bool verbose) { const ordinal_type order = std::min(3, maxOrder); TetBasisType tetBasis(order, POINTTYPE_WARPBLEND); shards::CellTopology tet_4(shards::getCellTopologyData >()); - + const ordinal_type cardinality = tetBasis.getCardinality(); DynRankViewScalarValueType ConstructWithLabel(dofCoords_scalar, cardinality , dim); @@ -201,7 +183,7 @@ int HCURL_TET_In_FEM_Test01(const bool verbose) { RealSpaceTools::clone(dofCoords, dofCoords_scalar); DynRankViewOutValueType ConstructWithLabelOutView(basisAtDofCoords, cardinality , cardinality, dim); - tetBasis.getValues(basisAtDofCoords, dofCoords, OPERATOR_VALUE); + tetBasis.getValues(space, basisAtDofCoords, dofCoords, OPERATOR_VALUE); auto h_basisAtDofCoords = Kokkos::create_mirror_view(basisAtDofCoords); Kokkos::deep_copy(h_basisAtDofCoords, basisAtDofCoords); @@ -301,7 +283,7 @@ int HCURL_TET_In_FEM_Test01(const bool verbose) { RealSpaceTools::clone(lattice,lattice_scalar); DynRankViewOutValueType ConstructWithLabelOutView(basisAtLattice, cardinality , np_lattice, dim); - tetBasis.getValues(basisAtLattice, lattice, OPERATOR_VALUE); + tetBasis.getValues(space, basisAtLattice, lattice, OPERATOR_VALUE); auto h_basisAtLattice = Kokkos::create_mirror_view(basisAtLattice); Kokkos::deep_copy(h_basisAtLattice, basisAtLattice); @@ -380,14 +362,14 @@ int HCURL_TET_In_FEM_Test01(const bool verbose) { shards::CellTopology tet_4(shards::getCellTopologyData >()); const ordinal_type np_lattice = PointTools::getLatticeSize(tet_4, order,0); const ordinal_type cardinality = tetBasis.getCardinality(); - + DynRankViewScalarValueType ConstructWithLabel(lattice_scalar, np_lattice , dim); PointTools::getLattice(lattice_scalar, tet_4, order, 0, POINTTYPE_EQUISPACED); DynRankViewPointValueType ConstructWithLabelPointView(lattice, np_lattice , dim); RealSpaceTools::clone(lattice,lattice_scalar); DynRankViewOutValueType ConstructWithLabelOutView(curlBasisAtLattice, cardinality , np_lattice, dim); - tetBasis.getValues(curlBasisAtLattice, lattice, OPERATOR_CURL); + tetBasis.getValues(space, curlBasisAtLattice, lattice, OPERATOR_CURL); auto h_curlBasisAtLattice = Kokkos::create_mirror_view(curlBasisAtLattice); Kokkos::deep_copy(h_curlBasisAtLattice, curlBasisAtLattice); @@ -449,23 +431,23 @@ int HCURL_TET_In_FEM_Test01(const bool verbose) { *outStream << "-------------------------------------------------------------------------------" << "\n\n"; errorFlag = -1000; }; - + *outStream << "\n" << "===============================================================================\n" << "| TEST 5: Function Space is Correct |\n" << "===============================================================================\n"; - + try { const ordinal_type order = std::min(3, maxOrder); TetBasisType tetBasis(order, POINTTYPE_WARPBLEND); - + const EFunctionSpace fs = tetBasis.getFunctionSpace(); - + if (fs != FUNCTION_SPACE_HCURL) { *outStream << std::setw(70) << "------------- TEST FAILURE! -------------" << "\n"; - + // Output the multi-index of the value where the error is: *outStream << " Expected a function space of FUNCTION_SPACE_HCURL (enum value " << FUNCTION_SPACE_HCURL << "),"; *outStream << " but got " << fs << "\n"; diff --git a/packages/intrepid2/unit-test/Discretization/Basis/HCURL_TRI_I1_FEM/test_01.hpp b/packages/intrepid2/unit-test/Discretization/Basis/HCURL_TRI_I1_FEM/test_01.hpp index 72536fd95736..379089a599b1 100644 --- a/packages/intrepid2/unit-test/Discretization/Basis/HCURL_TRI_I1_FEM/test_01.hpp +++ b/packages/intrepid2/unit-test/Discretization/Basis/HCURL_TRI_I1_FEM/test_01.hpp @@ -59,48 +59,29 @@ #include "Teuchos_RCP.hpp" #include "packages/intrepid2/unit-test/Discretization/Basis/Macros.hpp" +#include "packages/intrepid2/unit-test/Discretization/Basis/Setup.hpp" namespace Intrepid2 { namespace Test { + using HostSpaceType = Kokkos::DefaultHostExecutionSpace; + template int HCURL_TRI_I1_FEM_Test01(const bool verbose) { - - Teuchos::RCP outStream; - Teuchos::oblackholestream bhs; // outputs nothing - - if (verbose) - outStream = Teuchos::rcp(&std::cout, false); - else - outStream = Teuchos::rcp(&bhs, false); - + + //! Create an execution space instance. + const auto space = Kokkos::Experimental::partition_space(typename DeviceType::execution_space {}, 1)[0]; + + //! Setup test output stream. + Teuchos::RCP outStream = setup_output_stream( + verbose, "Basis_HCURL_TRI_I1_FEM", { + "1) Conversion of Dof tags into Dof ordinals and back", + "2) Basis values for VALUE and CURL operators" + }); + Teuchos::oblackholestream oldFormatState; oldFormatState.copyfmt(std::cout); - using DeviceSpaceType = typename DeviceType::execution_space; - typedef typename - Kokkos::DefaultHostExecutionSpace HostSpaceType ; - - *outStream << "DeviceSpace:: "; DeviceSpaceType().print_configuration(*outStream, false); - *outStream << "HostSpace:: "; HostSpaceType().print_configuration(*outStream, false); - - *outStream - << "===============================================================================\n" - << "| |\n" - << "| Unit Test (Basis_HCURL_TRI_I1_FEM) |\n" - << "| |\n" - << "| 1) Conversion of Dof tags into Dof ordinals and back |\n" - << "| 2) Basis values for VALUE and CURL operators |\n" - << "| |\n" - << "| Questions? Contact Pavel Bochev (pbboche@sandia.gov), |\n" - << "| Denis Ridzal (dridzal@sandia.gov), |\n" - << "| Kara Peterson (kjpeter@sandia.gov). |\n" - << "| Kyungjoo Kim (kyukim@sandia.gov). |\n" - << "| |\n" - << "| Intrepid's website: http://trilinos.sandia.gov/packages/intrepid |\n" - << "| Trilinos website: http://trilinos.sandia.gov |\n" - << "| |\n" - << "===============================================================================\n"; typedef Kokkos::DynRankView DynRankView; typedef Kokkos::DynRankView DynRankViewHost; @@ -135,14 +116,14 @@ namespace Intrepid2 { vals = DynRankView("vals", cardinality, numPoints); { - // exception #1: GRAD cannot be applied to HCURL functions + // exception #1: GRAD cannot be applied to HCURL functions INTREPID2_TEST_ERROR_EXPECTED( triBasis.getValues(vals, triNodes, OPERATOR_GRAD) ); } { // exception #2: DIV cannot be applied to HCURL functions INTREPID2_TEST_ERROR_EXPECTED( triBasis.getValues(vals, triNodes, OPERATOR_DIV) ); } - // Exceptions 3-7: all bf tags/bf Ids below are wrong and should cause getDofOrdinal() and + // Exceptions 3-7: all bf tags/bf Ids below are wrong and should cause getDofOrdinal() and // getDofTag() to access invalid array elements thereby causing bounds check exception { // exception #3 @@ -165,17 +146,17 @@ namespace Intrepid2 { // exception #9 dimension 1 in the input point array must equal space dimension of the cell { DynRankView ConstructWithLabel(badPoints2, 4, triBasis.getBaseCellTopology().getDimension() + 1); - INTREPID2_TEST_ERROR_EXPECTED( triBasis.getValues(vals, badPoints2, OPERATOR_VALUE) ); + INTREPID2_TEST_ERROR_EXPECTED( triBasis.getValues(vals, badPoints2, OPERATOR_VALUE) ); } { // exception #10 output values must be of rank-3 for OPERATOR_VALUE in 2D DynRankView ConstructWithLabel(badVals1, 4, 3); - INTREPID2_TEST_ERROR_EXPECTED( triBasis.getValues(badVals1, triNodes, OPERATOR_VALUE) ); + INTREPID2_TEST_ERROR_EXPECTED( triBasis.getValues(badVals1, triNodes, OPERATOR_VALUE) ); } { // exception #11 output values must be of rank-2 for OPERATOR_CURL DynRankView ConstructWithLabel(badCurls1,4,3,2); - INTREPID2_TEST_ERROR_EXPECTED( triBasis.getValues(badCurls1, triNodes, OPERATOR_CURL) ); + INTREPID2_TEST_ERROR_EXPECTED( triBasis.getValues(badCurls1, triNodes, OPERATOR_CURL) ); } { // exception #12 incorrect 0th dimension of output array (must equal number of basis functions) @@ -191,13 +172,13 @@ namespace Intrepid2 { // exception #14: incorrect 2nd dimension of output array for VALUE (must equal the space dimension) DynRankView ConstructWithLabel(badVals4, triBasis.getCardinality(), triNodes.extent(0), triBasis.getBaseCellTopology().getDimension() - 1); INTREPID2_TEST_ERROR_EXPECTED( triBasis.getValues(badVals4, triNodes, OPERATOR_VALUE) ) ; - } - // exception #15: D2 cannot be applied to HCURL functions + } + // exception #15: D2 cannot be applied to HCURL functions // resize vals to rank-3 container with dimensions (num. basis functions, num. points, arbitrary) -// vals.resize(triBasis.getCardinality(), -// triNodes.extent(0), +// vals.resize(triBasis.getCardinality(), +// triNodes.extent(0), // Intrepid2::getDkCardinality(OPERATOR_D2, triBasis.getBaseCellTopology().getDimension())); -// INTREPID2_TEST_ERROR_EXPECTED( triBasis.getValues(vals, triNodes, OPERATOR_D2) ); +// INTREPID2_TEST_ERROR_EXPECTED( triBasis.getValues(vals, triNodes, OPERATOR_D2) ); #endif // Check if number of thrown exceptions matches the one we expect if (nthrow != ncatch) { @@ -211,22 +192,22 @@ namespace Intrepid2 { *outStream << "-------------------------------------------------------------------------------" << "\n\n"; errorFlag = -1000; } - + *outStream << "\n" << "===============================================================================\n" << "| TEST 2: correctness of tag to enum and enum to tag lookups |\n" << "===============================================================================\n"; - + // all tags are on host space try{ const auto allTags = triBasis.getAllDofTags(); - + // Loop over all tags, lookup the associated dof enumeration and then lookup the tag again const ordinal_type dofTagSize = allTags.extent(0); for (ordinal_type i = 0; i < dofTagSize; ++i) { const auto bfOrd = triBasis.getDofOrdinal(allTags(i,0), allTags(i,1), allTags(i,2)); - + const auto myTag = triBasis.getDofTag(bfOrd); if( !( (myTag(0) == allTags(i,0)) && (myTag(1) == allTags(i,1)) && @@ -234,19 +215,19 @@ namespace Intrepid2 { (myTag(3) == allTags(i,3)) ) ) { errorFlag++; *outStream << std::setw(70) << "^^^^----FAILURE!" << "\n"; - *outStream << " getDofOrdinal( {" - << allTags(i,0) << ", " - << allTags(i,1) << ", " - << allTags(i,2) << ", " - << allTags(i,3) << "}) = " << bfOrd <<" but \n"; + *outStream << " getDofOrdinal( {" + << allTags(i,0) << ", " + << allTags(i,1) << ", " + << allTags(i,2) << ", " + << allTags(i,3) << "}) = " << bfOrd <<" but \n"; *outStream << " getDofTag(" << bfOrd << ") = { " - << myTag(0) << ", " - << myTag(1) << ", " - << myTag(2) << ", " - << myTag(3) << "}\n"; + << myTag(0) << ", " + << myTag(1) << ", " + << myTag(2) << ", " + << myTag(3) << "}\n"; } } - + // Now do the same but loop over basis functions for( ordinal_type bfOrd = 0; bfOrd < triBasis.getCardinality(); bfOrd++) { const auto myTag = triBasis.getDofTag(bfOrd); @@ -255,13 +236,13 @@ namespace Intrepid2 { errorFlag++; *outStream << std::setw(70) << "^^^^----FAILURE!" << "\n"; *outStream << " getDofTag(" << bfOrd << ") = { " - << myTag(0) << ", " - << myTag(1) << ", " - << myTag(2) << ", " - << myTag(3) << "} but getDofOrdinal({" - << myTag(0) << ", " - << myTag(1) << ", " - << myTag(2) << ", " + << myTag(0) << ", " + << myTag(1) << ", " + << myTag(2) << ", " + << myTag(3) << "} but getDofOrdinal({" + << myTag(0) << ", " + << myTag(1) << ", " + << myTag(2) << ", " << myTag(3) << "} ) = " << myBfOrd << "\n"; } } @@ -270,15 +251,15 @@ namespace Intrepid2 { *outStream << err.what() << "\n\n"; errorFlag = -1000; }; - + *outStream << "\n" << "===============================================================================\n" << "| TEST 3: correctness of basis function values |\n" << "===============================================================================\n"; - + outStream -> precision(20); - + // VALUE: correct values in (P,F,D) layout const ValueType basisValues[] = { 2.0, 0, 0, 0, 0, -2.0, 2.0, 2.0, 0, 2.0, 0, 0, 0, 0, \ @@ -286,9 +267,9 @@ namespace Intrepid2 { 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 0, \ -1.0, 0, -1.0, -2.0, 1.5, 0.5, -0.5, 0.5, \ -0.5, -1.5}; - + // CURL: correct values in (P,F) layout - const ValueType basisCurls[] = { + const ValueType basisCurls[] = { 4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0, @@ -297,18 +278,18 @@ namespace Intrepid2 { 4.0, 4.0, 4.0, 4.0, 4.0, 4.0 }; - + try{ DynRankViewHost ConstructWithLabel(triNodesHost, 7, 2); - triNodesHost(0,0) = 0.0; triNodesHost(0,1) = 0.0; - triNodesHost(1,0) = 1.0; triNodesHost(1,1) = 0.0; - triNodesHost(2,0) = 0.0; triNodesHost(2,1) = 1.0; + triNodesHost(0,0) = 0.0; triNodesHost(0,1) = 0.0; + triNodesHost(1,0) = 1.0; triNodesHost(1,1) = 0.0; + triNodesHost(2,0) = 0.0; triNodesHost(2,1) = 1.0; // edge midpoints - triNodesHost(3,0) = 0.5; triNodesHost(3,1) = 0.0; - triNodesHost(4,0) = 0.5; triNodesHost(4,1) = 0.5; - triNodesHost(5,0) = 0.0; triNodesHost(5,1) = 0.5; + triNodesHost(3,0) = 0.5; triNodesHost(3,1) = 0.0; + triNodesHost(4,0) = 0.5; triNodesHost(4,1) = 0.5; + triNodesHost(5,0) = 0.0; triNodesHost(5,1) = 0.5; // Inside Triangle - triNodesHost(6,0) = 0.25; triNodesHost(6,1) = 0.25; + triNodesHost(6,0) = 0.25; triNodesHost(6,1) = 0.25; auto triNodes = Kokkos::create_mirror_view(typename DeviceType::memory_space(), triNodesHost); Kokkos::deep_copy(triNodes, triNodesHost); @@ -317,17 +298,17 @@ namespace Intrepid2 { const ordinal_type cardinality = triBasis.getCardinality(); const ordinal_type numPoints = triNodes.extent(0); const ordinal_type spaceDim = triBasis.getBaseCellTopology().getDimension(); - + { // Check VALUE of basis functions: resize vals to rank-3 container: DynRankView ConstructWithLabel(vals, cardinality, numPoints, spaceDim); - triBasis.getValues(vals, triNodes, OPERATOR_VALUE); + triBasis.getValues(space, vals, triNodes, OPERATOR_VALUE); auto vals_host = Kokkos::create_mirror_view(typename HostSpaceType::memory_space(), vals); Kokkos::deep_copy(vals_host, vals); for (ordinal_type i = 0; i < cardinality; ++i) { for (ordinal_type j = 0; j < numPoints; ++j) { for (ordinal_type k = 0; k < spaceDim; ++k) { - + // compute offset for (P,F,D) data layout: indices are P->j, F->i, D->k ordinal_type l = k + i * spaceDim + j * spaceDim * cardinality; if (std::abs(vals_host(i,j,k) - basisValues[l]) > tol) { @@ -343,12 +324,12 @@ namespace Intrepid2 { } } } - } - + } + { // Check CURL of basis function: resize vals to rank-2 container DynRankView ConstructWithLabel(vals, cardinality, numPoints); - triBasis.getValues(vals, triNodes, OPERATOR_CURL); + triBasis.getValues(space, vals, triNodes, OPERATOR_CURL); auto vals_host = Kokkos::create_mirror_view(typename HostSpaceType::memory_space(), vals); Kokkos::deep_copy(vals_host, vals); for (ordinal_type i = 0; i < cardinality; ++i) { @@ -357,7 +338,7 @@ namespace Intrepid2 { if (std::abs(vals_host(i,j) - basisCurls[l]) > tol) { errorFlag++; *outStream << std::setw(70) << "^^^^----FAILURE!" << "\n"; - + // Output the multi-index of the value where the error is: *outStream << " At multi-index { "; *outStream << i << " ";*outStream << j << " "; @@ -365,17 +346,17 @@ namespace Intrepid2 { << " but reference curl component: " << basisCurls[l] << "\n"; } } - } + } } } //end try - + // Catch unexpected errors catch (std::logic_error &err) { *outStream << err.what() << "\n\n"; errorFlag = -1000; }; - - *outStream + + *outStream << "\n" << "===============================================================================\n" << "| TEST 4: correctness of DoF locations |\n" @@ -414,7 +395,7 @@ namespace Intrepid2 { DynRankView ConstructWithLabel(dofCoeffs, cardinality, spaceDim); triBasis.getDofCoeffs(dofCoeffs); triBasis.getDofCoords(cvals); - triBasis.getValues(bvals, cvals, OPERATOR_VALUE); + triBasis.getValues(space, bvals, cvals, OPERATOR_VALUE); auto cvals_host = Kokkos::create_mirror_view(typename HostSpaceType::memory_space(), cvals); Kokkos::deep_copy(cvals_host, cvals); @@ -455,14 +436,14 @@ namespace Intrepid2 { << "===============================================================================\n" << "| TEST 5: Function Space is Correct |\n" << "===============================================================================\n"; - + try { const EFunctionSpace fs = triBasis.getFunctionSpace(); - + if (fs != FUNCTION_SPACE_HCURL) { *outStream << std::setw(70) << "------------- TEST FAILURE! -------------" << "\n"; - + // Output the multi-index of the value where the error is: *outStream << " Expected a function space of FUNCTION_SPACE_HCURL (enum value " << FUNCTION_SPACE_HCURL << "),"; *outStream << " but got " << fs << "\n"; @@ -478,12 +459,12 @@ namespace Intrepid2 { *outStream << "-------------------------------------------------------------------------------" << "\n\n"; errorFlag = -1000; } - + if (errorFlag != 0) std::cout << "End Result: TEST FAILED\n"; else std::cout << "End Result: TEST PASSED\n"; - + // reset format state of std::cout std::cout.copyfmt(oldFormatState); return errorFlag; diff --git a/packages/intrepid2/unit-test/Discretization/Basis/HGRAD_HEX_C1_FEM/test_01.hpp b/packages/intrepid2/unit-test/Discretization/Basis/HGRAD_HEX_C1_FEM/test_01.hpp index 6707cb77be10..3db0cd5f4410 100644 --- a/packages/intrepid2/unit-test/Discretization/Basis/HGRAD_HEX_C1_FEM/test_01.hpp +++ b/packages/intrepid2/unit-test/Discretization/Basis/HGRAD_HEX_C1_FEM/test_01.hpp @@ -56,49 +56,30 @@ #include "Teuchos_RCP.hpp" #include "packages/intrepid2/unit-test/Discretization/Basis/Macros.hpp" +#include "packages/intrepid2/unit-test/Discretization/Basis/Setup.hpp" namespace Intrepid2 { namespace Test { + using HostSpaceType = Kokkos::DefaultHostExecutionSpace; + template int HGRAD_HEX_C1_FEM_Test01(const bool verbose) { - Teuchos::RCP outStream; - Teuchos::oblackholestream bhs; // outputs nothing + //! Create an execution space instance. + const auto space = Kokkos::Experimental::partition_space(typename DeviceType::execution_space {}, 1)[0]; - if (verbose) - outStream = Teuchos::rcp(&std::cout, false); - else - outStream = Teuchos::rcp(&bhs, false); + //! Setup test output stream. + Teuchos::RCP outStream = setup_output_stream( + verbose, "Basis_HGRAD_HEX_C1_FEM", { + "1) Conversion of Dof tags into Dof ordinals and back", + "2) Basis values for VALUE, GRAD, CURL, and Dk operators" + }); Teuchos::oblackholestream oldFormatState; oldFormatState.copyfmt(std::cout); - using DeviceSpaceType = typename DeviceType::execution_space; - typedef typename - Kokkos::DefaultHostExecutionSpace HostSpaceType ; - - *outStream << "DeviceSpace:: "; DeviceSpaceType().print_configuration(*outStream, false); - *outStream << "HostSpace:: "; HostSpaceType().print_configuration(*outStream, false); - - *outStream - << "===============================================================================\n" - << "| |\n" - << "| Unit Test (Basis_HGRAD_HEX_C1_FEM) |\n" - << "| |\n" - << "| 1) Conversion of Dof tags into Dof ordinals and back |\n" - << "| 2) Basis values for VALUE, GRAD, CURL, and Dk operators |\n" - << "| |\n" - << "| Questions? Contact Pavel Bochev (pbboche@sandia.gov), |\n" - << "| Denis Ridzal (dridzal@sandia.gov), |\n" - << "| Kara Peterson (kjpeter@sandia.gov). |\n" - << "| |\n" - << "| Intrepid's website: http://trilinos.sandia.gov/packages/intrepid |\n" - << "| Trilinos website: http://trilinos.sandia.gov |\n" - << "| |\n" - << "===============================================================================\n"; - typedef Kokkos::DynRankView DynRankView; typedef Kokkos::DynRankView DynRankViewHost; @@ -502,7 +483,7 @@ namespace Intrepid2 { { 0.00000, 0.00000, 0.12500, 0.00000, 0.12500, 0.00000 }, { 0.00000, 0.00000, -0.12500, 0.00000, 0.12500, 0.00000 } } }; - + // the only nonzeros for D3 are in the "4" slot of the operator column, with values ±1/8, as indicated below: const ValueType basisD3Nonzeros[8] = { -0.125, 0.125,-0.125, 0.125, 0.125,-0.125,0.125,-0.125 }; @@ -549,7 +530,7 @@ namespace Intrepid2 { // Check VALUE of basis functions: resize vals to rank-2 container: { DynRankView vals = DynRankView(work.data(), numFields, numPoints); - hexBasis.getValues(vals, hexNodes, OPERATOR_VALUE); + hexBasis.getValues(space, vals, hexNodes, OPERATOR_VALUE); auto vals_host = Kokkos::create_mirror_view(typename HostSpaceType::memory_space(), vals); Kokkos::deep_copy(vals_host, vals); for (auto i=0;i int HGRAD_HEX_DEG2_FEM_Test01(const bool verbose) { - Teuchos::RCP outStream; - Teuchos::oblackholestream bhs; // outputs nothing + //! Create an execution space instance. + const auto space = Kokkos::Experimental::partition_space(typename DeviceType::execution_space {}, 1)[0]; - if (verbose) - outStream = Teuchos::rcp(&std::cout, false); - else - outStream = Teuchos::rcp(&bhs, false); + //! Setup test output stream. + Teuchos::RCP outStream = setup_output_stream( + verbose, (serendipity) ? "Basis_HGRAD_HEX_I2_Serendipity FEM" : "Basis_HGRAD_HEX_C2_FEM", { + "1) Conversion of Dof tags into Dof ordinals and back", + "2) Basis values for VALUE, GRAD, and Dk operators" + }); Teuchos::oblackholestream oldFormatState; oldFormatState.copyfmt(std::cout); - using DeviceSpaceType = typename DeviceType::execution_space; - typedef typename - Kokkos::DefaultHostExecutionSpace HostSpaceType ; - - *outStream << "DeviceSpace:: "; DeviceSpaceType().print_configuration(*outStream, false); - *outStream << "HostSpace:: "; HostSpaceType().print_configuration(*outStream, false); - - *outStream - << "\n" - << "===============================================================================\n" - << "| |\n"; - - if constexpr (serendipity) - *outStream - << "| Unit Test (Basis_HGRAD_HEX_I2_Serendipity FEM) |\n"; - else - *outStream - << "| Unit Test (Basis_HGRAD_HEX_C2_FEM) |\n"; - *outStream - << "| |\n" - << "| 1) Conversion of Dof tags into Dof ordinals and back |\n" - << "| 2) Basis values for VALUE, GRAD, and Dk operators |\n" - << "| |\n" - << "===============================================================================\n"; - typedef Kokkos::DynRankView DynRankView; typedef Kokkos::DynRankView DynRankViewHost; @@ -110,7 +90,7 @@ namespace Intrepid2 { typedef ValueType outputValueType; typedef ValueType pointValueType; BasisPtr hexBasis; - if constexpr (serendipity) + if constexpr (serendipity) hexBasis = Teuchos::rcp(new Basis_HGRAD_HEX_I2_FEM()); else hexBasis = Teuchos::rcp(new Basis_HGRAD_HEX_C2_FEM()); @@ -443,12 +423,12 @@ namespace Intrepid2 { // Generic array for values, grads, curls, etc. that will be properly sized before each call DynRankView ConstructWithLabel(vals, numFields, numPoints); // Check VALUE of basis functions: resize vals to rank-2 container: - hexBasis->getValues(vals, hexNodes, OPERATOR_VALUE); + hexBasis->getValues(space, vals, hexNodes, OPERATOR_VALUE); auto vals_host = Kokkos::create_mirror_view(typename HostSpaceType::memory_space(), vals); Kokkos::deep_copy(vals_host, vals); for (ordinal_type i = 0; i < numFields; ++i) { for (ordinal_type j = 0; j < numPoints; ++j) { - ValueType basisVal = (i==j) ? 1.0 : 0.0; //Kronecher property + ValueType basisVal = (i==j) ? 1.0 : 0.0; //Kronecher property if (std::abs(vals_host(i,j) - basisVal) > tol ) { errorFlag++; *outStream << std::setw(70) << "^^^^----FAILURE!" << "\n"; @@ -466,7 +446,7 @@ namespace Intrepid2 { { DynRankView ConstructWithLabel(vals, numFields, numPoints, spaceDim); // Check GRAD of basis function: resize vals to rank-3 container - hexBasis->getValues(vals, hexNodes, OPERATOR_GRAD); + hexBasis->getValues(space, vals, hexNodes, OPERATOR_GRAD); auto vals_host = Kokkos::create_mirror_view(typename HostSpaceType::memory_space(), vals); Kokkos::deep_copy(vals_host, vals); for (ordinal_type i = 0; i < numFields; ++i) { @@ -490,7 +470,7 @@ namespace Intrepid2 { } // Check D1 of basis function (do not resize vals because it has the correct size: D1 = GRAD) - hexBasis->getValues(vals, hexNodes, OPERATOR_D1); + hexBasis->getValues(space, vals, hexNodes, OPERATOR_D1); Kokkos::deep_copy(vals_host, vals); for (ordinal_type i = 0; i < numFields; ++i) { for (ordinal_type j = 0; j < numPoints; ++j) { @@ -516,7 +496,7 @@ namespace Intrepid2 { { // Check D2 of basis function DynRankView ConstructWithLabel(vals, numFields, numPoints, D2Cardin); - hexBasis->getValues(vals, hexNodes, OPERATOR_D2); + hexBasis->getValues(space, vals, hexNodes, OPERATOR_D2); auto vals_host = Kokkos::create_mirror_view(typename HostSpaceType::memory_space(), vals); Kokkos::deep_copy(vals_host, vals); for (ordinal_type i = 0; i < numFields; ++i) { @@ -543,7 +523,7 @@ namespace Intrepid2 { { // Check D3 of basis function DynRankView ConstructWithLabel(vals, numFields, numPoints, D3Cardin); - hexBasis->getValues(vals, hexNodes, OPERATOR_D3); + hexBasis->getValues(space, vals, hexNodes, OPERATOR_D3); auto vals_host = Kokkos::create_mirror_view(typename HostSpaceType::memory_space(), vals); Kokkos::deep_copy(vals_host, vals); for (ordinal_type i = 0; i < numFields; ++i) { @@ -571,7 +551,7 @@ namespace Intrepid2 { // Check D4 of basis function if(!serendipity) { //don't have tabulated values for D4 for serendipity elements DynRankView ConstructWithLabel(vals, numFields, numPoints, D4Cardin); - hexBasis->getValues(vals, hexNodes, OPERATOR_D4); + hexBasis->getValues(space, vals, hexNodes, OPERATOR_D4); auto vals_host = Kokkos::create_mirror_view(typename HostSpaceType::memory_space(), vals); Kokkos::deep_copy(vals_host, vals); for (ordinal_type i = 0; i < numFields; i++) { @@ -609,7 +589,7 @@ namespace Intrepid2 { // The last dimension is the number of kth derivatives and needs to be resized for every Dk const ordinal_type DkCardin = getDkCardinality(op, spaceDim); DynRankView ConstructWithLabel(vals, numFields, numPoints, DkCardin); - hexBasis->getValues(vals, hexNodes, op); + hexBasis->getValues(space, vals, hexNodes, op); auto vals_host = Kokkos::create_mirror_view(typename HostSpaceType::memory_space(), vals); Kokkos::deep_copy(vals_host, vals); @@ -672,7 +652,7 @@ namespace Intrepid2 { // Check mathematical correctness. hexBasis->getDofCoords(cvals); - hexBasis->getValues(bvals, cvals, OPERATOR_VALUE); + hexBasis->getValues(space, bvals, cvals, OPERATOR_VALUE); auto cvals_host = Kokkos::create_mirror_view(typename HostSpaceType::memory_space(), cvals); Kokkos::deep_copy(cvals_host, cvals); auto bvals_host = Kokkos::create_mirror_view(typename HostSpaceType::memory_space(), bvals); @@ -704,14 +684,14 @@ namespace Intrepid2 { << "===============================================================================\n" << "| TEST 5: Function Space is Correct |\n" << "===============================================================================\n"; - + try { const EFunctionSpace fs = hexBasis->getFunctionSpace(); - + if (fs != FUNCTION_SPACE_HGRAD) { *outStream << std::setw(70) << "------------- TEST FAILURE! -------------" << "\n"; - + // Output the multi-index of the value where the error is: *outStream << " Expected a function space of FUNCTION_SPACE_HGRAD (enum value " << FUNCTION_SPACE_HGRAD << "),"; *outStream << " but got " << fs << "\n"; @@ -727,7 +707,7 @@ namespace Intrepid2 { *outStream << "-------------------------------------------------------------------------------" << "\n\n"; errorFlag = -1000; } - + if (errorFlag != 0) std::cout << "End Result: TEST FAILED\n"; else diff --git a/packages/intrepid2/unit-test/Discretization/Basis/HGRAD_HEX_Cn_FEM/test_01.hpp b/packages/intrepid2/unit-test/Discretization/Basis/HGRAD_HEX_Cn_FEM/test_01.hpp index dd0f57fde772..8e2370790ccd 100644 --- a/packages/intrepid2/unit-test/Discretization/Basis/HGRAD_HEX_Cn_FEM/test_01.hpp +++ b/packages/intrepid2/unit-test/Discretization/Basis/HGRAD_HEX_Cn_FEM/test_01.hpp @@ -61,57 +61,35 @@ #include "Teuchos_RCP.hpp" #include "packages/intrepid2/unit-test/Discretization/Basis/Macros.hpp" +#include "packages/intrepid2/unit-test/Discretization/Basis/Setup.hpp" namespace Intrepid2 { namespace Test { +using HostSpaceType = Kokkos::DefaultHostExecutionSpace; + template int HGRAD_HEX_Cn_FEM_Test01(const bool verbose) { - Teuchos::RCP outStream; - Teuchos::oblackholestream bhs; // outputs nothing + //! Create an execution space instance. + const auto space = Kokkos::Experimental::partition_space(typename DeviceType::execution_space {}, 1)[0]; - if (verbose) - outStream = Teuchos::rcp(&std::cout, false); - else - outStream = Teuchos::rcp(&bhs, false); + //! Setup test output stream. + Teuchos::RCP outStream = setup_output_stream( + verbose, "Basis_HGRAD_HEX_Cn_FEM FEM", { + "1) Conversion of Dof tags into Dof ordinals and back", + "2) Basis values for VALUE, GRAD, and Dk operators" + }); Teuchos::oblackholestream oldFormatState; oldFormatState.copyfmt(std::cout); - using DeviceSpaceType = typename DeviceType::execution_space; - typedef typename - Kokkos::DefaultHostExecutionSpace HostSpaceType ; - - *outStream << "DeviceSpace:: "; DeviceSpaceType().print_configuration(*outStream, false); - *outStream << "HostSpace:: "; HostSpaceType().print_configuration(*outStream, false); - - *outStream - << "===============================================================================\n" - << "| |\n" - << "| Unit Test (Basis_HGRAD_HEX_Cn_FEM) |\n" - << "| |\n" - << "| 1) Conversion of Dof tags into Dof ordinals and back |\n" - << "| 2) Basis values for VALUE, GRAD, and Dk operators |\n" - << "| |\n" - << "| Questions? Contact Pavel Bochev (pbboche@sandia.gov), |\n" - << "| Robert Kirby (robert.c.kirby@ttu.edu), |\n" - << "| Denis Ridzal (dridzal@sandia.gov), |\n" - << "| Kara Peterson (kjpeter@sandia.gov), |\n" - << "| Kyungjoo Kim (kyukim@sandia.gov), |\n" - << "| Mauro Perego (mperego@sandia.gov). |\n" - << "| |\n" - << "| Intrepid's website: http://trilinos.sandia.gov/packages/intrepid |\n" - << "| Trilinos website: http://trilinos.sandia.gov |\n" - << "| |\n" - << "===============================================================================\n"; - typedef Kokkos::DynRankView DynRankViewPointValueType; typedef Kokkos::DynRankView DynRankViewOutValueType; typedef typename ScalarTraits::scalar_type scalar_type; - typedef Kokkos::DynRankView DynRankViewScalarValueType; - typedef Kokkos::DynRankView DynRankViewHostScalarValueType; + typedef Kokkos::DynRankView DynRankViewScalarValueType; + typedef Kokkos::DynRankView DynRankViewHostScalarValueType; const scalar_type tol = tolerence(); int errorFlag = 0; @@ -315,7 +293,7 @@ int HGRAD_HEX_Cn_FEM_Test01(const bool verbose) { auto lattice_host = Kokkos::create_mirror_view(lattice); DynRankViewOutValueType ConstructWithLabelOutView(basisAtLattice, basisCardinality, basisCardinality); - hexBasis.getValues(basisAtLattice, lattice, OPERATOR_VALUE); + hexBasis.getValues(space, basisAtLattice, lattice, OPERATOR_VALUE); auto h_basisAtLattice = Kokkos::create_mirror_view(basisAtLattice); Kokkos::deep_copy(h_basisAtLattice, basisAtLattice); @@ -496,7 +474,7 @@ int HGRAD_HEX_Cn_FEM_Test01(const bool verbose) { DynRankViewHostScalarValueType ConstructWithLabel(hexNodesHost, 27, 3); DynRankViewPointValueType ConstructWithLabelPointView(hexNodes, 27, 3); - + // do it lexicographically as a lattice hexNodesHost(0, 0) = -1.0; hexNodesHost(0, 1) = -1.0; hexNodesHost(0, 2) = -1.0; @@ -529,7 +507,7 @@ int HGRAD_HEX_Cn_FEM_Test01(const bool verbose) { auto hexNodes_scalar = Kokkos::create_mirror_view(typename DeviceType::memory_space(), hexNodesHost); Kokkos::deep_copy(hexNodes_scalar, hexNodesHost); - + RealSpaceTools::clone(hexNodes, hexNodes_scalar); // Dimensions for the output arrays: @@ -544,7 +522,7 @@ int HGRAD_HEX_Cn_FEM_Test01(const bool verbose) { { // Check VALUE of basis functions: resize vals to rank-2 container: DynRankViewOutValueType ConstructWithLabelOutView(vals, numFields, numPoints); - hexBasis.getValues(vals, hexNodes, OPERATOR_VALUE); + hexBasis.getValues(space, vals, hexNodes, OPERATOR_VALUE); auto vals_host = Kokkos::create_mirror_view(vals); Kokkos::deep_copy(vals_host, vals); for (ordinal_type i = 0; i < numFields; ++i) { @@ -570,7 +548,7 @@ int HGRAD_HEX_Cn_FEM_Test01(const bool verbose) { { // Check GRAD of basis function: resize vals to rank-3 container DynRankViewOutValueType ConstructWithLabelOutView(vals, numFields, numPoints, spaceDim); - hexBasis.getValues(vals, hexNodes, OPERATOR_GRAD); + hexBasis.getValues(space, vals, hexNodes, OPERATOR_GRAD); auto vals_host = Kokkos::create_mirror_view(vals); Kokkos::deep_copy(vals_host, vals); for (ordinal_type i = 0; i < numFields; ++i) { @@ -598,7 +576,7 @@ int HGRAD_HEX_Cn_FEM_Test01(const bool verbose) { { // Check GRAD of basis function: resize vals to rank-3 container DynRankViewOutValueType ConstructWithLabelOutView(vals, numFields, numPoints, spaceDim); - hexBasis.getValues(vals, hexNodes, OPERATOR_D1); + hexBasis.getValues(space, vals, hexNodes, OPERATOR_D1); auto vals_host = Kokkos::create_mirror_view(vals); Kokkos::deep_copy(vals_host, vals); for (ordinal_type i = 0; i < numFields; ++i) { @@ -626,7 +604,7 @@ int HGRAD_HEX_Cn_FEM_Test01(const bool verbose) { { // Check GRAD of basis function: resize vals to rank-3 container DynRankViewOutValueType ConstructWithLabelOutView(vals, numFields, numPoints, D2Cardin); - hexBasis.getValues(vals, hexNodes, OPERATOR_D2); + hexBasis.getValues(space, vals, hexNodes, OPERATOR_D2); auto vals_host = Kokkos::create_mirror_view(vals); Kokkos::deep_copy(vals_host, vals); for (ordinal_type i = 0; i < numFields; ++i) { @@ -654,7 +632,7 @@ int HGRAD_HEX_Cn_FEM_Test01(const bool verbose) { { // Check GRAD of basis function: resize vals to rank-3 container DynRankViewOutValueType ConstructWithLabelOutView(vals, numFields, numPoints, D3Cardin); - hexBasis.getValues(vals, hexNodes, OPERATOR_D3); + hexBasis.getValues(space, vals, hexNodes, OPERATOR_D3); auto vals_host = Kokkos::create_mirror_view(vals); Kokkos::deep_copy(vals_host, vals); for (ordinal_type i = 0; i < numFields; ++i) { @@ -682,7 +660,7 @@ int HGRAD_HEX_Cn_FEM_Test01(const bool verbose) { { // Check GRAD of basis function: resize vals to rank-3 container DynRankViewOutValueType ConstructWithLabelOutView(vals, numFields, numPoints, D4Cardin); - hexBasis.getValues(vals, hexNodes, OPERATOR_D4); + hexBasis.getValues(space, vals, hexNodes, OPERATOR_D4); auto vals_host = Kokkos::create_mirror_view(vals); Kokkos::deep_copy(vals_host, vals); for (ordinal_type i = 0; i < numFields; ++i) { @@ -718,7 +696,7 @@ int HGRAD_HEX_Cn_FEM_Test01(const bool verbose) { const ordinal_type DkCardin = Intrepid2::getDkCardinality(op, spaceDim); DynRankViewOutValueType ConstructWithLabelOutView(vals, numFields, numPoints, DkCardin); - hexBasis.getValues(vals, hexNodes, op); + hexBasis.getValues(space, vals, hexNodes, op); auto vals_host = Kokkos::create_mirror_view(vals); Kokkos::deep_copy(vals_host, vals); for (ordinal_type i = 0; i < numFields; ++i) { @@ -744,23 +722,23 @@ int HGRAD_HEX_Cn_FEM_Test01(const bool verbose) { *outStream << err.what() << "\n\n"; errorFlag = -1000; }; - + *outStream << "\n" << "===============================================================================\n" << "| TEST 5: Function Space is Correct |\n" << "===============================================================================\n"; - + try { constexpr ordinal_type order = 2; HexBasisType hexBasis(order); - + const EFunctionSpace fs = hexBasis.getFunctionSpace(); - + if (fs != FUNCTION_SPACE_HGRAD) { *outStream << std::setw(70) << "------------- TEST FAILURE! -------------" << "\n"; - + // Output the multi-index of the value where the error is: *outStream << " Expected a function space of FUNCTION_SPACE_HGRAD (enum value " << FUNCTION_SPACE_HGRAD << "),"; *outStream << " but got " << fs << "\n"; diff --git a/packages/intrepid2/unit-test/Discretization/Basis/HGRAD_LINE_Cn_FEM_JACOBI/test_01.hpp b/packages/intrepid2/unit-test/Discretization/Basis/HGRAD_LINE_Cn_FEM_JACOBI/test_01.hpp index d98f9a7ae495..64f6001341f5 100644 --- a/packages/intrepid2/unit-test/Discretization/Basis/HGRAD_LINE_Cn_FEM_JACOBI/test_01.hpp +++ b/packages/intrepid2/unit-test/Discretization/Basis/HGRAD_LINE_Cn_FEM_JACOBI/test_01.hpp @@ -65,9 +65,14 @@ namespace Intrepid2 { namespace Test { + using HostSpaceType = Kokkos::DefaultHostExecutionSpace; + template int HGRAD_LINE_Cn_FEM_JACOBI_Test01(const bool verbose) { + //! Create an execution space instance. + const auto space = Kokkos::Experimental::partition_space(typename DeviceType::execution_space {}, 1)[0]; + Teuchos::RCP outStream = setup_output_stream( verbose, "Basis_HGRAD_LINE_Cn_FEM_JACOBI", { "1) Conversion of Dof tags into Dof ordinals and back", @@ -322,7 +327,7 @@ namespace Intrepid2 { { *outStream << " -- Comparing OPERATOR_VALUE -- \n\n"; DynRankView ConstructWithLabel(vals, numFields, numPoints); - lineBasis.getValues(vals, lineNodes, OPERATOR_VALUE); + lineBasis.getValues(space, vals, lineNodes, OPERATOR_VALUE); // host mirror for comparison auto valsHost = Kokkos::create_mirror_view(vals); @@ -352,7 +357,7 @@ namespace Intrepid2 { { *outStream << " -- Comparing OPERATOR_D1 -- \n\n"; DynRankView ConstructWithLabel(vals, numFields, numPoints, spaceDim); - lineBasis.getValues(vals, lineNodes, OPERATOR_D1); + lineBasis.getValues(space, vals, lineNodes, OPERATOR_D1); // host mirror for comparison auto valsHost = Kokkos::create_mirror_view(vals); @@ -382,7 +387,7 @@ namespace Intrepid2 { { *outStream << " -- Comparing OPERATOR_D2 -- \n\n"; DynRankView ConstructWithLabel(vals, numFields, numPoints, spaceDim); - lineBasis.getValues(vals, lineNodes, OPERATOR_D2); + lineBasis.getValues(space, vals, lineNodes, OPERATOR_D2); // host mirror for comparison auto valsHost = Kokkos::create_mirror_view(vals); @@ -412,7 +417,7 @@ namespace Intrepid2 { { *outStream << " -- Comparing OPERATOR_D3 -- \n\n"; DynRankView ConstructWithLabel(vals, numFields, numPoints, spaceDim); - lineBasis.getValues(vals, lineNodes, OPERATOR_D3); + lineBasis.getValues(space, vals, lineNodes, OPERATOR_D3); // host mirror for comparison auto valsHost = Kokkos::create_mirror_view(vals); diff --git a/packages/intrepid2/unit-test/Discretization/Basis/HGRAD_TET_COMP12_FEM/test_01.hpp b/packages/intrepid2/unit-test/Discretization/Basis/HGRAD_TET_COMP12_FEM/test_01.hpp index 812630c3952d..589db5455bcb 100644 --- a/packages/intrepid2/unit-test/Discretization/Basis/HGRAD_TET_COMP12_FEM/test_01.hpp +++ b/packages/intrepid2/unit-test/Discretization/Basis/HGRAD_TET_COMP12_FEM/test_01.hpp @@ -71,6 +71,9 @@ namespace Intrepid2 { template int HGRAD_TET_COMP12_FEM_Test01(const bool verbose) { + //! Create an execution space instance. + const auto space = Kokkos::Experimental::partition_space(typename DeviceType::execution_space {}, 1)[0]; + Teuchos::RCP outStream = setup_output_stream( verbose, "Basis_HGRAD_TET_COMP12_FEM", { "1) Evaluation of Basis Function Values" @@ -302,7 +305,7 @@ namespace Intrepid2 { { *outStream << " check VALUE of basis functions at nodes\n"; DynRankView vals = DynRankView("vals", numFields, numNodes); - tetBasis.getValues(vals, tetNodes, OPERATOR_VALUE); + tetBasis.getValues(space, vals, tetNodes, OPERATOR_VALUE); auto vals_host = Kokkos::create_mirror_view(typename HostSpaceType::memory_space(), vals); Kokkos::deep_copy(vals_host, vals); @@ -329,7 +332,7 @@ namespace Intrepid2 { { *outStream << " check VALUE of basis functions at points\n"; DynRankView vals = DynRankView("vals", numFields, numPoints); - tetBasis.getValues(vals, tetPoints, OPERATOR_VALUE); + tetBasis.getValues(space, vals, tetPoints, OPERATOR_VALUE); auto vals_host = Kokkos::create_mirror_view(typename HostSpaceType::memory_space(), vals); Kokkos::deep_copy(vals_host, vals); @@ -380,7 +383,7 @@ namespace Intrepid2 { DynRankView vals = DynRankView("vals", numFields, numRandomPoints); - tetBasis.getValues(vals, tetRandomPoints, OPERATOR_VALUE); + tetBasis.getValues(space, vals, tetRandomPoints, OPERATOR_VALUE); auto vals_host = Kokkos::create_mirror_view(typename HostSpaceType::memory_space(), vals); Kokkos::deep_copy(vals_host, vals); @@ -405,7 +408,7 @@ namespace Intrepid2 { // Check GRAD of basis functions at points: resize vals to rank-3 container:\n"; { DynRankView vals = DynRankView("vals", numFields, numPoints, spaceDim); - tetBasis.getValues(vals, tetPoints, OPERATOR_GRAD); + tetBasis.getValues(space, vals, tetPoints, OPERATOR_GRAD); auto vals_host = Kokkos::create_mirror_view(typename HostSpaceType::memory_space(), vals); Kokkos::deep_copy(vals_host, vals); for (ordinal_type i=0;i int HGRAD_TET_Cn_FEM_ORTH_Test01(const bool verbose) { + //! Create an execution space instance. + const auto space = Kokkos::Experimental::partition_space(typename DeviceType::execution_space {}, 1)[0]; + Teuchos::RCP outStream = setup_output_stream( verbose, "HGRAD_TET_Cn_FEM_ORTH", { "1) Tests orthogonality of tetrahedral orthogonal basis" @@ -115,7 +118,7 @@ int HGRAD_TET_Cn_FEM_ORTH_Test01(const bool verbose) { // Tabulate the basis functions at the cubature points DynRankView ConstructWithLabel(basisAtCubPts, polydim, npts); - tetBasis.getValues(basisAtCubPts, cubPoints, OPERATOR_VALUE); + tetBasis.getValues(space, basisAtCubPts, cubPoints, OPERATOR_VALUE); auto h_basisAtCubPts = Kokkos::create_mirror_view(basisAtCubPts); Kokkos::deep_copy(h_basisAtCubPts, basisAtCubPts); @@ -159,7 +162,7 @@ int HGRAD_TET_Cn_FEM_ORTH_Test01(const bool verbose) { PointTools::getLattice(lattice, tet_4, order, 0, POINTTYPE_EQUISPACED); DynRankView ConstructWithLabel(dBasisAtLattice, polydim , np_lattice , dim); - tetBasis.getValues(dBasisAtLattice, lattice, OPERATOR_D1); + tetBasis.getValues(space, dBasisAtLattice, lattice, OPERATOR_D1); auto h_dBasisAtLattice = Kokkos::create_mirror_view(dBasisAtLattice); Kokkos::deep_copy(h_dBasisAtLattice, dBasisAtLattice); @@ -598,17 +601,17 @@ int HGRAD_TET_Cn_FEM_ORTH_Test01(const bool verbose) { << "===============================================================================\n" << "| TEST 2: Function Space is Correct |\n" << "===============================================================================\n"; - + try { const ordinal_type order = std::min(3, maxOrder); tetBasisType tetBasis(order); - + const EFunctionSpace fs = tetBasis.getFunctionSpace(); - + if (fs != FUNCTION_SPACE_HGRAD) { *outStream << std::setw(70) << "------------- TEST FAILURE! -------------" << "\n"; - + // Output the multi-index of the value where the error is: *outStream << " Expected a function space of FUNCTION_SPACE_HGRAD (enum value " << FUNCTION_SPACE_HGRAD << "),"; *outStream << " but got " << fs << "\n"; @@ -626,7 +629,7 @@ int HGRAD_TET_Cn_FEM_ORTH_Test01(const bool verbose) { } // second order derivatives test missing!! - + if (errorFlag != 0) std::cout << "End Result: TEST FAILED\n"; else diff --git a/packages/intrepid2/unit-test/Discretization/Basis/HGRAD_TRI_Cn_FEM_ORTH/test_01.hpp b/packages/intrepid2/unit-test/Discretization/Basis/HGRAD_TRI_Cn_FEM_ORTH/test_01.hpp index 8b94e939250a..2649791eb623 100644 --- a/packages/intrepid2/unit-test/Discretization/Basis/HGRAD_TRI_Cn_FEM_ORTH/test_01.hpp +++ b/packages/intrepid2/unit-test/Discretization/Basis/HGRAD_TRI_Cn_FEM_ORTH/test_01.hpp @@ -60,6 +60,7 @@ #include "Intrepid2_CubatureDirectTriDefault.hpp" #include "packages/intrepid2/unit-test/Discretization/Basis/Macros.hpp" +#include "packages/intrepid2/unit-test/Discretization/Basis/Setup.hpp" namespace Intrepid2 { @@ -68,35 +69,17 @@ namespace Test { template int HGRAD_TRI_Cn_FEM_ORTH_Test01(const bool verbose) { - Teuchos::RCP outStream; - Teuchos::oblackholestream bhs; // outputs nothing + //! Create an execution space instance. + const auto space = Kokkos::Experimental::partition_space(typename DeviceType::execution_space {}, 1)[0]; - if (verbose) - outStream = Teuchos::rcp(&std::cout, false); - else - outStream = Teuchos::rcp(&bhs, false); + Teuchos::RCP outStream = setup_output_stream( + verbose, "OrthogonalBases", { + "1) Tests orthogonality of triangular orthogonal basis" + }); Teuchos::oblackholestream oldFormatState; oldFormatState.copyfmt(std::cout); - *outStream - << "===============================================================================\n" - << "| |\n" - << "| Unit Test OrthogonalBases |\n" - << "| |\n" - << "| 1) Tests orthogonality of triangular orthogonal basis |\n" - << "| |\n" - << "| Questions? Contact Pavel Bochev (pbboche@sandia.gov), |\n" - << "| Denis Ridzal (dridzal@sandia.gov), |\n" - << "| Robert Kirby (robert.c.kirby@ttu.edu), |\n" - << "| Mauro Perego (mperego@sandia.gov), |\n" - << "| Kyungjoo Kim (kyukim@sandia.gov) |\n" - << "| |\n" - << "| Intrepid's website: http://trilinos.sandia.gov/packages/intrepid |\n" - << "| Trilinos website: http://trilinos.sandia.gov |\n" - << "| |\n" - << "===============================================================================\n"; - typedef Kokkos::DynRankView DynRankView; const ValueType tol = tolerence(); @@ -138,7 +121,7 @@ int HGRAD_TRI_Cn_FEM_ORTH_Test01(const bool verbose) { // Tabulate the basis functions at the cubature points DynRankView ConstructWithLabel(basisAtCubPts, polydim, npts); - triBasis.getValues(basisAtCubPts, cubPoints, OPERATOR_VALUE); + triBasis.getValues(space, basisAtCubPts, cubPoints, OPERATOR_VALUE); auto h_basisAtCubPts = Kokkos::create_mirror_view(basisAtCubPts); Kokkos::deep_copy(h_basisAtCubPts, basisAtCubPts); @@ -181,7 +164,7 @@ int HGRAD_TRI_Cn_FEM_ORTH_Test01(const bool verbose) { PointTools::getLattice(lattice, tri_3, order, 0, POINTTYPE_EQUISPACED); DynRankView ConstructWithLabel(dBasisAtLattice, polydim , np_lattice , dim); - triBasis.getValues(dBasisAtLattice, lattice, OPERATOR_D1); + triBasis.getValues(space, dBasisAtLattice, lattice, OPERATOR_D1); auto h_dBasisAtLattice = Kokkos::create_mirror_view(dBasisAtLattice); Kokkos::deep_copy(h_dBasisAtLattice, dBasisAtLattice); @@ -334,7 +317,7 @@ int HGRAD_TRI_Cn_FEM_ORTH_Test01(const bool verbose) { PointTools::getLattice(lattice, tri_3, order, 0, POINTTYPE_EQUISPACED); DynRankView ConstructWithLabel(dBasisAtLattice, polydim , np_lattice , 3); - triBasis.getValues(dBasisAtLattice, lattice, OPERATOR_D2); + triBasis.getValues(space, dBasisAtLattice, lattice, OPERATOR_D2); auto h_dBasisAtLattice = Kokkos::create_mirror_view(dBasisAtLattice); Kokkos::deep_copy(h_dBasisAtLattice, dBasisAtLattice); From 8cc08e4dd1e0ee991ef25f3770f3e5c1673cdc40 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 Mar 2024 23:05:19 +0000 Subject: [PATCH 07/17] Bump actions/checkout from 3.6.0 to 4.1.2 Bumps [actions/checkout](https://github.com/actions/checkout) from 3.6.0 to 4.1.2. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3.6.0...9bb56186c3b09b4f86b1c65136769dd318469633) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/PR-gcc-openmpi.yml | 2 +- .github/workflows/clang_format.yml | 2 +- .github/workflows/dependency-review.yml | 2 +- .github/workflows/detect-git-lfs.yml | 2 +- .github/workflows/detect-mpi-comm-world.yml | 2 +- .github/workflows/scorecards.yml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/PR-gcc-openmpi.yml b/.github/workflows/PR-gcc-openmpi.yml index 7eb91f341044..ef830dad4860 100644 --- a/.github/workflows/PR-gcc-openmpi.yml +++ b/.github/workflows/PR-gcc-openmpi.yml @@ -44,7 +44,7 @@ jobs: mkdir -p /home/Trilinos/src/Trilinos mkdir -p /home/Trilinos/build - name: Clone trilinos - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 with: fetch-depth: 0 - name: Repo status diff --git a/.github/workflows/clang_format.yml b/.github/workflows/clang_format.yml index ca6c86305fee..b4c56c0a5e66 100644 --- a/.github/workflows/clang_format.yml +++ b/.github/workflows/clang_format.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - uses: DoozyX/clang-format-lint-action@1566bcec081dcb246ab02e7c5f9786c0b629dd4d # v0.16.2 with: source: './packages/muelu ./packages/tempus ./packages/teko ./packages/xpetra' diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index 3f3456223b0a..d16a2b437729 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -22,6 +22,6 @@ jobs: egress-policy: audit - name: 'Checkout Repository' - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 - name: 'Dependency Review' uses: actions/dependency-review-action@0efb1d1d84fc9633afcdaad14c485cbbc90ef46c # v2.5.1 diff --git a/.github/workflows/detect-git-lfs.yml b/.github/workflows/detect-git-lfs.yml index 42811f4d1eac..f8498ce6fd6f 100644 --- a/.github/workflows/detect-git-lfs.yml +++ b/.github/workflows/detect-git-lfs.yml @@ -12,7 +12,7 @@ jobs: steps: - name: Check out code - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 with: fetch-depth: 0 diff --git a/.github/workflows/detect-mpi-comm-world.yml b/.github/workflows/detect-mpi-comm-world.yml index 8d6b57826631..e4e0b5269637 100644 --- a/.github/workflows/detect-mpi-comm-world.yml +++ b/.github/workflows/detect-mpi-comm-world.yml @@ -12,7 +12,7 @@ jobs: steps: - name: Check out code - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 with: fetch-depth: 0 diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index 85f6e38986b3..3b39d77c4a06 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -31,7 +31,7 @@ jobs: steps: - name: "Checkout code" - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 with: persist-credentials: false From 1ac30cbdd0c4bff408dd82429f91130cbcfca20f Mon Sep 17 00:00:00 2001 From: Chris Siefert Date: Mon, 18 Mar 2024 13:29:23 -0600 Subject: [PATCH 08/17] Update README.md (#12841) Adding OpenSSF scorecard badge --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index dc8b85f36c8e..96a40e46dee8 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,10 @@ [Packages](http://trilinos.github.io/packages.html) +[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/trilinos/Trilinos/badge)](https://securityscorecards.dev/viewer/?uri=github.com/trilinos/Trilinos) + + + The Trilinos Project is an effort to develop algorithms and enabling technologies within an object-oriented software framework for the solution of large-scale, complex multi-physics engineering and scientific problems. A From df377374740a744138e1207189fa6a510cb79700 Mon Sep 17 00:00:00 2001 From: Maarten Arnst Date: Mon, 18 Mar 2024 11:35:47 +0100 Subject: [PATCH 09/17] Allow Intrepid2 functionalities to be used with both View and DynRankView --- .../src/Cell/Intrepid2_CellTools.hpp | 106 +++++++++--------- .../Cell/Intrepid2_CellToolsDefJacobian.hpp | 35 +++--- .../Cell/Intrepid2_CellToolsDefNodeInfo.hpp | 79 ++++++------- .../Cell/Intrepid2_CellToolsDefRefToPhys.hpp | 15 ++- .../Discretization/Basis/Intrepid2_Basis.hpp | 2 +- .../Basis/Intrepid2_BasisDef.hpp | 38 +++---- .../Basis/Intrepid2_HCURL_TET_I1_FEM.hpp | 4 +- .../Basis/Intrepid2_HCURL_TET_In_FEM.hpp | 4 +- .../Basis/Intrepid2_HCURL_TRI_I1_FEM.hpp | 4 +- .../Basis/Intrepid2_HCURL_TRI_In_FEM.hpp | 4 +- .../Basis/Intrepid2_HGRAD_HEX_C1_FEM.hpp | 4 +- .../Basis/Intrepid2_HGRAD_HEX_C2_FEM.hpp | 4 +- .../Basis/Intrepid2_HGRAD_HEX_Cn_FEM.hpp | 4 +- .../Basis/Intrepid2_HGRAD_LINE_C1_FEM.hpp | 4 +- .../Basis/Intrepid2_HGRAD_LINE_C2_FEM.hpp | 4 +- .../Basis/Intrepid2_HGRAD_LINE_Cn_FEM.hpp | 4 +- .../Basis/Intrepid2_HGRAD_QUAD_C1_FEM.hpp | 4 +- .../Basis/Intrepid2_HGRAD_QUAD_C2_FEM.hpp | 4 +- .../Basis/Intrepid2_HGRAD_QUAD_Cn_FEM.hpp | 4 +- .../Basis/Intrepid2_HGRAD_TET_C1_FEM.hpp | 4 +- .../Basis/Intrepid2_HGRAD_TET_C2_FEM.hpp | 4 +- .../Basis/Intrepid2_HGRAD_TET_COMP12_FEM.hpp | 2 +- .../Basis/Intrepid2_HGRAD_TET_Cn_FEM.hpp | 4 +- .../Basis/Intrepid2_HGRAD_TRI_C1_FEM.hpp | 4 +- .../Basis/Intrepid2_HGRAD_TRI_C2_FEM.hpp | 4 +- .../Basis/Intrepid2_HGRAD_TRI_Cn_FEM.hpp | 4 +- .../Intrepid2_FunctionSpaceTools.hpp | 24 ++-- .../Intrepid2_FunctionSpaceToolsDef.hpp | 30 ++--- .../Integration/Intrepid2_Cubature.hpp | 4 +- .../Integration/Intrepid2_CubatureDirect.hpp | 4 +- .../Shared/Intrepid2_ArrayToolsDefTensor.hpp | 2 +- .../intrepid2/src/Shared/Intrepid2_Data.hpp | 5 + 32 files changed, 213 insertions(+), 209 deletions(-) diff --git a/packages/intrepid2/src/Cell/Intrepid2_CellTools.hpp b/packages/intrepid2/src/Cell/Intrepid2_CellTools.hpp index 0cd1201ff0de..cfa4ac04987f 100644 --- a/packages/intrepid2/src/Cell/Intrepid2_CellTools.hpp +++ b/packages/intrepid2/src/Cell/Intrepid2_CellTools.hpp @@ -222,14 +222,14 @@ namespace Intrepid2 { \param startCell [in] - first cell index in cellWorkset for which we should compute the Jacobian; corresponds to the 0 index in Jacobian and/or points container. Default: 0. \param endCell [in] - first cell index in cellWorkset that we do not process; endCell - startCell must equal the extent of the Jacobian container in dimension 0. Default: -1, a special value that indicates the extent of the cellWorkset should be used. */ - template static void - setJacobian( Kokkos::DynRankView jacobian, - const Kokkos::DynRankView points, - const WorksetType worksetCell, + setJacobian( JacobianViewType jacobian, + const PointViewType points, + const WorksetType worksetCell, const Teuchos::RCP basis, const int startCell=0, const int endCell=-1); @@ -267,12 +267,12 @@ namespace Intrepid2 { \param startCell [in] - first cell index in cellWorkset for which we should compute the Jacobian; corresponds to the 0 index in Jacobian and/or points container. Default: 0. \param endCell [in] - first cell index in cellWorkset that we do not process; endCell - startCell must equal the extent of the Jacobian container in dimension 0. Default: -1, a special value that indicates the extent of the cellWorkset should be used. */ - template static void - setJacobian( Kokkos::DynRankView jacobian, - const WorksetType worksetCell, + setJacobian( JacobianViewType jacobian, + const WorksetType worksetCell, const BasisGradientsType gradients, const int startCell=0, const int endCell=-1); @@ -310,15 +310,15 @@ namespace Intrepid2 { \param cellTopo [in] - cell topology of the cells stored in \c cellWorkset */ - template + template static void - setJacobian( Kokkos::DynRankView jacobian, - const Kokkos::DynRankView points, - const Kokkos::DynRankView worksetCell, + setJacobian( JacobianViewType jacobian, + const PointViewType points, + const WorksetCellViewType worksetCell, const shards::CellTopology cellTopo ) { - using nonConstPointValueType = std::remove_const_t; + using nonConstPointValueType = typename PointViewType::non_const_value_type; auto basis = createHGradBasis(cellTopo); setJacobian(jacobian, points, @@ -336,11 +336,11 @@ namespace Intrepid2 { \param jacobianInv [out] - rank-4 array with dimensions (C,P,D,D) with the inverse Jacobians \param jacobian [in] - rank-4 array with dimensions (C,P,D,D) with the Jacobians */ - template + template static void - setJacobianInv( Kokkos::DynRankView jacobianInv, - const Kokkos::DynRankView jacobian ); + setJacobianInv( JacobianInvViewType jacobianInv, + const JacobianViewType jacobian ); /** \brief Computes the determinant of the Jacobian matrix \e DF of the reference-to-physical frame map \e F. @@ -352,11 +352,11 @@ namespace Intrepid2 { \param jacobianDet [out] - rank-2 array with dimensions (C,P) with Jacobian determinants \param jacobian [in] - rank-4 array with dimensions (C,P,D,D) with the Jacobians */ - template + template static void - setJacobianDet( Kokkos::DynRankView jacobianDet, - const Kokkos::DynRankView jacobian ); + setJacobianDet( JacobianDetViewType jacobianDet, + const JacobianViewType jacobian ); /** \brief Allocates and returns a Data container suitable for storing determinants corresponding to the Jacobians in the Data container provided @@ -507,9 +507,9 @@ namespace Intrepid2 { \remark When \c subcellDim = dimension of the \c parentCell this method returns the Cartesian coordinates of the nodes of the reference cell itself. Note that this requires \c subcellOrd=0. */ - template + template static void - getReferenceSubcellNodes( Kokkos::DynRankView subcellNodes, + getReferenceSubcellNodes( SubcellNodeViewType subcellNodes, const ordinal_type subcellDim, const ordinal_type subcellOrd, const shards::CellTopology parentCell ); @@ -539,11 +539,11 @@ namespace Intrepid2 { \param edgeOrd [in] - ordinal of the edge whose tangent is computed \param parentCell [in] - cell topology of the parent reference cell */ - template + template static void - getReferenceEdgeTangent( Kokkos::DynRankView refEdgeTangent, - const ordinal_type edgeOrd, - const shards::CellTopology parentCell ); + getReferenceEdgeTangent( RefEdgeTangentViewType refEdgeTangent, + const ordinal_type edgeOrd, + const shards::CellTopology parentCell ); /** \brief Computes pairs of constant tangent vectors to faces of a 3D reference cells. @@ -581,10 +581,10 @@ namespace Intrepid2 { \param faceOrd [in] - ordinal of the face whose tangents are computed \param parentCell [in] - cell topology of the parent 3D reference cell */ - template + template static void - getReferenceFaceTangents( Kokkos::DynRankView refFaceTanU, - Kokkos::DynRankView refFaceTanV, + getReferenceFaceTangents( RefFaceTanViewType refFaceTanU, + RefFaceTanViewType refFaceTanV, const ordinal_type faceOrd, const shards::CellTopology parentCell ); @@ -650,11 +650,11 @@ namespace Intrepid2 { \param sideOrd [in] - ordinal of the side whose normal is computed \param parentCell [in] - cell topology of the parent reference cell */ - template + template static void - getReferenceSideNormal( Kokkos::DynRankView refSideNormal, - const ordinal_type sideOrd, - const shards::CellTopology parentCell ); + getReferenceSideNormal( RefSideNormalViewType refSideNormal, + const ordinal_type sideOrd, + const shards::CellTopology parentCell ); /** \brief Computes constant normal vectors to faces of 3D reference cell. @@ -694,11 +694,11 @@ namespace Intrepid2 { \param faceOrd [in] - ordinal of the face whose normal is computed \param parentCell [in] - cell topology of the parent reference cell */ - template + template static void - getReferenceFaceNormal( Kokkos::DynRankView refFaceNormal, - const ordinal_type faceOrd, - const shards::CellTopology parentCell ); + getReferenceFaceNormal( RefFaceNormalViewType refFaceNormal, + const ordinal_type faceOrd, + const shards::CellTopology parentCell ); /** \brief Computes non-normalized tangent vectors to physical edges in an edge workset \f$\{\mathcal{E}_{c,i}\}_{c=0}^{N}\f$; (see \ref sec_cell_topology_subcell_wset for definition of edge worksets). @@ -1028,15 +1028,15 @@ namespace Intrepid2 { \param basis [in] - pointer to HGrad basis used in reference-to-physical cell mapping */ - template static void - mapToPhysicalFrame( Kokkos::DynRankView physPoints, - const Kokkos::DynRankView refPoints, - const WorksetType worksetCell, - const HGradBasisPtrType basis ); + mapToPhysicalFrame( PhysPointValueType physPoints, + const RefPointValueType refPoints, + const WorksetType worksetCell, + const HGradBasisPtrType basis ); /** \brief Computes \e F, the reference-to-physical frame map. @@ -1078,15 +1078,15 @@ namespace Intrepid2 { \param cellTopo [in] - cell topology of the cells stored in \c cellWorkset */ - template + template static void - mapToPhysicalFrame( Kokkos::DynRankView physPoints, - const Kokkos::DynRankView refPoints, - const Kokkos::DynRankView worksetCell, + mapToPhysicalFrame( PhysPointViewType physPoints, + const RefPointViewType refPoints, + const WorksetCellViewType worksetCell, const shards::CellTopology cellTopo ) { - using nonConstRefPointValueType = std::remove_const_t; + using nonConstRefPointValueType = typename RefPointViewType::non_const_value_type; auto basis = createHGradBasis(cellTopo); mapToPhysicalFrame(physPoints, refPoints, diff --git a/packages/intrepid2/src/Cell/Intrepid2_CellToolsDefJacobian.hpp b/packages/intrepid2/src/Cell/Intrepid2_CellToolsDefJacobian.hpp index d51bb30dc9c2..070349c77f9d 100644 --- a/packages/intrepid2/src/Cell/Intrepid2_CellToolsDefJacobian.hpp +++ b/packages/intrepid2/src/Cell/Intrepid2_CellToolsDefJacobian.hpp @@ -95,7 +95,7 @@ namespace Intrepid2 { const ordinal_type dim = _jacobian.extent(2); // dim2 and dim3 should match - const ordinal_type gradRank = _basisGrads.rank(); + const ordinal_type gradRank = rank(_basisGrads); if ( gradRank == 3) { const ordinal_type cardinality = _basisGrads.extent(0); @@ -796,13 +796,13 @@ namespace Intrepid2 { } template - template void CellTools:: - setJacobian( Kokkos::DynRankView jacobian, - const WorksetType worksetCell, + setJacobian( JacobianViewType jacobian, + const WorksetType worksetCell, const BasisGradientsType gradients, const int startCell, const int endCell) { constexpr bool is_accessible = @@ -810,7 +810,6 @@ namespace Intrepid2 { typename decltype(jacobian)::memory_space>::accessible; static_assert(is_accessible, "CellTools::setJacobian(..): output view's memory space is not compatible with DeviceType"); - using JacobianViewType = Kokkos::DynRankView; using FunctorType = FunctorCellTools::F_setJacobian ; // resolve the -1 default argument for endCell into the true end cell index @@ -824,15 +823,15 @@ namespace Intrepid2 { } template - template void CellTools:: - setJacobian( Kokkos::DynRankView jacobian, - const Kokkos::DynRankView points, - const WorksetType worksetCell, + setJacobian( JacobianViewType jacobian, + const PointViewType points, + const WorksetType worksetCell, const Teuchos::RCP basis, const int startCell, const int endCell) { constexpr bool are_accessible = @@ -888,12 +887,12 @@ namespace Intrepid2 { } template - template + template void CellTools:: - setJacobianInv( Kokkos::DynRankView jacobianInv, - const Kokkos::DynRankView jacobian ) { + setJacobianInv( JacobianInvViewType jacobianInv, + const JacobianViewType jacobian ) { #ifdef HAVE_INTREPID2_DEBUG CellTools_setJacobianInvArgs(jacobianInv, jacobian); #endif @@ -901,12 +900,12 @@ namespace Intrepid2 { } template - template + template void CellTools:: - setJacobianDet( Kokkos::DynRankView jacobianDet, - const Kokkos::DynRankView jacobian ) { + setJacobianDet( JacobianDetViewType jacobianDet, + const JacobianViewType jacobian ) { #ifdef HAVE_INTREPID2_DEBUG CellTools_setJacobianDetArgs(jacobianDet, jacobian); #endif diff --git a/packages/intrepid2/src/Cell/Intrepid2_CellToolsDefNodeInfo.hpp b/packages/intrepid2/src/Cell/Intrepid2_CellToolsDefNodeInfo.hpp index ff5ff3f65adb..c640e30a717d 100644 --- a/packages/intrepid2/src/Cell/Intrepid2_CellToolsDefNodeInfo.hpp +++ b/packages/intrepid2/src/Cell/Intrepid2_CellToolsDefNodeInfo.hpp @@ -72,7 +72,7 @@ namespace Intrepid2 { INTREPID2_TEST_FOR_EXCEPTION( !hasReferenceCell(cell), std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::getReferenceCellCenter): the specified cell topology does not have a reference cell." ); - INTREPID2_TEST_FOR_EXCEPTION( cellCenter.rank() != 1, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(cellCenter) != 1, std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::getReferenceCellCenter): cellCenter must have rank 1." ); INTREPID2_TEST_FOR_EXCEPTION( cellCenter.extent(0) < cell.getDimension(), std::invalid_argument, @@ -108,7 +108,7 @@ namespace Intrepid2 { INTREPID2_TEST_FOR_EXCEPTION( (vertexOrd < 0) || vertexOrd > static_cast(cell.getVertexCount()), std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::getReferenceVertex): invalid node ordinal for the specified cell topology." ); - INTREPID2_TEST_FOR_EXCEPTION( cellVertex.rank() != 1, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(cellVertex) != 1, std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::getReferenceNode): cellNodes must have rank 1." ); INTREPID2_TEST_FOR_EXCEPTION( cellVertex.extent(0) < cell.getDimension(), std::invalid_argument, @@ -148,7 +148,7 @@ namespace Intrepid2 { ">>> ERROR (Intrepid2::CellTools::getReferenceSubcellVertices): subcell ordinal cannot exceed subcell count." ); // Verify subcellVertices rank and dimensions - INTREPID2_TEST_FOR_EXCEPTION( subcellVertices.rank() != 2, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(subcellVertices) != 2, std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::getReferenceSubcellVertices): subcellVertieces must have rank 2." ); // need to match to node count as it invokes getReferenceSubcellNodes @@ -176,7 +176,7 @@ namespace Intrepid2 { INTREPID2_TEST_FOR_EXCEPTION( nodeOrd >= static_cast(cell.getNodeCount()), std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::getReferenceNode): invalid node ordinal for the specified cell topology." ); - INTREPID2_TEST_FOR_EXCEPTION( cellNode.rank() != 1, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(cellNode) != 1, std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::getReferenceNode): cellNode must have rank 1." ); INTREPID2_TEST_FOR_EXCEPTION( cellNode.extent(0) < cell.getDimension(), std::invalid_argument, @@ -196,10 +196,10 @@ namespace Intrepid2 { } template - template + template void CellTools:: - getReferenceSubcellNodes( Kokkos::DynRankView subcellNodes, + getReferenceSubcellNodes( SubcellNodeViewType subcellNodes, const ordinal_type subcellDim, const ordinal_type subcellOrd, const shards::CellTopology parentCell ) { @@ -214,7 +214,7 @@ namespace Intrepid2 { ">>> ERROR (Intrepid2::CellTools::getReferenceSubcellNodes): subcell ordinal out of range."); // Verify subcellNodes rank and dimensions - INTREPID2_TEST_FOR_EXCEPTION( subcellNodes.rank() != 2, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(subcellNodes) != 2, std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::getReferenceSubcellNodes): subcellNodes must have rank 2."); INTREPID2_TEST_FOR_EXCEPTION( subcellNodes.extent(0) != parentCell.getNodeCount(subcellDim, subcellOrd), std::invalid_argument, @@ -238,18 +238,18 @@ namespace Intrepid2 { } template - template + template void CellTools:: - getReferenceEdgeTangent( Kokkos::DynRankView refEdgeTangent, - const ordinal_type edgeOrd, - const shards::CellTopology parentCell ) { + getReferenceEdgeTangent( RefEdgeTangentViewType refEdgeTangent, + const ordinal_type edgeOrd, + const shards::CellTopology parentCell ) { #ifdef HAVE_INTREPID2_DEBUG INTREPID2_TEST_FOR_EXCEPTION( parentCell.getDimension() != 2 && parentCell.getDimension() != 3, std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::getReferenceEdgeTangent): two or three-dimensional parent cell required"); - INTREPID2_TEST_FOR_EXCEPTION( refEdgeTangent.rank() != 1, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(refEdgeTangent) != 1, std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::getReferenceEdgeTangent): rank = 1 required for output arrays"); INTREPID2_TEST_FOR_EXCEPTION( refEdgeTangent.extent(0) != parentCell.getDimension(), std::invalid_argument, @@ -276,11 +276,11 @@ namespace Intrepid2 { template - template + template void CellTools:: - getReferenceFaceTangents( Kokkos::DynRankView refFaceTanU, - Kokkos::DynRankView refFaceTanV, + getReferenceFaceTangents( RefFaceTanViewType refFaceTanU, + RefFaceTanViewType refFaceTanV, const ordinal_type faceOrd, const shards::CellTopology parentCell ) { #ifdef HAVE_INTREPID2_DEBUG @@ -290,7 +290,7 @@ namespace Intrepid2 { INTREPID2_TEST_FOR_EXCEPTION( faceOrd < 0 || faceOrd >= static_cast(parentCell.getSubcellCount(2)), std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::getReferenceFaceTangents): face ordinal out of bounds"); - INTREPID2_TEST_FOR_EXCEPTION( refFaceTanU.rank() != 1 || refFaceTanV.rank() != 1, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(refFaceTanU) != 1 || rank(refFaceTanV) != 1, std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::getReferenceFaceTangents): rank = 1 required for output arrays"); INTREPID2_TEST_FOR_EXCEPTION( refFaceTanU.extent(0) != parentCell.getDimension(), std::invalid_argument, @@ -321,12 +321,13 @@ namespace Intrepid2 { } template - template + template void CellTools:: - getReferenceSideNormal( Kokkos::DynRankView refSideNormal, - const ordinal_type sideOrd, - const shards::CellTopology parentCell ) { + getReferenceSideNormal( RefSideNormalViewType refSideNormal, + const ordinal_type sideOrd, + const shards::CellTopology parentCell ) { + using refSideNormalValueType = typename RefSideNormalViewType::non_const_value_type; #ifdef HAVE_INTREPID2_DEBUG INTREPID2_TEST_FOR_EXCEPTION( parentCell.getDimension() != 2 && parentCell.getDimension() != 3, std::invalid_argument, @@ -361,12 +362,12 @@ namespace Intrepid2 { template - template + template void CellTools:: - getReferenceFaceNormal( Kokkos::DynRankView refFaceNormal, - const ordinal_type faceOrd, - const shards::CellTopology parentCell ) { + getReferenceFaceNormal( RefFaceNormalViewType refFaceNormal, + const ordinal_type faceOrd, + const shards::CellTopology parentCell ) { #ifdef HAVE_INTREPID2_DEBUG INTREPID2_TEST_FOR_EXCEPTION( parentCell.getDimension() != 3, std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::getReferenceFaceNormal): three-dimensional parent cell required"); @@ -374,7 +375,7 @@ namespace Intrepid2 { INTREPID2_TEST_FOR_EXCEPTION( faceOrd < 0 || faceOrd >= static_cast(parentCell.getSubcellCount(2)), std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::getReferenceFaceNormal): face ordinal out of bounds"); - INTREPID2_TEST_FOR_EXCEPTION( refFaceNormal.rank() != 1, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(refFaceNormal) != 1, std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::getReferenceFaceNormal): rank = 1 required for output array"); INTREPID2_TEST_FOR_EXCEPTION( refFaceNormal.extent(0) != parentCell.getDimension(), std::invalid_argument, @@ -411,14 +412,14 @@ namespace Intrepid2 { ">>> ERROR (Intrepid2::CellTools::getPhysicalEdgeTangents): 2D or 3D parent cell required." ); // (1) edgeTangents is rank-3 (C,P,D) and D=2, or 3 is required - INTREPID2_TEST_FOR_EXCEPTION( edgeTangents.rank() != 3, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(edgeTangents) != 3, std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::getPhysicalEdgeTangents): edgeTangents requires rank 3." ); INTREPID2_TEST_FOR_EXCEPTION( edgeTangents.extent(2) != 2 && edgeTangents.extent(2) != 3, std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::getPhysicalEdgeTangents): edgeTangents dimension(2) must be 2 or 3." ); // (2) worksetJacobians in rank-4 (C,P,D,D) and D=2, or 3 is required - INTREPID2_TEST_FOR_EXCEPTION( worksetJacobians.rank() != 4, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(worksetJacobians) != 4, std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::getPhysicalEdgeTangents): worksetJacobians requires rank 4." ); INTREPID2_TEST_FOR_EXCEPTION( worksetJacobians.extent(2) != 2 && worksetJacobians.extent(2) != 3, std::invalid_argument, @@ -493,7 +494,7 @@ namespace Intrepid2 { ">>> ERROR (Intrepid2::CellTools::getPhysicalEdgeTangents): 2D or 3D parent cell required." ); // (1) edgeTangents is rank-3 (C,P,D) and D=2, or 3 is required - INTREPID2_TEST_FOR_EXCEPTION( edgeTangents.rank() != 3, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(edgeTangents) != 3, std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::getPhysicalEdgeTangents): edgeTangents requires rank 3." ); INTREPID2_TEST_FOR_EXCEPTION( edgeTangents.extent(2) != 2 && edgeTangents.extent(2) != 3, std::invalid_argument, @@ -503,7 +504,7 @@ namespace Intrepid2 { ">>> ERROR (Intrepid2::CellTools::getPhysicalEdgeTangents): worksetEdgeOrds extent 0 should match that of edgeTangents." ); // (2) worksetJacobians in rank-4 (C,P,D,D) and D=2, or 3 is required - INTREPID2_TEST_FOR_EXCEPTION( worksetJacobians.rank() != 4, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(worksetJacobians) != 4, std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::getPhysicalEdgeTangents): worksetJacobians requires rank 4." ); INTREPID2_TEST_FOR_EXCEPTION( worksetJacobians.extent(2) != 2 && worksetJacobians.extent(2) != 3, std::invalid_argument, @@ -557,8 +558,8 @@ namespace Intrepid2 { ">>> ERROR (Intrepid2::CellTools::getPhysicalFaceTangents): three-dimensional parent cell required"); // (1) faceTanU and faceTanV are rank-3 (C,P,D) and D=3 is required - INTREPID2_TEST_FOR_EXCEPTION( faceTanU.rank() != 3 || - faceTanV.rank() != 3, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(faceTanU) != 3 || + rank(faceTanV) != 3, std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::getPhysicalFaceTangents): faceTan U,V must have rank 3." ); INTREPID2_TEST_FOR_EXCEPTION( faceTanU.extent(2) != 3 || @@ -571,7 +572,7 @@ namespace Intrepid2 { } // (3) worksetJacobians in rank-4 (C,P,D,D) and D=3 is required - INTREPID2_TEST_FOR_EXCEPTION( worksetJacobians.rank() != 4, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(worksetJacobians) != 4, std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::getPhysicalFaceTangents): worksetJacobians must have rank 4." ); INTREPID2_TEST_FOR_EXCEPTION( worksetJacobians.extent(2) != 3, std::invalid_argument, @@ -653,8 +654,8 @@ namespace Intrepid2 { ">>> ERROR (Intrepid2::CellTools::getPhysicalFaceTangents): three-dimensional parent cell required"); // (1) faceTanU and faceTanV are rank-3 (C,P,D) and D=3 is required - INTREPID2_TEST_FOR_EXCEPTION( faceTanU.rank() != 3 || - faceTanV.rank() != 3, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(faceTanU) != 3 || + rank(faceTanV) != 3, std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::getPhysicalFaceTangents): faceTan U,V must have rank 3." ); INTREPID2_TEST_FOR_EXCEPTION( faceTanU.extent(2) != 3 || @@ -671,7 +672,7 @@ namespace Intrepid2 { // (3) worksetJacobians in rank-4 (C,P,D,D) and D=3 is required - INTREPID2_TEST_FOR_EXCEPTION( worksetJacobians.rank() != 4, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(worksetJacobians) != 4, std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::getPhysicalFaceTangents): worksetJacobians must have rank 4." ); INTREPID2_TEST_FOR_EXCEPTION( worksetJacobians.extent(2) != 3, std::invalid_argument, @@ -851,13 +852,13 @@ namespace Intrepid2 { ">>> ERROR (Intrepid2::CellTools::getPhysicalFaceNormals): three-dimensional parent cell required." ); // (1) faceNormals is rank-3 (C,P,D) and D=3 is required - INTREPID2_TEST_FOR_EXCEPTION( faceNormals.rank() != 3, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(faceNormals) != 3, std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::getPhysicalFaceNormals): faceNormals must have a rank 3." ); INTREPID2_TEST_FOR_EXCEPTION( faceNormals.extent(2) != 3, std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::getPhysicalFaceNormals): faceNormals dimension (2) must be 3." ); // (3) worksetJacobians in rank-4 (C,P,D,D) and D=3 is required - INTREPID2_TEST_FOR_EXCEPTION( worksetJacobians.rank() != 4, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(worksetJacobians) != 4, std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::getPhysicalFaceNormals): worksetJacobians must have a rank 4." ); INTREPID2_TEST_FOR_EXCEPTION( worksetJacobians.extent(2) != 3, std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::getPhysicalFaceNormals): worksetJacobians dimension (2) must be 3." ); @@ -913,7 +914,7 @@ namespace Intrepid2 { ">>> ERROR (Intrepid2::CellTools::getPhysicalFaceNormals): three-dimensional parent cell required." ); // (1) faceNormals is rank-3 (C,P,D) and D=3 is required - INTREPID2_TEST_FOR_EXCEPTION( faceNormals.rank() != 3, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(faceNormals) != 3, std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::getPhysicalFaceNormals): faceNormals must have a rank 3." ); INTREPID2_TEST_FOR_EXCEPTION( faceNormals.extent(2) != 3, std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::getPhysicalFaceNormals): faceNormals dimension (2) must be 3." ); @@ -921,7 +922,7 @@ namespace Intrepid2 { ">>> ERROR (Intrepid2::CellTools::getPhysicalFaceNormals): worksetFaceOrds extent 0 should match that of faceNormals." ); // (3) worksetJacobians in rank-4 (C,P,D,D) and D=3 is required - INTREPID2_TEST_FOR_EXCEPTION( worksetJacobians.rank() != 4, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(worksetJacobians) != 4, std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::getPhysicalFaceNormals): worksetJacobians must have a rank 4." ); INTREPID2_TEST_FOR_EXCEPTION( worksetJacobians.extent(2) != 3, std::invalid_argument, ">>> ERROR (Intrepid2::CellTools::getPhysicalFaceNormals): worksetJacobians dimension (2) must be 3." ); diff --git a/packages/intrepid2/src/Cell/Intrepid2_CellToolsDefRefToPhys.hpp b/packages/intrepid2/src/Cell/Intrepid2_CellToolsDefRefToPhys.hpp index 8132acaf175d..71ee942beb06 100644 --- a/packages/intrepid2/src/Cell/Intrepid2_CellToolsDefRefToPhys.hpp +++ b/packages/intrepid2/src/Cell/Intrepid2_CellToolsDefRefToPhys.hpp @@ -89,7 +89,7 @@ namespace Intrepid2 { iter ); auto phys = Kokkos::subdynrankview( _physPoints, cell, pt, Kokkos::ALL()); - const auto valRank = _basisVals.rank(); + const auto valRank = rank(_basisVals); const auto val = ( valRank == 2 ? Kokkos::subdynrankview( _basisVals, Kokkos::ALL(), pt) : Kokkos::subdynrankview( _basisVals, cell, Kokkos::ALL(), pt)); @@ -162,15 +162,15 @@ namespace Intrepid2 { } template - template void CellTools:: - mapToPhysicalFrame( Kokkos::DynRankView physPoints, - const Kokkos::DynRankView refPoints, - const WorksetType worksetCell, + mapToPhysicalFrame( PhysPointViewType physPoints, + const RefPointViewType refPoints, + const WorksetType worksetCell, const HGradBasisPtrType basis ) { #ifdef HAVE_INTREPID2_DEBUG CellTools_mapToPhysicalFrameArgs( physPoints, refPoints, worksetCell, basis->getBaseCellTopology() ); @@ -192,7 +192,6 @@ namespace Intrepid2 { const auto basisCardinality = basis->getCardinality(); auto vcprop = Kokkos::common_view_alloc_prop(physPoints); - using physPointViewType =Kokkos::DynRankView; using valViewType = Kokkos::DynRankViewgetDummyOutputValue()),DeviceType>; valViewType vals; @@ -218,7 +217,7 @@ namespace Intrepid2 { } } - using FunctorType = FunctorCellTools::F_mapToPhysicalFrame; + using FunctorType = FunctorCellTools::F_mapToPhysicalFrame; const auto loopSize = physPoints.extent(0)*physPoints.extent(1); Kokkos::RangePolicy > policy(0, loopSize); diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_Basis.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_Basis.hpp index d5e9de0b5126..0f91ad230c7b 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_Basis.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_Basis.hpp @@ -398,7 +398,7 @@ using HostBasisPtr = BasisPtr data(dataView); - bool useVectorData = (dataView.rank() == 3); + bool useVectorData = (rank(dataView) == 3); if (useVectorData) { diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_BasisDef.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_BasisDef.hpp index a5ed18acfa34..729a987acbec 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_BasisDef.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_BasisDef.hpp @@ -480,7 +480,7 @@ namespace Intrepid2 { const auto spaceDim = cellTopo.getDimension(); // Verify inputPoints array - INTREPID2_TEST_FOR_EXCEPTION( !(inputPoints.rank() == 2), std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( !(rank(inputPoints) == 2), std::invalid_argument, ">>> ERROR: (Intrepid2::getValues_HGRAD_Args) rank = 2 required for inputPoints array"); INTREPID2_TEST_FOR_EXCEPTION( (inputPoints.extent(0) <= 0), std::invalid_argument, @@ -513,7 +513,7 @@ namespace Intrepid2 { if(spaceDim == 1) { switch(operatorType){ case OPERATOR_VALUE: - INTREPID2_TEST_FOR_EXCEPTION( !(outputValues.rank() == 2), std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( !(rank(outputValues) == 2), std::invalid_argument, ">>> ERROR: (Intrepid2::getValues_HGRAD_Args) rank = 2 required for outputValues when operator = VALUE."); break; case OPERATOR_GRAD: @@ -529,7 +529,7 @@ namespace Intrepid2 { case OPERATOR_D8: case OPERATOR_D9: case OPERATOR_D10: - INTREPID2_TEST_FOR_EXCEPTION( !(outputValues.rank() == 3), std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( !(rank(outputValues) == 3), std::invalid_argument, ">>> ERROR: (Intrepid2::getValues_HGRAD_Args) rank = 3 required for outputValues in 1D when operator = GRAD, CURL, DIV, or Dk."); INTREPID2_TEST_FOR_EXCEPTION( !(outputValues.extent(2) == 1 ), @@ -543,13 +543,13 @@ namespace Intrepid2 { else if(spaceDim > 1) { switch(operatorType){ case OPERATOR_VALUE: - INTREPID2_TEST_FOR_EXCEPTION( !(outputValues.rank() == 2), std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( !(rank(outputValues) == 2), std::invalid_argument, ">>> ERROR: (Intrepid2::getValues_HGRAD_Args) rank = 2 required for outputValues when operator = VALUE."); break; case OPERATOR_GRAD: case OPERATOR_CURL: case OPERATOR_D1: - INTREPID2_TEST_FOR_EXCEPTION( !(outputValues.rank() == 3), std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( !(rank(outputValues) == 3), std::invalid_argument, ">>> ERROR: (Intrepid2::getValues_HGRAD_Args) rank = 3 required for outputValues in 2D and 3D when operator = GRAD, CURL (in 2D), or Dk."); INTREPID2_TEST_FOR_EXCEPTION( !(outputValues.extent(2) == spaceDim ), @@ -565,7 +565,7 @@ namespace Intrepid2 { case OPERATOR_D8: case OPERATOR_D9: case OPERATOR_D10: - INTREPID2_TEST_FOR_EXCEPTION( !(outputValues.rank() == 3), std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( !(rank(outputValues) == 3), std::invalid_argument, ">>> ERROR: (Intrepid2::getValues_HGRAD_Args) rank = 3 required for outputValues in 2D and 3D when operator = GRAD, CURL (in 2D), or Dk."); INTREPID2_TEST_FOR_EXCEPTION( !(static_cast(outputValues.extent(2)) == getDkCardinality(operatorType, spaceDim)), @@ -606,7 +606,7 @@ namespace Intrepid2 { // Verify inputPoints array - INTREPID2_TEST_FOR_EXCEPTION( !(inputPoints.rank() == 2), std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( !(rank(inputPoints) == 2), std::invalid_argument, ">>> ERROR: (Intrepid2::getValues_HCURL_Args) rank = 2 required for inputPoints array"); INTREPID2_TEST_FOR_EXCEPTION( (inputPoints.extent(0) <= 0), std::invalid_argument, ">>> ERROR (Intrepid2::getValues_HCURL_Args): dim 0 (number of points) > 0 required for inputPoints array"); @@ -630,7 +630,7 @@ namespace Intrepid2 { switch(operatorType) { case OPERATOR_VALUE: - INTREPID2_TEST_FOR_EXCEPTION( !(outputValues.rank() == 3), std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( !(rank(outputValues) == 3), std::invalid_argument, ">>> ERROR: (Intrepid2::getValues_HCURL_Args) rank = 3 required for outputValues when operator is VALUE"); INTREPID2_TEST_FOR_EXCEPTION( !(outputValues.extent(2) == spaceDim ), std::invalid_argument, @@ -641,7 +641,7 @@ namespace Intrepid2 { // in 3D we need an (F,P,D) container because CURL gives a vector field: if(spaceDim == 3) { - INTREPID2_TEST_FOR_EXCEPTION( !(outputValues.rank() == 3 ) , + INTREPID2_TEST_FOR_EXCEPTION( !(rank(outputValues) == 3 ) , std::invalid_argument, ">>> ERROR: (Intrepid2::getValues_HCURL_Args) rank = 3 required for outputValues in 3D when operator is CURL"); INTREPID2_TEST_FOR_EXCEPTION( !(outputValues.extent(2) == spaceDim), @@ -650,7 +650,7 @@ namespace Intrepid2 { } // In 2D we need an (F,P) container because CURL gives a scalar field else if(spaceDim == 2) { - INTREPID2_TEST_FOR_EXCEPTION( !(outputValues.rank() == 2 ) , + INTREPID2_TEST_FOR_EXCEPTION( !(rank(outputValues) == 2 ) , std::invalid_argument, ">>> ERROR: (Intrepid2::getValues_HCURL_Args) rank = 2 required for outputValues in 2D when operator is CURL"); } @@ -685,7 +685,7 @@ namespace Intrepid2 { const auto spaceDim = cellTopo.getDimension(); // Verify inputPoints array - INTREPID2_TEST_FOR_EXCEPTION( !(inputPoints.rank() == 2), std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( !(rank(inputPoints) == 2), std::invalid_argument, ">>> ERROR: (Intrepid2::getValues_HDIV_Args) rank = 2 required for inputPoints array"); INTREPID2_TEST_FOR_EXCEPTION( (inputPoints.extent(0) <= 0), std::invalid_argument, ">>> ERROR (Intrepid2::getValues_HDIV_Args): dim 0 (number of points) > 0 required for inputPoints array"); @@ -708,7 +708,7 @@ namespace Intrepid2 { // Check rank of outputValues switch(operatorType) { case OPERATOR_VALUE: - INTREPID2_TEST_FOR_EXCEPTION( !(outputValues.rank() == 3), std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( !(rank(outputValues) == 3), std::invalid_argument, ">>> ERROR: (Intrepid2::getValues_HDIV_Args) rank = 3 required for outputValues when operator is VALUE."); INTREPID2_TEST_FOR_EXCEPTION( !(outputValues.extent(2) == spaceDim ), @@ -716,7 +716,7 @@ namespace Intrepid2 { ">>> ERROR: (Intrepid2::getValues_HDIV_Args) dim 2 of outputValues must equal cell dimension for operator VALUE."); break; case OPERATOR_DIV: - INTREPID2_TEST_FOR_EXCEPTION( !(outputValues.rank() == 2), std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( !(rank(outputValues) == 2), std::invalid_argument, ">>> ERROR: (Intrepid2::getValues_HDIV_Args) rank = 2 required for outputValues when operator is DIV."); break; @@ -745,7 +745,7 @@ namespace Intrepid2 { const auto spaceDim = cellTopo.getDimension(); // Verify inputPoints array - INTREPID2_TEST_FOR_EXCEPTION( !(inputPoints.rank() == 2), std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( !(rank(inputPoints) == 2), std::invalid_argument, ">>> ERROR: (Intrepid2::getValues_HGRAD_Args) rank = 2 required for inputPoints array"); INTREPID2_TEST_FOR_EXCEPTION( (inputPoints.extent(0) <= 0), std::invalid_argument, @@ -778,7 +778,7 @@ namespace Intrepid2 { if(spaceDim == 1) { switch(operatorType){ case OPERATOR_VALUE: - INTREPID2_TEST_FOR_EXCEPTION( !(outputValues.rank() == 2), std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( !(rank(outputValues) == 2), std::invalid_argument, ">>> ERROR: (Intrepid2::getValues_HGRAD_Args) rank = 2 required for outputValues when operator = VALUE."); break; case OPERATOR_GRAD: @@ -794,7 +794,7 @@ namespace Intrepid2 { case OPERATOR_D8: case OPERATOR_D9: case OPERATOR_D10: - INTREPID2_TEST_FOR_EXCEPTION( !(outputValues.rank() == 3), std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( !(rank(outputValues) == 3), std::invalid_argument, ">>> ERROR: (Intrepid2::getValues_HGRAD_Args) rank = 3 required for outputValues in 1D when operator = GRAD, CURL, DIV, or Dk."); INTREPID2_TEST_FOR_EXCEPTION( !(outputValues.extent(2) == 1 ), @@ -808,13 +808,13 @@ namespace Intrepid2 { else if(spaceDim > 1) { switch(operatorType){ case OPERATOR_VALUE: - INTREPID2_TEST_FOR_EXCEPTION( !(outputValues.rank() == 2), std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( !(rank(outputValues) == 2), std::invalid_argument, ">>> ERROR: (Intrepid2::getValues_HGRAD_Args) rank = 2 required for outputValues when operator = VALUE."); break; case OPERATOR_GRAD: case OPERATOR_CURL: case OPERATOR_D1: - INTREPID2_TEST_FOR_EXCEPTION( !(outputValues.rank() == 3), std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( !(rank(outputValues) == 3), std::invalid_argument, ">>> ERROR: (Intrepid2::getValues_HGRAD_Args) rank = 3 required for outputValues in 2D and 3D when operator = GRAD, CURL (in 2D), or Dk."); INTREPID2_TEST_FOR_EXCEPTION( !(outputValues.extent(2) == spaceDim ), @@ -830,7 +830,7 @@ namespace Intrepid2 { case OPERATOR_D8: case OPERATOR_D9: case OPERATOR_D10: - INTREPID2_TEST_FOR_EXCEPTION( !(outputValues.rank() == 3), std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( !(rank(outputValues) == 3), std::invalid_argument, ">>> ERROR: (Intrepid2::getValues_HGRAD_Args) rank = 3 required for outputValues in 2D and 3D when operator = GRAD, CURL (in 2D), or Dk."); INTREPID2_TEST_FOR_EXCEPTION( !(static_cast(outputValues.extent(2)) == getDkCardinality(operatorType, spaceDim)), diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HCURL_TET_I1_FEM.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HCURL_TET_I1_FEM.hpp index 7b5f76c97b58..dacd5dba128b 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HCURL_TET_I1_FEM.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HCURL_TET_I1_FEM.hpp @@ -222,7 +222,7 @@ namespace Intrepid2 { getDofCoords( ScalarViewType dofCoords ) const override { #ifdef HAVE_INTREPID2_DEBUG // Verify rank of output array. - INTREPID2_TEST_FOR_EXCEPTION( dofCoords.rank() != 2, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(dofCoords) != 2, std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HCURL_TET_I1_FEM::getDofCoords) rank = 2 required for dofCoords array"); // Verify 0th dimension of output array. INTREPID2_TEST_FOR_EXCEPTION( static_cast(dofCoords.extent(0)) != this->basisCardinality_, std::invalid_argument, @@ -240,7 +240,7 @@ namespace Intrepid2 { getDofCoeffs( ScalarViewType dofCoeffs ) const override { #ifdef HAVE_INTREPID2_DEBUG // Verify rank of output array. - INTREPID2_TEST_FOR_EXCEPTION( dofCoeffs.rank() != 2, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(dofCoeffs) != 2, std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HCURL_TET_I1_FEM::getDofCoeffs) rank = 2 required for dofCoeffs array"); // Verify 0th dimension of output array. INTREPID2_TEST_FOR_EXCEPTION( static_cast(dofCoeffs.extent(0)) != this->getCardinality(), std::invalid_argument, diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HCURL_TET_In_FEM.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HCURL_TET_In_FEM.hpp index 4567f6a85d68..73bab0a66ed8 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HCURL_TET_In_FEM.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HCURL_TET_In_FEM.hpp @@ -255,7 +255,7 @@ class Basis_HCURL_TET_In_FEM getDofCoords( ScalarViewType dofCoords ) const override { #ifdef HAVE_INTREPID2_DEBUG // Verify rank of output array. - INTREPID2_TEST_FOR_EXCEPTION( dofCoords.rank() != 2, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(dofCoords) != 2, std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HCURL_TET_In_FEM::getDofCoords) rank = 2 required for dofCoords array"); // Verify 0th dimension of output array. INTREPID2_TEST_FOR_EXCEPTION( static_cast(dofCoords.extent(0)) != this->getCardinality(), std::invalid_argument, @@ -272,7 +272,7 @@ class Basis_HCURL_TET_In_FEM getDofCoeffs( ScalarViewType dofCoeffs ) const override { #ifdef HAVE_INTREPID2_DEBUG // Verify rank of output array. - INTREPID2_TEST_FOR_EXCEPTION( dofCoeffs.rank() != 2, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(dofCoeffs) != 2, std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HCURL_TET_In_FEM::getDofCoeffs) rank = 2 required for dofCoeffs array"); // Verify 0th dimension of output array. INTREPID2_TEST_FOR_EXCEPTION( static_cast(dofCoeffs.extent(0)) != this->getCardinality(), std::invalid_argument, diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HCURL_TRI_I1_FEM.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HCURL_TRI_I1_FEM.hpp index 41421828a081..d53279a4a007 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HCURL_TRI_I1_FEM.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HCURL_TRI_I1_FEM.hpp @@ -225,7 +225,7 @@ namespace Intrepid2 { getDofCoords( ScalarViewType dofCoords ) const override { #ifdef HAVE_INTREPID2_DEBUG // Verify rank of output array. - INTREPID2_TEST_FOR_EXCEPTION( dofCoords.rank() != 2, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(dofCoords) != 2, std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HCURL_TRI_I1_FEM::getDofCoords) rank = 2 required for dofCoords array"); // Verify 0th dimension of output array. INTREPID2_TEST_FOR_EXCEPTION( static_cast(dofCoords.extent(0)) != this->basisCardinality_, std::invalid_argument, @@ -242,7 +242,7 @@ namespace Intrepid2 { getDofCoeffs( ScalarViewType dofCoeffs ) const override { #ifdef HAVE_INTREPID2_DEBUG // Verify rank of output array. - INTREPID2_TEST_FOR_EXCEPTION( dofCoeffs.rank() != 2, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(dofCoeffs) != 2, std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HCURL_TRI_I1_FEM::getDofCoeffs) rank = 2 required for dofCoeffs array"); // Verify 0th dimension of output array. INTREPID2_TEST_FOR_EXCEPTION( static_cast(dofCoeffs.extent(0)) != this->getCardinality(), std::invalid_argument, diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HCURL_TRI_In_FEM.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HCURL_TRI_In_FEM.hpp index 95ca4b66b220..f8c923454763 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HCURL_TRI_In_FEM.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HCURL_TRI_In_FEM.hpp @@ -247,7 +247,7 @@ class Basis_HCURL_TRI_In_FEM getDofCoords( ScalarViewType dofCoords ) const override { #ifdef HAVE_INTREPID2_DEBUG // Verify rank of output array. - INTREPID2_TEST_FOR_EXCEPTION( dofCoords.rank() != 2, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(dofCoords) != 2, std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HCURL_TRI_In_FEM::getDofCoords) rank = 2 required for dofCoords array"); // Verify 0th dimension of output array. INTREPID2_TEST_FOR_EXCEPTION( static_cast(dofCoords.extent(0)) != this->getCardinality(), std::invalid_argument, @@ -264,7 +264,7 @@ class Basis_HCURL_TRI_In_FEM getDofCoeffs( ScalarViewType dofCoeffs ) const override { #ifdef HAVE_INTREPID2_DEBUG // Verify rank of output array. - INTREPID2_TEST_FOR_EXCEPTION( dofCoeffs.rank() != 2, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(dofCoeffs) != 2, std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HCURL_TRI_In_FEM::getDofCoeffs) rank = 2 required for dofCoeffs array"); // Verify 0th dimension of output array. INTREPID2_TEST_FOR_EXCEPTION( static_cast(dofCoeffs.extent(0)) != this->getCardinality(), std::invalid_argument, diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_HEX_C1_FEM.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_HEX_C1_FEM.hpp index cd1cf5d87e3a..fa89f6638648 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_HEX_C1_FEM.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_HEX_C1_FEM.hpp @@ -215,7 +215,7 @@ namespace Intrepid2 { getDofCoords( ScalarViewType dofCoords ) const override { #ifdef HAVE_INTREPID2_DEBUG // Verify rank of output array. - INTREPID2_TEST_FOR_EXCEPTION( dofCoords.rank() != 2, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(dofCoords) != 2, std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HGRAD_HEX_C1_FEM::getDofCoords) rank = 2 required for dofCoords array"); // Verify 0th dimension of output array. INTREPID2_TEST_FOR_EXCEPTION( static_cast(dofCoords.extent(0)) != this->getCardinality(), std::invalid_argument, @@ -232,7 +232,7 @@ namespace Intrepid2 { getDofCoeffs( ScalarViewType dofCoeffs ) const override { #ifdef HAVE_INTREPID2_DEBUG // Verify rank of output array. - INTREPID2_TEST_FOR_EXCEPTION( dofCoeffs.rank() != 1, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(dofCoeffs) != 1, std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HGRAD_HEX_C1_FEM::getdofCoeffs) rank = 1 required for dofCoeffs array"); // Verify 0th dimension of output array. INTREPID2_TEST_FOR_EXCEPTION( static_cast(dofCoeffs.extent(0)) != this->getCardinality(), std::invalid_argument, diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_HEX_C2_FEM.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_HEX_C2_FEM.hpp index 42af457ed601..c47b1a81c980 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_HEX_C2_FEM.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_HEX_C2_FEM.hpp @@ -283,7 +283,7 @@ namespace Intrepid2 { getDofCoords( ScalarViewType dofCoords ) const override { #ifdef HAVE_INTREPID2_DEBUG // Verify rank of output array. - INTREPID2_TEST_FOR_EXCEPTION( dofCoords.rank() != 2, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(dofCoords) != 2, std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HGRAD_HEX_DEG2_FEM::getDofCoords) rank = 2 required for dofCoords array"); // Verify 0th dimension of output array. INTREPID2_TEST_FOR_EXCEPTION( static_cast(dofCoords.extent(0)) != this->getCardinality(), std::invalid_argument, @@ -300,7 +300,7 @@ namespace Intrepid2 { getDofCoeffs( ScalarViewType dofCoeffs ) const override { #ifdef HAVE_INTREPID2_DEBUG // Verify rank of output array. - INTREPID2_TEST_FOR_EXCEPTION( dofCoeffs.rank() != 1, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(dofCoeffs) != 1, std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HGRAD_HEX_DEG2_FEM::getdofCoeffs) rank = 1 required for dofCoeffs array"); // Verify 0th dimension of output array. INTREPID2_TEST_FOR_EXCEPTION( static_cast(dofCoeffs.extent(0)) != this->getCardinality(), std::invalid_argument, diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_HEX_Cn_FEM.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_HEX_Cn_FEM.hpp index 35910c3034ea..2693616627a4 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_HEX_Cn_FEM.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_HEX_Cn_FEM.hpp @@ -223,7 +223,7 @@ namespace Intrepid2 { getDofCoords( ScalarViewType dofCoords ) const override { #ifdef HAVE_INTREPID2_DEBUG // Verify rank of output array. - INTREPID2_TEST_FOR_EXCEPTION( dofCoords.rank() != 2, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(dofCoords) != 2, std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HGRAD_HEX_Cn_FEM::getDofCoords) rank = 2 required for dofCoords array"); // Verify 0th dimension of output array. INTREPID2_TEST_FOR_EXCEPTION( static_cast(dofCoords.extent(0)) != this->getCardinality(), std::invalid_argument, @@ -240,7 +240,7 @@ namespace Intrepid2 { getDofCoeffs( ScalarViewType dofCoeffs ) const override { #ifdef HAVE_INTREPID2_DEBUG // Verify rank of output array. - INTREPID2_TEST_FOR_EXCEPTION( dofCoeffs.rank() != 1, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(dofCoeffs) != 1, std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HGRAD_HEX_Cn_FEM::getdofCoeffs) rank = 1 required for dofCoeffs array"); // Verify 0th dimension of output array. INTREPID2_TEST_FOR_EXCEPTION( static_cast(dofCoeffs.extent(0)) != this->getCardinality(), std::invalid_argument, diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_LINE_C1_FEM.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_LINE_C1_FEM.hpp index 0a08beed11e7..837ff598524f 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_LINE_C1_FEM.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_LINE_C1_FEM.hpp @@ -199,7 +199,7 @@ namespace Intrepid2 { getDofCoords( ScalarViewType dofCoords ) const override { #ifdef HAVE_INTREPID2_DEBUG // Verify rank of output array. - INTREPID2_TEST_FOR_EXCEPTION( dofCoords.rank() != 2, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(dofCoords) != 2, std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HGRAD_LINE_C1_FEM::getDofCoords) rank = 2 required for dofCoords array"); // Verify 0th dimension of output array. INTREPID2_TEST_FOR_EXCEPTION( static_cast(dofCoords.extent(0)) != this->basisCardinality_, std::invalid_argument, @@ -216,7 +216,7 @@ namespace Intrepid2 { getDofCoeffs( ScalarViewType dofCoeffs ) const override { #ifdef HAVE_INTREPID2_DEBUG // Verify rank of output array. - INTREPID2_TEST_FOR_EXCEPTION( dofCoeffs.rank() != 1, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(dofCoeffs) != 1, std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HGRAD_LINE_C1_FEM::getdofCoeffs) rank = 1 required for dofCoeffs array"); // Verify 0th dimension of output array. INTREPID2_TEST_FOR_EXCEPTION( static_cast(dofCoeffs.extent(0)) != this->getCardinality(), std::invalid_argument, diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_LINE_C2_FEM.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_LINE_C2_FEM.hpp index 564322e19736..86fce7d58f48 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_LINE_C2_FEM.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_LINE_C2_FEM.hpp @@ -199,7 +199,7 @@ namespace Intrepid2 { getDofCoords( ScalarViewType dofCoords ) const override { #ifdef HAVE_INTREPID2_DEBUG // Verify rank of output array. - INTREPID2_TEST_FOR_EXCEPTION( dofCoords.rank() != 2, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(dofCoords) != 2, std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HGRAD_LINE_C2_FEM::getDofCoords) rank = 2 required for dofCoords array"); // Verify 0th dimension of output array. INTREPID2_TEST_FOR_EXCEPTION( static_cast(dofCoords.extent(0)) != this->basisCardinality_, std::invalid_argument, @@ -216,7 +216,7 @@ namespace Intrepid2 { getDofCoeffs( ScalarViewType dofCoeffs ) const override { #ifdef HAVE_INTREPID2_DEBUG // Verify rank of output array. - INTREPID2_TEST_FOR_EXCEPTION( dofCoeffs.rank() != 1, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(dofCoeffs) != 1, std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HGRAD_LINE_C2_FEM::getdofCoeffs) rank = 1 required for dofCoeffs array"); // Verify 0th dimension of output array. INTREPID2_TEST_FOR_EXCEPTION( static_cast(dofCoeffs.extent(0)) != this->getCardinality(), std::invalid_argument, diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_LINE_Cn_FEM.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_LINE_Cn_FEM.hpp index fa64013d2d51..242c2a241614 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_LINE_Cn_FEM.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_LINE_Cn_FEM.hpp @@ -230,7 +230,7 @@ namespace Intrepid2 { getDofCoords( ScalarViewType dofCoords ) const override { #ifdef HAVE_INTREPID2_DEBUG // Verify rank of output array. - INTREPID2_TEST_FOR_EXCEPTION( dofCoords.rank() != 2, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(dofCoords) != 2, std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HGRAD_LINE_Cn_FEM::getDofCoords) rank = 2 required for dofCoords array"); // Verify 0th dimension of output array. INTREPID2_TEST_FOR_EXCEPTION( static_cast(dofCoords.extent(0)) != this->getCardinality(), std::invalid_argument, @@ -247,7 +247,7 @@ namespace Intrepid2 { getDofCoeffs( ScalarViewType dofCoeffs ) const override { #ifdef HAVE_INTREPID2_DEBUG // Verify rank of output array. - INTREPID2_TEST_FOR_EXCEPTION( dofCoeffs.rank() != 1, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(dofCoeffs) != 1, std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HGRAD_LINE_Cn_FEM::getdofCoeffs) rank = 1 required for dofCoeffs array"); // Verify 0th dimension of output array. INTREPID2_TEST_FOR_EXCEPTION( static_cast(dofCoeffs.extent(0)) != this->getCardinality(), std::invalid_argument, diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_QUAD_C1_FEM.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_QUAD_C1_FEM.hpp index d98596896141..c074163d0f1f 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_QUAD_C1_FEM.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_QUAD_C1_FEM.hpp @@ -205,7 +205,7 @@ namespace Intrepid2 { getDofCoords( ScalarViewType dofCoords ) const override { #ifdef HAVE_INTREPID2_DEBUG // Verify rank of output array. - INTREPID2_TEST_FOR_EXCEPTION( dofCoords.rank() != 2, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(dofCoords) != 2, std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HGRAD_QUAD_C1_FEM::getDofCoords) rank = 2 required for dofCoords array"); // Verify 0th dimension of output array. INTREPID2_TEST_FOR_EXCEPTION( static_cast(dofCoords.extent(0)) != this->getCardinality(), std::invalid_argument, @@ -222,7 +222,7 @@ namespace Intrepid2 { getDofCoeffs( ScalarViewType dofCoeffs ) const override { #ifdef HAVE_INTREPID2_DEBUG // Verify rank of output array. - INTREPID2_TEST_FOR_EXCEPTION( dofCoeffs.rank() != 1, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(dofCoeffs) != 1, std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HGRAD_QUAD_C1_FEM::getdofCoeffs) rank = 1 required for dofCoeffs array"); // Verify 0th dimension of output array. INTREPID2_TEST_FOR_EXCEPTION( static_cast(dofCoeffs.extent(0)) != this->getCardinality(), std::invalid_argument, diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_QUAD_C2_FEM.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_QUAD_C2_FEM.hpp index 285558110b19..30f679bb79cf 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_QUAD_C2_FEM.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_QUAD_C2_FEM.hpp @@ -232,7 +232,7 @@ namespace Intrepid2 { getDofCoords( ScalarViewType dofCoords ) const override { #ifdef HAVE_INTREPID2_DEBUG // Verify rank of output array. - INTREPID2_TEST_FOR_EXCEPTION( dofCoords.rank() != 2, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(dofCoords) != 2, std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HGRAD_QUAD_DEG2_FEM::getDofCoords) rank = 2 required for dofCoords array"); // Verify 0th dimension of output array. INTREPID2_TEST_FOR_EXCEPTION( static_cast(dofCoords.extent(0)) != this->getCardinality(), std::invalid_argument, @@ -249,7 +249,7 @@ namespace Intrepid2 { getDofCoeffs( ScalarViewType dofCoeffs ) const override { #ifdef HAVE_INTREPID2_DEBUG // Verify rank of output array. - INTREPID2_TEST_FOR_EXCEPTION( dofCoeffs.rank() != 1, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(dofCoeffs) != 1, std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HGRAD_QUAD_DEG2_FEM::getdofCoeffs) rank = 1 required for dofCoeffs array"); // Verify 0th dimension of output array. INTREPID2_TEST_FOR_EXCEPTION( static_cast(dofCoeffs.extent(0)) != this->getCardinality(), std::invalid_argument, diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_QUAD_Cn_FEM.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_QUAD_Cn_FEM.hpp index 352b726939b7..285f3561ef32 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_QUAD_Cn_FEM.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_QUAD_Cn_FEM.hpp @@ -219,7 +219,7 @@ namespace Intrepid2 { getDofCoords( ScalarViewType dofCoords ) const override { #ifdef HAVE_INTREPID2_DEBUG // Verify rank of output array. - INTREPID2_TEST_FOR_EXCEPTION( dofCoords.rank() != 2, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(dofCoords) != 2, std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HGRAD_QUAD_Cn_FEM::getDofCoords) rank = 2 required for dofCoords array"); // Verify 0th dimension of output array. INTREPID2_TEST_FOR_EXCEPTION( static_cast(dofCoords.extent(0)) != this->getCardinality(), std::invalid_argument, @@ -236,7 +236,7 @@ namespace Intrepid2 { getDofCoeffs( ScalarViewType dofCoeffs ) const override { #ifdef HAVE_INTREPID2_DEBUG // Verify rank of output array. - INTREPID2_TEST_FOR_EXCEPTION( dofCoeffs.rank() != 1, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(dofCoeffs) != 1, std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HGRAD_QUAD_Cn_FEM::getdofCoeffs) rank = 1 required for dofCoeffs array"); // Verify 0th dimension of output array. INTREPID2_TEST_FOR_EXCEPTION( static_cast(dofCoeffs.extent(0)) != this->getCardinality(), std::invalid_argument, diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TET_C1_FEM.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TET_C1_FEM.hpp index 1e499097e000..78ab1bf77428 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TET_C1_FEM.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TET_C1_FEM.hpp @@ -202,7 +202,7 @@ namespace Intrepid2 { getDofCoords( ScalarViewType dofCoords ) const override { #ifdef HAVE_INTREPID2_DEBUG // Verify rank of output array. - INTREPID2_TEST_FOR_EXCEPTION( dofCoords.rank() != 2, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(dofCoords) != 2, std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HGRAD_TET_C1_FEM::getDofCoords) rank = 2 required for dofCoords array"); // Verify 0th dimension of output array. INTREPID2_TEST_FOR_EXCEPTION( static_cast(dofCoords.extent(0)) != this->getCardinality(), std::invalid_argument, @@ -219,7 +219,7 @@ namespace Intrepid2 { getDofCoeffs( ScalarViewType dofCoeffs ) const override { #ifdef HAVE_INTREPID2_DEBUG // Verify rank of output array. - INTREPID2_TEST_FOR_EXCEPTION( dofCoeffs.rank() != 1, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(dofCoeffs) != 1, std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HGRAD_TET_C1_FEM::getdofCoeffs) rank = 1 required for dofCoeffs array"); // Verify 0th dimension of output array. INTREPID2_TEST_FOR_EXCEPTION( static_cast(dofCoeffs.extent(0)) != this->getCardinality(), std::invalid_argument, diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TET_C2_FEM.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TET_C2_FEM.hpp index 1aad51e6f624..ef630ee9ffe3 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TET_C2_FEM.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TET_C2_FEM.hpp @@ -221,7 +221,7 @@ namespace Intrepid2 { getDofCoords( ScalarViewType dofCoords ) const override { #ifdef HAVE_INTREPID2_DEBUG // Verify rank of output array. - INTREPID2_TEST_FOR_EXCEPTION( dofCoords.rank() != 2, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(dofCoords) != 2, std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HGRAD_TET_C2_FEM::getDofCoords) rank = 2 required for dofCoords array"); // Verify 0th dimension of output array. INTREPID2_TEST_FOR_EXCEPTION( static_cast(dofCoords.extent(0)) != this->getCardinality(), std::invalid_argument, @@ -239,7 +239,7 @@ namespace Intrepid2 { getDofCoeffs( ScalarViewType dofCoeffs ) const override { #ifdef HAVE_INTREPID2_DEBUG // Verify rank of output array. - INTREPID2_TEST_FOR_EXCEPTION( dofCoeffs.rank() != 1, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(dofCoeffs) != 1, std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HGRAD_TET_C2_FEM::getdofCoeffs) rank = 1 required for dofCoeffs array"); // Verify 0th dimension of output array. INTREPID2_TEST_FOR_EXCEPTION( static_cast(dofCoeffs.extent(0)) != this->getCardinality(), std::invalid_argument, diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TET_COMP12_FEM.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TET_COMP12_FEM.hpp index 221ea8eb1a78..a960590a3586 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TET_COMP12_FEM.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TET_COMP12_FEM.hpp @@ -247,7 +247,7 @@ namespace Intrepid2 { getDofCoords( ScalarViewType dofCoords ) const override { #ifdef HAVE_INTREPID2_DEBUG // Verify rank of output array. - INTREPID2_TEST_FOR_EXCEPTION( dofCoords.rank() != 2, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(dofCoords) != 2, std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HGRAD_TET_COMP12_FEM::getDofCoords) rank = 2 required for dofCoords array"); // Verify 0th dimension of output array. INTREPID2_TEST_FOR_EXCEPTION( static_cast(dofCoords.extent(0)) != this->getCardinality(), std::invalid_argument, diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TET_Cn_FEM.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TET_Cn_FEM.hpp index 546c6b5c3db7..bd8e0f6594fa 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TET_Cn_FEM.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TET_Cn_FEM.hpp @@ -245,7 +245,7 @@ namespace Intrepid2 { getDofCoords( ScalarViewType dofCoords ) const override { #ifdef HAVE_INTREPID2_DEBUG // Verify rank of output array. - INTREPID2_TEST_FOR_EXCEPTION( dofCoords.rank() != 2, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(dofCoords) != 2, std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HGRAD_TET_Cn_FEM::getDofCoords) rank = 2 required for dofCoords array"); // Verify 0th dimension of output array. INTREPID2_TEST_FOR_EXCEPTION( static_cast(dofCoords.extent(0)) != this->getCardinality(), std::invalid_argument, @@ -262,7 +262,7 @@ namespace Intrepid2 { getDofCoeffs( ScalarViewType dofCoeffs ) const override { #ifdef HAVE_INTREPID2_DEBUG // Verify rank of output array. - INTREPID2_TEST_FOR_EXCEPTION( dofCoeffs.rank() != 1, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(dofCoeffs) != 1, std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HGRAD_TET_Cn_FEM::getdofCoeffs) rank = 1 required for dofCoeffs array"); // Verify 0th dimension of output array. INTREPID2_TEST_FOR_EXCEPTION( static_cast(dofCoeffs.extent(0)) != this->getCardinality(), std::invalid_argument, diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TRI_C1_FEM.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TRI_C1_FEM.hpp index 24f9a3a4be0c..c1b876e56aea 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TRI_C1_FEM.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TRI_C1_FEM.hpp @@ -200,7 +200,7 @@ namespace Intrepid2 { getDofCoords( ScalarViewType dofCoords ) const override { #ifdef HAVE_INTREPID2_DEBUG // Verify rank of output array. - INTREPID2_TEST_FOR_EXCEPTION( dofCoords.rank() != 2, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(dofCoords) != 2, std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HGRAD_TRI_C1_FEM::getDofCoords) rank = 2 required for dofCoords array"); // Verify 0th dimension of output array. INTREPID2_TEST_FOR_EXCEPTION( static_cast(dofCoords.extent(0)) != this->getCardinality(), std::invalid_argument, @@ -217,7 +217,7 @@ namespace Intrepid2 { getDofCoeffs( ScalarViewType dofCoeffs ) const override { #ifdef HAVE_INTREPID2_DEBUG // Verify rank of output array. - INTREPID2_TEST_FOR_EXCEPTION( dofCoeffs.rank() != 1, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(dofCoeffs) != 1, std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HGRAD_TRI_C1_FEM::getdofCoeffs) rank = 1 required for dofCoeffs array"); // Verify 0th dimension of output array. INTREPID2_TEST_FOR_EXCEPTION( static_cast(dofCoeffs.extent(0)) != this->getCardinality(), std::invalid_argument, diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TRI_C2_FEM.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TRI_C2_FEM.hpp index ddbc49b24d12..fd4eb1330687 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TRI_C2_FEM.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TRI_C2_FEM.hpp @@ -211,7 +211,7 @@ namespace Intrepid2 { getDofCoords( ScalarViewType dofCoords ) const override { #ifdef HAVE_INTREPID2_DEBUG // Verify rank of output array. - INTREPID2_TEST_FOR_EXCEPTION( dofCoords.rank() != 2, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(dofCoords) != 2, std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HGRAD_TRI_C2_FEM::getDofCoords) rank = 2 required for dofCoords array"); // Verify 0th dimension of output array. INTREPID2_TEST_FOR_EXCEPTION( static_cast(dofCoords.extent(0)) != this->getCardinality(), std::invalid_argument, @@ -228,7 +228,7 @@ namespace Intrepid2 { getDofCoeffs( ScalarViewType dofCoeffs ) const override { #ifdef HAVE_INTREPID2_DEBUG // Verify rank of output array. - INTREPID2_TEST_FOR_EXCEPTION( dofCoeffs.rank() != 1, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(dofCoeffs) != 1, std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HGRAD_TRI_C2_FEM::getdofCoeffs) rank = 1 required for dofCoeffs array"); // Verify 0th dimension of output array. INTREPID2_TEST_FOR_EXCEPTION( static_cast(dofCoeffs.extent(0)) != this->getCardinality(), std::invalid_argument, diff --git a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TRI_Cn_FEM.hpp b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TRI_Cn_FEM.hpp index af2b8643aa63..41f74cd4a205 100644 --- a/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TRI_Cn_FEM.hpp +++ b/packages/intrepid2/src/Discretization/Basis/Intrepid2_HGRAD_TRI_Cn_FEM.hpp @@ -241,7 +241,7 @@ namespace Intrepid2 { getDofCoords( ScalarViewType dofCoords ) const override { #ifdef HAVE_INTREPID2_DEBUG // Verify rank of output array. - INTREPID2_TEST_FOR_EXCEPTION( dofCoords.rank() != 2, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(dofCoords) != 2, std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HGRAD_TRI_Cn_FEM::getDofCoords) rank = 2 required for dofCoords array"); // Verify 0th dimension of output array. INTREPID2_TEST_FOR_EXCEPTION( static_cast(dofCoords.extent(0)) != this->getCardinality(), std::invalid_argument, @@ -258,7 +258,7 @@ namespace Intrepid2 { getDofCoeffs( ScalarViewType dofCoeffs ) const override { #ifdef HAVE_INTREPID2_DEBUG // Verify rank of output array. - INTREPID2_TEST_FOR_EXCEPTION( dofCoeffs.rank() != 1, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(dofCoeffs) != 1, std::invalid_argument, ">>> ERROR: (Intrepid2::Basis_HGRAD_TRI_Cn_FEM::getdofCoeffs) rank = 1 required for dofCoeffs array"); // Verify 0th dimension of output array. INTREPID2_TEST_FOR_EXCEPTION( static_cast(dofCoeffs.extent(0)) != this->getCardinality(), std::invalid_argument, diff --git a/packages/intrepid2/src/Discretization/FunctionSpaceTools/Intrepid2_FunctionSpaceTools.hpp b/packages/intrepid2/src/Discretization/FunctionSpaceTools/Intrepid2_FunctionSpaceTools.hpp index 8f1b9e27e549..b709e8f4b4c6 100644 --- a/packages/intrepid2/src/Discretization/FunctionSpaceTools/Intrepid2_FunctionSpaceTools.hpp +++ b/packages/intrepid2/src/Discretization/FunctionSpaceTools/Intrepid2_FunctionSpaceTools.hpp @@ -595,13 +595,13 @@ namespace Intrepid2 { \param inputVals [in] - Input array of reference HGRAD gradients. */ - template + template static void - HGRADtransformGRAD( Kokkos::DynRankView outputVals, - const Kokkos::DynRankView jacobianInverse, - const Kokkos::DynRankView inputVals ); + HGRADtransformGRAD( OutputValViewType outputVals, + const JacobianInverseViewType jacobianInverse, + const InputValViewType inputVals ); /** \brief Transformation of a (vector) value field in the H-curl space, defined at points on a reference cell, stored in the user-provided container inputVals @@ -1185,13 +1185,13 @@ namespace Intrepid2 { \param inputDet [in] - Input array containing determinants of cell Jacobians. \param inputWeights [in] - Input integration weights. */ - template + template static bool - computeCellMeasure( Kokkos::DynRankView outputVals, - const Kokkos::DynRankView inputDet, - const Kokkos::DynRankView inputWeights ); + computeCellMeasure( OutputValViewType outputVals, + const InputDetViewType inputDet, + const InputWeightViewType inputWeights ); /** \brief Returns the weighted integration measures \a outputVals with dimensions (C,P) used for the computation of face integrals, based on the provided diff --git a/packages/intrepid2/src/Discretization/FunctionSpaceTools/Intrepid2_FunctionSpaceToolsDef.hpp b/packages/intrepid2/src/Discretization/FunctionSpaceTools/Intrepid2_FunctionSpaceToolsDef.hpp index 2f46bdd27816..be38155581bc 100644 --- a/packages/intrepid2/src/Discretization/FunctionSpaceTools/Intrepid2_FunctionSpaceToolsDef.hpp +++ b/packages/intrepid2/src/Discretization/FunctionSpaceTools/Intrepid2_FunctionSpaceToolsDef.hpp @@ -131,14 +131,14 @@ namespace Intrepid2 { } template - template + template void FunctionSpaceTools:: - HGRADtransformGRAD( Kokkos::DynRankView outputVals, - const Kokkos::DynRankView jacobianInverse, - const Kokkos::DynRankView inputVals ) { + HGRADtransformGRAD( OutputValViewType outputVals, + const JacobianInverseViewType jacobianInverse, + const InputValViewType inputVals ) { return HCURLtransformVALUE(outputVals, jacobianInverse, inputVals); } @@ -562,19 +562,19 @@ namespace Intrepid2 { } template - template + template bool FunctionSpaceTools:: - computeCellMeasure( Kokkos::DynRankView outputVals, - const Kokkos::DynRankView inputDet, - const Kokkos::DynRankView inputWeights ) { + computeCellMeasure( OutputValViewType outputVals, + const InputDetViewType inputDet, + const InputWeightViewType inputWeights ) { #ifdef HAVE_INTREPID2_DEBUG { - INTREPID2_TEST_FOR_EXCEPTION( inputDet.rank() != 2 || - inputWeights.rank() != 1 || - outputVals.rank() != 2, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(inputDet) != 2 || + rank(inputWeights) != 1 || + rank(outputVals) != 2, std::invalid_argument, ">>> ERROR (FunctionSpaceTools::computeCellMeasure): Ranks are not compatible."); INTREPID2_TEST_FOR_EXCEPTION( outputVals.extent(0) != inputDet.extent(0), std::invalid_argument, ">>> ERROR (FunctionSpaceTools::computeCellMeasure): Cell dimension does not match."); diff --git a/packages/intrepid2/src/Discretization/Integration/Intrepid2_Cubature.hpp b/packages/intrepid2/src/Discretization/Integration/Intrepid2_Cubature.hpp index a7fc8e04e674..33ec2fad7c0a 100644 --- a/packages/intrepid2/src/Discretization/Integration/Intrepid2_Cubature.hpp +++ b/packages/intrepid2/src/Discretization/Integration/Intrepid2_Cubature.hpp @@ -362,10 +362,10 @@ namespace Intrepid2 { \subsection fst_qs_sec Step 7: Apply function space tools \code - FunctionSpaceTools::computeCellMeasure(weighted_measure, // compute weighted cell measure + FunctionSpaceTools::computeCellMeasure(weighted_measure, // compute weighted cell measure jacobian_det, cub_weights); - FunctionSpaceTools::HGRADtransformGRAD(transformed_grad_at_cub_points, // transform reference gradients into physical space + FunctionSpaceTools::HGRADtransformGRAD(transformed_grad_at_cub_points, // transform reference gradients into physical space jacobian_inv, grad_at_cub_points); FunctionSpaceTools::multiplyMeasure(weighted_transformed_grad_at_cub_points, // multiply with weighted measure diff --git a/packages/intrepid2/src/Discretization/Integration/Intrepid2_CubatureDirect.hpp b/packages/intrepid2/src/Discretization/Integration/Intrepid2_CubatureDirect.hpp index 6f93faaf1999..d41ffc14f49d 100644 --- a/packages/intrepid2/src/Discretization/Integration/Intrepid2_CubatureDirect.hpp +++ b/packages/intrepid2/src/Discretization/Integration/Intrepid2_CubatureDirect.hpp @@ -141,10 +141,10 @@ namespace Intrepid2 { const CubatureData cubData) const { #ifdef HAVE_INTREPID2_DEBUG // check size of cubPoints and cubWeights - INTREPID2_TEST_FOR_EXCEPTION( cubPoints.rank() != 2, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(cubPoints) != 2, std::invalid_argument, ">>> ERROR (CubatureDirect): cubPoints must be rank 2." ); - INTREPID2_TEST_FOR_EXCEPTION( cubWeights.rank() != 1, std::invalid_argument, + INTREPID2_TEST_FOR_EXCEPTION( rank(cubWeights) != 1, std::invalid_argument, ">>> ERROR (CubatureDirect): cubPoints must be rank 1." ); INTREPID2_TEST_FOR_EXCEPTION( static_cast(cubPoints.extent(0)) < this->getNumPoints() || diff --git a/packages/intrepid2/src/Shared/Intrepid2_ArrayToolsDefTensor.hpp b/packages/intrepid2/src/Shared/Intrepid2_ArrayToolsDefTensor.hpp index eff53e119ebf..8c3eb86c0069 100644 --- a/packages/intrepid2/src/Shared/Intrepid2_ArrayToolsDefTensor.hpp +++ b/packages/intrepid2/src/Shared/Intrepid2_ArrayToolsDefTensor.hpp @@ -693,7 +693,7 @@ namespace Intrepid2 { leftInputViewType leftInput_, rightInputViewType rightInput_) : _output(output_), _leftInput(leftInput_), _rightInput(rightInput_), - _iend(output_.extent_int(output_.rank()-1)), _jend(rightInput_.extent_int(rightInputRank-1)) + _iend(output_.extent_int(rank(output_)-1)), _jend(rightInput_.extent_int(rightInputRank-1)) {} // ****** hasField == true cases ****** diff --git a/packages/intrepid2/src/Shared/Intrepid2_Data.hpp b/packages/intrepid2/src/Shared/Intrepid2_Data.hpp index 9aadb463ca1f..4e448ec284aa 100644 --- a/packages/intrepid2/src/Shared/Intrepid2_Data.hpp +++ b/packages/intrepid2/src/Shared/Intrepid2_Data.hpp @@ -2013,6 +2013,11 @@ class ZeroView { return underlyingMatchesLogical_; } }; + + template + KOKKOS_INLINE_FUNCTION constexpr unsigned rank(const Data& D) { + return D.rank(); + } } // we do ETI for doubles and default ExecutionSpace's device_type From 3c5b15170b18d491b0a3774c811b9ca2822c2466 Mon Sep 17 00:00:00 2001 From: Chris Siefert Date: Mon, 18 Mar 2024 16:10:59 -0600 Subject: [PATCH 10/17] Update clang_format.yml --- .github/workflows/clang_format.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/clang_format.yml b/.github/workflows/clang_format.yml index 392fa8499db2..71dd6d07896b 100644 --- a/.github/workflows/clang_format.yml +++ b/.github/workflows/clang_format.yml @@ -2,6 +2,8 @@ name: Check packages with clang-format on: [pull_request] +permissions: read-all + jobs: build: runs-on: ubuntu-latest From e1b34259316e91eb6345a2fdab50234b8824af26 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Mar 2024 09:10:32 -0600 Subject: [PATCH 11/17] Bump github/codeql-action from 3.24.7 to 3.24.8 (#12844) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.24.7 to 3.24.8. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/3ab4101902695724f9365a384f86c1074d94e18c...05963f47d870e2cb19a537396c1f668a348c7d8f) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/scorecards.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index f8a711409095..79336664cd67 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -66,6 +66,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@3ab4101902695724f9365a384f86c1074d94e18c # v3.24.7 + uses: github/codeql-action/upload-sarif@05963f47d870e2cb19a537396c1f668a348c7d8f # v3.24.8 with: sarif_file: results.sarif From b911093d1995c90dc14c1031ab55ec9c9bb66357 Mon Sep 17 00:00:00 2001 From: drnobleabq <44879870+drnobleabq@users.noreply.github.com> Date: Wed, 20 Mar 2024 07:55:30 -0600 Subject: [PATCH 12/17] Krino: Snapshot 03-17-24 12:32 from Sierra 5.19.1-190-gd624d6b6 (#12840) --- .../krino/krino/geometry/Akri_Segment.hpp | 25 +- .../krino/krino/geometry/Akri_Triangle.hpp | 21 +- .../Akri_AnalyticSurfaceInterfaceGeometry.cpp | 37 +- .../Akri_AnalyticSurfaceInterfaceGeometry.hpp | 5 +- .../krino/krino/krino_lib/Akri_CDMesh.cpp | 9 +- .../krino_lib/Akri_CDMesh_Refinement.cpp | 71 ++- .../krino_lib/Akri_CDMesh_Refinement.hpp | 12 +- .../krino_lib/Akri_InterfaceGeometry.hpp | 7 +- .../krino/krino/krino_lib/Akri_LevelSet.cpp | 524 +++++++++++------- .../krino/krino/krino_lib/Akri_LevelSet.hpp | 25 +- .../Akri_LevelSetInterfaceGeometry.cpp | 45 +- .../Akri_LevelSetInterfaceGeometry.hpp | 6 +- .../krino/krino_lib/Akri_OutputUtils.cpp | 10 + .../krino/krino_lib/Akri_OutputUtils.hpp | 1 + .../krino_lib/Akri_RefineNearLevelSets.cpp | 42 +- .../krino_lib/Akri_RefineNearLevelSets.hpp | 4 +- .../krino_lib/Akri_RefinementInterface.cpp | 9 + .../krino_lib/Akri_RefinementInterface.hpp | 1 + .../krino_lib/Akri_RefinementSupport.cpp | 25 +- .../krino_lib/Akri_RefinementSupport.hpp | 1 + .../krino/parser/Akri_LevelSet_Parser.cpp | 10 +- .../krino/refinement/Akri_NodeRefiner.hpp | 2 +- .../krino/refinement/Akri_Refinement.hpp | 2 +- .../Akri_TransitionElementEdgeMarker.hpp | 2 +- packages/krino/krino/region/Akri_Region.cpp | 99 +++- packages/krino/krino/region/Akri_Region.hpp | 7 +- .../region/Akri_ResultsOutputOptions.hpp | 2 - packages/krino/krino/surface/Akri_Facet.cpp | 100 +++- packages/krino/krino/surface/Akri_Facet.hpp | 65 ++- .../surface/Akri_FacetedSurfaceCalcs.cpp | 35 ++ .../surface/Akri_FacetedSurfaceCalcs.hpp | 3 + .../krino/surface/Akri_Faceted_Surface.cpp | 55 +- .../krino/surface/Akri_Faceted_Surface.hpp | 12 + .../Akri_String_Function_Expression.cpp | 21 + .../Akri_String_Function_Expression.hpp | 5 +- .../Akri_Unit_InterfaceGeometry.hpp | 5 +- .../unit_tests/Akri_Unit_RefineInterval.cpp | 3 +- packages/krino/tools/trilinos_snapshot.sh | 71 +++ 38 files changed, 943 insertions(+), 436 deletions(-) create mode 100755 packages/krino/tools/trilinos_snapshot.sh diff --git a/packages/krino/krino/geometry/Akri_Segment.hpp b/packages/krino/krino/geometry/Akri_Segment.hpp index 159c988316ae..db33122466e4 100644 --- a/packages/krino/krino/geometry/Akri_Segment.hpp +++ b/packages/krino/krino/geometry/Akri_Segment.hpp @@ -47,17 +47,30 @@ class CalcSegment3 { if(lenSquared == 0.0) { return 0.0; } return dotValA / lenSquared; } - static Vec3d closest_point(const Vec3d & p0, const Vec3d & p1, const Vec3d &queryPt) + + static void closest_point_and_parametric_coord(const Vec3d & p0, const Vec3d & p1, const Vec3d &queryPt, Vec3d &closestPt, REAL ¶mLoc) { - const REAL paramLoc = closest_parametric_location(p0, p1, queryPt); - return (1.0-paramLoc)*p0 + paramLoc*p1; + paramLoc = closest_parametric_location(p0, p1, queryPt); + closestPt = (1.0-paramLoc)*p0 + paramLoc*p1; } - static void closest_point(const Vec3d & p0, const Vec3d & p1, const Vec3d &queryPt, Vec3d &closestPt, REAL ¶mLoc) + + static void closest_point(const Vec3d & p0, const Vec3d & p1, const Vec3d &queryPt, Vec3d &closestPt) { - paramLoc = closest_parametric_location(p0, p1, queryPt); + const REAL paramLoc = closest_parametric_location(p0, p1, queryPt); closestPt = (1.0-paramLoc)*p0 + paramLoc*p1; } + static Vec3d closest_point(const Vec3d & p0, const Vec3d & p1, const Vec3d& queryPt) + { + Vec3d closestPt(stk::math::MemberInit::NONE); + closest_point(p0, p1, queryPt, closestPt); + return closestPt; + } + + static void closest_point_and_parametric_coord(const std::array & coords, const Vec3d &queryPt, Vec3d &closestPt, REAL ¶mLoc) { closest_point_and_parametric_coord(coords[0], coords[1], queryPt, closestPt, paramLoc); } + static void closest_point(const std::array & coords, const Vec3d &queryPt, Vec3d &closestPt) { closest_point(coords[0], coords[1], queryPt, closestPt); } + static Vec3d closest_point(const std::array & coords, const Vec3d &queryPt) { closest_point(coords[0], coords[1], queryPt); } + static REAL distance_squared(const Vec3d & p0, const Vec3d & p1, const Vec3d& queryPt) { return (queryPt - closest_point(p0, p1, queryPt)).length_squared(); @@ -65,8 +78,6 @@ class CalcSegment3 { static REAL length(const std::array & coords) { return (coords[1]-coords[0]).length(); } static REAL length_squared(const std::array & coords) { return (coords[1]-coords[0]).length_squared(); } - static Vec3d closest_point(const std::array & coords, const Vec3d &queryPt) { return closest_point(coords[0], coords[1], queryPt); } - static void closest_point(const std::array & coords, const Vec3d &queryPt, Vec3d &closestPt, REAL ¶mLoc) { closest_point(coords[0], coords[1], queryPt, closestPt, paramLoc); } static REAL distance_squared(const std::array & coords, const Vec3d& queryPt) { return distance_squared(coords[0], coords[1], queryPt); } }; diff --git a/packages/krino/krino/geometry/Akri_Triangle.hpp b/packages/krino/krino/geometry/Akri_Triangle.hpp index fa58b3865bcd..a40ba7902dde 100644 --- a/packages/krino/krino/geometry/Akri_Triangle.hpp +++ b/packages/krino/krino/geometry/Akri_Triangle.hpp @@ -148,6 +148,23 @@ class CalcTriangle3 { closest_point_projection(p0, p1, p2, queryPt, closestPt); } + static Vec3d closest_point(const Vec3d & p0, const Vec3d & p1, const Vec3d & p2, const Vec3d& queryPt) + { + Vec3d closestPt(stk::math::MemberInit::NONE); + closest_point(p0, p1, p2, queryPt, closestPt); + return closestPt; + } + + static void closest_point(const std::array & triCoords, const Vec3d& queryPt, Vec3d& closestPt) + { + closest_point(triCoords[0], triCoords[1], triCoords[2], queryPt, closestPt); + } + + static Vec3d closest_point(const std::array & triCoords, const Vec3d& queryPt) + { + return closest_point(triCoords[0], triCoords[1], triCoords[2], queryPt); + } + static void closest_point_and_parametric_coords(const Vec3d & p0, const Vec3d & p1, const Vec3d & p2, const Vec3d& queryPt, Vec3d& closestPt, Vec2d & paramPt) { closest_point_projection(p0, p1, p2, queryPt, std::tie(closestPt, paramPt)); @@ -169,9 +186,7 @@ class CalcTriangle3 { template inline REAL CalcTriangle3::distance_squared(const Vec3d & p0, const Vec3d & p1, const Vec3d & p2, const Vec3d& queryPt) { - Vec3d closestPt(stk::math::MemberInit::NONE); - closest_point(p0,p1,p2, queryPt, closestPt); - return (queryPt-closestPt).length_squared(); + return (queryPt-closest_point(p0,p1,p2, queryPt)).length_squared(); } template diff --git a/packages/krino/krino/krino_lib/Akri_AnalyticSurfaceInterfaceGeometry.cpp b/packages/krino/krino/krino_lib/Akri_AnalyticSurfaceInterfaceGeometry.cpp index 86d1db640b31..ea2c4a7fbd0d 100644 --- a/packages/krino/krino/krino_lib/Akri_AnalyticSurfaceInterfaceGeometry.cpp +++ b/packages/krino/krino/krino_lib/Akri_AnalyticSurfaceInterfaceGeometry.cpp @@ -217,6 +217,12 @@ void AnalyticSurfaceInterfaceGeometry::prepare_to_decompose_elements(const stk:: set_element_signs(mesh, selectAllPerSurfaceElementSelector); } +void AnalyticSurfaceInterfaceGeometry::prepare_to_intersect_elements(const stk::mesh::BulkData & mesh) const +{ + const NodeToCapturedDomainsMap emptyNodesToCapturedDomains; + prepare_to_intersect_elements(mesh, emptyNodesToCapturedDomains); +} + void AnalyticSurfaceInterfaceGeometry::prepare_to_intersect_elements(const stk::mesh::BulkData & mesh, const NodeToCapturedDomainsMap & nodesToCapturedDomains) const { @@ -269,8 +275,7 @@ static bool element_has_possibly_cut_edge(stk::topology elemTopology, const std: std::vector AnalyticSurfaceInterfaceGeometry::get_possibly_cut_elements(const stk::mesh::BulkData & mesh) const { - NodeToCapturedDomainsMap nodesToSnappedDomains; - prepare_to_intersect_elements(mesh, nodesToSnappedDomains); + prepare_to_intersect_elements(mesh); std::vector possibleCutElements; std::vector elementNodeCoords; @@ -292,43 +297,39 @@ std::vector AnalyticSurfaceInterfaceGeometry::get_possibly_cu return possibleCutElements; } -static bool element_intersects_interval(const std::vector surfaces, const std::vector & elemNodeCoords, const std::array & loAndHi, std::vector & elemNodeDistWorkspace) +static bool element_intersects_distance_interval(const Surface & surface, const std::vector & elemNodeCoords, const std::array & loAndHi, std::vector & elemNodeDistWorkspace) { - for (auto && surface : surfaces) - { - fill_point_distances(*surface, elemNodeCoords, elemNodeDistWorkspace); - if (InterfaceGeometry::element_with_nodal_distance_intersects_interval(elemNodeDistWorkspace, loAndHi)) - return true; - } - return false; + fill_point_distances(surface, elemNodeCoords, elemNodeDistWorkspace); + return InterfaceGeometry::element_with_nodal_distance_intersects_distance_interval(elemNodeDistWorkspace, loAndHi); } -std::vector AnalyticSurfaceInterfaceGeometry::get_elements_that_intersect_interval(const stk::mesh::BulkData & mesh, const std::array loAndHi) const +const Surface & AnalyticSurfaceInterfaceGeometry::get_surface_with_identifer(const Surface_Identifier surfaceIdentifier) const { - NodeToCapturedDomainsMap nodesToSnappedDomains; - prepare_to_intersect_elements(mesh, nodesToSnappedDomains); + auto iter = std::find(mySurfaceIdentifiers.begin(), mySurfaceIdentifiers.end(), surfaceIdentifier); + STK_ThrowRequire(iter != mySurfaceIdentifiers.end()); + return *mySurfaces[std::distance(mySurfaceIdentifiers.begin(), iter)]; +} - std::vector elementsThaIntersectInterval; +void AnalyticSurfaceInterfaceGeometry::fill_elements_that_intersect_distance_interval(const stk::mesh::BulkData & mesh, const Surface_Identifier surfaceIdentifier, const std::array loAndHi, std::vector & elementsThaIntersectInterval) const +{ std::vector elementNodeCoords; std::vector elementNodeDist; const FieldRef coordsField(mesh.mesh_meta_data().coordinate_field()); const stk::mesh::Selector activeLocallyOwned = myActivePart & (mesh.mesh_meta_data().locally_owned_part()); + elementsThaIntersectInterval.clear(); for(const auto & bucketPtr : mesh.get_buckets(stk::topology::ELEMENT_RANK, activeLocallyOwned)) { for(const auto & elem : *bucketPtr) { fill_element_node_coordinates(mesh, elem, coordsField, elementNodeCoords); - if (element_intersects_interval(mySurfaces, elementNodeCoords, loAndHi, elementNodeDist)) + if (element_intersects_distance_interval(get_surface_with_identifer(surfaceIdentifier), elementNodeCoords, loAndHi, elementNodeDist)) elementsThaIntersectInterval.push_back(elem); } } - - return elementsThaIntersectInterval; } - static bool all_nodes_of_element_will_be_snapped(const stk::mesh::BulkData & mesh, stk::mesh::Entity element, stk::mesh::Entity snapNode, diff --git a/packages/krino/krino/krino_lib/Akri_AnalyticSurfaceInterfaceGeometry.hpp b/packages/krino/krino/krino_lib/Akri_AnalyticSurfaceInterfaceGeometry.hpp index 410df9ae1609..fb0514125a62 100644 --- a/packages/krino/krino/krino_lib/Akri_AnalyticSurfaceInterfaceGeometry.hpp +++ b/packages/krino/krino/krino_lib/Akri_AnalyticSurfaceInterfaceGeometry.hpp @@ -82,6 +82,7 @@ class AnalyticSurfaceInterfaceGeometry : public InterfaceGeometry { virtual void prepare_to_decompose_elements(const stk::mesh::BulkData & mesh, const NodeToCapturedDomainsMap & nodesToSnappedDomains) const override; + virtual void prepare_to_intersect_elements(const stk::mesh::BulkData & mesh) const override; virtual void prepare_to_intersect_elements(const stk::mesh::BulkData & mesh, const NodeToCapturedDomainsMap & nodesToSnappedDomains) const override; virtual void prepare_to_intersect_elements(const stk::mesh::BulkData & mesh, @@ -89,7 +90,7 @@ class AnalyticSurfaceInterfaceGeometry : public InterfaceGeometry { const NodeToCapturedDomainsMap & nodesToSnappedDomains) const override; virtual std::vector get_possibly_cut_elements(const stk::mesh::BulkData & mesh) const override; - virtual std::vector get_elements_that_intersect_interval(const stk::mesh::BulkData & mesh, const std::array loAndHi) const override; + virtual void fill_elements_that_intersect_distance_interval(const stk::mesh::BulkData & mesh, const Surface_Identifier surfaceIdentifier, const std::array loAndHi, std::vector & elementsThaIntersectInterval) const override; virtual bool snapped_elements_may_have_new_intersections() const override { return false; } @@ -129,6 +130,8 @@ class AnalyticSurfaceInterfaceGeometry : public InterfaceGeometry { std::vector get_mesh_parent_elements(const stk::mesh::BulkData & mesh) const; private: + const Surface & get_surface_with_identifer(const Surface_Identifier surfaceIdentifier) const; + std::vector mySurfaces; const stk::mesh::Part & myActivePart; const CDFEM_Support & myCdfemSupport; diff --git a/packages/krino/krino/krino_lib/Akri_CDMesh.cpp b/packages/krino/krino/krino_lib/Akri_CDMesh.cpp index 557a4d4e1d12..59e7b9b20b3a 100644 --- a/packages/krino/krino/krino_lib/Akri_CDMesh.cpp +++ b/packages/krino/krino/krino_lib/Akri_CDMesh.cpp @@ -287,8 +287,7 @@ void CDMesh::prepare_for_resnapping(const stk::mesh::BulkData & mesh, const Inte cdfemSnapField.field().rotate_multistate_data(); interfaceGeometry.set_do_update_geometry_when_mesh_changes(true); - krino::NodeToCapturedDomainsMap nodesToCapturedDomains; - interfaceGeometry.prepare_to_intersect_elements(mesh, nodesToCapturedDomains); + interfaceGeometry.prepare_to_intersect_elements(mesh); interfaceGeometry.set_do_update_geometry_when_mesh_changes(false); undo_previous_snaps_without_interpolation(mesh, cdfemSupport.get_coords_field(), cdfemSnapField); @@ -633,11 +632,13 @@ CDMesh::nonconformal_adaptivity(stk::mesh::BulkData & mesh, const FieldRef coord { markerFunction = [&mesh, &refinementSupport, &interfaceGeometry](int num_refinements) { + constexpr bool isDefaultCoarsen = true; mark_elements_that_intersect_interval(mesh, refinementSupport.get_non_interface_conforming_refinement(), interfaceGeometry, - refinementSupport, - num_refinements); + refinementSupport.get_refinement_interval(), + refinementSupport.get_interface_minimum_refinement_level(), + isDefaultCoarsen); }; } else diff --git a/packages/krino/krino/krino_lib/Akri_CDMesh_Refinement.cpp b/packages/krino/krino/krino_lib/Akri_CDMesh_Refinement.cpp index b062b83e66cc..7f5b5c0b1be0 100644 --- a/packages/krino/krino/krino_lib/Akri_CDMesh_Refinement.cpp +++ b/packages/krino/krino/krino_lib/Akri_CDMesh_Refinement.cpp @@ -230,47 +230,52 @@ mark_nearest_node_on_cut_edges(const stk::mesh::BulkData& mesh, stk::mesh::parallel_max(mesh, {&node_marker_field.field()}); } -int determine_refinement_marker(const bool isElementIndicated, const int refinementIterCount, const int interfaceMinRefineLevel, const int elementRefineLevel) +static void initialize_marker(const stk::mesh::BulkData& mesh, + const RefinementInterface & refinement, + const bool isDefaultCoarsen) +{ + const FieldRef elementMarkerField = refinement.get_marker_field(); + const int initialVal = isDefaultCoarsen ? static_cast(Refinement_Marker::COARSEN) : static_cast(Refinement_Marker::NOTHING); + stk::mesh::field_fill(initialVal, elementMarkerField); +} + +int determine_refinement_marker(const bool isElementIndicated, const int interfaceMinRefineLevel, const int elementRefineLevel, const bool isDefaultCoarsen) { - auto marker = Refinement_Marker::NOTHING; + auto marker = isDefaultCoarsen ? Refinement_Marker::COARSEN : Refinement_Marker::NOTHING; const int targetRefineLevel = isElementIndicated ? interfaceMinRefineLevel : 0; if (elementRefineLevel < targetRefineLevel) - { marker = Refinement_Marker::REFINE; - } - else if (refinementIterCount < interfaceMinRefineLevel && - elementRefineLevel > targetRefineLevel) - { - // Stop coarsening after num_levels of refinement to avoid infinite looping - // from the interface position moving between elements because of snapping changes - // with refinement - marker = Refinement_Marker::COARSEN; - } + else if (elementRefineLevel == targetRefineLevel) + marker = Refinement_Marker::NOTHING; return static_cast(marker); } -void -mark_given_elements(const stk::mesh::BulkData& mesh, +static void mark_given_elements(const stk::mesh::BulkData& mesh, const RefinementInterface & refinement, - const RefinementSupport & refinementSupport, const std::vector elementsToMark, - const int refinementIterCount) + const int minRefineLevel, + const bool isDefaultCoarsen) { const FieldRef elementMarkerField = refinement.get_marker_field(); - const int interfaceMinRefineLevel = refinementSupport.get_interface_minimum_refinement_level(); constexpr bool doMarkElement = true; - stk::mesh::field_fill(static_cast(Refinement_Marker::COARSEN), elementMarkerField); - for( auto&& elem : elementsToMark ) { int & marker = *field_data(elementMarkerField, elem); const int elementRefineLevel = refinement.fully_refined_level(elem); - marker = determine_refinement_marker(doMarkElement, refinementIterCount, interfaceMinRefineLevel, elementRefineLevel); + marker = determine_refinement_marker(doMarkElement, minRefineLevel, elementRefineLevel, isDefaultCoarsen); } } +static bool should_continue_to_coarsen(const int refinementIterCount, const int targetRefineLevel) +{ + // Stop coarsening after num_levels of refinement to avoid infinite looping + // from the interface position moving between elements because of snapping changes + // with refinement + return refinementIterCount < targetRefineLevel; +} + void mark_possible_cut_elements_for_adaptivity(const stk::mesh::BulkData& mesh, const RefinementInterface & refinement, @@ -278,19 +283,32 @@ mark_possible_cut_elements_for_adaptivity(const stk::mesh::BulkData& mesh, const RefinementSupport & refinementSupport, const int refinementIterCount) { + const int minRefineLevel = refinementSupport.get_interface_minimum_refinement_level(); + const bool isDefaultCoarsen = should_continue_to_coarsen(refinementIterCount, minRefineLevel); const std::vector possiblyCutElems = interfaceGeometry.get_possibly_cut_elements(mesh); - mark_given_elements(mesh, refinement, refinementSupport, possiblyCutElems, refinementIterCount); + initialize_marker(mesh, refinement, isDefaultCoarsen); + mark_given_elements(mesh, refinement, possiblyCutElems, minRefineLevel, isDefaultCoarsen); } void mark_elements_that_intersect_interval(const stk::mesh::BulkData& mesh, const RefinementInterface & refinement, const InterfaceGeometry & interfaceGeometry, - const RefinementSupport & refinementSupport, - const int refinementIterCount) + const std::array refinementInterval, + const int numRefineLevels, + const bool isDefaultCoarsen) { - const std::vector elementsInInterval = interfaceGeometry.get_elements_that_intersect_interval(mesh, refinementSupport.get_refinement_interval()); - mark_given_elements(mesh, refinement, refinementSupport, elementsInInterval, refinementIterCount); + // Used to refine elements with 1 to many interfaces within the interfaceGeometry that each are to be refined with the same interval to the same refinement level + // If isDefaultCoarsen=false, then the refinement will be cumulative (since default will be to do nothing) + initialize_marker(mesh, refinement, isDefaultCoarsen); + interfaceGeometry.prepare_to_intersect_elements(mesh); + constexpr bool isDefaultCoarsenForEachLS = false; + std::vector elementsInInterval; + for (auto & surfaceIdentifier : interfaceGeometry.get_surface_identifiers()) + { + interfaceGeometry.fill_elements_that_intersect_distance_interval(mesh, surfaceIdentifier, refinementInterval, elementsInInterval); + mark_given_elements(mesh, refinement, elementsInInterval, numRefineLevels, isDefaultCoarsenForEachLS); + } } double compute_edge_length(const FieldRef coordsField, const stk::topology elemTopology, const stk::mesh::Entity * const elemNodes, const unsigned iEdge) @@ -378,6 +396,7 @@ mark_interface_elements_for_adaptivity(const stk::mesh::BulkData& mesh, const NodeToCapturedDomainsMap nodesToCapturedDomains; const std::vector edgeIntersections = interfaceGeometry.get_edge_intersection_points(mesh, nodesToCapturedDomains); + const bool isDefaultCoarsen = should_continue_to_coarsen(numRefinements, interfaceMinRefineLevel); FieldRef nodeMarkerField = refinementSupport.get_nonconforming_refinement_node_marker_field(); mark_nearest_node_on_cut_edges(mesh, edgeIntersections, nodeMarkerField); @@ -390,7 +409,7 @@ mark_interface_elements_for_adaptivity(const stk::mesh::BulkData& mesh, const int elementRefineLevel = refinement.fully_refined_level(elem); int & marker = *field_data(elementMarkerField, elem); - marker = determine_refinement_marker(hasCrossing, numRefinements, interfaceMinRefineLevel, elementRefineLevel); + marker = determine_refinement_marker(hasCrossing, interfaceMinRefineLevel, elementRefineLevel, isDefaultCoarsen); } write_refinement_level_sizes(mesh, refinement, coordsField, entities, interfaceMaxRefineLevel); diff --git a/packages/krino/krino/krino_lib/Akri_CDMesh_Refinement.hpp b/packages/krino/krino/krino_lib/Akri_CDMesh_Refinement.hpp index 5862dfb87a81..c8b6fac1e570 100644 --- a/packages/krino/krino/krino_lib/Akri_CDMesh_Refinement.hpp +++ b/packages/krino/krino/krino_lib/Akri_CDMesh_Refinement.hpp @@ -19,13 +19,6 @@ class CDFEM_Snapper; class RefinementSupport; class Phase_Support; -void -mark_given_elements(const stk::mesh::BulkData& mesh, - const RefinementInterface & refinement, - const RefinementSupport & refinementSupport, - const std::vector elementsToMark, - const int refinementIterCount); - void mark_possible_cut_elements_for_adaptivity(const stk::mesh::BulkData& mesh, const RefinementInterface & refinement, @@ -37,8 +30,9 @@ void mark_elements_that_intersect_interval(const stk::mesh::BulkData& mesh, const RefinementInterface & refinement, const InterfaceGeometry & interfaceGeometry, - const RefinementSupport & refinementSupport, - const int numRefinements); + const std::array refinementInterval, + const int numRefineLevels, + const bool isDefaultCoarsen); void mark_interface_elements_for_adaptivity(const stk::mesh::BulkData& mesh, diff --git a/packages/krino/krino/krino_lib/Akri_InterfaceGeometry.hpp b/packages/krino/krino/krino_lib/Akri_InterfaceGeometry.hpp index 94a298e8c739..6b3a73f72c73 100644 --- a/packages/krino/krino/krino_lib/Akri_InterfaceGeometry.hpp +++ b/packages/krino/krino/krino_lib/Akri_InterfaceGeometry.hpp @@ -46,12 +46,13 @@ class InterfaceGeometry { public: InterfaceGeometry() {} - static bool element_with_nodal_distance_intersects_interval(const std::vector & elemNodeDist, const std::array & loAndHi); + static bool element_with_nodal_distance_intersects_distance_interval(const std::vector & elemNodeDist, const std::array & loAndHi); virtual ~InterfaceGeometry() {} virtual bool might_have_interior_or_face_intersections() const = 0; virtual void prepare_to_decompose_elements(const stk::mesh::BulkData & mesh, const NodeToCapturedDomainsMap & nodesToCapturedDomains) const = 0; + virtual void prepare_to_intersect_elements(const stk::mesh::BulkData & mesh) const = 0; virtual void prepare_to_intersect_elements(const stk::mesh::BulkData & mesh, const NodeToCapturedDomainsMap & nodesToCapturedDomains) const = 0; virtual void prepare_to_intersect_elements(const stk::mesh::BulkData & mesh, @@ -59,7 +60,7 @@ class InterfaceGeometry { const NodeToCapturedDomainsMap & nodesToCapturedDomains) const = 0; virtual std::vector get_possibly_cut_elements(const stk::mesh::BulkData & mesh) const = 0; - virtual std::vector get_elements_that_intersect_interval(const stk::mesh::BulkData & mesh, const std::array loAndHi) const = 0; + virtual void fill_elements_that_intersect_distance_interval(const stk::mesh::BulkData & mesh, const Surface_Identifier surfaceIdentifier, const std::array loAndHi, std::vector & elementsThaIntersectInterval) const = 0; virtual bool snapped_elements_may_have_new_intersections() const = 0; @@ -92,7 +93,7 @@ class InterfaceGeometry { virtual void set_do_update_geometry_when_mesh_changes(const bool flag) const {} }; -inline bool InterfaceGeometry::element_with_nodal_distance_intersects_interval(const std::vector & elemNodeDist, const std::array & loAndHi) +inline bool InterfaceGeometry::element_with_nodal_distance_intersects_distance_interval(const std::vector & elemNodeDist, const std::array & loAndHi) { bool allLo = true; bool allHi = true; diff --git a/packages/krino/krino/krino_lib/Akri_LevelSet.cpp b/packages/krino/krino/krino_lib/Akri_LevelSet.cpp index de07769574f2..608097d57b18 100644 --- a/packages/krino/krino/krino_lib/Akri_LevelSet.cpp +++ b/packages/krino/krino/krino_lib/Akri_LevelSet.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include namespace krino { @@ -345,38 +346,60 @@ LevelSet::set_surface_distance(std::vector surfaces, const do } } -//----------------------------------------------------------------------------------- -void -LevelSet::advance_semilagrangian(const double deltaTime) -{ /* %TRACE[ON]% */ Trace trace__("krino::LevelSet::advance_semilagrangian(const double deltaTime)"); /* %TRACE% */ +static stk::math::Vector3d compute_interface_velocity_at_point(const int dim, const double time, const stk::math::Vector3d & coords, const std::vector & interfaceVelocityExpr) +{ + if (2 == dim) + return stk::math::Vector3d(interfaceVelocityExpr[0].evaluate(time, coords), interfaceVelocityExpr[1].evaluate(time, coords), 0.0); + return stk::math::Vector3d(interfaceVelocityExpr[0].evaluate(time, coords), interfaceVelocityExpr[1].evaluate(time, coords), interfaceVelocityExpr[2].evaluate(time, coords)); +} - if(trackIsoSurface) +template +double compute_max_facet_velocity_magnitude(const double time, + const std::vector & facets, + const std::vector & interfaceVelocity) +{ + double maxSqrMag = 0.; + for (auto & facet : facets) { - redistance(); + for (int n=0; n maxSqrMag) + maxSqrMag = velSqrMag; + } } - else - { - stk::mesh::Selector selector(my_meta.universal_part()); + return std::sqrt(maxSqrMag); +} - // store existing facets in facets_old - facets->swap( *facets_old ); +//----------------------------------------------------------------------------------- +void +LevelSet::advance_semilagrangian(const double timeN, const double timeNp1) +{ + STK_ThrowRequireMsg(myInterfaceVelocity.size() == spatial_dimension, "Did not find interface velocity expression. Was it provided?"); - // get non-local facets such that we have copies of all old facets - // within the range of this proc's nodes - prepare_to_compute_distance( deltaTime, selector ); + const stk::mesh::Selector activeFieldSelector = aux_meta().active_not_ghost_selector() & stk::mesh::selectField(get_distance_field()); + BoundingBox nodeBBox = krino::compute_nodal_bbox(mesh(), activeFieldSelector, get_coordinates_field()); - // compute nodal distances with semi-lagrangian step - stk::mesh::field_copy(my_old_distance_field, my_distance_field); - compute_distance_semilagrangian( deltaTime, selector ); + const double timeMid = 0.5*(timeN+timeNp1); + const double velMag = (2==spatial_dimension) ? + compute_max_facet_velocity_magnitude(timeMid, facets->get_facets_2d(), myInterfaceVelocity) : + compute_max_facet_velocity_magnitude(timeMid, facets->get_facets_3d(), myInterfaceVelocity); + const double paddingFactorOfSafety = 1.5; + nodeBBox.pad(paddingFactorOfSafety*velMag*(timeNp1-timeN)); // Need something better? - // build local facet list - build_facets_locally(my_meta.universal_part()); + facets->prepare_to_compute(nodeBBox, my_narrow_band_size); - // debugging - if (krinolog.shouldPrint(LOG_FACETS)) - { - write_facets(); - } + stk::mesh::field_copy(my_old_distance_field, my_distance_field); // 0th order predictor needed for preserving sign with narrow_band + compute_distance_semilagrangian( timeN, timeNp1, activeFieldSelector ); + + facets->swap( *facets_old ); // store existing facets in facets_old + + build_facets_locally(my_meta.universal_part()); + + // debugging + if (krinolog.shouldPrint(LOG_FACETS)) + { + write_facets(); } } @@ -756,10 +779,10 @@ void LevelSet::redistance_using_existing_facets(const stk::mesh::Selector & volu // get non-local facets such that we have copies of all "old" facets // within the range of this proc's nodes - prepare_to_compute_distance( 0., volumeSelector ); + prepare_to_compute_distance_to_stationary_facets( volumeSelector ); // compute nodal distances with semi-lagrangian step - compute_distance_semilagrangian( 0., volumeSelector ); + compute_signed_distance_at_selected_nodes( volumeSelector ); // swap so that the facets that were formed remain in the vector facets facets->swap( *facets_old ); @@ -831,46 +854,6 @@ static std::vector get_owned_and_shared_interface_and_child_e return initialNodes; } -void -LevelSet::interface_conforming_redistance() -{ - if (FAST_MARCHING == my_redistance_method) - krinolog << "Redistancing the level set field using CDFEM fast marching method..." << stk::diag::dendl; - else - krinolog << "Redistancing the level set field using CDFEM method..." << stk::diag::dendl; - - build_interface_conforming_facets(); - - sync_all_fields_to_host(); - - if (FAST_MARCHING == my_redistance_method) - fast_marching_interface_conforming_redistance_using_existing_facets(); - else - redistance_using_existing_facets(my_meta.universal_part()); -} - -void -LevelSet::fast_marching_interface_conforming_redistance_using_existing_facets() -{ - const auto & phaseSupport = Phase_Support::get(meta()); - const stk::mesh::Selector interfaceSelector = phaseSupport.get_negative_levelset_interface_selector(my_identifier); - const CDFEM_Support & cdfemSupport = CDFEM_Support::get(meta()); - const std::vector initialNodes = get_owned_and_shared_interface_and_child_element_nodes(mesh(), aux_meta(), cdfemSupport, interfaceSelector); - - redistance_nodes_using_existing_facets(initialNodes); - - const stk::mesh::Selector activeVolumeSelector = aux_meta().active_part(); - - std::function get_interface_speed; - Fast_Marching fm(mesh(), - activeVolumeSelector, - get_coordinates_field(), - get_distance_field(), - get_interface_speed, - my_redistance_timer); - fm.redistance(initialNodes); -} - static bool determine_polarity_for_negative_side_of_interface(const stk::mesh::BulkData & mesh, const stk::mesh::Selector & negativeSideElementSelector, const stk::mesh::Entity side) { const stk::topology sideTopology = mesh.bucket(side).topology(); @@ -886,6 +869,16 @@ static bool determine_polarity_for_negative_side_of_interface(const stk::mesh::B return false; } +static std::array get_triangle_side_vector(const stk::mesh::BulkData & mesh, const FieldRef vecField, const std::array triangleNodes) +{ + return {{ get_vector_field(mesh, vecField, triangleNodes[0]), get_vector_field(mesh, vecField, triangleNodes[1]), get_vector_field(mesh, vecField, triangleNodes[2]) }}; +} + +static std::array get_line_side_vector(const stk::mesh::BulkData & mesh, const FieldRef vecField, const std::array lineNodes) +{ + return {{ get_vector_field(mesh, vecField, lineNodes[0], 2), get_vector_field(mesh, vecField, lineNodes[1], 2) }}; +} + static std::array get_oriented_triangle_side_nodes(const stk::mesh::BulkData & mesh, const stk::mesh::Selector & negativeSideElementSelector, const stk::mesh::Entity side) { const stk::mesh::Entity* sideNodes = mesh.begin_nodes(side); @@ -896,12 +889,11 @@ static std::array get_oriented_triangle_side_nodes(const st return {{sideNodes[0], sideNodes[2], sideNodes[1]}}; } -static void append_facets_from_triangle_side(const stk::mesh::BulkData & mesh, const FieldRef coords, const stk::mesh::Selector & interfaceSelector, const stk::mesh::Selector & negativeSideElementSelector, const stk::mesh::Entity side, FacetedSurfaceBase & facets) +static void append_facet_from_triangle_side(const stk::mesh::BulkData & mesh, const FieldRef coords, const stk::mesh::Selector & interfaceSelector, const stk::mesh::Selector & negativeSideElementSelector, const stk::mesh::Entity side, std::vector & facets) { const std::array orientedSideNodes = get_oriented_triangle_side_nodes(mesh, negativeSideElementSelector, side); - - const std::array sideNodeCoords{{stk::math::Vector3d(field_data(coords, orientedSideNodes[0]), 3), stk::math::Vector3d(field_data(coords, orientedSideNodes[1]), 3), stk::math::Vector3d(field_data(coords, orientedSideNodes[2]), 3)}}; - facets.emplace_back_3d( sideNodeCoords[0], sideNodeCoords[1], sideNodeCoords[2] ); + const std::array sideNodeCoords = get_triangle_side_vector(mesh, coords, orientedSideNodes); + facets.emplace_back( sideNodeCoords[0], sideNodeCoords[1], sideNodeCoords[2] ); } static std::array get_oriented_line_side_nodes(const stk::mesh::BulkData & mesh, const stk::mesh::Selector & negativeSideElementSelector, const stk::mesh::Entity side) @@ -914,38 +906,223 @@ static std::array get_oriented_line_side_nodes(const stk::m return {{sideNodes[1], sideNodes[0]}}; } -static void append_facets_from_line_side(const stk::mesh::BulkData & mesh, const FieldRef coords, const stk::mesh::Selector & sideSelector, const stk::mesh::Selector & negativeSideElementSelector, const stk::mesh::Entity side, FacetedSurfaceBase & facets) +static void append_facet_from_line_side(const stk::mesh::BulkData & mesh, const FieldRef coords, const stk::mesh::Selector & sideSelector, const stk::mesh::Selector & negativeSideElementSelector, const stk::mesh::Entity side, std::vector & facets) +{ + const std::array orientedSideNodes = get_oriented_line_side_nodes(mesh, negativeSideElementSelector, side); + const std::array sideNodeCoords = get_line_side_vector(mesh, coords, orientedSideNodes); + facets.emplace_back(sideNodeCoords[0], sideNodeCoords[1]); +} + +static void append_facet_with_velocity_from_triangle_side(const stk::mesh::BulkData & mesh, const FieldRef coords, const FieldRef interfaceVelocity, const stk::mesh::Selector & interfaceSelector, const stk::mesh::Selector & negativeSideElementSelector, const stk::mesh::Entity side, std::vector & facets) +{ + const std::array orientedSideNodes = get_oriented_triangle_side_nodes(mesh, negativeSideElementSelector, side); + const std::array sideNodeCoords = get_triangle_side_vector(mesh, coords, orientedSideNodes); + const std::array sideNodeVelocity = get_triangle_side_vector(mesh, interfaceVelocity, orientedSideNodes); + facets.emplace_back( sideNodeCoords[0], sideNodeCoords[1], sideNodeCoords[2], sideNodeVelocity[0], sideNodeVelocity[1], sideNodeVelocity[2] ); +} + +static void append_facet_with_velocity_from_line_side(const stk::mesh::BulkData & mesh, const FieldRef coords, const FieldRef interfaceVelocity, const stk::mesh::Selector & sideSelector, const stk::mesh::Selector & negativeSideElementSelector, const stk::mesh::Entity side, std::vector & facets) { const std::array orientedSideNodes = get_oriented_line_side_nodes(mesh, negativeSideElementSelector, side); + const std::array sideNodeCoords = get_line_side_vector(mesh, coords, orientedSideNodes); + const std::array sideNodeVelocity = get_line_side_vector(mesh, interfaceVelocity, orientedSideNodes); + facets.emplace_back( sideNodeCoords[0], sideNodeCoords[1], sideNodeVelocity[0], sideNodeVelocity[1] ); +} - const std::array sideNodeCoords{{stk::math::Vector3d(field_data(coords, orientedSideNodes[0]), 2), stk::math::Vector3d(field_data(coords, orientedSideNodes[1]), 2)}}; - facets.emplace_back_2d(sideNodeCoords[0], sideNodeCoords[1]); +static void append_owned_facets_from_triangle_sides(const stk::mesh::BulkData & mesh, + const FieldRef cooordsField, + const stk::mesh::Selector & sideSelector, + const stk::mesh::Selector & negativeSideElementSelector, + std::vector & facets) +{ + for ( auto & bucket : mesh.get_buckets( mesh.mesh_meta_data().side_rank(), sideSelector & mesh.mesh_meta_data().locally_owned_part()) ) + { + STK_ThrowRequire(bucket->topology() == stk::topology::TRIANGLE_3); + for (auto & side : *bucket) + append_facet_from_triangle_side(mesh, cooordsField, sideSelector, negativeSideElementSelector, side, facets); + } } -void LevelSet::append_facets_from_side(const stk::mesh::Selector & sideSelector, const stk::mesh::Selector & negativeSideElementSelector, const stk::mesh::Entity side) +static void append_owned_facets_from_line_sides(const stk::mesh::BulkData & mesh, + const FieldRef cooordsField, + const stk::mesh::Selector & sideSelector, + const stk::mesh::Selector & negativeSideElementSelector, + std::vector & facets) { - if (mesh().bucket(side).topology() == stk::topology::TRIANGLE_3) - append_facets_from_triangle_side(mesh(), get_coordinates_field(), sideSelector, negativeSideElementSelector, side, *facets); - else if (mesh().bucket(side).topology() == stk::topology::LINE_2) - append_facets_from_line_side(mesh(), get_coordinates_field(), sideSelector, negativeSideElementSelector, side, *facets); + for ( auto & bucket : mesh.get_buckets( mesh.mesh_meta_data().side_rank(), sideSelector & mesh.mesh_meta_data().locally_owned_part()) ) + { + STK_ThrowRequire(bucket->topology() == stk::topology::LINE_2); + for (auto & side : *bucket) + append_facet_from_line_side(mesh, cooordsField, sideSelector, negativeSideElementSelector, side, facets); + } +} + +static void append_owned_facets_with_velocity_from_triangle_sides(const stk::mesh::BulkData & mesh, + const FieldRef cooordsField, + const FieldRef interfaceVelocity, + const stk::mesh::Selector & sideSelector, + const stk::mesh::Selector & negativeSideElementSelector, + std::vector & facets) +{ + for ( auto & bucket : mesh.get_buckets( mesh.mesh_meta_data().side_rank(), sideSelector & mesh.mesh_meta_data().locally_owned_part()) ) + { + STK_ThrowRequire(bucket->topology() == stk::topology::TRIANGLE_3); + for (auto & side : *bucket) + append_facet_with_velocity_from_triangle_side(mesh, cooordsField, interfaceVelocity, sideSelector, negativeSideElementSelector, side, facets); + } +} + +static void append_owned_facets_with_velocity_from_line_sides(const stk::mesh::BulkData & mesh, + const FieldRef cooordsField, + const FieldRef interfaceVelocity, + const stk::mesh::Selector & sideSelector, + const stk::mesh::Selector & negativeSideElementSelector, + std::vector & facets) +{ + for ( auto & bucket : mesh.get_buckets( mesh.mesh_meta_data().side_rank(), sideSelector & mesh.mesh_meta_data().locally_owned_part()) ) + { + STK_ThrowRequire(bucket->topology() == stk::topology::LINE_2); + for (auto & side : *bucket) + append_facet_with_velocity_from_line_side(mesh, cooordsField, interfaceVelocity, sideSelector, negativeSideElementSelector, side, facets); + } +} + +static void build_interface_conforming_facets(const stk::mesh::BulkData & mesh, + const Phase_Support & phaseSupport, + const stk::mesh::Part & activePart, + const FieldRef coordsField, + const Surface_Identifier lsIdentifier, + FacetedSurfaceBase & facets) +{ + const stk::mesh::Selector interfaceSelector = phaseSupport.get_negative_levelset_interface_selector(lsIdentifier); + const stk::mesh::Selector negativeSideBlockSelector = phaseSupport.get_negative_levelset_block_selector(lsIdentifier); + + const stk::mesh::Selector sideSelector = interfaceSelector & activePart; + const stk::mesh::Selector ownedSideSelector = sideSelector & mesh.mesh_meta_data().locally_owned_part(); + + facets.clear(); + if (3 == mesh.mesh_meta_data().spatial_dimension()) + append_owned_facets_from_triangle_sides(mesh, coordsField, sideSelector, negativeSideBlockSelector, facets.as_derived_type().get_facets()); + else + append_owned_facets_from_line_sides(mesh, coordsField, sideSelector, negativeSideBlockSelector, facets.as_derived_type().get_facets()); +} + +static void build_interface_conforming_facets_with_interface_velocity(const stk::mesh::BulkData & mesh, + const Phase_Support & phaseSupport, + const stk::mesh::Part & activePart, + const FieldRef coordsField, + const FieldRef interfaceVelocity, + const Surface_Identifier lsIdentifier, + FacetedSurfaceBase & facets) +{ + const stk::mesh::Selector interfaceSelector = phaseSupport.get_negative_levelset_interface_selector(lsIdentifier); + const stk::mesh::Selector negativeSideBlockSelector = phaseSupport.get_negative_levelset_block_selector(lsIdentifier); + + const stk::mesh::Selector sideSelector = interfaceSelector & activePart; + const stk::mesh::Selector ownedSideSelector = sideSelector & mesh.mesh_meta_data().locally_owned_part(); + + facets.clear(); + if (3 == mesh.mesh_meta_data().spatial_dimension()) + append_owned_facets_with_velocity_from_triangle_sides(mesh, coordsField, interfaceVelocity, sideSelector, negativeSideBlockSelector, facets.as_derived_type().get_facets()); + else + append_owned_facets_with_velocity_from_line_sides(mesh, coordsField, interfaceVelocity, sideSelector, negativeSideBlockSelector, facets.as_derived_type().get_facets()); } void -LevelSet::build_interface_conforming_facets() +LevelSet::interface_conforming_redistance() +{ + if (FAST_MARCHING == my_redistance_method) + krinolog << "Redistancing the level set field using CDFEM fast marching method..." << stk::diag::dendl; + else + krinolog << "Redistancing the level set field using CDFEM method..." << stk::diag::dendl; + + sync_all_fields_to_host(); + + const auto & phaseSupport = Phase_Support::get(meta()); + build_interface_conforming_facets(mesh(), phaseSupport, aux_meta().active_part(), get_coordinates_field(), my_identifier, *facets); + + if (FAST_MARCHING == my_redistance_method) + fast_marching_interface_conforming_redistance_using_existing_facets(); + else + redistance_using_existing_facets(my_meta.universal_part()); +} + +void +LevelSet::fast_marching_interface_conforming_redistance_using_existing_facets() { const auto & phaseSupport = Phase_Support::get(meta()); const stk::mesh::Selector interfaceSelector = phaseSupport.get_negative_levelset_interface_selector(my_identifier); - const stk::mesh::Selector negativeSideBlockSelector = phaseSupport.get_negative_levelset_block_selector(my_identifier); + const CDFEM_Support & cdfemSupport = CDFEM_Support::get(meta()); + const std::vector initialNodes = get_owned_and_shared_interface_and_child_element_nodes(mesh(), aux_meta(), cdfemSupport, interfaceSelector); - const stk::mesh::Selector sideSelector = interfaceSelector & aux_meta().active_part(); - const stk::mesh::Selector ownedSideSelector = sideSelector & meta().locally_owned_part(); + redistance_nodes_using_existing_facets(initialNodes); - std::vector< stk::mesh::Entity> sides; - stk::mesh::get_selected_entities( ownedSideSelector, mesh().buckets( meta().side_rank() ), sides ); + const stk::mesh::Selector activeVolumeSelector = aux_meta().active_part(); - facets->clear(); - for (auto && side : sides) - append_facets_from_side(sideSelector, negativeSideBlockSelector, side); + std::function get_interface_speed; + Fast_Marching fm(mesh(), + activeVolumeSelector, + get_coordinates_field(), + get_distance_field(), + get_interface_speed, + my_redistance_timer); + fm.redistance(initialNodes); +} + +template +void extend_velocity_to_selected_nodes(const stk::mesh::BulkData & mesh, + const stk::mesh::Selector & nodeSelector, + const FieldRef coordsField, + const FieldRef extendedVelocity, + const Faceted_Surface & interfaceFacets) +{ + for ( auto && bucketPtr : mesh.get_buckets( stk::topology::NODE_RANK, nodeSelector) ) + { + const size_t length = bucketPtr->size(); + const double *coordsData = field_data(coordsField, *bucketPtr); + double *extVelData = field_data(extendedVelocity, *bucketPtr); + + for (size_t i = 0; i < length; ++i) + { + const stk::math::Vector3d nodeCoords(coordsData+i*FACET::DIM, FACET::DIM); + const auto * nearest = interfaceFacets.get_closest_facet(nodeCoords); + const stk::math::Vector3d nearestVel = nearest->velocity_at_closest_point(nodeCoords); + for (int d=0; d interfaceFacets = FacetedSurfaceBase::build_with_velocity(nDim); + const auto & phaseSupport = Phase_Support::get(mesh.mesh_meta_data()); + const auto & auxMeta = AuxMetaData::get(mesh.mesh_meta_data()); + build_interface_conforming_facets_with_interface_velocity(mesh, phaseSupport, auxMeta.active_part(), coordsField, interfaceVelocity, lsIdentifier, *interfaceFacets); + + const stk::mesh::Selector nodeSelector = auxMeta.active_not_ghost_selector() & stk::mesh::selectField(extendedVelocity); + + BoundingBox nodeBBox = krino::compute_nodal_bbox(mesh, nodeSelector, coordsField); + interfaceFacets->prepare_to_compute(nodeBBox, 0.); + + if (3 == nDim) + extend_velocity_to_selected_nodes(mesh, nodeSelector, coordsField, extendedVelocity, interfaceFacets->as_derived_type()); + else + extend_velocity_to_selected_nodes(mesh, nodeSelector, coordsField, extendedVelocity, interfaceFacets->as_derived_type()); +} + +void LevelSet::set_interface_velocity( const std::vector & interfaceVelocity ) +{ + myInterfaceVelocity.clear(); + myInterfaceVelocity.reserve(interfaceVelocity.size()); + for (auto & component : interfaceVelocity) + myInterfaceVelocity.emplace_back(component); } double @@ -1205,153 +1382,82 @@ LevelSet::compute_continuous_gradient() const //----------------------------------------------------------------------------------- void -LevelSet::compute_nodal_bbox( const stk::mesh::Selector & selector, - BoundingBox & node_bbox, - const stk::math::Vector3d & displacement ) const -{ /* %TRACE[ON]% */ Trace trace__("krino::LevelSet::compute_nodal_bbox( BoundingBox & node_bboxes, const double & deltaTime ) const"); /* %TRACE% */ - - // find the local nodal bounding box - - const FieldRef xField = get_coordinates_field(); - const FieldRef dField = get_distance_field(); - - const stk::mesh::Selector active_field_selector = aux_meta().active_not_ghost_selector() & selector & stk::mesh::selectField(dField); - - node_bbox = krino::compute_nodal_bbox(mesh(), active_field_selector, xField); - node_bbox.shift(-displacement); -} - -//----------------------------------------------------------------------------------- - -void -LevelSet::prepare_to_compute_distance( const double & deltaTime, const stk::mesh::Selector & selector ) -{ /* %TRACE[ON]% */ Trace trace__("krino::LevelSet::get_nonlocal_facets( const double & deltaTime )"); /* %TRACE% */ - - // Get all of the facets that are within our processor's bounding box - // To do this, see if any local facets lie in the nodal bounding box - // of another proc. if so, send them a copy of those facets - - // First, find the bounding box for each proc that contains all of the - // nodes on that proc plus the narrow_band size - - BoundingBox node_bbox; - const stk::math::Vector3d displacement = deltaTime * get_extension_velocity(); - compute_nodal_bbox( selector, node_bbox, displacement ); +LevelSet::prepare_to_compute_distance_to_stationary_facets( const stk::mesh::Selector & selector ) +{ + const stk::mesh::Selector activeFieldSelector = aux_meta().active_not_ghost_selector() & selector & stk::mesh::selectField(get_distance_field()); + const BoundingBox nodeBBox = krino::compute_nodal_bbox(mesh(), activeFieldSelector, get_coordinates_field()); - facets_old->prepare_to_compute(node_bbox, my_narrow_band_size); + facets_old->prepare_to_compute(nodeBBox, my_narrow_band_size); } //----------------------------------------------------------------------------------- void -LevelSet::compute_distance_semilagrangian( const double & deltaTime, const stk::mesh::Selector & selector ) -{ /* %TRACE[ON]% */ Trace trace__("krino::LevelSet::compute_distance_semilagrangian( const double & deltaTime ) const"); /* %TRACE% */ - +LevelSet::compute_signed_distance_at_selected_nodes( const stk::mesh::Selector & selector ) +{ const double h_avg = compute_average_edge_length(); - const FieldRef xField = get_coordinates_field(); - const FieldRef dField = get_distance_field(); - const stk::math::Vector3d extv = get_extension_velocity(); + const FieldRef coordsField = get_coordinates_field(); + const FieldRef distField = get_distance_field(); - const stk::mesh::Selector active_field_selector = aux_meta().active_not_ghost_selector() & selector & stk::mesh::selectField(dField); + const stk::mesh::Selector active_field_selector = aux_meta().active_not_ghost_selector() & selector & stk::mesh::selectField(distField); stk::mesh::BucketVector const& buckets = mesh().get_buckets(stk::topology::NODE_RANK, active_field_selector); - for ( auto && bucket : buckets ) - { - const stk::mesh::Bucket & b = *bucket; + // If this is too large, then sharp edges can propagate incorrect signs + // (even through walls, etc). + // If this is too small, then a phase can't disappear because the sign + // preservation will prevent it even if the subelement contouring process + // neglects it. So this should be slightly larger than the tolerance in + // compute_subelement_decomposition. + const double signChangeTol = 5.e-4*h_avg; - const size_t length = b.size(); - - double *d = field_data( dField , b); - double *x = field_data( xField , b); + for ( auto && bucketPtr : buckets ) + { + const double * coordsData = field_data( coordsField , *bucketPtr); + double * distData = field_data( distField , *bucketPtr); - // Handle special case of ( deltaTime == 0. ) so that we - // can handle situation where velocity is not defined at all - // nodes where distance is defined. (This is currently a requirement - // for regular semilagrangian advancement). - if ( deltaTime == 0. ) + for (size_t i = 0; i < bucketPtr->size(); ++i) { - for (size_t i = 0; i < length; ++i) - { - stk::math::Vector3d x_node(stk::math::Vector3d::ZERO); - for ( unsigned dim = 0; dim < spatial_dimension; ++dim ) - { - int index = i*spatial_dimension+dim; - x_node[dim] = x[index]; - } + const stk::math::Vector3d nodeCoords(coordsData+i*spatial_dimension, spatial_dimension); - int previous_sign = LevelSet::sign(d[i]); - // If this is too large, then sharp edges can propagate incorrect signs - // (even through walls, etc). - // If this is too small, then a phase can't disappear because the sign - // preservation will prevent it even if the subelement contouring process - // neglects it. So this should be slightly larger than the tolerance in - // compute_subelement_decomposition. - bool enforce_sign = (std::abs(d[i]) > 5.e-4*h_avg); + const int previousSign = LevelSet::sign(distData[i]); + const bool doEnforceSign = (std::abs(distData[i]) > signChangeTol); - d[i] = distance( x_node, previous_sign, enforce_sign ); - } + distData[i] = distance( nodeCoords, previousSign, doEnforceSign ); } - else - { - for (size_t i = 0; i < length; ++i) - { - stk::math::Vector3d x_bw(stk::math::Vector3d::ZERO); - for ( unsigned dim = 0; dim < spatial_dimension; ++dim ) - { - int index = i*spatial_dimension+dim; - x_bw[dim] = x[index] - extv[dim] * deltaTime; - } - - int previous_sign = LevelSet::sign(d[i]); - - d[i] = distance( x_bw, previous_sign, false ); - } - } - } // end bucket loop + } } -//----------------------------------------------------------------------------------- - void -LevelSet::compute_distance( stk::mesh::Entity n, - const double & deltaTime ) const -{ /* %TRACE% */ /* %TRACE% */ - - // use the facet cell array to compute the distance to a node n - - const FieldRef xField = get_coordinates_field(); - const FieldRef dField = get_distance_field(); - const stk::math::Vector3d extv = get_extension_velocity(); +LevelSet::compute_distance_semilagrangian( const double & timeN, const double & timeNp1, const stk::mesh::Selector & selector ) +{ + const FieldRef coordsField = get_coordinates_field(); + const FieldRef distField = get_distance_field(); + const double dt = timeNp1 - timeN; - double *x = field_data( xField , n); - double *d = field_data( dField , n); + const stk::mesh::Selector active_field_selector = aux_meta().active_not_ghost_selector() & selector & stk::mesh::selectField(distField); + stk::mesh::BucketVector const& buckets = mesh().get_buckets(stk::topology::NODE_RANK, active_field_selector); - // Handle special case of ( deltaTime == 0. ) so that we - // can handle situation where velocity is not defined at all - // nodes where distance is defined. (This is currently a requirement - // for regular semilagrangian advancement). - if ( deltaTime == 0. ) + for ( auto && bucketPtr : buckets ) { - stk::math::Vector3d x_node(stk::math::Vector3d::ZERO); - for ( unsigned dim = 0; dim < spatial_dimension; ++dim ) - { - x_node[dim] = x[dim]; - } + const double * coordsData = field_data( coordsField , *bucketPtr); + double * distData = field_data( distField , *bucketPtr); - int previous_sign = LevelSet::sign(*d); - *d = distance( x_node, previous_sign, true ); - } - else - { - stk::math::Vector3d x_bw(stk::math::Vector3d::ZERO); - for ( unsigned dim = 0; dim < spatial_dimension; ++dim ) + for (size_t i = 0; i < bucketPtr->size(); ++i) { - x_bw[dim] = x[dim] - extv[dim] * deltaTime; - } + const stk::math::Vector3d nodeCoords(coordsData+i*spatial_dimension, spatial_dimension); + const stk::math::Vector3d closestPtN = facets->closest_point(nodeCoords); + const auto velN = compute_interface_velocity_at_point(spatial_dimension, timeN, closestPtN, myInterfaceVelocity); - int previous_sign = LevelSet::sign(*d); - *d = distance( x_bw, previous_sign, false ); + const stk::math::Vector3d coordsHalf = nodeCoords - 0.5*dt*velN; + const stk::math::Vector3d closestPtHalf = facets->closest_point(coordsHalf); + const auto velHalf = compute_interface_velocity_at_point(spatial_dimension, 0.5*(timeN+timeNp1), closestPtHalf, myInterfaceVelocity); + + const stk::math::Vector3d coordsNp1 = nodeCoords - dt*velHalf; + + const int previousSign = LevelSet::sign(distData[i]); + distData[i] = facets->truncated_point_signed_distance(coordsNp1, my_narrow_band_size, previousSign*my_narrow_band_size); + } } } @@ -1800,7 +1906,6 @@ LevelSet::gradient_magnitude_error(void) const FieldRef isoField = get_isovar_field(); xField.field().sync_to_host(); isoField.field().sync_to_host(); - //const Vector3d extv = get_extension_velocity(); stk::mesh::Selector active_field_selector = stk::mesh::selectField(isoField) & aux_meta().active_locally_owned_selector(); std::vector< stk::mesh::Entity> objs; @@ -1916,7 +2021,6 @@ LevelSet::LevelSet(stk::mesh::MetaData & in_meta, my_redistance_method(CLOSEST_POINT), epsilon(1.0e-16), trackIsoSurface(false), - my_facetFileIndex(1), my_needs_reinitialize_every_step(false) { /* %TRACE[ON]% */ Trace trace__("krino::LevelSet::LevelSet(stk::mesh::MetaData & in_meta, const std::string & ls_name, stk::diag::Timer & parent_timer)"); /* %TRACE% */ my_coordinates_field = my_aux_meta.get_current_coordinates(); diff --git a/packages/krino/krino/krino_lib/Akri_LevelSet.hpp b/packages/krino/krino/krino_lib/Akri_LevelSet.hpp index e31d8c558569..7427747219c2 100644 --- a/packages/krino/krino/krino_lib/Akri_LevelSet.hpp +++ b/packages/krino/krino/krino_lib/Akri_LevelSet.hpp @@ -37,6 +37,7 @@ namespace krino { class AuxMetaData; } namespace krino { class IC_Alg; } namespace krino { class ParallelErrorMessage; } namespace krino { class ContourElement; } +namespace krino { class String_Function_Expression; } namespace krino { @@ -73,7 +74,7 @@ friend class LevelSet_Size; void register_fields(); - void advance_semilagrangian(const double deltaTime); + void advance_semilagrangian(const double timeN, const double timeNP1); static void gather_nodal_field( const stk::mesh::BulkData& stk_mesh, @@ -93,9 +94,6 @@ friend class LevelSet_Size; double gradient_magnitude_error(); void compute_continuous_gradient() const; - void compute_distance( stk::mesh::Entity n, - const double & deltaTime ) const; - void increment_distance(const double increment, const bool enforce_sign = false, const double & signChangePurtubationTol = 0.5); void estimate_error(); @@ -124,8 +122,8 @@ friend class LevelSet_Size; const FieldRef & get_old_distance_field() const { return my_old_distance_field; } void set_old_distance_field( const FieldRef & ref ) { my_old_distance_field = ref; } - void set_extension_velocity( const stk::math::Vector3d & extension_velocity ) { my_extension_velocity = extension_velocity; } - const stk::math::Vector3d & get_extension_velocity() const { return my_extension_velocity; } + void set_interface_velocity( const std::vector & interfaceVelocity ); + const std::vector & get_interface_velocity() const { return myInterfaceVelocity; } const FieldRef & get_coordinates_field() const { return my_coordinates_field; } @@ -203,6 +201,7 @@ friend class LevelSet_Size; void fast_methods_redistance(const stk::mesh::Selector & selector, const bool compute_time_of_arrival = false); void interface_conforming_redistance(); void fast_marching_interface_conforming_redistance_using_existing_facets(); + static void extend_interface_velocity_using_closest_point_projection(const stk::mesh::BulkData & mesh, const FieldRef coordsField, const FieldRef interfaceVelocity, const FieldRef extendedVelocity, const Surface_Identifier lsIdentifier); std::pair get_conserved_negative_volume_and_time() const; void set_conserved_negative_volume_and_time(const double vol, const double time); @@ -212,10 +211,6 @@ friend class LevelSet_Size; double constrained_redistance(const bool use_initial_vol = false, const double & signChangePurtubationTol = 0.5); void locally_conserved_redistance(); - void compute_nodal_bbox( const stk::mesh::Selector & selector, - BoundingBox & node_bbox, - const stk::math::Vector3d & displacement = stk::math::Vector3d::ZERO ) const; - double find_redistance_correction( const double start_area, const double start_neg_vol, const double start_pos_vol, @@ -236,7 +231,6 @@ friend class LevelSet_Size; void redistance_using_existing_facets(const stk::mesh::Selector & volumeSelector); void redistance_nodes_using_existing_facets(const std::vector & nodesToRedistance); void append_facets_from_side(const stk::mesh::Selector & interfaceSelector, const stk::mesh::Selector & negativeSideElementSelector, const stk::mesh::Entity side); - void build_interface_conforming_facets(); stk::mesh::MetaData & my_meta; AuxMetaData & my_aux_meta; @@ -290,13 +284,13 @@ friend class LevelSet_Size; // vector of current facets std::unique_ptr facets; - stk::math::Vector3d my_extension_velocity; + std::vector myInterfaceVelocity; const double epsilon; bool trackIsoSurface; // used to increment file name for facet exoii database hack - int my_facetFileIndex; + int my_facetFileIndex{0}; double myConservedNegVolume{0.0}; double myConservedNegVolumeTime{0.0}; @@ -313,9 +307,10 @@ friend class LevelSet_Size; void time_integrate(const double deltaTime); - void prepare_to_compute_distance( const double & deltaTime, const stk::mesh::Selector & selector ); + void prepare_to_compute_distance_to_stationary_facets( const stk::mesh::Selector & selector ); - void compute_distance_semilagrangian(const double & deltaTime, const stk::mesh::Selector & selector ); + void compute_signed_distance_at_selected_nodes( const stk::mesh::Selector & selector ); + void compute_distance_semilagrangian( const double & timeN, const double & timeNp1, const stk::mesh::Selector & selector ); double distance( const stk::math::Vector3d & x, const int previous_sign, diff --git a/packages/krino/krino/krino_lib/Akri_LevelSetInterfaceGeometry.cpp b/packages/krino/krino/krino_lib/Akri_LevelSetInterfaceGeometry.cpp index 6a646b814f3f..676d6b97f21c 100644 --- a/packages/krino/krino/krino_lib/Akri_LevelSetInterfaceGeometry.cpp +++ b/packages/krino/krino/krino_lib/Akri_LevelSetInterfaceGeometry.cpp @@ -554,6 +554,12 @@ void LevelSetInterfaceGeometry::prepare_to_decompose_elements(const stk::mesh::B build_parent_edges_for_mesh(mesh, nodesToCapturedDomains); } +void LevelSetInterfaceGeometry::prepare_to_intersect_elements(const stk::mesh::BulkData & mesh) const +{ + const NodeToCapturedDomainsMap emptyNodesToCapturedDomains; + prepare_to_intersect_elements(mesh, emptyNodesToCapturedDomains); +} + void LevelSetInterfaceGeometry::prepare_to_intersect_elements(const stk::mesh::BulkData & mesh, const NodeToCapturedDomainsMap & nodesToCapturedDomains) const { @@ -625,46 +631,47 @@ std::vector LevelSetInterfaceGeometry::get_possibly_cut_eleme return get_active_elements_that_may_be_cut_by_levelsets(mesh, myActivePart, myLSFields); } -static void fill_node_distances(const stk::mesh::BulkData & mesh, const LS_Field & LSField, const stk::mesh::Entity elem, std::vector & nodeDist) +static void fill_node_levelset(const stk::mesh::BulkData & mesh, const LS_Field & LSField, const stk::mesh::Entity elem, std::vector & nodeLS) { - nodeDist.clear(); + nodeLS.clear(); for (auto node : StkMeshEntities{mesh.begin_nodes(elem), mesh.end_nodes(elem)}) { - const double * distPtr = field_data(LSField.isovar, node); - if (distPtr) - nodeDist.push_back(*distPtr); + const double * lsPtr = field_data(LSField.isovar, node); + if (lsPtr) + nodeLS.push_back(*lsPtr); } } -static bool element_intersects_interval(const stk::mesh::BulkData & mesh, const std::vector & LSFields, const stk::mesh::Entity elem, const std::array & loAndHi, std::vector & elemNodeDistWorkspace) +static bool element_intersects_distance_interval(const stk::mesh::BulkData & mesh, const LS_Field & LSField, const stk::mesh::Entity elem, const std::array & loAndHi, std::vector & elemNodeDistWorkspace) { - for(auto && LSField : LSFields) - { - fill_node_distances(mesh, LSField, elem, elemNodeDistWorkspace); - if (elemNodeDistWorkspace.size() == mesh.num_nodes(elem) && InterfaceGeometry::element_with_nodal_distance_intersects_interval(elemNodeDistWorkspace, loAndHi)) - return true; - } - return false; + // Note that levelset is assumed to signed distance here + fill_node_levelset(mesh, LSField, elem, elemNodeDistWorkspace); + return (elemNodeDistWorkspace.size() == mesh.num_nodes(elem) && InterfaceGeometry::element_with_nodal_distance_intersects_distance_interval(elemNodeDistWorkspace, loAndHi)); } -std::vector LevelSetInterfaceGeometry::get_active_elements_that_intersect_levelset_interval(const stk::mesh::BulkData & mesh, const stk::mesh::Part & activePart, const std::vector & LSFields, const std::array loAndHi) +void LevelSetInterfaceGeometry::fill_active_elements_that_intersect_levelset_interval(const stk::mesh::BulkData & mesh, const stk::mesh::Part & activePart, const LS_Field & lsField, const std::array loAndHi, std::vector & elementsThaIntersectInterval) { - std::vector elementsThaIntersectInterval; std::vector elementNodeDist; const stk::mesh::Selector activeLocallyOwned = activePart & mesh.mesh_meta_data().locally_owned_part(); + elementsThaIntersectInterval.clear(); for(const auto & bucketPtr : mesh.get_buckets(stk::topology::ELEMENT_RANK, activeLocallyOwned)) for(const auto & elem : *bucketPtr) - if (element_intersects_interval(mesh, LSFields, elem, loAndHi, elementNodeDist)) + if (element_intersects_distance_interval(mesh, lsField, elem, loAndHi, elementNodeDist)) elementsThaIntersectInterval.push_back(elem); +} - return elementsThaIntersectInterval; +const LS_Field & LevelSetInterfaceGeometry::get_ls_field_with_identifier(const Surface_Identifier surfaceIdentifier) const +{ + auto iter = std::find(mySurfaceIdentifiers.begin(), mySurfaceIdentifiers.end(), surfaceIdentifier); + STK_ThrowRequire(iter != mySurfaceIdentifiers.end()); + return myLSFields[std::distance(mySurfaceIdentifiers.begin(), iter)]; } -std::vector LevelSetInterfaceGeometry::get_elements_that_intersect_interval(const stk::mesh::BulkData & mesh, const std::array loAndHi) const +void LevelSetInterfaceGeometry::fill_elements_that_intersect_distance_interval(const stk::mesh::BulkData & mesh, const Surface_Identifier surfaceIdentifier, const std::array loAndHi, std::vector & elementsThaIntersectInterval) const { - return get_active_elements_that_intersect_levelset_interval(mesh, myActivePart, myLSFields, loAndHi); + fill_active_elements_that_intersect_levelset_interval(mesh, myActivePart, get_ls_field_with_identifier(surfaceIdentifier), loAndHi, elementsThaIntersectInterval); } bool LevelSetInterfaceGeometry::have_enough_levelsets_to_have_interior_intersections_or_multiple_crossings() const diff --git a/packages/krino/krino/krino_lib/Akri_LevelSetInterfaceGeometry.hpp b/packages/krino/krino/krino_lib/Akri_LevelSetInterfaceGeometry.hpp index 2845387d7cc3..f0707785e7cf 100644 --- a/packages/krino/krino/krino_lib/Akri_LevelSetInterfaceGeometry.hpp +++ b/packages/krino/krino/krino_lib/Akri_LevelSetInterfaceGeometry.hpp @@ -90,6 +90,7 @@ class LevelSetInterfaceGeometry : public InterfaceGeometry { virtual void prepare_to_decompose_elements(const stk::mesh::BulkData & mesh, const NodeToCapturedDomainsMap & nodesToCapturedDomains) const override; + virtual void prepare_to_intersect_elements(const stk::mesh::BulkData & mesh) const override; virtual void prepare_to_intersect_elements(const stk::mesh::BulkData & mesh, const NodeToCapturedDomainsMap & nodesToCapturedDomains) const override; virtual void prepare_to_intersect_elements(const stk::mesh::BulkData & mesh, @@ -97,7 +98,7 @@ class LevelSetInterfaceGeometry : public InterfaceGeometry { const NodeToCapturedDomainsMap & nodesToCapturedDomains) const override; virtual std::vector get_possibly_cut_elements(const stk::mesh::BulkData & mesh) const override; - virtual std::vector get_elements_that_intersect_interval(const stk::mesh::BulkData & mesh, const std::array loAndHi) const override; + virtual void fill_elements_that_intersect_distance_interval(const stk::mesh::BulkData & mesh, const Surface_Identifier surfaceIdentifier, const std::array loAndHi, std::vector & elementsThaIntersectInterval) const override; virtual bool snapped_elements_may_have_new_intersections() const override; virtual std::vector get_edge_intersection_points(const stk::mesh::BulkData & mesh, @@ -127,7 +128,7 @@ class LevelSetInterfaceGeometry : public InterfaceGeometry { const std::vector & get_surface_identifiers() const override { return mySurfaceIdentifiers; } static std::vector get_active_elements_that_may_be_cut_by_levelsets(const stk::mesh::BulkData & mesh, const stk::mesh::Part & activePart, const std::vector & LSFields); - static std::vector get_active_elements_that_intersect_levelset_interval(const stk::mesh::BulkData & mesh, const stk::mesh::Part & activePart, const std::vector & LSFields, const std::array loAndHi); + static void fill_active_elements_that_intersect_levelset_interval(const stk::mesh::BulkData & mesh, const stk::mesh::Part & activePart, const LS_Field & lsField, const std::array loAndHi, std::vector & elementsThaIntersectInterval); private: void set_parent_element_selector(); @@ -137,6 +138,7 @@ class LevelSetInterfaceGeometry : public InterfaceGeometry { void build_parent_edges_for_elements(const stk::mesh::BulkData & mesh, const std::vector & elementsToIntersect, const NodeToCapturedDomainsMap & nodesToCapturedDomains) const; + const LS_Field & get_ls_field_with_identifier(const Surface_Identifier surfaceIdentifier) const; const stk::mesh::Part & myActivePart; const CDFEM_Support & myCdfemSupport; const Phase_Support & myPhaseSupport; diff --git a/packages/krino/krino/krino_lib/Akri_OutputUtils.cpp b/packages/krino/krino/krino_lib/Akri_OutputUtils.cpp index 57acf9b21827..71c681ab43df 100644 --- a/packages/krino/krino/krino_lib/Akri_OutputUtils.cpp +++ b/packages/krino/krino/krino_lib/Akri_OutputUtils.cpp @@ -64,15 +64,25 @@ void output_composed_mesh_with_fields(const stk::mesh::BulkData & mesh, const st { Ioss::PropertyManager properties; properties.add(Ioss::Property("COMPOSE_RESULTS", 1)); + properties.add(Ioss::Property(stk::io::s_ignoreDisconnectedNodes, true)); output_mesh_with_fields_and_properties(mesh, outputSelector, fileName, step, time, properties, purpose); } void output_mesh_with_fields(const stk::mesh::BulkData & mesh, const stk::mesh::Selector & outputSelector, const std::string & fileName, int step, double time, stk::io::DatabasePurpose purpose) { Ioss::PropertyManager properties; + properties.add(Ioss::Property(stk::io::s_ignoreDisconnectedNodes, true)); output_mesh_with_fields_and_properties(mesh, outputSelector, fileName, step, time, properties, purpose); } +std::string create_filename_from_base_filename(const std::string & baseFileName, const int numFileRevisions) +{ + size_t lastIndex = baseFileName.find_last_of("."); + STK_ThrowRequire(lastIndex != std::string::npos); + const std::string fileBaseName = baseFileName.substr(0, lastIndex); + return create_file_name(fileBaseName, numFileRevisions); +} + std::string create_file_name(const std::string & fileBaseName, const int fileIndex) { STK_ThrowAssert(fileIndex >= 0); diff --git a/packages/krino/krino/krino_lib/Akri_OutputUtils.hpp b/packages/krino/krino/krino_lib/Akri_OutputUtils.hpp index 2b8f347c2642..8db7b3881523 100644 --- a/packages/krino/krino/krino_lib/Akri_OutputUtils.hpp +++ b/packages/krino/krino/krino_lib/Akri_OutputUtils.hpp @@ -22,6 +22,7 @@ class Faceted_Surface; void output_mesh_with_fields(const stk::mesh::BulkData & mesh, const stk::mesh::Selector & outputSelector, const std::string & fileName, int step, double time, stk::io::DatabasePurpose purpose = stk::io::WRITE_RESULTS); void output_composed_mesh_with_fields(const stk::mesh::BulkData & mesh, const stk::mesh::Selector & outputSelector, const std::string & fileName, int step, double time, stk::io::DatabasePurpose purpose = stk::io::WRITE_RESULTS); std::string create_file_name(const std::string & fileBaseName, const int fileIndex); +std::string create_filename_from_base_filename(const std::string & baseFileName, const int numFileRevisions); stk::mesh::PartVector turn_off_output_for_empty_io_parts(const stk::mesh::BulkData & mesh, const stk::mesh::Selector & outputSelector); template diff --git a/packages/krino/krino/krino_lib/Akri_RefineNearLevelSets.cpp b/packages/krino/krino/krino_lib/Akri_RefineNearLevelSets.cpp index f6b5db2c0037..d7270f710d9f 100644 --- a/packages/krino/krino/krino_lib/Akri_RefineNearLevelSets.cpp +++ b/packages/krino/krino/krino_lib/Akri_RefineNearLevelSets.cpp @@ -15,53 +15,51 @@ namespace krino { -std::vector build_levelset_fields(const std::vector*> & stkLevelSetFields) +std::vector build_levelset_fields(const stk::mesh::Field & stkLevelSetField) { unsigned lsId = 0; std::vector lsFields; - for (auto stkLevelSetField : stkLevelSetFields) - lsFields.emplace_back(stkLevelSetField->name(),Surface_Identifier(lsId++),FieldRef(stkLevelSetField),0.,nullptr); + lsFields.emplace_back(stkLevelSetField.name(),Surface_Identifier(lsId++),FieldRef(stkLevelSetField),0.,nullptr); return lsFields; } -void refine_elements_that_intersect_distance_interval_from_levelsets(stk::mesh::BulkData & mesh, +void refine_elements_that_intersect_distance_interval_from_levelset(stk::mesh::BulkData & mesh, const stk::mesh::Part & activePart, - const std::vector*> & stkLevelSetFields, - const std::function & initialize_levelsets, + const stk::mesh::Field & stkLevelSetField, + const std::function & initialize_levelset, const std::array & refinementDistanceInterval, const unsigned numRefinementLevels) { - RefinementSupport & refinementSupport = RefinementSupport::get(mesh.mesh_meta_data()); - refinementSupport.activate_nonconformal_adaptivity(numRefinementLevels); - refinementSupport.set_refinement_interval(refinementDistanceInterval); - RefinementInterface & refinement = krino::KrinoRefinement::create(mesh.mesh_meta_data()); - refinementSupport.set_non_interface_conforming_refinement(refinement); + RefinementInterface & refinement = krino::KrinoRefinement::get_or_create(mesh.mesh_meta_data()); const CDFEM_Support & cdfemSupport = CDFEM_Support::get(mesh.mesh_meta_data()); const Phase_Support & phaseSupport = Phase_Support::get(mesh.mesh_meta_data()); - const auto lsFields = build_levelset_fields(stkLevelSetFields); + const auto lsFields = build_levelset_fields(stkLevelSetField); const LevelSetSurfaceInterfaceGeometry interfaceGeom(mesh.mesh_meta_data().spatial_dimension(), activePart, cdfemSupport, phaseSupport, lsFields); - const int numRefinementSteps = 2*refinementSupport.get_interface_maximum_refinement_level(); // Make sure refinement completes so that elements touching interval are fully refined + const int numRefinementSteps = 2*numRefinementLevels; // Make sure refinement completes so that elements touching interval are fully refined + constexpr bool isDefaultCoarsen = false; // Refinement here will be "cumulative" - std::function initialize_levelsets_and_compute_distance_and_mark_elements_that_intersect_interval = - [&mesh, &interfaceGeom, &refinementSupport, &initialize_levelsets, numRefinementSteps](int refinementIterCount) + std::function initialize_levelset_and_compute_distance_and_mark_elements_that_intersect_interval = + [&mesh, &initialize_levelset, &refinement, &interfaceGeom, &refinementDistanceInterval, numRefinementSteps, numRefinementLevels](int refinementIterCount) { - initialize_levelsets(); + initialize_levelset(); if (refinementIterCount < numRefinementSteps) { krino::mark_elements_that_intersect_interval(mesh, - refinementSupport.get_non_interface_conforming_refinement(), + refinement, interfaceGeom, - refinementSupport, - refinementIterCount); + refinementDistanceInterval, + numRefinementLevels, + isDefaultCoarsen); } }; - perform_multilevel_adaptivity(refinementSupport.get_non_interface_conforming_refinement(), + stk::mesh::Selector emptySelector; + perform_multilevel_adaptivity(refinement, mesh, - initialize_levelsets_and_compute_distance_and_mark_elements_that_intersect_interval, - refinementSupport.get_do_not_refine_or_unrefine_selector()); + initialize_levelset_and_compute_distance_and_mark_elements_that_intersect_interval, + emptySelector); } } diff --git a/packages/krino/krino/krino_lib/Akri_RefineNearLevelSets.hpp b/packages/krino/krino/krino_lib/Akri_RefineNearLevelSets.hpp index 83e6854f45a4..b44e7b55c4cb 100644 --- a/packages/krino/krino/krino_lib/Akri_RefineNearLevelSets.hpp +++ b/packages/krino/krino/krino_lib/Akri_RefineNearLevelSets.hpp @@ -8,9 +8,9 @@ namespace krino { -void refine_elements_that_intersect_distance_interval_from_levelsets(stk::mesh::BulkData & mesh, +void refine_elements_that_intersect_distance_interval_from_levelset(stk::mesh::BulkData & mesh, const stk::mesh::Part & activePart, - const std::vector*> & stkLevelSetFields, + const stk::mesh::Field & stkLevelSetField, const std::function & initialize_levelsets, const std::array & refinementDistanceInterval, const unsigned numRefinementLevels); diff --git a/packages/krino/krino/krino_lib/Akri_RefinementInterface.cpp b/packages/krino/krino/krino_lib/Akri_RefinementInterface.cpp index 2c7d991f3766..9b3553f93840 100644 --- a/packages/krino/krino/krino_lib/Akri_RefinementInterface.cpp +++ b/packages/krino/krino/krino_lib/Akri_RefinementInterface.cpp @@ -221,6 +221,15 @@ KrinoRefinement::is_created(const stk::mesh::MetaData & meta) return refinement != nullptr; } +KrinoRefinement & +KrinoRefinement::get_or_create(stk::mesh::MetaData & meta) +{ + KrinoRefinement * refinement = const_cast(meta.get_attribute()); + if (refinement) + return *refinement; + return create(meta); +} + void KrinoRefinement::register_parts_and_fields_via_aux_meta_for_fmwk(stk::mesh::MetaData & meta) { diff --git a/packages/krino/krino/krino_lib/Akri_RefinementInterface.hpp b/packages/krino/krino/krino_lib/Akri_RefinementInterface.hpp index 8bc04748726e..e848a2d4f798 100644 --- a/packages/krino/krino/krino_lib/Akri_RefinementInterface.hpp +++ b/packages/krino/krino/krino_lib/Akri_RefinementInterface.hpp @@ -77,6 +77,7 @@ class KrinoRefinement : public RefinementInterface static KrinoRefinement & get(const stk::mesh::MetaData & meta); static KrinoRefinement & create(stk::mesh::MetaData & meta); static KrinoRefinement & create(stk::mesh::MetaData & meta, stk::diag::Timer & timer); + static KrinoRefinement & get_or_create(stk::mesh::MetaData & meta); static bool is_created(const stk::mesh::MetaData & meta); static void register_parts_and_fields_via_aux_meta_for_fmwk(stk::mesh::MetaData & meta); diff --git a/packages/krino/krino/krino_lib/Akri_RefinementSupport.cpp b/packages/krino/krino/krino_lib/Akri_RefinementSupport.cpp index 9bf4f42811c3..16764dda6449 100644 --- a/packages/krino/krino/krino_lib/Akri_RefinementSupport.cpp +++ b/packages/krino/krino/krino_lib/Akri_RefinementSupport.cpp @@ -34,22 +34,15 @@ RefinementSupport::get(const stk::mesh::MetaData & meta) return *support; } -RefinementSupport::RefinementSupport(stk::mesh::MetaData & meta) - : myMeta(meta), - myTimer("Noninterface Conforming Adapt", sierra::Diag::sierraTimer()) -{ - -} - -stk::mesh::Selector RefinementSupport::get_do_not_refine_or_unrefine_selector() const +stk::mesh::Selector RefinementSupport::do_not_refine_or_unrefine_selector(const stk::mesh::MetaData & meta) { - if (!CDFEM_Support::is_active(myMeta)) + if (!CDFEM_Support::is_active(meta)) { stk::mesh::Selector emptySelector; return emptySelector; } - const CDFEM_Support & cdfemSupport = CDFEM_Support::get(myMeta); + const CDFEM_Support & cdfemSupport = CDFEM_Support::get(meta); const stk::mesh::Selector parent_or_child_selector = cdfemSupport.get_child_part() | cdfemSupport.get_parent_part(); const stk::mesh::Selector decomposed_blocks_selector = @@ -58,6 +51,18 @@ stk::mesh::Selector RefinementSupport::get_do_not_refine_or_unrefine_selector() return do_not_refine_selector; } +RefinementSupport::RefinementSupport(stk::mesh::MetaData & meta) + : myMeta(meta), + myTimer("Noninterface Conforming Adapt", sierra::Diag::sierraTimer()) +{ + +} + +stk::mesh::Selector RefinementSupport::get_do_not_refine_or_unrefine_selector() const +{ + return do_not_refine_or_unrefine_selector(myMeta); +} + void RefinementSupport::activate_interface_refinement(int minimumLevel, int maximumLevel) { diff --git a/packages/krino/krino/krino_lib/Akri_RefinementSupport.hpp b/packages/krino/krino/krino_lib/Akri_RefinementSupport.hpp index b50e7e729c9f..c9ec5d1f98ca 100644 --- a/packages/krino/krino/krino_lib/Akri_RefinementSupport.hpp +++ b/packages/krino/krino/krino_lib/Akri_RefinementSupport.hpp @@ -21,6 +21,7 @@ class RefinementSupport { static RefinementSupport & get(stk::mesh::MetaData & meta); static RefinementSupport & get(const stk::mesh::MetaData & meta); static bool use_nonconformal_adaptivity(stk::mesh::MetaData & meta) { RefinementSupport & refinementSupport = get(meta); return refinementSupport.get_interface_maximum_refinement_level() > 0; } + static stk::mesh::Selector do_not_refine_or_unrefine_selector(const stk::mesh::MetaData & meta); void set_initial_refinement_levels(int levels) { my_initial_refinement_levels = levels; } int get_initial_refinement_levels() const { return my_initial_refinement_levels; } diff --git a/packages/krino/krino/parser/Akri_LevelSet_Parser.cpp b/packages/krino/krino/parser/Akri_LevelSet_Parser.cpp index 268c9a7d3fc4..0df859d33478 100644 --- a/packages/krino/krino/parser/Akri_LevelSet_Parser.cpp +++ b/packages/krino/krino/parser/Akri_LevelSet_Parser.cpp @@ -77,14 +77,14 @@ LevelSet_Parser::parse(const Parser::Node & region_node, stk::mesh::MetaData & m ls.set_distance_name(distance_name); } - std::vector extension_velocity; - if (ls_node.get_if_present("extension_velocity", extension_velocity)) + std::vector interfaceVelocity; + if (ls_node.get_if_present("interface_velocity", interfaceVelocity)) { - if (extension_velocity.size() != ls.spatial_dimension) + if (interfaceVelocity.size() != ls.spatial_dimension) { - stk::RuntimeDoomedAdHoc() << "Expecting " << ls.spatial_dimension << " real values for extension_velocity for level set " << ls_name << ".\n"; + stk::RuntimeDoomedAdHoc() << "Expecting " << ls.spatial_dimension << " string expressions for interface_velocity for level set " << ls_name << ".\n"; } - ls.set_extension_velocity(stk::math::Vector3d(extension_velocity.data(), extension_velocity.size())); + ls.set_interface_velocity(interfaceVelocity); } double narrow_band_multiplier = 0.0; diff --git a/packages/krino/krino/refinement/Akri_NodeRefiner.hpp b/packages/krino/krino/refinement/Akri_NodeRefiner.hpp index 2197020a5cd3..2a78d2d7a50c 100644 --- a/packages/krino/krino/refinement/Akri_NodeRefiner.hpp +++ b/packages/krino/krino/refinement/Akri_NodeRefiner.hpp @@ -9,7 +9,7 @@ namespace krino { -class Edge; +struct Edge; class FieldRef; class EdgeMarkerInterface; diff --git a/packages/krino/krino/refinement/Akri_Refinement.hpp b/packages/krino/krino/refinement/Akri_Refinement.hpp index 377205704bad..ddcc88c3bae7 100644 --- a/packages/krino/krino/refinement/Akri_Refinement.hpp +++ b/packages/krino/krino/refinement/Akri_Refinement.hpp @@ -11,7 +11,7 @@ #include "stk_util/diag/Timer.hpp" namespace stk { namespace mesh { class MetaData; } } -namespace stk { class topology; } +namespace stk { struct topology; } namespace krino { diff --git a/packages/krino/krino/refinement/Akri_TransitionElementEdgeMarker.hpp b/packages/krino/krino/refinement/Akri_TransitionElementEdgeMarker.hpp index f96214c94106..edf58ce6ba38 100644 --- a/packages/krino/krino/refinement/Akri_TransitionElementEdgeMarker.hpp +++ b/packages/krino/krino/refinement/Akri_TransitionElementEdgeMarker.hpp @@ -17,7 +17,7 @@ namespace krino { class Refinement; -class Edge; +struct Edge; class NodeRefiner; class EdgeMarkerInterface diff --git a/packages/krino/krino/region/Akri_Region.cpp b/packages/krino/krino/region/Akri_Region.cpp index 12b8929194f7..e3c284db8c5b 100644 --- a/packages/krino/krino/region/Akri_Region.cpp +++ b/packages/krino/krino/region/Akri_Region.cpp @@ -42,6 +42,7 @@ #include #include #include +#include namespace krino{ @@ -55,8 +56,9 @@ Region::Region(Simulation & owning_simulation, const std::string & regionName) my_timerExecute("Execute", my_timerRegion), my_timerMeshInput("Mesh input", my_timerRegion), my_timerMeshOutput("Mesh output", my_timerRegion), - my_output_file_index(0), - my_output_file_created(false) + myOutputFileIndex(0), + myOutputFileNumRevisions(0), + myIsOutputFileCreatedAndCurrent(false) { /* %TRACE[ON]% */ Trace trace__("krino::Region::Region()"); /* %TRACE% */ my_simulation.add_region(this); myOutputBroker = std::make_unique(stk::EnvData::parallel_comm()); @@ -185,13 +187,15 @@ void zero_error_indicator(stk::mesh::BulkData & mesh) static void refine_elements_near_interface(RefinementInterface & refinement, const RefinementSupport & refinementSupport, stk::mesh::BulkData & mesh, - const int numRefinementSteps) + const int numRefinementSteps, + const bool doInitializeLS) { std::function mark_elements_near_interface = - [&mesh, &refinementSupport, numRefinementSteps] + [&mesh, &refinementSupport, numRefinementSteps, doInitializeLS] (int num_refinements) { - LevelSet::initialize(mesh.mesh_meta_data()); + if (doInitializeLS) + LevelSet::initialize(mesh.mesh_meta_data()); if (num_refinements < numRefinementSteps) { const std::unique_ptr interfaceGeometry = create_interface_geometry(mesh.mesh_meta_data()); @@ -209,13 +213,15 @@ static void refine_elements_near_interface(RefinementInterface & refinement, static void refine_interface_elements(RefinementInterface & refinement, const RefinementSupport & refinementSupport, stk::mesh::BulkData & mesh, - const int numRefinementSteps) + const int numRefinementSteps, + const bool doInitializeLS) { std::function marker_function = - [&mesh, &refinementSupport, numRefinementSteps] + [&mesh, &refinementSupport, numRefinementSteps, doInitializeLS] (int num_refinements) { - LevelSet::initialize(mesh.mesh_meta_data()); + if (doInitializeLS) + LevelSet::initialize(mesh.mesh_meta_data()); if(num_refinements < numRefinementSteps) { const auto & auxMeta = krino::AuxMetaData::get(mesh.mesh_meta_data()); @@ -236,6 +242,7 @@ static void refine_elements_that_intersect_interval(RefinementInterface & refine [&mesh, &refinementSupport, numRefinementSteps] (int num_refinements) { + constexpr bool isDefaultCoarsen = true; LevelSet::initialize(mesh.mesh_meta_data()); if (num_refinements < numRefinementSteps) { @@ -243,8 +250,9 @@ static void refine_elements_that_intersect_interval(RefinementInterface & refine krino::mark_elements_that_intersect_interval(mesh, refinementSupport.get_non_interface_conforming_refinement(), *interfaceGeometry, - refinementSupport, - num_refinements); + refinementSupport.get_refinement_interval(), + refinementSupport.get_interface_minimum_refinement_level(), + isDefaultCoarsen); } }; @@ -275,7 +283,7 @@ static void refine_based_on_indicator_field(RefinementInterface & refinement, perform_multilevel_adaptivity(refinement, mesh, marker_function, refinementSupport.get_do_not_refine_or_unrefine_selector()); } -void do_adaptive_refinement(const krino::RefinementSupport & refinementSupport, stk::mesh::BulkData & mesh) +void do_adaptive_refinement(const krino::RefinementSupport & refinementSupport, const bool doInitializeLS, stk::mesh::BulkData & mesh) { stk::diag::TimeBlock adapt_timer__(refinementSupport.get_timer()); @@ -298,10 +306,10 @@ void do_adaptive_refinement(const krino::RefinementSupport & refinementSupport, if (doNearbyRefinementBeforeInterfaceRefinement) { const int numNearbyRefinementSteps = numRefinementLevels; - refine_elements_near_interface(refinement, refinementSupport, mesh, numNearbyRefinementSteps); + refine_elements_near_interface(refinement, refinementSupport, mesh, numNearbyRefinementSteps, doInitializeLS); } const int numInterfaceRefinementSteps = doNearbyRefinementBeforeInterfaceRefinement ? numRefinementLevels : (2*numRefinementLevels); // Make sure refinement completes so that interfacial elements are fully refined - refine_interface_elements(refinement, refinementSupport, mesh, numInterfaceRefinementSteps); + refine_interface_elements(refinement, refinementSupport, mesh, numInterfaceRefinementSteps, doInitializeLS); } } @@ -382,6 +390,7 @@ void Region::initialize() auto & bulk = mesh_bulk_data(); const auto & auxMeta = AuxMetaData::get(mesh_meta_data()); + const bool doInitializeLSDuringRefinement = true; const bool doRefinement = refinementSupport.get_initial_refinement_levels() > 0 || refinementSupport.get_interface_maximum_refinement_level() > 0 || refinementSupport.get_post_adapt_refinement_levels() > 0; @@ -394,7 +403,7 @@ void Region::initialize() if (refinementSupport.get_initial_refinement_levels() > 0) refinement.do_uniform_refinement(refinementSupport.get_initial_refinement_levels()); - do_adaptive_refinement(refinementSupport, bulk); + do_adaptive_refinement(refinementSupport, doInitializeLSDuringRefinement, bulk); do_post_adapt_uniform_refinement(my_simulation, refinementSupport, auxMeta, bulk); } @@ -454,12 +463,29 @@ void Region::execute() return; } - double deltaTime = time_step(); + const RefinementSupport & refinementSupport = RefinementSupport::get(mesh_meta_data()); + const bool doRefinement = refinementSupport.get_interface_maximum_refinement_level() > 0 || + refinementSupport.get_post_adapt_refinement_levels() > 0; + + if (doRefinement) + { + const bool doInitializeLSDuringRefinement = false; + auto & bulk = mesh_bulk_data(); + const auto & auxMeta = AuxMetaData::get(mesh_meta_data()); + + do_adaptive_refinement(refinementSupport, doInitializeLSDuringRefinement, bulk); + do_post_adapt_uniform_refinement(my_simulation, refinementSupport, auxMeta, bulk); + mesh_topology_has_changed(); + } + + const double deltaTime = time_step(); + const double timeN = get_current_time(); + const double timeNP1 = timeN + deltaTime; const Surface_Manager & surfaceManager = Surface_Manager::get(mesh_meta_data()); for(auto&& ls : surfaceManager.get_levelsets()) { - ls->advance_semilagrangian(deltaTime); + ls->advance_semilagrangian(timeN, timeNP1); } } @@ -469,6 +495,7 @@ stk::mesh::BulkData& Region::mesh_bulk_data() { return myMesh->bulk_data(); } const stk::mesh::MetaData& Region::mesh_meta_data() const { return myMesh->meta_data(); } stk::mesh::MetaData& Region::mesh_meta_data() { return myMesh->meta_data(); } double Region::time_step() const { return my_simulation.get_time_step(); } +double Region::get_current_time() const { return my_simulation.get_current_time(); } stk::io::StkMeshIoBroker & Region::stkOutput() { @@ -478,22 +505,42 @@ stk::io::StkMeshIoBroker & Region::stkOutput() void Region::create_output_mesh() { + myIsOutputFileCreatedAndCurrent = true; + bool output_mesh = my_results_options->get_num_step_increments() != 0; if(!output_mesh) return; my_results_options->get_scheduler().set_termination_time(my_simulation.get_stop_time()); - my_output_file_index = stkOutput().create_output_mesh(my_results_options->get_filename(), stk::io::WRITE_RESULTS, my_results_options->get_properties()); + const std::string baseFileName = my_results_options->get_filename(); + Ioss::PropertyManager fileProperties(my_results_options->get_properties()); + fileProperties.add(Ioss::Property("base_filename", baseFileName)); - std::shared_ptr active_selector = std::make_shared(AuxMetaData::get(mesh_meta_data()).active_part()); - stkOutput().set_subset_selector(my_output_file_index, active_selector); + std::string filename = baseFileName; + if (myOutputFileNumRevisions > 0) + { + std::shared_ptr ioRegion = stkOutput().get_output_ioss_region(myOutputFileIndex); + int stateCount = ioRegion->get_property("state_count").get_int(); + if (ioRegion->property_exists("state_offset")) + stateCount += ioRegion->get_property("state_offset").get_int(); + filename = create_filename_from_base_filename(baseFileName, myOutputFileNumRevisions); + fileProperties.add(Ioss::Property("state_offset", stateCount)); + } - stkOutput().write_output_mesh(my_output_file_index); + stkOutput().use_simple_fields(); + const auto oldOutputFileIndex = myOutputFileIndex; + myOutputFileIndex = stkOutput().create_output_mesh(filename, stk::io::WRITE_RESULTS, fileProperties); + + if (myOutputFileNumRevisions > 0) + stkOutput().close_output_mesh(oldOutputFileIndex); + + std::shared_ptr active_selector = std::make_shared(AuxMetaData::get(mesh_meta_data()).active_part()); + stkOutput().set_subset_selector(myOutputFileIndex, active_selector); - declare_output_variables(my_output_file_index); + declare_output_variables(myOutputFileIndex); - my_output_file_created = true; + myOutputFileNumRevisions++; } void @@ -557,13 +604,9 @@ void Region::process_output(bool forceOutput) if(!doOutput) return; - // A couple of krino tests that just compute surface distances never call Region::initialize() - // where we normally create the output mesh. - if(!my_output_file_created) create_output_mesh(); + if(!myIsOutputFileCreatedAndCurrent) create_output_mesh(); - stkOutput().begin_output_step(my_output_file_index, currentTime); - stkOutput().write_defined_output_fields(my_output_file_index); - stkOutput().end_output_step(my_output_file_index); + stkOutput().process_output_request(myOutputFileIndex, currentTime); } void diff --git a/packages/krino/krino/region/Akri_Region.hpp b/packages/krino/krino/region/Akri_Region.hpp index 2f57decfd593..77fe62d8dee5 100644 --- a/packages/krino/krino/region/Akri_Region.hpp +++ b/packages/krino/krino/region/Akri_Region.hpp @@ -35,6 +35,7 @@ class Region { virtual void execute(); double time_step() const; + double get_current_time() const; const std::string & name() const { return my_name; } unsigned spatial_dimension() const; const stk::mesh::BulkData& mesh_bulk_data() const; @@ -52,6 +53,7 @@ class Region { void declare_output_variables(size_t result_output_index); void process_output(bool forceOutput); ResultsOutputOptions * get_results_options() { return my_results_options.get(); } + void mesh_topology_has_changed() { myIsOutputFileCreatedAndCurrent = false; } private: Simulation & my_simulation; @@ -66,8 +68,9 @@ class Region { mutable stk::diag::Timer my_timerExecute; ///< Execute timer mutable stk::diag::Timer my_timerMeshInput; ///< Mesh input timer mutable stk::diag::Timer my_timerMeshOutput; ///< Mesh output timer - size_t my_output_file_index; - bool my_output_file_created; + size_t myOutputFileIndex; + int myOutputFileNumRevisions; + bool myIsOutputFileCreatedAndCurrent; }; } // namespace krino diff --git a/packages/krino/krino/region/Akri_ResultsOutputOptions.hpp b/packages/krino/krino/region/Akri_ResultsOutputOptions.hpp index 2a0b1796bd2c..1dfec1c48216 100644 --- a/packages/krino/krino/region/Akri_ResultsOutputOptions.hpp +++ b/packages/krino/krino/region/Akri_ResultsOutputOptions.hpp @@ -22,7 +22,6 @@ namespace stk { namespace mesh { class MetaData; } } namespace krino { - typedef std::pair StepIncrement; typedef std::pair FieldName_OutputName_Pair; class ResultsOutputOptions { @@ -49,7 +48,6 @@ namespace krino { const std::string & get_filename() const { return my_filename; } void add_step_increment(int start, int increment) { - StepIncrement aStep(start, increment); my_scheduler.add_interval(start, increment); my_numStepIncrements++; } diff --git a/packages/krino/krino/surface/Akri_Facet.cpp b/packages/krino/krino/surface/Akri_Facet.cpp index 67277c5beeb7..d8145e714b72 100644 --- a/packages/krino/krino/surface/Akri_Facet.cpp +++ b/packages/krino/krino/surface/Akri_Facet.cpp @@ -17,18 +17,31 @@ namespace krino{ // //-------------------------------------------------------------------------------- -static void unpack_vector3d_from_buffer( stk::CommBuffer & b, stk::math::Vector3d & coords ) +static void unpack_vector3d_from_buffer( stk::math::Vector3d & vec, stk::CommBuffer & b ) { - b.unpack(coords[0]); - b.unpack(coords[1]); - b.unpack(coords[2]); + b.unpack(vec[0]); + b.unpack(vec[1]); + b.unpack(vec[2]); } -static void unpack_vector2d_from_buffer( stk::CommBuffer & b, stk::math::Vector3d & coords ) +static void unpack_vector2d_from_buffer( stk::math::Vector3d & vec, stk::CommBuffer & b ) { - b.unpack(coords[0]); - b.unpack(coords[1]); - coords[2] = 0.; + b.unpack(vec[0]); + b.unpack(vec[1]); + vec[2] = 0.; +} + +static void unpack_vectors_from_buffer( std::array & vecs, stk::CommBuffer & b ) +{ + unpack_vector3d_from_buffer(vecs[0], b); + unpack_vector3d_from_buffer(vecs[1], b); + unpack_vector3d_from_buffer(vecs[2], b); +} + +static void unpack_vectors_from_buffer( std::array & vecs, stk::CommBuffer & b ) +{ + unpack_vector2d_from_buffer(vecs[0], b); + unpack_vector2d_from_buffer(vecs[1], b); } //-------------------------------------------------------------------------------- @@ -37,36 +50,73 @@ void Facet2d::pack_into_buffer(stk::CommBuffer & b) const { for (int n = 0; n < 2; ++n ) - { - b.pack(myCoords[n][0]); - b.pack(myCoords[n][1]); - } + for (int d = 0; d < 2; ++d ) + b.pack(myCoords[n][d]); } -void -Facet2d::unpack_facet_data_from_buffer( stk::CommBuffer & b, std::array & facetCoords) +Facet2d::Facet2d( stk::CommBuffer & b ) { - unpack_vector2d_from_buffer(b, facetCoords[0]); - unpack_vector2d_from_buffer(b, facetCoords[1]); + unpack_vectors_from_buffer(myCoords, b); } void Facet3d::pack_into_buffer(stk::CommBuffer & b) const { for (int n = 0; n < 3; ++n ) - { - b.pack(myCoords[n][0]); - b.pack(myCoords[n][1]); - b.pack(myCoords[n][2]); - } + for (int d = 0; d < 3; ++d ) + b.pack(myCoords[n][d]); +} + +Facet3d::Facet3d( stk::CommBuffer & b ) +{ + unpack_vectors_from_buffer(myCoords, b); +} + +void +FacetWithVelocity2d::pack_into_buffer(stk::CommBuffer & b) const +{ + Facet2d::pack_into_buffer(b); + for (int n = 0; n < 2; ++n ) + for (int d = 0; d < 2; ++d ) + b.pack(myVelocity[n][d]); +} + +FacetWithVelocity2d::FacetWithVelocity2d( stk::CommBuffer & b ) +: Facet2d(b) +{ + unpack_vectors_from_buffer(myVelocity, b); } void -Facet3d::unpack_facet_data_from_buffer( stk::CommBuffer & b, std::array & facetCoords) +FacetWithVelocity3d::pack_into_buffer(stk::CommBuffer & b) const +{ + Facet3d::pack_into_buffer(b); + for (int n = 0; n < 3; ++n ) + for (int d = 0; d < 3; ++d ) + b.pack(myVelocity[n][d]); +} + +FacetWithVelocity3d::FacetWithVelocity3d( stk::CommBuffer & b ) +: Facet3d(b) +{ + unpack_vectors_from_buffer(myVelocity, b); +} + +stk::math::Vector3d FacetWithVelocity2d::velocity_at_closest_point( const stk::math::Vector3d & queryPt ) const +{ + stk::math::Vector3d closestPt; + stk::math::Vector2d paramAtClosestPt; + closest_point(queryPt, closestPt, paramAtClosestPt); + return (1.-paramAtClosestPt[0]) * myVelocity[0] + paramAtClosestPt[0] * myVelocity[1]; +} + +stk::math::Vector3d FacetWithVelocity3d::velocity_at_closest_point( const stk::math::Vector3d & queryPt ) const { - unpack_vector3d_from_buffer(b, facetCoords[0]); - unpack_vector3d_from_buffer(b, facetCoords[1]); - unpack_vector3d_from_buffer(b, facetCoords[2]); + stk::math::Vector3d closestPt; + stk::math::Vector2d paramAtClosestPt; + closest_point(queryPt, closestPt, paramAtClosestPt); + return myVelocity[0] * (1.-paramAtClosestPt[0]) + myVelocity[1] * paramAtClosestPt[0]; + return (1.0-paramAtClosestPt[0]-paramAtClosestPt[1]) * myVelocity[0] + paramAtClosestPt[0] * myVelocity[1] + paramAtClosestPt[1] * myVelocity[2]; } std::ostream & Facet3d::put( std::ostream & os ) const diff --git a/packages/krino/krino/surface/Akri_Facet.hpp b/packages/krino/krino/surface/Akri_Facet.hpp index fcd70559870e..5627cbbb7b48 100644 --- a/packages/krino/krino/surface/Akri_Facet.hpp +++ b/packages/krino/krino/surface/Akri_Facet.hpp @@ -46,6 +46,7 @@ class Facet { virtual bool degenerate() const = 0; virtual double point_distance_squared( const stk::math::Vector3d & x ) const = 0; + virtual void closest_point( const stk::math::Vector3d & queryPt, stk::math::Vector3d & closestPt ) const = 0; virtual void closest_point( const stk::math::Vector3d & queryPt, stk::math::Vector3d & closestPt, stk::math::Vector2d & paramAtClosestPt ) const = 0; virtual double facet_plane_signed_distance( const stk::math::Vector3d & x ) const = 0; virtual int point_distance_sign( const stk::math::Vector3d & x ) const { return (facet_plane_signed_distance(x) < 0.0) ? -1 : 1; } @@ -63,9 +64,7 @@ class Facet3d : public Facet { Facet3d( const stk::math::Vector3d & x0, const stk::math::Vector3d & x1, const stk::math::Vector3d & x2 ); - Facet3d( const double * x0, - const double * x1, - const double * x2 ); + Facet3d(stk::CommBuffer & b); Facet3d() = delete; virtual ~Facet3d() {} @@ -78,8 +77,8 @@ class Facet3d : public Facet { virtual size_t storage_size() const override { return sizeof(Facet3d); } virtual std::ostream & put( std::ostream& os ) const override; - static void unpack_facet_data_from_buffer( stk::CommBuffer & b, std::array & facetCoords); virtual void pack_into_buffer(stk::CommBuffer & b) const; + static void emplace_back_from_buffer( std::vector & facets, stk::CommBuffer & b ); virtual const stk::math::Vector3d & facet_vertex(const int i) const override { return myCoords[i]; } virtual stk::math::Vector3d & facet_vertex(const int i) override { return myCoords[i]; } @@ -88,6 +87,8 @@ class Facet3d : public Facet { virtual bool degenerate() const override { return is_degenerate(myCoords); } virtual double point_distance_squared( const stk::math::Vector3d & x ) const override { return Calc::distance_squared( myCoords, x ); } + virtual void closest_point( const stk::math::Vector3d & queryPt, stk::math::Vector3d & closestPt ) const override + { Calc::closest_point( myCoords[0], myCoords[1], myCoords[2], queryPt, closestPt ); } virtual void closest_point( const stk::math::Vector3d & queryPt, stk::math::Vector3d & closestPt, stk::math::Vector2d & paramAtClosestPt ) const override { Calc::closest_point_and_parametric_coords( myCoords, queryPt, closestPt, paramAtClosestPt ); } virtual double facet_plane_signed_distance( const stk::math::Vector3d & x ) const override @@ -108,8 +109,7 @@ class Facet2d : public Facet { public: Facet2d( const stk::math::Vector3d & x0, const stk::math::Vector3d & x1 ); - Facet2d( const double * x0, - const double * x1 ); + Facet2d(stk::CommBuffer & b); Facet2d() = delete; virtual ~Facet2d() {} @@ -121,8 +121,8 @@ class Facet2d : public Facet { virtual size_t storage_size() const override { return sizeof(Facet2d); } virtual std::ostream & put( std::ostream& os ) const override; - static void unpack_facet_data_from_buffer( stk::CommBuffer & b, std::array & facetCoords); virtual void pack_into_buffer(stk::CommBuffer & b) const; + static void emplace_back_from_buffer( std::vector & facets, stk::CommBuffer & b ); virtual const stk::math::Vector3d & facet_vertex(const int i) const override { return myCoords[i]; } virtual stk::math::Vector3d & facet_vertex(const int i) override { return myCoords[i]; } @@ -132,8 +132,10 @@ class Facet2d : public Facet { virtual bool degenerate() const override { return (0.0 == Calc::length_squared(myCoords)); } virtual double point_distance_squared( const stk::math::Vector3d & x ) const override { return Calc::distance_squared(myCoords, x); } + virtual void closest_point( const stk::math::Vector3d & queryPt, stk::math::Vector3d & closestPt ) const override + { Calc::closest_point( myCoords, queryPt, closestPt ); } virtual void closest_point( const stk::math::Vector3d & queryPt, stk::math::Vector3d & closestPt, stk::math::Vector2d & paramAtClosestPt ) const override - { Calc::closest_point(myCoords, queryPt, closestPt, paramAtClosestPt[0]); } + { Calc::closest_point_and_parametric_coord(myCoords, queryPt, closestPt, paramAtClosestPt[0]); } virtual double facet_plane_signed_distance( const stk::math::Vector3d & x ) const override { return Dot(crossZ(facet_vertex(1)-facet_vertex(0)), x-facet_vertex(0)); } virtual stk::math::Vector3d weights(const stk::math::Vector2d & parametric_coords) const override @@ -148,6 +150,53 @@ class Facet2d : public Facet { std::array myCoords; }; +class FacetWithVelocity2d : public Facet2d { +public: + FacetWithVelocity2d( const stk::math::Vector3d & x0, + const stk::math::Vector3d & x1, + const stk::math::Vector3d vel0, + const stk::math::Vector3d vel1) + : Facet2d(x0, x1), myVelocity{vel0, vel1} {} + FacetWithVelocity2d( const stk::math::Vector3d & x0, + const stk::math::Vector3d & x1) + : FacetWithVelocity2d(x0, x1, stk::math::Vector3d::ZERO, stk::math::Vector3d::ZERO) {} + FacetWithVelocity2d(stk::CommBuffer & b); + virtual ~FacetWithVelocity2d() {} + void set_velocity(const std::array & velocity) { myVelocity = velocity; } + const std::array & get_velocity() const { return myVelocity; } + stk::math::Vector3d velocity_at_closest_point( const stk::math::Vector3d & queryPt ) const; + + virtual void pack_into_buffer(stk::CommBuffer & b) const; + static void emplace_back_from_buffer( std::vector & facets, stk::CommBuffer & b ); +private: + std::array myVelocity; +}; + +class FacetWithVelocity3d : public Facet3d { +public: + FacetWithVelocity3d( const stk::math::Vector3d & x0, + const stk::math::Vector3d & x1, + const stk::math::Vector3d & x2, + const stk::math::Vector3d vel0, + const stk::math::Vector3d vel1, + const stk::math::Vector3d vel2) + : Facet3d(x0, x1, x2), myVelocity{vel0, vel1, vel2} {} + FacetWithVelocity3d( const stk::math::Vector3d & x0, + const stk::math::Vector3d & x1, + const stk::math::Vector3d & x2) + : FacetWithVelocity3d(x0, x1, x2, stk::math::Vector3d::ZERO, stk::math::Vector3d::ZERO, stk::math::Vector3d::ZERO) {} + FacetWithVelocity3d(stk::CommBuffer & b); + virtual ~FacetWithVelocity3d() {} + void set_velocity(const std::array & velocity) { myVelocity = velocity; } + const std::array & get_velocity() const { return myVelocity; } + stk::math::Vector3d velocity_at_closest_point( const stk::math::Vector3d & queryPt ) const; + + virtual void pack_into_buffer(stk::CommBuffer & b) const; + static void emplace_back_from_buffer( std::vector & facets, stk::CommBuffer & b ); +private: + std::array myVelocity; +}; + template class FacetDistanceQuery { public: diff --git a/packages/krino/krino/surface/Akri_FacetedSurfaceCalcs.cpp b/packages/krino/krino/surface/Akri_FacetedSurfaceCalcs.cpp index d8a14e4e0c65..db87719f1e3a 100644 --- a/packages/krino/krino/surface/Akri_FacetedSurfaceCalcs.cpp +++ b/packages/krino/krino/surface/Akri_FacetedSurfaceCalcs.cpp @@ -66,6 +66,25 @@ static double compute_point_distance_squared(const stk::math::Vector3d &x, const return minSqrDist; } +template +stk::math::Vector3d compute_closest_point(const stk::math::Vector3d &x, const std::vector & nearestFacets) +{ + double minSqrDist = std::numeric_limits::max(); + stk::math::Vector3d closestPt; + stk::math::Vector3d facetClosestPt; + for ( auto&& facet : nearestFacets ) + { + facet->closest_point(x, facetClosestPt); + const double sqrDist = (x-facetClosestPt).length_squared(); + if (sqrDist < minSqrDist) + { + minSqrDist = sqrDist; + closestPt = facetClosestPt; + } + } + return closestPt; +} + template double point_distance_given_nearest_facets(const stk::math::Vector3d &x, const std::vector & nearestFacets, const double narrow_band_size, const double far_field_value, const bool compute_signed_distance) { @@ -307,6 +326,8 @@ stk::math::Vector3d compute_pseudo_normal(const stk::math::Vector3d &x, const st // Explicit template instantiation +template stk::math::Vector3d compute_closest_point(const stk::math::Vector3d &x, const std::vector & nearestFacets); +template stk::math::Vector3d compute_closest_point(const stk::math::Vector3d &x, const std::vector & nearestFacets); template double point_distance_given_nearest_facets(const stk::math::Vector3d &x, const std::vector & nearestFacets, const double narrow_band_size, const double far_field_value, const bool compute_signed_distance); template double point_distance_given_nearest_facets(const stk::math::Vector3d &x, const std::vector & nearestFacets, const double narrow_band_size, const double far_field_value, const bool compute_signed_distance); template double compute_point_to_facets_distance_by_average_normal(const stk::math::Vector3d &x, const std::vector & facets); @@ -318,4 +339,18 @@ template std::pair compute_facet_edge_intersection(const F template double compute_intersection_between_surface_facets_and_edge(const std::vector & candidates, const stk::math::Vector3d & edgePt0, const stk::math::Vector3d & edgePt1); template double compute_intersection_between_surface_facets_and_edge(const std::vector & candidates, const stk::math::Vector3d & edgePt0, const stk::math::Vector3d & edgePt1); +template stk::math::Vector3d compute_closest_point(const stk::math::Vector3d &x, const std::vector & nearestFacets); +template double point_distance_given_nearest_facets(const stk::math::Vector3d &x, const std::vector & nearestFacets, const double narrow_band_size, const double far_field_value, const bool compute_signed_distance); +template double compute_point_to_facets_distance_by_average_normal(const stk::math::Vector3d &x, const std::vector & facets); +template stk::math::Vector3d compute_pseudo_normal(const stk::math::Vector3d &x, const std::vector & nearestFacets); +template std::pair compute_facet_edge_intersection(const FacetWithVelocity2d & facet, const stk::math::Vector3d& edgePt0, const stk::math::Vector3d& edgePt1); +template double compute_intersection_between_surface_facets_and_edge(const std::vector & candidates, const stk::math::Vector3d & edgePt0, const stk::math::Vector3d & edgePt1); + +template stk::math::Vector3d compute_closest_point(const stk::math::Vector3d &x, const std::vector & nearestFacets); +template double point_distance_given_nearest_facets(const stk::math::Vector3d &x, const std::vector & nearestFacets, const double narrow_band_size, const double far_field_value, const bool compute_signed_distance); +template double compute_point_to_facets_distance_by_average_normal(const stk::math::Vector3d &x, const std::vector & facets); +template stk::math::Vector3d compute_pseudo_normal(const stk::math::Vector3d &x, const std::vector & nearestFacets); +template std::pair compute_facet_edge_intersection(const FacetWithVelocity3d & facet, const stk::math::Vector3d& edgePt0, const stk::math::Vector3d& edgePt1); +template double compute_intersection_between_surface_facets_and_edge(const std::vector & candidates, const stk::math::Vector3d & edgePt0, const stk::math::Vector3d & edgePt1); + } diff --git a/packages/krino/krino/surface/Akri_FacetedSurfaceCalcs.hpp b/packages/krino/krino/surface/Akri_FacetedSurfaceCalcs.hpp index 365dd493c09e..b28aefc0f214 100644 --- a/packages/krino/krino/surface/Akri_FacetedSurfaceCalcs.hpp +++ b/packages/krino/krino/surface/Akri_FacetedSurfaceCalcs.hpp @@ -13,6 +13,9 @@ namespace krino { std::vector fill_processor_bounding_boxes(const BoundingBox & localFacetBbox, const BoundingBox & localQueryBbox, const double truncationLength); + template + stk::math::Vector3d compute_closest_point(const stk::math::Vector3d &x, const std::vector & nearestFacets); + template double point_distance_given_nearest_facets(const stk::math::Vector3d &x, const std::vector & nearestFacets, const double narrow_band_size, const double far_field_value, const bool compute_signed_distance); diff --git a/packages/krino/krino/surface/Akri_Faceted_Surface.cpp b/packages/krino/krino/surface/Akri_Faceted_Surface.cpp index 7878e1e666dc..ddb5cf19cf3d 100644 --- a/packages/krino/krino/surface/Akri_Faceted_Surface.cpp +++ b/packages/krino/krino/surface/Akri_Faceted_Surface.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -49,13 +50,7 @@ static void unpack_and_append_facets_from_proc(stk::CommSparse & commSparse, con krinolog << "P" << stk::EnvData::parallel_rank() << ":" << " Receiving " << numProcFacets << " facets from proc#" << recvProc << stk::diag::dendl; for ( size_t n = 0; n < numProcFacets; ++n ) - { - FACET::unpack_facet_data_from_buffer(b, facetCoords); - if constexpr (FACET::DIM == 3) - facetVec.emplace_back(facetCoords[0], facetCoords[1], facetCoords[2]); - else - facetVec.emplace_back(facetCoords[0], facetCoords[1]); - } + facetVec.emplace_back(b); STK_ThrowAssert( 0 == b.remaining() ); } } @@ -282,7 +277,7 @@ void Faceted_Surface::prepare_to_compute(const double time, const Boundin my_facet_tree = std::make_unique>( myAllFacetPtrs, FACET::get_centroid, FACET::insert_into_bounding_box ); - if ( krinolog.shouldPrint(LOG_DEBUG) ) + if (krinolog.shouldPrint(LOG_DEBUG)) krinolog << "P" << stk::EnvData::parallel_rank() << ": After building search tree, storage size is " << storage_size()/(1024.*1024.) << " Mb." << stk::diag::dendl; } @@ -299,6 +294,35 @@ double Faceted_Surface::point_distance(const stk::math::Vector3d &x, cons return point_distance_given_nearest_facets(x, nearestFacets, narrow_band_size, far_field_value, compute_signed_distance); } +template +static const FACET * find_closest_facet(const stk::math::Vector3d &x, const std::vector & nearestFacets) +{ + const FACET* nearest = nullptr; + double minSqrDist = std::numeric_limits::max(); + for ( auto&& facet : nearestFacets ) + { + const double sqrDist = facet->point_distance_squared(x); + if (sqrDist < minSqrDist) + { + minSqrDist = sqrDist; + nearest = facet; + } + } + return nearest; +} + +template +const FACET * Faceted_Surface::get_closest_facet(const stk::math::Vector3d &x) const +{ + STK_ThrowAssertMsg(my_facet_tree, "ERROR: Empty facet tree"); + + std::vector nearestFacets; + my_facet_tree->find_closest_entities( x, nearestFacets ); + STK_ThrowRequire( !nearestFacets.empty() || my_facet_tree->empty() ); + + return find_closest_facet(x, nearestFacets); +} + template stk::math::Vector3d Faceted_Surface::pseudo_normal_at_closest_point(const stk::math::Vector3d &x) const { @@ -312,6 +336,19 @@ stk::math::Vector3d Faceted_Surface::pseudo_normal_at_closest_point(const return compute_pseudo_normal(x, nearestFacets); } +template +stk::math::Vector3d Faceted_Surface::closest_point(const stk::math::Vector3d &x) const +{ + if (my_facet_tree->empty()) + return stk::math::Vector3d::ZERO; + + std::vector nearestFacets; + my_facet_tree->find_closest_entities( x, nearestFacets, 0. ); + STK_ThrowRequire( !nearestFacets.empty() ); + + return compute_closest_point(x, nearestFacets); +} + template size_t Faceted_Surface::storage_size() const { @@ -403,5 +440,7 @@ std::string Faceted_Surface::print_sizes() const // Explicit template instantiation template class Faceted_Surface; template class Faceted_Surface; +template class Faceted_Surface; +template class Faceted_Surface; } // namespace krino diff --git a/packages/krino/krino/surface/Akri_Faceted_Surface.hpp b/packages/krino/krino/surface/Akri_Faceted_Surface.hpp index b7674ad14d2a..87cc0af53f87 100644 --- a/packages/krino/krino/surface/Akri_Faceted_Surface.hpp +++ b/packages/krino/krino/surface/Akri_Faceted_Surface.hpp @@ -28,6 +28,7 @@ class FacetedSurfaceBase : public SurfaceThatTakesAdvantageOfNarrowBandAndTheref { STK_ThrowRequire(myDim==2 || myDim==3); } static std::unique_ptr build(const int dim); + static std::unique_ptr build_with_velocity(const int dim); virtual Surface_Type type() const override { return (myDim == 3) ? FACETED_SURFACE_3D : FACETED_SURFACE_2D; } @@ -38,6 +39,7 @@ class FacetedSurfaceBase : public SurfaceThatTakesAdvantageOfNarrowBandAndTheref virtual double point_distance(const stk::math::Vector3d &x, const double narrow_band_size, const double far_field_value, const bool compute_signed_distance) const = 0; virtual void prepare_to_compute(const double time, const BoundingBox & point_bbox, const double truncation_length) = 0; virtual std::string print_sizes() const = 0; + virtual stk::math::Vector3d closest_point(const stk::math::Vector3d &x) const = 0; void prepare_to_compute(const BoundingBox & point_bbox, const double truncation_length) { @@ -106,8 +108,11 @@ class Faceted_Surface : public FacetedSurfaceBase const std::vector & get_facets() const { return myLocalFacets; } std::vector & get_facets() { return myLocalFacets; } + virtual stk::math::Vector3d closest_point(const stk::math::Vector3d &x) const override; + public: stk::math::Vector3d pseudo_normal_at_closest_point(const stk::math::Vector3d &x) const; + const FACET * get_closest_facet(const stk::math::Vector3d &x) const; private: virtual void build_local_facets(const BoundingBox & proc_bbox) {} @@ -127,6 +132,13 @@ inline std::unique_ptr FacetedSurfaceBase::build(const int d return std::make_unique>(); } +inline std::unique_ptr FacetedSurfaceBase::build_with_velocity(const int dim) +{ + if (dim == 2) + return std::make_unique>(); + return std::make_unique>(); +} + } // namespace krino #endif // Akri_Faceted_Surface_h diff --git a/packages/krino/krino/surface/Akri_String_Function_Expression.cpp b/packages/krino/krino/surface/Akri_String_Function_Expression.cpp index f47129655c19..4a1e89e3cb46 100644 --- a/packages/krino/krino/surface/Akri_String_Function_Expression.cpp +++ b/packages/krino/krino/surface/Akri_String_Function_Expression.cpp @@ -33,11 +33,22 @@ void String_Function_Expression::resolve(stk::expreval::VariableMap::iterator & std::string name = (*varIt).first; if (!(name).compare("x")) + { (*varIt).second->bind(myQueryCoords[0]); + } else if (!(name).compare("y")) + { (*varIt).second->bind(myQueryCoords[1]); + } else if (!(name).compare("z")) + { (*varIt).second->bind(myQueryCoords[2]); + } + else if (!(name).compare("t")) + { + (*varIt).second->bind(myTime); + myDoesUseTime = true; + } else { std::ostringstream msg; @@ -46,9 +57,19 @@ void String_Function_Expression::resolve(stk::expreval::VariableMap::iterator & } } +double +String_Function_Expression::evaluate(const double time, const stk::math::Vector3d &coord) const +{ + myTime = time; + myQueryCoords = coord; + return myEvaluator.evaluate(); +} + double String_Function_Expression::evaluate(const stk::math::Vector3d &coord) const { + if (myDoesUseTime) + throw std::runtime_error("String_Function_Expression is using time, but it is not provided in query."); myQueryCoords = coord; return myEvaluator.evaluate(); } diff --git a/packages/krino/krino/surface/Akri_String_Function_Expression.hpp b/packages/krino/krino/surface/Akri_String_Function_Expression.hpp index 5bcc259f93df..33c4236f73ba 100644 --- a/packages/krino/krino/surface/Akri_String_Function_Expression.hpp +++ b/packages/krino/krino/surface/Akri_String_Function_Expression.hpp @@ -20,10 +20,13 @@ class String_Function_Expression : public stk::expreval::VariableMap::Resolver String_Function_Expression(const std::string & expression); void resolve(stk::expreval::VariableMap::iterator & varIt) override; double evaluate(const stk::math::Vector3d &coords) const; + double evaluate(const double time, const stk::math::Vector3d &coord) const; private: void parse(const std::string & expression); stk::expreval::Eval myEvaluator; - mutable stk::math::Vector3d myQueryCoords; + mutable bool myDoesUseTime{false}; + mutable double myTime{0.0}; + mutable stk::math::Vector3d myQueryCoords{stk::math::Vector3d::ZERO}; }; } diff --git a/packages/krino/krino/unit_tests/Akri_Unit_InterfaceGeometry.hpp b/packages/krino/krino/unit_tests/Akri_Unit_InterfaceGeometry.hpp index 90ebb76b263d..84a1c32c5d3f 100644 --- a/packages/krino/krino/unit_tests/Akri_Unit_InterfaceGeometry.hpp +++ b/packages/krino/krino/unit_tests/Akri_Unit_InterfaceGeometry.hpp @@ -17,6 +17,7 @@ class IntersectionPointFromNodalLevelsetInterfaceGeometry : public InterfaceGeom public: virtual ~IntersectionPointFromNodalLevelsetInterfaceGeometry() {} virtual void prepare_to_decompose_elements(const stk::mesh::BulkData & mesh, const NodeToCapturedDomainsMap & nodesToCapturedDomains) const override {} + virtual void prepare_to_intersect_elements(const stk::mesh::BulkData & mesh) const override {} virtual void prepare_to_intersect_elements(const stk::mesh::BulkData & mesh, const NodeToCapturedDomainsMap & nodesToCapturedDomains) const override {} virtual void prepare_to_intersect_elements(const stk::mesh::BulkData & mesh, const std::vector & elementsToIntersect, @@ -24,8 +25,8 @@ class IntersectionPointFromNodalLevelsetInterfaceGeometry : public InterfaceGeom virtual std::vector get_possibly_cut_elements(const stk::mesh::BulkData & mesh) const override { STK_ThrowRequireMsg(false, "Unimplemented"); std::vector empty; return empty; } - virtual std::vector get_elements_that_intersect_interval(const stk::mesh::BulkData & mesh, const std::array loAndHi) const override - { STK_ThrowRequireMsg(false, "Unimplemented"); std::vector empty; return empty; } + virtual void fill_elements_that_intersect_distance_interval(const stk::mesh::BulkData & mesh, const Surface_Identifier surfaceIdentifier, const std::array loAndHi, std::vector & elementsThaIntersectInterval) const override + { STK_ThrowRequireMsg(false, "Unimplemented"); } virtual bool might_have_interior_or_face_intersections() const override { STK_ThrowRequireMsg(false, "Unimplemented"); return false; } virtual bool snapped_elements_may_have_new_intersections() const override { return false; } diff --git a/packages/krino/krino/unit_tests/Akri_Unit_RefineInterval.cpp b/packages/krino/krino/unit_tests/Akri_Unit_RefineInterval.cpp index 64871468e252..1465459c61e5 100644 --- a/packages/krino/krino/unit_tests/Akri_Unit_RefineInterval.cpp +++ b/packages/krino/krino/unit_tests/Akri_Unit_RefineInterval.cpp @@ -77,7 +77,8 @@ TEST(RefineWithinDistanceOfLevelSets, twoIntersectingLevelSets_correctElementsGe const std::array refinementDistanceInterval{-0.02,0.05}; const unsigned numRefinementLevels = 6; - krino::refine_elements_that_intersect_distance_interval_from_levelsets(mesh, activePart, levelSetFields, initialize_levelsets, refinementDistanceInterval, numRefinementLevels); + for (auto & levelSetField : levelSetFields) + krino::refine_elements_that_intersect_distance_interval_from_levelset(mesh, activePart, *levelSetField, initialize_levelsets, refinementDistanceInterval, numRefinementLevels); const bool doWriteMesh = false; if (doWriteMesh) diff --git a/packages/krino/tools/trilinos_snapshot.sh b/packages/krino/tools/trilinos_snapshot.sh new file mode 100755 index 000000000000..fdc794484ce4 --- /dev/null +++ b/packages/krino/tools/trilinos_snapshot.sh @@ -0,0 +1,71 @@ +#!/usr/bin/env bash + +exe() { + stdbuf -o0 -e0 echo "% $@" ; + eval "$@" ; + if [ $? -ne 0 ] ; then + echo "'$@' failed."; + exit 1; + fi +} + +verify_clean_repo() { + if [[ -n $(git status -s) ]] ; then + echo "Cannot proceed: repository at $1 is not clean" + exit 2; + fi +} + +verify_no_local_commits() { + if [[ $(git rev-list --left-only --count $1...origin/$1) -ne 0 ]] ; then + echo "Cannot proceed: branch $1 has local commits" + exit 3; + fi +} + +update_package() { + exe rm -rf packages/$1 + exe cp -r $SIERRA/$1 packages/$1 + exe git add --all packages/$1 +} + +export SIERRA=${SIERRA:-/fgs/$USER/trilinos-snapshot/code} +export SIERRA_BRANCH=master +export TRILINOS=${TRILINOS:-/fgs/$USER/trilinos-snapshot/Trilinos} +export TRILINOS_BRANCH=develop + +export SNAPSHOT_BRANCH=krino-snapshot + +echo "SIERRA: $SIERRA" +echo "TRILINOS: $TRILINOS" + +exe module load sierra-devel + +exe cd $SIERRA +verify_clean_repo $SIERRA +verify_no_local_commits $SIERRA_BRANCH +exe git checkout $SIERRA_BRANCH +exe repo sync +STK_VERSION_STRING=$(./stk/stk_util/stk_util/registry/stk_version_gen.sh) + +exe cd $TRILINOS +verify_clean_repo $TRILINOS +verify_no_local_commits $TRILINOS_BRANCH + +#Pull request workflow +exe git fetch upstream +exe git pull upstream develop +exe git push + +exe git checkout $TRILINOS_BRANCH +exe git pull + +exe git checkout $SNAPSHOT_BRANCH +exe git reset --hard $TRILINOS_BRANCH + +update_package krino +exe git rm -rf packages/krino/krino_sierra packages/krino/Jamfile packages/krino/.clang-format + +export COMMIT_MESSAGE="Krino: Snapshot $(date +'%m-%d-%y %H:%M') from Sierra $STK_VERSION_STRING" +exe git commit -am '"'$COMMIT_MESSAGE'"' +exe git push origin $SNAPSHOT_BRANCH From 132b16ae6ea3758cb3a51f032e689132f82601c8 Mon Sep 17 00:00:00 2001 From: Chris Siefert Date: Wed, 20 Mar 2024 10:41:14 -0600 Subject: [PATCH 13/17] Update TrilinosCTestDriverCore.lightsaber.gcc.cmake --- .../lightsaber/TrilinosCTestDriverCore.lightsaber.gcc.cmake | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/cmake/ctest/drivers/lightsaber/TrilinosCTestDriverCore.lightsaber.gcc.cmake b/cmake/ctest/drivers/lightsaber/TrilinosCTestDriverCore.lightsaber.gcc.cmake index e93f691e43da..3c3ff4aa104a 100644 --- a/cmake/ctest/drivers/lightsaber/TrilinosCTestDriverCore.lightsaber.gcc.cmake +++ b/cmake/ctest/drivers/lightsaber/TrilinosCTestDriverCore.lightsaber.gcc.cmake @@ -61,9 +61,7 @@ INCLUDE("${CTEST_SCRIPT_DIRECTORY}/../../TrilinosCTestDriverCore.cmake") # MACRO(TRILINOS_SYSTEM_SPECIFIC_CTEST_DRIVER) - - SET(CTEST_DROP_SITE "testing.sandia.gov") - + SET(CTEST_DROP_SITE "sems-cdash-son.sandia.gov") # Base of Trilinos/cmake/ctest then BUILD_DIR_NAME IF(COMM_TYPE STREQUAL MPI) From ca98a4d625572f1b49e477cb1bee00b18ed38d58 Mon Sep 17 00:00:00 2001 From: Chris Siefert Date: Wed, 20 Mar 2024 10:41:30 -0600 Subject: [PATCH 14/17] Update TrilinosCTestDriverCore.geminga.gcc-cuda.cmake --- .../geminga/TrilinosCTestDriverCore.geminga.gcc-cuda.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/ctest/drivers/geminga/TrilinosCTestDriverCore.geminga.gcc-cuda.cmake b/cmake/ctest/drivers/geminga/TrilinosCTestDriverCore.geminga.gcc-cuda.cmake index 72233790a54b..83d94b3d555a 100644 --- a/cmake/ctest/drivers/geminga/TrilinosCTestDriverCore.geminga.gcc-cuda.cmake +++ b/cmake/ctest/drivers/geminga/TrilinosCTestDriverCore.geminga.gcc-cuda.cmake @@ -61,7 +61,7 @@ INCLUDE("${CTEST_SCRIPT_DIRECTORY}/../../TrilinosCTestDriverCore.cmake") # MACRO(TRILINOS_SYSTEM_SPECIFIC_CTEST_DRIVER) - + SET(CTEST_DROP_SITE "sems-cdash-son.sandia.gov") # Base of Trilinos/cmake/ctest then BUILD_DIR_NAME IF(COMM_TYPE STREQUAL MPI) From 8d32733e4427f850c9cb76dfa8e147d03547eb68 Mon Sep 17 00:00:00 2001 From: Chris Siefert Date: Wed, 20 Mar 2024 10:41:48 -0600 Subject: [PATCH 15/17] Update TrilinosCTestDriverCore.geminga.gcc.cmake --- .../drivers/geminga/TrilinosCTestDriverCore.geminga.gcc.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/ctest/drivers/geminga/TrilinosCTestDriverCore.geminga.gcc.cmake b/cmake/ctest/drivers/geminga/TrilinosCTestDriverCore.geminga.gcc.cmake index 37bacdc2b98d..bd73358d9c02 100644 --- a/cmake/ctest/drivers/geminga/TrilinosCTestDriverCore.geminga.gcc.cmake +++ b/cmake/ctest/drivers/geminga/TrilinosCTestDriverCore.geminga.gcc.cmake @@ -61,7 +61,7 @@ INCLUDE("${CTEST_SCRIPT_DIRECTORY}/../../TrilinosCTestDriverCore.cmake") # MACRO(TRILINOS_SYSTEM_SPECIFIC_CTEST_DRIVER) - + SET(CTEST_DROP_SITE "sems-cdash-son.sandia.gov") # Base of Trilinos/cmake/ctest then BUILD_DIR_NAME IF(COMM_TYPE STREQUAL MPI) From 0bd74ac3892add73380fe7a35fc0a768d8fa3226 Mon Sep 17 00:00:00 2001 From: Brian Kelley Date: Wed, 20 Mar 2024 15:39:52 -0600 Subject: [PATCH 16/17] Tpetra: delete broken KokkosUVM test It crashes --- .../test/KokkosIntegration/CMakeLists.txt | 7 - .../core/test/KokkosIntegration/KokkosUVM.cpp | 149 ------------------ 2 files changed, 156 deletions(-) delete mode 100644 packages/tpetra/core/test/KokkosIntegration/KokkosUVM.cpp diff --git a/packages/tpetra/core/test/KokkosIntegration/CMakeLists.txt b/packages/tpetra/core/test/KokkosIntegration/CMakeLists.txt index e97ec317b559..1927063f9c99 100644 --- a/packages/tpetra/core/test/KokkosIntegration/CMakeLists.txt +++ b/packages/tpetra/core/test/KokkosIntegration/CMakeLists.txt @@ -20,13 +20,6 @@ IF (Tpetra_ENABLE_CUDA AND BUILD_SHARED_LIBS AND Tpetra_ENABLE_KokkosIntegration TESTONLY ) - TRIBITS_ADD_EXECUTABLE( - KokkosUVM - SOURCES KokkosUVM.cpp - TESTONLYLIBS ApiTest - COMM serial mpi - ) - TRIBITS_ADD_EXECUTABLE( KokkosDeepcopy SOURCES KokkosDeepcopy.cpp diff --git a/packages/tpetra/core/test/KokkosIntegration/KokkosUVM.cpp b/packages/tpetra/core/test/KokkosIntegration/KokkosUVM.cpp deleted file mode 100644 index 3e0748450e9c..000000000000 --- a/packages/tpetra/core/test/KokkosIntegration/KokkosUVM.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/* -// @HEADER -// *********************************************************************** -// -// Tpetra: Templated Linear Algebra Services Package -// Copyright (2008) Sandia Corporation -// -// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, -// the U.S. Government retains certain rights in this software. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// 1. Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// 3. Neither the name of the Corporation nor the names of the -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE -// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Questions? Contact Michael A. Heroux (maherou@sandia.gov) -// -// ************************************************************************ -// @HEADER -*/ - -#include - -#include "Kokkos_Core.hpp" -#include "Teuchos_StackedTimer.hpp" - - -class UVMTester { -public: - UVMTester() - : n(10), - factorDevice(2), - factorHost(5), - factorCombined(factorDevice*factorHost), - view("UVM View", n) - { } - - void run() { - log("Tpetra Kokkos UVM test start"); - - fillOnHost(); - modifyOnDevice(); - modifyOnHost(); - - if (isConsistent()) log("+++ Result is consistent +++"); - else log("!!! Result is inconsistent !!!"); - } - - void fillOnHost() { - Teuchos::TimeMonitor timer(*Teuchos::TimeMonitor::getNewTimer("fill on host")); - Kokkos::parallel_for( - "fill on host", - Kokkos::RangePolicy(0,n), - KOKKOS_LAMBDA(const int i) { - view(i) = i; - }); - } - - void modifyOnDevice() { - Teuchos::TimeMonitor timer(*Teuchos::TimeMonitor::getNewTimer("modify on device")); - Kokkos::parallel_for( - "modify on device", - Kokkos::RangePolicy(0,n), - KOKKOS_LAMBDA(const int i) { - view(i) *= factorDevice; - }); - Kokkos::fence(); - } - - void modifyOnHost() { - Teuchos::TimeMonitor timer(*Teuchos::TimeMonitor::getNewTimer("modify on host")); - Kokkos::parallel_for( - "modify on host", - Kokkos::RangePolicy(0,n), - KOKKOS_LAMBDA(const int i) { - view(i) *= factorHost; - }); - } - -private: - bool isConsistent() { - Teuchos::TimeMonitor timer(*Teuchos::TimeMonitor::getNewTimer("consistency check")); - bool correct = true; - for (int i=0; i view; -}; - -void reportTimings(Teuchos::RCP timer) { - Teuchos::RCP > comm = Teuchos::DefaultComm::getComm(); - - Teuchos::StackedTimer::OutputOptions options; - options.output_fraction = true; - options.output_histogram = true; - options.output_minmax = true; - - Teuchos::RCP out = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout)); - out->setOutputToRootOnly(0); - - timer->report(*out, comm, options); -} - -int main(int argc, char *argv[]) { - Kokkos::initialize(argc, argv); - - Teuchos::RCP stacked_timer = Teuchos::rcp(new Teuchos::StackedTimer("UVM Test")); - Teuchos::TimeMonitor::setStackedTimer(stacked_timer); - - UVMTester tester; - tester.run(); - - reportTimings(stacked_timer); - Kokkos::finalize(); - return 0; -} From 7897a3ab85f5db9ba8a6a6f30fa35443ca461309 Mon Sep 17 00:00:00 2001 From: Christian Glusa Date: Wed, 20 Mar 2024 17:20:42 -0600 Subject: [PATCH 17/17] Panzer MiniEM: Use truncated MG hierarchies on GPU --- .../example/BlockPrec/solverMueLuCuda.xml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/packages/panzer/mini-em/example/BlockPrec/solverMueLuCuda.xml b/packages/panzer/mini-em/example/BlockPrec/solverMueLuCuda.xml index a3ab680e2f5e..6dae2f4998dc 100644 --- a/packages/panzer/mini-em/example/BlockPrec/solverMueLuCuda.xml +++ b/packages/panzer/mini-em/example/BlockPrec/solverMueLuCuda.xml @@ -20,6 +20,15 @@ + + + + + + + + + @@ -29,6 +38,15 @@ + + + + + > + + + +