diff --git a/AMDiS/AMDISConfig.cmake.in b/AMDiS/AMDISConfig.cmake.in index 8c84c348c4476afcf831c627c6e8b295c3a3571b..95f6e6675f2f8dba3071a6ddae29f7649e11df12 100644 --- a/AMDiS/AMDISConfig.cmake.in +++ b/AMDiS/AMDISConfig.cmake.in @@ -59,12 +59,12 @@ unset(_AMDIS_LIB CACHE) # Boost libraries # --------------- set(AMDIS_HAS_PARALLEL_DOMAIN @ENABLE_PARALLEL_DOMAIN@) -set(AMDIS_NEED_COMPRESSION @ENABLE_COMPRESSIN@) +set(AMDIS_NEED_COMPRESSION @ENABLE_COMPRESSION@) set(BOOST_LIBS_REQUIRED system iostreams filesystem program_options date_time) -if(AMDIS_NEED_COMPRESSION) +if(WIN32 AND AMDIS_NEED_COMPRESSION) list(APPEND BOOST_LIBS_REQUIRED zlib bzip2) -endif(AMDIS_NEED_COMPRESSION) +endif(WIN32 AND AMDIS_NEED_COMPRESSION) set(BOOST_VERSION "1.42") if(AMDIS_HAS_PARALLEL_DOMAIN) diff --git a/AMDiS/CMakeLists.txt b/AMDiS/CMakeLists.txt index 07e26605fe42c225a9e44f1a7a1afca47ec9a86d..0b98bf11fb4290779c9bd1cbe742788b49a9235b 100644 --- a/AMDiS/CMakeLists.txt +++ b/AMDiS/CMakeLists.txt @@ -56,6 +56,8 @@ option(ENABLE_OUTPUT "AMDiS output printing, disable only for debugging!" true) mark_as_advanced(ENABLE_OUTPUT) +mark_as_advanced(ENABLE_BDDCML) +mark_as_advanced(USE_PETSC_DEV) find_package(Boost 1.44 REQUIRED) @@ -81,6 +83,7 @@ SET(AMDIS_SRC ${SOURCE_DIR}/AdaptBase.cc ${SOURCE_DIR}/Boundary.cc ${SOURCE_DIR}/BoundaryManager.cc ${SOURCE_DIR}/BoundaryObject.cc + ${SOURCE_DIR}/Bubble.cc ${SOURCE_DIR}/Cholesky.cc ${SOURCE_DIR}/CoarseningManager.cc ${SOURCE_DIR}/CoarseningManager1d.cc @@ -125,7 +128,7 @@ SET(AMDIS_SRC ${SOURCE_DIR}/AdaptBase.cc ${SOURCE_DIR}/OperatorTerm.cc ${SOURCE_DIR}/Parametric.cc ${SOURCE_DIR}/PeriodicBC.cc - ${SOURCE_DIR}/ProblemImplicit.cc + #${SOURCE_DIR}/ProblemImplicit.cc ${SOURCE_DIR}/ProblemInstat.cc ${SOURCE_DIR}/ProblemInterpol.cc ${SOURCE_DIR}/ProblemStat.cc @@ -342,7 +345,7 @@ endif(ENABLE_UMFPACK) if(ENABLE_HYPRE) - include(FindHYPRE.cmake) + include(HYPREConfig.cmake) message("have hypre: ${HAVE_HYPRE}") if (HAVE_HYPRE) if (NOT MPI_FOUND) @@ -437,13 +440,15 @@ if(ENABLE_EXTENSIONS) if(ENABLE_SEQ_PETSC) list(APPEND EXTENSIONS_SRC ${EXTENSIONS_DIR}/preconditioner/PetscPreconPfc.cc + ${EXTENSIONS_DIR}/preconditioner/PetscPreconPfcDiag.cc ${EXTENSIONS_DIR}/preconditioner/PetscPreconCahnHilliard.cc) endif(ENABLE_SEQ_PETSC) if(ENABLE_PARALLEL_DOMAIN) list(APPEND EXTENSIONS_SRC # ${EXTENSIONS_DIR}/preconditioner/PetscSolverNavierStokes2.cc - ${EXTENSIONS_DIR}/preconditioner/PetscSolverPfc.cc) + ${EXTENSIONS_DIR}/preconditioner/PetscSolverPfc.cc + ${EXTENSIONS_DIR}/preconditioner/PetscSolverPfc_diag.cc) endif(ENABLE_PARALLEL_DOMAIN) list(APPEND COMPILEFLAGS "-DHAVE_EXTENSIONS=1") @@ -502,7 +507,7 @@ if(ENABLE_EXTENSIONS) if(ENABLE_BASE_PROBLEMS) SET(BASE_PROBLEMS_SRC -# ${EXTENSIONS_DIR}/base_problems/CahnHilliard.cc + ${EXTENSIONS_DIR}/base_problems/CahnHilliard.cc ${EXTENSIONS_DIR}/base_problems/CahnHilliard_RB.cc ${EXTENSIONS_DIR}/base_problems/CahnHilliardNavierStokes.cc # ${EXTENSIONS_DIR}/base_problems/DiffuseDomainFsi.cc @@ -511,13 +516,15 @@ if(ENABLE_EXTENSIONS) # ${EXTENSIONS_DIR}/base_problems/NavierStokes_Chorin.cc ${EXTENSIONS_DIR}/base_problems/NavierStokesCahnHilliard.cc ${EXTENSIONS_DIR}/base_problems/NavierStokesPhase_TaylorHood.cc -# ${EXTENSIONS_DIR}/base_problems/NavierStokes_TaylorHood.cc + ${EXTENSIONS_DIR}/base_problems/NavierStokes_TaylorHood.cc ${EXTENSIONS_DIR}/base_problems/NavierStokes_TaylorHood_RB.cc -# ${EXTENSIONS_DIR}/base_problems/NavierStokes_TH_MultiPhase.cc + ${EXTENSIONS_DIR}/base_problems/NavierStokes_TH_MultiPhase.cc ${EXTENSIONS_DIR}/base_problems/NavierStokes_TH_MultiPhase_RB.cc ${EXTENSIONS_DIR}/base_problems/PhaseFieldCrystal.cc ${EXTENSIONS_DIR}/base_problems/PhaseFieldCrystal_Phase.cc - ${EXTENSIONS_DIR}/base_problems/PhaseFieldCrystal_RB.cc) + ${EXTENSIONS_DIR}/base_problems/PhaseFieldCrystal_RB.cc + ${EXTENSIONS_DIR}/base_problems/PolarizationField.cc + ${EXTENSIONS_DIR}/base_problems/QuasiCrystal.cc) list(APPEND COMPILEFLAGS "-DHAVE_BASE_PROBLEMS=1") list(APPEND AMDIS_INCLUDE_DIRS ${EXTENSIONS_DIR}/base_problems) if(WIN32) @@ -647,11 +654,21 @@ INSTALL(FILES ${HEADERS} DESTINATION include/amdis/est/) list(APPEND deb_add_dirs "include/amdis/est") -FILE(GLOB HEADERS "${SOURCE_DIR}/expressions/*.h") +FILE(GLOB HEADERS "${SOURCE_DIR}/expressions/*.h*") INSTALL(FILES ${HEADERS} DESTINATION include/amdis/expressions/) list(APPEND deb_add_dirs "include/amdis/expressions") +FILE(GLOB HEADERS "${SOURCE_DIR}/operations/*.h*") +INSTALL(FILES ${HEADERS} + DESTINATION include/amdis/operations/) +list(APPEND deb_add_dirs "include/amdis/operations") + +FILE(GLOB HEADERS "${SOURCE_DIR}/traits/*.h*") +INSTALL(FILES ${HEADERS} + DESTINATION include/amdis/traits/) +list(APPEND deb_add_dirs "include/amdis/traits") + FILE(GLOB HEADERS "${SOURCE_DIR}/time/*.h") INSTALL(FILES ${HEADERS} DESTINATION include/amdis/time/) diff --git a/AMDiS/FindHYPRE.cmake b/AMDiS/HYPREConfig.cmake similarity index 100% rename from AMDiS/FindHYPRE.cmake rename to AMDiS/HYPREConfig.cmake diff --git a/AMDiS/src/AMDiS.h b/AMDiS/src/AMDiS.h index 6ce7e89e28c77744a855f0b438dc9f259ec1d823..f27c34ab5bf960bbc7790114e6c34920cc51d161 100644 --- a/AMDiS/src/AMDiS.h +++ b/AMDiS/src/AMDiS.h @@ -37,6 +37,7 @@ #include "Boundary.h" #include "BoundaryCondition.h" #include "BoundaryManager.h" +#include "Bubble.h" #include "CoarseningManager.h" #include "CoarseningManager1d.h" #include "CoarseningManager2d.h" @@ -73,7 +74,7 @@ #include "Line.h" #include "MacroElement.h" #include "Marker.h" -#include "MathFunctions.h" +// #include "MathFunctions.h" #include "MatrixVector.h" #include "Mesh.h" #include "MeshStructure.h" @@ -85,7 +86,7 @@ #include "ProblemStat.h" #include "ProblemInstat.h" #include "ProblemTimeInterface.h" -#include "ProblemImplicit.h" +// #include "ProblemImplicit.h" #include "ProblemInterpol.h" #include "ProblemStatBase.h" #include "SecondOrderTerm.h" @@ -106,6 +107,7 @@ #include "TimedObject.h" #include "TransformDOF.h" #include "Traverse.h" +#include "Traits.h" #include "Triangle.h" #include "VertexVector.h" #include "ZeroOrderTerm.h" @@ -153,7 +155,7 @@ #include "parallel/ParallelProblemStat.h" #if HAVE_PARALLEL_MTL4 -#include "parallel/PMTL4Solver.h" +// #include "parallel/PMTL4Solver.h" #else #include "parallel/PetscSolver.h" #include "parallel/PetscSolverNavierStokes.h" diff --git a/AMDiS/src/AMDiS_fwd.h b/AMDiS/src/AMDiS_fwd.h index a6238d284735e114805cfcbbad9b00e9400f091f..8ea6e49f88d3556b3926bc6af5576ff1a31f8996 100644 --- a/AMDiS/src/AMDiS_fwd.h +++ b/AMDiS/src/AMDiS_fwd.h @@ -104,7 +104,7 @@ namespace AMDiS { class ElementFileWriter; class GNUPlotWriter; class MacroReader; - class MacroWriter; + struct MacroWriter; class PngWriter; class PovrayWriter; class Spreadsheet; diff --git a/AMDiS/src/AdaptInfo.h b/AMDiS/src/AdaptInfo.h index 079135a925e01a9e25be03b1e4377ed0528bfe53..340edc191ba7cc2a5e36dfee480fdbdd23606935 100644 --- a/AMDiS/src/AdaptInfo.h +++ b/AMDiS/src/AdaptInfo.h @@ -57,6 +57,7 @@ namespace AMDiS { fac_sum(1.0), spaceTolerance(0.0), timeTolerance(0.0), + timeRelativeTolerance(0.0), timeErrLow(0.0), coarsenAllowed(0), refinementAllowed(1), @@ -65,6 +66,7 @@ namespace AMDiS { { Parameters::get(prefix + "->tolerance", spaceTolerance); Parameters::get(prefix + "->time tolerance", timeTolerance); + Parameters::get(prefix + "->time relative tolerance", timeRelativeTolerance); Parameters::get(prefix + "->coarsen allowed", coarsenAllowed); Parameters::get(prefix + "->refinement allowed", refinementAllowed); Parameters::get(prefix + "->refine bisections", refineBisections); @@ -72,6 +74,8 @@ namespace AMDiS { Parameters::get(prefix + "->sum factor", fac_sum); Parameters::get(prefix + "->max factor", fac_max); + if (timeTolerance == 0.0 && timeRelativeTolerance == 0.0) + timeTolerance = 1.0; timeErrLow = timeTolerance * 0.3; } @@ -95,6 +99,9 @@ namespace AMDiS { /// Time tolerance. double timeTolerance; + + /// Relative time tolerance + double timeRelativeTolerance; /// Lower bound for the time error. double timeErrLow; @@ -143,6 +150,7 @@ namespace AMDiS { maxSolverIterations(0), solverTolerance(1e-8), solverResidual(0.0), + globalTimeTolerance(1.0), scalContents(size), deserialized(false), rosenbrockMode(false) @@ -175,6 +183,7 @@ namespace AMDiS { Parameters::get(name + "->min timestep", minTimestep); Parameters::get(name + "->max timestep", maxTimestep); Parameters::get(name + "->number of timesteps", nTimesteps); + Parameters::get(name + "->time tolerance", globalTimeTolerance); } /// Resets all variables to zero (or something equivalent) @@ -481,6 +490,12 @@ namespace AMDiS { return scalContents[index]->timeTolerance; } + /// Returns \ref timeRelativeTolerance. + inline double getTimeRelativeTolerance(int index) + { + return scalContents[index]->timeRelativeTolerance; + } + /// Sets \ref time inline double setTime(double t) { @@ -690,6 +705,18 @@ namespace AMDiS { { return solverResidual; } + + inline void setGlobalTimeTolerance(double tol) + { + globalTimeTolerance = tol; + } + + inline double getGlobalTimeTolerance() + { + return globalTimeTolerance; + } + + /// Returns true, if the adaptive procedure was deserialized from a file. bool isDeserialized() const @@ -796,6 +823,9 @@ namespace AMDiS { /// double solverResidual; + + /// tolerance for the overall time error + double globalTimeTolerance; /// Scalar adapt infos. std::vector<ScalContent*> scalContents; diff --git a/AMDiS/src/AdaptInstationary.cc b/AMDiS/src/AdaptInstationary.cc index 6adba249179ae0d36e6116c106acdf904c446a3f..94c84756ba6264c56f4bd2eb1815295f6222f5e8 100644 --- a/AMDiS/src/AdaptInstationary.cc +++ b/AMDiS/src/AdaptInstationary.cc @@ -162,12 +162,6 @@ namespace AMDiS { problemIteration->oneIteration(adaptInfo, FULL_ITERATION); problemIteration->endIteration(adaptInfo); adaptInfo->setLastProcessedTimestep(adaptInfo->getTimestep()); - if (dbgMode) { - std::cout << "=== ADAPT INFO DEBUG MODE ===\n"; - std::cout << "=== explicitTimeStrategy() ===\n"; - adaptInfo->printTimeErrorLowInfo(); - } - } @@ -207,15 +201,24 @@ namespace AMDiS { // === Space iterations. === do { problemIteration->beginIteration(adaptInfo); - if (dbgMode) { - std::cout << "=== ADAPT INFO DEBUG MODE ===\n"; - std::cout << "=== in implicitTimeStrategy() ===\n"; - std::cout << "=== space/time iteration "<< adaptInfo->getSpaceIteration() - <<" : "<< adaptInfo->getTimestepIteration() <<" ===\n"; - adaptInfo->printTimeErrorLowInfo(); - } - - if (problemIteration->oneIteration(adaptInfo, FULL_ITERATION)) { + + if (dbgMode) { + std::cout << "=== ADAPT INFO DEBUG MODE ===\n"; + std::cout << "=== in implicitTimeStrategy() ===\n"; + std::cout << "=== space/time iteration "<< adaptInfo->getSpaceIteration() + <<" : "<< adaptInfo->getTimestepIteration() <<" ===\n"; + adaptInfo->printTimeErrorLowInfo(); + } + + Flag adapted = problemIteration->oneIteration(adaptInfo, FULL_ITERATION); +#if HAVE_PARALLEL_DOMAIN_AMDIS + int recvAllValues = 0; + int isAdapted = static_cast<bool>(adapted); + MPI::COMM_WORLD.Allreduce(&isAdapted, &recvAllValues, 1, MPI_INT, MPI_SUM); + if (recvAllValues) { +#else + if (adapted) { +#endif if (!fixedTimestep && !adaptInfo->timeToleranceReached() && !(adaptInfo->getTimestep() <= adaptInfo->getMinTimestep())) { @@ -244,7 +247,6 @@ namespace AMDiS { adaptInfo->setLastProcessedTimestep(adaptInfo->getTimestep()); - // After successful iteration/timestep the timestep will be changed according // adaption rules for next timestep. // First, check for increase of timestep diff --git a/AMDiS/src/AdaptStationary.cc b/AMDiS/src/AdaptStationary.cc index a8593cbac25e02833251fefaaa635e13dca425fe..9a92eab69fbd8d4a402337184a1361ba05e04094 100644 --- a/AMDiS/src/AdaptStationary.cc +++ b/AMDiS/src/AdaptStationary.cc @@ -99,7 +99,7 @@ namespace AMDiS { void AdaptStationary::initialize() - { + { Parameters::get(name + "->info", info); } diff --git a/AMDiS/src/BasisFunction.cc b/AMDiS/src/BasisFunction.cc index 10d06da9f26fb6692590dcc7eae7958eeebb69cf..3a690abc03be564cf775b0a88b88d5ce7ad95c44 100644 --- a/AMDiS/src/BasisFunction.cc +++ b/AMDiS/src/BasisFunction.cc @@ -25,6 +25,7 @@ #include "DOFVector.h" #include "BasisFunction.h" #include "Lagrange.h" +#include "Bubble.h" namespace AMDiS { diff --git a/AMDiS/src/BasisFunction.h b/AMDiS/src/BasisFunction.h index 7813e1cee518104e44ce77771e81ed8573c38435..5ef65e0796dc27e8c8189959f6900ae2bccaa1bb 100644 --- a/AMDiS/src/BasisFunction.h +++ b/AMDiS/src/BasisFunction.h @@ -27,6 +27,7 @@ #include <string> #include "AMDiS_fwd.h" +#include "CreatorInterface.h" #include "Global.h" #include "Boundary.h" #include "MatrixVector.h" @@ -311,6 +312,12 @@ namespace AMDiS { const ElementVector& uh, WorldMatrix<double>* val) const; + /** + * override this method, if the base of your finite element space is not + * nodal + */ + virtual bool isNodal() const = 0; + protected: /// Textual description std::string name; @@ -339,6 +346,26 @@ namespace AMDiS { /// Vector of second derivatives std::vector<D2BasFctType*> *d2Phi; }; + + /** + * \brief + * Interface for creators of concrete BasisFunctions. + */ + class BasisFunctionCreator : public CreatorInterface<BasisFunction> + { + public: + virtual ~BasisFunctionCreator() {} + + /// Sets \ref problem + void setDim(int dim_) + { + dim = dim_; + } + + protected: + /// dimension of the mesh + int dim; + }; } #include "BasisFunction.hh" diff --git a/AMDiS/src/Bubble.cc b/AMDiS/src/Bubble.cc new file mode 100644 index 0000000000000000000000000000000000000000..f31b2f4e3081413ec933eecab8c2d5c75addc7e6 --- /dev/null +++ b/AMDiS/src/Bubble.cc @@ -0,0 +1,980 @@ +/****************************************************************************** + * + * AMDiS - Adaptive multidimensional simulations + * + * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. + * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis + * + * Authors: + * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * + * This file is part of AMDiS + * + * See also license.opensource.txt in the distribution. + * + ******************************************************************************/ + + +#include <stdio.h> +#include <algorithm> +#include <list> +#include "boost/lexical_cast.hpp" +#include "Mesh.h" +#include "Element.h" +#include "Bubble.h" +#include "DOFAdmin.h" +#include "RCNeighbourList.h" +#include "DOFVector.h" +#include "Traverse.h" +#include "Line.h" +#include "Triangle.h" +#include "Tetrahedron.h" +#include "Parametric.h" +#include "Debug.h" + +namespace AMDiS { + + using namespace std; + using boost::lexical_cast; + + std::vector<DimVec<double>* > Bubble::baryDimDegree; // lists with all basis-functions (important for later versions) + DimVec<int>* Bubble::ndofDimDegree; // number of DOFs per element + int Bubble::nBasFctsDimDegree; // number of basis functions per element + std::vector<BasFctType*> Bubble::phifunc; // basis functions + std::vector<GrdBasFctType*> Bubble::grdPhifunc; // first derivatives + std::vector<D2BasFctType*> Bubble::D2Phifunc; // second derivatives + + Bubble* Bubble::Singleton = nullptr; + + Bubble::Bubble(int dim, int degree) + : BasisFunction(std::string("Bubble"), dim, degree) + { + // set name + name += lexical_cast<std::string>(dim) + " " + lexical_cast<std::string>(degree); + + // set nDOF + setNDOF(); + + // set barycentric coordinates + setBary(); + + // set function pointer + setFunctionPointer(); + } + + + Bubble::~Bubble() + { + for (int i = 0; i < static_cast<int>(bary->size()); i++) + if ((*bary)[i]) { + delete (*bary)[i]; + (*bary)[i] = nullptr; + } + } + + + // creates a new FE-Space of this instance + Bubble* Bubble::getBubble(int dim, int degree) + { + if (Singleton == nullptr) //if their is no instance + { + Singleton = new Bubble(dim, degree); + } + return Singleton; + } + + + void Bubble::clear() + { + if (Singleton) { + delete (Singleton); + Singleton = nullptr; + } + } + + // set pointers to the used basis functions and their first and + // second derivatives. + // set also the refinement and coarsening functions + void Bubble::setFunctionPointer() + { + if (static_cast<int>(phifunc.size()) == 0) { + + for(int i = 0; i < dim+1; i++){ + phifunc.push_back(new Phi(this, VERTEX, i, 0)); // Vertex + grdPhifunc.push_back(new GrdPhi(this, VERTEX, i, 0)); + D2Phifunc.push_back(new D2Phi(this, VERTEX, i, 0)); + } + phifunc.push_back(new Phi(this, CENTER, 0, 0)); // Bubble + grdPhifunc.push_back(new GrdPhi(this, CENTER, 0, 0)); + D2Phifunc.push_back(new D2Phi(this, CENTER, 0, 0)); + + } + phi = &phifunc; + grdPhi = &grdPhifunc; + d2Phi = &D2Phifunc; + + // set refinement & coarse interpolation/restriction Function + switch (dim) { + case 1: + refineInter_fct = refineInter2_1d; + coarseRestr_fct = coarseRestr2_1d; + coarseInter_fct = coarseInter2_1d; + break; + case 2: + refineInter_fct = refineInter3_2d; + coarseRestr_fct = coarseRestr3_2d; + coarseInter_fct = coarseInter3_2d; + break; + case 3: + refineInter_fct = refineInter4_3d; + coarseRestr_fct = coarseRestr4_3d; + coarseInter_fct = coarseInter4_3d; + break; + default: + ERROR_EXIT("invalid dim!\n"); + } + } + + + + void Bubble::setNDOF() + { + nBasFcts = dim + 2; + nDOF = new DimVec<int>(dim, DEFAULT_VALUE, 0); +// for (int i = 0; i < dim; i++) + (*nDOF)[0] = 1; // CENTER + (*nDOF)[1] = 1; // VERTEX + } + + + DimVec<double> *Bubble::getCoords(int i) const + { + return (*bary)[i]; + } + + + void Bubble::setVertices(int dim, int degree, + GeoIndex position, int positionIndex, int nodeIndex, + int** vertices) + { + FUNCNAME_DBG("Bubble::setVertices()"); + + TEST_EXIT_DBG(*vertices == nullptr)("vertices != nullptr\n"); + + int dimOfPosition = DIM_OF_INDEX(position, dim); + + *vertices = new int[dimOfPosition + 1]; + + if (position == VERTEX) { // Vertex + (*vertices)[0] = Global::getReferenceElement(dim)->getVertexOfPosition(position, + positionIndex, 0); + } + else { // Bubble + for (int i = 0; i < dim+1; i++) { + (*vertices)[i] = Global::getReferenceElement(dim)->getVertexOfPosition(position, + positionIndex, i); + } + } + } + + + Bubble::Phi::Phi(Bubble* owner, + GeoIndex position, + int positionIndex, + int nodeIndex) + : vertices(nullptr) + { + FUNCNAME("Bubble::Phi::Phi()"); + + // get relevant vertices + Bubble::setVertices(owner->getDim(), + owner->getDegree(), + position, + positionIndex, + nodeIndex, + &vertices); + + // set function pointer + switch (position) { + case VERTEX: + func = phi1v; + break; + case CENTER: + switch (owner->getDim()) { + case 1: + func = phi2c; + break; + case 2: + func = phi3c; + break; + case 3: + func = phi4c; + break; + default: + ERROR_EXIT("invalid dim\n"); + break; + } + break; + default: + ERROR_EXIT("invalid position\n"); + } + } + + + Bubble::Phi::~Phi() + { + delete [] vertices; + } + + + Bubble::GrdPhi::GrdPhi(Bubble* owner, + GeoIndex position, + int positionIndex, + int nodeIndex) + : vertices(nullptr) + { + // get relevant vertices + Bubble::setVertices(owner->getDim(), + owner->getDegree(), + position, + positionIndex, + nodeIndex, + &vertices); + + // set function pointer + switch (position) { + case VERTEX: + func = grdPhi1v; + break; + case CENTER: + switch (owner->getDim()) { + case 1: + func = grdPhi2c; + break; + case 2: + func = grdPhi3c; + break; + case 3: + func = grdPhi4c; + break; + default: + ERROR_EXIT("invalid dim\n"); + break; + } + break; + default: + ERROR_EXIT("invalid position\n"); + } + } + + Bubble::GrdPhi::~GrdPhi() + { + delete [] vertices; + } + + Bubble::D2Phi::D2Phi(Bubble* owner, + GeoIndex position, + int positionIndex, + int nodeIndex) + : vertices(nullptr) + { + // get relevant vertices + Bubble::setVertices(owner->getDim(), + owner->getDegree(), + position, + positionIndex, + nodeIndex, + &vertices); + + // set function pointer + switch (position) { + case VERTEX: + func = D2Phi1v; + break; + case CENTER: + switch (owner->getDim()) { + case 1: + func = D2Phi2c; + break; + case 2: + func = D2Phi3c; + break; + case 3: + func = D2Phi4c; + break; + default: + ERROR_EXIT("invalid dim\n"); + break; + } + break; + default: + ERROR_EXIT("invalid position\n"); + } + } + + Bubble::D2Phi::~D2Phi() + { + delete [] vertices; + } + + // fills bary with the barycentric coordinates of the basis functions + void Bubble::setBary() + { + bary = &baryDimDegree; + if (static_cast<int>(bary->size()) == 0) { //nur ausführen, falls bary leer + bary = new vector<DimVec<double>* >; + + for (int i = 0; i < dim+1; i++) { + DimVec<double>* unit = new DimVec<double>(dim, DEFAULT_VALUE, 0.0); + (*unit)[i] = 1.0; + bary->push_back(unit); //coordinates of the Lagrange functions + } + bary->push_back(new DimVec<double>(dim, DEFAULT_VALUE,1.0/(dim + 1.0))); //coordinates of the bubble function + } + } + + // position = {vertex, edge, face, center} + // positionIndex i'th DOF at position + int* Bubble::orderOfPositionIndices(const Element* el, + GeoIndex position, + int positionIndex) const + { + // returns 0 in all valid cases + static int sortedVertex = 0; + static int sortedCenter = 0; + + if (position == VERTEX) + return &sortedVertex; + + if (position == CENTER) + return &sortedCenter; + + ERROR_EXIT("should not be reached\n"); + return nullptr; + } + + + // assign each DOF to the corresponding boundary type, + // following a strict order (vertices DOFs, edge-DOFs, faces-DOFs, center-DOFs) + // with the help of the variable offset + void Bubble::getBound(const ElInfo* elInfo, BoundaryType* bound) const + { + elInfo->testFlag(Mesh::FILL_BOUND); + + // boundaries + int index = 0; + int offset = 0; + BoundaryType boundaryType; + for (int i = dim - 1; i > 0; i--) //EDGES + offset += Global::getGeo(INDEX_OF_DIM(i, dim), dim); + + for (int i = 0; i < dim; i++) { + int jto = offset + Global::getGeo(INDEX_OF_DIM(i, dim), dim); + for (int j = offset; j < jto; j++) { + boundaryType = elInfo->getBoundary(j); + int kto = (*nDOF)[INDEX_OF_DIM(i, dim)]; + for (int k = 0; k < kto; k++) + bound[index++] = boundaryType; + } + offset -= Global::getGeo(INDEX_OF_DIM(i + 1, dim), dim); + } + + // interior nodes in the center + for (int i = 0; i < (*nDOF)[CENTER]; i++) + bound[index++] = INTERIOR; + + TEST_EXIT_DBG(index == nBasFcts)("found not enough boundarys. index=%d, nBasFcts=%d\n",index,nBasFcts); + } + + + // no = number of the basis fuctions where the interpolation coefficient is calculated + // b_no = pointer to the indices of the basis-functions + // f = function to be interpolated + // rvec = vector with the coefficient values + void Bubble::interpol(const ElInfo *elInfo, + int no, + const int *b_no, + AbstractFunction<double, WorldVector<double> > *f, + mtl::dense_vector<double> &rvec) const + { + FUNCNAME_DBG("Bubble::interpol()"); + + WorldVector<double> x; + + elInfo->testFlag(Mesh::FILL_COORDS); + + double sum = 0; + int BubbleIndex=-1; + + if (b_no) { + TEST_EXIT_DBG(no >= 0 && no < getNumber())("Something is wrong!\n"); + for (int i = 0; i < no; i++) { + if (b_no[i] < Global::getGeo(VERTEX, dim)) { + // interpolation in vertices: + rvec[i] = (*f)(elInfo->getCoord(b_no[i])); + sum += rvec[i]; + } else { + // interpolation at center: + elInfo->coordToWorld(*(*bary)[b_no[i]], x); + rvec[i] = (*f)(x); + BubbleIndex = i; + } + } + } + else { + int vertices = Global::getGeo(VERTEX, dim); + BubbleIndex = vertices; + for (int i = 0; i < vertices; i++) { + // interpolation in vertices: + rvec[i] = (*f)(elInfo->getCoord(i)); + sum += rvec[i]; + } + // interpolation at center: + elInfo->coordToWorld(*(*bary)[vertices], x); + rvec[vertices] = (*f)(x); + } + + // correction of the center-interpolation + if (BubbleIndex >= 0) + rvec[BubbleIndex] -= sum/(dim + 1.0); + } + + // no = number of the basis fuctions where the interpolation coefficient is calculated + // b_no = pointer to the indices of the basis-functions + // f = function to be interpolated + // rvec = vector with the coefficient values + void Bubble::interpol(const ElInfo *elInfo, + int no, + const int *b_no, + AbstractFunction<WorldVector<double>, WorldVector<double> > *f, + mtl::dense_vector<WorldVector<double> > &rvec) const //DONE + { + FUNCNAME_DBG("*Bubble::interpol()"); + + WorldVector<double> x; + + elInfo->testFlag(Mesh::FILL_COORDS); + + WorldVector<double> sum(DEFAULT_VALUE, 0.0); + int BubbleIndex=-1; + int vertices = Global::getGeo(VERTEX, dim); + + if (b_no) { + TEST_EXIT_DBG(no >= 0 && no < getNumber())("Something is wrong!\n"); + + for (int i = 0; i < no; i++) { + if (b_no[i] < Global::getGeo(VERTEX, dim)) { + // interpolation in vertices: + rvec[i] = (*f)(elInfo->getCoord(b_no[i])); + sum += rvec[i]; + } + else { + // interpolation at center: + elInfo->coordToWorld(*(*bary)[b_no[i]], x); + rvec[i] = (*f)(x); + BubbleIndex = i; + } + } + } + else { + BubbleIndex = vertices; + for (int i = 0; i < vertices; i++) { + // interpolation in vertices: + rvec[i] = (*f)(elInfo->getCoord(i)); + sum += rvec[i]; + } + // interpolation at center + elInfo->coordToWorld(*(*bary)[vertices], x); + rvec[vertices] = (*f)(x); + } + // correction of the center-interpolation + if (BubbleIndex >= 0) + rvec[BubbleIndex] -= sum/(dim + 1.0) ; + } + + // collects and order the DOFs per element + // at first the DOF at the vertices and then the DOF in the center + void Bubble::getLocalIndices(const Element *el, + const DOFAdmin *admin, + std::vector<DegreeOfFreedom>& dofs) const + { + if (static_cast<int>(dofs.size()) < nBasFcts) + dofs.resize(nBasFcts); + + const DegreeOfFreedom **dof = el->getDof(); + GeoIndex posIndex; + int n0, node0, j=0; + + // DOFs at vertices + posIndex = VERTEX; + n0 = admin->getNumberOfPreDofs(posIndex); + node0 = admin->getMesh()->getNode(posIndex); + int num = Global::getGeo(posIndex, dim); + for (int i = 0; i < num; node0++, i++) { + const int *indi = orderOfPositionIndices(el, posIndex, i); + dofs[j++] = dof[node0][n0 + indi[0]]; + } + + // DOFs at center + posIndex = CENTER; + n0 = admin->getNumberOfPreDofs(posIndex); + node0 = admin->getMesh()->getNode(posIndex); + const int *indi = orderOfPositionIndices(el, posIndex, 0); + dofs[j] = dof[node0][n0 + indi[0]]; + } + + + // returns a Vector filled with Pointer to the corresponding DOFs, + // sorted in following way: vertices, edges, faces, center + void Bubble::getLocalDofPtrVec(const Element *el, + const DOFAdmin *admin, + std::vector<const DegreeOfFreedom*>& dofs) const + { + if (static_cast<int>(dofs.size()) < nBasFcts) + dofs.resize(nBasFcts); + + const DegreeOfFreedom **dof = el->getDof(); + GeoIndex posIndex; + int n0, node0, j=0; + + // DOFs at vertices + posIndex = VERTEX; + n0 = admin->getNumberOfPreDofs(posIndex); + node0 = admin->getMesh()->getNode(posIndex); + int num = Global::getGeo(posIndex, dim); + for (int i = 0; i < num; node0++, i++) + { + const int *indi = orderOfPositionIndices(el, posIndex, i); + dofs[j++] = &(dof[node0][n0 + indi[0]]); + } + + // DOFs at center + posIndex = CENTER; + n0 = admin->getNumberOfPreDofs(posIndex); + node0 = admin->getMesh()->getNode(posIndex); + const int *indi = orderOfPositionIndices(el, posIndex, 0); + dofs[j] = &(dof[node0][n0 + indi[0]]); + } + + + void Bubble::l2ScpFctBas(Quadrature *q, + AbstractFunction<WorldVector<double>, WorldVector<double> >* f, + DOFVector<WorldVector<double> >* fh) + { + ERROR_EXIT("not yet\n"); + } + + + // calculates the L2-scalarproduct of given function f with all basis-functions by quadrature + void Bubble::l2ScpFctBas(Quadrature *quad, + AbstractFunction<double, WorldVector<double> >* f, + DOFVector<double>* fh) + { + FUNCNAME_DBG("Bubble::l2ScpFctBas()"); + + TEST_EXIT_DBG(fh)("no DOF_REAL_VEC fh\n"); + TEST_EXIT_DBG(fh->getFeSpace()) + ("no fe_space in DOF_REAL_VEC %s\n", fh->getName().c_str()); + TEST_EXIT_DBG(fh->getFeSpace()->getBasisFcts() == this) + ("wrong basis fcts for fh\n"); + TEST_EXIT_DBG(!fh->getFeSpace()->getMesh()->getParametric()) + ("Not yet implemented!"); + + if (!quad) + quad = Quadrature::provideQuadrature(dim, 2 * degree - 2); + + const FastQuadrature *quad_fast = FastQuadrature::provideFastQuadrature(this, *quad, INIT_PHI); + vector<double> wdetf_qp(quad->getNumPoints()); + int nPoints = quad->getNumPoints(); + DOFAdmin *admin = fh->getFeSpace()->getAdmin(); + WorldVector<double> x; + vector<DegreeOfFreedom> dof; + + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(fh->getFeSpace()->getMesh(), -1, + Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS); + while (elInfo) { + getLocalIndices(elInfo->getElement(), admin, dof); + double det = elInfo->getDet(); + + for (int iq = 0; iq < nPoints; iq++) { + elInfo->coordToWorld(quad->getLambda(iq), x); + wdetf_qp[iq] = quad->getWeight(iq) * det * ((*f)(x)); + } + + for (int j = 0; j < nBasFcts; j++) { + double val = 0.0; + for (int iq = 0; iq < nPoints; iq++) + val += quad_fast->getPhi(iq, j) * wdetf_qp[iq]; + + (*fh)[dof[j]] += val; + } + + elInfo = stack.traverseNext(elInfo); + } + } + + void Bubble::refineInter2_1d(DOFIndexed<double> *drv, + RCNeighbourList* list, + int n, + BasisFunction* basFct) + { + if (n < 1) + return; + + Element *el = list->getElement(0); + const DOFAdmin *admin = drv->getFeSpace()->getAdmin(); + vector<DegreeOfFreedom> pdof; + basFct->getLocalIndices(el, admin, pdof); + + int node = drv->getFeSpace()->getMesh()->getNode(VERTEX); + int n0 = admin->getNumberOfPreDofs(VERTEX); + + // vertex-dof 1 of child[0] + DegreeOfFreedom cdof1 = el->getChild(0)->getDof(node + 1, n0); + (*drv)[cdof1] = 0.5*((*drv)[pdof[0]]+(*drv)[pdof[1]]) + (*drv)[pdof[2]]; + + // vertex-dof 0 of child[1] + DegreeOfFreedom cdof0 = el->getChild(1)->getDof(node, n0); + (*drv)[cdof0] = 0.5*((*drv)[pdof[0]]+(*drv)[pdof[1]]) + (*drv)[pdof[2]]; + + node = drv->getFeSpace()->getMesh()->getNode(CENTER); + n0 = admin->getNumberOfPreDofs(CENTER); + + // barycenter of child[0] + DegreeOfFreedom cdof2 = el->getChild(0)->getDof(node, n0); + (*drv)[cdof2] = 0.25*(*drv)[pdof[2]]; + + // barycenter of child[1] + cdof2 = el->getChild(1)->getDof(node, n0); + (*drv)[cdof2] = 0.25*(*drv)[pdof[2]]; + } + + // drv = global DOF-values + // list = informations about element and the neighbours + // n = number of neighbours + void Bubble::refineInter3_2d(DOFIndexed<double> *drv, + RCNeighbourList* list, + int n, BasisFunction* basFct) + { + if (n < 1) + return; + + const DOFAdmin *admin = drv->getFeSpace()->getAdmin(); + Element *el = list->getElement(0); + vector<DegreeOfFreedom> pdof; + basFct->getLocalIndices(el, admin, pdof); + + int node = drv->getFeSpace()->getMesh()->getNode(VERTEX); + int n0 = admin->getNumberOfPreDofs(VERTEX); + + // newest vertex of child[0] and child[1], newest vertex is node+2 + DegreeOfFreedom cdof2 = el->getChild(0)->getDof(node + 2, n0); + (*drv)[cdof2] = 0.5*((*drv)[pdof[0]]+(*drv)[pdof[1]]); + + node = drv->getFeSpace()->getMesh()->getNode(CENTER); + n0 = admin->getNumberOfPreDofs(CENTER); + + // barycenter of child[0] + DegreeOfFreedom cdof3 = el->getChild(0)->getDof(node, n0); + (*drv)[cdof3] = 0.75*(*drv)[pdof[3]]; + + // barycenter of child[1] + cdof3 = el->getChild(1)->getDof(node, n0); + (*drv)[cdof3] = 0.75*(*drv)[pdof[3]]; + + if (n > 1) { + // adjust the values at the barycenters of the neighbour's children + el = list->getElement(1); + basFct->getLocalIndices(el, admin, pdof); + + // barycenter of child[0] + cdof3 = el->getChild(0)->getDof(node, n0); + (*drv)[cdof3] = 0.75*(*drv)[pdof[3]]; + + // barycenter of child[1] + cdof3 = el->getChild(1)->getDof(node, n0); + (*drv)[cdof3] = 0.75*(*drv)[pdof[3]]; + + } + } + + void Bubble::refineInter4_3d(DOFIndexed<double> *drv, + RCNeighbourList* list, + int n, + BasisFunction* basFct) + { + if (n < 1) + return; + + Element *el = list->getElement(0); + const DOFAdmin *admin = drv->getFeSpace()->getAdmin(); + vector<DegreeOfFreedom> pdof; + basFct->getLocalIndices(el, admin, pdof); + + int node = drv->getFeSpace()->getMesh()->getNode(VERTEX); + int n0 = admin->getNumberOfPreDofs(VERTEX); + + // newest vertex of child[0] and child[1], newest vertex is node+3 + DegreeOfFreedom cdof3 = el->getChild(0)->getDof(node + 3, n0); + (*drv)[cdof3] = 0.5*((*drv)[pdof[0]]+(*drv)[pdof[1]]); + + node = drv->getFeSpace()->getMesh()->getNode(CENTER); + n0 = admin->getNumberOfPreDofs(CENTER); + + // barycenter of child[0] + DegreeOfFreedom cdof4 = el->getChild(0)->getDof(node, n0); + (*drv)[cdof4] = 0.75*(*drv)[pdof[4]]; + + // barycenter of child[1] + cdof4 = el->getChild(1)->getDof(node, n0); + (*drv)[cdof4] = 0.75*(*drv)[pdof[4]]; + + for (int i = 1; i < n; i++) { + el = list->getElement(i); + TEST_EXIT_DBG(el)("Should not happen!\n"); + + basFct->getLocalIndices(el, admin, pdof); + + // barycenter of child[0] + cdof4 = el->getChild(0)->getDof(node, n0); + (*drv)[cdof4] = 0.75*(*drv)[pdof[4]]; + + // barycenter of child[1] + cdof4 = el->getChild(1)->getDof(node, n0); + (*drv)[cdof4] = 0.75*(*drv)[pdof[4]]; + } + } + + void Bubble::coarseRestr2_1d(DOFIndexed<double> *drv, + RCNeighbourList *list, + int n, BasisFunction* basFct) + { + FUNCNAME("Bubble::coarseRestr2_1d()"); + + TEST_EXIT(drv->getFeSpace())("No fe_space in dof_real_vec!\n"); + TEST_EXIT(drv->getFeSpace()->getBasisFcts())("No basis functions in fe_space!\n"); + + ERROR_EXIT("not yet implemented!\n"); + if (n < 1) + return; +#if 0 + const Element *el = list->getElement(0); + const DOFAdmin *admin = drv->getFeSpace()->getAdmin(); +#endif + // ... // + } + + // drv = global DOF-values + // list = informations about element and the neighbours + // n = number of neighbours + // Calculation of the values can be traced in the documentation + // TODO: maybe the implementation is wrong! + void Bubble::coarseRestr3_2d(DOFIndexed<double> *drv, + RCNeighbourList *list, + int n, BasisFunction* basFct) + { + FUNCNAME("Bubble::coarseRestr3_2d()"); + + TEST_EXIT(drv->getFeSpace())("No fe_space in dof_real_vec!\n"); + TEST_EXIT(drv->getFeSpace()->getBasisFcts())("No basis functions in fe_space!\n"); + + if (n < 1) + return; + + const Element *el = list->getElement(0); + const DOFAdmin *admin = drv->getFeSpace()->getAdmin(); + vector<DegreeOfFreedom> pdof(4), cdof0(4), cdof1(4); + vector<double> cdof(9); + basFct->getLocalIndices(el, admin, pdof); + basFct->getLocalIndices(el->getChild(0), admin, cdof0); + basFct->getLocalIndices(el->getChild(1), admin, cdof1); + + // Create a Vektor with the values of all Child-DOFs + cdof[0] = (*drv)[cdof0[0]]; + cdof[1] = (*drv)[cdof0[1]]; + cdof[2] = (*drv)[cdof0[2]]; + cdof[3] = (*drv)[cdof0[3]]; + cdof[4] = (*drv)[cdof1[0]]; + cdof[5] = (*drv)[cdof1[3]]; + + if (n==1){ + //no neighbours: + + // Calculate Parent DOF values via inv(A)*B + (*drv)[pdof[0]] = 61.0/72.0*cdof[1] + 11.0/36.0*cdof[2] + + 87.0/160.0*cdof[3] - 11.0/72.0*cdof[4] + - 57.0/160.0*cdof[5]; + (*drv)[pdof[1]] = -11.0/72.0*cdof[1] + 11.0/36.0*cdof[2] + - 57.0/160.0*cdof[3] + 61.0/72.0*cdof[4] + + 87.0/160.0*cdof[5]; + (*drv)[pdof[2]] = cdof[0] + 7.0/72.0*cdof[1] - 7.0/36.0*cdof[2] + + 3.0/32.0*cdof[3] + 7.0/72.0*cdof[4] + + 3.0/32.0*cdof[5]; + (*drv)[pdof[3]] = -35.0/162.0*cdof[1] + 35.0/81.0*cdof[2] + + 7.0/24.0*cdof[3] - 35.0/162.0*cdof[4] + + 7.0/24.0*cdof[5]; + + } + else { + vector<DegreeOfFreedom> pdof1(4); + // there is a neighbour: + el = list->getElement(1); + basFct->getLocalIndices(el, admin, pdof1); + basFct->getLocalIndices(el->getChild(0), admin, cdof0); + basFct->getLocalIndices(el->getChild(1), admin, cdof1); + + // Create a Vektor with the values of all Child-DOFs + // cdof[0], cdof[1] and cdof[4] are the values before coarsening of the first element + cdof[6] = (*drv)[cdof0[0]]; + cdof[7] = (*drv)[cdof0[3]]; + cdof[8] = (*drv)[cdof1[3]]; + + // Calculate Parent DOF values via modified inv(A)*B + (*drv)[pdof[0]] = 61.0/72.0 * cdof[1] + 11.0/36.0 * cdof[2] + + 87.0/320.0 * cdof[3] -11.0/72.0 * cdof[4] -57.0/320.0 * cdof[5] + - 57.0/320.0 * cdof[7] + 87.0/320.0 * cdof[8]; + (*drv)[pdof[1]] = -11.0/72.0 * cdof[1] + 11.0/36.0 * cdof[2] + - 57.0/320.0 * cdof[3] + 61.0/72.0 * cdof[4] + 87.0/320.0 * cdof[5] + + 87.0/320.0 * cdof[7] - 57.0/320.0 * cdof[8]; + (*drv)[pdof[2]] = cdof[0] + 7.0/72.0 * cdof[1] - 7.0/36.0 * cdof[2] + + 51.0/512.0 * cdof[3] + 7.0/72.0 * cdof[4] + 51.0/512.0 * cdof[5] + - 3.0/512.0 * cdof[7] - 3.0/512.0 * cdof[8]; + (*drv)[pdof[3]] = -35.0/162.0 * cdof[1] + 35.0/81.0 * cdof[2] + + 259.0/768.0 * cdof[3] - 35.0/162.0 * cdof[4] + 259.0/768.0 * cdof[5] + - 35.0/768.0 * cdof[7] - 35.0/768.0 * cdof[8]; + (*drv)[pdof1[2]] = 7.0/72.0 * cdof[1] - 7.0/36.0 * cdof[2] + - 3.0/512.0 * cdof[3] + 7.0/72.0 * cdof[4] - 3.0/512.0 * cdof[5] + + cdof[6] + 51.0/512.0 * cdof[7] + 51.0/512.0 * cdof[8]; + (*drv)[pdof1[3]] = -35.0/162.0 * cdof[1] + 35.0/81.0* cdof[2] + - 35.0/768.0 * cdof[3] - 35.0/162.0 * cdof[4] - 35.0/768.0 * cdof[5] + + 259.0/768.0 * cdof[7] + 259.0/768.0 * cdof[8]; + } + } + + void Bubble::coarseRestr4_3d(DOFIndexed<double> *drv, + RCNeighbourList *list, + int n, BasisFunction* basFct) + { + FUNCNAME("Bubble::coarseRestr4_3d()"); + + TEST_EXIT(drv->getFeSpace())("No fe_space in dof_real_vec!\n"); + TEST_EXIT(drv->getFeSpace()->getBasisFcts())("No basis functions in fe_space!\n"); + + ERROR_EXIT("not yet implemented!\n"); + if (n < 1) + return; +#if 0 + const Element *el = list->getElement(0); + const DOFAdmin *admin = drv->getFeSpace()->getAdmin(); +#endif + // ... // + } + + void Bubble::coarseInter2_1d(DOFIndexed<double> *drv, + RCNeighbourList* list, + int n, BasisFunction* basFct) + { + FUNCNAME("Bubble::coarseInter2_1d()"); + + TEST_EXIT(drv->getFeSpace())("No fe_space in dof_real_vec!\n"); + TEST_EXIT(drv->getFeSpace()->getBasisFcts())("No basis functions in fe_space!\n"); + + if (n < 1) + return; + + Element *el = list->getElement(0); + const DOFAdmin *admin = drv->getFeSpace()->getAdmin(); + + int node = drv->getFeSpace()->getMesh()->getNode(VERTEX); + int n0 = admin->getNumberOfPreDofs(VERTEX); + + DegreeOfFreedom cdof0_0 = el->getChild(0)->getDof(node, n0); + DegreeOfFreedom cdof1_0 = el->getChild(0)->getDof(node + 1, n0); + DegreeOfFreedom cdof1_1 = el->getChild(1)->getDof(node + 1, n0); + vector<DegreeOfFreedom> pdof; + basFct->getLocalIndices(el, admin, pdof); + + (*drv)[pdof[2]] = (*drv)[cdof1_0] - 1.0/2.0*((*drv)[cdof0_0]+(*drv)[cdof1_1]); + } + + // drv = global DOF-values + // list = informations about element and the neighbours + // n = number of neighbours + void Bubble::coarseInter3_2d(DOFIndexed<double> *drv, + RCNeighbourList* list, + int n, BasisFunction* basFct) + { + FUNCNAME("Bubble::coarseInter3_2d()"); + + TEST_EXIT(drv->getFeSpace())("No fe_space in dof_real_vec!\n"); + TEST_EXIT(drv->getFeSpace()->getBasisFcts())("No basis functions in fe_space!\n"); + + if (n < 1) + return; + + Element *el = list->getElement(0); + const DOFAdmin *admin = drv->getFeSpace()->getAdmin(); + + int node = drv->getFeSpace()->getMesh()->getNode(VERTEX); + int n0 = admin->getNumberOfPreDofs(VERTEX); + + DegreeOfFreedom cdof2 = el->getChild(0)->getDof(node + 2, n0); + DegreeOfFreedom cdof1 = el->getChild(0)->getDof(node + 1, n0); + DegreeOfFreedom cdof0 = el->getChild(1)->getDof(node, n0); + vector<DegreeOfFreedom> pdof; + basFct->getLocalIndices(el, admin, pdof); + + (*drv)[pdof[3]] = 2.0/3.0*(*drv)[cdof2] - 1.0/3.0*((*drv)[cdof1]+(*drv)[cdof0]); + + if (n > 1) { + Element *el = list->getElement(1); + cdof2 = el->getChild(0)->getDof(node + 2, n0); + cdof1 = el->getChild(0)->getDof(node + 1, n0); + cdof0 = el->getChild(1)->getDof(node, n0); + basFct->getLocalIndices(el, admin, pdof); + (*drv)[pdof[3]] = 2.0/3.0*(*drv)[cdof2] - 1.0/3.0*((*drv)[cdof1]+(*drv)[cdof0]); + } + } + + void Bubble::coarseInter4_3d(DOFIndexed<double> *drv, + RCNeighbourList* list, + int n, BasisFunction* basFct) + { + FUNCNAME("Bubble::coarseInter4_3d()"); + + TEST_EXIT(drv->getFeSpace())("No fe_space in dof_real_vec!\n"); + TEST_EXIT(drv->getFeSpace()->getBasisFcts())("No basis functions in fe_space!\n"); + + if (n < 1) + return; + + Element *el = list->getElement(0); + const DOFAdmin *admin = drv->getFeSpace()->getAdmin(); + + int node = drv->getFeSpace()->getMesh()->getNode(VERTEX); + int n0 = admin->getNumberOfPreDofs(VERTEX); + + DegreeOfFreedom cdof3_0 = el->getChild(0)->getDof(node + 3, n0); + DegreeOfFreedom cdof0_0 = el->getChild(0)->getDof(node, n0); + DegreeOfFreedom cdof0_1 = el->getChild(1)->getDof(node, n0); + vector<DegreeOfFreedom> pdof; + basFct->getLocalIndices(el, admin, pdof); + + (*drv)[pdof[4]] = 0.5*(*drv)[cdof3_0] - 0.25*((*drv)[cdof0_0]+(*drv)[cdof0_1]); + + for (int i = 1; i < n; i++) { + Element *el = list->getElement(i); + basFct->getLocalIndices(el, admin, pdof); + + cdof3_0 = el->getChild(0)->getDof(node + 3, n0); + cdof0_0 = el->getChild(0)->getDof(node, n0); + cdof0_1 = el->getChild(1)->getDof(node, n0); + (*drv)[pdof[4]] = 0.5*(*drv)[cdof3_0] - 0.25*((*drv)[cdof0_0]+(*drv)[cdof0_1]); + } + } +} diff --git a/AMDiS/src/Bubble.h b/AMDiS/src/Bubble.h new file mode 100644 index 0000000000000000000000000000000000000000..d00d81576d1fb0df23d0463e48683cc612c6f3f1 --- /dev/null +++ b/AMDiS/src/Bubble.h @@ -0,0 +1,427 @@ +/****************************************************************************** + * + * AMDiS - Adaptive multidimensional simulations + * + * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. + * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis + * + * Authors: + * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * + * This file is part of AMDiS + * + * See also license.opensource.txt in the distribution. + * + ******************************************************************************/ + +// Created by Roman Weissflog & Philipp Schulz + + + +/** \file Bubble.h */ + +#ifndef AMDIS_BUBBLE_H +#define AMDIS_BUBBLE_H + +#include <list> +#include <boost/numeric/mtl/mtl.hpp> +#include "AbstractFunction.h" +#include "BasisFunction.h" +#include "FixVec.h" + +namespace AMDiS { + + /** \ingroup FEMSpace + * \brief + * Lagrange basis functions plus Bubble function. Sub class of BasisFunction + */ + + class Bubble : public BasisFunction + { + public: + /// Creator class used in the BasisFunctionCreatorMap. + class Creator : public BasisFunctionCreator + { + public: + virtual ~Creator() {} + + /// Returns a new Lagrange object. + BasisFunction* create() + { + return getBubble(this->dim, this->dim + 1); // has to be generalized in later versions of bubble functions + } + }; + + protected: + /// Constructs lagrange/bubble basis functions with the given dim and degree. + /// Constructor is protected to avoid multiple instantiation of identical + /// basis functions. Use \ref getBubble instead. + Bubble(int dim_, int degree_); + + /** \brief + * destructor + */ + virtual ~Bubble(); + + public: + /// Returns a pointer to lagrange and bubble basis functions with the given dim and + /// degree. Multiple instantiation of identical basis functions is avoided + /// by rembering once created basis functions in \ref allBasFcts. + static Bubble* getBubble(int dim, int degree); + + /// Implements BasisFunction::interpol + void interpol(const ElInfo *, int, const int *, + AbstractFunction<double, WorldVector<double> >*, + mtl::dense_vector<double>&) const override; + + /// Implements BasisFunction::interpol + void interpol(const ElInfo *, int, + const int *b_no, + AbstractFunction<WorldVector<double>, WorldVector<double> >*, + mtl::dense_vector<WorldVector<double> >&) const override; + + /// Returns the barycentric coordinates of the i-th basis function. + DimVec<double> *getCoords(int i) const override; + + + /// Implements BasisFunction::getBound + void getBound(const ElInfo*, BoundaryType *) const override; + + + /** \brief + * Calculates the local vertex indices which are involved in evaluating + * the nodeIndex-th DOF at the positionIndex-th part of type position + * (VERTEX/EDGE/FACE/CENTER). nodeIndex determines the permutation + * of the involved vertices. So in 1d for lagrange4 there are two DOFs at + * the CENTER (which is an edge in this case). Then vertices[0] = {0, 1} and + * vertices[1] = {1, 0}. This allows to use the same local basis function + * for all DOFs at the same position. + */ + static void setVertices(int dim, int degree, + GeoIndex position, int positionIndex, int nodeIndex, + int** vertices); + + + /// Implements BasisFunction::refineInter + inline void refineInter(DOFIndexed<double> *drv, RCNeighbourList* list, int n) override + { + if (refineInter_fct) + (*refineInter_fct)(drv, list, n, this); + } + + /// Implements BasisFunction::coarseRestrict + inline void coarseRestr(DOFIndexed<double> *drv, RCNeighbourList* list, int n) override + { + if (coarseRestr_fct) + (*coarseRestr_fct)(drv, list, n, this); + } + + /// Implements BasisFunction::coarseInter + inline void coarseInter(DOFIndexed<double> *drv, RCNeighbourList* list, int n) override + { + if (coarseInter_fct) + (*coarseInter_fct)(drv, list, n, this); + } + + /// Implements BasisFunction::getLocalIndices(). + void getLocalIndices(const Element *el, + const DOFAdmin *admin, + std::vector<DegreeOfFreedom> &dofs) const override; + + /// Implements BasisFunction::getLocalDofPtrVec() + /// Returns an vector filled with all DOFs per position + void getLocalDofPtrVec(const Element *el, + const DOFAdmin *admin, + std::vector<const DegreeOfFreedom*>& vec) const override; + + /// Implements BasisFunction::l2ScpFctBas + void l2ScpFctBas(Quadrature* q, + AbstractFunction<double, WorldVector<double> >* f, + DOFVector<double>* fh) override; + + /// Implements BasisFunction::l2ScpFctBas + void l2ScpFctBas(Quadrature* q, + AbstractFunction<WorldVector<double>, WorldVector<double> >* f, + DOFVector<WorldVector<double> >* fh) override; + + static void clear(); + + /// Implements BasisFunction::isnodal + bool isNodal() const override + { + return false; + } + + + + protected: + /// sets the barycentric coordinates (stored in \ref bary) of the local + /// basis functions. + void setBary(); + + /// Implements BasisFunction::setNDOF + void setNDOF() override; + + /// Sets used function pointers + void setFunctionPointer(); + + /// Used by \ref getVec + int* orderOfPositionIndices(const Element* el, + GeoIndex position, + int positionIndex) const override; + + private: + /// barycentric coordinates of the locations of all basis functions + std::vector<DimVec<double>* > *bary; + + /** \name static dim-degree-arrays + * \{ + */ + static std::vector<DimVec<double>* > baryDimDegree; + static DimVec<int>* ndofDimDegree; + static int nBasFctsDimDegree; + static std::vector<BasFctType*> phifunc; + static std::vector<GrdBasFctType*> grdPhifunc; + static std::vector<D2BasFctType*> D2Phifunc; + /** \} */ + + /// List of all used BasisFunctions in the whole program. Avoids duplicate + /// instantiation of identical BasisFunctions. + static Bubble* Singleton; + + + protected: + /// Pointer to the used refineInter function + void (*refineInter_fct)(DOFIndexed<double> *, RCNeighbourList*, int, BasisFunction*); + + static void refineInter2_1d(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + static void refineInter3_2d(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + static void refineInter4_3d(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + + /// Pointer to the used coarseRestr function + void (*coarseRestr_fct)(DOFIndexed<double> *, RCNeighbourList*, int, BasisFunction*); + + static void coarseRestr2_1d(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + static void coarseRestr3_2d(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + static void coarseRestr4_3d(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + + /// Pointer to the used coarseInter function + void (*coarseInter_fct)(DOFIndexed<double> *, RCNeighbourList*, int, BasisFunction*); + + static void coarseInter2_1d(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + static void coarseInter3_2d(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + static void coarseInter4_3d(DOFIndexed<double> *, RCNeighbourList*, int, + BasisFunction*); + + + /// AbstractFunction which implements lagrange/bubble basis functions + class Phi : public BasFctType + { + public: + /// Constructs the local lagrange/bubble basis function for the given position, + /// positionIndex and nodeIndex. owner_ is a pointer to the Bubble + /// object this basis function belongs to. + Phi(Bubble* owner, GeoIndex position, int positionIndex, int nodeIndex); + + /// Destructor + virtual ~Phi(); + + private: + /// vertices needed for evaluation of this function + int* vertices; + + /// Pointer to the evaluating function + double (*func)(const DimVec<double>& lambda, int* vert); + + /// Returns \ref func(lambda, vertices) + inline double operator()(const DimVec<double>& lambda) const override + { + return func(lambda, vertices); + } + + // ====== Lagrange, degree = 1 ===================================== + // vertex + inline static double phi1v(const DimVec<double>& lambda, int* vertices) + { + return lambda[vertices[0]]; + } + + // ====== Bubble =================================================== + // 1d + inline static double phi2c(const DimVec<double>& lambda, int* vertices) + { + return (4.0 * lambda[vertices[0]] * lambda[vertices[1]]); + } + + // 2d + inline static double phi3c(const DimVec<double>& lambda, int* vertices) + { + return 27.0 * lambda[vertices[0]] * lambda[vertices[1]] * lambda[vertices[2]]; + } + + // 3d + inline static double phi4c(const DimVec<double>& lambda, int* vertices) + { + return 256.0 * lambda[vertices[0]] * lambda[vertices[1]] * + lambda[vertices[2]] * lambda[vertices[3]]; + } + }; + + + /// AbstractFunction which implements gradients of Lagrange/Bubble basis functions. + /// See \ref Phi + class GrdPhi : public GrdBasFctType + { + public: + GrdPhi(Bubble* owner, GeoIndex position, int positionIndex, int nodeIndex); + + virtual ~GrdPhi(); + private: + int* vertices; + + void (*func)(const DimVec<double>& lambda, + int* vertices_, + mtl::dense_vector<double>& result); + + inline void operator()(const DimVec<double>& lambda, + mtl::dense_vector<double>& result) const override + { + func(lambda, vertices, result); + } + + // ====== Lagrange1 ================================================ + // vertex + inline static void grdPhi1v(const DimVec<double>&, + int* vertices, + mtl::dense_vector<double>& result) + { + result = 0.0; + result[vertices[0]] = 1.0; + } + + // ======= Bubble ================================================== + inline static void grdPhi2c(const DimVec<double>& lambda, + int* vertices, + mtl::dense_vector<double>& result) + { + result = 0.0; + result[vertices[0]] = 4.0 * lambda[vertices[1]]; + result[vertices[1]] = 4.0 * lambda[vertices[0]]; + } + + + inline static void grdPhi3c(const DimVec<double>& lambda, + int* vertices, + mtl::dense_vector<double>& result) + { + result = 0.0; + result[vertices[0]] = 27.0 * lambda[vertices[1]] * lambda[vertices[2]]; + result[vertices[1]] = 27.0 * lambda[vertices[0]] * lambda[vertices[2]]; + result[vertices[2]] = 27.0 * lambda[vertices[0]] * lambda[vertices[1]]; + } + + inline static void grdPhi4c(const DimVec<double>& lambda, + int* vertices, + mtl::dense_vector<double>& result) + { + result = 0.0; + result[0] = + 256.0 * lambda[vertices[1]] * lambda[vertices[2]] * lambda[vertices[3]]; + result[1] = + 256.0 * lambda[vertices[0]] * lambda[vertices[2]] * lambda[vertices[3]]; + result[2] = + 256.0 * lambda[vertices[0]] * lambda[vertices[1]] * lambda[vertices[3]]; + result[3] = + 256.0 * lambda[vertices[0]] * lambda[vertices[1]] * lambda[vertices[2]]; + } + }; + + + /// AbstractFunction which implements second derivatives of Lagrange/Bubble basis + /// functions. See \ref Phi + class D2Phi : public D2BasFctType + { + public: + D2Phi(Bubble* owner, GeoIndex position, int positionIndex, int nodeIndex); + + virtual ~D2Phi(); + + private: + int* vertices; + + void (*func)(const DimVec<double>& lambda, int* vertices_, DimMat<double>& result); + + inline void operator()(const DimVec<double>& lambda, DimMat<double>& result) const override + { + return func(lambda, vertices, result); + } + + // ===== Lagrange1 ================================================ + // vertex + inline static void D2Phi1v(const DimVec<double>&, int*, DimMat<double>& result) + { + result.set(0.0); + } + + + // ===== Bubble =================================================== + inline static void D2Phi2c(const DimVec<double>&, int* vertices, + DimMat<double>& result) + { + result.set(0.0); + result[vertices[0]][vertices[1]] = 4.0; + result[vertices[1]][vertices[0]] = 4.0; + } + + inline static void D2Phi3c(const DimVec<double>& lambda, int* vertices, + DimMat<double>& result) + { + result.set(0.0); + result[vertices[0]][vertices[1]] = + result[vertices[1]][vertices[0]] = 27.0 * lambda[vertices[2]]; + result[vertices[0]][vertices[2]] = + result[vertices[2]][vertices[0]] = 27.0 * lambda[vertices[1]]; + result[vertices[1]][vertices[2]] = + result[vertices[2]][vertices[1]] = 27.0 * lambda[vertices[0]]; + } + + inline static void D2Phi4c(const DimVec<double>& lambda, int* vertices, + DimMat<double>& result) + { + result.set(0.0); + result[vertices[0]][vertices[1]] = + result[vertices[1]][vertices[0]] = + 256.0 * lambda[vertices[2]] * lambda[vertices[3]]; + result[vertices[0]][vertices[2]] = + result[vertices[2]][vertices[0]] = + 256.0 * lambda[vertices[1]] * lambda[vertices[3]]; + result[vertices[0]][vertices[3]] = + result[vertices[3]][vertices[0]] = + 256.0 * lambda[vertices[1]] * lambda[vertices[2]]; + result[vertices[1]][vertices[2]] = + result[vertices[2]][vertices[1]] = + 256.0 * lambda[vertices[0]] * lambda[vertices[3]]; + result[vertices[1]][vertices[3]] = + result[vertices[3]][vertices[1]] = + 256.0 * lambda[vertices[0]] * lambda[vertices[2]]; + result[vertices[2]][vertices[3]] = + result[vertices[3]][vertices[2]] = + 256.0 * lambda[vertices[0]] * lambda[vertices[1]]; + } + }; + }; +} + +#endif // AMDIS_Bubble_H diff --git a/AMDiS/src/Cholesky.cc b/AMDiS/src/Cholesky.cc index 72d39aa4a144332f19b3a45cfc526f2525a344cf..9410005fcba47fbd90b20eafd06c1da3d407848e 100644 --- a/AMDiS/src/Cholesky.cc +++ b/AMDiS/src/Cholesky.cc @@ -21,6 +21,11 @@ #include "Cholesky.h" +namespace AMDiS { + +using namespace std; +using namespace AMDiS; + bool Cholesky::factorization(Matrix<double> *A, Vector<double> *p) { FUNCNAME("Cholesky::factorization()"); @@ -183,3 +188,5 @@ bool Cholesky::solve(Matrix<double> *A, Vector<WorldVector<double> > *b, return success; } + +} diff --git a/AMDiS/src/Cholesky.h b/AMDiS/src/Cholesky.h index 374a0284255acc3b9b3f6af21b37934620b58f9d..85650fccaa65f8b79da7b9f4d6b2fc58d4e1ff4e 100644 --- a/AMDiS/src/Cholesky.h +++ b/AMDiS/src/Cholesky.h @@ -27,6 +27,8 @@ #include "FixVec.h" +namespace AMDiS { + using namespace std; using namespace AMDiS; @@ -63,4 +65,6 @@ class Cholesky Vector<double> *p = nullptr); }; +} + #endif diff --git a/AMDiS/src/ComponentTraverseInfo.cc b/AMDiS/src/ComponentTraverseInfo.cc index b77d7ab175bcb4f46cabe809cbd7d9dcdb1349ef..e8c384c77ef4a98f337e68d3b81216d26da08e3f 100644 --- a/AMDiS/src/ComponentTraverseInfo.cc +++ b/AMDiS/src/ComponentTraverseInfo.cc @@ -94,9 +94,9 @@ namespace AMDiS { TEST_EXIT_DBG(rowFeSpace != nullptr)("No row FE space!\n"); for (int i = 0; i < nComponents; i++) { - if (matrixComponents[row][i].getColFeSpace() != rowFeSpace) + if (matrixComponents[row][i].getColFeSpace() && matrixComponents[row][i].getColFeSpace() != rowFeSpace) return matrixComponents[row][i].getColFeSpace(); - if (matrixComponents[row][i].getAuxFeSpace() != rowFeSpace) + if (matrixComponents[row][i].getAuxFeSpace() && matrixComponents[row][i].getAuxFeSpace() != rowFeSpace) return matrixComponents[row][i].getAuxFeSpace(); } diff --git a/AMDiS/src/CreatorMap.cc b/AMDiS/src/CreatorMap.cc index 4b5d50d2f81572b5d096911ebaafbf4be13ae35c..36c001a8c01c40d1a375f2830be0ff5748df194f 100644 --- a/AMDiS/src/CreatorMap.cc +++ b/AMDiS/src/CreatorMap.cc @@ -19,6 +19,8 @@ ******************************************************************************/ +#include "BasisFunction.h" +#include "Bubble.h" #include "CreatorMap.h" #include "MTL4Types.h" #include "solver/LinearSolver.h" @@ -28,6 +30,7 @@ #include "solver/KrylovPreconditioner.h" #include "MatrixVector.h" #include "SystemVector.h" +#include "Lagrange.h" #include "LeafData.h" #include "SurfaceRegion_ED.h" #include "ElementRegion_ED.h" @@ -172,6 +175,25 @@ namespace AMDiS { } + template<> + void CreatorMap<BasisFunction>::addDefaultCreators() + { + BasisFunctionCreator *creator; + + // Lagrange-functions up to order 4 + for (int i = 1; i <= MAX_DEGREE; i++) { + creator = new Lagrange::Creator(i); + addCreator("P" + boost::lexical_cast<std::string>(i), creator); + addCreator("Lagrange" + boost::lexical_cast<std::string>(i), creator); + addCreator("CG" + boost::lexical_cast<std::string>(i), creator); + } + + // linear Lagrange functions plus element bubble function + creator = new Bubble::Creator; + addCreator("P1+bubble", creator); + } + + template<> void CreatorMap<ElementData>::addDefaultCreators() { diff --git a/AMDiS/src/DOFAdmin.h b/AMDiS/src/DOFAdmin.h index 6260940a8235d32f211fc97e6b9ca6441af04080..c8a1d5648150321cd66d62f8450d8161f0f334f3 100644 --- a/AMDiS/src/DOFAdmin.h +++ b/AMDiS/src/DOFAdmin.h @@ -251,6 +251,11 @@ namespace AMDiS { } int calcMemoryUsage(); + + void reset() + { + init(); + } /** \} */ diff --git a/AMDiS/src/DOFIndexed.h b/AMDiS/src/DOFIndexed.h index a3b89a9c8e0aa454b0c698c3911df5052ecfa4de..0aa663526bc1febf61a21e0ed1782a2cd3dfe0d8 100644 --- a/AMDiS/src/DOFIndexed.h +++ b/AMDiS/src/DOFIndexed.h @@ -91,6 +91,8 @@ namespace AMDiS { typedef DegreeOfFreedom size_type; typedef value_type& reference; typedef value_type const& const_reference; + typedef value_type* pointer; + typedef value_type const* const_pointer; typedef typename std::vector<value_type>::iterator iterator; typedef typename std::vector<value_type>::const_iterator const_iterator; @@ -116,6 +118,42 @@ namespace AMDiS { /// Returns container element at index i virtual const_reference operator[](size_type i) const = 0; }; + + template<> + class DOFIndexed<bool> : public DOFIndexedBase + { + public: // typedefs + typedef bool value_type; + typedef DegreeOfFreedom size_type; + typedef std::vector<bool>::reference reference; + typedef std::vector<bool>::const_reference const_reference; + typedef std::vector<bool>::pointer pointer; + typedef std::vector<bool>::const_pointer const_pointer; + + typedef std::vector<bool>::iterator iterator; + typedef std::vector<bool>::const_iterator const_iterator; + + public: + virtual ~DOFIndexed() {} + + /// Returns iterator to the begin of container + virtual iterator begin() = 0; + + /// Returns iterator to the end of container + virtual iterator end() = 0; + + /// Returns iterator to the begin of container + virtual const_iterator begin() const = 0; + + /// Returns iterator to the end of container + virtual const_iterator end() const = 0; + + /// Returns container element at index i + virtual reference operator[](size_type i) = 0; + + /// Returns container element at index i + virtual const_reference operator[](size_type i) const = 0; + }; void mv(MatrixTranspose transpose, const DOFMatrix &a, diff --git a/AMDiS/src/DOFIterator.h b/AMDiS/src/DOFIterator.h index 1c0b23618133162dccb98f3915cd4ec572628f29..be2f0913018508da00438863b6b92dc3d91135be 100644 --- a/AMDiS/src/DOFIterator.h +++ b/AMDiS/src/DOFIterator.h @@ -54,6 +54,9 @@ namespace AMDiS { */ class DOFIteratorBase { + public: + typedef std::bidirectional_iterator_tag iterator_category; + public: /** \brief * Constructs a DOFIteratorBase object of type t which can iterate through @@ -237,6 +240,11 @@ namespace AMDiS { template<typename T> class DOFIterator : public DOFIteratorBase { + public: + typedef T value_type; + typedef typename DOFIndexed<T>::reference reference; + typedef typename DOFIndexed<T>::pointer pointer; + public: /// Constructs a DOFIterator for cont of type t DOFIterator(DOFIndexed<T> *obj, DOFIteratorType t) @@ -253,13 +261,13 @@ namespace AMDiS { {} /// Dereference operator - inline T& operator*() + inline reference operator*() { return *it; } /// Dereference operator - inline T* operator->() + inline pointer operator->() { return &(*it); } @@ -338,18 +346,18 @@ namespace AMDiS { {} /// Dereference operator - inline const T& operator*() + inline const T& operator*() const { return *it; } /// Dereference operator - inline const T* operator->() + inline const T* operator->() const { return &(*it); } - inline bool operator!=(const DOFIterator<T>& rhs) + inline bool operator!=(const DOFIterator<T>& rhs) const { if (this->iteratedObject != rhs.iteratedObject) return true; @@ -360,7 +368,7 @@ namespace AMDiS { return false; } - inline bool operator==(const DOFIterator<T>& rhs) + inline bool operator==(const DOFIterator<T>& rhs) const { return !(this->operator==(rhs)); } diff --git a/AMDiS/src/DOFMatrix.cc b/AMDiS/src/DOFMatrix.cc index bb9741c0fc7167821942ef7b74913cf40f3d5c88..ea2aae87bc72470d2edca30644acfcf51f542380 100644 --- a/AMDiS/src/DOFMatrix.cc +++ b/AMDiS/src/DOFMatrix.cc @@ -67,10 +67,10 @@ namespace AMDiS { if (!colFeSpace) colFeSpace = rowFeSpace; - +#if 0 if (rowFeSpace && rowFeSpace->getAdmin()) (const_cast<DOFAdmin*>(rowFeSpace->getAdmin()))->addDOFIndexed(this); - +#endif boundaryManager = new BoundaryManager(rowFeSpace); nRow = rowFeSpace->getBasisFcts()->getNumber(); @@ -87,9 +87,10 @@ namespace AMDiS { FUNCNAME("DOFMatrix::DOFMatrix()"); *this = rhs; +#if 0 if (rowFeSpace && rowFeSpace->getAdmin()) (const_cast<DOFAdmin*>( rowFeSpace->getAdmin()))->addDOFIndexed(this); - +#endif TEST_EXIT(rhs.inserter == 0)("Cannot copy during insertion!\n"); inserter = 0; } @@ -97,8 +98,10 @@ namespace AMDiS { DOFMatrix::~DOFMatrix() { +#if 0 if (rowFeSpace && rowFeSpace->getAdmin()) (const_cast<DOFAdmin*>(rowFeSpace->getAdmin()))->removeDOFIndexed(this); +#endif if (boundaryManager) delete boundaryManager; if (inserter) @@ -292,10 +295,10 @@ namespace AMDiS { return matrix[a][b]; } - +#if 0 void DOFMatrix::freeDOFContent(int index) {} - +#endif void DOFMatrix::assemble(double factor, ElInfo *elInfo, @@ -466,25 +469,25 @@ namespace AMDiS { { using namespace mtl; - typedef traits::range_generator<tag::major, base_matrix_type>::type c_type; - typedef traits::range_generator<tag::nz, c_type>::type ic_type; + typedef mtl::traits::range_generator<mtl::tag::major, base_matrix_type>::type c_type; + typedef mtl::traits::range_generator<mtl::tag::nz, c_type>::type ic_type; typedef Collection<base_matrix_type>::size_type size_type; typedef Collection<base_matrix_type>::value_type value_type; - traits::row<base_matrix_type>::type row(matrix); - traits::col<base_matrix_type>::type col(matrix); - traits::const_value<base_matrix_type>::type value(matrix); + mtl::traits::row<base_matrix_type>::type row(matrix); + mtl::traits::col<base_matrix_type>::type col(matrix); + mtl::traits::const_value<base_matrix_type>::type value(matrix); size_type rows= num_rows(matrix), cols= num_cols(matrix), total= matrix.nnz(); SerUtil::serialize(out, rows); SerUtil::serialize(out, cols); SerUtil::serialize(out, total); - for (c_type cursor(mtl::begin<tag::major>(matrix)), - cend(mtl::end<tag::major>(matrix)); cursor != cend; ++cursor) - for (ic_type icursor(mtl::begin<tag::nz>(cursor)), - icend(mtl::end<tag::nz>(cursor)); icursor != icend; ++icursor) { + for (c_type cursor(mtl::begin<mtl::tag::major>(matrix)), + cend(mtl::end<mtl::tag::major>(matrix)); cursor != cend; ++cursor) + for (ic_type icursor(mtl::begin<mtl::tag::nz>(cursor)), + icend(mtl::end<mtl::tag::nz>(cursor)); icursor != icend; ++icursor) { size_type my_row= row(*icursor), my_col= col(*icursor); value_type my_value= value(*icursor); SerUtil::serialize(out, my_row); diff --git a/AMDiS/src/DOFMatrix.h b/AMDiS/src/DOFMatrix.h index 44eed142cc701cc11da8a675e52aa0894d5db5c9..7f44bb925cdfa296ff5725a9ed3e5402f19aeb46 100644 --- a/AMDiS/src/DOFMatrix.h +++ b/AMDiS/src/DOFMatrix.h @@ -48,17 +48,15 @@ namespace AMDiS { * on DOFVectors. The underlying matrix type * is a CRS matrix of double. */ - class DOFMatrix : public DOFIndexed<bool>, - public Serializable + class DOFMatrix : public Serializable { public: /// Type of scalars in the underlying matrix typedef MTLTypes::value_type value_type; // double - typedef MTLTypes::size_type size_type; // unsigned (long) - typedef mtl::matrix::parameters<mtl::row_major, mtl::index::c_index, mtl::non_fixed::dimensions, false, size_type> para; /// Type of underlying matrix + typedef mtl::matrix::parameters<mtl::row_major, mtl::index::c_index, mtl::non_fixed::dimensions, false, size_type> para; typedef mtl::compressed2D<value_type, para> base_matrix_type; /// Type of inserter for the base matrix; @@ -102,7 +100,7 @@ namespace AMDiS { { return matrix; } - +#if 0 // Only to get rid of the abstract functions, I hope they are not used std::vector<bool>::iterator begin() { @@ -130,25 +128,28 @@ namespace AMDiS { } bool dummy; // Must be deleted later - bool& operator[](DegreeOfFreedom i) + reference operator[](DegreeOfFreedom i) { ERROR_EXIT("Shouldn't be used, only fake."); - return dummy; + std::vector<bool> d; d.push_back(dummy); + return d[0]; } - const bool& operator[](DegreeOfFreedom i) const + const_reference operator[](DegreeOfFreedom i) const { ERROR_EXIT("Shouldn't be used, only fake."); - return dummy; + std::vector<bool> d; d.push_back(dummy); + return d[0]; } /// DOFMatrix does not need to be compressed before assembling, when using MTL4. void compressDOFIndexed(int first, int last, std::vector<DegreeOfFreedom> &newDOF) {} - + /// Implements DOFIndexedBase::freeDOFContent() virtual void freeDOFContent(int index); +#endif /// Returns \ref coupleMatrix. inline bool isCoupleMatrix() { @@ -330,13 +331,13 @@ namespace AMDiS { { return name; } - +#if 0 /// Resizes \ref matrix to n rows inline void resize(int n) { TEST_EXIT_DBG(n >= 0)("Can't resize DOFMatrix to negative size\n"); } - +#endif /// Returns value at logical indices a,b double logAcc(DegreeOfFreedom a, DegreeOfFreedom b) const; diff --git a/AMDiS/src/DOFVector.cc b/AMDiS/src/DOFVector.cc index 7aa20eff12a47bd39c992d7eb497f424742c3e10..7d46bc825b076db07bbb67a67ee70f8631261eee 100644 --- a/AMDiS/src/DOFVector.cc +++ b/AMDiS/src/DOFVector.cc @@ -24,6 +24,7 @@ #include "Traverse.h" #include "DualTraverse.h" #include "FixVec.h" +#include "ElementFunction.h" namespace AMDiS { @@ -237,8 +238,7 @@ namespace AMDiS { } #ifdef HAVE_PARALLEL_DOMAIN_AMDIS - double localResult = result; - MPI::COMM_WORLD.Allreduce(&localResult, &result, 1, MPI_DOUBLE, MPI_SUM); + Parallel::mpi::globalAdd(result); #endif return result; @@ -309,8 +309,7 @@ namespace AMDiS { } #ifdef HAVE_PARALLEL_DOMAIN_AMDIS - double localResult = result; - MPI::COMM_WORLD.Allreduce(&localResult, &result, 1, MPI_DOUBLE, MPI_SUM); + Parallel::mpi::globalAdd(result); #endif return result; @@ -421,6 +420,7 @@ namespace AMDiS { Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS); + if (basisFcts->isNodal()) { while (elInfo) { Element *el = elInfo->getElement(); @@ -436,6 +436,29 @@ namespace AMDiS { elInfo = stack.traverseNext(elInfo); } } else { + // nonnodal base: + ElementFunctionWorld<double> F(source, factor); + + while (elInfo) { + F.setElInfo(elInfo); + + Element *el = elInfo->getElement(); + + basisFcts->getLocalIndices(el, feSpace->getAdmin(), myLocalIndices); + + ElementVector rvec(nBasisFcts); + basisFcts->interpol(elInfo, nBasisFcts, NULL, &F, rvec); + + for (int i = 0; i < nBasisFcts; i++) { + if (vec[myLocalIndices[i]] == 0.0) { + vec[myLocalIndices[i]] = rvec[i]; + } + } + elInfo = stack.traverseNext(elInfo); + } + } + } else { + if (basisFcts->isNodal()) { DimVec<double> coords2(feSpace->getMesh()->getDim(), NO_INIT); DualTraverse dualStack; ElInfo *elInfo1, *elInfo2; @@ -476,6 +499,10 @@ namespace AMDiS { nextTraverse = dualStack.traverseNext(&elInfo1, &elInfo2, &elInfoSmall, &elInfoLarge); } + } else { + // nonnodal base + ERROR_EXIT("not yet implemented\n"); + } } } @@ -508,7 +535,7 @@ namespace AMDiS { TraverseStack stack; ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS); - + if (basFcts->isNodal()){ while (elInfo) { Element *el = elInfo->getElement(); basFcts->getLocalIndices(el, feSpace->getAdmin(), myLocalIndices); @@ -523,7 +550,30 @@ namespace AMDiS { elInfo = stack.traverseNext(elInfo); } } else { - ERROR_EXIT("not yet for dual traverse\n"); + //nonnodal base: + ElementFunctionWorld<WorldVector<double> > F(v, factor); + + while (elInfo) { + F.setElInfo(elInfo); + + Element *el = elInfo->getElement(); + + basFcts->getLocalIndices(el, feSpace->getAdmin(), myLocalIndices); + v->getLocalVector(el, vLocalCoeffs); + + mtl::dense_vector<WorldVector<double> > rvec(nBasFcts); + basFcts->interpol(elInfo, nBasFcts, NULL, &F, rvec); + + for (int i = 0; i < nBasFcts; i++) { + if (vec[myLocalIndices[i]] == nul) { + vec[myLocalIndices[i]] = rvec[i]; + } + } + elInfo = stack.traverseNext(elInfo); + } + } + } else { + ERROR_EXIT("not yet implemented for dual traverse\n"); } } @@ -728,7 +778,53 @@ namespace AMDiS { addElementVector(factor, this->elementVector, bound, mainElInfo); } + + template<> + void DOFVectorBase<double>::assembleOperator(Operator &op) + { + FUNCNAME("DOFVectorBase::assembleOperator()"); + TEST_EXIT(op.getRowFeSpace() == feSpace) + ("Row FE spaces do not fit together!\n"); + + Mesh *mesh = feSpace->getMesh(); + mesh->dofCompress(); + const BasisFunction *basisFcts = feSpace->getBasisFcts(); + + Flag assembleFlag = getAssembleFlag() | + Mesh::CALL_LEAF_EL | + Mesh::FILL_COORDS | + Mesh::FILL_DET | + Mesh::FILL_GRD_LAMBDA | + Mesh::FILL_NEIGH | + Mesh::FILL_BOUND; + + BoundaryType *bound = new BoundaryType[basisFcts->getNumber()]; + + if (getBoundaryManager()) + getBoundaryManager()->initVector(this); + + + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(mesh, -1, assembleFlag); + while (elInfo) { + basisFcts->getBound(elInfo, bound); + + assemble(1.0, elInfo, bound, &op); + + if (getBoundaryManager()) + getBoundaryManager()->fillBoundaryConditions(elInfo, this); + + elInfo = stack.traverseNext(elInfo); + } + + finishAssembling(); + getBoundaryManager()->exitVector(this); + + delete [] bound; + } + + double integrateGeneral(const std::vector<DOFVector<double>*> &vecs, AbstractFunction<double, std::vector<double> > *fct) { @@ -769,8 +865,7 @@ namespace AMDiS { } #ifdef HAVE_PARALLEL_DOMAIN_AMDIS - double localValue = value; - MPI::COMM_WORLD.Allreduce(&localValue, &value, 1, MPI_DOUBLE, MPI_SUM); + Parallel::mpi::globalAdd(value); #endif return value; @@ -826,8 +921,7 @@ namespace AMDiS { } #ifdef HAVE_PARALLEL_DOMAIN_AMDIS - double localValue = value; - MPI::COMM_WORLD.Allreduce(&localValue, &value, 1, MPI_DOUBLE, MPI_SUM); + Parallel::mpi::globalAdd(value); #endif return value; diff --git a/AMDiS/src/DOFVector.h b/AMDiS/src/DOFVector.h index ffad5593d663048ff26333a8100e7f6b664a653b..23f09aea56080c7bd0ff5a77da1f4d00aa9c4d8d 100644 --- a/AMDiS/src/DOFVector.h +++ b/AMDiS/src/DOFVector.h @@ -44,6 +44,7 @@ #include "BasisFunction.h" #include "FiniteElemSpace.h" #include "SurfaceQuadrature.h" +#include "Traits.h" namespace AMDiS { @@ -140,6 +141,9 @@ namespace AMDiS { ElInfo *elInfo, bool add = true); + /// + void assembleOperator(Operator &op); + /// That function must be called after the matrix assembling has been /// finished. This makes it possible to start some cleanup or matrix /// data compressing procedures. @@ -296,6 +300,12 @@ namespace AMDiS { template<typename T> class DOFVector : public DOFVectorBase<T>, public Serializable { + public: + typedef typename DOFVectorBase<T>::value_type value_type; + typedef typename DOFVectorBase<T>::size_type size_type; + typedef typename DOFVectorBase<T>::reference reference; + typedef typename DOFVectorBase<T>::const_reference const_reference; + public: /** \ingroup DOFAdministration * \brief @@ -451,7 +461,7 @@ namespace AMDiS { } /// Returns \ref vec[i] - inline const T& operator[](DegreeOfFreedom i) const + inline const_reference operator[](DegreeOfFreedom i) const { FUNCNAME_DBG("DOFVector<T>::operator[]"); TEST_EXIT_DBG(i >= 0 && i < static_cast<int>(vec.size())) @@ -460,7 +470,7 @@ namespace AMDiS { } /// Returns \ref vec[i] - inline T& operator[](DegreeOfFreedom i) + inline reference operator[](DegreeOfFreedom i) { FUNCNAME_DBG("DOFVector<T>::operator[]"); @@ -615,22 +625,40 @@ namespace AMDiS { ElInfo *oldElInfo = nullptr, bool useOldElInfo = false) const; - /// Writes the data of the DOFVector to an output stream. - void serialize(std::ostream &out) + template<typename S> + void serialize(std::ostream &out, boost::mpl::identity<S>) { unsigned int size = static_cast<unsigned int>(vec.size()); out.write(reinterpret_cast<const char*>(&size), sizeof(unsigned int)); out.write(reinterpret_cast<const char*>(&(vec[0])), size * sizeof(T)); } - - /// Reads data of an DOFVector from an input stream. - void deserialize(std::istream &in) + + // no serialization for bool vectors + void serialize(std::ostream &out, boost::mpl::identity<bool>) {} + + /// Writes the data of the DOFVector to an output stream. + void serialize(std::ostream &out) + { + serialize(out, boost::mpl::identity<T>()); + } + + template<typename S> + void deserialize(std::istream &in, boost::mpl::identity<S>) { unsigned int size; in.read(reinterpret_cast<char*>(&size), sizeof(unsigned int)); vec.resize(size); in.read(reinterpret_cast<char*>(&(vec[0])), size * sizeof(T)); } + + // no de-serialization for bool vectors + void deserialize(std::istream &in, boost::mpl::identity<bool>) {} + + /// Reads data of an DOFVector from an input stream. + void deserialize(std::istream &in) + { + deserialize(in, boost::mpl::identity<T>()); + } DOFVector<typename GradientType<T>::type>* getGradient(DOFVector<typename GradientType<T>::type> *grad) const; @@ -847,17 +875,17 @@ namespace AMDiS { vec.set(d); } - template<typename T> - inline int size(DOFVector<T> *vec) - { - return vec->getUsedSize(); - } - - template<typename T> - inline int size(const DOFVector<T>& vec) - { - return vec.getUsedSize(); - } +// template<typename T> +// inline int size(DOFVector<T> *vec) +// { +// return vec->getUsedSize(); +// } +// +// template<typename T> +// inline int size(const DOFVector<T>& vec) +// { +// return vec.getUsedSize(); +// } template<typename T> inline void checkFeSpace(const FiniteElemSpace* feSpace, const std::vector<T>& vec) @@ -937,8 +965,9 @@ namespace AMDiS { /// Computes the integral: \f$ \int v(\vec{x}) f(\vec{x})\,d\vec{x}\f$ template<typename T1, typename T2> - typename ProductType<T1,T2>::type integrate_VecTimesCoords(const DOFVector<T1> &vec, - AbstractFunction<T2, WorldVector<double> > *fct); + typename traits::mult_type<T1,T2>::type + integrate_VecTimesCoords(const DOFVector<T1> &vec, + AbstractFunction<T2, WorldVector<double> > *fct); /// Computes the integral: \f$ \int f(v(\vec{x}), \vec{x})\,d\vec{x}\f$ template<typename TOut, typename T> diff --git a/AMDiS/src/DOFVector.hh b/AMDiS/src/DOFVector.hh index 0016379e9d879eb38b16f68a0085489befcb2288..67556df30a5b4c9c60c02d4cb38113c8880d0fc6 100644 --- a/AMDiS/src/DOFVector.hh +++ b/AMDiS/src/DOFVector.hh @@ -47,6 +47,7 @@ #ifdef HAVE_PARALLEL_DOMAIN_AMDIS #include "parallel/MpiHelper.h" +#include "parallel/MeshDistributor.h" #endif // Defining the interface for MTL4 @@ -712,14 +713,15 @@ namespace AMDiS { template<typename T1, typename T2> - typename ProductType<T1,T2>::type integrate_VecTimesCoords(const DOFVector<T1> &vec, - AbstractFunction<T2, WorldVector<double> > *fct) + typename traits::mult_type<T1,T2>::type + integrate_VecTimesCoords(const DOFVector<T1> &vec, + AbstractFunction<T2, WorldVector<double> > *fct) { FUNCNAME("integrate_VecTimesCoords()"); TEST_EXIT(fct)("No function defined!\n"); - typedef typename ProductType<T1,T2>::type TOut; + typedef typename traits::mult_type<T1,T2>::type TOut; const FiniteElemSpace *feSpace = vec.getFeSpace(); Mesh *mesh = feSpace->getMesh(); @@ -1165,7 +1167,7 @@ namespace AMDiS { DOFVector<T> &result, bool add) { // Unfortunately needed - using namespace mtl; +// using namespace mtl; FUNCNAME("DOFVector<T>::mv()"); @@ -1691,24 +1693,24 @@ namespace AMDiS { // Some free functions used in MTL4 - template <typename T> - inline std::size_t size(const AMDiS::DOFVector<T>& v) - { - return v.getSize(); - } - - template <typename T> - inline std::size_t num_rows(const AMDiS::DOFVector<T>& v) - { - return v.getSize(); - } - - - template <typename T> - inline std::size_t num_cols(const AMDiS::DOFVector<T>& v) - { - return 1; - } +// template <typename T> +// inline std::size_t size(const AMDiS::DOFVector<T>& v) +// { +// return v.getSize(); +// } +// +// template <typename T> +// inline std::size_t num_rows(const AMDiS::DOFVector<T>& v) +// { +// return v.getSize(); +// } +// +// +// template <typename T> +// inline std::size_t num_cols(const AMDiS::DOFVector<T>& v) +// { +// return 1; +// } template <typename T> @@ -1906,7 +1908,12 @@ namespace AMDiS { elInfo = stack.traverseNext(elInfo); } - + + // NOTE: We have to synchronize the vectors in PARALLEL_DOMAIN_AMDIS mode +#ifdef HAVE_PARALLEL_DOMAIN_AMDIS + Parallel::MeshDistributor::globalMeshDistributor->synchAddVector(*result); + Parallel::MeshDistributor::globalMeshDistributor->synchAddVector(volume); +#endif DOFVector<double>::Iterator volIt(&volume, USED_DOFS); typename DOFVector<typename GradientType<T>::type>::Iterator grdIt(result, USED_DOFS); diff --git a/AMDiS/src/ElementFunction.h b/AMDiS/src/ElementFunction.h index c338d9b2bcbeb26928efa591f173666b8acda4c6..c755cdcceaa9729e388e41f0b42f33dd1dd5f01c 100644 --- a/AMDiS/src/ElementFunction.h +++ b/AMDiS/src/ElementFunction.h @@ -104,6 +104,56 @@ namespace AMDiS { /// DOFVector to be interpolated. const DOFVector<T> *dofVector; }; + + /// Abstract access to functions living on elements, but using world coordinates + template<typename T> + class ElementFunctionWorld : public AbstractFunction<T, WorldVector<double> > + { + public: + /// constructor. + ElementFunctionWorld(const DOFVector<T>* vec_, double factor_ = 1.0) + : elInfo(NULL), + vec(vec_), + localCoeff(vec_->getFeSpace()->getBasisFcts()->getNumber()), + coords(vec_->getFeSpace()->getBasisFcts()->getDim()), + factor(factor_) + {} + + /// destructor. + virtual ~ElementFunctionWorld() {} + + /// evaluation at given coordinates. + T operator()(const WorldVector<double>& x) const + { + const BasisFunction *basisFcts = vec->getFeSpace()->getBasisFcts(); + + elInfo->worldToCoord(x, &coords); + return basisFcts->evalUh(coords, localCoeff) * factor; + } + + /// sets \ref elInfo_; + inline void setElInfo(const ElInfo *elInfo_) + { + elInfo = elInfo_; + vec->getLocalVector(elInfo->getElement(), localCoeff); + } + + protected: + /// ElInfo the function currently lives on. + const ElInfo *elInfo; + + /// DOFVector to be interpolated. + const DOFVector<T>* vec; + + /// local dof-values of DOFVector on current element + mtl::dense_vector<T> localCoeff; + + /// barycentric coordinates + mutable DimVec<double> coords; + + /// global factor multiplied with result of operator() + double factor; + }; } diff --git a/AMDiS/src/FirstOrderTerm.h b/AMDiS/src/FirstOrderTerm.h index 2fb34e3e0556950934d861372c70e15660417994..dcc253a18814a1e2f0b7709ad057a9add0fb8bb1 100644 --- a/AMDiS/src/FirstOrderTerm.h +++ b/AMDiS/src/FirstOrderTerm.h @@ -30,6 +30,7 @@ #include "OperatorTerm.h" #include "AbstractFunction.h" #include "ElInfo.h" +#include "traits/size.hpp" namespace AMDiS { @@ -82,7 +83,7 @@ namespace AMDiS { mtl::dense_vector<double>& Lb, double factor) const { - const int dim = Lambda.getSize(); + const int dim = size(Lambda); for (int i = 0; i < dim; i++) { double val = 0.0; @@ -100,15 +101,17 @@ namespace AMDiS { mtl::dense_vector<double>& Lb, double factor) const { - const int dim = Lambda.getSize(); + const int dim = size(Lambda); for (int i = 0; i < dim; i++) { - double val = 0.0; - - for (int j = 0; j < dimOfWorld; j++) - val += Lambda[i][j] * b[j]; - - Lb[i] += val * factor; +// double val = Lambda[i] * b; +// double val = 0.0; +// +// for (int j = 0; j < dimOfWorld; j++) +// val += Lambda[i][j] * b[j]; +// +// Lb[i] += val * factor; + Lb[i] += (Lambda[i] * b) * factor; } } @@ -117,7 +120,7 @@ namespace AMDiS { mtl::dense_vector<double>& Lb, double factor) const { - const int dim = Lambda.getSize(); + const int dim = size(Lambda); for (int i = 0; i < dim; i++) Lb[i] += Lambda[i][bOne] * factor; diff --git a/AMDiS/src/FixVec.h b/AMDiS/src/FixVec.h index 4a88df89cc1f29c77f23f7742c5e8541422f3dde..3f17f8fb9e4f04717c9c928e04109d9c45cbd078 100644 --- a/AMDiS/src/FixVec.h +++ b/AMDiS/src/FixVec.h @@ -528,15 +528,31 @@ namespace AMDiS { { return v * d; } - + template<typename T> WorldVector<T> operator/(const WorldVector<T>& v, double d) { WorldVector<T> result = v; - result = 1./d*v; + result = v * (1.0/d); return result; } + template<typename T> + WorldVector<T>& operator+=(WorldVector<T>& v1, + const WorldVector<T>& v2) + { + add(v1, v2, v1); + return v1; + } + + template<typename T> + WorldVector<T>& operator-=(WorldVector<T>& v1, + const WorldVector<T>& v2) + { + axpy(-1.0, v2, v1); + return v1; + } + template<typename T> WorldVector<T> operator+(const WorldVector<T>& v1, const WorldVector<T>& v2) @@ -577,44 +593,72 @@ namespace AMDiS { } template<typename T> - const WorldMatrix<T>& operator*=(WorldMatrix<T>& m, T scal); + WorldMatrix<T>& operator*=(WorldMatrix<T>& m, T scal); template<typename T> - const WorldMatrix<T>& operator-=(WorldMatrix<T>& m1, const WorldMatrix<T>& m2); + WorldMatrix<T>& operator-=(WorldMatrix<T>& m1, const WorldMatrix<T>& m2); template<typename T> - const WorldMatrix<T>& operator+=(WorldMatrix<T>& m1, const WorldMatrix<T>& m2); + WorldMatrix<T>& operator+=(WorldMatrix<T>& m1, const WorldMatrix<T>& m2); template<typename T> - WorldMatrix<T> operator*(const WorldMatrix<T>& v, double d) + WorldMatrix<T> operator*(WorldMatrix<T> v, double d) { - WorldMatrix<T> result = v; - result *= d; - return result; + v *= d; + return v; } template<typename T> - WorldMatrix<T> operator*(double d, const WorldMatrix<T>& v) + WorldMatrix<T> operator*(double d, WorldMatrix<T> v) { - return v * d; + v *= d; + return v; } template<typename T> - WorldMatrix<T> operator/(const WorldMatrix<T>& v, double d) + WorldMatrix<T> operator/(WorldMatrix<T> v, double d) { - WorldMatrix<T> result = v; - result = 1./d*v; - return result; + v *= 1./d; + return v; } template<typename T> - WorldVector<T> operator*(const WorldMatrix<T>& M, const WorldVector<T>& v ) + WorldVector<T> operator*(const WorldMatrix<T>& M, const WorldVector<T>& v ) { WorldVector<T> res; res.multMatrixVec(M,v); return res; } + template<typename T> + WorldMatrix<T> operator+(WorldMatrix<T> M1, const WorldMatrix<T>& M2 ) + { + M1 += M2; + return M1; + } + + template<typename T> + WorldMatrix<T> operator-(WorldMatrix<T> M1, const WorldMatrix<T>& M2 ) + { + M1 -= M2; + return M1; + } + + + template<typename T> + WorldVector<T> operator-(WorldVector<T> v) + { + v *= -1.0; + return v; + } + + template<typename T> + WorldMatrix<T> operator-(WorldMatrix<T> v) + { + v *= -1.0; + return v; + } + inline double norm(const WorldVector<double>& v) { double val = 0.0; @@ -664,41 +708,6 @@ namespace AMDiS { return result; } }; - - /// defines of wich type the product T1*T2 is - template<typename T1, typename T2> - struct ProductType - { - typedef T1 type; - }; - - template<> struct ProductType<double, int> { typedef double type; }; - template<> struct ProductType<int, double> { typedef double type; }; - template<> struct ProductType<float, int> { typedef float type; }; - template<> struct ProductType<int, float> { typedef float type; }; - - // scalar times vector - template<typename T1> - struct ProductType<T1, WorldVector<T1> > - { - typedef WorldVector<typename ProductType<T1,T1>::type > type; - }; - - // vector times scalar - template<typename T1> - struct ProductType<WorldVector<T1>, T1> - { - typedef WorldVector<typename ProductType<T1,T1>::type > type; - }; - - // vector times vector - template<typename T1, typename T2> - struct ProductType<WorldVector<T1>, WorldVector<T2> > - { - typedef typename ProductType<T1,T2>::type type; - }; - - template<typename T,GeoIndex d> inline void resize(FixVec<T,d>& vec, size_t newSize) diff --git a/AMDiS/src/FixVec.hh b/AMDiS/src/FixVec.hh index 392c832a4975408306dcfa562584be70c1031827..98b9aaebb1e053987b1839da5e1a606db6a4f368 100644 --- a/AMDiS/src/FixVec.hh +++ b/AMDiS/src/FixVec.hh @@ -108,7 +108,7 @@ namespace AMDiS { } template<typename T> - const WorldMatrix<T>& operator*=(WorldMatrix<T>& m, T scal) + WorldMatrix<T>& operator*=(WorldMatrix<T>& m, T scal) { for (T* mIt = m.begin(); mIt != m.end(); mIt++) *mIt *= scal; @@ -117,7 +117,7 @@ namespace AMDiS { } template<typename T> - const WorldMatrix<T>& operator-=(WorldMatrix<T>& m1, const WorldMatrix<T>& m2) + WorldMatrix<T>& operator-=(WorldMatrix<T>& m1, const WorldMatrix<T>& m2) { T *m1It, *m2It; for (m1It = m1.begin(), m2It = m2.begin(); @@ -129,7 +129,7 @@ namespace AMDiS { } template<typename T> - const WorldMatrix<T>& operator+=(WorldMatrix<T>& m1, const WorldMatrix<T>& m2) + WorldMatrix<T>& operator+=(WorldMatrix<T>& m1, const WorldMatrix<T>& m2) { T* m1It, *m2It; for (m1It = m1.begin(), m2It = m2.begin(); diff --git a/AMDiS/src/Functors.h b/AMDiS/src/Functors.h index 815c6b03b3751f113d53c8b29c74514a1650090e..8bb9c4cb340f6d8b4f890dcae57527687ff02832 100644 --- a/AMDiS/src/Functors.h +++ b/AMDiS/src/Functors.h @@ -22,6 +22,8 @@ #define AMDIS_FUNCTORS_H #include "AbstractFunction.h" +#include <boost/math/special_functions/cbrt.hpp> +#include <boost/math/special_functions/pow.hpp> namespace AMDiS { @@ -155,12 +157,22 @@ struct Sqrt : public AbstractFunction<T,T> }; namespace detail { - template<int p, typename T> + template<int p, typename T, typename Enabled = void> struct Pow { - typedef typename AMDiS::ProductType<T, typename Pow<p-1,T>::result_type>::type result_type; + typedef typename traits::mult_type<T, typename Pow<p-1,T>::result_type>::type result_type; static result_type eval(const T& v) { return v*Pow<p-1,T>::eval(v); } }; + + template<int p, typename T> + struct Pow<p, T, typename boost::enable_if_c< + boost::is_same<T, typename traits::mult_type<T, T>::type>::value && + (p > 1) + >::type > + { + typedef T result_type; + static T eval(const T& v) { return boost::math::pow<p>(v); } + }; template<typename T> struct Pow<1,T> { @@ -185,18 +197,18 @@ private: double factor; }; -template<typename T1, typename T2 = ProductType<T1, T1> > -struct Norm2 : public AbstractFunction<T1, T2> +template<typename TIn, typename TOut = typename traits::mult_type<TIn, TIn>::type > +struct Norm2 : public AbstractFunction<TOut, TIn> { - Norm2(int degree = 4) : AbstractFunction<T1, T2>(degree) {} - T1 operator()(const T2 &v) const { return std::sqrt(v*v); } + Norm2(int degree = 4) : AbstractFunction<TOut, TIn>(degree) {} + TOut operator()(const TIn &v) const { return std::sqrt(v*v); } }; -template<typename T1, typename T2> -struct Norm2Sqr : public AbstractFunction<T1, T2> +template<typename TIn, typename TOut = typename traits::mult_type<TIn, TIn>::type > +struct Norm2Sqr : public AbstractFunction<TOut, TIn> { - Norm2Sqr(int degree = 2) : AbstractFunction<T1, T2>(degree) {} - T1 operator()(const T2 &v) const { return v*v; } + Norm2Sqr(int degree = 2) : AbstractFunction<TOut, TIn>(degree) {} + TOut operator()(const TIn &v) const { return v*v; } }; template<typename T> diff --git a/AMDiS/src/GenericOperatorTerm.h b/AMDiS/src/GenericOperatorTerm.h index 92d16d5ad868154cdf7cfdff8ae56f4fd83ae173..d703d1e6b39a5113a553ba754c97980aac8ac0ab 100644 --- a/AMDiS/src/GenericOperatorTerm.h +++ b/AMDiS/src/GenericOperatorTerm.h @@ -27,16 +27,14 @@ #include "AMDiS_fwd.h" #include "OperatorTerm.h" -#include "ValueTypes.h" #include "Functors.h" #include <boost/static_assert.hpp> - +#include <boost/type_traits.hpp> #include "expressions/LazyOperatorTerm.h" -#include "expressions/AtomicExpression.h" -#include "expressions/LazyExpression.h" -#include "expressions/cmath_expr.h" +#include "expressions/expressions.h" + /** generic operator-terms provide an easy way of automated generation of * 'arbitrary' operator-terms out of some elementary operations, by using a @@ -350,7 +348,7 @@ struct GenericSecondOrderTerm_1 : public SecondOrderTerm -template<typename Term, bool symmetric = true> +template<typename Term, bool symmetric = false> struct GenericSecondOrderTerm_A : public SecondOrderTerm { Term term; @@ -769,35 +767,112 @@ inline void addSOT(Operator& op, double term, int I, int J) } -// _____________________________________________________________________________ - +// ============================================================================= +/// Create an expression functor by wrapping an AbstractFunction and evaluate it a coordinates. template<typename TOut> -inline result_of::Function1<result_of::Wrapper<TOut,WorldVector<double> >, result_of::Coords> +inline expressions::Function1<expressions::Wrapper<TOut,WorldVector<double> >, expressions::Coords> eval(AbstractFunction<TOut, WorldVector<double> >* fct) { return function_(wrap(fct), X()); } -// C++11: -// template<typename TOut> -// inline auto eval(AbstractFunction<TOut, WorldVector<double> >* fct) -> decltype( function_(wrap(fct), X()) ) -// { return function_(wrap(fct), X()); } +/// Integrate an expression over a domain. +/** IF the expression does not contain any DOFVector, a mesh must be given as second argument */ +template<typename Term> +inline typename boost::enable_if<typename traits::is_expr<Term>::type, typename Term::value_type>::type +integrate(Term term, Mesh* mesh_ = NULL); +// ----------------------------------------------------------------------------- +/// Accumulate the values of an expression at the Degrees of freedom +template<typename Term, typename Functor> +inline typename boost::enable_if<typename traits::is_expr<Term>::type, typename Term::value_type>::type +accumulate(Term term, Functor f, typename Term::value_type value0); +/// Maximum of an expression at DOFs, using the \ref accumulate function. template<typename Term> -inline typename boost::enable_if<typename boost::is_base_of<LazyOperatorTermBase, Term>::type, typename Term::value_type>::type -integrate(Term term, Mesh* mesh_ = NULL); - +inline typename boost::enable_if<typename traits::is_expr<Term>::type, typename Term::value_type>::type +max(Term term) +{ + typename Term::value_type value0 = -1.e25; + value0 = accumulate(term, functors::max<typename Term::value_type>(), value0); + +#ifdef HAVE_PARALLEL_DOMAIN_AMDIS + Parallel::mpi::globalMax(value0); +#endif + return value0; +} +/// Minimum of an expression at DOFs, using the \ref accumulate function. template<typename Term> -inline typename boost::enable_if<typename boost::is_base_of<LazyOperatorTermBase, Term>::type, void>::type -transformDOF(Term term, DOFVector<typename Term::value_type>* result); +inline typename boost::enable_if<typename traits::is_expr<Term>::type, typename Term::value_type>::type +min(Term term) +{ + typename Term::value_type value0 = 1.e25; + value0 = accumulate(term, functors::min<typename Term::value_type>(), value0); + +#ifdef HAVE_PARALLEL_DOMAIN_AMDIS + Parallel::mpi::globalMin(value0); +#endif + return value0; +} +/// Maximum of absolute values of an expression at DOFs, using the \ref accumulate function. template<typename Term> -typename boost::enable_if<typename boost::is_base_of<LazyOperatorTermBase, Term>::type, - DOFVector<typename Term::value_type>& >::type -operator<<(DOFVector<typename Term::value_type>& result, const Term& term); +inline typename boost::enable_if<typename traits::is_expr<Term>::type, typename Term::value_type>::type +abs_max(Term term) +{ + typename Term::value_type value0 = 0.0; + value0 = accumulate(term, functors::abs_max<typename Term::value_type>(), value0); + +#ifdef HAVE_PARALLEL_DOMAIN_AMDIS + Parallel::mpi::globalMax(value0); +#endif + return value0; } +/// Minimum of absolute values of an expression at DOFs, using the \ref accumulate function. +template<typename Term> +inline typename boost::enable_if<typename traits::is_expr<Term>::type, typename Term::value_type>::type +abs_min(Term term) +{ + typename Term::value_type value0 = 1.e25; + value0 = accumulate(term, functors::abs_min<typename Term::value_type>(), value0); + +#ifdef HAVE_PARALLEL_DOMAIN_AMDIS + Parallel::mpi::globalMin(value0); +#endif + return value0; +} + +// ----------------------------------------------------------------------------- + +/// Assign an expression to a DOFVector +template<typename T, typename Term> +inline typename boost::enable_if< + typename boost::mpl::and_<typename traits::is_expr<Term>::type, + typename boost::is_convertible<typename Term::value_type, T>::type + >::type + >::type +transformDOF(Term term, DOFVector<T>* result); + +/// Assign an expression to a DOFVector +template<typename T, typename Term> +typename boost::enable_if< + typename boost::mpl::and_<typename traits::is_expr<Term>::type, + typename boost::is_convertible<typename Term::value_type, T>::type + >::type, + DOFVector<T>& >::type +operator<<(DOFVector<T>& result, const Term& term); + +// ----------------------------------------------------------------------------- + +/// Print an expression to an output stream +template<typename Term> +typename boost::enable_if<typename traits::is_expr<Term>::type, + std::ostream& >::type +operator<<(std::ostream& result, const Term& term); + +} // end namespace AMDiS + #include "GenericOperatorTerm.hh" #endif // AMDIS_GENERIC_OPERATOR_TERM_H diff --git a/AMDiS/src/GenericOperatorTerm.hh b/AMDiS/src/GenericOperatorTerm.hh index d05ee149f5acfa0cac505fc3d936883c33c4b14d..d6a136849a3d0d7949d0604d55b91a8e3604a90c 100644 --- a/AMDiS/src/GenericOperatorTerm.hh +++ b/AMDiS/src/GenericOperatorTerm.hh @@ -24,35 +24,36 @@ namespace AMDiS { - namespace detail { - - template<typename Term, typename T> - struct GenericOperatorTerm { }; - - template<typename Term> - struct GenericOperatorTerm<Term, double> { - typedef GenericZeroOrderTerm<Term> type; - }; - - template<typename Term> - struct GenericOperatorTerm<Term, WorldVector<double> > { - typedef GenericFirstOrderTerm_b<Term> type; - }; - - template<typename Term > - struct GenericOperatorTerm<Term, WorldMatrix<double> > { - typedef GenericSecondOrderTerm_A<Term, true> type; - }; - - } +namespace detail { + + template<typename Term, typename T, typename Enable = void> + struct GenericOperatorTerm { }; - template<typename Term> - struct GenericOperatorTerm { - typedef typename detail::GenericOperatorTerm<Term, typename Term::value_type>::type type; + template<typename Term, typename T> + struct GenericOperatorTerm<Term, T, typename boost::enable_if<traits::is_scalar<T> >::type> { + typedef GenericZeroOrderTerm<Term> type; }; + + template<typename Term, typename T> + struct GenericOperatorTerm<Term, T, typename boost::enable_if<traits::is_vector<T> >::type> { + typedef GenericFirstOrderTerm_b<Term> type; + }; + + template<typename Term, typename T > + struct GenericOperatorTerm<Term, T, typename boost::enable_if<traits::is_matrix<T> >::type> { + typedef GenericSecondOrderTerm_A<Term, true> type; + }; + +} // end namespace detail template<typename Term> -inline typename boost::enable_if<typename boost::is_base_of<LazyOperatorTermBase, Term>::type, typename Term::value_type>::type +struct GenericOperatorTerm { + typedef typename detail::GenericOperatorTerm<Term, typename Term::value_type>::type type; +}; + + +template<typename Term> +inline typename boost::enable_if<typename traits::is_expr<Term>::type, typename Term::value_type>::type integrate(Term term, Mesh* mesh_) { typedef typename Term::value_type TOut; @@ -91,16 +92,62 @@ integrate(Term term, Mesh* mesh_) } +template<typename Term, typename Functor> +inline typename boost::enable_if<typename traits::is_expr<Term>::type, typename Term::value_type>::type +accumulate(Term term, Functor f, typename Term::value_type value0) +{ + typedef typename Term::value_type TOut; + typename GenericOperatorTerm<Term>::type ot(term); + std::set<const FiniteElemSpace*> feSpaces = ot.getAuxFeSpaces(); + + TEST_EXIT(!feSpaces.empty())("The Expression must contain a DOFVector or FeSpace depended value!\n"); + const FiniteElemSpace* feSpace0 = *feSpaces.begin(); + Mesh* mesh = feSpace0->getMesh(); + + const BasisFunction *basisFcts = feSpace0->getBasisFcts(); + int nBasisFcts = basisFcts->getNumber(); + + DOFVector<bool> assigned(feSpace0, "assigned"); + assigned.set(false); + + std::vector<DegreeOfFreedom> localIndices(nBasisFcts); + TraverseStack stack; + ElInfo *elInfo = stack.traverseFirst(mesh, -1, + Mesh::CALL_LEAF_EL | + Mesh::FILL_COORDS | Mesh::FILL_GRD_LAMBDA); + + while (elInfo) { + term.initElement(&ot, elInfo, NULL, NULL, basisFcts); + basisFcts->getLocalIndices(elInfo->getElement(), feSpace0->getAdmin(), localIndices); + + for (int i = 0; i < nBasisFcts; i++) { + if (!assigned[localIndices[i]]) { + value0 = f(value0, term(i)); + assigned[localIndices[i]] = true; + } + } + elInfo = stack.traverseNext(elInfo); + } + + return value0; +} + + + // works only for nodal basis functions! -template<typename Term> -inline typename boost::enable_if<typename boost::is_base_of<LazyOperatorTermBase, Term>::type, void>::type -transformDOF(Term term, DOFVector<typename Term::value_type>* result) +template<typename T, typename Term> +inline typename boost::enable_if< + typename boost::mpl::and_<typename traits::is_expr<Term>::type, + typename boost::is_convertible<typename Term::value_type, T>::type + >::type + >::type +transformDOF(Term term, DOFVector<T>* result) { typedef typename Term::value_type TOut; TOut tmp; nullify(tmp); DOFVector<TOut> temp(result->getFeSpace(), "temp"); - DOFVector<short int> assigned(result->getFeSpace(), "assigned"); + DOFVector<int> assigned(result->getFeSpace(), "assigned"); typename GenericOperatorTerm<Term>::type ot(term); Mesh* mesh = result->getFeSpace()->getMesh(); @@ -119,7 +166,7 @@ transformDOF(Term term, DOFVector<typename Term::value_type>* result) Mesh::FILL_COORDS | Mesh::FILL_GRD_LAMBDA); while (elInfo) { - term.initElement(&ot, elInfo, NULL, NULL, basisFcts); + term.initElement(&ot, elInfo, NULL, NULL, basisFcts); basisFcts->getLocalIndices(elInfo->getElement(), resultFeSpace->getAdmin(), localIndices); for (int i = 0; i < nBasisFcts; i++) { @@ -128,23 +175,42 @@ transformDOF(Term term, DOFVector<typename Term::value_type>* result) } elInfo = stack.traverseNext(elInfo); } + +#ifdef HAVE_PARALLEL_DOMAIN_AMDIS + Parallel::MeshDistributor::globalMeshDistributor->synchAddVector(temp); + Parallel::MeshDistributor::globalMeshDistributor->synchAddVector(assigned); +#endif + DOFIterator<TOut> tempIter(&temp, USED_DOFS); - DOFIterator<TOut> resultIter(result, USED_DOFS); - DOFIterator<short int> assignedIter(&assigned, USED_DOFS); + DOFIterator<T> resultIter(result, USED_DOFS); + DOFIterator<int> assignedIter(&assigned, USED_DOFS); for (tempIter.reset(), resultIter.reset(), assignedIter.reset(); !resultIter.end(); ++tempIter, ++resultIter, ++assignedIter) { - *resultIter = (*tempIter)/static_cast<double>(*assignedIter); + *resultIter = (*tempIter) * (1.0/static_cast<double>(*assignedIter)); } } -template<typename Term> -typename boost::enable_if<typename boost::is_base_of<LazyOperatorTermBase, Term>::type, - DOFVector<typename Term::value_type>& >::type -operator<<(DOFVector<typename Term::value_type>& result, const Term& term) + +template<typename T, typename Term> +typename boost::enable_if< + typename boost::mpl::and_<typename traits::is_expr<Term>::type, + typename boost::is_convertible<typename Term::value_type, T>::type + >::type, + DOFVector<T>& >::type +operator<<(DOFVector<T>& result, const Term& term) { transformDOF(term, &result); return result; } -} \ No newline at end of file +template<typename Term> +typename boost::enable_if<typename traits::is_expr<Term>::type, + std::ostream& >::type +operator<<(std::ostream& result, const Term& term) +{ + result << term.str(); + return result; +} + +} // end namespace AMDiS diff --git a/AMDiS/src/Global.h b/AMDiS/src/Global.h index 251c48e1ab31c801c457867ac076ffe7b03f5a57..af3a26599a71b15bb880657945dab78dfeef490d 100644 --- a/AMDiS/src/Global.h +++ b/AMDiS/src/Global.h @@ -46,6 +46,9 @@ #if (defined BOOST_NO_CXX11_NULLPTR) || __cplusplus <= 199711L #define nullptr NULL #endif +#if !((defined BOOST_NO_CXX11_DECLTYPE) || defined(BOOST_NO_DECLTYPE)) + #define HAS_CPP11_DECLTYPE +#endif /** \brief current AMDiS version */ #ifndef AMDIS_VERSION diff --git a/AMDiS/src/Initfile.h b/AMDiS/src/Initfile.h index 4069c00582cbeda571333bcd8320ff5fc4e8a016..36cc97bcdfc6597a8e599738d808c774d9802c97 100644 --- a/AMDiS/src/Initfile.h +++ b/AMDiS/src/Initfile.h @@ -33,6 +33,8 @@ #include <typeinfo> #include "FixVec.h" +#include "traits/size.hpp" + #include <boost/lexical_cast.hpp> #include <boost/numeric/conversion/cast.hpp> @@ -213,15 +215,18 @@ namespace AMDiS { /// convert WorldVector to string + // TODO: allgemeine Funktion zum Schreiben von Vektoren implementieren + // unter Ausnutzung von Type-Traits template<typename T> inline void convert(const WorldVector<T>& c, std::string& valStr) { - std::vector<T> temp_vec(c.getSize()); - for (unsigned i = 0; i < temp_vec.size(); i++) + std::vector<T> temp_vec(size(c)); + for (unsigned i = 0; i < size(temp_vec); i++) temp_vec[i] = c[i]; convert(temp_vec, valStr); } + // forward declarations template< typename T > inline void convert(const std::string valStr, WorldVector<T>& c); @@ -281,6 +286,8 @@ namespace AMDiS { } } + // TODO: Verallgemeinerung der convert-method für bel. Vektoren und + // hinzunahme der Möglichkeit Matrizen anzugeben /// convert string to WorldVector template< typename T > @@ -333,7 +340,7 @@ namespace AMDiS { operator T() const { T t; - convert(valStr, t); + detail::convert(valStr, t); return t; } }; @@ -458,6 +465,7 @@ else if(error_code == TAG_NOT_FOUND_BREAK) singlett->msgInfo = debugInfo; } + /** Static get routine for getting a parameter-map from init-file * initialized in init()-method. * Idea: @@ -494,7 +502,6 @@ else if(error_code == TAG_NOT_FOUND_BREAK) } } - /// return InitEntry object for tag tag static InitEntry get(const std::string tag) { @@ -509,12 +516,12 @@ else if(error_code == TAG_NOT_FOUND_BREAK) #if 0 else if(error_code == TAG_NOT_FOUND_BREAK) - throw TagNotFoundBreak("get(): required tag '" + tag + "' not found"); + throw TagNotFoundBreak("get(): required tag '" + tag + "' not found"); else if (error_code == TAG_NOT_FOUND) - throw TagNotFound("get(): there is no tag '" + tag + "'"); + throw TagNotFound("get(): there is no tag '" + tag + "'"); // exception must be thrown, because an empty object would be return otherwise else - throw std::runtime_error("get(): unknown error_code returned for tag '" + tag + "'"); + throw std::runtime_error("get(): unknown error_code returned for tag '" + tag + "'"); #endif return result; diff --git a/AMDiS/src/Lagrange.cc b/AMDiS/src/Lagrange.cc index 52c59d270fdebd42ab52e272edcef62a9f530c9f..dd96a33572ad89698c4069d9afe3a8aab6e1b9ed 100644 --- a/AMDiS/src/Lagrange.cc +++ b/AMDiS/src/Lagrange.cc @@ -1170,7 +1170,7 @@ namespace AMDiS { RCNeighbourList* list, int n, BasisFunction* basFct) { - FUNCNAME("Lagrange::refineInter2_3d()"); + FUNCNAME_DBG("Lagrange::refineInter2_3d()"); if (n < 1) return; @@ -1227,14 +1227,21 @@ namespace AMDiS { if (list->getNeighbourElement(i, 1) && list->getNeighbourNr(i, 1) < i) lr_set += 2; - TEST_EXIT(lr_set > 0) - ("No values set on both neighbours of element %d\n", el->getIndex()); - /****************************************************************************/ /* values on child[0] */ /****************************************************************************/ switch (lr_set) { + case 0: + cdofi = el->getChild(0)->getDof(node0 + 4, n0); + (*drv)[cdofi] = + (0.125 * (-(*drv)[pdof[0]] - (*drv)[pdof[1]]) + 0.25 * (*drv)[pdof[4]] + + 0.5 * ((*drv)[pdof[5]] + (*drv)[pdof[7]])); + cdofi = el->getChild(0)->getDof(node0 + 5, n0); + (*drv)[cdofi] = + (0.125 * (-(*drv)[pdof[0]] - (*drv)[pdof[1]]) + 0.25 * (*drv)[pdof[4]] + + 0.5 * ((*drv)[pdof[6]] + (*drv)[pdof[8]])); + break; case 1: cdofi = el->getChild(0)->getDof(node0 + 4, n0); (*drv)[cdofi] = @@ -1544,8 +1551,6 @@ namespace AMDiS { if (list->getNeighbourElement(i, 1) && list->getNeighbourNr(i, 1) < i) lr_set += 2; - TEST_EXIT_DBG(lr_set)("no values set on both neighbours\n"); - /****************************************************************************/ /* values on child[0] */ /****************************************************************************/ @@ -1553,6 +1558,31 @@ namespace AMDiS { basFct->getLocalIndices(el->getChild(0), admin, cd); switch (lr_set) { + case 0: + (*drv)[cd[12]] = + (0.0625*((*drv)[pd[0]]+(*drv)[pd[1]]-(*drv)[pd[4]]-(*drv)[pd[5]]) + + 0.25*(-(*drv)[pd[6]] - (*drv)[pd[10]]) + + 0.5*((*drv)[pd[7]] + (*drv)[pd[11]] + (*drv)[pd[19]])); + (*drv)[cd[13]] = (*drv)[pd[19]]; + (*drv)[cd[14]] = + (0.0625*((*drv)[pd[0]]+(*drv)[pd[1]]-(*drv)[pd[4]]-(*drv)[pd[5]]) + + 0.25*(-(*drv)[pd[8]] - (*drv)[pd[12]]) + + 0.5*((*drv)[pd[9]] + (*drv)[pd[13]] + (*drv)[pd[18]])); + (*drv)[cd[15]] = (*drv)[pd[18]]; + (*drv)[cd[16]] = + (0.0625*((*drv)[pd[0]]+(*drv)[pd[1]]-(*drv)[pd[4]]-(*drv)[pd[5]]) + + 0.125*(-(*drv)[pd[6]]-(*drv)[pd[8]]-(*drv)[pd[10]]-(*drv)[pd[12]]) + + 0.5*((*drv)[pd[16]] + (*drv)[pd[17]]) + + 0.25*((*drv)[pd[18]] + (*drv)[pd[19]])); + (*drv)[cd[17]] = + (0.0625*(-(*drv)[pd[0]] + (*drv)[pd[1]]) + + 0.1875*((*drv)[pd[4]] - (*drv)[pd[5]]) + 0.375*(*drv)[pd[8]] + - 0.125*(*drv)[pd[12]] + 0.75*(*drv)[pd[18]]); + (*drv)[cd[18]] = + (0.0625*(-(*drv)[pd[0]] + (*drv)[pd[1]]) + + 0.1875*((*drv)[pd[4]] - (*drv)[pd[5]]) + 0.375*(*drv)[pd[6]] + - 0.125*(*drv)[pd[10]] + 0.75*(*drv)[pd[19]]); + break; case 1: (*drv)[cd[12]] = (0.0625*((*drv)[pd[0]]+(*drv)[pd[1]]-(*drv)[pd[4]]-(*drv)[pd[5]]) @@ -2164,8 +2194,6 @@ namespace AMDiS { if (list->getNeighbourElement(i, 1) && list->getNeighbourNr(i, 1) < i) lr_set += 2; - TEST_EXIT_DBG(lr_set)("no values set on both neighbours\n"); - /****************************************************************************/ /* values on child[0] */ /****************************************************************************/ @@ -2173,6 +2201,99 @@ namespace AMDiS { basFct->getLocalIndices(el->getChild(0), admin, cd); switch (lr_set) { + case 0: + (*drv)[cd[16]] = + (0.0390625*(-(*drv)[pd[0]] - (*drv)[pd[1]]) + + 0.03125*((*drv)[pd[4]] + (*drv)[pd[6]]) + + 0.015625*(*drv)[pd[5]] + + 0.1875*((*drv)[pd[7]] + (*drv)[pd[13]] + - (*drv)[pd[31]] - (*drv)[pd[32]]) + + 0.375*(-(*drv)[pd[8]] - (*drv)[pd[14]]) + + 0.5*((*drv)[pd[9]] + (*drv)[pd[15]]) + + 0.75*(*drv)[pd[33]]); + (*drv)[cd[17]] = (*drv)[pd[33]]; + (*drv)[cd[18]] = + (0.0234375*((*drv)[pd[0]] + (*drv)[pd[1]]) + + 0.09375*(-(*drv)[pd[4]] - (*drv)[pd[6]]) + + 0.140625*(*drv)[pd[5]] + + 0.0625*(-(*drv)[pd[7]] - (*drv)[pd[13]]) + + 0.5625*((*drv)[pd[31]] + (*drv)[pd[32]])); + (*drv)[cd[19]] = + (0.0390625*(-(*drv)[pd[0]] - (*drv)[pd[1]]) + + 0.03125*((*drv)[pd[4]] + (*drv)[pd[6]]) + + 0.015625*(*drv)[pd[5]] + + 0.1875*((*drv)[pd[10]] + (*drv)[pd[16]] + - (*drv)[pd[28]] - (*drv)[pd[29]]) + + 0.375*(-(*drv)[pd[11]] - (*drv)[pd[17]]) + + 0.5*((*drv)[pd[12]] + (*drv)[pd[18]]) + + 0.75*(*drv)[pd[30]]); + (*drv)[cd[20]] = (*drv)[pd[30]]; + (*drv)[cd[21]] = + (0.0234375*((*drv)[pd[0]] + (*drv)[pd[1]]) + + 0.09375*(-(*drv)[pd[4]] - (*drv)[pd[6]]) + + 0.140625*(*drv)[pd[5]] + + 0.0625*(-(*drv)[pd[10]] - (*drv)[pd[16]]) + + 0.5625*((*drv)[pd[28]] + (*drv)[pd[29]])); + (*drv)[cd[22]] = + (0.0390625*(-(*drv)[pd[0]] - (*drv)[pd[1]]) + + 0.03125*((*drv)[pd[4]] + (*drv)[pd[6]]) + + 0.015625*(*drv)[pd[5]] + + 0.125*((*drv)[pd[7]] - (*drv)[pd[8]] + (*drv)[pd[13]] + - (*drv)[pd[14]] - (*drv)[pd[31]] - (*drv)[pd[32]]) + + 0.0625*((*drv)[pd[10]] + (*drv)[pd[16]] + - (*drv)[pd[28]] - (*drv)[pd[29]]) + + 0.25*(-(*drv)[pd[22]] - (*drv)[pd[25]] + (*drv)[pd[33]]) + + 0.5*((*drv)[pd[23]] + (*drv)[pd[26]] + (*drv)[pd[34]])); + (*drv)[cd[23]] = + (0.0390625*(-(*drv)[pd[0]] - (*drv)[pd[1]]) + + 0.03125*((*drv)[pd[4]] + (*drv)[pd[6]]) + + 0.015625*(*drv)[pd[5]] + + 0.0625*((*drv)[pd[7]] + (*drv)[pd[13]] + - (*drv)[pd[31]] - (*drv)[pd[32]]) + + 0.125*((*drv)[pd[10]] - (*drv)[pd[11]] + (*drv)[pd[16]] + - (*drv)[pd[17]] - (*drv)[pd[28]] - (*drv)[pd[29]]) + + 0.25*(-(*drv)[pd[22]] - (*drv)[pd[25]] + (*drv)[pd[30]]) + + 0.5*((*drv)[pd[24]] + (*drv)[pd[27]] + (*drv)[pd[34]])); + (*drv)[cd[24]] = (*drv)[pd[34]]; + (*drv)[cd[25]] = + (0.0390625*(-(*drv)[pd[0]] - (*drv)[pd[1]]) + + 0.15625*((*drv)[pd[4]] + (*drv)[pd[6]]) + - 0.234375*(*drv)[pd[5]] + + 0.3125*((*drv)[pd[10]] - (*drv)[pd[29]]) + + 0.0625*(*drv)[pd[16]] + 0.9375*(*drv)[pd[28]]); + (*drv)[cd[26]] = + (0.0234375*(*drv)[pd[0]] - 0.0390625*(*drv)[pd[1]] + - 0.03125*(*drv)[pd[4]] - 0.046875*(*drv)[pd[5]] + + 0.09375*(*drv)[pd[6]] + + 0.125*(-(*drv)[pd[10]] + (*drv)[pd[16]] - (*drv)[pd[17]]) + + 0.375*((*drv)[pd[11]] + (*drv)[pd[28]] - (*drv)[pd[29]]) + + 0.75*(*drv)[pd[30]]); + (*drv)[cd[27]] = (*drv)[pd[28]]; + (*drv)[cd[28]] = + (0.0390625*(-(*drv)[pd[0]] - (*drv)[pd[1]]) + + 0.15625*((*drv)[pd[4]] + (*drv)[pd[6]]) + - 0.234375*(*drv)[pd[5]] + + 0.3125*((*drv)[pd[7]] - (*drv)[pd[32]]) + + 0.0625*(*drv)[pd[13]] + 0.9375*(*drv)[pd[31]]); + (*drv)[cd[29]] = + (0.0234375*(*drv)[pd[0]] - 0.0390625*(*drv)[pd[1]] + - 0.03125*(*drv)[pd[4]] - 0.046875*(*drv)[pd[5]] + + 0.09375*(*drv)[pd[6]] + + 0.125*(-(*drv)[pd[7]] + (*drv)[pd[13]] - (*drv)[pd[14]]) + + 0.375*((*drv)[pd[8]] + (*drv)[pd[31]] - (*drv)[pd[32]]) + + 0.75*(*drv)[pd[33]]); + (*drv)[cd[30]] = (*drv)[pd[31]]; + (*drv)[cd[34]] = + (0.0234375*(*drv)[pd[0]] - 0.0390625*(*drv)[pd[1]] + - 0.03125*(*drv)[pd[4]] - 0.046875*(*drv)[pd[5]] + + 0.09375*(*drv)[pd[6]] + + 0.0625*(-(*drv)[pd[7]] - (*drv)[pd[10]] + + (*drv)[pd[13]] + (*drv)[pd[16]]) + - 0.125*(*drv)[pd[22]] + 0.375*(*drv)[pd[25]] + + 0.1875*((*drv)[pd[28]] - (*drv)[pd[29]] + + (*drv)[pd[31]] - (*drv)[pd[32]]) + + 0.75*(*drv)[pd[34]]); + break; case 1: (*drv)[cd[16]] = (0.0390625*(-(*drv)[pd[0]] - (*drv)[pd[1]]) diff --git a/AMDiS/src/Lagrange.h b/AMDiS/src/Lagrange.h index 130e2ce52de15421d66dd20e6105dfa5e7d2a38c..e201c38fa2b1444b052d11a8be5a959d98e043d7 100644 --- a/AMDiS/src/Lagrange.h +++ b/AMDiS/src/Lagrange.h @@ -44,6 +44,24 @@ namespace AMDiS { */ class Lagrange : public BasisFunction { + public: + /// Creator class used in the BasisFunctionCreatorMap. + class Creator : public BasisFunctionCreator + { + public: + Creator(int degree_) : degree(degree_) {} + virtual ~Creator() {} + + /// Returns a new Lagrange object. + BasisFunction* create() + { + return getLagrange(this->dim, degree); + } + + protected: + int degree; + }; + protected: /// Constructs lagrange basis functions with the given dim and degree. /// Constructor is protected to avoid multiple instantiation of identical @@ -132,6 +150,12 @@ namespace AMDiS { DOFVector<WorldVector<double> >* fh); static void clear(); + + /// Implements BasisFunction::isnodal + bool isNodal() const + { + return true; + } protected: /// sets the barycentric coordinates (stored in \ref bary) of the local diff --git a/AMDiS/src/Mesh.cc b/AMDiS/src/Mesh.cc index 617d31995f890e0582ea6af5c262b6cd79e7be51..32cf1e0e23243579b828049d692fd75a2e84c28b 100644 --- a/AMDiS/src/Mesh.cc +++ b/AMDiS/src/Mesh.cc @@ -275,7 +275,7 @@ namespace AMDiS { me->setIndex(macroElements.size()); } - + void Mesh::removeMacroElements(std::set<MacroElement*>& delMacros, vector<const FiniteElemSpace*>& feSpaces) { @@ -350,6 +350,7 @@ namespace AMDiS { if ((*macroIt)->getNeighbour(i)->getNeighbour(j) == *macroIt) (*macroIt)->getNeighbour(i)->setNeighbour(j, nullptr); + Element *mel = (*macroIt)->getElement(); // Delete element hierarchie if (!(mel->isLeaf())) { @@ -393,25 +394,37 @@ namespace AMDiS { nLeaves = 0; nElements = 0; + nVertices = 0; - std::set<const DegreeOfFreedom*> allVertices; + if (!macroElements.empty()) { + std::set<const DegreeOfFreedom*> allVertices; - elInfo = stack.traverseFirst(this, -1, Mesh::CALL_EVERY_EL_PREORDER); - while (elInfo) { - nElements++; + elInfo = stack.traverseFirst(this, -1, Mesh::CALL_EVERY_EL_PREORDER); + while (elInfo) { + nElements++; + + if (elInfo->getElement()->isLeaf()) { + nLeaves++; - if (elInfo->getElement()->isLeaf()) { - nLeaves++; + for (int i = 0; i < getGeo(VERTEX); i++) + allVertices.insert(elInfo->getElement()->getDof(i)); + } - for (int i = 0; i < getGeo(VERTEX); i++) - allVertices.insert(elInfo->getElement()->getDof(i)); + elInfo = stack.traverseNext(elInfo); } - elInfo = stack.traverseNext(elInfo); + nVertices = allVertices.size(); + } else { + + for (size_t i = 0; i < admin.size(); i++) + { + TEST_EXIT_DBG(admin[i]->getUsedSize() == admin[i]->getHoleCount()) + ("All macro elements has been removed. But not all dofs are cleaned. (UsedSize = %d, HoleCount = %d)\n", + admin[i]->getUsedSize(), admin[i]->getHoleCount()); + + admin[i]->reset(); + } } - - nVertices = allVertices.size(); - // === Note: Although the macro elements are removed from the mesh, === // === they are not deleted from memory. The macro elements are still === // === stored in macroInfo structure. They are needed, if the mesh is === @@ -536,7 +549,7 @@ namespace AMDiS { for (int j = 0; j < n; j++) dof[n0 + j] = const_cast<DOFAdmin*>(localAdmin)->getDOFIndex(); } - + return dof; } @@ -623,7 +636,6 @@ namespace AMDiS { for (int j = 0; j < n; j++) admin[i]->freeDofIndex(dof[n0 + j]); } - delete [] dof; } @@ -1235,6 +1247,7 @@ namespace AMDiS { string valueFilename(""); string periodicFilename(""); int check = 1; + int strategy = 0; bool preserveMacroFileInfo = false; Parameters::get(name + "->macro file name", macroFilename); @@ -1243,7 +1256,14 @@ namespace AMDiS { Parameters::get(name + "->check", check); Parameters::get(name + "->preserve coarse dofs", preserveCoarseDOFs); Parameters::get(name + "->preserve macroFileInfo", preserveMacroFileInfo); - + + + Parameters::get("parallel->repartitioning->strategy", strategy); + if(strategy && !preserveMacroFileInfo) { + MSG("Preserve macroFileInfo.\n"); + preserveMacroFileInfo = true; + } + TEST_EXIT(macroFilename.length()) ("No mesh defined for parameter %s->macro file name !\n", name.c_str()); @@ -1314,8 +1334,9 @@ namespace AMDiS { // There should be at least 10 macro Elements per processor, therefore: // nMacroElements * 2^gr >= nProcs * 10 // => gr = log_2(nProcs * 10 / nMacroElements) - - double scale = 10.0 * MPI::COMM_WORLD.Get_size() / nMacroElements; + int minElemNum = 10; + Parameters::get("parallel->minion number of macro elements per processor", minElemNum); + double scale = static_cast<double>(minElemNum) * MPI::COMM_WORLD.Get_size() / nMacroElements; nParallelPreRefinements = static_cast<int>(std::max(0.0, ceil(log(scale) / log(2)))); diff --git a/AMDiS/src/Mesh.h b/AMDiS/src/Mesh.h index 210b2bd2e43435d9e815411ed22df108abd4810f..f0463f3705ef069f3bc78c229e79dd4def385d6a 100644 --- a/AMDiS/src/Mesh.h +++ b/AMDiS/src/Mesh.h @@ -878,7 +878,7 @@ namespace AMDiS { friend class MacroInfo; friend class io::MacroReader; - friend class io::MacroWriter; + friend struct io::MacroWriter; friend class MacroElement; friend class Element; }; diff --git a/AMDiS/src/MeshStructure.cc b/AMDiS/src/MeshStructure.cc index 8a2a91b181286dba30037655b265dfb8df327ebd..1769425ba7ce3811338ffbb909ae1d76e7f3f739 100644 --- a/AMDiS/src/MeshStructure.cc +++ b/AMDiS/src/MeshStructure.cc @@ -112,17 +112,29 @@ namespace AMDiS { MSG("s1 = %d s2 = %d\n", s1, s2); } - if (!el->isLeaf()) { - if (s1 == -1) - addAlongSide(el->getSecondChild(), bound.subObj, s2, - el->getChildType(bound.elType), bound.reverseMode); - else if (s2 == -1) - addAlongSide(el->getFirstChild(), bound.subObj, s1, - el->getChildType(bound.elType), bound.reverseMode); - else + /* switch (bound.subObj) + { + case EDGE: + */ + if (!el->isLeaf()) { + if (s1 == -1) + addAlongSide(el->getSecondChild(), bound.subObj, s2, + el->getChildType(bound.elType), bound.reverseMode); + else if (s2 == -1) + addAlongSide(el->getFirstChild(), bound.subObj, s1, + el->getChildType(bound.elType), bound.reverseMode); + else + addAlongSide(el, bound.subObj, bound.ithObj, bound.elType, bound.reverseMode); + } + /* break; + case FACE: addAlongSide(el, bound.subObj, bound.ithObj, bound.elType, bound.reverseMode); + break; + default: + ERROR_EXIT("What is this?\n"); } - + */ + commit(); } diff --git a/AMDiS/src/OperatorTerm.hh b/AMDiS/src/OperatorTerm.hh index c0850f8b9f1c2a1951311cd0cff420ee90ee8140..d7c6cee61f7b81742a5a208f0d8f06dd35396017 100644 --- a/AMDiS/src/OperatorTerm.hh +++ b/AMDiS/src/OperatorTerm.hh @@ -102,7 +102,7 @@ namespace AMDiS { { FUNCNAME("OperatorTerm::getGradientsAtQPs()"); - ERROR_EXIT("Not yet tested!\n"); +// ERROR_EXIT("Not yet tested!\n"); TEST_EXIT(smallElInfo->getMesh() == vec->getFeSpace()->getMesh() || largeElInfo->getMesh() == vec->getFeSpace()->getMesh()) diff --git a/AMDiS/src/ProblemInstat.h b/AMDiS/src/ProblemInstat.h index 59f393c3dba30aedca1c5aedb17e0d6acdec510d..757db148b006e0fa05fc5a918ffcb6aa0ddee021 100644 --- a/AMDiS/src/ProblemInstat.h +++ b/AMDiS/src/ProblemInstat.h @@ -52,10 +52,12 @@ namespace AMDiS { virtual ~ProblemInstatBase() {} /// Initialisation of the problem. +#if 0 virtual void initialize(Flag initFlag, ProblemInstat *adoptProblem = nullptr, Flag adoptFlag = INIT_NOTHING) {} +#endif virtual void setTime(AdaptInfo* adaptInfo) { @@ -166,9 +168,9 @@ namespace AMDiS { virtual ~ProblemInstat(); /// Initialisation of the problem. - void initialize(Flag initFlag, - ProblemInstat *adoptProblem = nullptr, - Flag adoptFlag = INIT_NOTHING); + virtual void initialize(Flag initFlag, + ProblemInstat *adoptProblem = nullptr, + Flag adoptFlag = INIT_NOTHING); /// Used in \ref initialize(). virtual void createUhOld(); diff --git a/AMDiS/src/ProblemStat.cc b/AMDiS/src/ProblemStat.cc index f4e9c9b1b3d86c06cfcfc4f428e2c42668d463a7..0cac92cb002403dcaa8c418dbb842eac5c83e38e 100644 --- a/AMDiS/src/ProblemStat.cc +++ b/AMDiS/src/ProblemStat.cc @@ -41,6 +41,7 @@ #include "RobinBC.h" #include "PeriodicBC.h" #include "Lagrange.h" +#include "Bubble.h" #include "Flag.h" #include "est/Estimator.h" #include "io/VtkWriter.h" @@ -439,7 +440,7 @@ namespace AMDiS { { FUNCNAME("ProblemStat::createFeSpace()"); - map<pair<Mesh*, int>, FiniteElemSpace*> feSpaceMap; + map<pair<Mesh*, string>, FiniteElemSpace*> feSpaceMap; int dim = -1; Parameters::get(name + "->dim", dim); TEST_EXIT(dim != -1)("no problem dimension specified!\n"); @@ -448,25 +449,46 @@ namespace AMDiS { traverseInfo.resize(nComponents); for (int i = 0; i < nComponents; i++) { - int degree = 1; - Parameters::get(name + "->polynomial degree[" + - boost::lexical_cast<string>(i) + "]", degree); - TEST_EXIT(degree > 0) - ("Poynomial degree in component %d must be larger than zero!\n", i); TEST_EXIT(componentSpaces[i] == nullptr)("feSpace already created\n"); + string componentString = "[" + boost::lexical_cast<string>(i) + "]"; + + string feSpaceName = ""; + string initFileStr = name + "->feSpace" + componentString; + Parameters::get(initFileStr, feSpaceName); + + // synonym for "feSpace" + if (feSpaceName.size() == 0) { + initFileStr = name + "->finite element space" + componentString; + Parameters::get(initFileStr, feSpaceName); + } + + // for backward compatibility also accept the old syntax + if (feSpaceName.size() == 0) { + int degree = 1; + initFileStr = name + "->polynomial degree" + componentString; + Parameters::get(initFileStr, degree); + TEST_EXIT(degree > 0) + ("Poynomial degree in component %d must be larger than zero!\n", i); + + feSpaceName = "Lagrange" + boost::lexical_cast<string>(degree); + } - if (feSpaceMap[pair<Mesh*, int>(componentMeshes[i], degree)] == nullptr) { - stringstream s; - s << name << "->feSpace[" << i << "]"; - + if (feSpaceMap[pair<Mesh*, string>(componentMeshes[i], feSpaceName)] == NULL) { + BasisFunctionCreator *basisFctCreator = + dynamic_cast<BasisFunctionCreator*>(CreatorMap<BasisFunction>::getCreator(feSpaceName, initFileStr)); + TEST_EXIT(basisFctCreator) + ("No valid basisfunction type found in parameter \"%s\"\n", initFileStr.c_str()); + basisFctCreator->setDim(dim); + FiniteElemSpace *newFeSpace = - FiniteElemSpace::provideFeSpace(admin, Lagrange::getLagrange(dim, degree), - componentMeshes[i], s.str()); - feSpaceMap[pair<Mesh*, int>(componentMeshes[i], degree)] = newFeSpace; + FiniteElemSpace::provideFeSpace(admin, basisFctCreator->create(), + componentMeshes[i], "FeSpace" + componentString + " (" + feSpaceName + ")"); + + feSpaceMap[pair<Mesh*, string>(componentMeshes[i], feSpaceName)] = newFeSpace; feSpaces.push_back(newFeSpace); } - componentSpaces[i] = feSpaceMap[pair<Mesh*, int>(componentMeshes[i], degree)]; + componentSpaces[i] = feSpaceMap[pair<Mesh*, string>(componentMeshes[i], feSpaceName)]; } for (int i = 0; i < nComponents; i++) { @@ -640,7 +662,7 @@ namespace AMDiS { solution->getDOFVector(i))); } - // create a filewrite for groups of components to write vector-values output + // create a filewrite for groups of components to write vector-valued output int nVectors = 0; Parameters::get(name + "->output->num vectors", nVectors); if (nVectors > 0) { diff --git a/AMDiS/src/Recovery.cc b/AMDiS/src/Recovery.cc index f26e1faf33c521e38e7f0f3703ca2acab5b1eff7..3ff50077f97dcbc1dcde727ff0b598c424f9d553 100644 --- a/AMDiS/src/Recovery.cc +++ b/AMDiS/src/Recovery.cc @@ -24,6 +24,8 @@ #include "parallel/MeshDistributor.h" #endif +namespace AMDiS { + RecoveryStructure& RecoveryStructure::operator=(const RecoveryStructure& rhs) { if (rhs.coords) { @@ -1020,3 +1022,5 @@ void Recovery::test(DOFVector<double> *uh, const FiniteElemSpace *fe_space) (*struct_vec)[position].print(); } } + +} diff --git a/AMDiS/src/Serializer.h b/AMDiS/src/Serializer.h index 894b1da334914770f9ccfa99a9482ff57f8f3bc3..e6c9fa4462dd2bce8a26440e864597f8c2309b5f 100644 --- a/AMDiS/src/Serializer.h +++ b/AMDiS/src/Serializer.h @@ -35,7 +35,7 @@ #include "Global.h" #include "Initfile.h" #include "AdaptInfo.h" -#include "io/FileWriter.h" +#include "io/FileWriterInterface.h" namespace AMDiS { diff --git a/AMDiS/src/Traits.h b/AMDiS/src/Traits.h new file mode 100644 index 0000000000000000000000000000000000000000..4979b5ac74c60283b8d82b31929b15b36bb58d58 --- /dev/null +++ b/AMDiS/src/Traits.h @@ -0,0 +1,225 @@ +/****************************************************************************** + * + * AMDiS - Adaptive multidimensional simulations + * + * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. + * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis + * + * Authors: + * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * + * This file is part of AMDiS + * + * See also license.opensource.txt in the distribution. + * + ******************************************************************************/ + + + +/** \file Traits.h */ + +#ifndef AMDIS_TRAITS_H +#define AMDIS_TRAITS_H + +#include <iostream> +#include "FixVec.h" +#include "MatrixVector.h" +#include "AMDiS_fwd.h" + +#include "traits/tag.hpp" +#include "traits/types.hpp" +#include "traits/category.hpp" +#include "traits/num_rows.hpp" +#include "traits/num_cols.hpp" +#include "traits/size.hpp" + +#include "boost/numeric/ublas/detail/returntype_deduction.hpp" +#include "boost/numeric/mtl/concept/std_concept.hpp" // for return_type deduction + +namespace AMDiS +{ + namespace traits + { + + // type-generators + // _________________________________________________________________________ + + // larger types + template<typename T1, typename T2> + struct larger_type + { + typedef typename boost::mpl::if_c< (sizeof(T1) > sizeof(T2)), T1, T2 >::type type; + }; + +#ifdef HAS_CPP11_DECLTYPE + + /// determines the type of the product T1*T2 + template<typename T1, typename T2> + struct mult_type + { + typedef boost::numeric::ublas::type_deduction_detail::base_result_of<T1, T2> base_type; + static typename base_type::x_type x; + static typename base_type::y_type y; + + typedef decltype( x * y ) type; + }; + + /// determines the type of the sum T1+T2 + template<typename T1, typename T2> + struct add_type + { + typedef boost::numeric::ublas::type_deduction_detail::base_result_of<T1, T2> base_type; + static typename base_type::x_type x; + static typename base_type::y_type y; + + typedef decltype( x + y ) type; + }; + +#else + + // multiplication types + // _________________________________________________________________________ + template<typename T1, typename T2, typename Category1, typename Category2> + struct mult_type_dispatch + { + typedef no_valid_type type; + }; + + /// determines the type of the product T1*T2 + template<typename T1, typename T2> + struct mult_type : mult_type_dispatch + < + T1, T2, + typename category<T1>::tag, + typename category<T2>::tag + > {}; + + /// Scalar*Scalar => Scalar + template<typename T1, typename T2> + struct mult_type_dispatch<T1, T2, tag::scalar, tag::scalar> + { + typedef typename mtl::Multiplicable<T1, T2>::result_type type; + }; + + /// Vec*Vec => Scalar (dot-product) + template<typename T1, typename T2> + struct mult_type_dispatch<T1, T2, tag::vector, tag::vector> + { + typedef typename mult_type + < + typename category<T1>::value_type, + typename category<T2>::value_type + >::type type; + }; + + /// Mat*Mat => Mat + template<typename T> + struct mult_type_dispatch<T, T, tag::matrix, tag::matrix> + { + typedef T type; + }; + + + /// Vec*Scalar => Vector + template<template<class> class Container, typename T1, typename T2> + struct mult_type_dispatch<Container<T1>, T2, tag::vector, tag::scalar> + { + typedef typename mult_type<T1, T2>::type value_type; + typedef Container<value_type> type; + }; + + /// Scalar*Vector => Vector + template<template<class> class Container, typename T1, typename T2> + struct mult_type_dispatch<T1, Container<T2>, tag::scalar, tag::matrix> + { + typedef typename mult_type<T1, T2>::type value_type; + typedef Container<value_type> type; + }; + + + /// Vec*Scalar => Vector + template<template<class> class Container, typename T1, typename T2> + struct mult_type_dispatch<Container<T1>, T2, tag::matrix, tag::scalar> + { + typedef typename mult_type<T1, T2>::type value_type; + typedef Container<value_type> type; + }; + + /// Scalar*Vector => Vector + template<template<class> class Container, typename T1, typename T2> + struct mult_type_dispatch<T1, Container<T2>, tag::scalar, tag::vector> + { + typedef typename mult_type<T1, T2>::type value_type; + typedef Container<value_type> type; + }; + + + // addition types + // _________________________________________________________________________ + template<typename T1, typename T2, typename Category1, typename Category2> + struct add_type_dispatch + { + typedef no_valid_type type; + }; + + /// determines the type of the sum T1+T2 + template<typename T1, typename T2> + struct add_type : add_type_dispatch + < + T1, T2, + typename category<T1>::tag, + typename category<T2>::tag + > {}; + + /// Scalar+Scalar => Scalar + template<typename T1, typename T2> + struct add_type_dispatch<T1, T2, tag::scalar, tag::scalar> + { + typedef typename mtl::Addable<T1, T2>::result_type type; + }; + + /// Vec+Vec => Vec + template<template<class> class Container, typename T1, typename T2> + struct add_type_dispatch<Container<T1>, Container<T2>, tag::vector, tag::vector> + { + typedef typename add_type<T1, T2>::type value_type; + typedef Container<value_type> type; + }; + + /// Mat+Mat => Mat + template<template<class> class Container, typename T1, typename T2> + struct add_type_dispatch<Container<T1>, Container<T2>, tag::matrix, tag::matrix> + { + typedef typename add_type<T1, T2>::type value_type; + typedef Container<value_type> type; + }; + + + /// Vec+Scalar => Vector + template<template<class> class Container, typename T1, typename T2> + struct add_type_dispatch<Container<T1>, T2, tag::vector, tag::scalar> + { + typedef typename add_type<T1, T2>::type value_type; + typedef Container<value_type> type; + }; + + /// Mat+Scalar => Mat + template<template<class> class Container, typename T1, typename T2> + struct add_type_dispatch<Container<T1>, T2, tag::matrix, tag::scalar> + { + typedef typename add_type<T1, T2>::type value_type; + typedef Container<value_type> type; + }; + +#endif // endif(HAS_CPP11_DECLTYPE) + + + } // end namespace traits + +} // end namespace AMDiS + +#endif diff --git a/AMDiS/src/compositeFEM/CompositeFEMMethods.cc b/AMDiS/src/compositeFEM/CompositeFEMMethods.cc index 86e858e7ca575c49f2ebced28f2f8892a1eaf66d..29f60061f12fffae0b3774776578dae87159aede 100644 --- a/AMDiS/src/compositeFEM/CompositeFEMMethods.cc +++ b/AMDiS/src/compositeFEM/CompositeFEMMethods.cc @@ -31,6 +31,10 @@ #include "CompositeFEMMethods.h" +namespace compositeFEM { + +using namespace AMDiS; +using namespace std; void CompositeFEMMethods::setPosLsToVal(DOFVector<double> *dof, const double &val, @@ -152,3 +156,5 @@ void CompositeFEMMethods::printBoundaryElements(const std::string fn_str, boundaryOut.close(); } + +} diff --git a/AMDiS/src/compositeFEM/CompositeFEMMethods.h b/AMDiS/src/compositeFEM/CompositeFEMMethods.h index 77d416cb447c9d214ceca78777d888143fbf1ac6..bdecda51d2b0fbd918a81f5bcd7faab02e271671 100644 --- a/AMDiS/src/compositeFEM/CompositeFEMMethods.h +++ b/AMDiS/src/compositeFEM/CompositeFEMMethods.h @@ -30,6 +30,8 @@ #include "FiniteElemSpace.h" #include "ElementLevelSet.h" +namespace compositeFEM { + using namespace AMDiS; class CompositeFEMMethods @@ -59,4 +61,8 @@ public: FiniteElemSpace *feSpace); }; +} + +using compositeFEM::CompositeFEMMethods; + #endif // AMDIS_COMPOSITEFEMMETHODS_H diff --git a/AMDiS/src/compositeFEM/CompositeFEMOperator.cc b/AMDiS/src/compositeFEM/CompositeFEMOperator.cc index 640f8fc913562483af63a515100f6c33994eefec..a52bb65b7ed5face9d43ef103fba366cd613e2e6 100644 --- a/AMDiS/src/compositeFEM/CompositeFEMOperator.cc +++ b/AMDiS/src/compositeFEM/CompositeFEMOperator.cc @@ -25,6 +25,11 @@ #include "SubElInfo.h" #include "SubPolytope.h" +namespace compositeFEM { + +using namespace std; +using namespace AMDiS; + void CompositeFEMOperator::getElementMatrix(const ElInfo *elInfo, ElementMatrix& userMat, double factor) @@ -288,3 +293,5 @@ void CompositeFEMOperator::getElementVector(const ElInfo *elInfo, // Free data delete subPolytope; } + +} diff --git a/AMDiS/src/compositeFEM/CompositeFEMOperator.h b/AMDiS/src/compositeFEM/CompositeFEMOperator.h index 492598398c133473207e5759a4380a66951c90e2..1fef3c19b24b42f91647e788c6b7fde945c18c15 100644 --- a/AMDiS/src/compositeFEM/CompositeFEMOperator.h +++ b/AMDiS/src/compositeFEM/CompositeFEMOperator.h @@ -38,6 +38,8 @@ class ElInfo; class FiniteElemSpace; } +namespace compositeFEM { + using namespace AMDiS; using namespace std; @@ -118,4 +120,8 @@ protected: int elStatus; }; +} + +using compositeFEM::CompositeFEMOperator; + #endif // AMDIS_COMPOSITEFEMOPERATOR_H diff --git a/AMDiS/src/compositeFEM/ElementLevelSet.cc b/AMDiS/src/compositeFEM/ElementLevelSet.cc index 8bc3cd353bf67dfad084792689e4523c7a010c20..cf983f87496650fa2ee4921da18e0cd11521caa7 100644 --- a/AMDiS/src/compositeFEM/ElementLevelSet.cc +++ b/AMDiS/src/compositeFEM/ElementLevelSet.cc @@ -22,6 +22,11 @@ #include "ElementLevelSet.h" #include "ElInfo.h" +namespace compositeFEM { + +using namespace AMDiS; +using namespace std; + int ElementLevelSet::createElementLevelSet(const ElInfo *elInfo_, const bool doCalcIntersecPts_) @@ -439,3 +444,4 @@ ElementLevelSet::getElPos(const DimVec<double> barCoords) } } +} diff --git a/AMDiS/src/compositeFEM/ElementLevelSet.h b/AMDiS/src/compositeFEM/ElementLevelSet.h index 9ffa04d28516206221241d30ad4d29b3f90cbd6a..73f5fe77b2f8fd1937da51ffaa0c2cc6dd3c9f9f 100644 --- a/AMDiS/src/compositeFEM/ElementLevelSet.h +++ b/AMDiS/src/compositeFEM/ElementLevelSet.h @@ -35,8 +35,9 @@ namespace AMDiS { class Mesh; } -using namespace AMDiS; -using namespace std; +namespace compositeFEM { + + using namespace AMDiS; // =========================================================================== // ===== class ElementLevelSet =============================================== @@ -468,4 +469,8 @@ protected: static const int MAX_INTERSECTION_POINTS = 4; }; +} + +using compositeFEM::ElementLevelSet; + #endif // AMDIS_ELEMENTLEVELSET_H diff --git a/AMDiS/src/compositeFEM/LevelSetAdaptMesh.cc b/AMDiS/src/compositeFEM/LevelSetAdaptMesh.cc index ef4e1c46f2e830b8ae6e595f37403d70083788d8..f4c0a5aed674c0584d19e53f6dd4569673fd117b 100644 --- a/AMDiS/src/compositeFEM/LevelSetAdaptMesh.cc +++ b/AMDiS/src/compositeFEM/LevelSetAdaptMesh.cc @@ -24,6 +24,10 @@ #include "ElementLevelSet.h" #include "LevelSetAdaptMesh.h" +namespace compositeFEM { + +using namespace AMDiS; + void LevelSetAdaptMesh::adaptMesh(AdaptInfo *adaptInfo) { @@ -245,3 +249,5 @@ LevelSetAdaptMesh::getElementSizesFromInit(const std::string probName, TEST_EXIT(sizePosLs_ >= 0)("illegal sizePosLs !\n"); TEST_EXIT(bandSize_ >= 0)("illegal bandSize !\n"); } + +} diff --git a/AMDiS/src/compositeFEM/LevelSetAdaptMesh.h b/AMDiS/src/compositeFEM/LevelSetAdaptMesh.h index 191ae3df88ef2fe7821207495ea6f4d5ced532bb..9c8f3d2f9ab243a0811ee8c8af78407df0191d6b 100644 --- a/AMDiS/src/compositeFEM/LevelSetAdaptMesh.h +++ b/AMDiS/src/compositeFEM/LevelSetAdaptMesh.h @@ -33,6 +33,8 @@ #include "ElementLevelSet.h" +namespace compositeFEM { + using namespace AMDiS; class LevelSetAdaptMesh @@ -194,4 +196,8 @@ public: bool coarseningMarkIsSet; }; +} + +using compositeFEM::LevelSetAdaptMesh; + #endif // AMDIS_LEVELSETADAPTMESH_H diff --git a/AMDiS/src/compositeFEM/PenaltyOperator.cc b/AMDiS/src/compositeFEM/PenaltyOperator.cc index dbf8af157219087514fab6f7aa07f82354da29ed..7c799fef19e1eaa6c4a6e6a589e000314a2e28d2 100644 --- a/AMDiS/src/compositeFEM/PenaltyOperator.cc +++ b/AMDiS/src/compositeFEM/PenaltyOperator.cc @@ -22,6 +22,11 @@ #include "PenaltyOperator.h" #include "SurfaceOperator.h" +namespace compositeFEM { + +using namespace AMDiS; +using namespace std; + double PenaltyOperator::getPenaltyCoeff(const ElInfo *elInfo) { @@ -266,3 +271,5 @@ PenaltyOperator::getElementVector(const ElInfo *elInfo, return; } + +} diff --git a/AMDiS/src/compositeFEM/PenaltyOperator.h b/AMDiS/src/compositeFEM/PenaltyOperator.h index 9df5e3de5bae12cce94edb99a0a39eb8011f6e33..aed02f00b24039e6bccfb3f2e1cdfb0b9db1e5f7 100644 --- a/AMDiS/src/compositeFEM/PenaltyOperator.h +++ b/AMDiS/src/compositeFEM/PenaltyOperator.h @@ -36,6 +36,8 @@ namespace AMDiS { class FiniteElemSpace; } +namespace compositeFEM { + using namespace AMDiS; using namespace std; @@ -141,4 +143,8 @@ protected: VectorOfFixVecs<DimVec<double> > *tempCoords; }; +} + +using compositeFEM::PenaltyOperator; + #endif // AMDIS_PENALTYOPERATOR_H diff --git a/AMDiS/src/compositeFEM/TranslateLsFct.h b/AMDiS/src/compositeFEM/TranslateLsFct.h index 42b24300155e3619109bf710adcaae6634d33dbf..e73548cc642a271c1ece99bdc74d46b8937cf9d4 100644 --- a/AMDiS/src/compositeFEM/TranslateLsFct.h +++ b/AMDiS/src/compositeFEM/TranslateLsFct.h @@ -28,6 +28,8 @@ #include "ElementFunction.h" #include "FixVec.h" +namespace compositeFEM { + using namespace AMDiS; template<typename T> @@ -61,4 +63,8 @@ protected: double c; }; +} + +using compositeFEM::TranslateLsFct; + #endif // AMDIS_TRANSLATELSFCT_H diff --git a/AMDiS/src/MathFunctions.h b/AMDiS/src/deprecated/MathFunctions.h similarity index 100% rename from AMDiS/src/MathFunctions.h rename to AMDiS/src/deprecated/MathFunctions.h diff --git a/AMDiS/src/ProblemImplicit.cc b/AMDiS/src/deprecated/ProblemImplicit.cc similarity index 100% rename from AMDiS/src/ProblemImplicit.cc rename to AMDiS/src/deprecated/ProblemImplicit.cc diff --git a/AMDiS/src/ProblemImplicit.h b/AMDiS/src/deprecated/ProblemImplicit.h similarity index 100% rename from AMDiS/src/ProblemImplicit.h rename to AMDiS/src/deprecated/ProblemImplicit.h diff --git a/AMDiS/src/est/Estimator.cc b/AMDiS/src/est/Estimator.cc index 0eb0897cf4b4dd733c9029d82250e62ddaf7d24a..63e54ff2f6b6db8995d9f909713cac417ebfc473 100644 --- a/AMDiS/src/est/Estimator.cc +++ b/AMDiS/src/est/Estimator.cc @@ -39,7 +39,7 @@ namespace AMDiS { double Estimator::estimate(double ts) - { + { FUNCNAME("Estimator::estimate()"); bool dualTraverse = false; @@ -51,8 +51,9 @@ namespace AMDiS { traverseInfo.getStatus(row, i) == SingleComponentInfo::DIF_SPACES_NO_AUX || traverseInfo.getStatus(row, i) == SingleComponentInfo::DIF_SPACES_WITH_AUX) dualTraverse = true; - +#ifndef NDEBUG MSG("traverseInfo = %d, dualTraverse = %d\n", traverseInfo.getStatus(row, i), int(dualTraverse)); +#endif } if (!dualTraverse) { diff --git a/AMDiS/src/est/ResidualEstimator.cc b/AMDiS/src/est/ResidualEstimator.cc index 2bbe3958ca4991745cb61f95aab34eafa674b638..e647f3bbf5ed8c0541d517e2b91cbaace83914c2 100644 --- a/AMDiS/src/est/ResidualEstimator.cc +++ b/AMDiS/src/est/ResidualEstimator.cc @@ -174,7 +174,7 @@ namespace AMDiS { #ifdef HAVE_PARALLEL_DOMAIN_AMDIS void ResidualEstimator::initParallel() { - FUNCNAME("ResidualEstimator::initParallel()"); + FUNCNAME_DBG("ResidualEstimator::initParallel()"); if (C1 == 0.0) return; diff --git a/AMDiS/src/expressions/AtomicExpression.h b/AMDiS/src/expressions/AtomicExpression.h deleted file mode 100644 index 2e9b0bee1aac4f39b507bb55766f0a2410ace03d..0000000000000000000000000000000000000000 --- a/AMDiS/src/expressions/AtomicExpression.h +++ /dev/null @@ -1,491 +0,0 @@ -/****************************************************************************** - * - * AMDiS - Adaptive multidimensional simulations - * - * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. - * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis - * - * Authors: - * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al. - * - * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * - * This file is part of AMDiS - * - * See also license.opensource.txt in the distribution. - * - ******************************************************************************/ - - - -/** \file AtomicExpression.h */ - -#ifndef AMDIS_ATOMIC_EXPRESSION_H -#define AMDIS_ATOMIC_EXPRESSION_H - -#include "AMDiS_fwd.h" -#include "LazyOperatorTerm.h" -#include "ValueTypes.h" - -#include <boost/static_assert.hpp> - -#include "ValueOf.h" -#include "GradientOf.h" - -namespace AMDiS { - -namespace traits { - - template<typename T> - struct ValueType { - typedef T type; - static type eval(const T& t) { return t; } - }; - - template<typename T> - struct ValueType<T&> { - typedef typename ValueType<T>::type type; - static type eval(T& t) { return t; } - }; - - template<typename T> - struct ValueType<T*> { - typedef typename ValueType<T>::type type; - static type eval(T* t) { return ValueType<T>::eval(*t); } - }; - - template<typename T> - struct ValueType<const T> { - typedef typename ValueType<T>::type type; - static type eval(const T& t) { return ValueType<T>::eval(t); } - }; - -} - -namespace result_of { - - /// initialize a coordinate vector at quadrature points - struct Coords : public LazyOperatorTermBase - { - typedef WorldVector<double> value_type; - mutable mtl::dense_vector<WorldVector<double> > x; - - Coords() {} - - template<typename List> - void insertFeSpaces(List& feSpaces) const {} - - int getDegree() const - { - return 1; - } - - template<typename OT> - void initElement(OT* ot, const ElInfo* elInfo, - SubAssembler* subAssembler, Quadrature *quad, - const BasisFunction *basisFct = NULL) - { - if (subAssembler) { - subAssembler->getCoordsAtQPs(elInfo, quad, x); - } - else if (quad) { - const int nPoints = quad->getNumPoints(); - - x.change_dim(nPoints); - for (int i = 0; i < nPoints; i++) - elInfo->coordToWorld(quad->getLambda(i), x[i]); - } - else if (basisFct) { - const int nBasisFct = basisFct->getNumber(); - - x.change_dim(nBasisFct); - for (int i = 0; i < nBasisFct; i++) - elInfo->coordToWorld(*basisFct->getCoords(i), x[i]); - } - } - - - template<typename OT> - void initElement(OT* ot, const ElInfo* smallElInfo, const ElInfo* largeElInfo, - SubAssembler* subAssembler, Quadrature *quad, - const BasisFunction *basisFct = NULL) - { - if (subAssembler) { - subAssembler->getCoordsAtQPs(smallElInfo, quad, x); - } - else if (quad) { - const int nPoints = quad->getNumPoints(); - - x.change_dim(nPoints); - for (int i = 0; i < nPoints; i++) - smallElInfo->coordToWorld(quad->getLambda(i), x[i]); - } - else if (basisFct) { - const int nBasisFct = basisFct->getNumber(); - - x.change_dim(nBasisFct); - for (int i = 0; i < nBasisFct; i++) - smallElInfo->coordToWorld(*basisFct->getCoords(i), x[i]); - } - } - - inline value_type operator()(const int& iq) const { return x[iq]; } - - template<typename Identifier> - inline value_type derivative(const int& iq) const { WorldVector<double> vec0; vec0.set(0.0); return vec0; } - }; - - - template<int I> - struct Coord : public LazyOperatorTermBase - { - typedef double value_type; - mutable mtl::dense_vector<WorldVector<double> > x; - - Coord() {} - - template<typename List> - void insertFeSpaces(List& feSpaces) const {} - - int getDegree() const - { - return 1; - } - - template<typename OT> - void initElement(OT* ot, const ElInfo* elInfo, - SubAssembler* subAssembler, Quadrature *quad, - const BasisFunction *basisFct = NULL) - { - if (subAssembler) { - subAssembler->getCoordsAtQPs(elInfo, quad, x); - } - else if (quad) { - const int nPoints = quad->getNumPoints(); - - x.change_dim(nPoints); - for (int i = 0; i < nPoints; i++) - elInfo->coordToWorld(quad->getLambda(i), x[i]); - } - else if (basisFct) { - const int nBasisFct = basisFct->getNumber(); - - x.change_dim(nBasisFct); - for (int i = 0; i < nBasisFct; i++) - elInfo->coordToWorld(*basisFct->getCoords(i), x[i]); - } - } - - template<typename OT> - void initElement(OT* ot, const ElInfo* smallElInfo, const ElInfo* largeElInfo, - SubAssembler* subAssembler, Quadrature *quad, - const BasisFunction *basisFct = NULL) - { - if (subAssembler) { - subAssembler->getCoordsAtQPs(smallElInfo, quad, x); - } - else if (quad) { - const int nPoints = quad->getNumPoints(); - - x.change_dim(nPoints); - for (int i = 0; i < nPoints; i++) - smallElInfo->coordToWorld(quad->getLambda(i), x[i]); - } - else if (basisFct) { - const int nBasisFct = basisFct->getNumber(); - - x.change_dim(nBasisFct); - for (int i = 0; i < nBasisFct; i++) - smallElInfo->coordToWorld(*basisFct->getCoords(i), x[i]); - } - } - - inline double operator()(const int& iq) const { return x[iq][I]; } - - template<typename Identifier> - inline double derivative(const int& iq) const { return 0.0; } - }; - - - /// initialize a normal vector at quadrature points - struct Normals : public LazyOperatorTermBase - { - typedef WorldVector<double> value_type; - mutable WorldVector<double> normal; - int side; - - Normals(int side_) : side(side_) {} - - template<typename List> - void insertFeSpaces(List& feSpaces) const {} - - int getDegree() const - { - return 1; - } - - template<typename OT> - void initElement(OT* ot, const ElInfo* elInfo, - SubAssembler* subAssembler, Quadrature *quad, - const BasisFunction *basisFct = NULL) - { - elInfo->getNormal(side, normal); - } - - - template<typename OT> - void initElement(OT* ot, const ElInfo* smallElInfo, const ElInfo* largeElInfo, - SubAssembler* subAssembler, Quadrature *quad, - const BasisFunction *basisFct = NULL) - { - smallElInfo->getNormal(side, normal); - } - - inline value_type operator()(const int& iq) const { return normal; } - - template<typename Identifier> - inline value_type derivative(const int& iq) const { WorldVector<double> vec0; vec0.set(0.0); return vec0; } - }; - - - struct Normal : public LazyOperatorTermBase - { - typedef double value_type; - mutable WorldVector<double> normal; - int side; - int I; - - Normal(int side_, int I_) : side(side_), I(I_) {} - - template<typename List> - void insertFeSpaces(List& feSpaces) const {} - - int getDegree() const - { - return 1; - } - - template<typename OT> - void initElement(OT* ot, const ElInfo* elInfo, - SubAssembler* subAssembler, Quadrature *quad, - const BasisFunction *basisFct = NULL) - { - elInfo->getNormal(side, normal); - } - - - template<typename OT> - void initElement(OT* ot, const ElInfo* smallElInfo, const ElInfo* largeElInfo, - SubAssembler* subAssembler, Quadrature *quad, - const BasisFunction *basisFct = NULL) - { - smallElInfo->getNormal(side, normal); - } - - inline value_type operator()(const int& iq) const { return normal[I]; } - - template<typename Identifier> - inline value_type derivative(const int& iq) const { return 0.0; } - }; - - - - /// initialize a normal vector at quadrature points - struct ElementNormals : public LazyOperatorTermBase - { - typedef WorldVector<double> value_type; - mutable WorldVector<double> elementNormal; - - ElementNormals() {} - - template<typename List> - void insertFeSpaces(List& feSpaces) const {} - - int getDegree() const - { - return 1; - } - - template<typename OT> - void initElement(OT* ot, const ElInfo* elInfo, - SubAssembler* subAssembler, Quadrature *quad, - const BasisFunction *basisFct = NULL) - { - elInfo->getElementNormal(elementNormal); - } - - - template<typename OT> - void initElement(OT* ot, const ElInfo* smallElInfo, const ElInfo* largeElInfo, - SubAssembler* subAssembler, Quadrature *quad, - const BasisFunction *basisFct = NULL) - { - smallElInfo->getElementNormal(elementNormal); - } - - inline value_type operator()(const int& iq) const { return elementNormal; } - - template<typename Identifier> - inline value_type derivative(const int& iq) const { WorldVector<double> vec0; vec0.set(0.0); return vec0; } - }; - - - struct ElementNormal : public LazyOperatorTermBase - { - typedef double value_type; - mutable WorldVector<double> elementNormal; - int I; - - ElementNormal(int I_) : I(I_) {} - - template<typename List> - void insertFeSpaces(List& feSpaces) const {} - - int getDegree() const - { - return 1; - } - - template<typename OT> - void initElement(OT* ot, const ElInfo* elInfo, - SubAssembler* subAssembler, Quadrature *quad, - const BasisFunction *basisFct = NULL) - { - elInfo->getElementNormal(elementNormal); - } - - - template<typename OT> - void initElement(OT* ot, const ElInfo* smallElInfo, const ElInfo* largeElInfo, - SubAssembler* subAssembler, Quadrature *quad, - const BasisFunction *basisFct = NULL) - { - smallElInfo->getElementNormal(elementNormal); - } - - inline value_type operator()(const int& iq) const { return elementNormal[I]; } - - template<typename Identifier> - inline value_type derivative(const int& iq) const { return 0.0; } - }; - - - template<typename T> - struct Const : public LazyOperatorTermBase - { - typedef T value_type; - T value; - Const(const T& value_) : value(value_) {} - - template<typename List> - void insertFeSpaces(List& feSpaces) const {} - - int getDegree() const - { - return 0; - } - - template<typename OT> - void initElement(OT* ot, const ElInfo* elInfo, - SubAssembler* subAssembler, Quadrature *quad, - const BasisFunction *basisFct = NULL) {} - - template<typename OT> - void initElement(OT* ot, const ElInfo* smallElInfo, const ElInfo* largeElInfo, - SubAssembler* subAssembler, Quadrature *quad, - const BasisFunction *basisFct = NULL) {} - - inline value_type operator()(const int& iq) const { return value; } - - template<typename Identifier> - inline value_type derivative(const int& iq) const { return 0.0; } - }; - - - template<typename T> - struct Reference : public LazyOperatorTermBase - { - typedef typename ValueType<T>::type value_type; - const value_type& value; - Reference(const T& value_) : value(value_) {} - Reference(const T* value_) : value(*value_) {} - - template<typename List> - void insertFeSpaces(List& feSpaces) const {} - - int getDegree() const - { - return 0; - } - - template<typename OT> - void initElement(OT* ot, const ElInfo* elInfo, - SubAssembler* subAssembler, Quadrature *quad, - const BasisFunction *basisFct = NULL) {} - - template<typename OT> - void initElement(OT* ot, const ElInfo* smallElInfo, const ElInfo* largeElInfo, - SubAssembler* subAssembler, Quadrature *quad, - const BasisFunction *basisFct = NULL) {} - - inline value_type operator()(const int& iq) const { return value; } - - template<typename Identifier> - inline value_type derivative(const int& iq) const { return 0.0; } - }; - - - - /// - template<typename Term, typename Identifier> - struct Jacobian : public LazyOperatorTerm1<Term> - { - typedef LazyOperatorTerm1<Term> super; - typedef typename Term::value_type value_type; - - Jacobian(const Term& term_) : super(term_) {} - - int getDegree() const - { - // TODO: eventuell noch Polynomgrad der Ableitung extra bestimmen - return super::term.getDegree(); - } - - inline value_type operator()(const int& iq) const { return super::term.template derivative<Identifier>(iq); } - }; - -} - -inline result_of::Coords X() { return result_of::Coords(); } -template<int I> -inline result_of::Coord<I> X() { return result_of::Coord<I>(); } - -inline result_of::Normals N(int side) { return result_of::Normals(side); } -inline result_of::Normal N(int side, int I) { return result_of::Normal(side, I); } - -inline result_of::ElementNormals M() { return result_of::ElementNormals(); } -inline result_of::ElementNormal M(int I) { return result_of::ElementNormal(I); } - -template<typename T> -inline result_of::Const<T> constant(const T& value) { return result_of::Const<T>(value); } - -template<typename T> -inline result_of::Reference<T> ref_(T& value) { return result_of::Reference<T>(value); } -template<typename T> -inline result_of::Reference<T> ref_(T* value) { return result_of::Reference<T>(value); } - -namespace Private { - - template<typename Identifier, typename Term> - inline typename boost::enable_if< - typename boost::is_base_of<LazyOperatorTermBase, Term>::type, - result_of::Jacobian<Term, Identifier> >::type - jacobian(const Term& t) { return result_of::Jacobian<Term, Identifier>(t); } - -} - -} // end namespace AMDiS - -#endif \ No newline at end of file diff --git a/AMDiS/src/expressions/GradientOf.h b/AMDiS/src/expressions/GradientOf.h deleted file mode 100644 index 4319dedb08f897f8506d2b5cf1263d3b00e171f3..0000000000000000000000000000000000000000 --- a/AMDiS/src/expressions/GradientOf.h +++ /dev/null @@ -1,250 +0,0 @@ -/****************************************************************************** - * - * AMDiS - Adaptive multidimensional simulations - * - * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. - * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis - * - * Authors: - * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al. - * - * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * - * This file is part of AMDiS - * - * See also license.opensource.txt in the distribution. - * - ******************************************************************************/ - - - -/** \file GradientOf.h */ - -#ifndef AMDIS_GRADIENT_OF_H -#define AMDIS_GRADIENT_OF_H - -#include "AMDiS_fwd.h" -#include "LazyOperatorTerm.h" -#include "ValueTypes.h" -#include "DOFVector.h" - -#include <boost/static_assert.hpp> - -namespace AMDiS { - -namespace result_of { - - template<typename Vector> - struct GradientOf : public LazyOperatorTermBase - { - typedef typename ValueType<Vector>::type T; - typedef typename GradientType<T>::type value_type; - - DOFVector<T>* vecDV; - mutable mtl::dense_vector<typename GradientType<T>::type> vec; - mutable mtl::dense_vector<T> coeff; - - GradientOf(Vector& vector) : vecDV(&vector) {} - GradientOf(Vector* vector) : vecDV(vector) {} - - template<typename List> - void insertFeSpaces(List& feSpaces) const - { - feSpaces.insert(vecDV->getFeSpace()); - } - - int getDegree() const - { - return vecDV->getFeSpace()->getBasisFcts()->getDegree() /* -1 */; - } - - template<typename OT> - void initElement(OT* ot, const ElInfo* elInfo, - SubAssembler* subAssembler, Quadrature *quad, - const BasisFunction *basisFct = NULL) - { - if (ot && subAssembler) - ot->getGradientsAtQPs(vecDV, elInfo, subAssembler, quad, vec); - else if (quad) - vecDV->getGrdAtQPs(elInfo, quad, NULL, vec); - else if (basisFct) { - const BasisFunction *localBasisFct = vecDV->getFeSpace()->getBasisFcts(); - - // get coefficients of DOFVector - coeff.change_dim(localBasisFct->getNumber()); - vecDV->getLocalVector(elInfo->getElement(), coeff); - - // eval basisfunctions of DOFVector at coords of given basisFct - size_t nBasisFct = basisFct->getNumber(); - vec.change_dim(nBasisFct); - - const DimVec<WorldVector<double> > &grdLambda = elInfo->getGrdLambda(); - for (size_t i = 0; i < nBasisFct; i++) - localBasisFct->evalGrdUh(*basisFct->getCoords(i), grdLambda, coeff, vec[i]); - } - } - - - template<typename OT> - inline void initElement(OT* ot, const ElInfo* smallElInfo, const ElInfo* largeElInfo, - SubAssembler* subAssembler, Quadrature *quad, - const BasisFunction *basisFct = NULL) - { - if (ot && subAssembler) - ot->getGradientsAtQPs(vecDV, smallElInfo, largeElInfo, subAssembler, quad, vec); - else if (quad) - vecDV->getGrdAtQPs(smallElInfo, largeElInfo, quad, NULL, vec); - else if (basisFct) { - const BasisFunction *localBasisFct = vecDV->getFeSpace()->getBasisFcts(); - - // get coefficients of DOFVector - coeff.change_dim(localBasisFct->getNumber()); - vecDV->getLocalVector(smallElInfo->getElement(), coeff); - - // eval basisfunctions of DOFVector at coords of given basisFct - size_t nBasisFct = basisFct->getNumber(); - vec.change_dim(nBasisFct); - - const DimVec<WorldVector<double> > &grdLambda = smallElInfo->getGrdLambda(); - for (size_t i = 0; i < nBasisFct; i++) - localBasisFct->evalGrdUh(*basisFct->getCoords(i), grdLambda, coeff, vec[i]); - } - } - - value_type operator()(const int& iq) const { return vec[iq]; } - }; - - - template<int I, typename Vector> - struct DerivativeOf : public LazyOperatorTermBase - { - typedef typename ValueType<Vector>::type T; - typedef T value_type; - - DOFVector<T>* vecDV; - mutable mtl::dense_vector<typename GradientType<T>::type> vec; -// mutable mtl::dense_vector<T> vec; - mutable mtl::dense_vector<T> coeff; - int comp; - - DerivativeOf(Vector& vector) : vecDV(&vector), comp(I) {} - DerivativeOf(Vector* vector) : vecDV(vector), comp(I) {} - - DerivativeOf(Vector& vector, int I0) : vecDV(&vector), comp(I0) - { - TEST_EXIT_DBG( I < 0 && I0 >= 0 ) - ("You yould specify eather template<int I>, or constructor(int I0)\n"); - } - DerivativeOf(Vector* vector, int I0) : vecDV(vector), comp(I0) - { - TEST_EXIT_DBG( I < 0 && I0 >= 0 ) - ("You yould specify eather template<int I>, or constructor(int I0)\n"); - } - - template<typename List> - void insertFeSpaces(List& feSpaces) const - { - feSpaces.insert(vecDV->getFeSpace()); - } - - int getDegree() const - { - return vecDV->getFeSpace()->getBasisFcts()->getDegree() /* -1 */; - } - - template<typename OT> - void initElement(OT* ot, const ElInfo* elInfo, - SubAssembler* subAssembler, Quadrature *quad, - const BasisFunction *basisFct = NULL) - { - if (ot && subAssembler) - ot->getGradientsAtQPs(vecDV, elInfo, subAssembler, quad, vec); //subAssembler->getDerivativeAtQPs(vecDV, elInfo, quad, comp, vec); - else if (quad) - vecDV->getGrdAtQPs(elInfo, quad, NULL, vec); //vecDV->getDerivativeAtQPs(elInfo, quad, NULL, comp, vec); - else if (basisFct) { - const BasisFunction *localBasisFct = vecDV->getFeSpace()->getBasisFcts(); - - // get coefficients of DOFVector - coeff.change_dim(localBasisFct->getNumber()); - vecDV->getLocalVector(elInfo->getElement(), coeff); - - // eval basisfunctions of DOFVector at coords of given basisFct - size_t nBasisFct = basisFct->getNumber(); -// mtl::dense_vector<typename GradientType<T>::type> helper(nBasisFct); - - const DimVec<WorldVector<double> > &grdLambda = elInfo->getGrdLambda(); - vec.change_dim(nBasisFct); - for (size_t i = 0; i < nBasisFct; i++) - localBasisFct->evalGrdUh(*basisFct->getCoords(i), grdLambda, coeff, vec[i]); //helper[i]); - -// for (size_t i = 0; i < num_rows(helper); i++) -// vec[i] = helper[i][comp]; - } - } - - - template<typename OT> - void initElement(OT* ot, const ElInfo* smallElInfo, const ElInfo* largeElInfo, - SubAssembler* subAssembler, Quadrature *quad, - const BasisFunction *basisFct = NULL) - { -// if (op && subAssembler) -// ot->getGradientsAtQPs(vecDV, smallElInfo, largeElInfo, subAssembler, quad, vec); -// else -// vecDV->getGrdAtQPs(smallElInfo, largeElInfo, localQuad, NULL, vec); - - if (ot && subAssembler) - ot->getGradientsAtQPs(vecDV, smallElInfo, largeElInfo, subAssembler, quad, vec); //subAssembler->getDerivativeAtQPs(vecDV, smallElInfo, largeElInfo, quad, comp, vec); - else if (quad) - vecDV->getGrdAtQPs(smallElInfo, largeElInfo, quad, NULL, vec); // vecDV->getDerivativeAtQPs(smallElInfo, largeElInfo, quad, NULL, comp, vec); - else if (basisFct) { - const BasisFunction *localBasisFct = vecDV->getFeSpace()->getBasisFcts(); - - // get coefficients of DOFVector - coeff.change_dim(localBasisFct->getNumber()); - vecDV->getLocalVector(smallElInfo->getElement(), coeff); - - // eval basisfunctions of DOFVector at coords of given basisFct - size_t nBasisFct = basisFct->getNumber(); -// mtl::dense_vector<typename GradientType<T>::type> helper(nBasisFct); - - const DimVec<WorldVector<double> > &grdLambda = smallElInfo->getGrdLambda(); - vec.change_dim(nBasisFct); - for (size_t i = 0; i < nBasisFct; i++) - localBasisFct->evalGrdUh(*basisFct->getCoords(i), grdLambda, coeff, vec[i]); //helper[i]); - -// for (size_t i = 0; i < num_rows(helper); i++) -// vec[i] = helper[i][comp]; - } - } - - value_type operator()(const int& iq) const { return vec[iq][comp]; } -// value_type operator()(const int& iq) const { return vec[iq]; } - }; - -} // end namespace result_of - -template<typename T> -result_of::GradientOf<DOFVector<T> > gradientOf(DOFVector<T>& vector) { return result_of::GradientOf<DOFVector<T> >(vector); } - -template<typename T> -result_of::GradientOf<DOFVector<T> > gradientOf(DOFVector<T>* vector) { return result_of::GradientOf<DOFVector<T> >(vector); } - -template<int I, typename T> -result_of::DerivativeOf<I, DOFVector<T> > derivativeOf(DOFVector<T>& vector) { return result_of::DerivativeOf<I, DOFVector<T> >(vector); } - -template<int I, typename T> -result_of::DerivativeOf<I, DOFVector<T> > derivativeOf(DOFVector<T>* vector) { return result_of::DerivativeOf<I, DOFVector<T> >(vector); } - -template<typename T> -result_of::DerivativeOf<-1, DOFVector<T> > derivativeOf(DOFVector<T>& vector, int I0) { return result_of::DerivativeOf<-1, DOFVector<T> >(vector, I0); } - -template<typename T> -result_of::DerivativeOf<-1, DOFVector<T> > derivativeOf(DOFVector<T>* vector, int I0) { return result_of::DerivativeOf<-1, DOFVector<T> >(vector, I0); } - -} // end namespace AMDiS - - -#endif \ No newline at end of file diff --git a/AMDiS/src/expressions/LazyExpression.h b/AMDiS/src/expressions/LazyExpression.h deleted file mode 100644 index c2f5a0c993d3bc40729ebb6251891b69589f7a89..0000000000000000000000000000000000000000 --- a/AMDiS/src/expressions/LazyExpression.h +++ /dev/null @@ -1,547 +0,0 @@ -/****************************************************************************** - * - * AMDiS - Adaptive multidimensional simulations - * - * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. - * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis - * - * Authors: - * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al. - * - * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * - * This file is part of AMDiS - * - * See also license.opensource.txt in the distribution. - * - ******************************************************************************/ - - - -/** \file LazyExpression.h */ - -#ifndef AMDIS_LAZY_EXPRESSION_H -#define AMDIS_LAZY_EXPRESSION_H - -#include "AMDiS_fwd.h" -#include "LazyOperatorTerm.h" -#include "ValueTypes.h" -#include "Functors.h" - -#include <boost/static_assert.hpp> - - -namespace AMDiS { - -struct NoType {}; - -struct FunctorBase -{ - typedef NoType value_type; - int getDegree() const { return 0; } - int getDegree(int d0) const { return 0; } - int getDegree(int d0, int d1) const { return 0; } - int getDegree(int d0, int d1, int d2) const { return 0; } - int getDegree(int d0, int d1, int d2, int d3) const { return 0; } - -protected: - virtual void helper() {}; -}; - - -namespace result_of { - - /// - template<typename Term1, typename Term2> - struct Add : public LazyOperatorTerm2<Term1, Term2> - { - typedef LazyOperatorTerm2<Term1, Term2> super; - typedef typename Term1::value_type value_type; - - Add(const Term1& term1_, const Term2& term2_) - : super(term1_, term2_) {} - - int getDegree() const - { - return std::max(super::term1.getDegree(), super::term2.getDegree()); - } - - inline value_type operator()(const int& iq) const { return super::term1(iq) + super::term2(iq); } - - template<typename Identifier> - inline value_type derivative(const int& iq) const - { - return derivative<Identifier>(iq, typename traits::DependsOn<Identifier, super>::type()); - } - - template<typename Identifier> - inline value_type derivative(const int& iq, boost::mpl::true_) const - { - return super::term1.derivative<Identifier>(iq) + super::term2.derivative<Identifier>(iq); - } - - template<typename Identifier> - inline value_type derivative(const int& iq, boost::mpl::false_) const - { - value_type result; - nullify(result); - return result; - } - }; - - - /// - template<typename Term1, typename Term2> - struct Mult : public LazyOperatorTerm2<Term1, Term2> - { - typedef LazyOperatorTerm2<Term1, Term2> super; - typedef typename ProductType<typename Term1::value_type, - typename Term2::value_type>::type value_type; - - Mult(const Term1& term1_, const Term2& term2_) - : super(term1_, term2_) {} - - int getDegree() const - { - return super::term1.getDegree() + super::term2.getDegree(); - } - - inline value_type operator()(const int& iq) const { return super::term1(iq) * super::term2(iq); } - - template<typename Identifier> - inline value_type derivative(const int& iq) const - { - return derivative<Identifier>(iq, typename traits::DependsOn<Identifier, super>::type()); - } - - template<typename Identifier> - inline value_type derivative(const int& iq, boost::mpl::true_) const - { - return super::term1.derivative<Identifier>(iq) * super::term2(iq) + super::term1(iq) * super::term2.derivative<Identifier>(iq); - } - - template<typename Identifier> - inline value_type derivative(const int& iq, boost::mpl::false_) const - { - value_type result; - nullify(result); - return result; - } - }; - - - /// - template<typename Term1, typename Term2> - struct Divide : public LazyOperatorTerm2<Term1, Term2> - { - typedef LazyOperatorTerm2<Term1, Term2> super; - typedef typename ProductType<typename Term1::value_type, - typename Term2::value_type>::type value_type; - - Divide(const Term1& term1_, const Term2& term2_) - : super(term1_, term2_) {} - - int getDegree() const - { - return super::term1.getDegree() + super::term2.getDegree(); // stimmt nicht ganz :) - } - - inline value_type operator()(const int& iq) const { return super::term1(iq) / super::term2(iq); } - - template<typename Identifier> - inline value_type derivative(const int& iq) const - { - return derivative<Identifier>(iq, typename traits::DependsOn<Identifier, super>::type()); - } - - template<typename Identifier> - inline value_type derivative(const int& iq, boost::mpl::true_) const - { - typename Term2::value_type term2_eval = super::term2(iq); - return (super::term1.derivative<Identifier>(iq) * term2_eval - super::term1(iq) * super::term2.derivative<Identifier>(iq)) / (sqr(term2_eval)); - } - - template<typename Identifier> - inline value_type derivative(const int& iq, boost::mpl::false_) const - { - value_type result; - nullify(result); - return result; - } - }; - - - /// - template<typename F, typename Term> - struct Function1 : public LazyOperatorTerm1<Term> - { - typedef LazyOperatorTerm1<Term> super; - BOOST_STATIC_ASSERT_MSG( (boost::is_base_of<FunctorBase, F>::value), "********** ERROR: Only functors with base FunctorBase allowed **********" ); - - typedef typename F::value_type value_type; - BOOST_STATIC_ASSERT_MSG( (!boost::is_same<value_type, NoType>::value), "********** ERROR: You have to define a value_type for your Functor **********" ); - - F f; - Function1(const F& f_, const Term& term_) : super(term_), f(f_) {} - - int getDegree() const - { - return f.getDegree(super::term.getDegree()); - } - - inline value_type operator()(const int& iq) const { return f(super::term(iq)); } - - template<typename Identifier> - inline value_type derivative(const int& iq) const - { - return derivative<Identifier>(iq, typename traits::DependsOn<Identifier, super>::type()); - } - - template<typename Identifier> - inline value_type derivative(const int& iq, boost::mpl::true_) const - { - return super::term.derivative<Identifier>(iq) * f.derivative<0>(super::term(iq)); - } - - template<typename Identifier> - inline value_type derivative(const int& iq, boost::mpl::false_) const - { - value_type result; - nullify(result); - return result; - } - }; - - - /// - template<typename F, typename Term1, typename Term2> - struct Function2 : public LazyOperatorTerm2<Term1, Term2> - { - typedef LazyOperatorTerm2<Term1, Term2> super; - BOOST_STATIC_ASSERT_MSG( (boost::is_base_of<FunctorBase, F>::value), "********** ERROR: Only functors with base FunctorBase allowed **********" ); - - typedef typename F::value_type value_type; - BOOST_STATIC_ASSERT_MSG( (!boost::is_same<value_type, NoType>::value), "********** ERROR: You have to define a value_type for your Functor **********" ); - - F f; - - Function2(const F& f_, const Term1& term1_, const Term2& term2_) : super(term1_, term2_), f(f_) {} - - int getDegree() const - { - return f.getDegree(super::term1.getDegree(), super::term2.getDegree()); - } - - inline value_type operator()(const int& iq) const { return f(super::term1(iq), super::term2(iq)); } - - template<typename Identifier> - inline value_type derivative(const int& iq) const - { - return derivative<Identifier>(iq, typename traits::DependsOn<Identifier, super>::type()); - } - - template<typename Identifier> - inline value_type derivative(const int& iq, boost::mpl::true_) const - { - return super::term1.derivative<Identifier>(iq) * f.derivative<0>(super::term1(iq), super::term2(iq)) - +super::term2.derivative<Identifier>(iq) * f.derivative<1>(super::term1(iq), super::term2(iq)); - } - - template<typename Identifier> - inline value_type derivative(const int& iq, boost::mpl::false_) const - { - value_type result; - nullify(result); - return result; - } - }; - - - /// - template<typename F, typename Term1, typename Term2, typename Term3> - struct Function3 : public LazyOperatorTerm3<Term1, Term2, Term3> - { - typedef LazyOperatorTerm3<Term1, Term2, Term3> super; - BOOST_STATIC_ASSERT_MSG( (boost::is_base_of<FunctorBase, F>::value), "********** ERROR: Only functors with base FunctorBase allowed **********" ); - - typedef typename F::value_type value_type; - BOOST_STATIC_ASSERT_MSG( (!boost::is_same<value_type, NoType>::value), "********** ERROR: You have to define a value_type for your Functor **********" ); - - F f; - - Function3(const F& f_, const Term1& term1_, const Term2& term2_, const Term3& term3_) - : super(term1_, term2_, term3_), f(f_) {} - - int getDegree() const - { - return f.getDegree(super::term1.getDegree(), super::term2.getDegree(), super::term3.getDegree()); - } - - inline value_type operator()(const int& iq) const { return f(super::term1(iq), super::term2(iq), super::term3(iq)); } - - template<typename Identifier> - inline value_type derivative(const int& iq) const - { - return derivative<Identifier>(iq, typename traits::DependsOn<Identifier, super>::type()); - } - - template<typename Identifier> - inline value_type derivative(const int& iq, boost::mpl::true_) const - { - return super::term1.derivative<Identifier>(iq) * f.derivative<0>(super::term1(iq), super::term2(iq), super::term3(iq)) - +super::term2.derivative<Identifier>(iq) * f.derivative<1>(super::term1(iq), super::term2(iq), super::term3(iq)) - +super::term3.derivative<Identifier>(iq) * f.derivative<2>(super::term1(iq), super::term2(iq), super::term3(iq)); - } - - template<typename Identifier> - inline value_type derivative(const int& iq, boost::mpl::false_) const - { - value_type result; - nullify(result); - return result; - } - }; - - template<typename TOut, typename TIn> - struct Wrapper : public FunctorBase - { - typedef TOut value_type; - Wrapper(AbstractFunction<TOut, TIn>* fct_) : fct(fct_) {} - int getDegree(int degree) const { return fct->getDegree(); } - - TOut operator()(const TIn& x) const - { - return (*fct)(x); - } - - protected: - AbstractFunction<TOut, TIn>* fct; - }; -} - - -namespace traits -{ - - template<typename Identifier, typename Term1, typename Term2> - struct DependsOn<Identifier, AMDiS::result_of::Add<Term1, Term2> > - : public DependsOn<Identifier, LazyOperatorTerm2<Term1, Term2> >::type {}; - - template<typename Identifier, typename Term1, typename Term2> - struct DependsOn<Identifier, AMDiS::result_of::Mult<Term1, Term2> > - : public DependsOn<Identifier, LazyOperatorTerm2<Term1, Term2> >::type {}; - - template<typename Identifier, typename Term1, typename Term2> - struct DependsOn<Identifier, AMDiS::result_of::Divide<Term1, Term2> > - : public DependsOn<Identifier, LazyOperatorTerm2<Term1, Term2> >::type {}; - - - template<typename Identifier, typename F, typename Term> - struct DependsOn<Identifier, AMDiS::result_of::Function1<F, Term> > - : public boost::mpl::bool_< DependsOn<Identifier, Term>::type::value > {}; - - template<typename Identifier, typename F, typename Term1, typename Term2> - struct DependsOn<Identifier, AMDiS::result_of::Function2<F, Term1, Term2> > - : public DependsOn<Identifier, LazyOperatorTerm2<Term1, Term2> >::type {}; - - template<typename Identifier, typename F, typename Term1, typename Term2, typename Term3> - struct DependsOn<Identifier, AMDiS::result_of::Function3<F, Term1, Term2, Term3> > - : public DependsOn<Identifier, LazyOperatorTerm3<Term1, Term2, Term3> >::type {}; -} - - -// add two terms -template<typename Term1, typename Term2> -inline typename boost::enable_if< - typename boost::mpl::and_<typename boost::is_base_of<LazyOperatorTermBase, Term1>::type, - typename boost::is_base_of<LazyOperatorTermBase, Term2>::type>::type, - result_of::Add<Term1, Term2> >::type -add(const Term1& t1, const Term2& t2) { return result_of::Add<Term1, Term2>(t1, t2); } - -template<typename Term1, typename Term2> -inline typename boost::enable_if< - typename boost::mpl::and_<typename boost::is_base_of<LazyOperatorTermBase, Term1>::type, - typename boost::is_base_of<LazyOperatorTermBase, Term2>::type>::type, - result_of::Add<Term1, Term2> >::type -operator+(const Term1& t1, const Term2& t2) { return result_of::Add<Term1, Term2>(t1, t2); } - -template<typename T, typename Term> -inline typename boost::enable_if< - typename boost::mpl::and_<typename boost::is_fundamental<T>::type, - typename boost::is_base_of<LazyOperatorTermBase, Term>::type>::type, - result_of::Add<result_of::Const<T>, Term> >::type -operator+(const T& t1, const Term& t2) { return result_of::Add<result_of::Const<T>, Term>(constant(t1), t2); } - -template<typename Term, typename T> -inline typename boost::enable_if< - typename boost::mpl::and_<typename boost::is_fundamental<T>::type, - typename boost::is_base_of<LazyOperatorTermBase, Term>::type>::type, - result_of::Add<Term, result_of::Const<T> > >::type -operator+(const Term& t1, const T& t2) { return result_of::Add<Term, result_of::Const<T> >(t1, constant(t2)); } - - -// subtract two terms -template<typename Term1, typename Term2> -inline typename boost::enable_if< - typename boost::mpl::and_<typename boost::is_base_of<LazyOperatorTermBase, Term1>::type, - typename boost::is_base_of<LazyOperatorTermBase, Term2>::type>::type, - result_of::Add<Term1, result_of::Mult<result_of::Const<double>, Term2> > >::type -subtract(const Term1& t1, const Term2& t2) -{ - return result_of::Add<Term1, result_of::Mult<result_of::Const<double>, Term2> > - (t1, result_of::Mult<result_of::Const<double>, Term2> - (result_of::Const<double>(-1.0), t2) ); -} - -template<typename Term1, typename Term2> -inline typename boost::enable_if< - typename boost::mpl::and_<typename boost::is_base_of<LazyOperatorTermBase, Term1>::type, - typename boost::is_base_of<LazyOperatorTermBase, Term2>::type>::type, - result_of::Add<Term1, result_of::Mult<result_of::Const<double>, Term2> > >::type -operator-(const Term1& t1, const Term2& t2) { return subtract(t1, t2); } - -template<typename T, typename Term> -inline typename boost::enable_if< - typename boost::mpl::and_<typename boost::is_fundamental<T>::type, - typename boost::is_base_of<LazyOperatorTermBase, Term>::type>::type, - result_of::Add<result_of::Const<T>, result_of::Mult<result_of::Const<double>, Term> > >::type -operator-(const T& t1, const Term& t2) { return subtract(constant(t1), t2); } - -template<typename Term, typename T> -inline typename boost::enable_if< - typename boost::mpl::and_<typename boost::is_fundamental<T>::type, - typename boost::is_base_of<LazyOperatorTermBase, Term>::type>::type, - result_of::Add<Term, result_of::Const<T> > >::type -operator-(const Term& t1, const T& t2) { return result_of::Add<Term, result_of::Const<T> >(t1, constant(-t2)); } - - -// multiply two terms -template<typename Term1, typename Term2> -inline typename boost::enable_if< - typename boost::mpl::and_<typename boost::is_base_of<LazyOperatorTermBase, Term1>::type, - typename boost::is_base_of<LazyOperatorTermBase, Term2>::type>::type, - result_of::Mult<Term1, Term2> >::type -mult(const Term1& t1, const Term2& t2) { return result_of::Mult<Term1, Term2>(t1, t2); } - -template<typename Term1, typename Term2> -inline typename boost::enable_if< - typename boost::mpl::and_<typename boost::is_base_of<LazyOperatorTermBase, Term1>::type, - typename boost::is_base_of<LazyOperatorTermBase, Term2>::type>::type, - result_of::Mult<Term1, Term2> >::type -operator*(const Term1& t1, const Term2& t2) { return result_of::Mult<Term1, Term2>(t1, t2); } - -template<typename T, typename Term> -inline typename boost::enable_if< - typename boost::mpl::and_<typename boost::is_fundamental<T>::type, - typename boost::is_base_of<LazyOperatorTermBase, Term>::type>::type, - result_of::Mult<result_of::Const<T>, Term> >::type -operator*(const T& t1, const Term& t2) { return result_of::Mult<result_of::Const<T>, Term>(constant(t1), t2); } - -template<typename Term, typename T> -inline typename boost::enable_if< - typename boost::mpl::and_<typename boost::is_fundamental<T>::type, - typename boost::is_base_of<LazyOperatorTermBase, Term>::type>::type, - result_of::Mult<Term, result_of::Const<T> > >::type -operator*(const Term& t1, const T& t2) { return result_of::Mult<Term, result_of::Const<T> >(t1, constant(t2)); } - - -// divide two terms -template<typename Term1, typename Term2> -inline typename boost::enable_if< - typename boost::mpl::and_<typename boost::is_base_of<LazyOperatorTermBase, Term1>::type, - typename boost::is_base_of<LazyOperatorTermBase, Term2>::type>::type, - result_of::Divide<Term1, Term2> >::type -divide(const Term1& t1, const Term2& t2) { return result_of::Divide<Term1, Term2>(t1, t2); } - -template<typename Term1, typename Term2> -inline typename boost::enable_if< - typename boost::mpl::and_<typename boost::is_base_of<LazyOperatorTermBase, Term1>::type, - typename boost::is_base_of<LazyOperatorTermBase, Term2>::type>::type, - result_of::Divide<Term1, Term2> >::type -operator/(const Term1& t1, const Term2& t2) { return divide(t1, t2); } - -template<typename T, typename Term> -inline typename boost::enable_if< - typename boost::mpl::and_<typename boost::is_fundamental<T>::type, - typename boost::is_base_of<LazyOperatorTermBase, Term>::type>::type, - result_of::Divide<result_of::Const<T>, Term> >::type -operator/(const T& t1, const Term& t2) { return divide(constant(t1), t2); } - -template<typename Term, typename T> -inline typename boost::enable_if< - typename boost::mpl::and_<typename boost::is_fundamental<T>::type, - typename boost::is_base_of<LazyOperatorTermBase, Term>::type>::type, - result_of::Divide<Term, result_of::Const<T> > >::type -operator/(const Term& t1, const T& t2) { return divide(t1, constant(t2)); } - - -// _____________________________________________________________________________ - -// call a function with 1 argument -template<typename F, typename Term> -inline typename boost::enable_if< - typename boost::is_base_of<LazyOperatorTermBase, Term>::type, - result_of::Function1<F,Term> >::type -function_(const F& f, const Term& t) { return result_of::Function1<F,Term>(f,t); } - -template<typename F, typename Term> -inline typename boost::enable_if< - typename boost::is_base_of<LazyOperatorTermBase, Term>::type, - result_of::Function1<F,Term> >::type -function_(const Term& t) { return result_of::Function1<F,Term>(F(),t); } - - -// call a function with 2 arguments -template<typename F, typename Term1, typename Term2> -inline typename boost::enable_if< - typename boost::mpl::and_<typename boost::is_base_of<LazyOperatorTermBase, Term1>::type, - typename boost::is_base_of<LazyOperatorTermBase, Term2>::type>::type, - result_of::Function2<F, Term1, Term2> >::type -function_(const F& f, const Term1& t1, const Term2& t2) { return result_of::Function2<F,Term1,Term2>(f,t1,t2); } - -template<typename F, typename Term1, typename Term2> -inline typename boost::enable_if< - typename boost::mpl::and_<typename boost::is_base_of<LazyOperatorTermBase, Term1>::type, - typename boost::is_base_of<LazyOperatorTermBase, Term2>::type>::type, - result_of::Function2<F, Term1, Term2> >::type -function_(const Term1& t1, const Term2& t2) { return result_of::Function2<F,Term1,Term2>(F(),t1,t2); } - - -// call a function with 3 arguments -template<typename F, typename Term1, typename Term2, typename Term3> -inline -typename boost::enable_if< - typename boost::mpl::and_< - typename boost::mpl::and_< - typename boost::is_base_of<LazyOperatorTermBase, Term1>::type, - typename boost::is_base_of<LazyOperatorTermBase, Term2>::type - >::type, - typename boost::is_base_of<LazyOperatorTermBase, Term3>::type - >::type, - result_of::Function3<F, Term1, Term2, Term3> - >::type -function_(const F& f, const Term1& t1, const Term2& t2, const Term3& t3) { return result_of::Function3<F,Term1,Term2,Term3>(f,t1,t2,t3); } - -template<typename F, typename Term1, typename Term2, typename Term3> -inline -typename boost::enable_if< - typename boost::mpl::and_< - typename boost::mpl::and_< - typename boost::is_base_of<LazyOperatorTermBase, Term1>::type, - typename boost::is_base_of<LazyOperatorTermBase, Term2>::type - >::type, - typename boost::is_base_of<LazyOperatorTermBase, Term3>::type - >::type, - result_of::Function3<F, Term1, Term2, Term3> - >::type -function_(const Term1& t1, const Term2& t2, const Term3& t3) { return result_of::Function3<F,Term1,Term2,Term3>(F(),t1,t2,t3); } - - -template<typename TOut, typename TIn> -inline result_of::Wrapper<TOut,TIn> wrap(AbstractFunction<TOut, TIn>* fct) { return result_of::Wrapper<TOut,TIn>(fct); } - -} // end namespace AMDiS - -#endif \ No newline at end of file diff --git a/AMDiS/src/expressions/LazyOperatorTerm.h b/AMDiS/src/expressions/LazyOperatorTerm.h index 16e9ef567d4cef83804eaa1d04100d4c950adbc2..2de7dbbcfb0d21c32a97d362df0427f67a06dc14 100644 --- a/AMDiS/src/expressions/LazyOperatorTerm.h +++ b/AMDiS/src/expressions/LazyOperatorTerm.h @@ -26,147 +26,140 @@ #define AMDIS_LAZY_OPERATOR_TERM_H #include "AMDiS_fwd.h" -#include <boost/static_assert.hpp> - -namespace AMDiS { - -struct LazyOperatorTermBase -{ -protected: - virtual void helper() {} -}; - -template<typename Term> -struct LazyOperatorTerm1 : public LazyOperatorTermBase -{ - Term term; - LazyOperatorTerm1(const Term& term_) : term(term_) {} - - template<typename List> - inline void insertFeSpaces(List& feSpaces) - { - term.insertFeSpaces(feSpaces); - } - - template<typename OT> - inline void initElement(OT* ot, const ElInfo* elInfo, - SubAssembler* subAssembler, Quadrature *quad, - const BasisFunction *basisFct = NULL) - { - term.initElement(ot, elInfo, subAssembler, quad, basisFct); - } +#include "Traits.h" - template<typename OT> - inline void initElement(OT* ot, const ElInfo* smallElInfo, const ElInfo* largeElInfo, - SubAssembler* subAssembler, Quadrature *quad, - const BasisFunction *basisFct = NULL) - { - term.initElement(ot, smallElInfo, largeElInfo, subAssembler, quad, basisFct); - } - - inline double operator()(const int& iq) const; -}; - -template<typename Term1, typename Term2> -struct LazyOperatorTerm2 : public LazyOperatorTermBase -{ - Term1 term1; - Term2 term2; - LazyOperatorTerm2(const Term1& term1_, const Term2& term2_) : term1(term1_), term2(term2_) {} - - template<typename List> - inline void insertFeSpaces(List& feSpaces) - { - term1.insertFeSpaces(feSpaces); - term2.insertFeSpaces(feSpaces); - } - - template<typename OT> - inline void initElement(OT* ot, const ElInfo* elInfo, - SubAssembler* subAssembler, Quadrature *quad, - const BasisFunction *basisFct = NULL) - { - term1.initElement(ot, elInfo, subAssembler, quad, basisFct); - term2.initElement(ot, elInfo, subAssembler, quad, basisFct); - } - - template<typename OT> - inline void initElement(OT* ot, const ElInfo* smallElInfo, const ElInfo* largeElInfo, - SubAssembler* subAssembler, Quadrature *quad, - const BasisFunction *basisFct = NULL) +namespace AMDiS +{ + struct LazyOperatorTermBase { - term1.initElement(ot, smallElInfo, largeElInfo, subAssembler, quad, basisFct); - term2.initElement(ot, smallElInfo, largeElInfo, subAssembler, quad, basisFct); - } - - double operator()(const int& iq) const; -}; - -template<typename Term1, typename Term2, typename Term3> -struct LazyOperatorTerm3 : public LazyOperatorTermBase -{ - Term1 term1; - Term2 term2; - Term3 term3; - LazyOperatorTerm3(const Term1& term1_, const Term2& term2_, const Term3& term3_) - : term1(term1_), term2(term2_), term3(term3_) {} - - template<typename List> - inline void insertFeSpaces(List& feSpaces) + template<typename List> + void insertFeSpaces(List& feSpaces) const {} + + int getDegree() const { return 0; } + + template<typename OT> + void initElement(OT* ot, const ElInfo* elInfo, + SubAssembler* subAssembler, Quadrature *quad, + const BasisFunction *basisFct = NULL) {} + + template<typename OT> + void initElement(OT* ot, const ElInfo* smallElInfo, const ElInfo* largeElInfo, + SubAssembler* subAssembler, Quadrature *quad, + const BasisFunction *basisFct = NULL) {} + protected: + virtual void helper() {} + }; + + + template<typename Term> + struct LazyOperatorTerm1 : public LazyOperatorTermBase { - term1.insertFeSpaces(feSpaces); - term2.insertFeSpaces(feSpaces); - term3.insertFeSpaces(feSpaces); - } - - template<typename OT> - inline void initElement(OT* ot, const ElInfo* elInfo, - SubAssembler* subAssembler, Quadrature *quad, - const BasisFunction *basisFct = NULL) + Term term; + LazyOperatorTerm1(const Term& term_) : term(term_) {} + + template<typename List> + inline void insertFeSpaces(List& feSpaces) + { + term.insertFeSpaces(feSpaces); + } + + template<typename OT> + inline void initElement(OT* ot, const ElInfo* elInfo, + SubAssembler* subAssembler, Quadrature *quad, + const BasisFunction *basisFct = NULL) + { + term.initElement(ot, elInfo, subAssembler, quad, basisFct); + } + + template<typename OT> + inline void initElement(OT* ot, const ElInfo* smallElInfo, const ElInfo* largeElInfo, + SubAssembler* subAssembler, Quadrature *quad, + const BasisFunction *basisFct = NULL) + { + term.initElement(ot, smallElInfo, largeElInfo, subAssembler, quad, basisFct); + } + + inline double operator()(const int& iq) const; + }; + + + template<typename Term1, typename Term2> + struct LazyOperatorTerm2 : public LazyOperatorTermBase { - term1.initElement(ot, elInfo, subAssembler, quad, basisFct); - term2.initElement(ot, elInfo, subAssembler, quad, basisFct); - term3.initElement(ot, elInfo, subAssembler, quad, basisFct); - } - - template<typename OT> - inline void initElement(OT* ot, const ElInfo* smallElInfo, const ElInfo* largeElInfo, - SubAssembler* subAssembler, Quadrature *quad, - const BasisFunction *basisFct = NULL) + Term1 term1; + Term2 term2; + LazyOperatorTerm2(const Term1& term1_, const Term2& term2_) : term1(term1_), term2(term2_) {} + + template<typename List> + inline void insertFeSpaces(List& feSpaces) + { + term1.insertFeSpaces(feSpaces); + term2.insertFeSpaces(feSpaces); + } + + template<typename OT> + inline void initElement(OT* ot, const ElInfo* elInfo, + SubAssembler* subAssembler, Quadrature *quad, + const BasisFunction *basisFct = NULL) + { + term1.initElement(ot, elInfo, subAssembler, quad, basisFct); + term2.initElement(ot, elInfo, subAssembler, quad, basisFct); + } + + template<typename OT> + inline void initElement(OT* ot, const ElInfo* smallElInfo, const ElInfo* largeElInfo, + SubAssembler* subAssembler, Quadrature *quad, + const BasisFunction *basisFct = NULL) + { + term1.initElement(ot, smallElInfo, largeElInfo, subAssembler, quad, basisFct); + term2.initElement(ot, smallElInfo, largeElInfo, subAssembler, quad, basisFct); + } + + double operator()(const int& iq) const; + }; + + + template<typename Term1, typename Term2, typename Term3> + struct LazyOperatorTerm3 : public LazyOperatorTermBase { - term1.initElement(ot, smallElInfo, largeElInfo, subAssembler, quad, basisFct); - term2.initElement(ot, smallElInfo, largeElInfo, subAssembler, quad, basisFct); - term3.initElement(ot, smallElInfo, largeElInfo, subAssembler, quad, basisFct); - } - - inline double operator()(const int& iq) const; -}; - - -namespace traits -{ - template<typename Identifier, typename T> - struct DependsOn : public boost::mpl::bool_<false> {}; - - template<typename Identifier, typename Term> - struct DependsOn<Identifier, LazyOperatorTerm1<Term> > - : public boost::mpl::bool_< DependsOn<Identifier, Term>::type::value > {}; - - template<typename Identifier, typename Term1, typename Term2> - struct DependsOn<Identifier, LazyOperatorTerm2<Term1, Term2> > - : public boost::mpl::bool_< boost::mpl::or_< - typename DependsOn<Identifier, Term1>::type, - typename DependsOn<Identifier, Term2>::type>::type::value > {}; - - template<typename Identifier, typename Term1, typename Term2, typename Term3> - struct DependsOn<Identifier, LazyOperatorTerm3<Term1, Term2, Term3> > - : public boost::mpl::bool_< boost::mpl::or_< - typename DependsOn<Identifier, Term1>::type, - typename DependsOn<Identifier, Term2>::type, - typename DependsOn<Identifier, Term3>::type>::type::value > {}; -} + Term1 term1; + Term2 term2; + Term3 term3; + LazyOperatorTerm3(const Term1& term1_, const Term2& term2_, const Term3& term3_) + : term1(term1_), term2(term2_), term3(term3_) {} + + template<typename List> + inline void insertFeSpaces(List& feSpaces) + { + term1.insertFeSpaces(feSpaces); + term2.insertFeSpaces(feSpaces); + term3.insertFeSpaces(feSpaces); + } + + template<typename OT> + inline void initElement(OT* ot, const ElInfo* elInfo, + SubAssembler* subAssembler, Quadrature *quad, + const BasisFunction *basisFct = NULL) + { + term1.initElement(ot, elInfo, subAssembler, quad, basisFct); + term2.initElement(ot, elInfo, subAssembler, quad, basisFct); + term3.initElement(ot, elInfo, subAssembler, quad, basisFct); + } + + template<typename OT> + inline void initElement(OT* ot, const ElInfo* smallElInfo, const ElInfo* largeElInfo, + SubAssembler* subAssembler, Quadrature *quad, + const BasisFunction *basisFct = NULL) + { + term1.initElement(ot, smallElInfo, largeElInfo, subAssembler, quad, basisFct); + term2.initElement(ot, smallElInfo, largeElInfo, subAssembler, quad, basisFct); + term3.initElement(ot, smallElInfo, largeElInfo, subAssembler, quad, basisFct); + } + + inline double operator()(const int& iq) const; + }; } // end namespace AMDiS -#endif \ No newline at end of file +#endif // AMDIS_LAZY_OPERATOR_TERM_H diff --git a/AMDiS/src/expressions/ValueOf.h b/AMDiS/src/expressions/ValueOf.h deleted file mode 100644 index 3974d4fb4d64a87f36914d814af5548389927d89..0000000000000000000000000000000000000000 --- a/AMDiS/src/expressions/ValueOf.h +++ /dev/null @@ -1,367 +0,0 @@ -/****************************************************************************** - * - * AMDiS - Adaptive multidimensional simulations - * - * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. - * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis - * - * Authors: - * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al. - * - * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * - * This file is part of AMDiS - * - * See also license.opensource.txt in the distribution. - * - ******************************************************************************/ - - - -/** \file GenericOperatorTerm.h */ - -#ifndef AMDIS_VALUE_OF_H -#define AMDIS_VALUE_OF_H - -#include "AMDiS_fwd.h" -#include "LazyOperatorTerm.h" -#include "ValueTypes.h" -#include "DOFVector.h" - -#include <boost/static_assert.hpp> -#include <boost/mpl/bool.hpp> - - -namespace AMDiS { - -struct _unknown {}; - -namespace result_of { - - - template<typename Vector, typename Name> - struct ValueOf : public LazyOperatorTermBase {}; - - template<typename T, typename Name> - struct ValueOf<DOFVector<T>, Name> : public LazyOperatorTermBase - { - typedef T value_type; - - DOFVector<T>* vecDV; - mutable mtl::dense_vector<T> vec; - mutable mtl::dense_vector<T> coeff; - - ValueOf(DOFVector<T>& vector) : vecDV(&vector) {} - ValueOf(DOFVector<T>* vector) : vecDV(vector) {} - - template<typename List> - inline void insertFeSpaces(List& feSpaces) const - { - feSpaces.insert(vecDV->getFeSpace()); - } - - inline int getDegree() const - { - return vecDV->getFeSpace()->getBasisFcts()->getDegree(); - } - - template<typename OT> - inline void initElement(OT* ot, const ElInfo* elInfo, - SubAssembler* subAssembler, Quadrature *quad, - const BasisFunction *basisFct = NULL) - { - if (ot && subAssembler) - ot->getVectorAtQPs(vecDV, elInfo, subAssembler, quad, vec); - else if (quad) - vecDV->getVecAtQPs(elInfo, quad, NULL, vec); - else if (basisFct) { - const BasisFunction *localBasisFct = vecDV->getFeSpace()->getBasisFcts(); - - // get coefficients of DOFVector - coeff.change_dim(localBasisFct->getNumber()); - vecDV->getLocalVector(elInfo->getElement(), coeff); - - // eval basisfunctions of DOFVector at coords of given basisFct - size_t nBasisFct = basisFct->getNumber(); - vec.change_dim(nBasisFct); - for (size_t i = 0; i < nBasisFct; i++) - vec[i] = localBasisFct->evalUh(*basisFct->getCoords(i), coeff); - } - } - - - template<typename OT> - inline void initElement(OT* ot, const ElInfo* smallElInfo, const ElInfo* largeElInfo, - SubAssembler* subAssembler, Quadrature *quad, - const BasisFunction *basisFct = NULL) - { - if (ot && subAssembler) - ot->getVectorAtQPs(vecDV, smallElInfo, largeElInfo, subAssembler, quad, vec); - else if (quad) - vecDV->getVecAtQPs(smallElInfo, largeElInfo, quad, NULL, vec); - else if (basisFct) { - const BasisFunction *localBasisFct = vecDV->getFeSpace()->getBasisFcts(); - - // get coefficients of DOFVector - coeff.change_dim(localBasisFct->getNumber()); - vecDV->getLocalVector(smallElInfo->getElement(), coeff); - - // eval basisfunctions of DOFVector at coords of given basisFct - size_t nBasisFct = basisFct->getNumber(); - vec.change_dim(nBasisFct); - for (size_t i = 0; i < nBasisFct; i++) - vec[i] = localBasisFct->evalUh(*basisFct->getCoords(i), coeff); - } - } - - inline value_type operator()(const int& iq) const { return vec[iq]; } - - template<typename Identifier> - inline value_type derivative(const int& iq) const { return ( boost::is_same<Identifier, Name>::type::value ? 1.0 : 0.0 ); } - }; - - - template<template<class> class Vector, typename T, typename Name> - struct ValueOf<Vector<DOFVector<T>*>, Name> : public LazyOperatorTermBase - { - typedef Vector<T> value_type; - - Vector<DOFVector<T>*> vecDV; - mutable mtl::dense_vector<value_type> vec; - mutable Vector<mtl::dense_vector<T> > coeff; - - ValueOf(Vector<DOFVector<T>*>& vector) : vecDV(vector) - { - resize(coeff, num_rows(vecDV)); - } - - template<typename List> - inline void insertFeSpaces(List& feSpaces) const - { - for (size_t i = 0; i < num_rows(vecDV); i++) - feSpaces.insert(vecDV[i]->getFeSpace()); - } - - inline int getDegree() const - { - return vecDV[0]->getFeSpace()->getBasisFcts()->getDegree(); - } - - template<typename OT> - inline void initElement(OT* ot, const ElInfo* elInfo, - SubAssembler* subAssembler, Quadrature *quad, - const BasisFunction *basisFct = NULL) - { - Vector<mtl::dense_vector<T> > helper; resize(helper, num_rows(vecDV)); - for (size_t i = 0; i < num_rows(vecDV); i++) { - if (ot && subAssembler) - ot->getVectorAtQPs(vecDV[i], elInfo, subAssembler, quad, helper[i]); - else if (quad) - vecDV[i]->getVecAtQPs(elInfo, quad, NULL, helper[i]); - else if (basisFct) { - const BasisFunction *localBasisFct = vecDV[i]->getFeSpace()->getBasisFcts(); - - // get coefficients of DOFVector - coeff[i].change_dim(localBasisFct->getNumber()); - vecDV[i]->getLocalVector(elInfo->getElement(), coeff[i]); - - // eval basisfunctions of DOFVector at coords of given basisFct - size_t nBasisFct = basisFct->getNumber(); - helper[i].change_dim(nBasisFct); - for (size_t j = 0; j < nBasisFct; j++) - helper[i][j] = localBasisFct->evalUh(*basisFct->getCoords(j), coeff[i]); - } - } - vec.change_dim(num_rows(helper[0])); - for (size_t iq = 0; iq < num_rows(helper[0]); iq++) { - value_type tmp; resize(tmp, num_rows(vecDV)); - for (size_t i = 0; i < num_rows(vecDV); i++) - tmp[i] = helper[i][iq]; - vec[iq] = tmp; - } - } - - - template<typename OT> - inline void initElement(OT* ot, const ElInfo* smallElInfo, const ElInfo* largeElInfo, - SubAssembler* subAssembler, Quadrature *quad, - const BasisFunction *basisFct = NULL) - { - Vector<mtl::dense_vector<T> > helper; resize(helper, num_rows(vecDV)); - for (size_t i = 0; i < num_rows(vecDV); i++) { - if (ot && subAssembler) - ot->getVectorAtQPs(vecDV[i], smallElInfo, subAssembler, quad, helper[i]); - else if (quad) - vecDV[i]->getVecAtQPs(smallElInfo, quad, NULL, helper[i]); - else if (basisFct) { - const BasisFunction *localBasisFct = vecDV[i]->getFeSpace()->getBasisFcts(); - - // get coefficients of DOFVector - coeff[i].change_dim(localBasisFct->getNumber()); - vecDV[i]->getLocalVector(smallElInfo->getElement(), coeff[i]); - - // eval basisfunctions of DOFVector at coords of given basisFct - size_t nBasisFct = basisFct->getNumber(); - helper[i].change_dim(nBasisFct); - for (size_t j = 0; j < nBasisFct; j++) - helper[i][j] = localBasisFct->evalUh(*basisFct->getCoords(j), coeff[i]); - } - } - vec.change_dim(num_rows(helper[0])); - for (size_t iq = 0; iq < num_rows(helper[0]); iq++) { - value_type tmp; resize(tmp, num_rows(vecDV)); - for (size_t i = 0; i < num_rows(vecDV); i++) - tmp[i] = helper[i][iq]; - vec[iq] = tmp; - } - } - - inline value_type operator()(const int& iq) const { return vec[iq]; } - - template<typename Identifier> - inline value_type derivative(const int& iq) const { - value_type result; result.set(1.0); - if (boost::is_same<Identifier, Name>::type::value) - result.set(1.0); - else - nullify(result); - return result; - } - }; - - - template<typename Vector> - struct ComponentOf : public LazyOperatorTermBase {}; - - template<template<class> class Vector, typename T> - struct ComponentOf<DOFVector<Vector<T> > > : public LazyOperatorTermBase - { - typedef T value_type; - - DOFVector<Vector<T> >* vecDV; - mutable mtl::dense_vector<Vector<T> > vec; - mutable mtl::dense_vector<Vector<T> > coeff; - int I; - - ComponentOf(DOFVector<Vector<T> >& vector, int I_) : vecDV(&vector), I(I_) {} - ComponentOf(DOFVector<Vector<T> >* vector, int I_) : vecDV(vector), I(I_) {} - - template<typename List> - inline void insertFeSpaces(List& feSpaces) const - { - feSpaces.insert(vecDV->getFeSpace()); - } - - inline int getDegree() const - { - return vecDV->getFeSpace()->getBasisFcts()->getDegree(); - } - - template<typename OT> - inline void initElement(OT* ot, const ElInfo* elInfo, - SubAssembler* subAssembler, Quadrature *quad, - const BasisFunction *basisFct = NULL) - { - if (ot && subAssembler) - ot->getVectorAtQPs(vecDV, elInfo, subAssembler, quad, vec); - else if (quad) - vecDV->getVecAtQPs(elInfo, quad, NULL, vec); - else if (basisFct) { - const BasisFunction *localBasisFct = vecDV->getFeSpace()->getBasisFcts(); - - // get coefficients of DOFVector - coeff.change_dim(localBasisFct->getNumber()); - vecDV->getLocalVector(elInfo->getElement(), coeff); - - // eval basisfunctions of DOFVector at coords of given basisFct - size_t nBasisFct = basisFct->getNumber(); - vec.change_dim(nBasisFct); - for (size_t i = 0; i < nBasisFct; i++) - vec[i] = localBasisFct->evalUh(*basisFct->getCoords(i), coeff); - } - } - - - template<typename OT> - inline void initElement(OT* ot, const ElInfo* smallElInfo, const ElInfo* largeElInfo, - SubAssembler* subAssembler, Quadrature *quad, - const BasisFunction *basisFct = NULL) - { - if (ot && subAssembler) - ot->getVectorAtQPs(vecDV, smallElInfo, largeElInfo, subAssembler, quad, vec); - else if (quad) - vecDV->getVecAtQPs(smallElInfo, largeElInfo, quad, NULL, vec); - else if (basisFct) { - const BasisFunction *localBasisFct = vecDV->getFeSpace()->getBasisFcts(); - - // get coefficients of DOFVector - coeff.change_dim(localBasisFct->getNumber()); - vecDV->getLocalVector(smallElInfo->getElement(), coeff); - - // eval basisfunctions of DOFVector at coords of given basisFct - size_t nBasisFct = basisFct->getNumber(); - vec.change_dim(nBasisFct); - for (size_t i = 0; i < nBasisFct; i++) - vec[i] = localBasisFct->evalUh(*basisFct->getCoords(i), coeff); - } - } - - inline value_type operator()(const int& iq) const { return vec[iq][I]; } - - template<typename Identifier> - inline value_type derivative(const int& iq) const { return 0.0; } - }; - - -} // end namespace result_of - -namespace traits { - - template<typename Identifier, typename T, typename Name> - struct DependsOn<Identifier, AMDiS::result_of::ValueOf<T, Name> > : public boost::is_same<Identifier, Name> {}; - -} - - -#if __cplusplus > 199711L -template<typename Name = _unknown, typename T> -result_of::ValueOf<DOFVector<T>, Name > valueOf(DOFVector<T>& vector) { return result_of::ValueOf<DOFVector<T>, Name >(vector); } - -template<typename Name = _unknown, typename T> -result_of::ValueOf<DOFVector<T>, Name > valueOf(DOFVector<T>* vector) { return result_of::ValueOf<DOFVector<T>, Name >(vector); } - -template<typename Name = _unknown, template<class> class Vector, typename T> -result_of::ValueOf<Vector<DOFVector<T>*>, Name > valueOf(Vector<DOFVector<T>*> &vector) { return result_of::ValueOf<Vector<DOFVector<T>*>, Name >(vector); } -#else -// with Name -template<typename Name, typename T> -result_of::ValueOf<DOFVector<T>, Name > valueOf(DOFVector<T>& vector) { return result_of::ValueOf<DOFVector<T>, Name >(vector); } - -template<typename Name, typename T> -result_of::ValueOf<DOFVector<T>, Name > valueOf(DOFVector<T>* vector) { return result_of::ValueOf<DOFVector<T>, Name >(vector); } - -template<typename Name, template<class> class Vector, typename T> -result_of::ValueOf<Vector<DOFVector<T>*>, Name > valueOf(Vector<DOFVector<T>*> &vector) { return result_of::ValueOf<Vector<DOFVector<T>*>, Name >(vector); } - -// without Name -template<typename T> -result_of::ValueOf<DOFVector<T>, _unknown > valueOf(DOFVector<T>& vector) { return result_of::ValueOf<DOFVector<T>, _unknown >(vector); } - -template<typename T> -result_of::ValueOf<DOFVector<T>, _unknown > valueOf(DOFVector<T>* vector) { return result_of::ValueOf<DOFVector<T>, _unknown >(vector); } - -template<template<class> class Vector, typename T> -result_of::ValueOf<Vector<DOFVector<T>*>, _unknown > valueOf(Vector<DOFVector<T>*> &vector) { return result_of::ValueOf<Vector<DOFVector<T>*>, _unknown >(vector); } -#endif - -template<template<class> class Vector, typename T> -result_of::ComponentOf<DOFVector<Vector<T> > > componentOf(DOFVector<Vector<T> >& vector, int I) { return result_of::ComponentOf<DOFVector<Vector<T> > >(vector, I); } - -template<template<class> class Vector, typename T> -result_of::ComponentOf<DOFVector<Vector<T> > > componentOf(DOFVector<Vector<T> >* vector, int I) { return result_of::ComponentOf<DOFVector<Vector<T> > >(vector, I); } - -} // end namespace AMDiS - -#endif // AMDIS_VALUE_OF_H \ No newline at end of file diff --git a/AMDiS/src/expressions/add_expr.hpp b/AMDiS/src/expressions/add_expr.hpp new file mode 100644 index 0000000000000000000000000000000000000000..085427ec575c2528fe25486b8057798d42f41042 --- /dev/null +++ b/AMDiS/src/expressions/add_expr.hpp @@ -0,0 +1,167 @@ +/****************************************************************************** + * + * AMDiS - Adaptive multidimensional simulations + * + * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. + * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis + * + * Authors: + * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * + * This file is part of AMDiS + * + * See also license.opensource.txt in the distribution. + * + ******************************************************************************/ + + + +/** \file add_expr.hpp */ + +#ifndef AMDIS_ADD_EXPRESSION_HPP +#define AMDIS_ADD_EXPRESSION_HPP + +#include "AMDiS_fwd.h" +#include "LazyOperatorTerm.h" + +#include <boost/static_assert.hpp> + +namespace AMDiS +{ + namespace expressions + { + /// Expression that represents "E1 + E2" + template<typename Term1, typename Term2> + struct Add : public LazyOperatorTerm2<Term1, Term2> + { + typedef LazyOperatorTerm2<Term1, Term2> super; + typedef typename traits::add_type + < + typename Term1::value_type, + typename Term2::value_type + >::type value_type; + + BOOST_STATIC_ASSERT_MSG( !(boost::is_same<value_type, traits::no_valid_type>::value), "********** ERROR: Can not add terms **********" ); + + Add(const Term1& term1_, const Term2& term2_) + : super(term1_, term2_) {} + + int getDegree() const + { + return std::max(super::term1.getDegree(), super::term2.getDegree()); + } + + inline value_type operator()(const int& iq) const { return super::term1(iq) + super::term2(iq); } + + std::string str() const { return std::string("(") + super::term1.str() + " + " + super::term2.str() + ")"; } + }; + + /// Expression that represents "-E" + template<typename Term> + struct Negative : public LazyOperatorTerm1<Term> + { + typedef LazyOperatorTerm1<Term> super; + typedef typename Term::value_type value_type; + + Negative(const Term& term_) + : super(term_) {} + + int getDegree() const + { + return super::term.getDegree(); + } + + inline value_type operator()(const int& iq) const { return -super::term(iq); } + + std::string str() const { return std::string("-(") + super::term.str() + ")"; } + }; + + } // end namespace expressions + + + namespace result_of + { + template<typename Term1, typename Term2> + struct Add : boost::enable_if + < + typename traits::is_valid_arg2<Term1, Term2>::type, + expressions::Add + < + typename traits::to_expr<Term1>::type, + typename traits::to_expr<Term2>::type + > + > {}; + + + template<typename Term> + struct Negative : boost::enable_if + < + typename traits::is_valid_arg<Term>::type, + expressions::Negative + < + typename traits::to_expr<Term>::type + > + > {}; + + + template<typename Term1, typename Term2> + struct Subtract : boost::enable_if + < + typename traits::is_valid_arg2<Term1, Term2>::type, + typename boost::mpl::if_< + typename traits::is_constant<Term2>::type, + expressions::Add + < + typename traits::to_expr<Term1>::type, + typename traits::to_expr<Term2>::type + >, + expressions::Add + < + typename traits::to_expr<Term1>::type, + expressions::Negative< typename traits::to_expr<Term2>::type > + > + >::type + > {}; + } + + + // add two terms + // _____________________________________________________________________________ + template<typename Term1, typename Term2> + inline typename result_of::Add<Term1, Term2>::type + operator+(const Term1& t1, const Term2& t2) + { + typedef typename traits::to_expr<Term1>::to Expr1; + typedef typename traits::to_expr<Term2>::to Expr2; + return expressions::Add< typename Expr1::type, typename Expr2::type > + (Expr1::get(t1), Expr2::get(t2)); + } + + + // negative of a term + // _____________________________________________________________________________ + template<typename Term> + inline typename result_of::Negative<Term>::type + operator-(const Term& t) + { + typedef typename traits::to_expr<Term>::to Expr; + return expressions::Negative< typename Expr::type >(Expr::get(t)); + } + + + // substract two terms + // _____________________________________________________________________________ + template<typename Term1, typename Term2> + inline typename result_of::Subtract<Term1, Term2>::type + operator-(const Term1& t1, const Term2& t2) + { + return t1 + (-t2); + } + +} // end namespace AMDiS + +#endif // AMDIS_ADD_EXPRESSION_HPP diff --git a/AMDiS/src/expressions/cmath_expr.h b/AMDiS/src/expressions/cmath_expr.h deleted file mode 100644 index 4af0f07d176b345d6de304a4c0389473e60fa335..0000000000000000000000000000000000000000 --- a/AMDiS/src/expressions/cmath_expr.h +++ /dev/null @@ -1,1185 +0,0 @@ -/****************************************************************************** - * - * AMDiS - Adaptive multidimensional simulations - * - * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. - * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis - * - * Authors: - * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al. - * - * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * - * This file is part of AMDiS - * - * See also license.opensource.txt in the distribution. - * - ******************************************************************************/ - - - -/** \file cmath_expr.h */ - -#ifndef AMDIS_CMATH_EXPRESSION_H -#define AMDIS_CMATH_EXPRESSION_H - -#include "AMDiS_fwd.h" -#include "LazyOperatorTerm.h" -#include "ValueTypes.h" -#include "Functors.h" - -#include <boost/static_assert.hpp> - - -namespace AMDiS { - -namespace result_of { - - - - /// - template<typename Term> - struct Abs : public LazyOperatorTerm1<Term> - { - typedef LazyOperatorTerm1<Term> super; - typedef typename Term::value_type value_type; - - Abs(const Term& term_) : super(term_) {} - - int getDegree() const - { - return super::term.getDegree(); - } - - inline value_type operator()(const int& iq) const { return std::abs(super::term(iq)); } - - template<typename Identifier> - inline value_type derivative(const int& iq) const - { - return derivative<Identifier>(iq, typename traits::DependsOn<Identifier, Term>::type()); - } - - template<typename Identifier> - inline value_type derivative(const int& iq, boost::mpl::true_) const - { - return super::term(iq) > 0.0 ? super::term.derivative<Identifier>(iq) : -super::term.derivative<Identifier>(iq); - } - - template<typename Identifier> - inline value_type derivative(const int& iq, boost::mpl::false_) const - { - value_type result; - nullify(result); - return result; - } - }; - - - /// - template<typename Term> - struct Signum : public LazyOperatorTerm1<Term> - { - typedef LazyOperatorTerm1<Term> super; - typedef typename Term::value_type value_type; - - Signum(const Term& term_) : super(term_) {} - - int getDegree() const - { - return 0; - } - - inline value_type operator()(const int& iq) const { return (super::term(iq) > 0.0 ? 1.0 : -1.0); } - - template<typename Identifier> - inline value_type derivative(const int& iq) const - { - value_type result; - nullify(result); - return result; - } - }; - - - - /// - template<typename Term> - struct Ceil : public LazyOperatorTerm1<Term> - { - typedef LazyOperatorTerm1<Term> super; - typedef typename Term::value_type value_type; - - Ceil(const Term& term_) : super(term_) {} - - int getDegree() const { return 0; } - - inline value_type operator()(const int& iq) const { return ceil(super::term(iq)); } - - template<typename Identifier> - inline value_type derivative(const int& iq) const - { - value_type result; - nullify(result); - return result; - } - }; - - - /// - template<typename Term> - struct Floor : public LazyOperatorTerm1<Term> - { - typedef LazyOperatorTerm1<Term> super; - typedef typename Term::value_type value_type; - - Floor(const Term& term_) : super(term_) {} - - int getDegree() const { return 0; } - - inline value_type operator()(const int& iq) const { return floor(super::term(iq)); } - - template<typename Identifier> - inline value_type derivative(const int& iq) const - { - value_type result; - nullify(result); - return result; - } - }; - - - // ___________________________________________________________________________ - - - /// - template<int I, typename Term> - struct Pow : public LazyOperatorTerm1<Term> - { - typedef LazyOperatorTerm1<Term> super; - typedef typename AMDiS::detail::Pow<I,typename Term::value_type>::result_type value_type; - - Pow(const Term& term_) : super(term_) {} - - int getDegree() const - { - return I * (super::term.getDegree()); - } - - inline value_type operator()(const int& iq) const { return AMDiS::detail::Pow<I,typename Term::value_type>::eval(super::term(iq)); } - - template<typename Identifier> - inline value_type derivative(const int& iq) const - { - return derivative<Identifier>(iq, typename traits::DependsOn<Identifier, Term>::type()); - } - - template<typename Identifier> - inline value_type derivative(const int& iq, boost::mpl::true_) const - { - return super::term.derivative<Identifier>(iq) * I*AMDiS::detail::Pow<I-1,typename Term::value_type>::eval(super::term(iq)); - } - - template<typename Identifier> - inline value_type derivative(const int& iq, boost::mpl::false_) const - { - value_type result; - nullify(result); - return result; - } - }; - - - /// - template<typename Term> - struct Sqrt : public LazyOperatorTerm1<Term> - { - typedef LazyOperatorTerm1<Term> super; - typedef typename Term::value_type value_type; - - Sqrt(const Term& term_) : super(term_) {} - - int getDegree() const - { - return 2 * (super::term.getDegree()); // stimmt nicht ganz - } - - inline value_type operator()(const int& iq) const { return sqrt(super::term(iq)); } - - template<typename Identifier> - inline value_type derivative(const int& iq) const - { - return derivative<Identifier>(iq, typename traits::DependsOn<Identifier, Term>::type()); - } - - template<typename Identifier> - inline value_type derivative(const int& iq, boost::mpl::true_) const - { - return super::term.derivative<Identifier>(iq) / (2.0 * sqrt(super::term(iq))); - } - - template<typename Identifier> - inline value_type derivative(const int& iq, boost::mpl::false_) const - { - value_type result; - nullify(result); - return result; - } - }; - - - // ___________________________________________________________________________ - - /// - template<typename Term> - struct Exp : public LazyOperatorTerm1<Term> - { - typedef LazyOperatorTerm1<Term> super; - typedef typename Term::value_type value_type; - int degree; - - Exp(const Term& term_, int degree_ = 1) : super(term_), degree(degree_) {} - - int getDegree() const - { - return degree * (super::term.getDegree()); - } - - inline value_type operator()(const int& iq) const { return exp(super::term(iq)); } - - - template<typename Identifier> - inline value_type derivative(const int& iq) const - { - return derivative<Identifier>(iq, typename traits::DependsOn<Identifier, Term>::type()); - } - - template<typename Identifier> - inline value_type derivative(const int& iq, boost::mpl::true_) const - { - return super::term.derivative<Identifier>(iq) * exp(super::term(iq)); - } - - template<typename Identifier> - inline value_type derivative(const int& iq, boost::mpl::false_) const - { - value_type result; - nullify(result); - return result; - } - }; - - /// - template<typename Term> - struct Log : public LazyOperatorTerm1<Term> - { - typedef LazyOperatorTerm1<Term> super; - typedef typename Term::value_type value_type; - int degree; - - Log(const Term& term_, int degree_ = 1) : super(term_), degree(degree_) {} - - int getDegree() const - { - return degree * (super::term.getDegree()); - } - - inline value_type operator()(const int& iq) const { return log(super::term(iq)); } - - - template<typename Identifier> - inline value_type derivative(const int& iq) const - { - return derivative<Identifier>(iq, typename traits::DependsOn<Identifier, Term>::type()); - } - - template<typename Identifier> - inline value_type derivative(const int& iq, boost::mpl::true_) const - { - return super::term.derivative<Identifier>(iq) / (super::term(iq)); - } - - template<typename Identifier> - inline value_type derivative(const int& iq, boost::mpl::false_) const - { - value_type result; - nullify(result); - return result; - } - }; - - // ___________________________________________________________________________ - - - /// - template<typename Term> - struct Cos : public LazyOperatorTerm1<Term> - { - typedef LazyOperatorTerm1<Term> super; - typedef typename Term::value_type value_type; - int degree; - - Cos(const Term& term_, int degree_ = 1) : super(term_), degree(degree_) {} - - int getDegree() const - { - return degree * (super::term.getDegree()); - } - - inline value_type operator()(const int& iq) const { return cos(super::term(iq)); } - - - template<typename Identifier> - inline value_type derivative(const int& iq) const - { - return derivative<Identifier>(iq, typename traits::DependsOn<Identifier, Term>::type()); - } - - template<typename Identifier> - inline value_type derivative(const int& iq, boost::mpl::true_) const - { - return -super::term.derivative<Identifier>(iq) * sin(super::term(iq)); - } - - template<typename Identifier> - inline value_type derivative(const int& iq, boost::mpl::false_) const - { - value_type result; - nullify(result); - return result; - } - }; - - /// - template<typename Term> - struct Sin : public LazyOperatorTerm1<Term> - { - typedef LazyOperatorTerm1<Term> super; - typedef typename Term::value_type value_type; - int degree; - - Sin(const Term& term_, int degree_ = 1) : super(term_), degree(degree_) {} - - int getDegree() const - { - return degree * (super::term.getDegree()); - } - - inline value_type operator()(const int& iq) const { return sin(super::term(iq)); } - - - template<typename Identifier> - inline value_type derivative(const int& iq) const - { - return derivative<Identifier>(iq, typename traits::DependsOn<Identifier, Term>::type()); - } - - template<typename Identifier> - inline value_type derivative(const int& iq, boost::mpl::true_) const - { - return super::term.derivative<Identifier>(iq) * cos(super::term(iq)); - } - - template<typename Identifier> - inline value_type derivative(const int& iq, boost::mpl::false_) const - { - value_type result; - nullify(result); - return result; - } - }; - - /// - template<typename Term> - struct Tan : public LazyOperatorTerm1<Term> - { - typedef LazyOperatorTerm1<Term> super; - typedef typename Term::value_type value_type; - int degree; - - Tan(const Term& term_, int degree_ = 1) : super(term_), degree(degree_) {} - - int getDegree() const - { - return degree * (super::term.getDegree()); - } - - inline value_type operator()(const int& iq) const { return tan(super::term(iq)); } - - - template<typename Identifier> - inline value_type derivative(const int& iq) const - { - return derivative<Identifier>(iq, typename traits::DependsOn<Identifier, Term>::type()); - } - - template<typename Identifier> - inline value_type derivative(const int& iq, boost::mpl::true_) const - { - return super::term.derivative<Identifier>(iq) * (1.0 - sqr(tan(super::term(iq)))); - } - - template<typename Identifier> - inline value_type derivative(const int& iq, boost::mpl::false_) const - { - value_type result; - nullify(result); - return result; - } - }; - - // ___________________________________________________________________________ - - - /// - template<typename Term> - struct Acos : public LazyOperatorTerm1<Term> - { - typedef LazyOperatorTerm1<Term> super; - typedef typename Term::value_type value_type; - int degree; - - Acos(const Term& term_, int degree_ = 1) : super(term_), degree(degree_) {} - - int getDegree() const - { - return degree * (super::term.getDegree()); - } - - inline value_type operator()(const int& iq) const { return acos(super::term(iq)); } - - - template<typename Identifier> - inline value_type derivative(const int& iq) const - { - return derivative<Identifier>(iq, typename traits::DependsOn<Identifier, Term>::type()); - } - - template<typename Identifier> - inline value_type derivative(const int& iq, boost::mpl::true_) const - { - return -super::term.derivative<Identifier>(iq) / (1.0 - sqr(super::term(iq))); - } - - template<typename Identifier> - inline value_type derivative(const int& iq, boost::mpl::false_) const - { - value_type result; - nullify(result); - return result; - } - }; - - /// - template<typename Term> - struct Asin : public LazyOperatorTerm1<Term> - { - typedef LazyOperatorTerm1<Term> super; - typedef typename Term::value_type value_type; - int degree; - - Asin(const Term& term_, int degree_ = 1) : super(term_), degree(degree_) {} - - int getDegree() const - { - return degree * (super::term.getDegree()); - } - - inline value_type operator()(const int& iq) const { return asin(super::term(iq)); } - - - template<typename Identifier> - inline value_type derivative(const int& iq) const - { - return derivative<Identifier>(iq, typename traits::DependsOn<Identifier, Term>::type()); - } - - template<typename Identifier> - inline value_type derivative(const int& iq, boost::mpl::true_) const - { - return super::term.derivative<Identifier>(iq) / sqrt(1.0 - sqr(super::term(iq))); - } - - template<typename Identifier> - inline value_type derivative(const int& iq, boost::mpl::false_) const - { - value_type result; - nullify(result); - return result; - } - }; - - /// - template<typename Term> - struct Atan : public LazyOperatorTerm1<Term> - { - typedef LazyOperatorTerm1<Term> super; - typedef typename Term::value_type value_type; - int degree; - - Atan(const Term& term_, int degree_ = 1) : super(term_), degree(degree_) {} - - int getDegree() const - { - return degree * (super::term.getDegree()); - } - - inline value_type operator()(const int& iq) const { return atan(super::term(iq)); } - - - template<typename Identifier> - inline value_type derivative(const int& iq) const - { - return derivative<Identifier>(iq, typename traits::DependsOn<Identifier, Term>::type()); - } - - template<typename Identifier> - inline value_type derivative(const int& iq, boost::mpl::true_) const - { - return super::term.derivative<Identifier>(iq) / (1.0 + sqr(super::term(iq))); - } - - template<typename Identifier> - inline value_type derivative(const int& iq, boost::mpl::false_) const - { - value_type result; - nullify(result); - return result; - } - }; - - /// - template<typename Term1, typename Term2> - struct Atan2 : public LazyOperatorTerm2<Term1, Term2> - { - typedef LazyOperatorTerm2<Term1, Term2> super; - typedef typename Term1::value_type value_type; - int degree; - - Atan2(const Term1& term1_, const Term2& term2_, int degree_ = 1) : super(term1_, term2_), degree(degree_) {} - - int getDegree() const - { - return degree * (super::term1.getDegree() + super::term2.getDegree()); - } - - inline value_type operator()(const int& iq) const { return atan2(super::term1(iq), super::term2(iq)); } - - - template<typename Identifier> - inline value_type derivative(const int& iq) const - { - throw std::runtime_error("diff(atanh2) not implemented yet!"); - value_type result; nullify(result); - return result; - } - }; - - // ___________________________________________________________________________ - - - /// - template<typename Term> - struct Cosh : public LazyOperatorTerm1<Term> - { - typedef LazyOperatorTerm1<Term> super; - typedef typename Term::value_type value_type; - int degree; - - Cosh(const Term& term_, int degree_ = 1) : super(term_), degree(degree_) {} - - int getDegree() const - { - return degree * (super::term.getDegree()); - } - - inline value_type operator()(const int& iq) const { return cosh(super::term(iq)); } - - - template<typename Identifier> - inline value_type derivative(const int& iq) const - { - return derivative<Identifier>(iq, typename traits::DependsOn<Identifier, Term>::type()); - } - - template<typename Identifier> - inline value_type derivative(const int& iq, boost::mpl::true_) const - { - return super::term.derivative<Identifier>(iq) * sinh(super::term(iq)); - } - - template<typename Identifier> - inline value_type derivative(const int& iq, boost::mpl::false_) const - { - value_type result; - nullify(result); - return result; - } - }; - - /// - template<typename Term> - struct Sinh : public LazyOperatorTerm1<Term> - { - typedef LazyOperatorTerm1<Term> super; - typedef typename Term::value_type value_type; - int degree; - - Sinh(const Term& term_, int degree_ = 1) : super(term_), degree(degree_) {} - - int getDegree() const - { - return degree * (super::term.getDegree()); - } - - inline value_type operator()(const int& iq) const { return sinh(super::term(iq)); } - - - template<typename Identifier> - inline value_type derivative(const int& iq) const - { - return derivative<Identifier>(iq, typename traits::DependsOn<Identifier, Term>::type()); - } - - template<typename Identifier> - inline value_type derivative(const int& iq, boost::mpl::true_) const - { - return super::term.derivative<Identifier>(iq) * cosh(super::term(iq)); - } - - template<typename Identifier> - inline value_type derivative(const int& iq, boost::mpl::false_) const - { - value_type result; - nullify(result); - return result; - } - }; - - /// - template<typename Term> - struct Tanh : public LazyOperatorTerm1<Term> - { - typedef LazyOperatorTerm1<Term> super; - typedef typename Term::value_type value_type; - int degree; - - Tanh(const Term& term_, int degree_ = 1) : super(term_), degree(degree_) {} - - int getDegree() const - { - return degree * (super::term.getDegree()); - } - - inline value_type operator()(const int& iq) const { return tanh(super::term(iq)); } - - - template<typename Identifier> - inline value_type derivative(const int& iq) const - { - return derivative<Identifier>(iq, typename traits::DependsOn<Identifier, Term>::type()); - } - - template<typename Identifier> - inline value_type derivative(const int& iq, boost::mpl::true_) const - { - return super::term.derivative<Identifier>(iq) * (1.0 - sqr(tanh(super::term(iq)))); - } - - template<typename Identifier> - inline value_type derivative(const int& iq, boost::mpl::false_) const - { - value_type result; - nullify(result); - return result; - } - }; - - // ___________________________________________________________________________ - - - /// - template<typename Term> - struct Acosh : public LazyOperatorTerm1<Term> - { - typedef LazyOperatorTerm1<Term> super; - typedef typename Term::value_type value_type; - int degree; - - Acosh(const Term& term_, int degree_ = 1) : super(term_), degree(degree_) {} - - int getDegree() const - { - return degree * (super::term.getDegree()); - } - - inline value_type operator()(const int& iq) const { - value_type tmp = super::term(iq); - return log(tmp + sqrt(sqr(tmp) - 1.0)); - } - - - template<typename Identifier> - inline value_type derivative(const int& iq) const - { - throw std::runtime_error("diff(acosh) not implemented yet!"); - value_type result; nullify(result); - return result; - } - }; - - /// - template<typename Term> - struct Asinh : public LazyOperatorTerm1<Term> - { - typedef LazyOperatorTerm1<Term> super; - typedef typename Term::value_type value_type; - int degree; - - Asinh(const Term& term_, int degree_ = 1) : super(term_), degree(degree_) {} - - int getDegree() const - { - return degree * (super::term.getDegree()); - } - - inline value_type operator()(const int& iq) const { - value_type tmp = super::term(iq); - return log(tmp + sqrt(sqr(tmp) + 1.0)); - } - - - template<typename Identifier> - inline value_type derivative(const int& iq) const - { - throw std::runtime_error("diff(asinh) not implemented yet!"); - value_type result; nullify(result); - return result; - } - }; - - /// - template<typename Term> - struct Atanh : public LazyOperatorTerm1<Term> - { - typedef LazyOperatorTerm1<Term> super; - typedef typename Term::value_type value_type; - int degree; - - Atanh(const Term& term_, int degree_ = 1) : super(term_), degree(degree_) {} - - int getDegree() const - { - return degree * (super::term.getDegree()); - } - - inline value_type operator()(const int& iq) const { - value_type tmp = super::term(iq); - return 0.5 * log((1.0 + tmp) / (1.0 - tmp)); - } - - - template<typename Identifier> - inline value_type derivative(const int& iq) const - { - throw std::runtime_error("diff(atanh) not implemented yet!"); - value_type result; nullify(result); - return result; - } - }; - - - // ___________________________________________________________________________ - - - /// - template<typename Term1, typename Term2> - struct Max : public LazyOperatorTerm2<Term1, Term2> - { - typedef LazyOperatorTerm2<Term1, Term2> super; - typedef typename Term1::value_type value_type; - - Max(const Term1& term1_, const Term2& term2_) - : super(term1_, term2_) {} - - int getDegree() const - { - return std::max(super::term1.getDegree(), super::term2.getDegree()); - } - - inline value_type operator()(const int& iq) const - { - return std::max(super::term1(iq), super::term2(iq)); - } - - template<typename Identifier> - inline value_type derivative(const int& iq) const - { - return derivative<Identifier>(iq, typename traits::DependsOn<Identifier, super>::type()); - } - - template<typename Identifier> - inline value_type derivative(const int& iq, boost::mpl::true_) const - { - return super::term1(iq) > super::term2(iq) ? super::term1.derivative<Identifier>(iq) : super::term2.derivative<Identifier>(iq); - } - - template<typename Identifier> - inline value_type derivative(const int& iq, boost::mpl::false_) const - { - value_type result; - nullify(result); - return result; - } - }; - - - /// - template<typename Term1, typename Term2> - struct Min : public LazyOperatorTerm2<Term1, Term2> - { - typedef LazyOperatorTerm2<Term1, Term2> super; - typedef typename Term1::value_type value_type; - - Min(const Term1& term1_, const Term2& term2_) - : super(term1_, term2_) {} - - int getDegree() const - { - return std::max(super::term1.getDegree(), super::term2.getDegree()); - } - - inline value_type operator()(const int& iq) const - { - return std::min(super::term1(iq), super::term2(iq)); - } - - template<typename Identifier> - inline value_type derivative(const int& iq) const - { - return derivative<Identifier>(iq, typename traits::DependsOn<Identifier, super>::type()); - } - - template<typename Identifier> - inline value_type derivative(const int& iq, boost::mpl::true_) const - { - return super::term1(iq) < super::term2(iq) ? super::term1.derivative<Identifier>(iq) : super::term2.derivative<Identifier>(iq); - } - - template<typename Identifier> - inline value_type derivative(const int& iq, boost::mpl::false_) const - { - value_type result; - nullify(result); - return result; - } - }; - -} - - -namespace traits -{ - - template<typename Identifier, typename Term> - struct DependsOn<Identifier, AMDiS::result_of::Abs<Term> > - : public boost::mpl::bool_< DependsOn<Identifier, Term>::type::value > {}; - - template<typename Identifier, typename Term> - struct DependsOn<Identifier, AMDiS::result_of::Signum<Term> > - : public boost::mpl::bool_< DependsOn<Identifier, Term>::type::value > {}; - - template<typename Identifier, typename Term> - struct DependsOn<Identifier, AMDiS::result_of::Ceil<Term> > - : public boost::mpl::bool_< DependsOn<Identifier, Term>::type::value > {}; - - template<typename Identifier, typename Term> - struct DependsOn<Identifier, AMDiS::result_of::Floor<Term> > - : public boost::mpl::bool_< DependsOn<Identifier, Term>::type::value > {}; - - - template<typename Identifier, int I, typename Term> - struct DependsOn<Identifier, AMDiS::result_of::Pow<I, Term> > - : public boost::mpl::bool_< DependsOn<Identifier, Term>::type::value > {}; - - template<typename Identifier, typename Term> - struct DependsOn<Identifier, AMDiS::result_of::Sqrt<Term> > - : public boost::mpl::bool_< DependsOn<Identifier, Term>::type::value > {}; - - - template<typename Identifier, typename Term> - struct DependsOn<Identifier, AMDiS::result_of::Exp<Term> > - : public boost::mpl::bool_< DependsOn<Identifier, Term>::type::value > {}; - - template<typename Identifier, typename Term> - struct DependsOn<Identifier, AMDiS::result_of::Log<Term> > - : public boost::mpl::bool_< DependsOn<Identifier, Term>::type::value > {}; - - - template<typename Identifier, typename Term> - struct DependsOn<Identifier, AMDiS::result_of::Cos<Term> > - : public boost::mpl::bool_< DependsOn<Identifier, Term>::type::value > {}; - - template<typename Identifier, typename Term> - struct DependsOn<Identifier, AMDiS::result_of::Sin<Term> > - : public boost::mpl::bool_< DependsOn<Identifier, Term>::type::value > {}; - - template<typename Identifier, typename Term> - struct DependsOn<Identifier, AMDiS::result_of::Tan<Term> > - : public boost::mpl::bool_< DependsOn<Identifier, Term>::type::value > {}; - - - template<typename Identifier, typename Term> - struct DependsOn<Identifier, AMDiS::result_of::Acos<Term> > - : public boost::mpl::bool_< DependsOn<Identifier, Term>::type::value > {}; - - template<typename Identifier, typename Term> - struct DependsOn<Identifier, AMDiS::result_of::Asin<Term> > - : public boost::mpl::bool_< DependsOn<Identifier, Term>::type::value > {}; - - template<typename Identifier, typename Term> - struct DependsOn<Identifier, AMDiS::result_of::Atan<Term> > - : public boost::mpl::bool_< DependsOn<Identifier, Term>::type::value > {}; - - - template<typename Identifier, typename Term> - struct DependsOn<Identifier, AMDiS::result_of::Cosh<Term> > - : public boost::mpl::bool_< DependsOn<Identifier, Term>::type::value > {}; - - template<typename Identifier, typename Term> - struct DependsOn<Identifier, AMDiS::result_of::Sinh<Term> > - : public boost::mpl::bool_< DependsOn<Identifier, Term>::type::value > {}; - - template<typename Identifier, typename Term> - struct DependsOn<Identifier, AMDiS::result_of::Tanh<Term> > - : public boost::mpl::bool_< DependsOn<Identifier, Term>::type::value > {}; - - - template<typename Identifier, typename Term> - struct DependsOn<Identifier, AMDiS::result_of::Acosh<Term> > - : public boost::mpl::bool_< DependsOn<Identifier, Term>::type::value > {}; - - template<typename Identifier, typename Term> - struct DependsOn<Identifier, AMDiS::result_of::Asinh<Term> > - : public boost::mpl::bool_< DependsOn<Identifier, Term>::type::value > {}; - - template<typename Identifier, typename Term> - struct DependsOn<Identifier, AMDiS::result_of::Atanh<Term> > - : public boost::mpl::bool_< DependsOn<Identifier, Term>::type::value > {}; - - - template<typename Identifier, typename Term1, typename Term2> - struct DependsOn<Identifier, AMDiS::result_of::Max<Term1, Term2> > - : public DependsOn<Identifier, LazyOperatorTerm2<Term1, Term2> >::type {}; - - template<typename Identifier, typename Term1, typename Term2> - struct DependsOn<Identifier, AMDiS::result_of::Min<Term1, Term2> > - : public DependsOn<Identifier, LazyOperatorTerm2<Term1, Term2> >::type {}; - -} - - -// maximum of two terms -template<typename Term1, typename Term2> -inline typename boost::enable_if< - typename boost::mpl::and_<typename boost::is_base_of<LazyOperatorTermBase, Term1>::type, - typename boost::is_base_of<LazyOperatorTermBase, Term2>::type>::type, - result_of::Max<Term1, Term2> >::type -max(const Term1& t1, const Term2& t2) { return result_of::Max<Term1, Term2>(t1, t2); } - -template<typename T, typename Term> -inline typename boost::enable_if< - typename boost::mpl::and_<typename boost::is_fundamental<T>::type, - typename boost::is_base_of<LazyOperatorTermBase, Term>::type>::type, - result_of::Max<result_of::Const<T>, Term> >::type -max(const T& t1, const Term& t2) { return result_of::Max<result_of::Const<T>, Term>(constant(t1), t2); } - -template<typename Term, typename T> -inline typename boost::enable_if< - typename boost::mpl::and_<typename boost::is_fundamental<T>::type, - typename boost::is_base_of<LazyOperatorTermBase, Term>::type>::type, - result_of::Max<Term, result_of::Const<T> > >::type -max(const Term& t1, const T& t2) { return result_of::Max<Term, result_of::Const<T> >(t1, constant(t2)); } - - - -// minimum of two terms -template<typename Term1, typename Term2> -inline typename boost::enable_if< - typename boost::mpl::and_<typename boost::is_base_of<LazyOperatorTermBase, Term1>::type, - typename boost::is_base_of<LazyOperatorTermBase, Term2>::type>::type, - result_of::Min<Term1, Term2> >::type -min(const Term1& t1, const Term2& t2) { return result_of::Min<Term1, Term2>(t1, t2); } - -template<typename T, typename Term> -inline typename boost::enable_if< - typename boost::mpl::and_<typename boost::is_fundamental<T>::type, - typename boost::is_base_of<LazyOperatorTermBase, Term>::type>::type, - result_of::Min<result_of::Const<T>, Term> >::type -min(const T& t1, const Term& t2) { return result_of::Max<result_of::Const<T>, Term>(constant(t1), t2); } - -template<typename Term, typename T> -inline typename boost::enable_if< - typename boost::mpl::and_<typename boost::is_fundamental<T>::type, - typename boost::is_base_of<LazyOperatorTermBase, Term>::type>::type, - result_of::Min<Term, result_of::Const<T> > >::type -min(const Term& t1, const T& t2) { return result_of::Min<Term, result_of::Const<T> >(t1, constant(t2)); } - -//______________________________________________________________________________ - -// absolute value of a term -template<typename Term> -inline typename boost::enable_if< - typename boost::is_base_of<LazyOperatorTermBase, Term>::type, - result_of::Abs<Term> >::type -abs_(const Term& t) { return result_of::Abs<Term>(t); } // TODO: Funktionsnamen ohne Unterstrich - -// signum of a term -template<typename Term> -inline typename boost::enable_if< - typename boost::is_base_of<LazyOperatorTermBase, Term>::type, - result_of::Signum<Term> >::type -signum(const Term& t) { return result_of::Signum<Term>(t); } - -// -template<typename Term> -inline typename boost::enable_if< - typename boost::is_base_of<LazyOperatorTermBase, Term>::type, - result_of::Ceil<Term> >::type -ceil(const Term& t) { return result_of::Ceil<Term>(t); } - -// -template<typename Term> -inline typename boost::enable_if< - typename boost::is_base_of<LazyOperatorTermBase, Term>::type, - result_of::Floor<Term> >::type -floor(const Term& t) { return result_of::Floor<Term>(t); } - -//______________________________________________________________________________ - -// I'th power of a term -template<int I, typename Term> -inline typename boost::enable_if< - typename boost::is_base_of<LazyOperatorTermBase, Term>::type, - result_of::Pow<I, Term> >::type -pow(const Term& t) { return result_of::Pow<I, Term>(t); } - -// square root of a term -template<typename Term> -inline typename boost::enable_if< - typename boost::is_base_of<LazyOperatorTermBase, Term>::type, - result_of::Sqrt<Term> >::type -sqrt(const Term& t) { return result_of::Sqrt<Term>(t); } - -//______________________________________________________________________________ - -// exponential function of a term -template<typename Term> -inline typename boost::enable_if< - typename boost::is_base_of<LazyOperatorTermBase, Term>::type, - result_of::Exp<Term> >::type -exp(const Term& t) { return result_of::Exp<Term>(t); } - -// natural logarithm of a term -template<typename Term> -inline typename boost::enable_if< - typename boost::is_base_of<LazyOperatorTermBase, Term>::type, - result_of::Log<Term> >::type -log(const Term& t) { return result_of::Log<Term>(t); } - -//______________________________________________________________________________ - -// cosine function of a term -template<typename Term> -inline typename boost::enable_if< - typename boost::is_base_of<LazyOperatorTermBase, Term>::type, - result_of::Cos<Term> >::type -cos(const Term& t) { return result_of::Cos<Term>(t); } - -// sine function of a term -template<typename Term> -inline typename boost::enable_if< - typename boost::is_base_of<LazyOperatorTermBase, Term>::type, - result_of::Sin<Term> >::type -sin(const Term& t) { return result_of::Sin<Term>(t); } - -// tangens function of a term -template<typename Term> -inline typename boost::enable_if< - typename boost::is_base_of<LazyOperatorTermBase, Term>::type, - result_of::Tan<Term> >::type -tan(const Term& t) { return result_of::Tan<Term>(t); } - -//______________________________________________________________________________ - -// arkuscosine function of a term -template<typename Term> -inline typename boost::enable_if< - typename boost::is_base_of<LazyOperatorTermBase, Term>::type, - result_of::Acos<Term> >::type -acos(const Term& t) { return result_of::Acos<Term>(t); } - -// arkussine function of a term -template<typename Term> -inline typename boost::enable_if< - typename boost::is_base_of<LazyOperatorTermBase, Term>::type, - result_of::Asin<Term> >::type -asin(const Term& t) { return result_of::Asin<Term>(t); } - -// arkustangens function of a term -template<typename Term> -inline typename boost::enable_if< - typename boost::is_base_of<LazyOperatorTermBase, Term>::type, - result_of::Atan<Term> >::type -atan(const Term& t) { return result_of::Atan<Term>(t); } - -//______________________________________________________________________________ - -// cosine-hyperbolicus function of a term -template<typename Term> -inline typename boost::enable_if< - typename boost::is_base_of<LazyOperatorTermBase, Term>::type, - result_of::Cosh<Term> >::type -cosh(const Term& t) { return result_of::Cosh<Term>(t); } - -// sine-hyperbolicus function of a term -template<typename Term> -inline typename boost::enable_if< - typename boost::is_base_of<LazyOperatorTermBase, Term>::type, - result_of::Sin<Term> >::type -sinh(const Term& t) { return result_of::Sinh<Term>(t); } - -// tangens-hyperbolicus function of a term -template<typename Term> -inline typename boost::enable_if< - typename boost::is_base_of<LazyOperatorTermBase, Term>::type, - result_of::Tan<Term> >::type -tanh(const Term& t) { return result_of::Tanh<Term>(t); } - -//______________________________________________________________________________ - -// arkuscosine-hypüerbolicus function of a term -template<typename Term> -inline typename boost::enable_if< - typename boost::is_base_of<LazyOperatorTermBase, Term>::type, - result_of::Acosh<Term> >::type -acosh(const Term& t) { return result_of::Acosh<Term>(t); } - -// arkussine-hyperbolicus function of a term -template<typename Term> -inline typename boost::enable_if< - typename boost::is_base_of<LazyOperatorTermBase, Term>::type, - result_of::Asinh<Term> >::type -asinh(const Term& t) { return result_of::Asinh<Term>(t); } - -// arkustangens-hyperbolicus function of a term -template<typename Term> -inline typename boost::enable_if< - typename boost::is_base_of<LazyOperatorTermBase, Term>::type, - result_of::Atanh<Term> >::type -atanh(const Term& t) { return result_of::Atanh<Term>(t); } - -} // end namespace AMDiS - -#endif \ No newline at end of file diff --git a/AMDiS/src/expressions/cmath_expr.hpp b/AMDiS/src/expressions/cmath_expr.hpp new file mode 100644 index 0000000000000000000000000000000000000000..f99b978e6c566d1be64fbce4943ad8e1581cd970 --- /dev/null +++ b/AMDiS/src/expressions/cmath_expr.hpp @@ -0,0 +1,740 @@ +/****************************************************************************** + * + * AMDiS - Adaptive multidimensional simulations + * + * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. + * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis + * + * Authors: + * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * + * This file is part of AMDiS + * + * See also license.opensource.txt in the distribution. + * + ******************************************************************************/ + + + +/** \file cmath_expr.hpp */ + +#ifndef AMDIS_CMATH_EXPRESSION_HPP +#define AMDIS_CMATH_EXPRESSION_HPP + +#include "AMDiS_fwd.h" +#include "LazyOperatorTerm.h" + +#include "operations/functors.hpp" + +namespace AMDiS +{ + namespace expressions + { + /// Expression that represents an absolute value |v| + template<typename Term> + struct Abs : public LazyOperatorTerm1<Term> + { + typedef LazyOperatorTerm1<Term> super; + typedef typename Term::value_type value_type; + + Abs(const Term& term_) : super(term_) {} + + int getDegree() const + { + return super::term.getDegree(); + } + + inline value_type operator()(const int& iq) const { return std::abs(super::term(iq)); } + + std::string str() const { return std::string("abs(") + super::term.str() + ")"; } + }; + + + /// Expressions that represents the sign of a value == sign(v) + template<typename Term> + struct Signum : public LazyOperatorTerm1<Term> + { + typedef LazyOperatorTerm1<Term> super; + typedef typename Term::value_type value_type; + + Signum(const Term& term_) : super(term_) {} + + int getDegree() const + { + return 0; + } + + inline value_type operator()(const int& iq) const { return (super::term(iq) > 0.0 ? 1.0 : -1.0); } + + std::string str() const { return std::string("sign(") + super::term.str() + ")"; } + }; + + + /// Expressions for ceiling a value + template<typename Term> + struct Ceil : public LazyOperatorTerm1<Term> + { + typedef LazyOperatorTerm1<Term> super; + typedef typename Term::value_type value_type; + + Ceil(const Term& term_) : super(term_) {} + + int getDegree() const { return 0; } + + inline value_type operator()(const int& iq) const { return std::ceil(super::term(iq)); } + + std::string str() const { return std::string("ceil(") + super::term.str() + ")"; } + }; + + + /// Expressions to round to a lower integer + template<typename Term> + struct Floor : public LazyOperatorTerm1<Term> + { + typedef LazyOperatorTerm1<Term> super; + typedef typename Term::value_type value_type; + + Floor(const Term& term_) : super(term_) {} + + int getDegree() const { return 0; } + + inline value_type operator()(const int& iq) const { return std::floor(super::term(iq)); } + + std::string str() const { return std::string("floor(") + super::term.str() + ")"; } + }; + + + // ___________________________________________________________________________ + + + /// Expressions that represents the Ith power of E + template<int I, typename Term> + struct Pow : public LazyOperatorTerm1<Term> + { + typedef LazyOperatorTerm1<Term> super; + typedef typename AMDiS::detail::Pow<I,typename Term::value_type>::result_type value_type; + + Pow(const Term& term_) : super(term_) {} + + int getDegree() const + { + return I * (super::term.getDegree()); + } + + inline value_type operator()(const int& iq) const { return functors::pow<I,typename Term::value_type>::eval(super::term(iq)); } + + std::string str() const { return std::string("pow<") + boost::lexical_cast<std::string>(I) + ">(" + super::term.str() + ")"; } + }; + + + /// Expression that represents that square root of E + template<typename Term> + struct Sqrt : public LazyOperatorTerm1<Term> + { + typedef LazyOperatorTerm1<Term> super; + typedef typename Term::value_type value_type; + + Sqrt(const Term& term_) : super(term_) {} + + int getDegree() const + { + return 2 * (super::term.getDegree()); // stimmt nicht ganz + } + + inline value_type operator()(const int& iq) const { return std::sqrt(super::term(iq)); } + + std::string str() const { return std::string("sqrt(") + super::term.str() + ")"; } + }; + + + // ___________________________________________________________________________ + + /// Expressions for the exponential function + template<typename Term> + struct Exp : public LazyOperatorTerm1<Term> + { + typedef LazyOperatorTerm1<Term> super; + typedef typename Term::value_type value_type; + int degree; + + Exp(const Term& term_, int degree_ = 1) : super(term_), degree(degree_) {} + + int getDegree() const + { + return degree * (super::term.getDegree()); + } + + inline value_type operator()(const int& iq) const { return std::exp(super::term(iq)); } + + std::string str() const { return std::string("exp(") + super::term.str() + ")"; } + }; + + /// Expression for the logarithm + template<typename Term> + struct Log : public LazyOperatorTerm1<Term> + { + typedef LazyOperatorTerm1<Term> super; + typedef typename Term::value_type value_type; + int degree; + + Log(const Term& term_, int degree_ = 1) : super(term_), degree(degree_) {} + + int getDegree() const + { + return degree * (super::term.getDegree()); + } + + inline value_type operator()(const int& iq) const { return std::log(super::term(iq)); } + + std::string str() const { return std::string("log(") + super::term.str() + ")"; } + }; + + // ___________________________________________________________________________ + + + /// Expressions for Cosine + template<typename Term> + struct Cos : public LazyOperatorTerm1<Term> + { + typedef LazyOperatorTerm1<Term> super; + typedef typename Term::value_type value_type; + int degree; + + Cos(const Term& term_, int degree_ = 1) : super(term_), degree(degree_) {} + + int getDegree() const + { + return degree * (super::term.getDegree()); + } + + inline value_type operator()(const int& iq) const { return std::cos(super::term(iq)); } + + std::string str() const { return std::string("cos(") + super::term.str() + ")"; } + }; + + /// Expressions for Sine + template<typename Term> + struct Sin : public LazyOperatorTerm1<Term> + { + typedef LazyOperatorTerm1<Term> super; + typedef typename Term::value_type value_type; + int degree; + + Sin(const Term& term_, int degree_ = 1) : super(term_), degree(degree_) {} + + int getDegree() const + { + return degree * (super::term.getDegree()); + } + + inline value_type operator()(const int& iq) const { return std::sin(super::term(iq)); } + + std::string str() const { return std::string("sin(") + super::term.str() + ")"; } + }; + + /// Expressions for Tangence + template<typename Term> + struct Tan : public LazyOperatorTerm1<Term> + { + typedef LazyOperatorTerm1<Term> super; + typedef typename Term::value_type value_type; + int degree; + + Tan(const Term& term_, int degree_ = 1) : super(term_), degree(degree_) {} + + int getDegree() const + { + return degree * (super::term.getDegree()); + } + + inline value_type operator()(const int& iq) const { return std::tan(super::term(iq)); } + + std::string str() const { return std::string("tan(") + super::term.str() + ")"; } + }; + + // ___________________________________________________________________________ + + + /// Expressions for arcus cosine + template<typename Term> + struct Acos : public LazyOperatorTerm1<Term> + { + typedef LazyOperatorTerm1<Term> super; + typedef typename Term::value_type value_type; + int degree; + + Acos(const Term& term_, int degree_ = 1) : super(term_), degree(degree_) {} + + int getDegree() const + { + return degree * (super::term.getDegree()); + } + + inline value_type operator()(const int& iq) const { return std::acos(super::term(iq)); } + + std::string str() const { return std::string("acos(") + super::term.str() + ")"; } + }; + + /// Expressions for arcus sine + template<typename Term> + struct Asin : public LazyOperatorTerm1<Term> + { + typedef LazyOperatorTerm1<Term> super; + typedef typename Term::value_type value_type; + int degree; + + Asin(const Term& term_, int degree_ = 1) : super(term_), degree(degree_) {} + + int getDegree() const + { + return degree * (super::term.getDegree()); + } + + inline value_type operator()(const int& iq) const { return std::asin(super::term(iq)); } + + std::string str() const { return std::string("asin(") + super::term.str() + ")"; } + }; + + /// Expressions for arcus tangence + template<typename Term> + struct Atan : public LazyOperatorTerm1<Term> + { + typedef LazyOperatorTerm1<Term> super; + typedef typename Term::value_type value_type; + int degree; + + Atan(const Term& term_, int degree_ = 1) : super(term_), degree(degree_) {} + + int getDegree() const + { + return degree * (super::term.getDegree()); + } + + inline value_type operator()(const int& iq) const { return std::atan(super::term(iq)); } + + std::string str() const { return std::string("atan(") + super::term.str() + ")"; } + }; + + /// Expressions for arcus tangence2, i.e. atan(x/y) + template<typename Term1, typename Term2> + struct Atan2 : public LazyOperatorTerm2<Term1, Term2> + { + typedef LazyOperatorTerm2<Term1, Term2> super; + typedef typename Term1::value_type value_type; + int degree; + + Atan2(const Term1& term1_, const Term2& term2_, int degree_ = 1) : super(term1_, term2_), degree(degree_) {} + + int getDegree() const + { + return degree * (super::term1.getDegree() + super::term2.getDegree()); + } + + inline value_type operator()(const int& iq) const { return std::atan2(super::term1(iq), super::term2(iq)); } + + std::string str() const { return std::string("atan2(") + super::term.str() + ")"; } + }; + + // ___________________________________________________________________________ + + + /// Expressions for cosine hyperbolicus + template<typename Term> + struct Cosh : public LazyOperatorTerm1<Term> + { + typedef LazyOperatorTerm1<Term> super; + typedef typename Term::value_type value_type; + int degree; + + Cosh(const Term& term_, int degree_ = 1) : super(term_), degree(degree_) {} + + int getDegree() const + { + return degree * (super::term.getDegree()); + } + + inline value_type operator()(const int& iq) const { return std::cosh(super::term(iq)); } + + std::string str() const { return std::string("cosh(") + super::term.str() + ")"; } + }; + + /// Expressions for sine hyperbolicus + template<typename Term> + struct Sinh : public LazyOperatorTerm1<Term> + { + typedef LazyOperatorTerm1<Term> super; + typedef typename Term::value_type value_type; + int degree; + + Sinh(const Term& term_, int degree_ = 1) : super(term_), degree(degree_) {} + + int getDegree() const + { + return degree * (super::term.getDegree()); + } + + inline value_type operator()(const int& iq) const { return std::sinh(super::term(iq)); } + + std::string str() const { return std::string("sinh(") + super::term.str() + ")"; } + }; + + /// Expressions for tangence hyperbolicus + template<typename Term> + struct Tanh : public LazyOperatorTerm1<Term> + { + typedef LazyOperatorTerm1<Term> super; + typedef typename Term::value_type value_type; + int degree; + + Tanh(const Term& term_, int degree_ = 1) : super(term_), degree(degree_) {} + + int getDegree() const + { + return degree * (super::term.getDegree()); + } + + inline value_type operator()(const int& iq) const { return std::tanh(super::term(iq)); } + + std::string str() const { return std::string("tanh(") + super::term.str() + ")"; } + }; + + // ___________________________________________________________________________ + + + /// Expressions for arcus cosine hyperbolicus + template<typename Term> + struct Acosh : public LazyOperatorTerm1<Term> + { + typedef LazyOperatorTerm1<Term> super; + typedef typename Term::value_type value_type; + int degree; + + Acosh(const Term& term_, int degree_ = 1) : super(term_), degree(degree_) {} + + int getDegree() const + { + return degree * (super::term.getDegree()); + } + + inline value_type operator()(const int& iq) const { + value_type tmp = super::term(iq); + return std::log(tmp + std::sqrt(sqr(tmp) - 1.0)); + } + + std::string str() const { return std::string("acosh(") + super::term.str() + ")"; } + }; + + /// Expressions for arcus sine hyperbolicus + template<typename Term> + struct Asinh : public LazyOperatorTerm1<Term> + { + typedef LazyOperatorTerm1<Term> super; + typedef typename Term::value_type value_type; + int degree; + + Asinh(const Term& term_, int degree_ = 1) : super(term_), degree(degree_) {} + + int getDegree() const + { + return degree * (super::term.getDegree()); + } + + inline value_type operator()(const int& iq) const { + value_type tmp = super::term(iq); + return std::log(tmp + std::sqrt(sqr(tmp) + 1.0)); + } + + std::string str() const { return std::string("asinh(") + super::term.str() + ")"; } + }; + + /// Expressions for arcus tangence hyperbolicus + template<typename Term> + struct Atanh : public LazyOperatorTerm1<Term> + { + typedef LazyOperatorTerm1<Term> super; + typedef typename Term::value_type value_type; + int degree; + + Atanh(const Term& term_, int degree_ = 1) : super(term_), degree(degree_) {} + + int getDegree() const + { + return degree * (super::term.getDegree()); + } + + inline value_type operator()(const int& iq) const { + value_type tmp = super::term(iq); + return 0.5 * std::log((1.0 + tmp) / (1.0 - tmp)); + } + + std::string str() const { return std::string("atanh(") + super::term.str() + ")"; } + }; + + + // ___________________________________________________________________________ + + + /// Expressions for the maximum of two expressions max(E1, E2) + template<typename Term1, typename Term2> + struct Max : public LazyOperatorTerm2<Term1, Term2> + { + typedef LazyOperatorTerm2<Term1, Term2> super; + typedef typename Term1::value_type value_type; + + Max(const Term1& term1_, const Term2& term2_) + : super(term1_, term2_) {} + + int getDegree() const + { + return std::max(super::term1.getDegree(), super::term2.getDegree()); + } + + inline value_type operator()(const int& iq) const + { + return std::max(super::term1(iq), super::term2(iq)); + } + + std::string str() const { return std::string("max(") + super::term1.str() + ", " + super::term2.str() + ")"; } + }; + + + /// Expressions for the minimum of two expressions min(E1, E2) + template<typename Term1, typename Term2> + struct Min : public LazyOperatorTerm2<Term1, Term2> + { + typedef LazyOperatorTerm2<Term1, Term2> super; + typedef typename Term1::value_type value_type; + + Min(const Term1& term1_, const Term2& term2_) + : super(term1_, term2_) {} + + int getDegree() const + { + return std::max(super::term1.getDegree(), super::term2.getDegree()); + } + + inline value_type operator()(const int& iq) const + { + return std::min(super::term1(iq), super::term2(iq)); + } + + std::string str() const { return std::string("min(") + super::term1.str() + ", " + super::term2.str() + ")"; } + }; + + } // end namespace expressions + + + namespace result_of + { + template<typename Term1, typename Term2> + struct Min : boost::enable_if + < + typename traits::is_valid_arg2<Term1, Term2>::type, + expressions::Min + < + typename traits::to_expr<Term1>::type, + typename traits::to_expr<Term2>::type + > + > {}; + + + template<typename Term1, typename Term2> + struct Max : boost::enable_if + < + typename traits::is_valid_arg2<Term1, Term2>::type, + expressions::Max + < + typename traits::to_expr<Term1>::type, + typename traits::to_expr<Term2>::type + > + > {}; + + } // end namespace result_of + + + // maximum of two terms + // _____________________________________________________________________________ + template<typename Term1, typename Term2> + inline typename result_of::Max<Term1, Term2>::type + max(const Term1& t1, const Term2& t2) + { + typedef typename traits::to_expr<Term1>::to Expr1; + typedef typename traits::to_expr<Term2>::to Expr2; + return expressions::Max< typename Expr1::type, typename Expr2::type > + (Expr1::get(t1), Expr2::get(t2)); + } + + // minimum of two terms + // _____________________________________________________________________________ + template<typename Term1, typename Term2> + inline typename result_of::Min<Term1, Term2>::type + min(const Term1& t1, const Term2& t2) + { + typedef typename traits::to_expr<Term1>::to Expr1; + typedef typename traits::to_expr<Term2>::to Expr2; + return expressions::Min< typename Expr1::type, typename Expr2::type > + (Expr1::get(t1), Expr2::get(t2)); + } + + + //______________________________________________________________________________ + + // absolute value of a term + template<typename Term> + inline typename boost::enable_if< + typename traits::is_expr<Term>::type, + expressions::Abs<Term> >::type + abs_(const Term& t) { return expressions::Abs<Term>(t); } // TODO: Funktionsnamen ohne Unterstrich + + // signum of a term + template<typename Term> + inline typename boost::enable_if< + typename traits::is_expr<Term>::type, + expressions::Signum<Term> >::type + signum(const Term& t) { return expressions::Signum<Term>(t); } + + // + template<typename Term> + inline typename boost::enable_if< + typename traits::is_expr<Term>::type, + expressions::Ceil<Term> >::type + ceil(const Term& t) { return expressions::Ceil<Term>(t); } + + // + template<typename Term> + inline typename boost::enable_if< + typename traits::is_expr<Term>::type, + expressions::Floor<Term> >::type + floor(const Term& t) { return expressions::Floor<Term>(t); } + + //______________________________________________________________________________ + + // I'th power of a term + template<int I, typename Term> + inline typename boost::enable_if< + typename traits::is_expr<Term>::type, + expressions::Pow<I, Term> >::type + pow(const Term& t) { return expressions::Pow<I, Term>(t); } + + // square root of a term + template<typename Term> + inline typename boost::enable_if< + typename traits::is_expr<Term>::type, + expressions::Sqrt<Term> >::type + sqrt(const Term& t) { return expressions::Sqrt<Term>(t); } + + //______________________________________________________________________________ + + // exponential function of a term + template<typename Term> + inline typename boost::enable_if< + typename traits::is_expr<Term>::type, + expressions::Exp<Term> >::type + exp(const Term& t) { return expressions::Exp<Term>(t); } + + // natural logarithm of a term + template<typename Term> + inline typename boost::enable_if< + typename traits::is_expr<Term>::type, + expressions::Log<Term> >::type + log(const Term& t) { return expressions::Log<Term>(t); } + + //______________________________________________________________________________ + + // cosine function of a term + template<typename Term> + inline typename boost::enable_if< + typename traits::is_expr<Term>::type, + expressions::Cos<Term> >::type + cos(const Term& t) { return expressions::Cos<Term>(t); } + + // sine function of a term + template<typename Term> + inline typename boost::enable_if< + typename traits::is_expr<Term>::type, + expressions::Sin<Term> >::type + sin(const Term& t) { return expressions::Sin<Term>(t); } + + // tangens function of a term + template<typename Term> + inline typename boost::enable_if< + typename traits::is_expr<Term>::type, + expressions::Tan<Term> >::type + tan(const Term& t) { return expressions::Tan<Term>(t); } + + //______________________________________________________________________________ + + // arkuscosine function of a term + template<typename Term> + inline typename boost::enable_if< + typename traits::is_expr<Term>::type, + expressions::Acos<Term> >::type + acos(const Term& t) { return expressions::Acos<Term>(t); } + + // arkussine function of a term + template<typename Term> + inline typename boost::enable_if< + typename traits::is_expr<Term>::type, + expressions::Asin<Term> >::type + asin(const Term& t) { return expressions::Asin<Term>(t); } + + // arkustangens function of a term + template<typename Term> + inline typename boost::enable_if< + typename traits::is_expr<Term>::type, + expressions::Atan<Term> >::type + atan(const Term& t) { return expressions::Atan<Term>(t); } + + //______________________________________________________________________________ + + // cosine-hyperbolicus function of a term + template<typename Term> + inline typename boost::enable_if< + typename traits::is_expr<Term>::type, + expressions::Cosh<Term> >::type + cosh(const Term& t) { return expressions::Cosh<Term>(t); } + + // sine-hyperbolicus function of a term + template<typename Term> + inline typename boost::enable_if< + typename traits::is_expr<Term>::type, + expressions::Sinh<Term> >::type + sinh(const Term& t) { return expressions::Sinh<Term>(t); } + + // tangens-hyperbolicus function of a term + template<typename Term> + inline typename boost::enable_if< + typename traits::is_expr<Term>::type, + expressions::Tanh<Term> >::type + tanh(const Term& t) { return expressions::Tanh<Term>(t); } + + //______________________________________________________________________________ + + // arkuscosine-hypüerbolicus function of a term + template<typename Term> + inline typename boost::enable_if< + typename traits::is_expr<Term>::type, + expressions::Acosh<Term> >::type + acosh(const Term& t) { return expressions::Acosh<Term>(t); } + + // arkussine-hyperbolicus function of a term + template<typename Term> + inline typename boost::enable_if< + typename traits::is_expr<Term>::type, + expressions::Asinh<Term> >::type + asinh(const Term& t) { return expressions::Asinh<Term>(t); } + + // arkustangens-hyperbolicus function of a term + template<typename Term> + inline typename boost::enable_if< + typename traits::is_expr<Term>::type, + expressions::Atanh<Term> >::type + atanh(const Term& t) { return expressions::Atanh<Term>(t); } + +} // end namespace AMDiS + +#endif // AMDIS_CMATH_EXPRESSION_HPP diff --git a/AMDiS/src/expressions/coords_expr.hpp b/AMDiS/src/expressions/coords_expr.hpp new file mode 100644 index 0000000000000000000000000000000000000000..ab75686bbcf5ab7296a9347be84d78ebbbebcda6 --- /dev/null +++ b/AMDiS/src/expressions/coords_expr.hpp @@ -0,0 +1,359 @@ +/****************************************************************************** + * + * AMDiS - Adaptive multidimensional simulations + * + * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. + * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis + * + * Authors: + * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * + * This file is part of AMDiS + * + * See also license.opensource.txt in the distribution. + * + ******************************************************************************/ + + + +/** \file coords_expr.hpp */ + +#ifndef AMDIS_COORDS_EXPRESSION_HPP +#define AMDIS_COORDS_EXPRESSION_HPP + +#include "AMDiS_fwd.h" +#include "LazyOperatorTerm.h" + +namespace AMDiS +{ + namespace expressions + { + /// Expression that representy the coordinate vector + struct Coords : public LazyOperatorTermBase + { + typedef WorldVector<double> value_type; + mutable mtl::dense_vector<WorldVector<double> > x; + + Coords() {} + + template<typename List> + void insertFeSpaces(List& feSpaces) const {} + + int getDegree() const { return 1; } + + template<typename OT> + void initElement(OT* ot, const ElInfo* elInfo, + SubAssembler* subAssembler, Quadrature *quad, + const BasisFunction *basisFct = NULL) + { + if (subAssembler) { + subAssembler->getCoordsAtQPs(elInfo, quad, x); + } + else if (quad) { + const int nPoints = quad->getNumPoints(); + + x.change_dim(nPoints); + for (int i = 0; i < nPoints; i++) + elInfo->coordToWorld(quad->getLambda(i), x[i]); + } + else if (basisFct) { + const int nBasisFct = basisFct->getNumber(); + + x.change_dim(nBasisFct); + for (int i = 0; i < nBasisFct; i++) + elInfo->coordToWorld(*basisFct->getCoords(i), x[i]); + } + } + + + template<typename OT> + void initElement(OT* ot, const ElInfo* smallElInfo, const ElInfo* largeElInfo, + SubAssembler* subAssembler, Quadrature *quad, + const BasisFunction *basisFct = NULL) + { + if (subAssembler) { + subAssembler->getCoordsAtQPs(smallElInfo, quad, x); + } + else if (quad) { + const int nPoints = quad->getNumPoints(); + + x.change_dim(nPoints); + for (int i = 0; i < nPoints; i++) + smallElInfo->coordToWorld(quad->getLambda(i), x[i]); + } + else if (basisFct) { + const int nBasisFct = basisFct->getNumber(); + + x.change_dim(nBasisFct); + for (int i = 0; i < nBasisFct; i++) + smallElInfo->coordToWorld(*basisFct->getCoords(i), x[i]); + } + } + + inline value_type operator()(const int& iq) const { return x[iq]; } + + std::string str() { return "X"; } + }; + + + /// Expression that represents the Ith component of the coordinate vector + template<int I_> + struct Coord : public LazyOperatorTermBase + { + typedef double value_type; + mutable mtl::dense_vector<WorldVector<double> > x; + int I; + + Coord(int i = -1) : I(i >= 0 ? i : I_) { } + + template<typename List> + void insertFeSpaces(List& feSpaces) const {} + + int getDegree() const { return 1; } + + template<typename OT> + void initElement(OT* ot, const ElInfo* elInfo, + SubAssembler* subAssembler, Quadrature *quad, + const BasisFunction *basisFct = NULL) + { + if (subAssembler) { + subAssembler->getCoordsAtQPs(elInfo, quad, x); + } + else if (quad) { + const int nPoints = quad->getNumPoints(); + + x.change_dim(nPoints); + for (int i = 0; i < nPoints; i++) + elInfo->coordToWorld(quad->getLambda(i), x[i]); + } + else if (basisFct) { + const int nBasisFct = basisFct->getNumber(); + + x.change_dim(nBasisFct); + for (int i = 0; i < nBasisFct; i++) + elInfo->coordToWorld(*basisFct->getCoords(i), x[i]); + } + } + + template<typename OT> + void initElement(OT* ot, const ElInfo* smallElInfo, const ElInfo* largeElInfo, + SubAssembler* subAssembler, Quadrature *quad, + const BasisFunction *basisFct = NULL) + { + if (subAssembler) { + subAssembler->getCoordsAtQPs(smallElInfo, quad, x); + } + else if (quad) { + const int nPoints = quad->getNumPoints(); + + x.change_dim(nPoints); + for (int i = 0; i < nPoints; i++) + smallElInfo->coordToWorld(quad->getLambda(i), x[i]); + } + else if (basisFct) { + const int nBasisFct = basisFct->getNumber(); + + x.change_dim(nBasisFct); + for (int i = 0; i < nBasisFct; i++) + smallElInfo->coordToWorld(*basisFct->getCoords(i), x[i]); + } + } + + inline double operator()(const int& iq) const { return x[iq][I]; } + + std::string str() { return std::string("X<") + boost::lexical_cast<std::string>(I) + ">"; } + }; + + + /// Expression that represents the element normal vector + /** In the constructor the corresponding face must be given, of which + you want to calculate the normal vector. **/ + struct Normals : public LazyOperatorTermBase + { + typedef WorldVector<double> value_type; + mutable WorldVector<double> normal; + int side; + + Normals(int side_) : side(side_) {} + + template<typename List> + void insertFeSpaces(List& feSpaces) const {} + + int getDegree() const { return 1; } + + template<typename OT> + void initElement(OT* ot, const ElInfo* elInfo, + SubAssembler* subAssembler, Quadrature *quad, + const BasisFunction *basisFct = NULL) + { + elInfo->getNormal(side, normal); + } + + + template<typename OT> + void initElement(OT* ot, const ElInfo* smallElInfo, const ElInfo* largeElInfo, + SubAssembler* subAssembler, Quadrature *quad, + const BasisFunction *basisFct = NULL) + { + smallElInfo->getNormal(side, normal); + } + + inline value_type operator()(const int& iq) const { return normal; } + + std::string str() { return "N"; } + }; + + + /// Expression that represents the Ith component of an element normal vector + /** In the constructor the corresponding face must be given, of which + you want to calculate the normal vector. **/ + struct Normal : public LazyOperatorTermBase + { + typedef double value_type; + mutable WorldVector<double> normal; + BoundaryType boundary; + int I; + + Normal(BoundaryType boundary_, int I_) : boundary(boundary_), I(I_) {} + + template<typename List> + void insertFeSpaces(List& feSpaces) const {} + + int getDegree() const { return 1; } + + template<typename OT> + void initElement(OT* ot, const ElInfo* elInfo, + SubAssembler* subAssembler, Quadrature *quad, + const BasisFunction *basisFct = NULL) + { + int dim = elInfo->getMesh()->getDim(); + for (int side = 0; side < dim+1; ++side) { + if (elInfo->getBoundary(side) == boundary) { + elInfo->getNormal(side, normal); + break; + } + } + } + + + template<typename OT> + void initElement(OT* ot, const ElInfo* smallElInfo, const ElInfo* largeElInfo, + SubAssembler* subAssembler, Quadrature *quad, + const BasisFunction *basisFct = NULL) + { + initElement(ot, smallElInfo, subAssembler, quad, basisFct); + } + + inline value_type operator()(const int& iq) const { return normal[I]; } + + std::string str() { return std::string("N<") + boost::lexical_cast<std::string>(I) + ">"; } + }; + + + /// Expression that represents the surface normal vector + struct ElementNormals : public LazyOperatorTermBase + { + typedef WorldVector<double> value_type; + mutable WorldVector<double> elementNormal; + + ElementNormals() {} + + template<typename List> + void insertFeSpaces(List& feSpaces) const {} + + int getDegree() const { return 1; } + + template<typename OT> + void initElement(OT* ot, const ElInfo* elInfo, + SubAssembler* subAssembler, Quadrature *quad, + const BasisFunction *basisFct = NULL) + { + elInfo->getElementNormal(elementNormal); + } + + + template<typename OT> + void initElement(OT* ot, const ElInfo* smallElInfo, const ElInfo* largeElInfo, + SubAssembler* subAssembler, Quadrature *quad, + const BasisFunction *basisFct = NULL) + { + smallElInfo->getElementNormal(elementNormal); + } + + inline value_type operator()(const int& iq) const { return elementNormal; } + + std::string str() { return "M"; } + }; + + + /// Expression that represents the Ith component of a surface normal vector + struct ElementNormal : public LazyOperatorTermBase + { + typedef double value_type; + mutable WorldVector<double> elementNormal; + int I; + + ElementNormal(int I_) : I(I_) {} + + template<typename List> + void insertFeSpaces(List& feSpaces) const {} + + int getDegree() const { return 1; } + + template<typename OT> + void initElement(OT* ot, const ElInfo* elInfo, + SubAssembler* subAssembler, Quadrature *quad, + const BasisFunction *basisFct = NULL) + { + elInfo->getElementNormal(elementNormal); + } + + + template<typename OT> + void initElement(OT* ot, const ElInfo* smallElInfo, const ElInfo* largeElInfo, + SubAssembler* subAssembler, Quadrature *quad, + const BasisFunction *basisFct = NULL) + { + smallElInfo->getElementNormal(elementNormal); + } + + inline value_type operator()(const int& iq) const { return elementNormal[I]; } + + std::string str() { return std::string("M<") + boost::lexical_cast<std::string>(I) + ">"; } + }; + + } // end namespace expressions + + + inline expressions::Coords X() + { return expressions::Coords(); } + + template<int I> + inline expressions::Coord<I> X() + { return expressions::Coord<I>(); } + + inline expressions::Coord<-1> X(int i) + { return expressions::Coord<-1>(i); } + + + inline expressions::Normals N(int side) + { return expressions::Normals(side); } + + inline expressions::Normal N(int side, int I) + { return expressions::Normal(side, I); } + + + inline expressions::ElementNormals M() + { return expressions::ElementNormals(); } + + inline expressions::ElementNormal M(int I) + { return expressions::ElementNormal(I); } + + +} // end namespace AMDiS + +#endif // AMDIS_COORDS_EXPRESSION_HPP diff --git a/AMDiS/src/expressions/diff_expr.hpp b/AMDiS/src/expressions/diff_expr.hpp new file mode 100644 index 0000000000000000000000000000000000000000..5eb8a48a464925a51f0b16127086d7d1a0ecb629 --- /dev/null +++ b/AMDiS/src/expressions/diff_expr.hpp @@ -0,0 +1,684 @@ +/****************************************************************************** + * + * AMDiS - Adaptive multidimensional simulations + * + * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. + * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis + * + * Authors: + * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * + * This file is part of AMDiS + * + * See also license.opensource.txt in the distribution. + * + ******************************************************************************/ + + + +/** \file diff_expr.hpp */ + +#ifndef AMDIS_DIFF_EXPRESSION_HPP +#define AMDIS_DIFF_EXPRESSION_HPP + +#include "AMDiS_fwd.h" +#include "LazyOperatorTerm.h" +#include "simplify_expr.hpp" + +namespace AMDiS +{ + // by default the derivative is zero + namespace expressions + { + struct DummyType { + typedef _unknown id; + typedef double value_type; + }; + + template<typename Identifier, typename Term, typename Direction = DummyType> + struct Diff + { + typedef CValue<0> type; + typedef CValue<0> dir_type; + static type eval(Term const& t) { return CValue<0>(); } + static dir_type eval(Term const& t, Direction const& d) { return CValue<0>(); } + }; + + } // end namespace expressions + + template<typename Id, typename Term> + inline typename expressions::Diff<Id,Term>::type + diff(const Term& t) { return expressions::Diff<Id,Term>::eval(t); } + + template<typename Id, typename Term, typename Direction> + inline typename expressions::Diff<Id,Term,Direction>::dir_type + diff(const Term& t, const Direction& d) { return expressions::Diff<Id,Term,Direction>::eval(t,d); } + + + // _____________________________________________________________________________ + // value/gradient expressions + namespace expressions + { + // ValueOf + template<typename Id, typename Vector, typename Name, typename Direction> + struct Diff< Id, ValueOf<Vector, Name>, Direction > + { + typedef ValueOf<Vector, Name> Term; + typedef CValue<0> type; + typedef CValue<0> dir_type; + + static type eval(Term const& t) { return CValue<0>(); } + static dir_type eval(Term const& t, Direction const& d) { return CValue<0>(); } + }; + + template<typename Id, typename Vector, typename Direction> + struct Diff< Id, ValueOf<Vector, Id>, Direction > + { + typedef expressions::ValueOf<Vector, Id> Term; + typedef CValue<1> type; + typedef Direction dir_type; + + static type eval(Term const& t) { return CValue<1>(); } + static dir_type eval(Term const& t, Direction const& d) { return d; } + }; + + + // GradientOf + template<typename Id, typename Vector, typename Name, typename Direction> + struct Diff< Id, GradientOf<Vector, Name>, Direction > + { + typedef GradientOf<Vector, Name> Term; + typedef CValue<0> type; + typedef CValue<0> dir_type; + + static type eval(Term const& t) { return CValue<0>(); } + static dir_type eval(Term const& t, Direction const& d) { return CValue<0>(); } + }; + + template<typename Id, typename Vector, typename Direction> + struct Diff< Id, GradientOf<Vector, Id>, Direction > + { + typedef GradientOf<Vector, Id> Term; + typedef CValue<0> type; + typedef GradientOf<Vector, typename Direction::id> dir_type; + + static type eval(Term const& t) { return CValue<0>(); } + static dir_type eval(Term const& t, Direction const& d) { return gradientOf<typename Direction::id>(d.vecDV); } + }; + + + // DerivativeOf + template<typename Id, int I, typename Vector, typename Name, typename Direction> + struct Diff< Id, DerivativeOf<I, Vector, Name>, Direction > + { + typedef DerivativeOf<I, Vector, Name> Term; + typedef CValue<0> type; + typedef CValue<0> dir_type; + + static type eval(Term const& t) { return CValue<0>(); } + static dir_type eval(Term const& t, Direction const& d) { return CValue<0>(); } + }; + + template<typename Id, int I, typename Vector, typename Direction> + struct Diff< Id, DerivativeOf<I, Vector, Id>, Direction > + { + typedef DerivativeOf<I, Vector, Id> original_type; + typedef CValue<0> type; + typedef DerivativeOf<I, Vector, typename Direction::id> dir_type; + + static type eval(original_type const& t) { return CValue<0>(); } + static dir_type eval(original_type const& t, Direction const& d) { return derivativeOf<typename Direction::id, I>(d.vecDV); } + }; + + } // end namespace expressions + + + // _____________________________________________________________________________ + // multiplication expressions + namespace expressions + { + + template<typename Id, typename Term1, typename Term2, typename Direction> + class Diff< Id, Mult<Term1, Term2>, Direction > + { + typedef typename Simplify< typename Diff<Id, Term1>::type >::type D1; + typedef typename Simplify< typename Diff<Id, Term2>::type >::type D2; + typedef typename Simplify< typename Diff<Id, Term1, Direction>::dir_type >::type D1_; + typedef typename Simplify< typename Diff<Id, Term2, Direction>::dir_type >::type D2_; + + public: + typedef Mult<Term1, Term2> original_type; + typedef typename Simplify< Add< Mult< D1, Term2 >, + Mult< Term1, D2 > > >::type type; + typedef typename Simplify< Add< Mult< D1_, Term2 >, + Mult< Term1, D2_> > >::type dir_type; + + static type eval(original_type const& t) + { + return simplify(simplify(diff<Id>(t.term1)) * t.term2 + t.term1 * simplify(diff<Id>(t.term2))); + } + + static dir_type eval(original_type const& t, Direction const& d) + { + return simplify(simplify(diff<Id>(t.term1,d)) * t.term2 + t.term1 * simplify(diff<Id>(t.term2,d))); + } + }; + + template<typename Id, typename Term, typename Direction> + class Diff< Id, MultInverse<Term>, Direction > + { + typedef typename Simplify< typename Diff<Id, Term>::type >::type D; + typedef typename Simplify< typename Diff<Id, Term, Direction>::dir_type >::type D_; + + public: + typedef MultInverse<Term> original_type; + typedef typename Simplify< Mult< Negative<D>, + MultInverse< Pow<2, Term> > > >::type type; + typedef typename Simplify< Mult< Negative<D_>, + MultInverse< Pow<2, Term> > > >::type dir_type; + + static type eval(original_type const& t) + { + return simplify((-simplify(diff<Id>(t.term))) / pow<2>(t.term)); + } + + static dir_type eval(original_type const& t, Direction const& d) + { + return simplify((-simplify(diff<Id>(t.term,d))) / pow<2>(t.term)); + } + }; + + } // end namespace expressions + + + // _____________________________________________________________________________ + // add expressions + namespace expressions + { + + template<typename Id, typename Term1, typename Term2, typename Direction> + class Diff< Id, Add<Term1, Term2>, Direction > + { + typedef typename Simplify< typename Diff<Id, Term1>::type >::type D1; + typedef typename Simplify< typename Diff<Id, Term2>::type >::type D2; + typedef typename Simplify< typename Diff<Id, Term1, Direction>::dir_type >::type D1_; + typedef typename Simplify< typename Diff<Id, Term2, Direction>::dir_type >::type D2_; + + public: + typedef Add<Term1, Term2> original_type; + typedef typename Simplify< Add< D1, D2 > >::type type; + typedef typename Simplify< Add< D1_, D2_ > >::type dir_type; + + static type eval(original_type const& t) + { + return simplify(simplify(diff<Id>(t.term1)) + simplify(diff<Id>(t.term2))); + } + + static dir_type eval(original_type const& t, Direction const& d) + { + return simplify(simplify(diff<Id>(t.term1,d)) + simplify(diff<Id>(t.term2,d))); + } + }; + + template<typename Id, typename Term, typename Direction> + struct Diff< Id, Negative<Term>, Direction > + { + typedef Negative<Term> original_type; + typedef typename Simplify< Negative< typename Diff<Id, Term>::type > >::type type; + typedef typename Simplify< Negative< typename Diff<Id, Term, Direction>::dir_type > >::type dir_type; + + static type eval(original_type const& t) + { + return simplify(-diff<Id>(t.term)); + } + + static dir_type eval(original_type const& t, Direction const& d) + { + return simplify(-diff<Id>(t.term,d)); + } + }; + + } // end namespace expressions + + + // _____________________________________________________________________________ + // absolute value and signum + namespace expressions + { + template<typename Term, typename Id> + struct Diff< Id, Abs<Term> > {}; // not yet implemented + + } // end namespace expressions + + + // _____________________________________________________________________________ + // powers and roots + namespace expressions + { + template<typename Id, int I, typename Term, typename Direction> + class Diff< Id, Pow<I, Term>,Direction > + { + typedef typename Simplify< typename Diff<Id, Term>::type >::type D; + typedef typename Simplify< typename Diff<Id, Term, Direction>::dir_type >::type D_; + + public: + typedef Pow<I, Term> original_type; + typedef typename Simplify< Mult< Mult<D, CValue<I> >, Pow<I-1, Term> > >::type type; + typedef typename Simplify< Mult< Mult<D_, CValue<I> >, Pow<I-1, Term> > >::type dir_type; + + static type eval(original_type const& t) + { + return simplify(simplify(diff<Id>(t.term)) * CValue<I>() * pow<I-1>(t.term)); + } + + static dir_type eval(original_type const& t, Direction const& d) + { + return simplify(simplify(diff<Id>(t.term, d)) * CValue<I>() * pow<I-1>(t.term)); + } + }; + + template<typename Id, typename Term, typename Direction> + class Diff< Id, Pow<1, Term>, Direction > + { + typedef typename Simplify< typename Diff<Id, Term>::type >::type D; + typedef typename Simplify< typename Diff<Id, Term, Direction>::dir_type >::type D_; + + public: + typedef Pow<1, Term> original_type; + typedef D type; + typedef D_ dir_type; + + static type eval(original_type const& t) + { + return simplify(diff<Id>(t.term)); + } + + static dir_type eval(original_type const& t, Direction const& d) + { + return simplify(diff<Id>(t.term, d)); + } + }; + + template<typename Id, typename Term, typename Direction> + class Diff< Id, Sqrt<Term>, Direction > + { + typedef typename Simplify< typename Diff<Id, Term>::type >::type D; + typedef typename Simplify< typename Diff<Id, Term, Direction>::dir_type >::type D_; + + public: + typedef Sqrt<Term> original_type; + typedef typename Simplify< Mult< D, MultInverse< Mult< CValue<2>, Sqrt<Term> > > > >::type type; + typedef typename Simplify< Mult< D_, MultInverse< Mult< CValue<2>, Sqrt<Term> > > > >::type dir_type; + + static type eval(original_type const& t) + { + return simplify(simplify(diff<Id>(t.term)) / (CValue<2>() * sqrt(t.term))); + } + + static dir_type eval(original_type const& t, Direction const& d) + { + return simplify(simplify(diff<Id>(t.term, d)) / (CValue<2>() * sqrt(t.term))); + } + }; + + } // end namespace expressions + + + // _____________________________________________________________________________ + // exponential function and logarithms + namespace expressions + { + template<typename Id, typename Term, typename Direction> + class Diff< Id, Exp<Term>, Direction > + { + typedef typename Simplify< typename Diff<Id, Term>::type >::type D; + typedef typename Simplify< typename Diff<Id, Term, Direction>::dir_type >::type D_; + + public: + typedef Exp<Term> original_type; + typedef typename Simplify< Mult< D, Exp<Term> > >::type type; + typedef typename Simplify< Mult< D_, Exp<Term> > >::type dir_type; + + static type eval(Exp<Term> const& t) + { + return simplify(simplify(diff<Id>(t.term)) * exp(t.term)); + } + + static dir_type eval(original_type const& t, Direction const& d) + { + return simplify(simplify(diff<Id>(t.term, d)) * exp(t.term)); + } + }; + + template<typename Id, typename Term, typename Direction> + class Diff< Id, Log<Term>, Direction > + { + typedef typename Simplify< typename Diff<Id, Term>::type >::type D; + typedef typename Simplify< typename Diff<Id, Term, Direction>::dir_type >::type D_; + + public: + typedef Log<Term> original_type; + typedef typename Simplify< Mult< D, MultInverse<Term> > >::type type; + typedef typename Simplify< Mult< D_, MultInverse<Term> > >::type dir_type; + + static type eval(original_type const& t) + { + return simplify(simplify(diff<Id>(t.term)) / t.term); + } + + static dir_type eval(original_type const& t, Direction const& d) + { + return simplify(simplify(diff<Id>(t.term, d)) / t.term); + } + }; + + } // end namespace expressions + + // _____________________________________________________________________________ + // cosine, sine and tangence + namespace expressions + { + template<typename Id, typename Term, typename Direction> + class Diff< Id, Cos<Term>, Direction > + { + typedef typename Simplify< typename Diff<Id, Term>::type >::type D; + typedef typename Simplify< typename Diff<Id, Term, Direction>::dir_type >::type D_; + + public: + typedef Cos<Term> original_type; + typedef typename Simplify< Negative< Mult< D, Sin<Term> > > >::type type; + typedef typename Simplify< Negative< Mult< D_, Sin<Term> > > >::type dir_type; + + static type eval(original_type const& t) + { + return simplify(-(simplify(diff<Id>(t.term)) * sin(t.term))); + } + + static dir_type eval(original_type const& t, Direction const& d) + { + return simplify(-(simplify(diff<Id>(t.term, d)) * sin(t.term))); + } + }; + + template<typename Id, typename Term, typename Direction> + class Diff< Id, Sin<Term>, Direction > + { + typedef typename Simplify< typename Diff<Id, Term>::type >::type D; + typedef typename Simplify< typename Diff<Id, Term, Direction>::dir_type >::type D_; + + public: + typedef Sin<Term> original_type; + typedef typename Simplify< Mult< D, Cos<Term> > >::type type; + typedef typename Simplify< Mult< D_, Cos<Term> > >::type dir_type; + + static type eval(original_type const& t) + { + return simplify(simplify(diff<Id>(t.term)) * cos(t.term)); + } + + static dir_type eval(original_type const& t, Direction const& d) + { + return simplify(simplify(diff<Id>(t.term, d)) * cos(t.term)); + } + }; + + template<typename Id, typename Term, typename Direction> + class Diff< Id, Tan<Term>, Direction > + { + typedef typename Simplify< typename Diff<Id, Term>::type >::type D; + typedef typename Simplify< typename Diff<Id, Term, Direction>::dir_type >::type D_; + + public: + typedef Tan<Term> original_type; + typedef typename Simplify< Mult< D, Add< CValue<1>, Negative< Pow<2, Tan<Term> > > > > >::type type; + typedef typename Simplify< Mult< D_, Add< CValue<1>, Negative< Pow<2, Tan<Term> > > > > >::type dir_type; + + static type eval(original_type const& t) + { + return simplify(simplify(diff<Id>(t.term)) * (CValue<1>() - pow<2>(tan(t.term)))); + } + + static dir_type eval(original_type const& t, Direction const& d) + { + return simplify(simplify(diff<Id>(t.term, d)) * (CValue<1>() - pow<2>(tan(t.term)))); + } + }; + + } // end namespace expressions + + // _____________________________________________________________________________ + // arcus-(cosine, sine, tangence) + namespace expressions + { + template<typename Id, typename Term, typename Direction> + class Diff< Id, Acos<Term>, Direction > + { + typedef typename Simplify< typename Diff<Id, Term>::type >::type D; + typedef typename Simplify< typename Diff<Id, Term, Direction>::dir_type >::type D_; + + public: + typedef Acos<Term> original_type; + typedef typename Simplify< Negative< Mult< D, MultInverse< Add< CValue<1>, Negative< Pow<2, Term> > > > > > >::type type; + typedef typename Simplify< Negative< Mult< D_, MultInverse< Add< CValue<1>, Negative< Pow<2, Term> > > > > > >::type dir_type; + + static type eval(original_type const& t) + { + return simplify(-(simplify(diff<Id>(t.term)) / (CValue<1>() - pow<2>(t.term)))); + } + + static dir_type eval(original_type const& t, Direction const& d) + { + return simplify(-(simplify(diff<Id>(t.term, d)) / (CValue<1>() - pow<2>(t.term)))); + } + }; + + template<typename Id, typename Term, typename Direction> + class Diff< Id, Asin<Term>, Direction > + { + typedef typename Simplify< typename Diff<Id, Term>::type >::type D; + typedef typename Simplify< typename Diff<Id, Term, Direction>::dir_type >::type D_; + + public: + typedef Asin<Term> original_type; + typedef typename Simplify< Mult< D, MultInverse< Sqrt< Add< CValue<1>, Negative< Pow<2, Term> > > > > > >::type type; + typedef typename Simplify< Mult< D_, MultInverse< Sqrt< Add< CValue<1>, Negative< Pow<2, Term> > > > > > >::type dir_type; + + static type eval(original_type const& t) + { + return simplify(simplify(diff<Id>(t.term)) / sqrt(CValue<1>() - pow<2>(t.term))); + } + + static dir_type eval(original_type const& t, Direction const& d) + { + return simplify(simplify(diff<Id>(t.term, d)) / sqrt(CValue<1>() - pow<2>(t.term))); + } + }; + + template<typename Id, typename Term, typename Direction> + class Diff< Id, Atan<Term>, Direction > + { + typedef typename Simplify< typename Diff<Id, Term>::type >::type D; + typedef typename Simplify< typename Diff<Id, Term, Direction>::dir_type >::type D_; + + public: + typedef Atan<Term> original_type; + typedef typename Simplify< Mult< D, MultInverse< Add< CValue<1>, Pow<2, Term> > > > >::type type; + typedef typename Simplify< Mult< D_, MultInverse< Add< CValue<1>, Pow<2, Term> > > > >::type dir_type; + + static type eval(original_type const& t) + { + return simplify(simplify(diff<Id>(t.term)) / (CValue<1>() + pow<2>(t.term))); + } + + static dir_type eval(original_type const& t, Direction const& d) + { + return simplify(simplify(diff<Id>(t.term, d)) / (CValue<1>() + pow<2>(t.term))); + } + }; + + template<typename Id, typename Term1, typename Term2> + struct Diff< Id, Atan2<Term1, Term2> > {}; + + } // end namespace expressions + + // _____________________________________________________________________________ + // (cose, sine ,tangence)-hyperbolicus + namespace expressions + { + template<typename Id, typename Term, typename Direction> + class Diff< Id, Cosh<Term>, Direction > + { + typedef typename Simplify< typename Diff<Id, Term>::type >::type D; + typedef typename Simplify< typename Diff<Id, Term, Direction>::dir_type >::type D_; + + public: + typedef Cosh<Term> original_type; + typedef typename Simplify< Mult< D, Sinh<Term> > >::type type; + typedef typename Simplify< Mult< D_, Sinh<Term> > >::type dir_type; + + static type eval(Cosh<Term> const& t) + { + return simplify(simplify(diff<Id>(t.term)) * sinh(t.term)); + } + + static dir_type eval(original_type const& t, Direction const& d) + { + return simplify(simplify(diff<Id>(t.term, d)) * sinh(t.term)); + } + }; + + template<typename Id, typename Term, typename Direction> + class Diff< Id, Sinh<Term>, Direction > + { + typedef typename Simplify< typename Diff<Id, Term>::type >::type D; + typedef typename Simplify< typename Diff<Id, Term, Direction>::dir_type >::type D_; + + public: + typedef Sinh<Term> original_type; + typedef typename Simplify< Mult< D, Cosh<Term> > >::type type; + typedef typename Simplify< Mult< D_, Cosh<Term> > >::type dir_type; + + static type eval(Sinh<Term> const& t) + { + return simplify(simplify(diff<Id>(t.term)) * cosh(t.term)); + } + + static dir_type eval(original_type const& t, Direction const& d) + { + return simplify(simplify(diff<Id>(t.term, d)) * cosh(t.term)); + } + }; + + template<typename Id, typename Term, typename Direction> + class Diff< Id, Tanh<Term>, Direction > + { + typedef typename Simplify< typename Diff<Id, Term>::type >::type D; + typedef typename Simplify< typename Diff<Id, Term, Direction>::dir_type >::type D_; + + public: + typedef Tanh<Term> original_type; + typedef typename Simplify< Mult< D, Add< CValue<1>, Negative< Pow<2, Tanh<Term> > > > > >::type type; + typedef typename Simplify< Mult< D_, Add< CValue<1>, Negative< Pow<2, Tanh<Term> > > > > >::type dir_type; + + static type eval(Tanh<Term> const& t) + { + return simplify(simplify(diff<Id>(t.term)) * (CValue<1>() - pow<2>(tanh(t.term)))); + } + + static dir_type eval(original_type const& t, Direction const& d) + { + return simplify(simplify(diff<Id>(t.term, d)) * (CValue<1>() - pow<2>(tanh(t.term)))); + } + }; + + } // end namespace expressions + + + #if 0 + // _____________________________________________________________________________ + // arcus-(cosine, sine, tangence)-hyperbolicus + namespace expressions { + + template<typename Id, typename Term> + struct Diff< Id, Acosh<Term> > {}; // not yet implemented + + template<typename Id, typename Term> + struct Diff< Id, Asinh<Term> > {}; // not yet implemented + + template<typename Id, typename Term> + struct Diff< Id, Atanh<Term> > {}; // not yet implemented + + } // end namespace expressions + + + // _____________________________________________________________________________ + // maximum and mininmum + namespace expressions { + + template<typename Id, typename Term1, typename Term2> + struct Diff< Id, Max<Term1, Term2> > {}; // not yet implemented + + template<typename Id, typename Term1, typename Term2> + struct Diff< Id, Min<Term1, Term2> > {}; // not yet implemented + + } // end namespace expressions + #endif + + // ============================================================================= + // higher order derivatives + + // forward declaration + namespace expressions + { + template<int N, class Id, class Term> struct DiffN; + + } // end namespace expressions + + template<int N, typename Id, typename Term> + inline typename expressions::DiffN<N,Id,Term>::type diff(const Term& t) { return expressions::DiffN<N,Id,Term>::eval(t); } + + namespace expressions + { + template<int N, class Id, class Term> + struct DiffN + { + typedef typename DiffN<N-1, Id, typename Diff<Id, Term>::type>::type type; + + static type eval(Term const& t) + { + return diff<N-1, Id>(diff<Id>(t)); + } + }; + + template<class Id, class Term> + struct DiffN<1, Id, Term> + { + typedef typename Diff<Id, Term>::type type; + + static type eval(Term const& t) + { + return diff<Id>(t); + } + }; + + template<class Id, class Term> + struct DiffN<0, Id, Term> + { + typedef Term type; + + static type eval(Term const& t) + { + return t; + } + }; + + } // end namespace expressions + + +} // end namespace AMDiS + +#endif // AMDIS_DIFF_EXPRESSION_HPP diff --git a/AMDiS/src/expressions/expr_traits.hpp b/AMDiS/src/expressions/expr_traits.hpp new file mode 100644 index 0000000000000000000000000000000000000000..15c9bc1b2ad374db2a5145cef5ea0e208cc162a8 --- /dev/null +++ b/AMDiS/src/expressions/expr_traits.hpp @@ -0,0 +1,142 @@ +/****************************************************************************** + * + * AMDiS - Adaptive multidimensional simulations + * + * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. + * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis + * + * Authors: + * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * + * This file is part of AMDiS + * + * See also license.opensource.txt in the distribution. + * + ******************************************************************************/ + + + +/** \file expr_traits.hpp */ + +#ifndef AMDIS_EXPR_TRAITS_HPP +#define AMDIS_EXPR_TRAITS_HPP + +#include "Traits.h" +#include "LazyOperatorTerm.h" +#include "value_expr.hpp" + +namespace AMDiS +{ + namespace traits + { + + // type-trait for short-cuts for constants + // ___________________________________________________________________________ + + template<typename T> + struct is_constant : is_numeric<T>::type {}; + + template<typename T> + struct is_constant<WorldVector<T> > : boost::mpl::bool_<true> {}; + + template<typename T> + struct is_constant<WorldMatrix<T> > : boost::mpl::bool_<true> {}; + + + // type-traits for terms + // ___________________________________________________________________________ + template<typename T> + struct is_expr : boost::is_base_of<LazyOperatorTermBase, T>::type {}; + + + // type-traits for arguments, filter terms and constants + // ___________________________________________________________________________ + template<typename T> + struct is_valid_arg : boost::mpl::or_ + < + typename is_expr<T>::type, + typename is_constant<T>::type + >::type {}; + + template<typename T1, typename T2> + struct is_valid_arg2 : boost::mpl::and_ + < + typename is_valid_arg<T1>::type, + typename is_valid_arg<T2>::type, + typename boost::mpl::or_ + < + typename is_expr<T1>::type, + typename is_expr<T2>::type + >::type + >::type {}; + + template<typename T1, typename T2, typename T3> + struct is_valid_arg3 : boost::mpl::and_ + < + typename is_valid_arg<T1>::type, + typename is_valid_arg<T2>::type, + typename is_valid_arg<T3>::type, + typename boost::mpl::or_ + < + typename is_expr<T1>::type, + typename is_expr<T2>::type, + typename is_expr<T3>::type + >::type + >::type {}; + + + + // expressions + template < typename T > + struct category<T, typename boost::enable_if< typename is_expr<T>::type >::type > + { + typedef tag::expression tag; + typedef typename T::value_type value_type; + // typedef size_t size_type; + }; + + + // type-conversion + // ___________________________________________________________________________ + + template<typename T, bool IsValid, bool IsConstant> + struct to_expr_aux { + typedef void type; + }; + + template<typename T> + struct to_expr_aux<T, /*IsValid: */true, /*IsConstant: */false> + { + typedef T type; + static const type& get(const T& t) + { + return t; + } + }; + + template<typename T> // T is numeric constant + struct to_expr_aux<T, /*IsValid: */true, /*IsConstant: */true> + { + typedef ::AMDiS::expressions::RValue<T> type; + static type get(const T& t) + { + return type(t); + } + }; + + template<typename T> + struct to_expr + { + typedef to_expr_aux<T, is_valid_arg<T>::value, is_constant<T>::value> to; + typedef typename to::type type; + }; + + } // end namespace traits + +} // end namespace AMDiS + +#endif // AMDIS_EXPR_TRAITS_HPP diff --git a/AMDiS/src/expressions/expressions.h b/AMDiS/src/expressions/expressions.h new file mode 100644 index 0000000000000000000000000000000000000000..78e27b953c332210f1178d832cd5b09d63cb30cb --- /dev/null +++ b/AMDiS/src/expressions/expressions.h @@ -0,0 +1,44 @@ +/****************************************************************************** + * + * AMDiS - Adaptive multidimensional simulations + * + * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. + * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis + * + * Authors: + * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * + * This file is part of AMDiS + * + * See also license.opensource.txt in the distribution. + * + ******************************************************************************/ + + + +/** \file expressions.h */ + +#ifndef AMDIS_EXPRESSIONS_H +#define AMDIS_EXPRESSIONS_H + +#include "expr_traits.hpp" // collection of traits necessary to construct expressions +#include "value_expr.hpp" // constants +#include "coords_expr.hpp" // coordinates / normal vectors +#include "valueOf.hpp" // value of DOFVector at QPs +#include "gradientOf.hpp" // gradient of DOFVector at QPs + +#include "add_expr.hpp" // add two expressions +#include "mult_expr.hpp" // multiply two expressions +#if __cplusplus > 199711L + #include "functorN_expr.hpp" // apply a functor with arbitrary nr. of arguments to expressions +#else + #include "functor_expr.hpp" // apply a functor with 1/2/3 arguments to expressions +#endif +#include "cmath_expr.hpp" // apply a cmath function to expressions +#include "vec_functors.hpp" // apply a vector function to expressions + +#endif // AMDIS_EXPRESSIONS_H diff --git a/AMDiS/src/expressions/functorN_expr.hpp b/AMDiS/src/expressions/functorN_expr.hpp new file mode 100644 index 0000000000000000000000000000000000000000..f333949f6c599cfb8f211e4f86018d4a315325f9 --- /dev/null +++ b/AMDiS/src/expressions/functorN_expr.hpp @@ -0,0 +1,259 @@ +/****************************************************************************** + * + * AMDiS - Adaptive multidimensional simulations + * + * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. + * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis + * + * Authors: + * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * + * This file is part of AMDiS + * + * See also license.opensource.txt in the distribution. + * + ******************************************************************************/ + + + +/** \file functorN_expr.h */ + +#ifndef AMDIS_FUNCTOR_N_EXPRESSION_HPP +#define AMDIS_FUNCTOR_N_EXPRESSION_HPP + +#include "AMDiS_fwd.h" +#include "LazyOperatorTerm.h" +#include "Functors.h" +#include "expressions/functor_expr.hpp" +#include "operations/functors.hpp" + +#include <boost/static_assert.hpp> + +#include <tuple> +#include <utility> + +namespace AMDiS +{ + /// for_each for std::tuple + template<std::size_t I = 0, typename FuncT, typename... Tp> + inline typename std::enable_if<I == sizeof...(Tp), void>::type + for_each(std::tuple<Tp...> &, FuncT) { } + + template<std::size_t I = 0, typename FuncT, typename... Tp> + inline typename std::enable_if<I < sizeof...(Tp), void>::type + for_each(std::tuple<Tp...>& t, FuncT f) + { + f(std::get<I>(t)); + for_each<I + 1, FuncT, Tp...>(t, f); + } + + template<int I> + using int_ = std::integral_constant<int, I>; + + + namespace traits + { + /// get the degree of a functor by combining the degrees of the arguments + template<typename F, typename Enable = void> + struct functor_degree + { + template<typename... Int> + static int eval(F f, Int... d) { return 0; } + }; + + template<typename F> + struct functor_degree<F, typename std::enable_if<boost::is_base_of<FunctorBase, F>::value>::type > + { + template<typename... Int> + static int eval(F f, Int... d) { return f.getDegree(d...); } + }; + } + + + namespace detail + { + /// Functor that initializes the feSpace list + template<typename List> + struct InsertFeSpaces + { + List& feSpaces; + InsertFeSpaces(List& feSpaces_) : feSpaces(feSpaces_) {}; + + template<typename Term> + void operator()(Term& term) { + term.insertFeSpaces(feSpaces); + } + }; + + /// Functor that is called on each term to initialize it on an element + template<typename OT> + struct InitElement + { + OT* ot; + const ElInfo *elInfo, *elInfo2; + SubAssembler* subAssembler; + Quadrature *quad; + const BasisFunction *basisFct; + + InitElement(OT* ot_, const ElInfo* elInfo_, SubAssembler* subAssembler_, Quadrature *quad_, const BasisFunction *basisFct_) + : ot(ot_), elInfo(elInfo_), elInfo2(NULL), subAssembler(subAssembler_), + quad(quad_), basisFct(basisFct_) {} + + InitElement(OT* ot_, const ElInfo* smallElInfo_, const ElInfo* largeElInfo_, SubAssembler* subAssembler_, Quadrature *quad_, const BasisFunction *basisFct_) + : ot(ot_), elInfo(smallElInfo_), elInfo2(largeElInfo_), subAssembler(subAssembler_), + quad(quad_), basisFct(basisFct_) {} + + template<typename Term> + void operator()(Term& term) { + if (elInfo2) + term.initElement(ot, elInfo, elInfo2, subAssembler, quad, basisFct); + else + term.initElement(ot, elInfo, subAssembler, quad, basisFct); + } + }; + + } // end namespace detail + + + /// Operator term with arbitrary number of sub-term (expressions) + template<typename... Terms> + struct LazyOperatorTerms : public LazyOperatorTermBase + { + std::tuple<Terms...> term_tuple; + + template<typename... Terms_> + LazyOperatorTerms(Terms_... terms_) + : term_tuple(terms_...) {} + + template<typename List> + inline void insertFeSpaces(List& feSpaces) + { + for_each(term_tuple, detail::InsertFeSpaces<List>(feSpaces)); + } + + template<typename OT> + inline void initElement(OT* ot, const ElInfo* elInfo, + SubAssembler* subAssembler, Quadrature *quad, + const BasisFunction *basisFct = NULL) + { + for_each(term_tuple, detail::InitElement<OT>(ot, elInfo, subAssembler, quad, basisFct)); + } + + template<typename OT> + inline void initElement(OT* ot, const ElInfo* smallElInfo, const ElInfo* largeElInfo, + SubAssembler* subAssembler, Quadrature *quad, + const BasisFunction *basisFct = NULL) + { + for_each(term_tuple, detail::InitElement<OT>(ot, smallElInfo, largeElInfo, subAssembler, quad, basisFct)); + } + + inline double operator()(const int& iq) const; + }; + + + // the expressions + // _____________________________________________________________________________ + + namespace expressions + { + /// Functor that takes arbitrary number of arguments + template<typename F, typename... Terms> + struct FunctionN : public LazyOperatorTerms<Terms...> + { + typedef LazyOperatorTerms<Terms...> super; + static const int N = sizeof...(Terms); + + typedef typename traits::functor_result_type<F>::type value_type; + BOOST_STATIC_ASSERT_MSG( (!boost::is_same<value_type, traits::no_valid_type>::value), "********** ERROR: You have to define a result_type for your Functor **********" ); + + F f; ///< the functor + + template<typename... Terms_> + FunctionN(const F& f_, Terms_... terms_) + : super(terms_...), f(f_) {} + + // call f.getDegree() function + template<int I, typename... Terms_> + int getDegree(int_<I>, const Terms_&... terms) const + { + return getDegree(int_<I-1>(), std::get<I-1>(super::term_tuple), terms...); + } + + template<typename... Terms_> + int getDegree(int_<0>, const Terms_&... terms) const + { + return traits::functor_degree<F>::eval(f, terms.getDegree()...); + } + + int getDegree() const + { + return getDegree(int_<N>()); + } + + // call f.operator()(...) + template<int I, typename... Terms_> + inline value_type eval(const int& iq, int_<I>, const Terms_&... terms) const + { + return eval(iq, int_<I-1>(), std::get<I-1>(super::term_tuple), terms...); + } + + template<typename... Terms_> + inline value_type eval(const int& iq, int_<0>, Terms_... terms) const + { + return f(terms(iq)...); // f(term1(iq), term2(iq), term3(iq),...) + } + + inline value_type operator()(const int& iq) const { return eval(iq, int_<N>()); } + }; + + } // end namespace expressions + + + namespace result_of + { + // result of generator-functions (used for enable_if constructs) + template<typename F, typename... Terms> + struct FunctionN : boost::enable_if + < + typename boost::mpl::and_< typename traits::is_valid_arg<Terms>::type... >::type, + expressions::FunctionN< F, typename traits::to_expr<Terms>::type...> + > {}; + + } // end namespace result_of + + + // generator-functions + // _____________________________________________________________________________ + + template<typename F, typename... Terms> + inline typename result_of::FunctionN<F, Terms...>::type + function_(const F& f, Terms... ts) + { + return expressions::FunctionN<F, typename traits::to_expr<Terms>::to::type...> + (f, traits::to_expr<Terms>::to::get(ts)...); + } + + template<typename F, typename... Terms> + inline typename result_of::FunctionN<F, Terms...>::type + func(const F& f, Terms... ts) + { + return expressions::FunctionN<F, typename traits::to_expr<Terms>::to::type...> + (f, traits::to_expr<Terms>::to::get(ts)...); + } + + template<typename F, typename Term0, typename... Terms> + inline typename result_of::FunctionN<F, Term0, Terms...>::type + eval(const F& f, Term0 t0, Terms... ts) + { + return expressions::FunctionN<F, typename traits::to_expr<Term0>::to::type, + typename traits::to_expr<Terms>::to::type...> + (f, traits::to_expr<Term0>::to::get(t0), traits::to_expr<Terms>::to::get(ts)...); + } + +} // end namespace AMDiS + +#endif // AMDIS_FUNCTOR_N_EXPRESSION_HPP diff --git a/AMDiS/src/expressions/functor_expr.hpp b/AMDiS/src/expressions/functor_expr.hpp new file mode 100644 index 0000000000000000000000000000000000000000..045048894d51dd6ffa83d14fdc2d69731b435c6d --- /dev/null +++ b/AMDiS/src/expressions/functor_expr.hpp @@ -0,0 +1,279 @@ +/****************************************************************************** + * + * AMDiS - Adaptive multidimensional simulations + * + * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. + * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis + * + * Authors: + * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * + * This file is part of AMDiS + * + * See also license.opensource.txt in the distribution. + * + ******************************************************************************/ + + + +/** \file functor_expr.hpp */ + +#ifndef AMDIS_FUNCTOR_EXPRESSION_HPP +#define AMDIS_FUNCTOR_EXPRESSION_HPP + +#include "AMDiS_fwd.h" +#include "LazyOperatorTerm.h" +#include "Functors.h" +#include "operations/functors.hpp" + +#include <boost/static_assert.hpp> + +namespace AMDiS +{ + namespace traits + { + template<class T> + struct void_{ typedef void type; }; + + template<typename F, typename Enable = void> + struct functor_result_type {}; + + template<typename F> + struct functor_result_type<F, typename void_<typename F::value_type>::type> + { + typedef typename F::value_type type; + }; + + template<typename F> + struct functor_result_type<F, typename void_<typename F::result_type>::type> + { + typedef typename F::result_type type; + }; + + } // end namespace traits + + namespace expressions + { + /// Expressions for a functor with one argument + template<typename F, typename Term> + struct Function1 : public LazyOperatorTerm1<Term> + { + typedef LazyOperatorTerm1<Term> super; + BOOST_STATIC_ASSERT_MSG( (boost::is_base_of<FunctorBase, F>::value), "********** ERROR: Only functors with base FunctorBase allowed **********" ); + + typedef typename traits::functor_result_type<F>::type value_type; + BOOST_STATIC_ASSERT_MSG( (!boost::is_same<value_type, traits::no_valid_type>::value), "********** ERROR: You have to define a result_type for your Functor **********" ); + + F f; + Function1(const F& f_, const Term& term_) : super(term_), f(f_) {} + + int getDegree() const + { + return f.getDegree(super::term.getDegree()); + } + + inline value_type operator()(const int& iq) const { return f(super::term(iq)); } + }; + + + /// Expressions for a functor with two arguments + template<typename F, typename Term1, typename Term2> + struct Function2 : public LazyOperatorTerm2<Term1, Term2> + { + typedef LazyOperatorTerm2<Term1, Term2> super; + BOOST_STATIC_ASSERT_MSG( (boost::is_base_of<FunctorBase, F>::value), "********** ERROR: Only functors with base FunctorBase allowed **********" ); + + typedef typename traits::functor_result_type<F>::type value_type; + BOOST_STATIC_ASSERT_MSG( (!boost::is_same<value_type, traits::no_valid_type>::value), "********** ERROR: You have to define a result_type for your Functor **********" ); + + F f; + Function2(const F& f_, const Term1& term1_, const Term2& term2_) : super(term1_, term2_), f(f_) {} + + int getDegree() const + { + return f.getDegree(super::term1.getDegree(), super::term2.getDegree()); + } + + inline value_type operator()(const int& iq) const { return f(super::term1(iq), super::term2(iq)); } + }; + + + /// Expressions for a functor with 3 arguments + template<typename F, typename Term1, typename Term2, typename Term3> + struct Function3 : public LazyOperatorTerm3<Term1, Term2, Term3> + { + typedef LazyOperatorTerm3<Term1, Term2, Term3> super; + BOOST_STATIC_ASSERT_MSG( (boost::is_base_of<FunctorBase, F>::value), "********** ERROR: Only functors with base FunctorBase allowed **********" ); + + typedef typename traits::functor_result_type<F>::type value_type; + BOOST_STATIC_ASSERT_MSG( (!boost::is_same<value_type, traits::no_valid_type>::value), "********** ERROR: You have to define a result_type for your Functor **********" ); + + F f; + Function3(const F& f_, const Term1& term1_, const Term2& term2_, const Term3& term3_) + : super(term1_, term2_, term3_), f(f_) {} + + int getDegree() const + { + return f.getDegree(super::term1.getDegree(), super::term2.getDegree(), super::term3.getDegree()); + } + + inline value_type operator()(const int& iq) const { return f(super::term1(iq), super::term2(iq), super::term3(iq)); } + }; + + + /// A wrapper functor for AMDiS::AbstractFunctions + template<typename TOut, typename TIn> + struct Wrapper : public FunctorBase + { + typedef TOut result_type; + Wrapper(AbstractFunction<TOut, TIn>* fct_) : fct(fct_) {} + int getDegree(int degree) const { return fct->getDegree(); } + + TOut operator()(const TIn& x) const + { + return (*fct)(x); + } + + protected: + AbstractFunction<TOut, TIn>* fct; + }; + + } // end namespace expressions + + + namespace result_of + { + // function with one argument + template<typename F, typename Term> + struct Function1 : boost::enable_if + < + typename traits::is_valid_arg<Term>::type, + expressions::Function1 + < + F, typename traits::to_expr<Term>::type + > + > {}; + + // function with two arguments + template<typename F, typename Term1, typename Term2> + struct Function2 : boost::enable_if + < + typename boost::mpl::and_ + < + typename traits::is_valid_arg<Term1>::type, + typename traits::is_valid_arg<Term2>::type + >::type, + expressions::Function2 + < + F, + typename traits::to_expr<Term1>::type, + typename traits::to_expr<Term2>::type + > + > {}; + + + // function with three arguments + template<typename F, typename Term1, typename Term2, typename Term3> + struct Function3 : boost::enable_if + < + typename boost::mpl::and_ + < + typename traits::is_valid_arg<Term1>::type, + typename traits::is_valid_arg<Term2>::type, + typename traits::is_valid_arg<Term3>::type + >::type, + expressions::Function3 + < + F, + typename traits::to_expr<Term1>::type, + typename traits::to_expr<Term2>::type, + typename traits::to_expr<Term3>::type + > + > {}; + + } // end namespace result_of + + + // call a function with 1 argument + // _____________________________________________________________________________ + template<typename F, typename Term> + inline typename result_of::Function1<F, Term>::type + function_(const F& f, const Term& t) + { + typedef typename traits::to_expr<Term>::to Expr; + return expressions::Function1<F, typename Expr::type>(f, Expr::get(t)); + } + + + template<typename F, typename Term> + inline typename result_of::Function1<F, Term>::type + function_(const Term& t) + { + typedef typename traits::to_expr<Term>::to Expr; + return expressions::Function1<F, typename Expr::type>(F(), Expr::get(t)); + } + + + // call a function with 2 arguments + // _____________________________________________________________________________ + template<typename F, typename Term1, typename Term2> + inline typename result_of::Function2<F, Term1, Term2>::type + function_(const F& f, const Term1& t1, const Term2& t2) + { + typedef typename traits::to_expr<Term1>::to Expr1; + typedef typename traits::to_expr<Term2>::to Expr2; + return expressions::Function2<F, typename Expr1::type, typename Expr2::type> + (f, Expr1::get(t1), Expr2::get(t2)); + } + + + template<typename F, typename Term1, typename Term2> + inline typename result_of::Function2<F, Term1, Term2>::type + function_(const Term1& t1, const Term2& t2) + { + typedef typename traits::to_expr<Term1>::to Expr1; + typedef typename traits::to_expr<Term2>::to Expr2; + return expressions::Function2<F, typename Expr1::type, typename Expr2::type> + (F(), Expr1::get(t1), Expr2::get(t2)); + } + + + // call a function with 3 arguments + // _____________________________________________________________________________ + template<typename F, typename Term1, typename Term2, typename Term3> + inline typename result_of::Function3<F, Term1, Term2, Term2>::type + function_(const F& f, const Term1& t1, const Term2& t2, const Term3& t3) + { + typedef typename traits::to_expr<Term1>::to Expr1; + typedef typename traits::to_expr<Term2>::to Expr2; + typedef typename traits::to_expr<Term3>::to Expr3; + return expressions::Function3<F, typename Expr1::type, typename Expr2::type, typename Expr3::type> + (f, Expr1::get(t1), Expr2::get(t2), Expr3::get(t3)); + } + + + template<typename F, typename Term1, typename Term2, typename Term3> + inline typename result_of::Function3<F, Term1, Term2, Term2>::type + function_(const Term1& t1, const Term2& t2, const Term3& t3) + { + typedef typename traits::to_expr<Term1>::to Expr1; + typedef typename traits::to_expr<Term2>::to Expr2; + typedef typename traits::to_expr<Term3>::to Expr3; + return expressions::Function3<F, typename Expr1::type, typename Expr2::type, typename Expr3::type> + (F(), Expr1::get(t1), Expr2::get(t2), Expr3::get(t3)); + } + + + // function wrapper for abstract functions + // _____________________________________________________________________________ + template<typename TOut, typename TIn> + inline expressions::Wrapper<TOut,TIn> wrap(AbstractFunction<TOut, TIn>* fct) + { return expressions::Wrapper<TOut,TIn>(fct); } + +} // end namespace AMDiS + +#endif // AMDIS_FUNCTOR_EXPRESSION_HPP diff --git a/AMDiS/src/expressions/gradientOf.hpp b/AMDiS/src/expressions/gradientOf.hpp new file mode 100644 index 0000000000000000000000000000000000000000..08da7d184af953373581951abca778a028e4a00d --- /dev/null +++ b/AMDiS/src/expressions/gradientOf.hpp @@ -0,0 +1,383 @@ +/****************************************************************************** + * + * AMDiS - Adaptive multidimensional simulations + * + * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. + * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis + * + * Authors: + * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * + * This file is part of AMDiS + * + * See also license.opensource.txt in the distribution. + * + ******************************************************************************/ + + + +/** \file gradientOf.hpp */ + +#ifndef AMDIS_GRADIENT_OF_HPP +#define AMDIS_GRADIENT_OF_HPP + +#include "AMDiS_fwd.h" +#include "LazyOperatorTerm.h" +#include "DOFVector.h" +#include "traits/category.hpp" + +namespace AMDiS +{ + namespace expressions + { + /// Expressions that extracts the gradient of a DOFVector at QPs + template<typename Vector, typename Name> + struct GradientOf : public LazyOperatorTermBase + { + typedef typename traits::category<Vector>::value_type T; + typedef typename GradientType<T>::type value_type; + typedef Name id; + + DOFVector<T>* vecDV; + mutable mtl::dense_vector<typename GradientType<T>::type> vec; + mutable mtl::dense_vector<T> coeff; + + GradientOf(Vector& vector) : vecDV(&vector) {} + GradientOf(Vector* vector) : vecDV(vector) {} + + template<typename List> + void insertFeSpaces(List& feSpaces) const + { + feSpaces.insert(vecDV->getFeSpace()); + } + + int getDegree() const + { + return vecDV->getFeSpace()->getBasisFcts()->getDegree() /* -1 */; + } + + template<typename OT> + void initElement(OT* ot, const ElInfo* elInfo, + SubAssembler* subAssembler, Quadrature *quad, + const BasisFunction *basisFct = NULL) + { + if (ot && subAssembler) + ot->getGradientsAtQPs(vecDV, elInfo, subAssembler, quad, vec); + else if (quad) + vecDV->getGrdAtQPs(elInfo, quad, NULL, vec); + else if (basisFct) { + const BasisFunction *localBasisFct = vecDV->getFeSpace()->getBasisFcts(); + + // get coefficients of DOFVector + coeff.change_dim(localBasisFct->getNumber()); + vecDV->getLocalVector(elInfo->getElement(), coeff); + + // eval basisfunctions of DOFVector at coords of given basisFct + size_t nBasisFct = basisFct->getNumber(); + vec.change_dim(nBasisFct); + + const DimVec<WorldVector<double> > &grdLambda = elInfo->getGrdLambda(); + for (size_t i = 0; i < nBasisFct; i++) + localBasisFct->evalGrdUh(*basisFct->getCoords(i), grdLambda, coeff, vec[i]); + } + } + + + template<typename OT> + inline void initElement(OT* ot, const ElInfo* smallElInfo, const ElInfo* largeElInfo, + SubAssembler* subAssembler, Quadrature *quad, + const BasisFunction *basisFct = NULL) + { + if (ot && subAssembler) + ot->getGradientsAtQPs(vecDV, smallElInfo, largeElInfo, subAssembler, quad, vec); + else if (quad) + vecDV->getGrdAtQPs(smallElInfo, largeElInfo, quad, NULL, vec); + else if (basisFct) { + const BasisFunction *localBasisFct = vecDV->getFeSpace()->getBasisFcts(); + + // get coefficients of DOFVector + coeff.change_dim(localBasisFct->getNumber()); + vecDV->getLocalVector(smallElInfo->getElement(), coeff); + + // eval basisfunctions of DOFVector at coords of given basisFct + size_t nBasisFct = basisFct->getNumber(); + vec.change_dim(nBasisFct); + + const DimVec<WorldVector<double> > &grdLambda = smallElInfo->getGrdLambda(); + for (size_t i = 0; i < nBasisFct; i++) + localBasisFct->evalGrdUh(*basisFct->getCoords(i), grdLambda, coeff, vec[i]); + } + } + + value_type operator()(const int& iq) const { return vec[iq]; } + + std::string str() const { return std::string("grad(") + vecDV->getName() + ")"; } + }; + + + /// Expressions that extracts the partial derivative of a DOFVector at QPs + template<int I, typename Vector, typename Name> + struct DerivativeOf : public LazyOperatorTermBase + { + typedef typename traits::category<Vector>::value_type T; + typedef T value_type; + typedef Name id; + + DOFVector<T>* vecDV; + mutable mtl::dense_vector<typename GradientType<T>::type> vec; + // mutable mtl::dense_vector<T> vec; + mutable mtl::dense_vector<T> coeff; + int comp; + + DerivativeOf(Vector& vector) : vecDV(&vector), comp(I) {} + DerivativeOf(Vector* vector) : vecDV(vector), comp(I) {} + + DerivativeOf(Vector& vector, int I0) : vecDV(&vector), comp(I0) + { + TEST_EXIT_DBG( I < 0 && I0 >= 0 ) + ("You yould specify eather template<int I>, or constructor(int I0)\n"); + } + DerivativeOf(Vector* vector, int I0) : vecDV(vector), comp(I0) + { + TEST_EXIT_DBG( I < 0 && I0 >= 0 ) + ("You yould specify eather template<int I>, or constructor(int I0)\n"); + } + + template<typename List> + void insertFeSpaces(List& feSpaces) const + { + feSpaces.insert(vecDV->getFeSpace()); + } + + int getDegree() const + { + return vecDV->getFeSpace()->getBasisFcts()->getDegree() /* -1 */; + } + + template<typename OT> + void initElement(OT* ot, const ElInfo* elInfo, + SubAssembler* subAssembler, Quadrature *quad, + const BasisFunction *basisFct = NULL) + { + if (ot && subAssembler) + ot->getGradientsAtQPs(vecDV, elInfo, subAssembler, quad, vec); //subAssembler->getDerivativeAtQPs(vecDV, elInfo, quad, comp, vec); + else if (quad) + vecDV->getGrdAtQPs(elInfo, quad, NULL, vec); //vecDV->getDerivativeAtQPs(elInfo, quad, NULL, comp, vec); + else if (basisFct) { + const BasisFunction *localBasisFct = vecDV->getFeSpace()->getBasisFcts(); + + // get coefficients of DOFVector + coeff.change_dim(localBasisFct->getNumber()); + vecDV->getLocalVector(elInfo->getElement(), coeff); + + // eval basisfunctions of DOFVector at coords of given basisFct + size_t nBasisFct = basisFct->getNumber(); + // mtl::dense_vector<typename GradientType<T>::type> helper(nBasisFct); + + const DimVec<WorldVector<double> > &grdLambda = elInfo->getGrdLambda(); + vec.change_dim(nBasisFct); + for (size_t i = 0; i < nBasisFct; i++) + localBasisFct->evalGrdUh(*basisFct->getCoords(i), grdLambda, coeff, vec[i]); //helper[i]); + + // for (size_t i = 0; i < num_rows(helper); i++) + // vec[i] = helper[i][comp]; + } + } + + template<typename OT> + void initElement(OT* ot, const ElInfo* smallElInfo, const ElInfo* largeElInfo, + SubAssembler* subAssembler, Quadrature *quad, + const BasisFunction *basisFct = NULL) + { + // if (op && subAssembler) + // ot->getGradientsAtQPs(vecDV, smallElInfo, largeElInfo, subAssembler, quad, vec); + // else + // vecDV->getGrdAtQPs(smallElInfo, largeElInfo, localQuad, NULL, vec); + + if (ot && subAssembler) + ot->getGradientsAtQPs(vecDV, smallElInfo, largeElInfo, subAssembler, quad, vec); //subAssembler->getDerivativeAtQPs(vecDV, smallElInfo, largeElInfo, quad, comp, vec); + else if (quad) + vecDV->getGrdAtQPs(smallElInfo, largeElInfo, quad, NULL, vec); // vecDV->getDerivativeAtQPs(smallElInfo, largeElInfo, quad, NULL, comp, vec); + else if (basisFct) { + const BasisFunction *localBasisFct = vecDV->getFeSpace()->getBasisFcts(); + + // get coefficients of DOFVector + coeff.change_dim(localBasisFct->getNumber()); + vecDV->getLocalVector(smallElInfo->getElement(), coeff); + + // eval basisfunctions of DOFVector at coords of given basisFct + size_t nBasisFct = basisFct->getNumber(); + // mtl::dense_vector<typename GradientType<T>::type> helper(nBasisFct); + + const DimVec<WorldVector<double> > &grdLambda = smallElInfo->getGrdLambda(); + vec.change_dim(nBasisFct); + for (size_t i = 0; i < nBasisFct; i++) + localBasisFct->evalGrdUh(*basisFct->getCoords(i), grdLambda, coeff, vec[i]); //helper[i]); + + // for (size_t i = 0; i < num_rows(helper); i++) + // vec[i] = helper[i][comp]; + } + } + + value_type operator()(const int& iq) const { return vec[iq][comp]; } + // value_type operator()(const int& iq) const { return vec[iq]; } + + std::string str() const { return std::string("deriv<") + boost::lexical_cast<std::string>(I) + ">(" + vecDV->getName() + ")"; } + }; + + + #if 0 + /// Expressions that extracts the divergence of a DOFVector<Vector> at QPs + template<typename Vector> + struct DivergenceOf : public LazyOperatorTermBase + { + typedef typename traits::ValueType<Vector>::type T; // e.g. WorldVector<double> + typedef typename traits::ValueType<T>::type value_type; // => double + + DOFVector<T>* vecDV; + mutable mtl::dense_vector<typename GradientType<T>::type> vec; + mutable mtl::dense_vector<T> coeff; + + GradientOf(Vector& vector) : vecDV(&vector) {} + GradientOf(Vector* vector) : vecDV(vector) {} + + template<typename List> + void insertFeSpaces(List& feSpaces) const + { + feSpaces.insert(vecDV->getFeSpace()); + } + + int getDegree() const + { + return vecDV->getFeSpace()->getBasisFcts()->getDegree() /* -1 */; + } + + template<typename OT> + void initElement(OT* ot, const ElInfo* elInfo, + SubAssembler* subAssembler, Quadrature *quad, + const BasisFunction *basisFct = NULL) + { + if (ot && subAssembler) + ot->getGradientsAtQPs(vecDV, elInfo, subAssembler, quad, vec); + else if (quad) + vecDV->getGrdAtQPs(elInfo, quad, NULL, vec); + else if (basisFct) { + const BasisFunction *localBasisFct = vecDV->getFeSpace()->getBasisFcts(); + + // get coefficients of DOFVector + coeff.change_dim(localBasisFct->getNumber()); + vecDV->getLocalVector(elInfo->getElement(), coeff); + + // eval basisfunctions of DOFVector at coords of given basisFct + size_t nBasisFct = basisFct->getNumber(); + vec.change_dim(nBasisFct); + + const DimVec<WorldVector<double> > &grdLambda = elInfo->getGrdLambda(); + for (size_t i = 0; i < nBasisFct; i++) + localBasisFct->evalGrdUh(*basisFct->getCoords(i), grdLambda, coeff, vec[i]); + } + } + + + template<typename OT> + inline void initElement(OT* ot, const ElInfo* smallElInfo, const ElInfo* largeElInfo, + SubAssembler* subAssembler, Quadrature *quad, + const BasisFunction *basisFct = NULL) + { + if (ot && subAssembler) + ot->getGradientsAtQPs(vecDV, smallElInfo, largeElInfo, subAssembler, quad, vec); + else if (quad) + vecDV->getGrdAtQPs(smallElInfo, largeElInfo, quad, NULL, vec); + else if (basisFct) { + const BasisFunction *localBasisFct = vecDV->getFeSpace()->getBasisFcts(); + + // get coefficients of DOFVector + coeff.change_dim(localBasisFct->getNumber()); + vecDV->getLocalVector(smallElInfo->getElement(), coeff); + + // eval basisfunctions of DOFVector at coords of given basisFct + size_t nBasisFct = basisFct->getNumber(); + vec.change_dim(nBasisFct); + + const DimVec<WorldVector<double> > &grdLambda = smallElInfo->getGrdLambda(); + for (size_t i = 0; i < nBasisFct; i++) + localBasisFct->evalGrdUh(*basisFct->getCoords(i), grdLambda, coeff, vec[i]); + } + } + + value_type operator()(const int& iq) const { return vec[iq]; } + }; + + #endif + + } // end namespace expressions + + + // gradient of a DOFVector + // _____________________________________________________________________________ + + // with Name + template<typename Name, typename T> + expressions::GradientOf<DOFVector<T>, Name > gradientOf(DOFVector<T>& vector) + { return expressions::GradientOf<DOFVector<T>, Name >(vector); } + + template<typename Name, typename T> + expressions::GradientOf<DOFVector<T>, Name > gradientOf(DOFVector<T>* vector) + { return expressions::GradientOf<DOFVector<T>, Name >(vector); } + + // without Name + template<typename T> + expressions::GradientOf<DOFVector<T>, _unknown > gradientOf(DOFVector<T>& vector) + { return expressions::GradientOf<DOFVector<T>, _unknown >(vector); } + + template<typename T> + expressions::GradientOf<DOFVector<T>, _unknown > gradientOf(DOFVector<T>* vector) + { return expressions::GradientOf<DOFVector<T>, _unknown >(vector); } + + + // Partial derivative of a DOFVector + // _____________________________________________________________________________ + + // with Name + template<typename Name, int I, typename T> + expressions::DerivativeOf<I, DOFVector<T>, Name > derivativeOf(DOFVector<T>& vector) + { return expressions::DerivativeOf<I, DOFVector<T>, Name >(vector); } + + template<typename Name, int I, typename T> + expressions::DerivativeOf<I, DOFVector<T>, Name > derivativeOf(DOFVector<T>* vector) + { return expressions::DerivativeOf<I, DOFVector<T>, Name >(vector); } + + template<typename Name, typename T> + expressions::DerivativeOf<-1, DOFVector<T>, Name > derivativeOf(DOFVector<T>& vector, int I0) + { return expressions::DerivativeOf<-1, DOFVector<T>, Name >(vector, I0); } + + template<typename Name, typename T> + expressions::DerivativeOf<-1, DOFVector<T>, Name > derivativeOf(DOFVector<T>* vector, int I0) + { return expressions::DerivativeOf<-1, DOFVector<T>, Name >(vector, I0); } + + + // without Name + template<int I, typename T> + expressions::DerivativeOf<I, DOFVector<T>, _unknown > derivativeOf(DOFVector<T>& vector) + { return expressions::DerivativeOf<I, DOFVector<T>, _unknown >(vector); } + + template<int I, typename T> + expressions::DerivativeOf<I, DOFVector<T>, _unknown > derivativeOf(DOFVector<T>* vector) + { return expressions::DerivativeOf<I, DOFVector<T>, _unknown >(vector); } + + template<typename T> + expressions::DerivativeOf<-1, DOFVector<T>, _unknown > derivativeOf(DOFVector<T>& vector, int I0) + { return expressions::DerivativeOf<-1, DOFVector<T>, _unknown >(vector, I0); } + + template<typename T> + expressions::DerivativeOf<-1, DOFVector<T>, _unknown > derivativeOf(DOFVector<T>* vector, int I0) + { return expressions::DerivativeOf<-1, DOFVector<T>, _unknown >(vector, I0); } + +} // end namespace AMDiS + + +#endif // AMDIS_GRADIENT_OF_HPP diff --git a/AMDiS/src/expressions/mult_expr.hpp b/AMDiS/src/expressions/mult_expr.hpp new file mode 100644 index 0000000000000000000000000000000000000000..9155dc7dfcc4fd9ee94881058f15ecab00052072 --- /dev/null +++ b/AMDiS/src/expressions/mult_expr.hpp @@ -0,0 +1,141 @@ +/****************************************************************************** + * + * AMDiS - Adaptive multidimensional simulations + * + * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. + * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis + * + * Authors: + * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * + * This file is part of AMDiS + * + * See also license.opensource.txt in the distribution. + * + ******************************************************************************/ + + + +/** \file mult_expr.hpp */ + +#ifndef AMDIS_MULT_EXPRESSION_HPP +#define AMDIS_MULT_EXPRESSION_HPP + +#include "AMDiS_fwd.h" +#include "LazyOperatorTerm.h" + +namespace AMDiS +{ + namespace expressions + { + + /// Expressions that represents the multiplication of two expressions: E1 * E2 + template<typename Term1, typename Term2> + struct Mult : public LazyOperatorTerm2<Term1, Term2> + { + typedef LazyOperatorTerm2<Term1, Term2> super; + typedef typename traits::mult_type + < + typename Term1::value_type, + typename Term2::value_type + >::type value_type; + + BOOST_STATIC_ASSERT_MSG( !(boost::is_same<value_type, traits::no_valid_type>::value), "********** ERROR: Can not multiply terms **********" ); + + Mult(const Term1& term1_, const Term2& term2_) + : super(term1_, term2_) {} + + int getDegree() const + { + return super::term1.getDegree() + super::term2.getDegree(); + } + + inline value_type operator()(const int& iq) const { return super::term1(iq) * super::term2(iq); } + + std::string str() const { return std::string("(") + super::term1.str() + " * " + super::term2.str() + ")"; } + }; + + + /// Expressions that represents the inverse of an expressions: 1/E + template<typename Term> + struct MultInverse : public LazyOperatorTerm1<Term> + { + typedef LazyOperatorTerm1<Term> super; + typedef typename Term::value_type value_type; + + MultInverse(const Term& term_) + : super(term_) {} + + int getDegree() const + { + return super::term.getDegree(); + } + + // works only for scalar types + // TODO: extend implementation to inverse of matrices + inline value_type operator()(const int& iq) const { return 1.0 / super::term(iq); } + + std::string str() const { return std::string("(") + super::term.str() + ")^(-1)"; } + }; + + } // end namespace expressions + + + namespace result_of + { + template<typename Term1, typename Term2> + struct Mult : boost::enable_if + < + typename traits::is_valid_arg2<Term1, Term2>::type, + expressions::Mult + < + typename traits::to_expr<Term1>::type, + typename traits::to_expr<Term2>::type + > + > {}; + + + template<typename Term1, typename Term2> + struct Divide : boost::enable_if + < + typename traits::is_valid_arg2<Term1, Term2>::type, + expressions::Mult + < + typename traits::to_expr<Term1>::type, + expressions::MultInverse< typename traits::to_expr<Term2>::type > + > + > {}; + + } // end namespace result_of + + + // multiply two terms + // _____________________________________________________________________________ + template<typename Term1, typename Term2> + inline typename result_of::Mult<Term1, Term2>::type + operator*(const Term1& t1, const Term2& t2) + { + typedef typename traits::to_expr<Term1>::to Expr1; + typedef typename traits::to_expr<Term2>::to Expr2; + return expressions::Mult< typename Expr1::type, typename Expr2::type > + (Expr1::get(t1), Expr2::get(t2)); + } + + + // divide two terms + // _____________________________________________________________________________ + template<typename Term1, typename Term2> + inline typename result_of::Divide<Term1, Term2>::type + operator/(const Term1& t1, const Term2& t2) + { + typedef typename traits::to_expr<Term2>::to Expr2; + return t1 * expressions::MultInverse< typename Expr2::type >(Expr2::get(t2)); + } + +} // end namespace AMDiS + +#endif // AMDIS_MULT_EXPRESSION_HPP diff --git a/AMDiS/src/expressions/simplify_expr.hpp b/AMDiS/src/expressions/simplify_expr.hpp new file mode 100644 index 0000000000000000000000000000000000000000..d69487ea4049e950632b11d148fb1a90a293be52 --- /dev/null +++ b/AMDiS/src/expressions/simplify_expr.hpp @@ -0,0 +1,448 @@ +/****************************************************************************** + * + * AMDiS - Adaptive multidimensional simulations + * + * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. + * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis + * + * Authors: + * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * + * This file is part of AMDiS + * + * See also license.opensource.txt in the distribution. + * + ******************************************************************************/ + + + +/** \file simplify_expr.hpp */ + +#ifndef AMDIS_SIMPLIFY_EXPRESSION_HPP +#define AMDIS_SIMPLIFY_EXPRESSION_HPP + +#include "AMDiS_fwd.h" +#include "LazyOperatorTerm.h" +#include "value_expr.hpp" + +#define SINGLE_ARG(...) __VA_ARGS__ + +namespace AMDiS +{ + namespace traits + { + template<typename T> + struct is_ct_value : boost::mpl::false_ {}; + + template<int I> + struct is_ct_value< expressions::CValue<I> > : boost::mpl::true_ {}; + + } // end namespace traits + + + namespace expressions + { + template<typename Term, typename Enabled = void> + struct Simplify + { + typedef Term type; + + static type eval(Term const& t) { return t; } + }; // by default do not simplify a term + + } // end namespace expressions + + + // generator function for simplification + template<typename Term> + inline typename expressions::Simplify<Term>::type simplify(const Term& t) + { return expressions::Simplify<Term>::eval(t); } + + + namespace expressions + { + /// -(N) -> (-N) + template<int N> + struct Simplify< Negative<CValue<N> > > + { + typedef CValue<-N> type; + + static type eval(Negative<CValue<N> > const& t) + { return CValue<-N>(); } + + }; + + /// -0 -> 0 + template<> + struct Simplify< Negative<CValue<0> > > + { + typedef CValue<0> type; + + static type eval(Negative<CValue<0> > const& t) + { return CValue<0>(); } + }; + + /// (N) + (M) -> (N+M) + template<int N, int M> + struct Simplify< Add<CValue<N>, CValue<M> > > + { + typedef CValue<N+M> type; + + static type eval(Add<CValue<N>, CValue<M> > const& t) + { return CValue<N+M>(); } + }; + + /// (N) * (M) -> (N*M) + template<int N, int M > + struct Simplify< Mult<CValue<N>, CValue<M> > > + { + typedef CValue<N*M> type; + + static type eval(Mult<CValue<N>, CValue<M> > const& t) + { return CValue<N*M>(); } + }; + + /// (M) ^ N -> (M^N) + template<int N, int M > + struct Simplify< Pow<N, CValue<M> > > + { + typedef CValue<meta::pow<M,N>::value> type; + + static type eval(Pow<N, CValue<M> > const& t) + { return type(); } + }; + + } // end namespace expressions + + namespace expressions + { + /// X + 0 -> X + template<typename Term> + struct Simplify< Add<Term, CValue<0> >, typename boost::enable_if_c<!traits::is_ct_value<Term>::value>::type > + { + typedef typename Simplify<Term>::type type; + + static type eval(Add<Term, CValue<0> > const& t) + { return simplify(t.term1); } + }; + + /// 0 + X -> X + template<typename Term> + struct Simplify< Add<CValue<0>, Term>, typename boost::enable_if_c<!traits::is_ct_value<Term>::value>::type > + { + typedef typename Simplify<Term>::type type; + + static type eval(Add<CValue<0>, Term> const& t) + { return simplify(t.term2); } + }; + + /// X * 0 -> 0 + template<typename Term> + struct Simplify< Mult<Term, CValue<0> >, typename boost::enable_if_c<!traits::is_ct_value<Term>::value>::type > + { + typedef CValue<0> type; + + static type eval(Mult<Term, CValue<0> > const& t) + { return CValue<0>(); } + }; + + /// 0 * X -> 0 + template<typename Term> + struct Simplify< Mult<CValue<0>, Term>, typename boost::enable_if_c<!traits::is_ct_value<Term>::value>::type > + { + typedef CValue<0> type; + + static type eval(Mult<CValue<0>, Term> const& t) + { return CValue<0>(); } + }; + + /// X * 1 -> X + template<typename Term> + struct Simplify< Mult<Term, CValue<1> >, typename boost::enable_if_c<!traits::is_ct_value<Term>::value>::type > + { + typedef typename Simplify<Term>::type type; + + static type eval(Mult<Term, CValue<1> > const& t) + { return simplify(t.term1); } + }; + + /// 1 * X -> X + template<typename Term> + struct Simplify< Mult<CValue<1>, Term>, typename boost::enable_if_c<!traits::is_ct_value<Term>::value>::type > + { + typedef typename Simplify<Term>::type type; + + static type eval(Mult<CValue<1>, Term> const& t) + { return simplify(t.term2); } + }; + + } // end namespace expressions + + + namespace expressions + { + /// X / X -> 1 + template<typename Term> + struct Simplify< Mult<Term, MultInverse<Term> > > + { + typedef CValue<1> type; + + static type eval(Mult<Term, MultInverse<Term> > const& t) + { return CValue<1>(); } + }; + + /// X / X -> 1 + template<typename Term> + struct Simplify< Mult<MultInverse<Term>, Term> > + { + typedef CValue<1> type; + + static type eval(Mult<MultInverse<Term>, Term> const& t) + { return CValue<1>(); } + }; + + /// -(-X) -> X + template<typename Term> + struct Simplify< Negative<Negative<Term> > > + { + typedef Term type; + + static type eval(Negative<Negative<Term> > const& t) + { return t.term.term; } + }; + + /// (X^(-1))^(-1) -> X + template<typename Term> + struct Simplify< MultInverse<MultInverse<Term> > > + { + typedef Term type; + + static type eval(MultInverse<MultInverse<Term> > const& t) + { return t.term.term; } + }; + + /// -(X - Y) -> Y - X + template<typename X, typename Y> + struct Simplify< Negative<Add<X, Negative<Y> > > > + { + typedef Add<Y, Negative<X> > type; + + static type eval(Negative<Add<X, Negative<Y> > > const& t) + { return t.term.term2.term - t.term.term1; } + }; + + } // end namespace expressions + + + namespace expressions + { + /// X^1 -> X + template<typename Term> + struct Simplify< Pow<1, Term>, typename boost::enable_if_c<!traits::is_ct_value<Term>::value>::type > + { + typedef Term type; + + static type eval(Pow<1,Term> const& t) { return t.term; } + }; + + /// X^0 -> 1 + template<typename Term> + struct Simplify< Pow<0, Term>, typename boost::enable_if_c<!traits::is_ct_value<Term>::value>::type > + { + typedef CValue<1> type; + + static type eval(Pow<0,Term> const& t) { return CValue<1>(); } + }; + + } // end namespace expressions + + + namespace expressions + { + /// (XY) / (XZ) -> Y/Z + template<typename X, typename Y, typename Z> + struct Simplify< Mult<Mult<X,Y>, MultInverse<Mult<X,Z> > > > + { + typedef Mult<Y, MultInverse<Z> > type; + + // Y = t.term1.term2, Z = t.term2.term.term2 + static type eval(Mult<Mult<X,Y>, MultInverse<Mult<X,Z> > > const& t) + { return t.term1.term2 / t.term2.term.term2; } + }; + + /// (XY) / X -> Y + template<typename X, typename Y> + struct Simplify< Mult<Mult<X,Y>, MultInverse<X> > > + { + typedef Y type; + + // Y = t.term1.term2 + static type eval(Mult<Mult<X,Y>, MultInverse<X> > const& t) + { return t.term1.term2; } + }; + + /// X / (XY) -> 1/Y + template<typename X, typename Y> + struct Simplify< Mult<X, MultInverse<Mult<X,Y> > > > + { + typedef MultInverse<Y> type; + + // Y = t.term2.term.term2 + static type eval(Mult<Mult<X,Y>, MultInverse<X> > const& t) + { return MultInverse<Y>(t.term2.term.term2); } + }; + + /// N*(M*X) -> (N*M) * X + template<int N, int M, typename X> + struct Simplify< Mult<CValue<N>, Mult<CValue<M>, X> >, typename boost::enable_if_c< N!=0 && N!=1 && M!=0 && M!=1 >::type > + { + typedef Mult<CValue<N*M>, X> type; + + // X = t.term2.term2 + static type eval(Mult<CValue<N>, Mult<CValue<M>, X> > const& t) + { return CValue<N*M>() * (t.term2.term2); } + }; + + /// N*(X*M) -> (N*M) * X + template<int N, int M, typename X> + struct Simplify< Mult<CValue<N>, Mult<X, CValue<M> > >, typename boost::enable_if_c< N!=0 && N!=1 && M!=0 && M!=1 >::type > + { + typedef Mult<CValue<N*M>, X> type; + + // X = t.term2.term1 + static type eval(Mult<CValue<N>, Mult<X, CValue<M> > > const& t) + { return CValue<N*M>() * (t.term2.term1); } + }; + + + /// (M*X)*N -> (N*M) * X + template<int N, int M, typename X> + struct Simplify< Mult<Mult<CValue<M>, X>, CValue<N> >, typename boost::enable_if_c< N!=0 && N!=1 && M!=0 && M!=1 >::type > + { + typedef Mult<CValue<N*M>, X> type; + + // X = t.term1.term2 + static type eval(Mult<Mult<CValue<M>, X>, CValue<N> > const& t) + { return CValue<N*M>() * (t.term1.term2); } + }; + + + /// (X*M)*N -> (N*M) * X + template<int N, int M, typename X> + struct Simplify< Mult<Mult<X, CValue<M> >, CValue<N> >, typename boost::enable_if_c< N!=0 && N!=1 && M!=0 && M!=1 >::type > + { + typedef Mult<CValue<N*M>, X> type; + + // X = t.term1.term1 + static type eval(Mult<Mult<X, CValue<M> >, CValue<N> > const& t) + { return CValue<N*M>() * (t.term1.term1); } + }; + + } // end namespace expressions + + + namespace expressions + { + /// A + B -> simplify(A) + simplify(B) + template<typename Term1, typename Term2> + class Simplify< Add<Term1, Term2>, typename boost::enable_if_c<!(traits::is_ct_value<Term1>::value || traits::is_ct_value<Term2>::value)>::type > + { + typedef typename Simplify<Term1>::type S1; + typedef typename Simplify<Term2>::type S2; + + public: + typedef Add<S1, S2> type; + + static type eval(Add<Term1, Term2> const& t) + { + return simplify(t.term1) + simplify(t.term2); + } + }; + + /// A * B -> simplify(A) * simplify(B) + template<typename Term1, typename Term2> + class Simplify< Mult<Term1, Term2>, typename boost::enable_if_c<!(traits::is_ct_value<Term1>::value || traits::is_ct_value<Term2>::value)>::type > + { + typedef typename Simplify<Term1>::type S1; + typedef typename Simplify<Term2>::type S2; + + public: + typedef Mult<S1, S2> type; + + static type eval(Mult<Term1, Term2> const& t) + { + return simplify(t.term1) * simplify(t.term2); + } + }; + + /// X(A) -> X(simplify(A)) + template<template<class> class Outer, class Inner> + class Simplify< Outer<Inner>, typename boost::enable_if_c<!(traits::is_ct_value<Inner>::value) && traits::is_expr<Inner>::value>::type > + { + typedef typename Simplify<Inner>::type S; + + public: + typedef Outer<S> type; + + static type eval(Outer<Inner> const& t) + { + return type(simplify(t.term)); + } + }; + + } // end namespace expressions + + + // ============================================================================= + // multiple simplifications + + namespace expressions + { + template<int N, typename Term, typename Enabled = void> + struct SimplifyRecursive + { + typedef typename Simplify< typename SimplifyRecursive<N-1, Term>::type >::type type; + }; + + template<typename Term> + struct SimplifyRecursive<1, Term> + { + typedef typename Simplify< Term >::type type; + }; + + template<int N, typename Term > + struct SimplifyRecursive<N, Term, typename boost::enable_if_c<(N <= 0)>::type> + { + typedef Term type; + }; + + } // end namespace expressions + + + template<int N, typename Term> + inline typename expressions::SimplifyRecursive<N, Term>::type + simplify(const Term& t); + + template<int N, typename Term> + inline typename expressions::SimplifyRecursive<N, Term>::type + simplify(const Term& t, boost::mpl::int_<N>) { return simplify(simplify<N-1>(t)); } + + template<typename Term> + inline typename expressions::SimplifyRecursive<1, Term>::type + simplify(const Term& t, boost::mpl::int_<1>) { return simplify(t); } + + template<typename Term> + inline typename expressions::SimplifyRecursive<0, Term>::type + simplify(const Term& t, boost::mpl::int_<0>) { return t; } + + template<int N, typename Term> + inline typename expressions::SimplifyRecursive<N, Term>::type + simplify(const Term& t) { return simplify(t, boost::mpl::int_<N>()); } + +} // end namespace AMDiS + +#endif // AMDIS_SIMPLIFY_EXPRESSION_HPP diff --git a/AMDiS/src/expressions/valueOf.hpp b/AMDiS/src/expressions/valueOf.hpp new file mode 100644 index 0000000000000000000000000000000000000000..5b7536192ed16e771cc3b602beeb710523a00ed8 --- /dev/null +++ b/AMDiS/src/expressions/valueOf.hpp @@ -0,0 +1,437 @@ +/****************************************************************************** + * + * AMDiS - Adaptive multidimensional simulations + * + * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. + * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis + * + * Authors: + * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * + * This file is part of AMDiS + * + * See also license.opensource.txt in the distribution. + * + ******************************************************************************/ + + + +/** \file valueOf.hpp */ + +#ifndef AMDIS_VALUE_OF_HPP +#define AMDIS_VALUE_OF_HPP + +#include "AMDiS_fwd.h" +#include "LazyOperatorTerm.h" +#include "DOFVector.h" + +#include "traits/category.hpp" +#include "traits/at.hpp" + +#include <boost/static_assert.hpp> +#include <boost/mpl/bool.hpp> + + +namespace AMDiS +{ + struct _unknown {}; + + namespace expressions + { + /// Expressions that extracts the values of a DOFVector at QPs + template<typename Vector, typename Name, typename Enable = void> + struct ValueOf : public LazyOperatorTermBase {}; + + template<typename T, typename Name> + struct ValueOf<DOFVector<T>, Name> : public LazyOperatorTermBase + { + typedef T value_type; + typedef Name id; + + DOFVector<T>* vecDV; + mutable mtl::dense_vector<T> vec; + mutable mtl::dense_vector<T> coeff; + + ValueOf(DOFVector<T>& vector) : vecDV(&vector) {} + ValueOf(DOFVector<T>* vector) : vecDV(vector) {} + + template<typename List> + inline void insertFeSpaces(List& feSpaces) const + { + feSpaces.insert(vecDV->getFeSpace()); + } + + inline int getDegree() const + { + return vecDV->getFeSpace()->getBasisFcts()->getDegree(); + } + + template<typename OT> + inline void initElement(OT* ot, const ElInfo* elInfo, + SubAssembler* subAssembler, Quadrature *quad, + const BasisFunction *basisFct = NULL) + { + if (ot && subAssembler) + ot->getVectorAtQPs(vecDV, elInfo, subAssembler, quad, vec); + else if (quad) + vecDV->getVecAtQPs(elInfo, quad, NULL, vec); + else if (basisFct) { + const BasisFunction *localBasisFct = vecDV->getFeSpace()->getBasisFcts(); + + // get coefficients of DOFVector + coeff.change_dim(localBasisFct->getNumber()); + vecDV->getLocalVector(elInfo->getElement(), coeff); + + // eval basisfunctions of DOFVector at coords of given basisFct + size_t nBasisFct = basisFct->getNumber(); + vec.change_dim(nBasisFct); + for (size_t i = 0; i < nBasisFct; i++) + vec[i] = localBasisFct->evalUh(*basisFct->getCoords(i), coeff); + } + } + + + template<typename OT> + inline void initElement(OT* ot, const ElInfo* smallElInfo, const ElInfo* largeElInfo, + SubAssembler* subAssembler, Quadrature *quad, + const BasisFunction *basisFct = NULL) + { + if (ot && subAssembler) + ot->getVectorAtQPs(vecDV, smallElInfo, largeElInfo, subAssembler, quad, vec); + else if (quad) + vecDV->getVecAtQPs(smallElInfo, largeElInfo, quad, NULL, vec); + else if (basisFct) { + const BasisFunction *localBasisFct = vecDV->getFeSpace()->getBasisFcts(); + + // get coefficients of DOFVector + coeff.change_dim(localBasisFct->getNumber()); + vecDV->getLocalVector(smallElInfo->getElement(), coeff); + + // eval basisfunctions of DOFVector at coords of given basisFct + size_t nBasisFct = basisFct->getNumber(); + vec.change_dim(nBasisFct); + for (size_t i = 0; i < nBasisFct; i++) + vec[i] = localBasisFct->evalUh(*basisFct->getCoords(i), coeff); + } + } + + inline value_type operator()(const int& iq) const { return vec[iq]; } + + std::string str() const { return std::string("value(") + vecDV->getName() + ")"; } + }; + + + /// Expressions that extracts the matrix-value of a Matrix<DOFVector> at QPs + template<template<class> class Matrix, typename T, typename Name> + struct ValueOf<Matrix<DOFVector<T>*>, Name, + typename boost::enable_if<typename traits::is_matrix<Matrix<T> >::type>::type > + : public LazyOperatorTermBase + { + typedef Matrix<T> value_type; + typedef Name id; + + Matrix<DOFVector<T>*> vecDV; + mutable mtl::dense_vector<value_type> vec; + mutable Matrix<mtl::dense_vector<T> > coeff; + + ValueOf(Matrix<DOFVector<T>*>& vector) : vecDV(vector) + { + resize(coeff, num_rows(vecDV), num_cols(vecDV)); + } + + template<typename List> + inline void insertFeSpaces(List& feSpaces) const + { + for (size_t i = 0; i < num_rows(vecDV); i++) + for (size_t j = 0; j < num_cols(vecDV); j++) + feSpaces.insert(at(vecDV, i, j)->getFeSpace()); + } + + inline int getDegree() const + { + return at(vecDV, 0, 0)->getFeSpace()->getBasisFcts()->getDegree(); + } + + template<typename OT> + inline void initElement(OT* ot, const ElInfo* elInfo, + SubAssembler* subAssembler, Quadrature *quad, + const BasisFunction *basisFct = NULL) + { + Matrix<mtl::dense_vector<T> > helper; resize(helper, num_rows(vecDV), num_cols(vecDV)); + for (size_t i = 0; i < num_rows(vecDV); i++) { + for (size_t j = 0; j < num_cols(vecDV); j++) { + if (ot && subAssembler) + ot->getVectorAtQPs(at(vecDV, i, j), elInfo, subAssembler, quad, at(helper, i, j)); + else if (quad) + at(vecDV, i, j)->getVecAtQPs(elInfo, quad, NULL, at(helper, i, j)); + else if (basisFct) { + const BasisFunction *localBasisFct = at(vecDV, i, j)->getFeSpace()->getBasisFcts(); + + // get coefficients of DOFVector + at(coeff, i, j).change_dim(localBasisFct->getNumber()); + at(vecDV, i, j)->getLocalVector(elInfo->getElement(), at(coeff, i, j)); + + // eval basisfunctions of DOFVector at coords of given basisFct + size_t nBasisFct = basisFct->getNumber(); + at(helper, i, j).change_dim(nBasisFct); + for (size_t k = 0; k < nBasisFct; k++) + at(helper, i, j)[k] = localBasisFct->evalUh(*basisFct->getCoords(k), at(coeff, i, j)); + } + } + } + vec.change_dim(num_rows(at(helper, 0, 0))); + for (size_t iq = 0; iq < num_rows(at(helper, 0, 0)); iq++) { + value_type tmp; resize(tmp, num_rows(vecDV), num_cols(vecDV)); + for (size_t i = 0; i < num_rows(vecDV); i++) { + for (size_t j = 0; j < num_cols(vecDV); j++) { + at(tmp, i, j) = at(helper, i, j)[iq]; + } + } + vec[iq] = tmp; + } + } + + + template<typename OT> + inline void initElement(OT* ot, const ElInfo* smallElInfo, const ElInfo* largeElInfo, + SubAssembler* subAssembler, Quadrature *quad, + const BasisFunction *basisFct = NULL) + { + initElement(ot, smallElInfo, subAssembler, quad, basisFct); + } + + inline value_type operator()(const int& iq) const { return vec[iq]; } + + std::string str() const { return std::string("value_(") + at(vecDV, 0, 0)->getName() + ")"; } + }; + + + /// Expressions that extracts the vector-value of a Vector<DOFVector> at QPs + template<template<class> class Vector, typename T, typename Name> + struct ValueOf<Vector<DOFVector<T>*>, Name, + typename boost::enable_if<typename traits::is_vector<Vector<T> >::type>::type > + : public LazyOperatorTermBase + { + typedef Vector<T> value_type; + typedef Name id; + + Vector<DOFVector<T>*> vecDV; + mutable mtl::dense_vector<value_type> vec; + mutable Vector<mtl::dense_vector<T> > coeff; + + ValueOf(Vector<DOFVector<T>*>& vector) : vecDV(vector) + { + resize(coeff, num_rows(vecDV)); + } + + template<typename List> + inline void insertFeSpaces(List& feSpaces) const + { + for (size_t i = 0; i < num_rows(vecDV); i++) + feSpaces.insert(at(vecDV, i)->getFeSpace()); + } + + inline int getDegree() const + { + return at(vecDV, 0)->getFeSpace()->getBasisFcts()->getDegree(); + } + + template<typename OT> + inline void initElement(OT* ot, const ElInfo* elInfo, + SubAssembler* subAssembler, Quadrature *quad, + const BasisFunction *basisFct = NULL) + { + Vector<mtl::dense_vector<T> > helper; resize(helper, num_rows(vecDV)); + for (size_t i = 0; i < num_rows(vecDV); i++) { + if (ot && subAssembler) + ot->getVectorAtQPs(at(vecDV, i), elInfo, subAssembler, quad, at(helper, i)); + else if (quad) + at(vecDV, i)->getVecAtQPs(elInfo, quad, NULL, at(helper, i)); + else if (basisFct) { + const BasisFunction *localBasisFct = at(vecDV, i)->getFeSpace()->getBasisFcts(); + + // get coefficients of DOFVector + at(coeff, i).change_dim(localBasisFct->getNumber()); + at(vecDV, i)->getLocalVector(elInfo->getElement(), at(coeff, i)); + + // eval basisfunctions of DOFVector at coords of given basisFct + size_t nBasisFct = basisFct->getNumber(); + at(helper, i).change_dim(nBasisFct); + for (size_t j = 0; j < nBasisFct; j++) + at(helper, i)[j] = localBasisFct->evalUh(*basisFct->getCoords(j), at(coeff, i)); + } + } + vec.change_dim(num_rows(at(helper, 0))); + for (size_t iq = 0; iq < num_rows(at(helper, 0)); iq++) { + value_type tmp; resize(tmp, num_rows(vecDV)); + for (size_t i = 0; i < num_rows(vecDV); i++) + at(tmp, i) = at(helper, i)[iq]; + vec[iq] = tmp; + } + } + + + template<typename OT> + inline void initElement(OT* ot, const ElInfo* smallElInfo, const ElInfo* largeElInfo, + SubAssembler* subAssembler, Quadrature *quad, + const BasisFunction *basisFct = NULL) + { + initElement(ot, smallElInfo, subAssembler, quad, basisFct); + } + + inline value_type operator()(const int& iq) const { return vec[iq]; } + + std::string str() const { return std::string("value_(") + at(vecDV, 0)->getName() + ")"; } + }; + + + /// Expression that extracts the component of a vector-values DOFVector at QPs + template<typename Vector> + struct ComponentOf : public LazyOperatorTermBase {}; + + template<template<class> class Vector, typename T> + struct ComponentOf<DOFVector<Vector<T> > > : public LazyOperatorTermBase + { + typedef T value_type; + + DOFVector<Vector<T> >* vecDV; + mutable mtl::dense_vector<Vector<T> > vec; + mutable mtl::dense_vector<Vector<T> > coeff; + int I; + + ComponentOf(DOFVector<Vector<T> >& vector, int I_) : vecDV(&vector), I(I_) {} + ComponentOf(DOFVector<Vector<T> >* vector, int I_) : vecDV(vector), I(I_) {} + + template<typename List> + inline void insertFeSpaces(List& feSpaces) const + { + feSpaces.insert(vecDV->getFeSpace()); + } + + inline int getDegree() const + { + return vecDV->getFeSpace()->getBasisFcts()->getDegree(); + } + + template<typename OT> + inline void initElement(OT* ot, const ElInfo* elInfo, + SubAssembler* subAssembler, Quadrature *quad, + const BasisFunction *basisFct = NULL) + { + if (ot && subAssembler) + ot->getVectorAtQPs(vecDV, elInfo, subAssembler, quad, vec); + else if (quad) + vecDV->getVecAtQPs(elInfo, quad, NULL, vec); + else if (basisFct) { + const BasisFunction *localBasisFct = vecDV->getFeSpace()->getBasisFcts(); + + // get coefficients of DOFVector + coeff.change_dim(localBasisFct->getNumber()); + vecDV->getLocalVector(elInfo->getElement(), coeff); + + // eval basisfunctions of DOFVector at coords of given basisFct + size_t nBasisFct = basisFct->getNumber(); + vec.change_dim(nBasisFct); + for (size_t i = 0; i < nBasisFct; i++) + vec[i] = localBasisFct->evalUh(*basisFct->getCoords(i), coeff); + } + } + + + template<typename OT> + inline void initElement(OT* ot, const ElInfo* smallElInfo, const ElInfo* largeElInfo, + SubAssembler* subAssembler, Quadrature *quad, + const BasisFunction *basisFct = NULL) + { + if (ot && subAssembler) + ot->getVectorAtQPs(vecDV, smallElInfo, largeElInfo, subAssembler, quad, vec); + else if (quad) + vecDV->getVecAtQPs(smallElInfo, largeElInfo, quad, NULL, vec); + else if (basisFct) { + const BasisFunction *localBasisFct = vecDV->getFeSpace()->getBasisFcts(); + + // get coefficients of DOFVector + coeff.change_dim(localBasisFct->getNumber()); + vecDV->getLocalVector(smallElInfo->getElement(), coeff); + + // eval basisfunctions of DOFVector at coords of given basisFct + size_t nBasisFct = basisFct->getNumber(); + vec.change_dim(nBasisFct); + for (size_t i = 0; i < nBasisFct; i++) + vec[i] = localBasisFct->evalUh(*basisFct->getCoords(i), coeff); + } + } + + inline value_type operator()(const int& iq) const { return vec[iq][I]; } + + std::string str() const { return std::string("comp<") + boost::lexical_cast<std::string>(I) + ">(" + vecDV->getName() + ")"; } + }; + + + } // end namespace expressions + + // value of a DOFVector<T> + // ___________________________________________________________________________ + + // with Name + template<typename Name, typename T> + expressions::ValueOf<DOFVector<T>, Name > valueOf(DOFVector<T>& vector) + { return expressions::ValueOf<DOFVector<T>, Name >(vector); } + + template<typename Name, typename T> + expressions::ValueOf<DOFVector<T>, Name > valueOf(DOFVector<T>* vector) + { return expressions::ValueOf<DOFVector<T>, Name >(vector); } + + template<typename Name, template<class> class Matrix, typename T> + typename boost::enable_if<typename traits::is_matrix<Matrix<T> >::type, + expressions::ValueOf<Matrix<DOFVector<T>*>, Name > >::type + valueOf(Matrix<DOFVector<T>*> &mat) + { return expressions::ValueOf<Matrix<DOFVector<T>*>, Name >(mat); } + + template<typename Name, template<class> class Vector, typename T> + typename boost::enable_if<typename traits::is_vector<Vector<T> >::type, + expressions::ValueOf<Vector<DOFVector<T>*>, Name > >::type + valueOf(Vector<DOFVector<T>*> &vector) + { return expressions::ValueOf<Vector<DOFVector<T>*>, Name >(vector); } + + + // without Name + template<typename T> + expressions::ValueOf<DOFVector<T>, _unknown > valueOf(DOFVector<T>& vector) + { return expressions::ValueOf<DOFVector<T>, _unknown >(vector); } + + template<typename T> + expressions::ValueOf<DOFVector<T>, _unknown > valueOf(DOFVector<T>* vector) + { return expressions::ValueOf<DOFVector<T>, _unknown >(vector); } + + template<template<class> class Matrix, typename T> + typename boost::enable_if<typename traits::is_matrix<Matrix<T> >::type, + expressions::ValueOf<Matrix<DOFVector<T>*>, _unknown > >::type + valueOf(Matrix<DOFVector<T>*> &mat) + { return expressions::ValueOf<Matrix<DOFVector<T>*>, _unknown >(mat); } + + template<template<class> class Vector, typename T> + typename boost::enable_if<typename traits::is_vector<Vector<T> >::type, + expressions::ValueOf<Vector<DOFVector<T>*>, _unknown > >::type + valueOf(Vector<DOFVector<T>*> &vector) + { return expressions::ValueOf<Vector<DOFVector<T>*>, _unknown >(vector); } + + + // component of a DOFVector<Vector> + // ___________________________________________________________________________ + + template<template<class> class Vector, typename T> + expressions::ComponentOf<DOFVector<Vector<T> > > componentOf(DOFVector<Vector<T> >& vector, int I) + { return expressions::ComponentOf<DOFVector<Vector<T> > >(vector, I); } + + template<template<class> class Vector, typename T> + expressions::ComponentOf<DOFVector<Vector<T> > > componentOf(DOFVector<Vector<T> >* vector, int I) + { return expressions::ComponentOf<DOFVector<Vector<T> > >(vector, I); } + +} // end namespace AMDiS + +#endif // AMDIS_VALUE_OF_HPP diff --git a/AMDiS/src/expressions/value_expr.hpp b/AMDiS/src/expressions/value_expr.hpp new file mode 100644 index 0000000000000000000000000000000000000000..f7c80e86ae6f80f8f9eb70fd1f1eed1afdb1728e --- /dev/null +++ b/AMDiS/src/expressions/value_expr.hpp @@ -0,0 +1,217 @@ +/****************************************************************************** + * + * AMDiS - Adaptive multidimensional simulations + * + * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. + * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis + * + * Authors: + * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * + * This file is part of AMDiS + * + * See also license.opensource.txt in the distribution. + * + ******************************************************************************/ + + + +/** \file value_expr.hpp */ + +#ifndef AMDIS_VALUE_EXPR_HPP +#define AMDIS_VALUE_EXPR_HPP + +#include "LazyOperatorTerm.h" + +namespace AMDiS +{ + namespace expressions + { + /// Expression that encapsulates a runtime value + template<typename T> + struct RValue : public LazyOperatorTermBase + { + typedef T value_type; + T value; + RValue(const T& value_) : value(value_) {} + + inline value_type operator()(const int& iq) const { return value; } + + std::string str() const { return boost::lexical_cast<std::string>(value); } + }; + + + /// Expression that encapsulates a compiletime value + template<int V> + struct CValue : public LazyOperatorTermBase + { + typedef int value_type; + inline value_type operator()(const int& iq) const { return V; } + + std::string str() const { return std::string("[") + boost::lexical_cast<std::string>(V) + "]"; } + }; + + + /// Expression that encapsulates a compiletime vector + template<int Size, int V0 = 0, int V1 = 0, int V2 = 0> + struct CVector : public LazyOperatorTermBase + { + typedef Vector<int> value_type; + value_type V; + + template<typename OT> + void initElement(OT* ot, const ElInfo* elInfo, + SubAssembler* subAssembler, Quadrature *quad, + const BasisFunction *basisFct = NULL) + { + V.resize(Size); + int values[Size] = {V0, V1, V2}; + V.setValues(&values); + } + + template<typename OT> + void initElement(OT* ot, const ElInfo* smallElInfo, const ElInfo* largeElInfo, + SubAssembler* subAssembler, Quadrature *quad, + const BasisFunction *basisFct = NULL) + { + initElement(ot, smallElInfo, subAssembler, quad, basisFct); + } + + inline value_type operator()(const int& iq) const { return V; } + + std::string str() const { return std::string("[V(") + boost::lexical_cast<std::string>(Size) + ")]"; } + }; + + + /// Expression that encapsulates a compiletime matrix + template<int Rows, int Cols, int V0 = 0, int V1 = 0, int V2 = 0, + int V3 = 0, int V4 = 0, int V5 = 0, + int V6 = 0, int V7 = 0, int V8 = 0> + struct CMatrix : public LazyOperatorTermBase + { + typedef Matrix<int> value_type; + value_type V; + + template<typename OT> + void initElement(OT* ot, const ElInfo* elInfo, + SubAssembler* subAssembler, Quadrature *quad, + const BasisFunction *basisFct = NULL) + { + V.resize(Rows, Cols); + int values[Rows*Cols] = {V0, V1, V2, V3, V4, V5, V6, V7, V8}; + V.setValues(&values); + } + + template<typename OT> + void initElement(OT* ot, const ElInfo* smallElInfo, const ElInfo* largeElInfo, + SubAssembler* subAssembler, Quadrature *quad, + const BasisFunction *basisFct = NULL) + { + initElement(ot, smallElInfo, subAssembler, quad, basisFct); + } + + inline value_type operator()(const int& iq) const { return V; } + + std::string str() const { return std::string("[M(") + boost::lexical_cast<std::string>(Rows) + ","+ boost::lexical_cast<std::string>(Cols) + ")]"; } + }; + + } // end namespace expressions + + + namespace traits + { + template<typename T> + struct remove_all_qualifiers + { + typedef typename boost::remove_cv + < typename boost::remove_pointer + < typename boost::remove_reference<T>::type >::type + >::type type; + }; + + + template<typename T> + struct pure_value { + typedef typename remove_all_qualifiers<T>::type type; + static type eval(const T& t) { return t; } + }; + + template<typename T> + struct pure_value<T&> { + typedef typename remove_all_qualifiers<T>::type type; + static type eval(T& t) { return t; } + }; + + template<typename T> + struct pure_value<T*> { + typedef typename remove_all_qualifiers<T>::type type; + static type eval(T* t) { return pure_value<T>::eval(*t); } + }; + + template<typename T> + struct pure_value<const T> { + typedef typename remove_all_qualifiers<T>::type type; + static type eval(const T& t) { return pure_value<T>::eval(t); } + }; + + } // end namespace traits + + namespace expressions + { + /// Expression that points to a value given by reference + template<typename T> + struct Reference : public LazyOperatorTermBase + { + typedef typename traits::pure_value<T>::type value_type; + const value_type& value; + Reference(const T& value_) : value(value_) {} + Reference(const T* value_) : value(*value_) {} + + template<typename List> + void insertFeSpaces(List& feSpaces) const {} + + int getDegree() const + { + return 0; + } + + template<typename OT> + void initElement(OT* ot, const ElInfo* elInfo, + SubAssembler* subAssembler, Quadrature *quad, + const BasisFunction *basisFct = NULL) {} + + template<typename OT> + void initElement(OT* ot, const ElInfo* smallElInfo, const ElInfo* largeElInfo, + SubAssembler* subAssembler, Quadrature *quad, + const BasisFunction *basisFct = NULL) {} + + inline value_type operator()(const int& iq) const { return traits::pure_value<T>::eval(value); } + + std::string str() const { return std::string("&(") + boost::lexical_cast<std::string>(traits::pure_value<T>::eval(value)) + ")"; } + }; + + } // end namespace expressions + + + // generator functions + // _____________________________________________________________________________ + + template<typename T> + inline expressions::RValue<T> constant(T value) { return expressions::RValue<T>(value); } + + template<int I> + inline expressions::CValue<I> constant() { return expressions::CValue<I>(); } + + template<typename T> + inline expressions::Reference<T> ref_(T& value) { return expressions::Reference<T>(value); } + + template<typename T> + inline expressions::Reference<T> ref_(T* value) { return expressions::Reference<T>(value); } + +} // end namespace AMDiS + +#endif // AMDIS_VALUE_EXPR_HPP diff --git a/AMDiS/src/expressions/vec_functors.hpp b/AMDiS/src/expressions/vec_functors.hpp new file mode 100644 index 0000000000000000000000000000000000000000..a6f870478044260bd0410cd27f5738b695386648 --- /dev/null +++ b/AMDiS/src/expressions/vec_functors.hpp @@ -0,0 +1,427 @@ +/****************************************************************************** + * + * AMDiS - Adaptive multidimensional simulations + * + * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. + * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis + * + * Authors: + * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * + * This file is part of AMDiS + * + * See also license.opensource.txt in the distribution. + * + ******************************************************************************/ + + + +/** \file vec_functors.hpp */ + +#ifndef AMDIS_VEC_FUNCTORS_HPP +#define AMDIS_VEC_FUNCTORS_HPP + +#include "functor_expr.hpp" +#include "operations/norm.hpp" +#include "operations/product.hpp" + +namespace AMDiS +{ + namespace traits + { + template<typename T> struct is_always_true : boost::mpl::true_ {}; + } + + namespace result_of + { + // helper class for UnaryExpr + template<template<class> class Functor, + typename Term, + template<class> class Condition1 = traits::is_always_true, + template<class> class Condition2 = traits::is_always_true, + template<class> class Condition3 = traits::is_always_true> + struct UnaryExpr : boost::enable_if + < + typename boost::mpl::and_ + < + typename traits::is_expr<Term>::type, + typename boost::mpl::or_ + < + typename Condition1<typename Term::value_type>::type, + typename Condition2<typename Term::value_type>::type, + typename Condition3<typename Term::value_type>::type + >::type + >, + expressions::Function1<Functor<typename Term::value_type>, Term> + > {}; + + // helper class for UnaryExpr + template<class Functor, + typename Term, + template<class> class Condition1 = traits::is_always_true, + template<class> class Condition2 = traits::is_always_true, + template<class> class Condition3 = traits::is_always_true> + struct UnaryExprFull : boost::enable_if + < + typename boost::mpl::and_ + < + typename traits::is_expr<Term>::type, + typename boost::mpl::or_ + < + typename Condition1<typename Term::value_type>::type, + typename Condition2<typename Term::value_type>::type, + typename Condition3<typename Term::value_type>::type + >::type + >, + expressions::Function1<Functor, Term> + > {}; + + + // helper class for BinaryExpr + template<template<class,class> class Functor, + typename Term1, typename Term2, + template<class> class Condition1 = traits::is_always_true, + template<class> class Condition2 = traits::is_always_true, + template<class> class Condition3 = traits::is_always_true, + typename Expr1 = typename traits::to_expr<Term1>::type, + typename Expr2 = typename traits::to_expr<Term2>::type> + struct BinaryExpr : boost::enable_if + < + typename boost::mpl::and_ + < + typename traits::is_valid_arg2<Term1, Term2>::type, + typename boost::mpl::or_ + < + typename Condition1<typename Expr1::value_type>::type, + typename Condition2<typename Expr1::value_type>::type, + typename Condition3<typename Expr1::value_type>::type + >::type, + typename boost::mpl::or_ + < + typename Condition1<typename Expr2::value_type>::type, + typename Condition2<typename Expr2::value_type>::type, + typename Condition3<typename Expr2::value_type>::type + >::type + >::type, + expressions::Function2 + < + Functor<typename Expr1::value_type, typename Expr2::value_type>, + Expr1, Expr2 + > + > {}; + + } // end namespace result_of + + + /// expression with one vector + template<template<class> class Functor, typename Term> + inline typename result_of::UnaryExpr<Functor, Term>::type + unary_expr(const Term& t) + { + return function_< Functor< typename Term::value_type > >(t); + } + + template<class Functor, typename Term> + inline typename result_of::UnaryExprFull<Functor, Term>::type + unary_expr_full(const Term& t) + { + return function_< Functor >(t); + } + + + /// expression with two vectors v1, v2 + template<template<class,class> class Functor, typename Term1, typename Term2> + inline typename result_of::BinaryExpr<Functor, Term1, Term2>::type + binary_expr(const Term1& t1, const Term2& t2) + { + typedef typename traits::to_expr<Term1>::to Expr1; + typedef typename traits::to_expr<Term2>::to Expr2; + return function_ + < Functor< typename Expr1::type::value_type, typename Expr2::type::value_type > > + (Expr1::get(t1), Expr2::get(t2)); + } + + +// two_norm of vectors +// _____________________________________________________________________________ + + namespace result_of + { + template<typename T> + struct two_norm<T, tag::expression> : result_of::UnaryExpr<functors::TwoNorm, T, traits::is_vector> {}; + } + + /// the 2-norm of a vector v: result = sqrt(v^H * v) + template<typename Term> + inline typename result_of::two_norm<Term, tag::expression>::type + two_norm_dispatch(const Term& t, tag::expression) + { + return unary_expr< functors::TwoNorm >(t); + } + + +// one_norm of vectors and matrices +// _____________________________________________________________________________ + + namespace result_of + { + template<typename T> + struct one_norm<T, tag::expression> : result_of::UnaryExpr<functors::OneNorm, T, traits::is_vector, traits::is_matrix> {}; + } + + /// the 2-norm of a vector v: result = sqrt(v^H * v) + template<typename Term> + inline typename result_of::one_norm<Term, tag::expression>::type + one_norm_dispatch(const Term& t, tag::expression) + { + return unary_expr< functors::OneNorm >(t); + } + + +// p_norm<P> of vectors +// _____________________________________________________________________________ + + namespace result_of + { + template<int P, typename T> + struct p_norm<P, T, tag::expression> : result_of::UnaryExprFull<functors::PNorm<P, typename T::value_type>, T, traits::is_vector> {}; + } + + /// the 2-norm of a vector v: result = sqrt(v^H * v) + template<int P, typename Term> + inline typename result_of::p_norm<P, Term, tag::expression>::type + p_norm_dispatch(const Term& t, tag::expression) + { + return unary_expr_full< functors::PNorm<P, typename Term::value_type> >(t); + } + + +// unary dot (v' * v) of a vector v +// _____________________________________________________________________________ + + namespace result_of + { + template<typename T> + struct unary_dot<T, tag::expression> : result_of::UnaryExpr<functors::UnaryDot, T, traits::is_vector> {}; + } + + /// the 2-norm squared of a vector v: result = v^H * v + template<typename Term> + inline typename result_of::unary_dot<Term, tag::expression>::type + unary_dot_dispatch(const Term& t, tag::expression) + { + return unary_expr< functors::UnaryDot >(t); + } + + +// inner product of two vectors +// _____________________________________________________________________________ + + namespace result_of + { + template<typename T1, typename T2> + struct dot<T1, T2, tag::expression, tag::expression> : result_of::BinaryExpr<functors::Inner, T1, T2, traits::is_vector> {}; + template<typename T1, typename T2> + struct dot<T1, T2, tag::expression, tag::vector> : result_of::BinaryExpr<functors::Inner, T1, T2, traits::is_vector> {}; + template<typename T1, typename T2> + struct dot<T1, T2, tag::vector, tag::expression> : result_of::BinaryExpr<functors::Inner, T1, T2, traits::is_vector> {}; + } + + /// inner/dot product of two vectors v1, v2: result = v1^T * v2 + template<typename Term1, typename Term2, typename Tag2> + inline typename boost::enable_if< typename traits::is_expr<Term1>::type, + typename result_of::dot<Term1, Term2, tag::expression, Tag2>::type + >::type + dot_dispatch(const Term1& t1, const Term2& t2, tag::expression tag1_, Tag2 tag2_) + { + return binary_expr<functors::Inner>(t1, t2); + } + + template<typename Term1, typename Term2, typename Tag1> + inline typename boost::enable_if_c< (traits::is_expr<Term2>::type::value && !(traits::is_expr<Term1>::type::value)), + typename result_of::dot<Term1, Term2, Tag1, tag::expression>::type + >::type + dot_dispatch(const Term1& t1, const Term2& t2, Tag1 tag1_, tag::expression tag2_) + { + return binary_expr<functors::Inner>(t1, t2); + } + + +// cross-product of two vectors +// _____________________________________________________________________________ + + namespace result_of + { + template<typename T1, typename T2> + struct cross<T1, T2, tag::expression, tag::expression> : result_of::BinaryExpr<functors::Cross, T1, T2, traits::is_vector> {}; + template<typename T1, typename T2> + struct cross<T1, T2, tag::expression, tag::vector> : result_of::BinaryExpr<functors::Cross, T1, T2, traits::is_vector> {}; + template<typename T1, typename T2> + struct cross<T1, T2, tag::vector, tag::expression> : result_of::BinaryExpr<functors::Cross, T1, T2, traits::is_vector> {}; + } + + /// cross product of two vectors v1, v2: result = v1 x v2 + template<typename Term1, typename Term2, typename Tag2> + inline typename boost::enable_if< typename traits::is_expr<Term1>::type, + typename result_of::cross<Term1, Term2, tag::expression, Tag2>::type + >::type + cross_dispatch(const Term1& t1, const Term2& t2, tag::expression tag1_, Tag2 tag2_) + { + return binary_expr<functors::Cross>(t1, t2); + } + + template<typename Term1, typename Term2, typename Tag1> + inline typename boost::enable_if_c< (traits::is_expr<Term2>::type::value && !(traits::is_expr<Term1>::type::value)), + typename result_of::cross<Term1, Term2, Tag1, tag::expression>::type + >::type + cross_dispatch(const Term1& t1, const Term2& t2, Tag1 tag1_, tag::expression tag2_) + { + return binary_expr<functors::Cross>(t1, t2); + } + + +// generator for a diagonal matrix from a vector +// _____________________________________________________________________________ + + namespace expressions + { + template<typename VectorType> + struct DiagonalMat : public FunctorBase {}; + + template<typename T> + struct DiagonalMat<WorldVector<T> > : public FunctorBase + { + typedef WorldMatrix<T> result_type; + + int getDegree(int d0) const { return d0; } + result_type operator()(const WorldVector<T> &v) const + { + T zero; nullify(zero); + result_type matrix(DEFAULT_VALUE, zero); + for (int i = 0; i < v.getSize(); ++i) + matrix[i][i] = v[i]; + return matrix; + } + }; + + template<typename T> + struct DiagonalMat<DimVec<T> > : public FunctorBase + { + typedef DimMat<T> result_type; + + int getDegree(int d0) const { return d0; } + result_type operator()(const DimVec<T> &v) const + { + T zero; nullify(zero); + result_type matrix(v.getDim(), DEFAULT_VALUE, zero); + for (int i = 0; i < v.getSize(); ++i) + matrix[i][i] = v[i]; + return matrix; + } + }; + + template<typename T> + struct DiagonalMat<Vector<T> > : public FunctorBase + { + typedef Matrix<T> result_type; + + int getDegree(int d0) const { return d0; } + result_type operator()(const DimVec<T> &v) const + { + T zero; nullify(zero); + result_type matrix(v.getSize(), v.getSize()); + matrix.set(zero); + for (int i = 0; i < v.getSize(); ++i) + matrix[i][i] = v[i]; + return matrix; + } + }; + + template<typename T, typename Param> + struct DiagonalMat<mtl::dense_vector<T, Param> > : public FunctorBase + { + typedef mtl::matrix::compressed2D<T, mtl::matrix::parameters<> > result_type; + + int getDegree(int d0) const { return d0; } + template<typename Vector> + result_type operator()(const Vector &v) const + { + return diagonal(v); + } + }; + } + + + /// create diagonal matrix from vector + template<typename Term> + inline typename result_of::UnaryExpr<expressions::DiagonalMat, Term, traits::is_vector>::type + diagonal(const Term& t) + { + return unary_expr<expressions::DiagonalMat>(t); + } + + +// outer product / dyadic product of two vectors to create a matrix +// _____________________________________________________________________________ + + /// outer product of two vectors v1, v2: result = v1 * v2^T + template<typename Term1, typename Term2> + inline typename result_of::BinaryExpr<functors::Outer, Term1, Term2, traits::is_vector>::type + outer(const Term1& t1, const Term2& t2) + { + return binary_expr<functors::Outer>(t1, t2); + } + + +// extract a component of a vector/matrix +// _____________________________________________________________________________ + + namespace expressions + { + template<typename T> + struct VecComponent : public FunctorBase + { + typedef typename traits::category<T>::value_type result_type; + VecComponent(int I_) : I(I_) {} + + int getDegree(int d0) const { return d0; } + result_type operator()(const T &v) const { return v[I]; } + private: + int I; + }; + + template<typename T> + struct MatComponent : public FunctorBase + { + typedef typename traits::category<T>::value_type result_type; + MatComponent(int I_, int J_) : I(I_), J(J_) {} + + int getDegree(int d0) const { return d0; } + result_type operator()(const T &m) const { return m[I][J]; } + private: + int I; + int J; + }; + } + + template<typename Term> + typename result_of::UnaryExpr<expressions::VecComponent, Term, traits::is_vector>::type + at(const Term& t, int I) + { + return function_(expressions::VecComponent<typename Term::value_type>(I), t); + } + + template<typename Term> + typename result_of::UnaryExpr<expressions::MatComponent, Term, traits::is_matrix>::type + at(const Term& t, int I, int J) + { + return function_(expressions::MatComponent<typename Term::value_type>(I, J), t); + } + +} + +#endif // AMDIS_VEC_FUNCTORS_HPP diff --git a/AMDiS/src/io/Arh2Reader.h b/AMDiS/src/io/Arh2Reader.h index 7b2fbfa56c7b44efe168d0005bc2b4e8bfc29108..744617bd1172c9254796e5e514d5c7471dd3c080 100644 --- a/AMDiS/src/io/Arh2Reader.h +++ b/AMDiS/src/io/Arh2Reader.h @@ -46,12 +46,11 @@ namespace AMDiS { namespace io { * if the value is set to true, in Parallel Model, the behavior depends on \ref nProcs. * But in Sequential Model, an error will be thrown. * \param nProcs - * It only affects when \ref writeParallel is set to true. + * the default value is -1. But it only affects when \ref writeParallel is set to true. * If nProcs is -1, and it's in Parallel Model, every processor reads their own filename (with processor * numbers). But in Sequential Model, an error will be thrown. - * And you can also set nProcs to the number of the arh files created last time. Then every - * processor will read all the files to search their own data block, which is useful for restart from - * a different partition. + * And you can also set nProcs to a value which is smaller than the number of Processors. Then every + * processor will read all the files with names from -p0- to -p[nProcs]-. */ void readFile(std::string filename, SystemVector* sysVec, @@ -189,14 +188,11 @@ namespace AMDiS { namespace io { int readMetaFromArh(std::string filename, std::map<int, int> &elInRank, std::map<int, int> &elCodeSize); - + /// Only returns just the number of subdomains a meta ARH file is defined for. int readMetaData(std::string filename); - /// Please make sure the number of processors matches the the number of parallel arh files - /// when calling the following functions. - /// Returns the number of value vectors in the file. int readNumOfValueVectors(std::string filename, bool writeParallel = WRITE_PARALLEL); diff --git a/AMDiS/src/io/FileWriter.cc b/AMDiS/src/io/FileWriter.cc index c006f36fc6b4f4be2883cfdb4275094695ee5cd1..0a54ddc7778982257eee264c190e1535dc579060 100644 --- a/AMDiS/src/io/FileWriter.cc +++ b/AMDiS/src/io/FileWriter.cc @@ -125,8 +125,9 @@ namespace AMDiS if (createParaViewSubDir) { using namespace boost::filesystem; path vtu_path = fn; + path data_basedir("data"); path vtu_filename = vtu_path.filename(); - vtu_path.remove_filename() /= vtu_filename.stem(); + vtu_path.remove_filename() /= data_basedir; try { create_directory(vtu_path); vtu_path /= vtu_filename; diff --git a/AMDiS/src/io/FileWriter.h b/AMDiS/src/io/FileWriter.h index e5497574320a329a5720b591ece679c0aa5ad002..201000732ec774fb1072371b82af158c3031a878 100644 --- a/AMDiS/src/io/FileWriter.h +++ b/AMDiS/src/io/FileWriter.h @@ -32,63 +32,12 @@ #include <vector> #include <string> #include "AMDiS_fwd.h" +#include "FileWriterInterface.h" #include "Mesh.h" #include "DataCollector.h" #include "FileCompression.h" namespace AMDiS { - - class FileWriterInterface - { - public: - FileWriterInterface() - : filename(""), - traverseLevel(-1), - traverseFlag(Mesh::CALL_LEAF_EL), - writeElement(NULL) - {} - - virtual ~FileWriterInterface() {} - - /** \brief - * Interface. Must be overridden in subclasses. - * \param time time index of solution std::vector. - * \param force enforces the output operation for the last timestep. - */ - virtual void writeFiles(AdaptInfo *adaptInfo, bool force, - int level = -1, - Flag traverseFlag = Mesh::CALL_LEAF_EL, - bool (*writeElem)(ElInfo*) = NULL) = 0; - - void setTraverseProperties(int level, - Flag flag, - bool (*writeElem)(ElInfo*)) - { - traverseLevel = level; - traverseFlag |= flag; - writeElement = writeElem; - } - - std::string getFilename() - { - return filename; - } - - void setFilename(std::string n) - { - filename = n; - } - - protected: - /// Used filename prefix. - std::string filename; - - int traverseLevel; - - Flag traverseFlag; - - bool (*writeElement)(ElInfo*); - }; namespace detail { diff --git a/AMDiS/src/io/FileWriterInterface.h b/AMDiS/src/io/FileWriterInterface.h new file mode 100644 index 0000000000000000000000000000000000000000..43e0faf9995d47cedd42a2243785ad3521fba570 --- /dev/null +++ b/AMDiS/src/io/FileWriterInterface.h @@ -0,0 +1,93 @@ +/****************************************************************************** + * + * AMDiS - Adaptive multidimensional simulations + * + * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. + * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis + * + * Authors: + * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * + * This file is part of AMDiS + * + * See also license.opensource.txt in the distribution. + * + ******************************************************************************/ + + + +/** \file FileWriterInterface.h */ + +/** \defgroup Output Output module + * @{ <img src="output.png"> @} + */ + +#ifndef AMDIS_FILEWRITER_INTERFACE_H +#define AMDIS_FILEWRITER_INTERFACE_H + +#include <vector> +#include <string> +#include "AMDiS_fwd.h" +#include "Mesh.h" + +namespace AMDiS { + + class FileWriterInterface + { + public: + FileWriterInterface() + : filename(""), + traverseLevel(-1), + traverseFlag(Mesh::CALL_LEAF_EL), + writeElement(NULL) + {} + + virtual ~FileWriterInterface() {} + + /** \brief + * Interface. Must be overridden in subclasses. + * \param time time index of solution std::vector. + * \param force enforces the output operation for the last timestep. + */ + virtual void writeFiles(AdaptInfo *adaptInfo, bool force, + int level = -1, + Flag traverseFlag = Mesh::CALL_LEAF_EL, + bool (*writeElem)(ElInfo*) = NULL) = 0; + + void setTraverseProperties(int level, + Flag flag, + bool (*writeElem)(ElInfo*)) + { + traverseLevel = level; + traverseFlag |= flag; + writeElement = writeElem; + } + + std::string getFilename() + { + return filename; + } + + void setFilename(std::string n) + { + filename = n; + } + + protected: + /// Used filename prefix. + std::string filename; + + int traverseLevel; + + Flag traverseFlag; + + bool (*writeElement)(ElInfo*); + }; + +} + +#endif diff --git a/AMDiS/src/io/MacroInfo.cc b/AMDiS/src/io/MacroInfo.cc index 1e28a31e99a63b9dd71af3d4a98dd438f0feb682..bf64f1d7b9e0c1b71097bd52d2f0a8ce84f0ed4e 100644 --- a/AMDiS/src/io/MacroInfo.cc +++ b/AMDiS/src/io/MacroInfo.cc @@ -29,13 +29,16 @@ #include <cstring> namespace AMDiS { - void MacroInfo::fill(Mesh *pmesh, int nElements, int nVertices) + void MacroInfo::fill(Mesh *pmesh, int nelements, int nvertices) { FUNCNAME("MacroInfo::fill()"); TEST_EXIT(pmesh)("no mesh\n"); mesh = pmesh; + nElements = nelements; + nVertices = nvertices; + mesh->setNumberOfElements(nElements); mesh->setNumberOfLeaves(nElements); mesh->setNumberOfVertices(nVertices); @@ -79,6 +82,10 @@ namespace AMDiS { mesh = nullptr; neigh_set = false; + + nElements = 0; + nVertices = 0; + initialized = false; } @@ -143,10 +150,14 @@ namespace AMDiS { return const_cast<const char *>(key); } - void MacroInfo::readAMDiSMacro(std::string filename, Mesh* mesh) { FUNCNAME("MacroInfo::readAMDiSMacro()"); + + if (initialized) { + WARNING("The old data in macro info will be removed.\n"); + clear(); + } int dim, dow; int nElements, nVertices; @@ -494,6 +505,8 @@ namespace AMDiS { delete ind; fclose(file); + + initialized = true; } @@ -596,5 +609,5 @@ namespace AMDiS { ERROR_EXIT("invalid dim\n"); } } - + } diff --git a/AMDiS/src/io/MacroInfo.h b/AMDiS/src/io/MacroInfo.h index d3836b8d5502755a3d015d78662cfd73dce97043..2067498825c9024663406def903ad44dc8be7728 100644 --- a/AMDiS/src/io/MacroInfo.h +++ b/AMDiS/src/io/MacroInfo.h @@ -58,8 +58,13 @@ namespace AMDiS { /// true, if boundary information is in macro file bool bound_set; + + int nElements; + + int nVertices; public: + MacroInfo() : initialized(false) {}; /** \brief * Reads macro triangulation from ascii file in AMDiS format. * Fills MacroInfo structure. @@ -80,10 +85,17 @@ namespace AMDiS { void dirichletBoundary(); void fillBoundaryInfo(Mesh *mesh); + + bool isInitialized() + { + return initialized; + } protected: /// Reads indices from macro file int read_indices(FILE *file, DimVec<int> &id); + + bool initialized; }; } diff --git a/AMDiS/src/io/MacroReader.cc b/AMDiS/src/io/MacroReader.cc index fba012ff030dbaa718c3266682076c948a1fcb1d..5f6ad0414ba2d73752a4956779ebb6212fb4b2da 100644 --- a/AMDiS/src/io/MacroReader.cc +++ b/AMDiS/src/io/MacroReader.cc @@ -38,6 +38,54 @@ #include "VertexVector.h" namespace AMDiS { namespace io { + + void MacroReader::restoreMacroDofs(MacroInfo& macroInfo, int check) + { + FUNCNAME("MacroReader::restoreMacroDofs()"); + + TEST_EXIT(macroInfo.isInitialized()) + ("Cannot set dof since macro info is not initialized.\n"); + + Mesh* mesh = macroInfo.mesh; + int nVertices = macroInfo.nVertices; + int nElements = macroInfo.nElements; + int **mel_vertex = macroInfo.mel_vertex; + DegreeOfFreedom** dof = macroInfo.dof; + + TEST_EXIT(mesh->getNumberOfMacros() == nElements) + ("Mesh's current macro doesn't match the macro file.\n"); + + mesh->setNumberOfElements(nElements); + mesh->setNumberOfLeaves(nElements); + mesh->setNumberOfVertices(nVertices); + + // Vertices dofs + for (int i = 0; i < nVertices; i++) + dof[i] = mesh->getDof(VERTEX); + + std::deque<MacroElement*>::iterator it = mesh->firstMacroElement(); + + for (int i = 0; i < mesh->getNumberOfMacros(); i++) + for (int k = 0; k < mesh->getGeo(VERTEX); k++) + const_cast<Element*>((*(it + i))->getElement())-> + setDof(k, dof[mel_vertex[i][k]]); + + // Edge and face dofs + if (mesh->getDim() > 1) + boundaryDOFs(mesh); + + // Center dofs + if (mesh->getNumberOfDofs(CENTER)) { + it = mesh->firstMacroElement(); + + for (int i = 0; i < mesh->getNumberOfMacros(); i++) + const_cast<Element*>(it[i]->getElement())-> + setDof(mesh->getNode(CENTER), mesh->getDof(CENTER)); + } + + if (check) + checkMesh(mesh); + } MacroInfo* MacroReader::readMacro(std::string filename, Mesh* mesh, @@ -234,7 +282,7 @@ namespace AMDiS { namespace io { // ========================================================= - + // Set coordinate for (int i = 0; i < mesh->getNumberOfMacros(); i++) { for (int k = 0; k < mesh->getGeo(VERTEX); k++) { (*(mel + i))->setCoord(k, coords[melVertex[i][k]]); @@ -338,8 +386,7 @@ namespace AMDiS { namespace io { return macroInfo; } - - + void MacroReader::computeNeighbours(Mesh *mesh) { FUNCNAME("MacroReader::computeNeighbours()"); @@ -481,6 +528,7 @@ namespace AMDiS { namespace io { // check for periodic boundary Element *el = const_cast<Element*>((*(mel+i))->getElement()); + ElementData *ed = el->getElementData(PERIODIC); DimVec<bool> periodic(dim, DEFAULT_VALUE, false); diff --git a/AMDiS/src/io/MacroReader.h b/AMDiS/src/io/MacroReader.h index 4153579752fe83716112114d137c8f05e1c8446e..79ffa4f8a5e6d74b59ff8f55a47eb3d01a4c0354 100644 --- a/AMDiS/src/io/MacroReader.h +++ b/AMDiS/src/io/MacroReader.h @@ -96,7 +96,14 @@ namespace AMDiS { namespace io { Mesh* mesh, std::string periodicFile, int check); - + + /** \brief + * Used only for mesh repartition when the mesh is in initial state only + * containing macro elements without refinement even dofs. Then this + * function will reset all the dofs of macros. + */ + static void restoreMacroDofs(MacroInfo& macroInfo, int check = 1); + protected: static void computeNeighbours(Mesh *mesh); diff --git a/AMDiS/src/io/PngReader.h b/AMDiS/src/io/PngReader.h index 8f8b9c0891a55817445b6ed6a40e1765679a61e9..aab187e16125cbf11bbf2cf77b8ef374726ba2eb 100644 --- a/AMDiS/src/io/PngReader.h +++ b/AMDiS/src/io/PngReader.h @@ -56,7 +56,7 @@ namespace AMDiS { namespace io { inline void readFile(std::string filename, DOFVector<double> &dofVector) { - readFile(filename, dofVector); + readFile(filename, &dofVector); } } diff --git a/AMDiS/src/io/VtkReader.hh b/AMDiS/src/io/VtkReader.hh index ef0fa888c3ddb386071749e0778cab4b0840cbb2..874bd8d6de0e80507ea1e4b2095910aa2d876d40 100644 --- a/AMDiS/src/io/VtkReader.hh +++ b/AMDiS/src/io/VtkReader.hh @@ -27,8 +27,10 @@ #include "Mesh.h" #include "boost/filesystem.hpp" #include "pugixml.hpp" +// extension { #include "kdtree_nanoflann.h" #include "VectorOperations.h" +// } #include "detail/VtkReader.h" namespace AMDiS @@ -88,9 +90,9 @@ namespace AMDiS int nComponents = -1; if (DataArray.attribute("NumberOfComponents")) nComponents = DataArray.attribute("NumberOfComponents").as_int(); - TEST_EXIT(nComponents == -1 || static_cast<int>(vector_operations::num_rows(test)) <= nComponents) + TEST_EXIT(nComponents == -1 || static_cast<int>(size(test)) <= nComponents) ("Can not read values in DOFVector with given value type. Too many components!\n"); - detail::string2valueList(values, valueList[i], vector_operations::num_rows(test), nComponents); + detail::string2valueList(values, valueList[i], size(test), nComponents); break; } } @@ -151,9 +153,9 @@ namespace AMDiS int nComponents = -1; if (pointDataIndex[i].first.attribute("NumberOfComponents")) nComponents = pointDataIndex[i].first.attribute("NumberOfComponents").as_int(); - TEST_EXIT(nComponents == -1 || static_cast<int>(vector_operations::num_rows(test)) <= nComponents) + TEST_EXIT(nComponents == -1 || static_cast<int>(size(test)) <= nComponents) ("Can not read values in DOFVector with given value type. Too many components!\n"); - detail::binary2valueList(values, type, (zlib != ""), valueList[j], vector_operations::num_rows(test), nComponents); + detail::binary2valueList(values, type, (zlib != ""), valueList[j], size(test), nComponents); break; } } @@ -169,7 +171,7 @@ namespace AMDiS DOFVector<WorldVector<double> > coords(dofVectors[0]->getFeSpace(), "coords"); dofVectors[0]->getFeSpace()->getMesh()->getDofIndexCoords(coords); - experimental::KD_Tree tree(Global::getGeo(WORLD), pointList, 10); + extensions::KD_Tree tree(Global::getGeo(WORLD), pointList, 10); tree.index->buildIndex(); DOFIterator<WorldVector<double> > it_coords(&coords, USED_DOFS); diff --git a/AMDiS/src/io/XYZReader.cc b/AMDiS/src/io/XYZReader.cc index eda0d358a96460499520aa5c87c6d6121954218f..3bcfcc56767ed1b4b65caa8f355dd2f8b3838650 100644 --- a/AMDiS/src/io/XYZReader.cc +++ b/AMDiS/src/io/XYZReader.cc @@ -18,6 +18,7 @@ * ******************************************************************************/ +#ifdef HAVE_EXTENSIONS #include <cstring> #include <fstream> @@ -46,7 +47,7 @@ namespace AMDiS { namespace io { std::vector<std::vector<double> > > &data) { FUNCNAME("readFile()"); - using ::AMDiS::io::VtkReader::detail::string2valueList; + using VtkReader::detail::string2valueList; TEST_EXIT(filename != "")("Filename not specified!\n"); @@ -98,3 +99,7 @@ namespace AMDiS { namespace io { } // end namespace XYZReader } } // end namespace io, AMDiS + +#endif + + diff --git a/AMDiS/src/io/XYZReader.h b/AMDiS/src/io/XYZReader.h index 9cdedd87845be5eb230512ac21e3a4ec198a89c5..27361d38b6d20c8d093b82ddbbabe8222f247c3b 100644 --- a/AMDiS/src/io/XYZReader.h +++ b/AMDiS/src/io/XYZReader.h @@ -25,6 +25,8 @@ #ifndef AMDIS_XYZREADER_H #define AMDIS_XYZREADER_H +#ifdef HAVE_EXTENSIONS + #include <cstring> namespace AMDiS { namespace io { @@ -51,3 +53,6 @@ namespace AMDiS { namespace io { } } // end namespace io, AMDiS #endif + +#endif + diff --git a/AMDiS/src/io/detail/Arh2Reader.h b/AMDiS/src/io/detail/Arh2Reader.h index 834f85ed8e7c52ee46bc9df866282751b79731de..d4d82d061abcd454f10ceec820d7cfff1c270b0f 100644 --- a/AMDiS/src/io/detail/Arh2Reader.h +++ b/AMDiS/src/io/detail/Arh2Reader.h @@ -78,4 +78,4 @@ namespace AMDiS { namespace io { } // end namespace Arh2Reader } } // end namespace io, AMDiS -#endif \ No newline at end of file +#endif diff --git a/AMDiS/src/io/detail/Arh2Writer.cc b/AMDiS/src/io/detail/Arh2Writer.cc index 071fb96294cc57e4777af5addbccd67e538e3c2c..8257d4d3c661ebeb638c52b62dd4e72bdf0b5818 100644 --- a/AMDiS/src/io/detail/Arh2Writer.cc +++ b/AMDiS/src/io/detail/Arh2Writer.cc @@ -434,6 +434,7 @@ namespace AMDiS { namespace io { file << tmp.rdbuf(); return tmp.str().length(); } + }//end namespace detail } // end namespace Arh2Writer -} } // end namespace io, AMDiS \ No newline at end of file +} } // end namespace io, AMDiS diff --git a/AMDiS/src/io/detail/Arh2Writer.h b/AMDiS/src/io/detail/Arh2Writer.h index 0b7d6b9d9f11a4e5c4170e055b8f2425e2b22568..a12ccf954f707705754acbaca87e7fa60b270678 100644 --- a/AMDiS/src/io/detail/Arh2Writer.h +++ b/AMDiS/src/io/detail/Arh2Writer.h @@ -68,4 +68,4 @@ namespace AMDiS { namespace io { } // end namespace Arh2Writer } } // end namespace io, AMDiS -#endif \ No newline at end of file +#endif diff --git a/AMDiS/src/io/detail/ArhReader.cc b/AMDiS/src/io/detail/ArhReader.cc index f24e7263855b98695b487470eacf5685cfc8ed24..777196153d64d6a1737637c43f238e7f794e3189 100644 --- a/AMDiS/src/io/detail/ArhReader.cc +++ b/AMDiS/src/io/detail/ArhReader.cc @@ -262,4 +262,4 @@ namespace AMDiS { namespace io { } }//end namespace detail } // end namespace ArhReader -} } // end namespace io, AMDiS \ No newline at end of file +} } // end namespace io, AMDiS diff --git a/AMDiS/src/io/detail/ArhReader.h b/AMDiS/src/io/detail/ArhReader.h index 84c8630c62d68264a159186688cbcb95f1ce4b41..f05de260a017037664e50a4314c317ac6db3c19d 100644 --- a/AMDiS/src/io/detail/ArhReader.h +++ b/AMDiS/src/io/detail/ArhReader.h @@ -33,6 +33,4 @@ namespace AMDiS { namespace io { } // end namespace ArhReader } } // end namespace io, AMDiS - - -#endif \ No newline at end of file +#endif diff --git a/AMDiS/src/io/detail/ArhWriter.cc b/AMDiS/src/io/detail/ArhWriter.cc index ad9c187b47dbe0cba94ee7990665c13b37b2f439..02c1f397295d66f8e92e913c70b42dec40439511 100644 --- a/AMDiS/src/io/detail/ArhWriter.cc +++ b/AMDiS/src/io/detail/ArhWriter.cc @@ -137,6 +137,7 @@ namespace AMDiS { namespace io { file.write(reinterpret_cast<char*>(&(values[i][0])), 8 * nValuesPerVector); } } + }//end namespace detail } // end namespace ArhWriter -} } // end namespace io, AMDiS \ No newline at end of file +} } // end namespace io, AMDiS diff --git a/AMDiS/src/io/detail/ArhWriter.h b/AMDiS/src/io/detail/ArhWriter.h index 48f599da8f362635e40184d746eec9178250b6ca..713596855173808d7db2b770062680b05d182bb1 100644 --- a/AMDiS/src/io/detail/ArhWriter.h +++ b/AMDiS/src/io/detail/ArhWriter.h @@ -25,10 +25,9 @@ namespace AMDiS { namespace io { MeshStructure &code, std::vector<std::vector<double> >& values, uint32_t elIndex); + }//end namespace detail } // end namespace ArhWriter } } // end namespace io, AMDiS - - -#endif \ No newline at end of file +#endif diff --git a/AMDiS/src/io/detail/VtkReader.h b/AMDiS/src/io/detail/VtkReader.h index bed5e5ab0626fafa7c3698981dd66df0330a1c59..89b915ce96710708900da87a71ba11b07f59839e 100644 --- a/AMDiS/src/io/detail/VtkReader.h +++ b/AMDiS/src/io/detail/VtkReader.h @@ -39,8 +39,10 @@ #include "Mesh.h" #include "boost/filesystem.hpp" #include "pugixml.hpp" +// extensions { #include "kdtree_nanoflann.h" #include "VectorOperations.h" +// } #define BLOCKSIZE 32768 @@ -305,7 +307,7 @@ namespace AMDiS // find point in mesh using KD-tree structure - inline size_t getNearestIndex(experimental::KD_Tree& tree, + inline size_t getNearestIndex(extensions::KD_Tree& tree, WorldVector<double>& x) { // do a knn search diff --git a/AMDiS/src/io/detail/VtkWriter.cc b/AMDiS/src/io/detail/VtkWriter.cc index 885be35260323832d6240db9ca7f70d83875d66b..808300a43066272395b657fcc441f24bd8b4749b 100644 --- a/AMDiS/src/io/detail/VtkWriter.cc +++ b/AMDiS/src/io/detail/VtkWriter.cc @@ -252,7 +252,7 @@ namespace AMDiS { namespace io { int nValues = static_cast<int>(componentNames.size()); nValues = writeAsVector ? std::min(nValues,1) : nValues; - for (size_t i = 0; i < nValues; i++) { + for (int i = 0; i < nValues; i++) { if(highPrecision && format != ::AMDiS::io::VtkWriter::ASCII) file << " <PDataArray type=\"Float64\" Name=\""; else diff --git a/AMDiS/src/operations/functors.hpp b/AMDiS/src/operations/functors.hpp new file mode 100644 index 0000000000000000000000000000000000000000..229114a9271a992da967ad8b97bdda5e6555c944 --- /dev/null +++ b/AMDiS/src/operations/functors.hpp @@ -0,0 +1,268 @@ +/****************************************************************************** + * + * AMDiS - Adaptive multidimensional simulations + * + * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. + * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis + * + * Authors: + * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * + * This file is part of AMDiS + * + * See also license.opensource.txt in the distribution. + * + ******************************************************************************/ + + + +/** \file functors.hpp */ + +#ifndef AMDIS_OPERATIONS_FUNCTOR_HPP +#define AMDIS_OPERATIONS_FUNCTOR_HPP + +#include <complex> +#include <cmath> + +#include <boost/math/special_functions/cbrt.hpp> +#include <boost/math/special_functions/pow.hpp> +#include "traits/types.hpp" +#include "operations/meta.hpp" + +namespace AMDiS +{ + struct FunctorBase + { + int getDegree() const { return 0; } + int getDegree(int d0) const { return 0; } + int getDegree(int d0, int d1) const { return 0; } + int getDegree(int d0, int d1, int d2) const { return 0; } + int getDegree(int d0, int d1, int d2, int d3) const { return 0; } + }; + + namespace functors + { + /// identity(v) == v + template<typename T> + struct identity : FunctorBase + { + typedef T result_type; + int degree(int d0) const { return d0; } + + static T eval(const T& v) { return v; } + T operator()(const T& v) const { return eval(v); } + }; + + /// constant(v) == val + template<typename T> + struct constant : FunctorBase + { + typedef T result_type; + constant(T val_) : val(val_) {} + + template<typename V> + result_type operator()(const V& v) const { return val; } + + private: + T val; + }; + + /// functor for operator+= + template<typename T> + struct assign : FunctorBase + { + typedef T result_type; + + static result_type& apply(T& v, T const& v0) { return (v = v0); } + result_type& operator()(T& v, T const& v0) { return apply(v,v0); } + }; + + /// functor for operator+= + template<typename T> + struct add_assign : FunctorBase + { + typedef T result_type; + + static result_type& apply(T& v, T const& v0) { return (v += v0); } + result_type& operator()(T& v, T const& v0) { return apply(v,v0); } + }; + + /// functor for operator*= + template<typename T> + struct mult_assign : FunctorBase + { + typedef T result_type; + + static result_type& apply(T& v, T const& v0) { return (v *= v0); } + result_type& operator()(T& v, T const& v0) { return apply(v,v0); } + }; + + /// abs(v) == |v| + template<typename T> + struct abs : FunctorBase + { + typedef T result_type; + int getDegree(int d0) const { return d0; } + + static result_type eval(const T& v) { return std::abs(v); } + result_type operator()(const T &v) const { return eval(v); } + }; + + template<typename T> + struct abs<std::complex<T> > : FunctorBase + { + typedef T result_type; + int getDegree(int d0) const { return d0; } + + static result_type eval(const T& v) { return std::norm(v); } + result_type operator()(const T &v) const { return eval(v); } + }; + + /// max(a,b) + template<typename T> + struct max : FunctorBase + { + typedef T result_type; + int getDegree(int d0) const { return d0; } + + static result_type eval(const T& v0, const T& v1) { return std::max(v0, v1); } + result_type operator()(const T &v0, const T& v1) const { return eval(v0,v1); } + }; + + /// min(a,b) + template<typename T> + struct min : FunctorBase + { + typedef T result_type; + int getDegree(int d0) const { return d0; } + + static result_type eval(const T& v0, const T& v1) { return std::min(v0, v1); } + result_type operator()(const T &v0, const T& v1) const { return eval(v0,v1); } + }; + + /// max(|a|,|b|) + template<typename T> + struct abs_max : FunctorBase + { + typedef T result_type; + int getDegree(int d0) const { return d0; } + + static result_type eval(const T& v0, const T& v1) { return std::max(std::abs(v0), std::abs(v1)); } + result_type operator()(const T &v0, const T& v1) const { return eval(v0,v1); } + }; + + /// min(|a|,|b|) + template<typename T> + struct abs_min : FunctorBase + { + typedef T result_type; + int getDegree(int d0) const { return d0; } + + static result_type eval(const T& v0, const T& v1) { return std::min(std::abs(v0), std::abs(v1)); } + result_type operator()(const T &v0, const T& v1) const { return eval(v0,v1); } + }; + + + /// apply a functor N times + template<typename Functor, int N> + struct apply + { + typedef typename Functor::result_type result_type; + + apply(const Functor& f_) : f(f_), inner(f_) {} + int getDegree(int d0) const + { + return f.getDegree(inner.getDegree(d0)); + } + + template<typename V> + static result_type eval(const V& v) { return Functor::eval(apply<Functor, N-1>::eval(v)); } + template<typename V> + result_type operator()(const V& v) const + { + return f(inner(v)); + } + + private: + const Functor& f; + apply<Functor, N-1> inner; + }; + + template<typename Functor> + struct apply<Functor, 0> + { + typedef typename Functor::result_type result_type; + + apply(const Functor& f_) : f(f_) {} + int getDegree(int d0) const { return d0; } + + template<typename V> + static result_type eval(const V& v) { return v; } + template<typename V> + result_type operator()(const V& v) const { return v; } + + private: + const Functor& f; + }; + + /// pow<p>(v) == v^p + template<int p, typename T> + struct pow : FunctorBase + { + typedef T result_type; + int getDegree(int d0) const { return p*d0; } + + static result_type eval(const T& v) { return boost::math::pow<p>(v); } + result_type operator()(const T& v) const { return eval(v); } + }; + + /// root<p>(v) == p-th-root(v) + template<int p, typename T, typename Enabled = void> + struct root_dispatch; + + template<int p, typename T> + struct root : FunctorBase + { + typedef T result_type; + int getDegree(int d0) const { return p*d0; } // optimal polynomial approximation degree ? + + static result_type eval(const T& v) { return root_dispatch<p,T>::eval(v); } + result_type operator()(const T& v) const { return eval(v); } + }; + + template<int p, typename T, typename Enabled> + struct root_dispatch { static T eval(const T& v) { return std::pow(v, 1.0/p); } }; + + template<int p, typename T> + struct root_dispatch<p, T, typename boost::enable_if<typename meta::is_power_of<p, 3>::type>::type> + { + static T eval(const T& v) { return apply<root<3, T>, meta::log<p, 3>::value>::eval(v); } + }; + + template<int p, typename T> + struct root_dispatch<p, T, typename boost::enable_if<typename meta::is_power_of<p, 2>::type>::type> + { + static T eval(const T& v) { return apply<root<2, T>, meta::log<p, 2>::value>::eval(v); } + }; + + template<typename T> + struct root_dispatch<3, T> { static T eval(const T& v) { return boost::math::cbrt(v); } }; + + template<typename T> + struct root_dispatch<2, T> { static T eval(const T& v) { return std::sqrt(v); } }; + + template<typename T> + struct root_dispatch<1, T> { static T eval(const T& v) { return v; } }; + + template<typename T> + struct root_dispatch<0, T> { static T eval(const T& v) { return 1.0; } }; + + } // end namespace functors + +} // end namespace AMDiS + +#endif // AMDIS_OPERATIONS_FUNCTOR_HPP diff --git a/AMDiS/src/operations/meta.hpp b/AMDiS/src/operations/meta.hpp new file mode 100644 index 0000000000000000000000000000000000000000..65b7f8e062e61af022a48df3f4b3e39967b2ea59 --- /dev/null +++ b/AMDiS/src/operations/meta.hpp @@ -0,0 +1,151 @@ +/****************************************************************************** + * + * AMDiS - Adaptive multidimensional simulations + * + * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. + * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis + * + * Authors: + * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * + * This file is part of AMDiS + * + * See also license.opensource.txt in the distribution. + * + ******************************************************************************/ + + + +/** \file meta.hpp */ + +#ifndef AMDIS_OPERATIONS_META_HPP +#define AMDIS_OPERATIONS_META_HPP + +#include <boost/mpl/bool.hpp> +#include <boost/mpl/if.hpp> +#include <boost/mpl/int.hpp> +#include <boost/mpl/not.hpp> + +namespace AMDiS +{ + namespace meta + { + /// abs<X> == |X| + // _________________________________________________________________________ + template<int X> + struct abs : boost::mpl::int_< (X >= 0 ? X : -X) > {}; + + /// pow<x, p> == x^p + // _________________________________________________________________________ + template<int X, int P> + struct pow : boost::mpl::int_< (X * pow<X, P-1>::value) > {}; + + template<int X> + struct pow<X, 0> : boost::mpl::int_< 1 > {}; + + template<int X> + struct sqr : pow<X, 2> {}; + + /// root<x, p> == p-th-root(x) + // _________________________________________________________________________ + template<int X, int P, int I = 1> + struct root : boost::mpl::if_c + < + boost::mpl::less<pow<I, P>, boost::mpl::int_<X> >::value, + root<X, P, I+1>, + boost::mpl::int_< I > + >::type {}; + + template<int X, int P> + struct root<X, P, X> : boost::mpl::int_< X > {}; + + template<int X> + struct sqrt : root<X, 2> {}; + + /// log<x, p> == log_p(x) + // _________________________________________________________________________ + template<int X, int P, int I = 1> + struct log : boost::mpl::if_c + < + boost::mpl::less<pow<P, I>, boost::mpl::int_<X> >::value, + log<X, P, I+1>, + boost::mpl::int_< I > + >::type {}; + + template<int X, int P> + struct log<X, P, X> : boost::mpl::int_< 0 > {}; + + + template<int X, int Base> + struct is_power_of : boost::mpl::bool_< (pow<Base, log<X, Base>::value>::value == X) > {}; + + /// is divisible by + // _________________________________________________________________________ + template<int U, int V> + struct is_divisible_by : boost::mpl::bool_< (U % V == 0) > {}; + + template<int U> + struct is_divisible_by<U, 0> : boost::mpl::false_ {}; + + template<int U> + struct is_even : is_divisible_by<U, 2> {}; + + template<int U> + struct is_odd : boost::mpl::not_< is_even<U> > {}; + + /// generic loops + // _________________________________________________________________________ + template<long I, long N> + struct FOR + { + template<class A, class B, class Op> + static void transform(A const& a, B& b, Op op, size_t shift = 0) + { + b[I+shift] = op(a[I+shift]); + FOR<I+1,N>::transform(a, b, op, shift); + } + + template<class A, class T, class Op, class BinaryOp> + static T accumulate(A const& a, T init, Op op, BinaryOp binary_op, size_t shift = 0) + { + return binary_op(FOR<I+1,N>::accumulate(a, init, op, binary_op, shift), + op(a[I+shift])); + } + + template<class A, class B, class T, class BinaryOp1, class BinaryOp2> + static T inner_product(A const& a, B const& b, T init, BinaryOp1 binary_op1, BinaryOp2 binary_op2, size_t shift = 0) + { + return binary_op1(FOR<I+1,N>::inner_product(a, b, init, binary_op1, binary_op2, shift), + binary_op2(a[I+shift], b[I+shift])); + } + }; + + // Abbruchbedingung I==N + template<long N> + struct FOR<N, N> + { + template<class A, class B, class Op> + static void transform(A const& a, B& b, Op op, size_t shift = 0) {} + + template<class A, class T, class Op, class BinaryOp> + static T accumulate(A const& a, T init, Op op, BinaryOp binary_op, size_t shift = 0) + { + return init; + } + + template<class A, class B, class T, class BinaryOp1, class BinaryOp2> + static T inner_product(A const& a, B const& b, T init, BinaryOp1 binary_op1, BinaryOp2 binary_op2, size_t shift = 0) + { + return init; + } + }; + + } // end namespace meta + +} // end namespace AMDiS + +#endif // AMDIS_OPERATIONS_META_HPP diff --git a/AMDiS/src/operations/norm.hpp b/AMDiS/src/operations/norm.hpp new file mode 100644 index 0000000000000000000000000000000000000000..f9ec4e966d51066be447ff715a9fa596360b697f --- /dev/null +++ b/AMDiS/src/operations/norm.hpp @@ -0,0 +1,215 @@ +/****************************************************************************** + * + * AMDiS - Adaptive multidimensional simulations + * + * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. + * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis + * + * Authors: + * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * + * This file is part of AMDiS + * + * See also license.opensource.txt in the distribution. + * + ******************************************************************************/ + + + +/** \file norm.hpp */ + +#ifndef AMDIS_OPERATIONS_NORM_HPP +#define AMDIS_OPERATIONS_NORM_HPP + +#include "AMDiS_fwd.h" +#include "Traits.h" +#include "traits/num_rows.hpp" +#include "traits/num_cols.hpp" +#include "traits/size.hpp" +#include "boost/numeric/mtl/operation/two_norm.hpp" +#include "boost/numeric/mtl/operation/one_norm.hpp" +#include "boost/numeric/mtl/vector/dense_vector.hpp" +#include "boost/numeric/mtl/vector/parameter.hpp" + +#include "operations/functors.hpp" + +namespace AMDiS +{ + // 2-norm + // ___________________________________________________________________________ + + namespace result_of + { + template <typename T, typename Tag> struct two_norm {}; + + template <typename T> + struct two_norm<T, tag::vector> : boost::mpl::identity<typename traits::category<T>::value_type> {}; + } + + template <typename T> + typename result_of::two_norm<T, tag::vector>::type + inline two_norm_dispatch(const T& v, tag::vector) + { + typedef typename traits::category<T>::value_type value_type; + typedef typename traits::category<T>::size_type size_type; + + using namespace mtl::vector; + typedef parameters<mtl::col_major, non_fixed::dimension, false, size_type> param; + mtl::dense_vector<value_type, param> tmp(AMDiS::size(v), v.begin()); + return mtl::two_norm(tmp); + } + + template <typename T> + typename boost::disable_if< typename traits::is_mtl<T>::type, + typename result_of::two_norm<T, typename traits::category<T>::tag>::type + >::type + inline two_norm(const T& t) + { + return two_norm_dispatch(t, typename traits::category<T>::tag()); + } + + + namespace functors + { + /// two_norm(v) == ||v||_2 == sqrt(v' * v) + template<typename T> + struct TwoNorm : FunctorBase + { + typedef typename result_of::two_norm<T, typename traits::category<T>::tag>::type result_type; + int getDegree(int d0) const { return 2*d0; } + + static result_type eval(const T& v) { return AMDiS::two_norm(v); } + result_type operator()(const T& v) const { return eval(v); } + }; + } + + + // 1-norm + // ___________________________________________________________________________ + + namespace result_of + { + template <typename T, typename Tag> struct one_norm {}; + + template <typename T> + struct one_norm<T, tag::vector> : boost::mpl::identity<typename traits::category<T>::value_type> {}; + template <typename T> + struct one_norm<T, tag::matrix> : boost::mpl::identity<typename traits::category<T>::value_type> {}; + } + + template <typename T> + typename result_of::one_norm<T, tag::vector>::type + inline one_norm_dispatch(const T& v, tag::vector) // for vector types + { + typedef typename traits::category<T>::value_type value_type; + typedef typename traits::category<T>::size_type size_type; + + using namespace mtl::vector; + typedef parameters<mtl::col_major, non_fixed::dimension, false, size_type> param; + mtl::dense_vector<value_type, param> tmp(AMDiS::size(v), v.begin()); + return mtl::vector::one_norm(tmp); + } + + template <typename T> + typename result_of::one_norm<T, tag::matrix>::type + inline one_norm_dispatch(const T& m, tag::matrix) // for matrix types + { + typedef typename traits::category<T>::value_type value_type; + value_type result; + nullify(result); + + typedef typename traits::category<T>::size_type size_type; + for (size_type j = 0; j < num_cols(m); ++j) { + value_type asum; nullify(asum); + for (size_type i = 0; i < num_rows(m); ++i) + asum += std::abs(at(m,i,j)); + result = std::max(result, asum); + } + return result; + } + + template <typename T> + typename boost::disable_if< typename traits::is_mtl<T>::type, + typename result_of::one_norm<T, typename traits::category<T>::tag>::type + >::type + inline one_norm(const T& t) + { + return one_norm_dispatch(t, typename traits::category<T>::tag()); + } + + + namespace functors + { + /// one_norm(v) == ||v||_1 == max_i(|v_i|) + template<typename T> + struct OneNorm : FunctorBase + { + typedef typename result_of::one_norm<T, typename traits::category<T>::tag>::type result_type; + int getDegree(int d0) const { return d0; } + + static result_type eval(const T& v) { return AMDiS::one_norm(v); } + result_type operator()(const T& v) const { return eval(v); } + }; + } + + + // p-norm + // ___________________________________________________________________________ + + namespace result_of + { + template <int P, typename T, typename Tag> struct p_norm {}; + + template <int P, typename T> + struct p_norm<P, T, tag::vector> : boost::mpl::identity<typename traits::category<T>::value_type> {}; + } + + template <int P, typename T> + typename result_of::p_norm<P, T, tag::vector>::type + inline p_norm_dispatch(const T& v, tag::vector) + { + typedef typename result_of::p_norm<P, T, tag::vector>::type value_type; + typedef typename traits::category<T>::size_type size_type; + static const int BLOCK_SIZE = 8; + + value_type result; + nullify(result); + + size_type i = 0; + for (; i+BLOCK_SIZE < size(v); i+=BLOCK_SIZE) + result = meta::FOR<0, BLOCK_SIZE>::accumulate(v, result, functors::pow<P, value_type>(), std::plus<value_type>(), i); + for (; i < size(v); i++) + result += functors::pow<P, value_type>::eval(v[i]); + + return functors::root<P, value_type>::eval(result); + } + + template <int P, typename T> + typename result_of::p_norm<P, T, typename traits::category<T>::tag>::type + inline p_norm(const T& t) + { + return p_norm_dispatch<P>(t, typename traits::category<T>::tag()); + } + + + namespace functors + { + /// + template<int p, typename T> + struct PNorm : FunctorBase + { + typedef typename result_of::p_norm<p, T, typename traits::category<T>::tag>::type result_type; + int getDegree(int d0) const { return p*d0; } + + static result_type eval(const T& v) { return AMDiS::p_norm<p>(v); } + result_type operator()(const T& v) const { return eval(v); } + }; + } + +} // end namespace AMDiS + +#endif // AMDIS_OPERATIONS_NORM_HPP diff --git a/AMDiS/src/operations/product.hpp b/AMDiS/src/operations/product.hpp new file mode 100644 index 0000000000000000000000000000000000000000..85a29407b5f9f00de79bad2e1c6a00d2d9beacab --- /dev/null +++ b/AMDiS/src/operations/product.hpp @@ -0,0 +1,277 @@ +/****************************************************************************** + * + * AMDiS - Adaptive multidimensional simulations + * + * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. + * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis + * + * Authors: + * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * + * This file is part of AMDiS + * + * See also license.opensource.txt in the distribution. + * + ******************************************************************************/ + + + +/** \file product.hpp */ + +#ifndef AMDIS_OPERATIONS_PRODUCT_HPP +#define AMDIS_OPERATIONS_PRODUCT_HPP + +#include "AMDiS_fwd.h" +#include "Traits.h" +#include "traits/num_rows.hpp" +#include "traits/num_cols.hpp" +#include "traits/size.hpp" +#include "operations/functors.hpp" +#include "operations/meta.hpp" + +#include "boost/numeric/mtl/operation/dot.hpp" +#include "boost/numeric/mtl/operation/unary_dot.hpp" +#include "boost/numeric/mtl/operation/cross.hpp" + +namespace AMDiS +{ + // (v1' * v2) + // ___________________________________________________________________________ + + namespace result_of + { + template <typename T1, typename T2, typename Tag1, typename Tag2> struct dot {}; + + template <typename T1, typename T2> + struct dot<T1, T2, tag::vector, tag::vector> + : boost::mpl::identity<typename traits::mult_type<T1, T2>::type> {}; + } + + template <typename T1, typename T2> + typename result_of::dot<T1, T2, tag::vector, tag::vector>::type + inline dot_dispatch(const T1& v1, const T2& v2, + tag::vector, tag::vector) + { + typedef typename traits::category<T1>::value_type value_type1; + typedef typename traits::category<T2>::value_type value_type2; + typedef typename traits::category<T1>::size_type size_type1; + typedef typename traits::category<T2>::size_type size_type2; + + using namespace mtl::vector; + typedef parameters<mtl::col_major, non_fixed::dimension, false, size_type1> param1; + typedef parameters<mtl::col_major, non_fixed::dimension, false, size_type2> param2; + mtl::dense_vector<value_type1, param1> tmp1(AMDiS::size(v1), v1.begin()); + mtl::dense_vector<value_type2, param2> tmp2(AMDiS::size(v2), v2.begin()); + return mtl::dot(tmp1, tmp2); + } + + template <typename T1, typename T2> + typename boost::lazy_disable_if< typename boost::mpl::or_ + < + typename traits::is_mtl<T1>::type, + typename traits::is_mtl<T2>::type + >::type, + typename result_of::dot< T1, T2, + typename traits::category<T1>::tag, + typename traits::category<T2>::tag + > + >::type + inline dot(const T1& v1, const T2& v2) + { + typedef typename traits::category<T1>::tag tag1_; + typedef typename traits::category<T2>::tag tag2_; + return dot_dispatch(v1, v2, tag1_(), tag2_()); + } + + template <typename T1, typename T2> + typename result_of::dot< T1, T2, + typename traits::category<T1>::tag, + typename traits::category<T2>::tag + >::type + inline inner(const T1& v1, const T2& v2) + { + return dot(v1, v2); + } + + + namespace functors + { + /// inner(v1, v2) == v1' * v2 + template<typename T1, typename T2> + struct Inner : FunctorBase + { + typedef typename result_of::dot<T1, T2, typename traits::category<T1>::tag, typename traits::category<T2>::tag>::type result_type; + int getDegree(int d0, int d1) const { return d0+d1; } + + static result_type eval(const T1 &v1, const T2& v2) { return dot(v1, v2); } + result_type operator()(const T1 &v1, const T2& v2) const { return eval(v1, v2); } + }; + } + + + // (v' * v) + // ___________________________________________________________________________ + + namespace result_of + { + template <typename T, typename Tag> struct unary_dot {}; + + template <typename T> + struct unary_dot<T, tag::vector> + : boost::mpl::identity<typename traits::mult_type<T,T>::type> {}; + } + + template <typename T> + typename result_of::unary_dot<T, tag::vector>::type + inline unary_dot_dispatch(const T& v, tag::vector) + { + return v*v; + } + + template <typename T> + typename boost::disable_if< typename traits::is_mtl<T>::type, + typename result_of::unary_dot<T, typename traits::category<T>::tag>::type + >::type + inline unary_dot(const T& t) + { + return unary_dot_dispatch(t, typename traits::category<T>::tag()); + } + + + namespace functors + { + /// unary_dot(v) = v' * v + template<typename T> + struct UnaryDot : FunctorBase + { + typedef typename result_of::unary_dot<T, typename traits::category<T>::tag>::type result_type; + int getDegree(int d0) const { return 2*d0; } + + static result_type eval(const T& v) { return unary_dot(v); } + result_type operator()(const T& v) const { return eval(v); } + }; + } + + + // (v1 x v2) + // ___________________________________________________________________________ + + namespace result_of + { + template <typename T1, typename T2, typename Tag1, typename Tag2, typename Enabled = void> struct cross {}; + + template <typename T1, typename T2> + struct cross< T1, T2, tag::vector, tag::vector, + typename boost::enable_if<typename traits::is_mtl<T1>::type>::type > + : mtl::vector::detail::cross_result<T1, T2> {}; + + template <template<typename> class Vector, typename T> + struct cross<Vector<T>, Vector<T>, tag::vector, tag::vector> + : boost::mpl::identity<Vector<typename traits::mult_type<T, T>::type > > {}; + } + + template <template<typename> class Vector, typename T> + typename result_of::cross<Vector<T>, Vector<T>, tag::vector, tag::vector>::type + inline cross_dispatch(const Vector<T>& v1, const Vector<T>& v2, tag::vector, tag::vector) + { + typedef typename traits::mult_type<T, T>::type value_type; + typedef typename traits::category<Vector<T> >::size_type size_type; + Vector<value_type> result; + + if (size(v1) != 3 || size(v1) != size(v2)) + throw std::runtime_error("cross: inkompatible sizes!"); + + for (size_type i = 0; i < size(v1); i++) { + size_type k = (i+1) % 3, l = (i+2) % 3; + result[i] = v1[k] * v2[l] - v1[l] * v2[k]; + } + return result; + } + + template <typename T1, typename T2> + typename boost::lazy_disable_if< typename boost::mpl::or_ + < + typename traits::is_mtl<T1>::type, + typename traits::is_mtl<T2>::type + >::type, + typename result_of::cross< T1, T2, + typename traits::category<T1>::tag, + typename traits::category<T2>::tag + > + >::type + inline cross(const T1& v1, const T2& v2) + { + typedef typename traits::category<T1>::tag tag1_; + typedef typename traits::category<T2>::tag tag2_; + return cross_dispatch(v1, v2, tag1_(), tag2_()); + } + + + namespace functors + { + /// cross(v1, v2) = v1 x v2 + template<typename T1, typename T2> + struct Cross : FunctorBase + { + typedef typename result_of::cross<T1, T2, typename traits::category<T1>::tag, + typename traits::category<T2>::tag>::type result_type; + int getDegree(int d0, int d1) const { return d0+d1; } + + static result_type eval(const T1 &v1, const T2& v2) { return cross(v1, v2); } + result_type operator()(const T1 &v1, const T2& v2) const { return eval(v1, v2); } + }; + } + + + // (v1 * v2') (only for WorldVector) + // ___________________________________________________________________________ + + namespace result_of + { + template <typename T1, typename T2, typename Tag1, typename Tag2> struct outer {}; + + template <typename T> + struct outer< WorldVector<T>, WorldVector<T>, tag::vector, tag::vector > + : boost::mpl::identity<WorldMatrix<T> > {}; + } + + template <typename T> + WorldMatrix<T> + inline outer_dispatch(const WorldVector<T>& v1, const WorldVector<T>& v2, boost::mpl::false_) + { + WorldMatrix<T> result; + result.vecProduct(v1, v2); + return result; + } + + template <typename T> + WorldMatrix<T> + inline outer(const WorldVector<T>& v1, const WorldVector<T>& v2) + { + return outer_dispatch(v1, v2, boost::mpl::false_()); + } + + + namespace functors + { + /// outer(v1, v2) = v1 * v2' + template<typename T1, typename T2> + struct Outer : FunctorBase + { + typedef typename result_of::outer<T1, T2, typename traits::category<T1>::tag, typename traits::category<T2>::tag>::type result_type; + typedef typename traits::category<T1>::value_type Value1; + typedef typename traits::category<T2>::value_type Value2; + int getDegree(int d0, int d1) const { return d0+d1; } + + static result_type eval(const WorldVector<Value1> &v1, const WorldVector<Value2>& v2) { return outer(v1, v2); } + result_type operator()(const WorldVector<Value1> &v1, const WorldVector<Value2>& v2) const { return eval(v1, v2); } + }; + } + +} // end namespace AMDiS + +#endif // AMDIS_OPERATIONS_PRODUCT_HPP diff --git a/AMDiS/src/parallel/BddcMlSolver.cc b/AMDiS/src/parallel/BddcMlSolver.cc index 9ccb18c07101613d7346e50f2fdbe521e15afcab..61fba305e1c7ebfd834521926682ffbb29284c33 100644 --- a/AMDiS/src/parallel/BddcMlSolver.cc +++ b/AMDiS/src/parallel/BddcMlSolver.cc @@ -29,8 +29,10 @@ extern "C" { #include "parallel/MpiHelper.h" namespace AMDiS { namespace Parallel { + + using namespace std; - int BddcMlSolver::solveLinearSystem(const Matrix<DOFMatrix*>& mat, + int BddcMlSolver::solveLinearSystem(const SolverMatrix<Matrix<DOFMatrix*> >& A, SystemVector &vec, SystemVector &rhsVec, bool createMatrixData,// ignored @@ -40,6 +42,8 @@ namespace AMDiS { namespace Parallel { TEST_EXIT(meshDistributor)("No meshDistributor provided!\n"); + const Matrix<DOFMatrix*>* mat = A.getOriginalMat(); + int nComponents = vec.getSize(); const FiniteElemSpace *feSpace = vec.getFeSpace(0); Mesh *mesh = feSpace->getMesh(); @@ -238,7 +242,7 @@ namespace AMDiS { namespace Parallel { for (int i = 0; i < nComponents; i++) for (int j = 0; j < nComponents; j++) if ((*mat)[i][j]) - addDofMatrix(mat[i][j], + addDofMatrix((*mat)[i][j], i_sparse, j_sparse, a_sparse, nComponents, i, j); diff --git a/AMDiS/src/parallel/BddcMlSolver.h b/AMDiS/src/parallel/BddcMlSolver.h index 4b2159b7caaff6489f6e8bd67e4702e27ce40c9a..be6f05941d1ba1a7cb25051b9c81043ea300e155 100644 --- a/AMDiS/src/parallel/BddcMlSolver.h +++ b/AMDiS/src/parallel/BddcMlSolver.h @@ -59,7 +59,7 @@ namespace AMDiS { namespace Parallel { bool createMatrixData, bool storeMatrixData); - void addDofMatrix(DOFMatrix* mat, + void addDofMatrix(const DOFMatrix* mat, std::vector<int>& i_sparse, std::vector<int>& j_sparse, std::vector<double>& a_sparse, diff --git a/AMDiS/src/parallel/ElementObjectDatabase.cc b/AMDiS/src/parallel/ElementObjectDatabase.cc index b1541055a2237eba1277bf031810d4128763fa9d..250f06062752f17703b8a8b9206f43005a670f2b 100644 --- a/AMDiS/src/parallel/ElementObjectDatabase.cc +++ b/AMDiS/src/parallel/ElementObjectDatabase.cc @@ -23,10 +23,26 @@ #include "parallel/ElementObjectDatabase.h" #include "parallel/MeshLevelData.h" +#include "Serializer.h" + using namespace std; namespace AMDiS { namespace Parallel { + void ElementObjectData::serialize(std::ostream &out) const + { + SerUtil::serialize(out, elIndex); + SerUtil::serialize(out, ithObject); + } + + /// Read this element object from disk. + void ElementObjectData::deserialize(std::istream &in) + { + SerUtil::deserialize(in, elIndex); + SerUtil::deserialize(in, ithObject); + } + + void ElementObjectDatabase::create(map<int, int>& rankMap, MeshLevelData& ld) { FUNCNAME("ElementObjectDatabase::create()"); diff --git a/AMDiS/src/parallel/ElementObjectDatabase.h b/AMDiS/src/parallel/ElementObjectDatabase.h index 41a9e69fa91c18f6fda3d6631cb4020e494fa99a..c9954b9472f2123d5a1c2b28b5561e9295e7e036 100644 --- a/AMDiS/src/parallel/ElementObjectDatabase.h +++ b/AMDiS/src/parallel/ElementObjectDatabase.h @@ -31,12 +31,13 @@ #include <boost/tuple/tuple_comparison.hpp> #include <boost/container/flat_map.hpp> -#include "AMDiS_fwd.h" +//#include "AMDiS_fwd.h" #include "Containers.h" #include "Global.h" #include "Boundary.h" -#include "Serializer.h" +//#include "Serializer.h" #include "FiniteElemSpace.h" +#include "Mesh.h" namespace AMDiS { namespace Parallel { @@ -66,18 +67,10 @@ namespace AMDiS { namespace Parallel { char ithObject; /// Write this element object to disk. - void serialize(std::ostream &out) const - { - SerUtil::serialize(out, elIndex); - SerUtil::serialize(out, ithObject); - } + void serialize(std::ostream &out) const; /// Read this element object from disk. - void deserialize(std::istream &in) - { - SerUtil::deserialize(in, elIndex); - SerUtil::deserialize(in, ithObject); - } + void deserialize(std::istream &in); /// Compare this element object with another one. bool operator==(ElementObjectData& cmp) const diff --git a/AMDiS/src/parallel/MeshDistributor.cc b/AMDiS/src/parallel/MeshDistributor.cc index e6d00f378d9673d6cbb68c9130e94854e3443724..d1a09e93fc443de4d01ee372542836eab6786019 100644 --- a/AMDiS/src/parallel/MeshDistributor.cc +++ b/AMDiS/src/parallel/MeshDistributor.cc @@ -63,6 +63,7 @@ #include "RefinementManager3d.h" #include "Debug.h" #include "Timer.h" +#include "io/MacroReader.h" namespace AMDiS { namespace Parallel { @@ -185,6 +186,12 @@ namespace AMDiS { namespace Parallel { partitioner = nullptr; } } + + void MeshDistributor::addInterchangeVector(SystemVector *vec) + { + for (int i = 0; i < vec->getSize(); i++) + interchangeVectors.push_back(vec->getDOFVector(i)); + } void MeshDistributor::initParallelization() @@ -204,6 +211,7 @@ namespace AMDiS { namespace Parallel { ("No FE space has been defined for the mesh distributor!\n"); TEST_EXIT(mesh)("No mesh has been defined for the mesh distributor!\n"); + // === Sort FE spaces with respect to the degree of the basis === // === functions. Use stuiped bubble sort for this. === @@ -276,6 +284,7 @@ namespace AMDiS { namespace Parallel { // Create interior boundary information. createInteriorBoundary(true); + // === Remove neighbourhood relations due to periodic bounday conditions. === for (deque<MacroElement*>::iterator it = mesh->firstMacroElement(); @@ -1112,7 +1121,7 @@ namespace AMDiS { namespace Parallel { int recvAllValues = 0; int sendValue = static_cast<int>(mesh->getChangeIndex() != lastMeshChangeIndex); mpiComm.Allreduce(&sendValue, &recvAllValues, 1, MPI_INT, MPI_SUM); - + if (recvAllValues == 0) return; @@ -1422,12 +1431,11 @@ namespace AMDiS { namespace Parallel { } #endif } - - - void MeshDistributor::repartitionMesh() + + bool MeshDistributor::isRepartitionNecessary() { - FUNCNAME("MeshDistributor::repartitionMesh()"); - + FUNCNAME("MeshDistributor::isRepartitionNecessary()"); + MPI::Intracomm &mpiComm = MPI::COMM_WORLD; // === First, check if the load is unbalanced on the ranks. === @@ -1440,6 +1448,7 @@ namespace AMDiS { namespace Parallel { Parameters::get("parallel->repartitioning->imbalance", imbalanceRepartitionBound); + //TODO:047 if (imbalanceFactor > imbalanceRepartitionBound) repartitioning = 1; @@ -1447,28 +1456,13 @@ namespace AMDiS { namespace Parallel { } else { mpiComm.Bcast(&repartitioning, 1, MPI_INT, 0); } - - if (repartitioning == 0) - return; - - Timer t; - -#if (DEBUG != 0) - ParallelDebug::testDoubleDofs(mesh); - int writePartMesh = 1; -#else - int writePartMesh = 0; -#endif - Parameters::get("parallel->debug->write part mesh", writePartMesh); - if (writePartMesh > 0 && repartitioningCounter == 0) - ParallelDebug::writePartitioningFile(debugOutputDir + "partitioning", - repartitioningCounter, - feSpaces[0]); - - repartitioningCounter++; - - // === Create new element weights. === - + return (repartitioning != 0); + } + + void MeshDistributor::calculateElemWeights() + { + FUNCNAME("MeshDistributor::calculateElemWeights()"); + elemWeights.clear(); { TraverseStack stack; @@ -1486,11 +1480,47 @@ namespace AMDiS { namespace Parallel { maxWeight = std::max(maxWeight, it->second); sumWeight += it->second; } - + + //TODO:047 +// elemWeights[0] = 10000.0; + mpi::globalMax(maxWeight); mpi::globalAdd(sumWeight); MSG("Partition weight: sum = %e max = %e\n", sumWeight, maxWeight); + } + + + void MeshDistributor::repartitionMesh() + { + FUNCNAME("MeshDistributor::repartitionMesh()"); + + MPI::Intracomm &mpiComm = MPI::COMM_WORLD; + + // === First, check if the load is unbalanced on the ranks. === + + if (!isRepartitionNecessary()) + return; + + Timer t; + +#if (DEBUG != 0) + ParallelDebug::testDoubleDofs(mesh); + int writePartMesh = 1; +#else + int writePartMesh = 0; +#endif + Parameters::get("parallel->debug->write part mesh", writePartMesh); + if (writePartMesh > 0 && repartitioningCounter == 0) + ParallelDebug::writePartitioningFile(debugOutputDir + "partitioning", + repartitioningCounter, + feSpaces[0]); + + repartitioningCounter++; + + // === Create new element weights. === + + calculateElemWeights(); // === Run mesh partitioner to calculate a new mesh partitioning. === @@ -1505,6 +1535,7 @@ namespace AMDiS { namespace Parallel { repartitioningFailed = repartitioningWaitAfterFail;; MSG("Mesh partitioner created empty partition!\n"); MSG("Mesh repartitioning needed %.5f seconds\n", t.elapsed()); +// sleep(1); return; } @@ -1519,16 +1550,61 @@ namespace AMDiS { namespace Parallel { mpiComm.Barrier(); repartitioningFailed = repartitioningWaitAfterFail;; MSG("Mesh repartitioning needed %.5f seconds\n", t.elapsed()); +// sleep(1); return; } } - - + TEST_EXIT_DBG(!(partitioner->getSendElements().size() == mesh->getMacroElements().size() && partitioner->getRecvElements().size() == 0)) ("Partition is empty, should not happen!\n"); + + int strategy = 0; + Parameters::get("parallel->repartitioning->strategy", strategy); + + switch (strategy) + { + case 0: + quickRepartition(); + break; + case 1: + fullRepartition(); + break; + default: + ERROR_EXIT("Unknown repartition strategy = %d!\n", strategy); + } + + partitioner->createPartitionMap(partitionMap); + + createInteriorBoundary(false); + updateLocalGlobalNumbering(); + + +#if (DEBUG != 0) + MSG("AMDiS runs in debug mode, so make some test ...\n"); + ParallelDebug::writePartitioningFile(debugOutputDir + "partitioning", + repartitioningCounter, + feSpaces[0]); + ParallelDebug::testAllElements(*this); + ParallelDebug::testDoubleDofs(mesh); + ParallelDebug::testInteriorBoundary(*this); + ParallelDebug::testPeriodicBoundary(*this); + + MSG("Debug mode tests finished!\n"); +#endif + + + mpiComm.Barrier(); + MSG("Mesh repartitioning needed %.5f seconds\n", t.elapsed()); + } + + void MeshDistributor::quickRepartition() + { + FUNCNAME("MeshDistributor::quickRepartition()"); + + MPI::Intracomm &mpiComm = MPI::COMM_WORLD; // === Create map that maps macro element indices to pointers to the === // === macro elements. === @@ -1578,6 +1654,7 @@ namespace AMDiS { namespace Parallel { // Push the macro element to all macro elements in mesh. mesh->getMacroElements().push_back(mel); + } @@ -1690,14 +1767,15 @@ namespace AMDiS { namespace Parallel { MeshManipulation meshManipulation(mesh); meshManipulation.deleteDoubleDofs(feSpaces, newMacroEl, elObjDb); - + mesh->dofCompress(); - partitioner->createPartitionMap(partitionMap); - - - createInteriorBoundary(false); - - updateLocalGlobalNumbering(); + +// partitioner->createPartitionMap(partitionMap); +// +// +// createInteriorBoundary(false); +// +// updateLocalGlobalNumbering(); // === After mesh adaption, set values of interchange vectors. === @@ -1716,28 +1794,280 @@ namespace AMDiS { namespace Parallel { i++; } } + + // In 3D we have to make some test, if the resulting mesh is valid. + fix3dMeshRefinement(); + } + + void MeshDistributor::fullRepartition() + { + FUNCNAME("MeshDistributor::fullRepartition()"); + + TEST_EXIT(interchangeVectors.size() > 0) + ("There are no interchange vectors defined!\n"); + + TEST_EXIT(mesh->getMacroFileInfo()) + ("Please turn on \"preserve macroFileInfo\". Should not happen.\n"); + + MPI::Intracomm &mpiComm = MPI::COMM_WORLD; + +#if DEBUG != 0 + int nOldLeaves = mesh->getNumberOfLeaves(); + int nAllOldLeaves = 0; + mpiComm.Allreduce(&nOldLeaves, &nAllOldLeaves, 1, MPI_INT, MPI_SUM); +#endif + + // === Create map that maps macro element indices to pointers to the === + // === macro elements. === + map<int, MacroElement*> elIndexMap; + for (vector<MacroElement*>::iterator it = allMacroElements.begin(); + it != allMacroElements.end(); ++it) + elIndexMap[(*it)->getIndex()] = *it; -#if (DEBUG != 0) - MSG("AMDiS runs in debug mode, so make some test ...\n"); - ParallelDebug::writePartitioningFile(debugOutputDir + "partitioning", - repartitioningCounter, - feSpaces[0]); - ParallelDebug::testAllElements(*this); - ParallelDebug::testDoubleDofs(mesh); - ParallelDebug::testInteriorBoundary(*this); - ParallelDebug::testPeriodicBoundary(*this); + // === Create set of all new macro elements this rank will receive from === + // === other ranks. === - MSG("Debug mode tests finished!\n"); -#endif + std::set<MacroElement*> newMacroEl; + for (map<int, vector<int> >::iterator it = partitioner->getRecvElements().begin(); + it != partitioner->getRecvElements().end(); ++it) { + for (vector<int>::iterator elIt = it->second.begin(); + elIt != it->second.end(); ++elIt) { + TEST_EXIT_DBG(elIndexMap.count(*elIt) == 1) + ("Could not find macro element %d\n", *elIt); - // In 3D we have to make some test, if the resulting mesh is valid. + newMacroEl.insert(elIndexMap[*elIt]); + } + } + + // === Store mesh structure code and value for domain macro elements. === + + std::set<MacroElement*> allMacroEl; + for (deque<MacroElement*>::iterator it = mesh->firstMacroElement(); + it != mesh->endOfMacroElements(); ++it) + allMacroEl.insert(*it); + + + map<int, MeshStructure> domainMacroCodes; + map<int, vector<vector<double> > > domainMacroValues; + + for (std::set<MacroElement*>::iterator it = allMacroEl.begin(); + it != allMacroEl.end(); ++it) { + + MeshStructure elCode; + vector<vector<double> > elValue; + + int macroId = (*it)->getElement()->getIndex(); + + elCode.init(mesh, macroId); + for (size_t i = 0; i < interchangeVectors.size(); i++) { + vector<double> valVec; + elCode.getMeshStructureValues(macroId, interchangeVectors[i], valVec); + elValue.push_back(valVec); + } + + domainMacroCodes[macroId] = elCode; + domainMacroValues[macroId] = elValue; + } + + // === Rebuild all macros in order to clean and renumber the dofs. === + + // Remove domain meshes, not optimized. + mesh->removeMacroElements(allMacroEl, feSpaces); + + TEST_EXIT_DBG(!mesh->getNumberOfMacros()) + ("Still %d macros remain?\n", mesh->getNumberOfMacros()); + + // Add all macros again. + for (vector<MacroElement*>::iterator it = allMacroElements.begin(); + it != allMacroElements.end(); ++it) { + + MacroElement *mel = *it; + int elIndex = mel->getIndex(); + + TEST_EXIT_DBG(macroElementNeighbours.count(elIndex) == 1) + ("Macro (%d) is not recorded for its neighbour information. Should not happen.\n", elIndex); + TEST_EXIT_DBG(static_cast<int>(macroElementNeighbours[elIndex].size()) == + mesh->getGeo(NEIGH)) + ("Should not happen!\n"); + + // Set initial neighbour information. + for (int i = 0; i < mesh->getGeo(NEIGH); i++) { + + int neighIndex = macroElementNeighbours[elIndex][i]; + + if (neighIndex == -1) + mel->setNeighbour(i, nullptr); + else { + TEST_EXIT_DBG(elIndexMap.count(neighIndex) == 1) + ("Should not happen!\n"); + + (*it)->setNeighbour(i, elIndexMap[neighIndex]); + } + } + + // Allocate dof pointers without initialization. Since neighbour info + // is set, neighbours share common dofs + mel->getElement()->createNewDofPtrs(); + + // Push the macro element to all macro elements in mesh. + mesh->getMacroElements().push_back(mel); + } + + // New dof indices for all macro elements. + io::MacroReader::restoreMacroDofs(*(mesh->getMacroFileInfo())); + + // === Update the current mesh partition. === + + for (map<int, vector<int> >::iterator it = partitioner->getSendElements().begin(); + it != partitioner->getSendElements().end(); ++it) { + for (vector<int>::iterator elIt = it->second.begin(); + elIt != it->second.end(); ++elIt) { + TEST_EXIT_DBG(elIndexMap.count(*elIt) == 1) + ("Could not find macro element %d\n", *elIt); + + allMacroEl.erase(elIndexMap[*elIt]); + } + } + + std::set<MacroElement*> localMacroEl = allMacroEl; + + for (std::set<MacroElement*>::iterator it = newMacroEl.begin(); + it != newMacroEl.end(); ++it) + allMacroEl.insert(*it); + + + // === Delete macros which don't belong to the domain in this === + // === round of partition. === + + std::set<MacroElement*> deleteMacroElements; + + for (vector<MacroElement*>::iterator it = allMacroElements.begin(); + it != allMacroElements.end(); ++it) + if (allMacroEl.find(*it) == allMacroEl.end()) + deleteMacroElements.insert(*it); + + // Note that also if there are no macros to be deleted, this function will + // update the number of elements, vertices, etc. of the mesh. + mesh->removeMacroElements(deleteMacroElements, feSpaces); + mesh->dofCompress(); fix3dMeshRefinement(); + + // === Adapte all domain macro elements. === + + // Send and receive mesh structure codes. + map<int, MeshCodeVec> sendCodes; + map<int, vector<vector<double> > > sendValues; + for (map<int, vector<int> >::iterator it = partitioner->getSendElements().begin(); + it != partitioner->getSendElements().end(); ++it) { + for (vector<int>::iterator elIt = it->second.begin(); + elIt != it->second.end(); ++elIt) { + + sendCodes[it->first].push_back(domainMacroCodes[*elIt]); + sendValues[it->first].reserve(sendValues[it->first].size() + domainMacroValues.size()); + sendValues[it->first].insert( + sendValues[it->first].end(), domainMacroValues[*elIt].begin(), domainMacroValues[*elIt].end()); + } + } + + StdMpi<MeshCodeVec> stdMpi(mpiComm, true); + stdMpi.send(sendCodes); + for (map<int, vector<int> >::iterator it = partitioner->getRecvElements().begin(); + it != partitioner->getRecvElements().end(); ++it) + stdMpi.recv(it->first); + stdMpi.startCommunication(); - mpiComm.Barrier(); - MSG("Mesh repartitioning needed %.5f seconds\n", t.elapsed()); + StdMpi<vector<vector<double> > > stdMpi2(mpiComm, true); + stdMpi2.send(sendValues); + for (map<int, vector<int> >::iterator it = partitioner->getRecvElements().begin(); + it != partitioner->getRecvElements().end(); ++it) + stdMpi2.recv(it->first); + stdMpi2.startCommunication(); + + + // === Adapte the new macro elements due to the received mesh === + // === structure codes, reserved elements due to the local + // === mesh structure codes. === + + for (map<int, vector<int> >::iterator it = partitioner->getRecvElements().begin(); + it != partitioner->getRecvElements().end(); ++it) { + MeshCodeVec &recvCodes = stdMpi.getRecvData()[it->first]; + int i = 0; + + TEST_EXIT_DBG(recvCodes.size() == it->second.size()) + ("Should not happen!\n"); + + for (vector<int>::iterator elIt = it->second.begin(); + elIt != it->second.end(); ++elIt) { + + TEST_EXIT_DBG(allMacroEl.find(elIndexMap[*elIt]) != allMacroEl.end()) + ("Received a macro element[%d] which doesn't belong to the domain. Something wrong.\n", *elIt); + +// MSG("%d-\n", *elIt); +// +// TEST_EXIT_DBG(elIndexMap[*elIt]->getElement()->isLeaf()) +// ("Macro %d already refined before applying mesh structure code?\n", *elIt); + + recvCodes[i++].fitMeshToStructure(mesh, refineManager, false, *elIt); + } + } + + + // === After mesh adaption, set values of interchange vectors. === + + for (std::set<MacroElement*>::iterator it = localMacroEl.begin(); + it != localMacroEl.end(); ++it) { + + int macroId = (*it)->getIndex(); + + TEST_EXIT_DBG(domainMacroCodes.count(macroId)) + ("Reserved macro element[%d] has no stored structure data. Something wrong.\n", macroId); + +// MSG("%d-\n", *macroId); +// +// TEST_EXIT_DBG(elIndexMap[macroId]->getElement()->isLeaf()) +// ("Macro %d already refined before applying mesh structure code?\n", macroId); + + domainMacroCodes[macroId].fitMeshToStructure(mesh, refineManager, false, macroId); + + for (size_t i = 0; i < interchangeVectors.size(); i++) { + domainMacroCodes[macroId].setMeshStructureValues(macroId, + interchangeVectors[i], + domainMacroValues[macroId][i]); +#if DEBUG != 0 + MeshStructure code; + code.init(mesh, macroId); + TEST_EXIT(code.getCode() == domainMacroCodes[macroId].getCode()) + ("Local mesh structure code not equal. Due to parallel adaption?\n"); +#endif + } + } + + for (map<int, vector<int> >::iterator it = partitioner->getRecvElements().begin(); + it != partitioner->getRecvElements().end(); ++it) { + MeshCodeVec &recvCodes = stdMpi.getRecvData()[it->first]; + vector<vector<double> > &recvValues = stdMpi2.getRecvData()[it->first]; + int i = 0, j = 0; + for (vector<int>::iterator elIt = it->second.begin(); + elIt != it->second.end(); ++elIt) { + for (unsigned int k = 0; k < interchangeVectors.size(); k++) + recvCodes[i].setMeshStructureValues(*elIt, + interchangeVectors[k], + recvValues[j++]); + i++; + } + } + +#if DEBUG != 0 + int nNewLeaves = mesh->getNumberOfLeaves(); + int nAllNewLeaves = 0; + mpiComm.Allreduce(&nNewLeaves, &nAllNewLeaves, 1, MPI_INT, MPI_SUM); + + TEST_EXIT(nAllOldLeaves == nAllNewLeaves) + ("Overall number of leaves change from %d to %d\n", nAllOldLeaves, nAllNewLeaves); +#endif } diff --git a/AMDiS/src/parallel/MeshDistributor.h b/AMDiS/src/parallel/MeshDistributor.h index 3f00a9ca2b5a6340652ac0c71c8493d1bf977f96..9fbf39fcd32f1cd0c7b5fe7ad6f96fd1edfda151 100644 --- a/AMDiS/src/parallel/MeshDistributor.h +++ b/AMDiS/src/parallel/MeshDistributor.h @@ -44,7 +44,9 @@ #include "FiniteElemSpace.h" #include "Serializer.h" #include "BoundaryManager.h" -#include "SystemVector.h" +#include <string> + +#include "operations/functors.hpp" namespace AMDiS { namespace Parallel { @@ -93,11 +95,7 @@ namespace AMDiS { namespace Parallel { } /// Adds all DOFVectors of a SystemVector to \ref interchangeVecs. - void addInterchangeVector(SystemVector *vec) - { - for (int i = 0; i < vec->getSize(); i++) - interchangeVectors.push_back(vec->getDOFVector(i)); - } + void addInterchangeVector(SystemVector *vec); /** \brief * This function checks if the mesh has changed on at least on rank. In @@ -119,6 +117,10 @@ namespace AMDiS { namespace Parallel { /// ranks. void repartitionMesh(); + void quickRepartition(); + + void fullRepartition(); + void getImbalanceFactor(double &imbalance, int &minDofs, int &maxDofs, @@ -191,19 +193,12 @@ namespace AMDiS { namespace Parallel { // Reads the object data from an input stream. void deserialize(std::istream &in); - - /** \brief - * This function must be used if the values of a DOFVector must be - * synchronised over all ranks. That means, that each rank sends the - * values of the DOFs, which are owned by the rank and lie on an interior - * boundary, to all other ranks also having these DOFs. - * - * This function must be used, for example, after the linear system is - * solved, or after the DOFVector is set by some user defined functions, - * e.g., initial solution functions. - */ - template<typename T> - void synchVector(DOFVector<T> &vec) + + /// Works quite similar to the function \ref synchVector, but instead the + /// values of subdomain vectors are combined along the boundaries, by a + /// binary functor. + template<typename T, typename Operator> + void synchVector(DOFVector<T> &vec, Operator op) { const FiniteElemSpace *fe = vec.getFeSpace(); @@ -211,7 +206,7 @@ namespace AMDiS { namespace Parallel { for (int level = nLevels - 1; level >= 0; level--) { StdMpi<std::vector<T> > stdMpi(levelData.getMpiComm(level)); - for (DofComm::Iterator it(dofComm[level].getSendDofs(), fe); + for (DofComm::Iterator it(dofComm[level].getRecvDofs(), fe); !it.end(); it.nextRank()) { std::vector<T> dofs; dofs.reserve(it.getDofs().size()); @@ -222,61 +217,47 @@ namespace AMDiS { namespace Parallel { stdMpi.send(it.getRank(), dofs); } - for (DofComm::Iterator it(dofComm[level].getRecvDofs()); + for (DofComm::Iterator it(dofComm[level].getSendDofs()); !it.end(); it.nextRank()) stdMpi.recv(it.getRank()); stdMpi.startCommunication(); - for (DofComm::Iterator it(dofComm[level].getRecvDofs(), fe); + for (DofComm::Iterator it(dofComm[level].getSendDofs(), fe); !it.end(); it.nextRank()) for (; !it.endDofIter(); it.nextDof()) - vec[it.getDofIndex()] = - stdMpi.getRecvData(it.getRank())[it.getDofCounter()]; + op(vec[it.getDofIndex()], + stdMpi.getRecvData(it.getRank())[it.getDofCounter()]); } + if (!boost::is_same<Operator, functors::assign<T> >::value) + synchVector(vec); + } + + /** \brief + * This function must be used if the values of a DOFVector must be + * synchronised over all ranks. That means, that each rank sends the + * values of the DOFs, which are owned by the rank and lie on an interior + * boundary, to all other ranks also having these DOFs. + * + * This function must be used, for example, after the linear system is + * solved, or after the DOFVector is set by some user defined functions, + * e.g., initial solution functions. + */ + template<typename T> + void synchVector(DOFVector<T> &vec) + { + synchVector(vec, functors::assign<T>()); } /// Works in the same way as the function above defined for DOFVectors. Due /// to performance, this function does not call \ref synchVector for each /// DOFVector, but instead sends all values of all DOFVectors all at once. void synchVector(SystemVector &vec); - - /// Works quite similar to the function \ref synchVector, but instead the - /// values of subdomain vectors are add along the boundaries. + template<typename T> void synchAddVector(DOFVector<T> &vec) { - const FiniteElemSpace *fe = vec.getFeSpace(); - - int nLevels = levelData.getNumberOfLevels(); - for (int level = nLevels - 1; level >= 0; level--) { - StdMpi<std::vector<T> > stdMpi(levelData.getMpiComm(level)); - - for (DofComm::Iterator it(dofComm[level].getRecvDofs(), fe); - !it.end(); it.nextRank()) { - std::vector<T> dofs; - dofs.reserve(it.getDofs().size()); - - for (; !it.endDofIter(); it.nextDof()) - dofs.push_back(vec[it.getDofIndex()]); - - stdMpi.send(it.getRank(), dofs); - } - - for (DofComm::Iterator it(dofComm[level].getSendDofs()); - !it.end(); it.nextRank()) - stdMpi.recv(it.getRank()); - - stdMpi.startCommunication(); - - for (DofComm::Iterator it(dofComm[level].getSendDofs(), fe); - !it.end(); it.nextRank()) - for (; !it.endDofIter(); it.nextDof()) - vec[it.getDofIndex()] += - stdMpi.getRecvData(it.getRank())[it.getDofCounter()]; - } - - synchVector(vec); + synchVector(vec, functors::add_assign<T>()); } /// In 3D, a subdomain may not be a valid AMDiS mesh if it contains two @@ -354,12 +335,20 @@ namespace AMDiS { namespace Parallel { } protected: + + /// Checks if repartition is needed. + bool isRepartitionNecessary(); + /// Creates an initial partitioning of the mesh. void createInitialPartitioning(); /// Set for each element on the partitioning level the number of /// leaf elements. void setInitialElementWeights(); + + /// Calculates \ref elemWeights with the gloabl max weight and + /// global sum of weight. + void calculateElemWeights(); /// void addProblemStat(ProblemStatSeq *probStat); diff --git a/AMDiS/src/parallel/MeshManipulation.cc b/AMDiS/src/parallel/MeshManipulation.cc index 6f1c7d8862c056e80355c10a83785c4bbad268e1..fce566c7e9f75813fd0e356d5361baff87bbebd5 100644 --- a/AMDiS/src/parallel/MeshManipulation.cc +++ b/AMDiS/src/parallel/MeshManipulation.cc @@ -20,11 +20,13 @@ #include "parallel/MeshManipulation.h" +#include "DOFVector.h" #include "Mesh.h" #include "MeshStructure.h" #include "BasisFunction.h" #include "Traverse.h" #include "Debug.h" +#include "FiniteElemSpace.h" using namespace std; @@ -329,6 +331,7 @@ namespace AMDiS { namespace Parallel { #endif + pcode = &code; pstack = &stack; rMode = boundEl.reverseMode; @@ -340,10 +343,6 @@ namespace AMDiS { namespace Parallel { if (boundEl.el->isLeaf()) { - // If element is leaf and code contains only one leaf element, we are finished. - if (code.getNumElements() == 1 && code.isLeafElement()) - return false; - // Create traverse stack and traverse the mesh to the element. TraverseStack stack; ElInfo *elInfo = @@ -357,6 +356,11 @@ namespace AMDiS { namespace Parallel { refineManager->setStack(&stack); refineManager->refineFunction(elInfo); meshChanged = true; + // If element is leaf and code contains only one leaf element, we are finished. + if (code.getNumElements() == 1 && code.isLeafElement()) + return true; + + } Element *child0 = boundEl.el->getFirstChild(); diff --git a/AMDiS/src/parallel/MeshPartitioner.cc b/AMDiS/src/parallel/MeshPartitioner.cc index 0c16092fe8cec0162b79b5a51f069c1b1f526267..f6dd5a0aa78e512f3d045665692bb540e0be2cbc 100644 --- a/AMDiS/src/parallel/MeshPartitioner.cc +++ b/AMDiS/src/parallel/MeshPartitioner.cc @@ -88,7 +88,6 @@ namespace AMDiS { namespace Parallel { else useInitialPartitioning = true; } - if (partitioningArhBased) { MSG("Read Arh partitioning files: %s\n", arhFile.c_str()); int nProc = io::Arh2Reader::readMetaFromArh(arhFile, mapElInRank, arhElCodeSize); @@ -97,8 +96,6 @@ namespace AMDiS { namespace Parallel { else useInitialPartitioning = true; } - - } diff --git a/AMDiS/src/parallel/MpiHelper.h b/AMDiS/src/parallel/MpiHelper.h index 4acf1472aa7b9678de21b31e068d134b65dfff8f..c6e92262bf06cf73ef4161c8018e15f3d7db3a8e 100644 --- a/AMDiS/src/parallel/MpiHelper.h +++ b/AMDiS/src/parallel/MpiHelper.h @@ -29,10 +29,15 @@ #include <time.h> #include <stdlib.h> #include "Global.h" +#include "traits/category.hpp" namespace AMDiS { namespace Parallel { - namespace mpi { + namespace mpi + { + + // TODO: replace globalAdd, global* by boost::mpi::all_reduce using functors + void globalAdd(MPI::Intracomm &mpiComm, double &value); inline void globalAdd(double &value) @@ -46,19 +51,25 @@ namespace AMDiS { namespace Parallel { { globalAdd(MPI::COMM_WORLD, value); } + + template<typename VectorType> + void globalAdd_dispatch(VectorType &value, tag::vector) + { + typedef typename traits::category<VectorType>::size_type size_type; + for (size_type i = 0; i < num_rows(value); i++) + globalAdd(value[i]); + } - template<typename T> - void globalAdd(T &value) + template<typename T, typename Tag> + void globalAdd_dispatch(T &value, Tag t) { WARNING("Unknown type for globalAdd. Can not sum up the values of all processors!\n"); } - - template<typename VectorType> - inline typename boost::enable_if< mtl::traits::is_vector<VectorType>, void > - globalAdd(VectorType &value) + + template<typename T> + void globalAdd(T &value) { - for (size_t i = 0; i < num_rows(value); i++) - globalAdd(value[i]); + globalAdd_dispatch(value, typename traits::category<T>::tag()); } void globalMin(double &value); diff --git a/AMDiS/src/parallel/PITL_Solver.h b/AMDiS/src/parallel/PITL_Solver.h index b4dab17c5448c7451abbd9ec72a1ae147c12d9a3..905f9acfb0c01fd06f6de175301b0e2a7332d1cc 100644 --- a/AMDiS/src/parallel/PITL_Solver.h +++ b/AMDiS/src/parallel/PITL_Solver.h @@ -27,7 +27,7 @@ #ifdef HAVE_PARALLEL_MTL4 #include "solver/ITL_Solver.h" -#include "parallel/PMTL4Solver.h" +#include "solver/MTL4Solver.h" #include "MTL4Types.h" namespace AMDiS @@ -37,10 +37,10 @@ namespace AMDiS using namespace MTLTypes; template< typename SolverType > - struct PITL_Solver : PMTL4Solver< PMTLMatrix, PMTLVector, ITL_Runner< SolverType, PMTLMatrix, PMTLVector > > + struct PITL_Solver : MTL4Solver< PMTLMatrix, PMTLVector, ITL_Runner< SolverType, PMTLMatrix, PMTLVector >, true > { PITL_Solver(std::string name) - : PMTL4Solver< PMTLMatrix, PMTLVector, ITL_Runner< SolverType, PMTLMatrix, PMTLVector > >(name) {} + : MTL4Solver< PMTLMatrix, PMTLVector, ITL_Runner< SolverType, PMTLMatrix, PMTLVector >, true >(name) {} }; typedef PITL_Solver< cg_solver_type > P_CGSolver; diff --git a/AMDiS/src/parallel/ParallelMapper.h b/AMDiS/src/parallel/ParallelMapper.h index 2c36e52218fe14cc97a2dcf9a8e1afb2820e5711..7e0f1f7cb1b762d8cc48ea4b429a0f0d0a9a277a 100644 --- a/AMDiS/src/parallel/ParallelMapper.h +++ b/AMDiS/src/parallel/ParallelMapper.h @@ -28,9 +28,11 @@ namespace AMDiS { namespace Parallel { - template< typename size_type > - class ParallelMapper_base : public MapperBase< size_type > + template< typename size_type_ > + class ParallelMapper_base : public MapperBase< ParallelMapper_base<size_type_> > { + typedef size_type_ size_type; + ParallelDofMapping& map; /// the current component row in the problem system diff --git a/AMDiS/src/parallel/PetscSolver.cc b/AMDiS/src/parallel/PetscSolver.cc index cb68372cd11b2bb165557e2975cdf4876dc562b7..f3e666df3443bb95849d1c85eef1b0e8dbf09540 100644 --- a/AMDiS/src/parallel/PetscSolver.cc +++ b/AMDiS/src/parallel/PetscSolver.cc @@ -119,10 +119,10 @@ namespace AMDiS { namespace Parallel { PetscInt nIter = 0; KSPGetIterationNumber(kspInterior, &nIter); - PetscReal residual_norm = 0.0; + PetscReal residual_norm = -1.0; KSPGetResidualNorm(kspInterior, &residual_norm); - if (residual_norm == 0.0) { + if (residual_norm <= 0.0) { Vec r; createVec(*interiorMap, r); KSPBuildResidual(kspInterior, PETSC_NULL, PETSC_NULL, &r); @@ -132,11 +132,6 @@ namespace AMDiS { namespace Parallel { setErrorCode(solverError); setIterations(nIter); setResidual(residual_norm); - -// if (solverError != 0) { -// AMDiS::finalize(); -// exit(-1); -// } } diff --git a/AMDiS/src/parallel/PetscSolverFetiDebug.cc b/AMDiS/src/parallel/PetscSolverFetiDebug.cc index 37aa00035a85d30013fe8e04801adf5dc0995c7f..e4808fd04e10cbcdce14ac37428aebfe4a124db6 100644 --- a/AMDiS/src/parallel/PetscSolverFetiDebug.cc +++ b/AMDiS/src/parallel/PetscSolverFetiDebug.cc @@ -23,6 +23,7 @@ #include "parallel/ParallelDofMapping.h" #include "parallel/PetscSolverFeti.h" #include "parallel/PetscSolverFetiDebug.h" +#include "io/VtkWriter.h" namespace AMDiS { namespace Parallel { diff --git a/AMDiS/src/parallel/PetscSolverNavierStokes.cc b/AMDiS/src/parallel/PetscSolverNavierStokes.cc index 660b1b61e26bb9ec2afbe6d56f43f73220c519c6..6509b5f9dfe0bb62bb73b851cf5c970dda24783c 100644 --- a/AMDiS/src/parallel/PetscSolverNavierStokes.cc +++ b/AMDiS/src/parallel/PetscSolverNavierStokes.cc @@ -61,12 +61,12 @@ namespace AMDiS { namespace Parallel { velocitySolutionMode(0), massSolutionMode(0), laplaceSolutionMode(0), - massMatrixSolver(nullptr), - laplaceMatrixSolver(nullptr), - nu(nullptr), - invTau(nullptr), - solution(nullptr), - phase(nullptr) + massMatrixSolver(NULL), + laplaceMatrixSolver(NULL), + nu(NULL), + invTau(NULL), + solution(NULL), + phase(NULL) { Parameters::get(initFileStr + "->navierstokes->pressure component", pressureComponent); @@ -198,7 +198,7 @@ namespace AMDiS { namespace Parallel { DOFMatrix massMatrix(pressureFeSpace, pressureFeSpace); { Operator massOp(pressureFeSpace, pressureFeSpace); - ZeroOrderTerm *massTerm = nullptr; + ZeroOrderTerm *massTerm = NULL; if ((!phase) || (*nu == 0.0)) massTerm = new Simple_ZOT; else @@ -216,7 +216,7 @@ namespace AMDiS { namespace Parallel { DOFMatrix laplaceMatrix(pressureFeSpace, pressureFeSpace); { Operator laplaceOp(pressureFeSpace, pressureFeSpace); - SecondOrderTerm *laplaceTerm = nullptr; + SecondOrderTerm *laplaceTerm = NULL; if ((!phase) || (*nu == 0.0)) laplaceTerm = new Simple_SOT; else @@ -246,9 +246,9 @@ namespace AMDiS { namespace Parallel { { Operator conDifOp(pressureFeSpace, pressureFeSpace); - ZeroOrderTerm *conDif0 = nullptr; - SecondOrderTerm *conDif1 = nullptr; - FirstOrderTerm *conDif2 = nullptr, *conDif3 = nullptr, *conDif4 = nullptr; + ZeroOrderTerm *conDif0 = NULL; + SecondOrderTerm *conDif1 = NULL; + FirstOrderTerm *conDif2 = NULL, *conDif3 = NULL, *conDif4 = NULL; if (!phase) { MSG("INIT WITHOUT PHASE!\n"); @@ -257,14 +257,14 @@ namespace AMDiS { namespace Parallel { conDifOp.addTerm(conDif0); conDif1 = new Simple_SOT(*nu); conDifOp.addTerm(conDif1); - conDif2 = new VecAtQP_FOT(&vx, nullptr, 0); + conDif2 = new VecAtQP_FOT(&vx, NULL, 0); conDifOp.addTerm(conDif2, GRD_PHI); if (dim >= 2) { - conDif3 = new VecAtQP_FOT(&vy, nullptr, 1); + conDif3 = new VecAtQP_FOT(&vy, NULL, 1); conDifOp.addTerm(conDif3, GRD_PHI); } if (dim == 3) { - conDif4 = new VecAtQP_FOT(&vz, nullptr, 2); + conDif4 = new VecAtQP_FOT(&vz, NULL, 2); conDifOp.addTerm(conDif4, GRD_PHI); } } else { // no phase given @@ -272,19 +272,19 @@ namespace AMDiS { namespace Parallel { vp.interpol(phase); if (*nu > 0.0) { - conDif0 = new VecAtQP_ZOT(&vp, nullptr, *invTau); + conDif0 = new VecAtQP_ZOT(&vp, NULL, *invTau); conDifOp.addTerm(conDif0); - conDif1 = new VecAtQP_SOT(&vp, nullptr, *nu); + conDif1 = new VecAtQP_SOT(&vp, NULL, *nu); conDifOp.addTerm(conDif1); - conDif2 = new Vec2AtQP_FOT(&vx, &vp, nullptr, 0); + conDif2 = new Vec2AtQP_FOT(&vx, &vp, NULL, 0); conDifOp.addTerm(conDif2, GRD_PHI); if (dim >= 2) { - conDif3 = new Vec2AtQP_FOT(&vy, &vp, nullptr, 1); + conDif3 = new Vec2AtQP_FOT(&vy, &vp, NULL, 1); conDifOp.addTerm(conDif3, GRD_PHI); } if (dim == 3) { - conDif4 = new Vec2AtQP_FOT(&vz, &vp, nullptr, 2); + conDif4 = new Vec2AtQP_FOT(&vz, &vp, NULL, 2); conDifOp.addTerm(conDif4, GRD_PHI); } } else { @@ -378,12 +378,12 @@ namespace AMDiS { namespace Parallel { delete massMatrixSolver; - massMatrixSolver = nullptr; + massMatrixSolver = NULL; delete laplaceMatrixSolver; - laplaceMatrixSolver = nullptr; + laplaceMatrixSolver = NULL; delete conDifMatrixSolver; - conDifMatrixSolver = nullptr; + conDifMatrixSolver = NULL; } } } diff --git a/AMDiS/src/parallel/StdMpi.cc b/AMDiS/src/parallel/StdMpi.cc index 5d2f7ae68d9f8f54585c494442b8e27071c8eec3..15ae83026f73d4f78d76477fb09c670697383125 100644 --- a/AMDiS/src/parallel/StdMpi.cc +++ b/AMDiS/src/parallel/StdMpi.cc @@ -37,6 +37,7 @@ namespace AMDiS { namespace Parallel { MPI_Datatype StdMpiHelper<map<BoundaryType, map<DegreeOfFreedom, DegreeOfFreedom> > >::mpiDataType = MPI_INT; MPI_Datatype StdMpiHelper<vector<std::pair<int, int> > >::mpiDataType = MPI_INT; MPI_Datatype StdMpiHelper<vector<WorldVector<double> > >::mpiDataType = MPI_DOUBLE; + MPI_Datatype StdMpiHelper<vector<WorldMatrix<double> > >::mpiDataType = MPI_DOUBLE; MPI_Datatype StdMpiHelper<map<WorldVector<double>, int> >::mpiDataType = MPI_DOUBLE; MPI_Datatype StdMpiHelper<map<int, WorldVector<double> > >::mpiDataType = MPI_DOUBLE; MPI_Datatype StdMpiHelper<vector<vector<WorldVector<double> > > >::mpiDataType = MPI_DOUBLE; @@ -467,6 +468,38 @@ namespace AMDiS { namespace Parallel { + // T = vector<WorldMatrix<double> > + + int StdMpiHelper<vector<WorldMatrix<double> > >::getBufferSize(vector<WorldMatrix<double> > &data) + { + return data.size() * sqr(Global::getGeo(WORLD)); + } + + void StdMpiHelper<vector<WorldMatrix<double> > >::createBuffer(vector<WorldMatrix<double> > &data, double *buf) + { + int dimOfWorld = Global::getGeo(WORLD); + int pos = 0; + for (unsigned int i = 0; i < data.size(); i++) + for (int j = 0; j < dimOfWorld; j++) + for (int k = 0; k < dimOfWorld; k++) + buf[pos++] = data[i][j][k]; + } + + void StdMpiHelper<vector<WorldMatrix<double> > >::makeFromBuffer(vector<WorldMatrix<double> > &data, double *buf, int bufSize) + { + int dimOfWorld = Global::getGeo(WORLD); + TEST_EXIT(bufSize % sqr(Global::getGeo(WORLD)) == 0)("This should not happen!\n"); + + int pos = 0; + data.resize(bufSize / sqr(dimOfWorld)); + for (unsigned int i = 0; i < data.size(); i++) + for (int j = 0; j < dimOfWorld; j++) + for (int k = 0; k < dimOfWorld; k++) + data[i][j][k] = buf[pos++]; + } + + + // T = map<WorldVector<double>, int> int StdMpiHelper<map<WorldVector<double>, int> >::getBufferSize(map<WorldVector<double>, int> &data) diff --git a/AMDiS/src/parallel/StdMpi.h b/AMDiS/src/parallel/StdMpi.h index ae1c51d6c68bd9041e595151e1dea3765618e9e4..9fb376566357260591ff35110dcc5215149edf99 100644 --- a/AMDiS/src/parallel/StdMpi.h +++ b/AMDiS/src/parallel/StdMpi.h @@ -225,6 +225,19 @@ namespace AMDiS { namespace Parallel { static void makeFromBuffer(std::vector<WorldVector<double> > &data, double *buf, int bufSize); }; + + template<> + struct StdMpiHelper<std::vector<WorldMatrix<double> > > { + static MPI_Datatype mpiDataType; + + typedef double cppDataType; + + static int getBufferSize(std::vector<WorldMatrix<double> > &data); + + static void createBuffer(std::vector<WorldMatrix<double> > &data, double *buf); + + static void makeFromBuffer(std::vector<WorldMatrix<double> > &data, double *buf, int bufSize); + }; // ParallelDebug::testGlobalIndexByCoords::CoordsIndexMap diff --git a/AMDiS/src/parallel/ZoltanPartitioner.h b/AMDiS/src/parallel/ZoltanPartitioner.h index 7040692197106a1c752891fdc60cfcdf1b549998..290d4fb2a6f9f94a5c82889f75dda01d73c94ec9 100644 --- a/AMDiS/src/parallel/ZoltanPartitioner.h +++ b/AMDiS/src/parallel/ZoltanPartitioner.h @@ -29,13 +29,12 @@ #include <map> #include <set> +#include <string> #include <zoltan_cpp.h> -#include <set> #include "AMDiS_fwd.h" #include "parallel/MeshPartitioner.h" -using namespace std; namespace AMDiS { namespace Parallel { @@ -65,8 +64,8 @@ namespace AMDiS { namespace Parallel { std::map<int, double> *elWeights; /// parmeter map to configure zoltan - std::map<string,string> paramMapInitial; - std::map<string,string> paramMap; + std::map<std::string,std::string> paramMapInitial; + std::map<std::string,std::string> paramMap; friend class ZoltanFunctions; }; diff --git a/AMDiS/src/reinit/BoundaryElementDist.cc b/AMDiS/src/reinit/BoundaryElementDist.cc index 19d2b128f9eb5afabf17003ecbace1fdf6a12ec9..d3f6c7b205853a7afca5f2f4d5ed344f1c18a7bc 100644 --- a/AMDiS/src/reinit/BoundaryElementDist.cc +++ b/AMDiS/src/reinit/BoundaryElementDist.cc @@ -21,6 +21,10 @@ #include "BoundaryElementDist.h" +namespace reinit { + +using namespace AMDiS; + void BoundaryElementDist::calcNormal( const FixVec<WorldVector<double>, DIMEN> &vecs, @@ -78,3 +82,5 @@ BoundaryElementDist::calcNormal_3d( normalVec[i] = 1/norm * normalVec[i]; } } + +} diff --git a/AMDiS/src/reinit/BoundaryElementDist.h b/AMDiS/src/reinit/BoundaryElementDist.h index 14adc18a415d82338022f22231920bbc7a3c9539..30d356bad88ac0b4bf8b0b59e9359cf0e7f474f2 100644 --- a/AMDiS/src/reinit/BoundaryElementDist.h +++ b/AMDiS/src/reinit/BoundaryElementDist.h @@ -28,7 +28,9 @@ #include "ElementLevelSet.h" -using namespace AMDiS; +namespace reinit { + + using namespace AMDiS; class BoundaryElementDist { public: @@ -97,4 +99,8 @@ public: ElementLevelSet *elLS; }; +} + +using reinit::BoundaryElementDist; + #endif // BOUNDARYELEMENTDIST_H diff --git a/AMDiS/src/reinit/BoundaryElementEdgeDist.cc b/AMDiS/src/reinit/BoundaryElementEdgeDist.cc index a37fd813c6cfdcd1b80271809b4f42a55fbb709f..01263420448a99c7fcb1db39438a78c947322402 100644 --- a/AMDiS/src/reinit/BoundaryElementEdgeDist.cc +++ b/AMDiS/src/reinit/BoundaryElementEdgeDist.cc @@ -21,6 +21,9 @@ #include "BoundaryElementEdgeDist.h" +namespace reinit { + +using namespace AMDiS; int BoundaryElementEdgeDist::calcDistOnBoundaryElement( ElInfo *elInfo, @@ -74,3 +77,5 @@ BoundaryElementEdgeDist::calcDistOnBoundaryElement( return elStatus; } + +} diff --git a/AMDiS/src/reinit/BoundaryElementEdgeDist.h b/AMDiS/src/reinit/BoundaryElementEdgeDist.h index 21dda47bd57eab3a0dd4ac509e4ae83c2749df88..d611721f51343e07eb9710bfb157f307c7de6989 100644 --- a/AMDiS/src/reinit/BoundaryElementEdgeDist.h +++ b/AMDiS/src/reinit/BoundaryElementEdgeDist.h @@ -31,7 +31,9 @@ #include "BoundaryElementDist.h" -using namespace AMDiS; +namespace reinit { + + using namespace AMDiS; class BoundaryElementEdgeDist : public BoundaryElementDist { @@ -53,4 +55,8 @@ public: FixVec<double, VERTEX> &dVec); }; +} + +using reinit::BoundaryElementEdgeDist; + #endif // BOUNDARYELEMENTEDGEDIST_H diff --git a/AMDiS/src/reinit/BoundaryElementLevelSetDist.cc b/AMDiS/src/reinit/BoundaryElementLevelSetDist.cc index a7ffca891af0d87c18c3dcd95ef629b8450219fd..abd5862480aa581e8d7f977b0f81302de075ce7c 100644 --- a/AMDiS/src/reinit/BoundaryElementLevelSetDist.cc +++ b/AMDiS/src/reinit/BoundaryElementLevelSetDist.cc @@ -21,6 +21,9 @@ #include "BoundaryElementLevelSetDist.h" +namespace reinit { + +using namespace AMDiS; int BoundaryElementLevelSetDist::calcDistOnBoundaryElement( ElInfo *elInfo, @@ -40,3 +43,5 @@ BoundaryElementLevelSetDist::calcDistOnBoundaryElement( return elStatus; } + +} diff --git a/AMDiS/src/reinit/BoundaryElementLevelSetDist.h b/AMDiS/src/reinit/BoundaryElementLevelSetDist.h index 20e0c10f302c395fc1a51188d787401fbfdca4f9..ad98d4da897c13c5dbf1785b39322567e05a2362 100644 --- a/AMDiS/src/reinit/BoundaryElementLevelSetDist.h +++ b/AMDiS/src/reinit/BoundaryElementLevelSetDist.h @@ -29,6 +29,8 @@ #include "ElementLevelSet.h" #include "BoundaryElementDist.h" +namespace reinit { + using namespace AMDiS; class BoundaryElementLevelSetDist : public BoundaryElementDist @@ -51,4 +53,8 @@ public: FixVec<double, VERTEX> &dVec); }; +} + +using reinit::BoundaryElementLevelSetDist; + #endif // BOUNDARYELEMENTLEVELSETDIST_H diff --git a/AMDiS/src/reinit/BoundaryElementNormalDist.cc b/AMDiS/src/reinit/BoundaryElementNormalDist.cc index 1c0b0e4f2ab42bb3d508905153d1c02095bf9f1b..542583c68e4acca0782750d09b907abe017bfdf2 100644 --- a/AMDiS/src/reinit/BoundaryElementNormalDist.cc +++ b/AMDiS/src/reinit/BoundaryElementNormalDist.cc @@ -21,6 +21,9 @@ #include "BoundaryElementNormalDist.h" +namespace reinit { + +using namespace AMDiS; int BoundaryElementNormalDist::calcDistOnBoundaryElement( ElInfo *elInfo, @@ -73,3 +76,5 @@ BoundaryElementNormalDist::calculateDistLevelSetWithNormal( return fabs(dist); } + +} diff --git a/AMDiS/src/reinit/BoundaryElementNormalDist.h b/AMDiS/src/reinit/BoundaryElementNormalDist.h index 4cca4f5c6349dbb3803f26b379d364391433938d..fe2c789995f1f13f4185b8eecf4d0908bdf66bc8 100644 --- a/AMDiS/src/reinit/BoundaryElementNormalDist.h +++ b/AMDiS/src/reinit/BoundaryElementNormalDist.h @@ -28,7 +28,9 @@ #include "ElementLevelSet.h" #include "BoundaryElementDist.h" -using namespace AMDiS; +namespace reinit { + + using namespace AMDiS; class BoundaryElementNormalDist : public BoundaryElementDist { @@ -60,4 +62,8 @@ public: WorldVector<double> &planeVec); }; +} + +using reinit::BoundaryElementNormalDist; + #endif // BOUNDARYELEMENTNORMALDIST_H diff --git a/AMDiS/src/reinit/BoundaryElementTopDist.cc b/AMDiS/src/reinit/BoundaryElementTopDist.cc index bc4034acb2f55f28f64f9ec3bb036feb4c37b20c..7d191c62e97baa1ee95f64c1d1779b25e01347aa 100644 --- a/AMDiS/src/reinit/BoundaryElementTopDist.cc +++ b/AMDiS/src/reinit/BoundaryElementTopDist.cc @@ -21,6 +21,8 @@ #include "BoundaryElementTopDist.h" +namespace reinit { +using namespace AMDiS; int BoundaryElementTopDist::calcDistOnBoundaryElement( ElInfo *elInfo, @@ -422,3 +424,5 @@ BoundaryElementTopDist::projected_on_a_straight_line( v_p[i] = sP1[i] + lambda * sP1_sP2[i]; } } + +} diff --git a/AMDiS/src/reinit/BoundaryElementTopDist.h b/AMDiS/src/reinit/BoundaryElementTopDist.h index 311d94a4922d8db3c05dc48476d4484b04347cd0..d15724967b0f1e0e6ddb3fbb353bb597208a1652 100644 --- a/AMDiS/src/reinit/BoundaryElementTopDist.h +++ b/AMDiS/src/reinit/BoundaryElementTopDist.h @@ -30,6 +30,8 @@ #include "BoundaryElementDist.h" #include "VelocityExt.h" +namespace reinit { + using namespace AMDiS; class BoundaryElementTopDist : public BoundaryElementDist @@ -92,5 +94,9 @@ public: */ VelocityExt *velExt; }; + +} + +using reinit::BoundaryElementTopDist; #endif // BOUNDARYELEMENTTOPDIST_H diff --git a/AMDiS/src/reinit/ElementLevelSet.cc b/AMDiS/src/reinit/ElementLevelSet.cc index db7173e721116eeea7964edcc42c5f978e19324b..af96399b5def4610411b9fe489076bd82abae836 100644 --- a/AMDiS/src/reinit/ElementLevelSet.cc +++ b/AMDiS/src/reinit/ElementLevelSet.cc @@ -22,6 +22,9 @@ #include "ElementLevelSet.h" #include "ElInfo.h" +namespace reinit { + +using namespace AMDiS; int ElementLevelSet::createElementLevelSet(const ElInfo *elInfo_, const bool doCalcIntersecPts_) @@ -442,3 +445,4 @@ ElementLevelSet::getElPos(const DimVec<double> barCoords) } } +} diff --git a/AMDiS/src/reinit/ElementLevelSet.h b/AMDiS/src/reinit/ElementLevelSet.h index 987d4f90288e9464645606157c06d665554dc6c9..62e69b3bac275f33fd440c67b762c799ac54aa46 100644 --- a/AMDiS/src/reinit/ElementLevelSet.h +++ b/AMDiS/src/reinit/ElementLevelSet.h @@ -29,7 +29,9 @@ #include "FixVec.h" #include "Initfile.h" -using namespace AMDiS; +namespace reinit { + + using namespace AMDiS; // =========================================================================== // ===== class ElementLevelSet =============================================== @@ -487,4 +489,8 @@ class ElementLevelSet static const int MAX_INTERSECTION_POINTS = 4; }; +} + +using reinit::ElementLevelSet; + #endif // AMDIS_ELEMENTLEVELSET_H diff --git a/AMDiS/src/reinit/ElementUpdate.h b/AMDiS/src/reinit/ElementUpdate.h index ad46b38bff123807807ed84394c575395954631b..29c6a749263c34329bac877c0fc995f0b8f645c7 100644 --- a/AMDiS/src/reinit/ElementUpdate.h +++ b/AMDiS/src/reinit/ElementUpdate.h @@ -27,6 +27,8 @@ #include "FixVec.h" #include "VelocityExt.h" +namespace reinit { + using namespace AMDiS; class ElementUpdate @@ -53,4 +55,8 @@ public: VelocityExt *velExt; }; +} + +using reinit::ElementUpdate; + #endif // ELEMENTUPDATE_H diff --git a/AMDiS/src/reinit/ElementUpdate_2d.cc b/AMDiS/src/reinit/ElementUpdate_2d.cc index 8c17c1da7892a659a98b33da07e9ef53db759f7e..2eba2a50a68fb3784fcb900b53712f3486f52399 100644 --- a/AMDiS/src/reinit/ElementUpdate_2d.cc +++ b/AMDiS/src/reinit/ElementUpdate_2d.cc @@ -21,6 +21,10 @@ #include "ElementUpdate_2d.h" +namespace reinit { + +using namespace AMDiS; + double ElementUpdate_2d::calcElementUpdate(const FixVec<WorldVector<double> *, VERTEX> &vert, FixVec<double, VERTEX> &uhVal) { @@ -67,3 +71,5 @@ double ElementUpdate_2d::calcElementUpdate(const FixVec<WorldVector<double> *, V return update; } + +} diff --git a/AMDiS/src/reinit/ElementUpdate_2d.h b/AMDiS/src/reinit/ElementUpdate_2d.h index 4d93e1de928d70fe972a28096f312103b2bbe475..29df3b1c9c4799894eeb74fc8d6c85a18dcbe919 100644 --- a/AMDiS/src/reinit/ElementUpdate_2d.h +++ b/AMDiS/src/reinit/ElementUpdate_2d.h @@ -28,6 +28,8 @@ #include "ElementUpdate.h" #include "VelocityExt.h" +namespace reinit { + using namespace AMDiS; class ElementUpdate_2d : public ElementUpdate @@ -48,5 +50,9 @@ private: WorldVector<double> xhminusYh, zhminusYh, xhminusZh; }; +} + +using reinit::ElementUpdate_2d; + #endif // ELEMENTUPDATE_2D_H diff --git a/AMDiS/src/reinit/ElementUpdate_3d.cc b/AMDiS/src/reinit/ElementUpdate_3d.cc index ff755ace602e22c76c30aef035ef12b60d41e53a..93cf44663dd3beb2172c3051bb1d51fda10fcb96 100644 --- a/AMDiS/src/reinit/ElementUpdate_3d.cc +++ b/AMDiS/src/reinit/ElementUpdate_3d.cc @@ -21,6 +21,10 @@ #include "ElementUpdate_3d.h" +namespace reinit { + +using namespace AMDiS; + double ElementUpdate_3d::calcElementUpdate( const FixVec<WorldVector<double> *, VERTEX> &vert_, @@ -628,3 +632,5 @@ ElementUpdate_3d::calcFaceUpdate(WorldVector<double> *A2d, return elUpdate2d->calcElementUpdate(vert2d, uhVal2d); } + +} diff --git a/AMDiS/src/reinit/ElementUpdate_3d.h b/AMDiS/src/reinit/ElementUpdate_3d.h index dd2a06c763ddb963d7e27dd48bba9854f7dc01b6..5365df71b9d9afd49a81a17f701af1dd478bc88c 100644 --- a/AMDiS/src/reinit/ElementUpdate_3d.h +++ b/AMDiS/src/reinit/ElementUpdate_3d.h @@ -29,6 +29,8 @@ #include "ElementUpdate_2d.h" #include "VelocityExt.h" +namespace reinit { + using namespace AMDiS; class ElementUpdate_3d : public ElementUpdate @@ -127,4 +129,8 @@ public: static const int EDGE_BC = 6; }; +} + +using reinit::ElementUpdate_3d; + #endif // ELEMENTUPDATE_3D_H diff --git a/AMDiS/src/reinit/HL_SignedDist.cc b/AMDiS/src/reinit/HL_SignedDist.cc index 52072084cea0ac43a92a89fcc247c54f2f8782af..70ed3c73996b70db3b96ff42132ad642796afa26 100644 --- a/AMDiS/src/reinit/HL_SignedDist.cc +++ b/AMDiS/src/reinit/HL_SignedDist.cc @@ -21,6 +21,10 @@ #include "HL_SignedDist.h" +namespace reinit { + +using namespace AMDiS; + const Flag HL_SignedDist::VEL_EXT = 0X01L; const Flag HL_SignedDist::VEL_EXT_FROM_VEL_FIELD = 0X02L; @@ -382,3 +386,5 @@ void HL_SignedDist::setSign() if ((*it_lS) < 0) (*it_sD) *= -1; } + +} diff --git a/AMDiS/src/reinit/HL_SignedDist.h b/AMDiS/src/reinit/HL_SignedDist.h index 09c0ce703be807cbe5daba30655e2dea3e29c19f..2c3b555b50aae518d95d7783a151f42e5d4d4e17 100644 --- a/AMDiS/src/reinit/HL_SignedDist.h +++ b/AMDiS/src/reinit/HL_SignedDist.h @@ -44,7 +44,7 @@ #include "VelocityExt.h" #include "VelocityExtFromVelocityField.h" -using namespace AMDiS; +namespace reinit { ////////////////////////////////////////////////////////////////////////////// // @@ -65,7 +65,7 @@ public: HL_SignedDist(const char *name_, int dim_, bool doVelocityExt = false, - Flag velExtType_ = VEL_EXT) + AMDiS::Flag velExtType_ = VEL_EXT) : name(name_), adaptInfo(nullptr), dim(dim_), @@ -85,7 +85,7 @@ public: TEST_EXIT(dim == 2 || dim == 3)("only works for dimension 2 and 3 !\n"); // ===== Read parameters from init file. ===== - Parameters::get(name + "->infinity value", inftyValue); + AMDiS::Parameters::get(name + "->infinity value", inftyValue); TEST_EXIT(inftyValue > 1000)("illegal infinity value !\n"); @@ -128,18 +128,18 @@ public: * If elFct != nullptr, this ElementFunction is used as level set function. * In this case: only calculation of distance function (positive sign) ! */ - void calcSignedDistFct(AdaptInfo *adaptInfo_, - const DOFVector<double> *lS_DOF_, - DOFVector<double> *sD_DOF_, - ElementFunction<double> *elFct = nullptr); + void calcSignedDistFct(AMDiS::AdaptInfo *adaptInfo_, + const AMDiS::DOFVector<double> *lS_DOF_, + AMDiS::DOFVector<double> *sD_DOF_, + AMDiS::ElementFunction<double> *elFct = nullptr); /** * Calculates the signed distance function for the interface given * implicitly by the zero level set of lS_DOF_. The result * is stored in lS_DOF_. */ - void calcSignedDistFct(AdaptInfo *adaptInfo_, - DOFVector<double> *lS_DOF_); + void calcSignedDistFct(AMDiS::AdaptInfo *adaptInfo_, + AMDiS::DOFVector<double> *lS_DOF_); /** * Calculates the extension of a velocity origVel_DOF_ from the interface @@ -153,13 +153,13 @@ public: * If elFct != nullptr, this ElementFunction is used as level set function. * In this case: only calculation of distance function (positive sign) ! */ - void calcVelocityExt(AdaptInfo *adaptInfo_, - DOFVector<double> *origVel_DOF_, - DOFVector<double> *vel_DOF_, - const DOFVector<double> *lS_DOF_, - DOFVector<double> *sD_DOF_, + void calcVelocityExt(AMDiS::AdaptInfo *adaptInfo_, + AMDiS::DOFVector<double> *origVel_DOF_, + AMDiS::DOFVector<double> *vel_DOF_, + const AMDiS::DOFVector<double> *lS_DOF_, + AMDiS::DOFVector<double> *sD_DOF_, bool calcSDFct, - ElementFunction<double> *elFct = nullptr); + AMDiS::ElementFunction<double> *elFct = nullptr); /** * Calculates the extension of a velocity vel_DOF_ from the interface @@ -173,11 +173,11 @@ public: * If elFct != nullptr, this ElementFunction is used as level set function. * In this case: only calculation of distance function (positive sign) ! */ - void calcVelocityExt(AdaptInfo *adaptInfo_, - DOFVector<double> *vel_DOF_, - DOFVector<double> *lS_DOF_, + void calcVelocityExt(AMDiS::AdaptInfo *adaptInfo_, + AMDiS::DOFVector<double> *vel_DOF_, + AMDiS::DOFVector<double> *lS_DOF_, bool calcSDFct, - ElementFunction<double> *elFct = nullptr); + AMDiS::ElementFunction<double> *elFct = nullptr); /** * Calculates the extension of the velocity vectors in origVel_DOF_ @@ -192,13 +192,13 @@ public: * If elFct != nullptr, this ElementFunction is used as level set function. * In this case: only calculation of distance function (positive sign) ! */ - void calcVelocityExt(AdaptInfo *adaptInfo_, - std::vector<DOFVector<double> *> origVel_DOF_, - std::vector<DOFVector<double> *> vel_DOF_, - const DOFVector<double> *lS_DOF_, - DOFVector<double> *sD_DOF_, + void calcVelocityExt(AMDiS::AdaptInfo *adaptInfo_, + std::vector<AMDiS::DOFVector<double> *> origVel_DOF_, + std::vector<AMDiS::DOFVector<double> *> vel_DOF_, + const AMDiS::DOFVector<double> *lS_DOF_, + AMDiS::DOFVector<double> *sD_DOF_, bool calcSDFct, - ElementFunction<double> *elFct = nullptr); + AMDiS::ElementFunction<double> *elFct = nullptr); /** * Calculates the extension of the velocity vectors in vel_DOF_ @@ -212,11 +212,11 @@ public: * If elFct != nullptr, this ElementFunction is used as level set function. * In this case: only calculation of distance function (positive sign) ! */ - void calcVelocityExt(AdaptInfo *adaptInfo_, - std::vector<DOFVector<double> *> vel_DOF_, - DOFVector<double> *lS_DOF_, + void calcVelocityExt(AMDiS::AdaptInfo *adaptInfo_, + std::vector<AMDiS::DOFVector<double> *> vel_DOF_, + AMDiS::DOFVector<double> *lS_DOF_, bool calcSDFct, - ElementFunction<double> *elFct = nullptr); + AMDiS::ElementFunction<double> *elFct = nullptr); /** * Calculates the normal velocity for the velocity field velField_ and its @@ -232,13 +232,13 @@ public: * In this case: only calculation of distance function (positive sign) ! */ void calcVelocityExtFromVelocityField( - AdaptInfo *adaptInfo_, - std::vector<DOFVector<double> *> &velField_, - DOFVector<double> *vel_DOF_, - const DOFVector<double> *lS_DOF_, - DOFVector<double> *sD_DOF_, + AMDiS::AdaptInfo *adaptInfo_, + std::vector<AMDiS::DOFVector<double> *> &velField_, + AMDiS::DOFVector<double> *vel_DOF_, + const AMDiS::DOFVector<double> *lS_DOF_, + AMDiS::DOFVector<double> *sD_DOF_, bool calcSDFct, - ElementFunction<double> *elFct = nullptr); + AMDiS::ElementFunction<double> *elFct = nullptr); /** * Calculates the normal velocity for the velocity field velField_ and its @@ -254,22 +254,22 @@ public: * In this case: only calculation of distance function (positive sign) ! */ void calcVelocityExtFromVelocityField( - AdaptInfo *adaptInfo_, - std::vector<DOFVector<double> *> &velField_, - DOFVector<double> *vel_DOF_, - DOFVector<double> *lS_DOF_, + AMDiS::AdaptInfo *adaptInfo_, + std::vector<AMDiS::DOFVector<double> *> &velField_, + AMDiS::DOFVector<double> *vel_DOF_, + AMDiS::DOFVector<double> *lS_DOF_, bool calcSDFct, - ElementFunction<double> *elFct = nullptr); + AMDiS::ElementFunction<double> *elFct = nullptr); /** * Print initial function: level set function defining the interface. */ void printLevelSetFct() { - FileWriter *fileWriter = new FileWriter( + AMDiS::FileWriter *fileWriter = new AMDiS::FileWriter( "SignedDist->level set fct output", feSpace->getMesh(), - const_cast<DOFVector<double> *>(lS_DOF)); + const_cast<AMDiS::DOFVector<double> *>(lS_DOF)); fileWriter->writeFiles(adaptInfo, false); delete fileWriter; @@ -280,7 +280,7 @@ public: */ void printSignedDistFct() { - FileWriter *fileWriter = new FileWriter( + AMDiS::FileWriter *fileWriter = new AMDiS::FileWriter( "SignedDist->result output", feSpace->getMesh(), sD_DOF); @@ -293,7 +293,7 @@ public: /** * Initialization. */ - virtual void initialize(ElementFunction<double> *elFct = nullptr); + virtual void initialize(AMDiS::ElementFunction<double> *elFct = nullptr); /** * Initializes the boundary: calculation of the distance of boundary @@ -321,7 +321,7 @@ public: */ void printBoundInitFct() { - FileWriter *fileWriter = new FileWriter("SignedDist->boundary initialization output", + AMDiS::FileWriter *fileWriter = new AMDiS::FileWriter("SignedDist->boundary initialization output", feSpace->getMesh(), sD_DOF); fileWriter->writeFiles(adaptInfo, false); @@ -345,7 +345,7 @@ public: /** * AdaptInfo. */ - AdaptInfo *adaptInfo; + AMDiS::AdaptInfo *adaptInfo; /** * Dimension. @@ -356,25 +356,25 @@ public: * Level set function giving implicitely (as zero level set) the * interface for which the signed distance function is calculated. */ - const DOFVector<double> *lS_DOF; + const AMDiS::DOFVector<double> *lS_DOF; /** * DOF vector for the calculated signed distance function. * Also used during calculation. */ - DOFVector<double> *sD_DOF; + AMDiS::DOFVector<double> *sD_DOF; /** * Marker for boundary vertices: * 0 - vertex is no boundary vertex * 1 - vertex is boundary vertex */ - DOFVector<double> *bound_DOF; + AMDiS::DOFVector<double> *bound_DOF; /** * Finite element space. */ - const FiniteElemSpace *feSpace; + const AMDiS::FiniteElemSpace *feSpace; /** * Initialization value "inifinity" for non-boundary vertices. @@ -403,7 +403,7 @@ public: * zero level set. * This representation is needed for the use of class ElementLevelSet. */ - ElementFunction<double> *phi; + AMDiS::ElementFunction<double> *phi; /** * Object needed to extrapolate velocity from the interface. @@ -415,7 +415,11 @@ public: * VEL_EXT - object of class VelocityExt * VEL_EXT_FROM_VEL_FIELD - object of class VelocityExtFromVelocityField */ - Flag velExtType; + AMDiS::Flag velExtType; }; +} // end namespace reinit + +using reinit::HL_SignedDist; + #endif // HL_SIGNEDDIST diff --git a/AMDiS/src/reinit/HL_SignedDistBornemann.h b/AMDiS/src/reinit/HL_SignedDistBornemann.h index 2b14a359b6fa76ce2e3398d5bd672e416611b80c..1c8e4aa261ee90315d64d54ee31f8d928e198eaf 100644 --- a/AMDiS/src/reinit/HL_SignedDistBornemann.h +++ b/AMDiS/src/reinit/HL_SignedDistBornemann.h @@ -39,6 +39,8 @@ #include "SMIAdapter.h" #include "smi.h" +namespace reinit { + using namespace AMDiS; typedef struct @@ -918,4 +920,8 @@ public: int print_in_list; }; +} // end namespace reinit + +using reinit::HL_SignedDistBornemann; + #endif // HL_SIGNEDDISTBORNEMANN diff --git a/AMDiS/src/reinit/HL_SignedDistTraverse.cc b/AMDiS/src/reinit/HL_SignedDistTraverse.cc index 0d34d22fdad81cefabc23d351f1db90632bcb7ff..88bd1c2c4e088ea4306648855fd9210babde0a99 100644 --- a/AMDiS/src/reinit/HL_SignedDistTraverse.cc +++ b/AMDiS/src/reinit/HL_SignedDistTraverse.cc @@ -22,6 +22,8 @@ #include "HL_SignedDistTraverse.h" #include "VelocityExtFromVelocityField.h" +namespace reinit { + void HL_SignedDistTraverse::initializeBoundary() { FUNCNAME("HL_SignedDistTraverse::initializeBoundary()"); @@ -263,3 +265,5 @@ bool HL_SignedDistTraverse::checkTol() return true; } + +} diff --git a/AMDiS/src/reinit/HL_SignedDistTraverse.h b/AMDiS/src/reinit/HL_SignedDistTraverse.h index ec348ef43534108d456e0c9f6da318b67b2d7997..5fbe713ec09ea002f47c8afea727bc4057af1f56 100644 --- a/AMDiS/src/reinit/HL_SignedDistTraverse.h +++ b/AMDiS/src/reinit/HL_SignedDistTraverse.h @@ -35,6 +35,8 @@ #include "HL_SignedDist.h" #include "VelocityExt.h" +namespace reinit { + using namespace AMDiS; class HL_SignedDistTraverse : public HL_SignedDist @@ -164,4 +166,8 @@ public: }; +} // end namespace reinit + +using reinit::HL_SignedDistTraverse; + #endif // HL_SIGNEDDISTTRAVERSE diff --git a/AMDiS/src/reinit/NormEps.cc b/AMDiS/src/reinit/NormEps.cc index a79b0001248e82c211b62725693d7785d17b0128..d2874f241d23cd7ae2c93bde4c633cae4f6f0a4a 100644 --- a/AMDiS/src/reinit/NormEps.cc +++ b/AMDiS/src/reinit/NormEps.cc @@ -21,6 +21,8 @@ #include "NormEps.h" +namespace reinit { + double NormEps::eps = 0.0; double @@ -48,3 +50,5 @@ NormEps::calcNormEps2(const WorldVector<double> &x) return(result); } + +} diff --git a/AMDiS/src/reinit/NormEps.h b/AMDiS/src/reinit/NormEps.h index 2952e5d453de364efd7a26b6299e5d5da8c36ace..796f298bb6fcd7364feebceaa3029c781fe232d2 100644 --- a/AMDiS/src/reinit/NormEps.h +++ b/AMDiS/src/reinit/NormEps.h @@ -28,6 +28,8 @@ #include "Global.h" #include "Initfile.h" +namespace reinit { + using namespace AMDiS; class NormEps @@ -56,4 +58,8 @@ protected: static double eps; }; +} + +using reinit::NormEps; + #endif // NORMEPS_H diff --git a/AMDiS/src/reinit/VelocityExt.cc b/AMDiS/src/reinit/VelocityExt.cc index 750619a9adb355aec369121989f17602e8725f42..53b0c335100d67478f67d9db26a12e63b490e6eb 100644 --- a/AMDiS/src/reinit/VelocityExt.cc +++ b/AMDiS/src/reinit/VelocityExt.cc @@ -21,6 +21,8 @@ #include "VelocityExt.h" +namespace reinit { + void VelocityExt::calcVelocityBoundary(DegreeOfFreedom *lokInd, const int indexV) { @@ -279,3 +281,5 @@ VelocityExt::swapVertices(int i1, int i2) permutation[i1]=permutation[i2]; permutation[i2]=temp; } + +} diff --git a/AMDiS/src/reinit/VelocityExt.h b/AMDiS/src/reinit/VelocityExt.h index 7b83115ceec4dbb3922b97c27cdc19be4653646d..0d6d50e358f1b005fa266299859d55cfca9d9b59 100644 --- a/AMDiS/src/reinit/VelocityExt.h +++ b/AMDiS/src/reinit/VelocityExt.h @@ -30,6 +30,8 @@ #include "io/FileWriter.h" #include "FixVec.h" +namespace reinit { + using namespace AMDiS; class VelocityExt @@ -261,4 +263,8 @@ public: DimVec<int> permutation; }; +} + +using reinit::VelocityExt; + #endif // VELOCITYEXT_H diff --git a/AMDiS/src/reinit/VelocityExtFromVelocityField.cc b/AMDiS/src/reinit/VelocityExtFromVelocityField.cc index 7a094bb366d91014d77d96cfef3d2843b87a1f4b..64ffc01ef316883ddda9f47beca5eb5a6c1e9127 100644 --- a/AMDiS/src/reinit/VelocityExtFromVelocityField.cc +++ b/AMDiS/src/reinit/VelocityExtFromVelocityField.cc @@ -21,6 +21,8 @@ #include "VelocityExtFromVelocityField.h" +namespace reinit { + // double NormEps::eps = 0.0; void @@ -59,3 +61,5 @@ VelocityExtFromVelocityField::calcVelocityBoundary(DegreeOfFreedom *locInd, } (*(velDOF[0]))[locInd[indexV]]=tempV; } + +} diff --git a/AMDiS/src/reinit/VelocityExtFromVelocityField.h b/AMDiS/src/reinit/VelocityExtFromVelocityField.h index 758003703752eb44274fa5917ef9f2fb3675b9d9..685cd9a49e16310afa453b69f76b82598da39bef 100644 --- a/AMDiS/src/reinit/VelocityExtFromVelocityField.h +++ b/AMDiS/src/reinit/VelocityExtFromVelocityField.h @@ -31,6 +31,8 @@ #include "NormEps.h" #include "VelocityExt.h" +namespace reinit { + using namespace AMDiS; ///////////////////////////////////////////////////////////////////////////// @@ -121,4 +123,8 @@ public: ElInfo *elInfo; }; +} + +using reinit::VelocityExtFromVelocityField; + #endif // VELOCITYEXTFROMVELOCITYFIELD_H diff --git a/AMDiS/src/solver/ITL_Runner.h b/AMDiS/src/solver/ITL_Runner.h index 2140e76e023ac465a3474a8c10cbdad4205618b7..aa1216da9542b93f32f5de56d2578d07f57452de 100644 --- a/AMDiS/src/solver/ITL_Runner.h +++ b/AMDiS/src/solver/ITL_Runner.h @@ -46,6 +46,12 @@ namespace AMDiS { }; + /** \ingroup Solver + * + * \brief + * Wrapper class for different MTL4 itl-solvers. These solvers + * are parametrized by Matrix- and VectorType. + **/ template< typename ITLSolver, typename MatrixType, typename VectorType > struct ITL_Runner : public MTL4Runner< MatrixType, VectorType > { @@ -99,6 +105,7 @@ namespace AMDiS { } int error = 0; if (oem.getInfo() == 0) { + // iteration that does not print residual per iteration itl::basic_iteration<value_type> iter(r, oem.getMaxIterations(), oem.getRelative(), oem.getTolerance()); @@ -106,7 +113,9 @@ namespace AMDiS { oem.setErrorCode(error); oem.setIterations(iter.iterations()); oem.setResidual(iter.resid()); + oem.setRelativeResidual(iter.relresid()); } else { + // print information about the solution process itl::cyclic_iteration<value_type> iter(r, oem.getMaxIterations(), oem.getRelative(), oem.getTolerance(), oem.getPrint_cycle()); @@ -115,6 +124,7 @@ namespace AMDiS { oem.setErrorCode(error); oem.setIterations(iter.iterations()); oem.setResidual(iter.resid()); + oem.setRelativeResidual(iter.relresid()); } return error; @@ -128,30 +138,32 @@ namespace AMDiS { TEST_EXIT(preconPair.l != nullptr)("there is no left preconditioner\n"); TEST_EXIT(preconPair.r != nullptr)("there is no right preconditioner\n"); -// typedef typename mtl::Collection<MatrixType>::value_type value_type; -// mtl::matrix::transposed_view<const MatrixType> B(A); -// VectorType r(B * x - b); -// int error = 0; -// if (oem.getInfo() == 0) { -// itl::basic_iteration<value_type> -// iter(r, oem.getMaxIterations(), oem.getRelative(), oem.getTolerance()); -// -// error = solver(B, x, b, *(preconPair.l), *(preconPair.r), iter); -// oem.setErrorCode(error); -// oem.setIterations(iter.iterations()); -// oem.setResidual(iter.resid()); -// } else { -// itl::cyclic_iteration<value_type> -// iter(r, oem.getMaxIterations(), oem.getRelative(), oem.getTolerance(), -// oem.getPrint_cycle()); -// -// error = solver(B, x, b, *(preconPair.l), *(preconPair.r), iter); -// oem.setErrorCode(error); -// oem.setIterations(iter.iterations()); -// oem.setResidual(iter.resid()); -// } -// -// return error; +#if 0 + typedef typename mtl::Collection<MatrixType>::value_type value_type; + mtl::matrix::transposed_view<const MatrixType> B(A); + VectorType r(B * x - b); + int error = 0; + if (oem.getInfo() == 0) { + itl::basic_iteration<value_type> + iter(r, oem.getMaxIterations(), oem.getRelative(), oem.getTolerance()); + + error = solver(B, x, b, *(preconPair.l), *(preconPair.r), iter); + oem.setErrorCode(error); + oem.setIterations(iter.iterations()); + oem.setResidual(iter.resid()); + } else { + itl::cyclic_iteration<value_type> + iter(r, oem.getMaxIterations(), oem.getRelative(), oem.getTolerance(), + oem.getPrint_cycle()); + + error = solver(B, x, b, *(preconPair.l), *(preconPair.r), iter); + oem.setErrorCode(error); + oem.setIterations(iter.iterations()); + oem.setResidual(iter.resid()); + } + + return error; +#endif return 1; } @@ -181,13 +193,14 @@ namespace AMDiS { LinearSolver& oem; ITLSolver solver; + /// create left/right preconditioners from parameters given in the init-file void setPrecon(PreconPair<MatrixType, VectorType>& pair) { FUNCNAME("ITL_Runner::setPrecon()"); - /// Creator for the left preconditioner + // Creator for the left preconditioner CreatorInterfaceName< ITL_BasePreconditioner<MatrixType, VectorType> >* leftCreator(nullptr); - /// Creator for the right preconditioner + // Creator for the right preconditioner CreatorInterfaceName< ITL_BasePreconditioner<MatrixType, VectorType> >* rightCreator(nullptr); std::string preconType("no"); diff --git a/AMDiS/src/solver/ITL_Solver.h b/AMDiS/src/solver/ITL_Solver.h index ef9a0dbaa8610d21c7b5b582fc93db698c554c2e..ffbf90da7b77dd61818925ee85e786da4d671f64 100644 --- a/AMDiS/src/solver/ITL_Solver.h +++ b/AMDiS/src/solver/ITL_Solver.h @@ -289,8 +289,10 @@ namespace AMDiS { default: case GRAM_SCHMIDT: return itl::gmres2(A, x, b, l, r, iter, restart); break; +#ifndef HAVE_PARALLEL_MTL4 case HOUSEHOLDER: return itl::gmres_householder(A, x, b, l, iter, restart); break; +#endif } } }; @@ -404,8 +406,10 @@ namespace AMDiS { default: case GRAM_SCHMIDT: return itl::fgmres(A, x, b, l, r, iter, restart); break; +#ifndef HAVE_PARALLEL_MTL4 case HOUSEHOLDER: return itl::fgmres_householder(A, x, b, r, iter, restart); break; +#endif } } }; diff --git a/AMDiS/src/solver/KrylovPreconditioner.h b/AMDiS/src/solver/KrylovPreconditioner.h index 79a96ea19f9857df3b7ef989b07f1ea30ad66449..8c573d2f87f13e90eb28de18935f2d2d7a7c704f 100644 --- a/AMDiS/src/solver/KrylovPreconditioner.h +++ b/AMDiS/src/solver/KrylovPreconditioner.h @@ -31,7 +31,6 @@ namespace AMDiS { - using namespace std; /** * \ingroup Solver @@ -70,21 +69,21 @@ namespace AMDiS { { #if defined HAVE_PARALLEL_PETSC - string backend("p_petsc"); + std::string backend("p_petsc"); #elif defined HAVE_PARALLEL_MTL - string backend("p_mtl"); + std::string backend("p_mtl"); #elif defined HAVE_PETSC || defined HAVE_SEQ_PETSC - string backend("petsc"); + std::string backend("petsc"); #else - string backend("mtl"); + std::string backend("mtl"); #endif // === read backend-name === - string initFileStr = name + "->solver"; + std::string initFileStr = name + "->solver"; Parameters::get(initFileStr + "->backend", backend); // === read solver-name === - string solverType("0"); + std::string solverType("0"); Parameters::get(initFileStr, solverType); if (backend != "0" && backend != "no" && backend != "") diff --git a/AMDiS/src/solver/LinearSolver.h b/AMDiS/src/solver/LinearSolver.h index a5c02743c1291b0cc3e692cb5ca92ef3e7577c3d..2e06cd2b8acbfba935d05608ccb1173f17c7fd3d 100644 --- a/AMDiS/src/solver/LinearSolver.h +++ b/AMDiS/src/solver/LinearSolver.h @@ -96,8 +96,7 @@ namespace AMDiS { print_cycle(100), iterations(-1), error(-1), - breakTolNotReached(true), - calculateResidual(false) + breakTolNotReached(true) { Parameters::get(name + "->tolerance", tolerance); Parameters::get(name + "->relative tolerance", relative); @@ -105,7 +104,6 @@ namespace AMDiS { Parameters::get(name + "->print cycle", print_cycle); Parameters::get(name + "->info", info); Parameters::get(name + "->break if tolerance not reached", breakTolNotReached); - Parameters::get(name + "->calculate residual", calculateResidual); } /// destructor @@ -124,21 +122,26 @@ namespace AMDiS { residual = -1.0; int error_code = solveLinearSystem(A, x, b, createMatrixData, storeMatrixData); + TEST_EXIT(error_code == 0) + ("Error [%d] in LinearSolver. residual = %e, rel_residual = %e\n", error_code, residual, rel_residual); + // calculate and print resiual if (info > 0) { -#ifndef HAVE_PARALLEL_DOMAIN_AMDIS - if (residual < 0 || calculateResidual) { - SystemVector r(b); - mv(*A.getOriginalMat(), x, r); - r -= b; - residual = norm(&r); + if (residual >= 0.0 && rel_residual >= 0.0) { + MSG("Residual norm: ||b-Ax|| = %e, ||b-Ax||/||b|| = %e\n", residual, rel_residual); + } else if (residual >= 0.0) { + MSG("Residual norm: ||b-Ax|| = %e\n", residual); } -#endif - - MSG("Residual norm: ||b-Ax|| = %e\n", residual); - TEST_EXIT((isNumber(residual) && residual <= tolerance) || !breakTolNotReached) + // test for absolute tolerance + TEST_EXIT((isNumber(residual) && (residual < 0.0 || tolerance < 1.e-30 || residual <= tolerance)) + || !breakTolNotReached) ("Tolerance tol = %e could not be reached!\n Set tolerance by '->solver->tolerance:' \n", tolerance); + + // test for relative tolerance + TEST_EXIT((isNumber(rel_residual) && (rel_residual < 0.0 || relative < 1.e-30 || rel_residual <= relative)) + || !breakTolNotReached) + ("Relative tolerance rtol = %e could not be reached!\n Set tolerance by '->solver->relative tolerance:' \n", relative); } return error_code; } @@ -315,11 +318,8 @@ namespace AMDiS { /// Error code in last solver (not set by UmfPack) int error; - // break if residual norm > prescribed tolerance + /// break if residual norm > prescribed tolerance bool breakTolNotReached; - - // calculate residual ||b-Ax|| directly - bool calculateResidual; }; diff --git a/AMDiS/src/solver/MTL4Solver.h b/AMDiS/src/solver/MTL4Solver.h index 598462aafb264d92fec491bcb21b2051a32c2e53..0917b36cd016d39bda407ae46676b4b515f31944 100644 --- a/AMDiS/src/solver/MTL4Solver.h +++ b/AMDiS/src/solver/MTL4Solver.h @@ -25,15 +25,10 @@ #define AMDIS_MTL4SOLVER_H #include "solver/LinearSolver.h" -#include "solver/MTL4SolverBase.h" -#include "Timer.h" -#include <iostream> -#include <boost/mpl/bool.hpp> -#include <boost/numeric/mtl/utility/is_distributed.hpp> - -#if defined(HAVE_PARALLEL_DOMAIN_AMDIS) && defined(HAVE_PARALLEL_MTL4) -#include <boost/numeric/mtl/par/distribution.hpp> +#ifdef HAVE_PARALLEL_DOMAIN_AMDIS +#include "parallel/ParallelSolver.h" #endif +#include "solver/MTL4SolverBase.h" namespace AMDiS { @@ -51,6 +46,30 @@ namespace AMDiS { }; }; +#ifndef HAVE_PARALLEL_DOMAIN_AMDIS + namespace Parallel { + typedef LinearSolver ParallelSolver; + } + typedef BlockMapper ParallelMapper; +#endif + + using Parallel::ParallelSolver; + + + /// Wrapper for template-argument dependent constructors + template <bool parallel = false> + struct MTL4SolverBase : LinearSolver + { + MTL4SolverBase(std::string name) : LinearSolver(name) {} + }; + +#ifdef HAVE_PARALLEL_DOMAIN_AMDIS + template <> + struct MTL4SolverBase<true> : ParallelSolver + { + MTL4SolverBase(std::string name) : ParallelSolver(name, false) {} + }; +#endif /** \ingroup Solver * @@ -61,14 +80,20 @@ namespace AMDiS { * solvers where MTL4 provides an interface, can be assigned * by different Runner objects. **/ - template< typename MatrixType, typename VectorType, typename Runner > - class MTL4Solver : public LinearSolver, protected MTL4SolverBase<MatrixType, VectorType, Runner> + template < typename MatrixType, typename VectorType, typename Runner, bool parallel = false/*mtl::traits::is_distributed<MatrixType>::value*/ > + class MTL4Solver : public MTL4SolverBase<parallel> { + private: + typedef MTL4SolverBase<parallel> super; + typedef MTL4Solver<MatrixType, VectorType, Runner> self; - public: - typedef MTL4Solver<MatrixType, VectorType, Runner> self; - typedef MTL4SolverBase<MatrixType, VectorType, Runner> details; + typedef typename boost::mpl::if_c<parallel, ParallelMapper, BlockMapper>::type Mapper; + Runner runner; // redirect the implementation to a runner + MatrixType matrix; + Mapper* mapper; + + public: /// Creator class used in the LinearSolverMap. class Creator : public LinearSolverCreator { @@ -84,32 +109,49 @@ namespace AMDiS { /// Constructor MTL4Solver(std::string n) - : LinearSolver(n), - details(this) + : super(n), + runner(this) {} /// Implementation of \ref LinearSolver::getRunner() - OEMRunner* getRunner() override + OEMRunner* getRunner() { - return details::getRunner(); + return &runner; } /// Implementation of \ref LinearSolver::getLeftPrecon() - OEMPreconditioner* getLeftPrecon() override + OEMPreconditioner* getLeftPrecon() { - return details::getLeftPrecon(); + return runner.getLeftPrecon(); } /// Implementation of \ref LinearSolver::getRightPrecon() - OEMPreconditioner* getRightPrecon() override + OEMPreconditioner* getRightPrecon() + { + return runner.getRightPrecon(); + } + + protected: + /// create a sequential BlockMapper + template<bool par> + void initMapper(const SolverMatrix<Matrix<DOFMatrix*> >& A) + { + mapper = new BlockMapper(A); + } + +#ifdef HAVE_PARALLEL_MTL4 + /// create a parallel mapper based on local-to-global mapping + template<> + void initMapper<true>(const SolverMatrix<Matrix<DOFMatrix*> >& A) { - return details::getRightPrecon(); + mapper = new ParallelMapper(*ParallelSolver::getDofMapping()); } +#endif - protected: + /// Implementation of \ref LinearSolver::solveLinearSystem() int solveLinearSystem(const SolverMatrix<Matrix<DOFMatrix*> >& A, SystemVector& x, @@ -117,8 +159,69 @@ namespace AMDiS { bool createMatrixData, bool storeMatrixData) override { - VectorialMapper mapper(A); - return details::solve(A, x, b, mapper, createMatrixData, storeMatrixData); +#ifdef HAVE_PARALLEL_DOMAIN_AMDIS + MPI::COMM_WORLD.Barrier(); +#endif + initMapper<parallel>(A); + + Timer t; + if (createMatrixData) { + initMatrix(matrix, A, *mapper); + runner.init(A, matrix); + } + + VectorType mtl_x; + initVector(mtl_x, x, *mapper); + + VectorType mtl_b; + initVector(mtl_b, b, *mapper); + + INFO(self::getInfo(), 8)("fill MTL4 matrix needed %.5f seconds\n", t.elapsed()); + + int error = runner.solve(matrix ,mtl_x, mtl_b); + VecMap< SystemVector, Mapper > xVecMap(x, *mapper); + mtl_x >> xVecMap; + + if (!storeMatrixData) + runner.exit(); + + delete mapper; + return error; + } + + // functions to initialize mtl-matrix and mtl-vector + // from AMDiS matrix / vectors using mappers + + /// initialize a MTL matrix + template< typename MatrixT, typename M > + void initMatrix(MatrixT& m, MapperBase<M>& mapper) + { + dispatch::initMatrix(m, mapper.self(), typename traits::distributed_tag<MatrixT>::type() ); + } + + /// initialize a MTL matrix and assign values from an AMDiS matrix + template< typename Matrix1, typename Matrix2, typename M > + void initMatrix(Matrix1& target, const Matrix2& source, MapperBase<M>& mapper) + { + dispatch::initMatrix(target, mapper.self(), typename traits::distributed_tag<Matrix1>::type() ); + MatMap< const Matrix2, M > matMap(source, mapper.self()); + target << matMap; + } + + /// initialize a MTL vector + template< typename VectorT > + void initVector(VectorT& v) + { + dispatch::initVector(v, matrix, typename traits::distributed_tag<VectorT>::type() ); + } + + /// initialize a MTL vector and assign values from an AMDiS vector + template< typename Vector1, typename Vector2, typename M > + void initVector(Vector1& target, const Vector2& source, MapperBase<M>& mapper) + { + initVector(target); + VecMap< const Vector2, M > srcVecMap(source, mapper.self()); + target << srcVecMap; } }; } diff --git a/AMDiS/src/solver/MTL4SolverBase.h b/AMDiS/src/solver/MTL4SolverBase.h index 94cac3a77a81446d375d3ea75b62742226d6a5cf..51616e584d8d48db042a38896b403826bc747259 100644 --- a/AMDiS/src/solver/MTL4SolverBase.h +++ b/AMDiS/src/solver/MTL4SolverBase.h @@ -35,24 +35,29 @@ #endif namespace AMDiS { - - template< typename MatrixType, typename VectorType, typename Runner > - class MTL4SolverBase + + namespace tag + { + struct distributed {}; + struct non_distributed {}; + } + + namespace traits + { + template< class T > + struct distributed_tag : boost::mpl::if_< + mtl::traits::is_distributed< T >, + tag::distributed, + tag::non_distributed + > {}; + } + + namespace dispatch { - public: - /// Constructor - MTL4SolverBase(LinearSolver* oem_) - : runner(oem_), - oem(*oem_)/*, - matrix(0,0)*/ - {} - - protected: /// init systemmatrix depending on Mapper parameters. - template< typename MatrixT, typename Mapper > - typename boost::disable_if< mtl::traits::is_distributed< MatrixT >, void >::type - initMatrix(MatrixT& m, Mapper& mapper) + template< typename MatrixT, typename M > + void initMatrix(MatrixT& m, MapperBase<M>& mapper, tag::non_distributed) { m.change_dim(mapper.getNumRows(), mapper.getNumCols()); set_to_zero(m); @@ -63,8 +68,7 @@ namespace AMDiS { /// init systemmatrix depending on Mapper parameters, /// specialized for distributed matrices template< typename MatrixT > - typename boost::enable_if< mtl::traits::is_distributed< MatrixT >, void >::type - initMatrix(MatrixT& m, ParallelMapper& mapper) + void initMatrix(MatrixT& m, ParallelMapper& mapper, tag::distributed) { mtl::par::block_distribution dist(mapper.getNumRows()); dist.setup_from_local_size(mapper.getMap().getLocalDofs()); @@ -76,9 +80,8 @@ namespace AMDiS { /// init MTL-vector depending on Mapper parameters. - template< typename VectorT > - typename boost::disable_if< mtl::traits::is_distributed< VectorT >, void >::type - initVector(VectorT& v) + template< typename VectorT, typename MatrixT > + void initVector(VectorT& v, const MatrixT& matrix, tag::non_distributed) { v.change_dim(num_rows(matrix)); set_to_zero(v); @@ -87,82 +90,14 @@ namespace AMDiS { /// init MTL-vector depending on Mapper parameters, /// specialized for distributed matrices - template< typename VectorT > - typename boost::enable_if< mtl::traits::is_distributed< VectorT >, void >::type - initVector(VectorT& v) + template< typename VectorT, typename MatrixT > + void initVector(VectorT& v, const MatrixT& matrix, tag::distributed) { v.init_distribution(row_distribution(matrix), num_rows(matrix)); set_to_zero(v); } - - /// Realization of solve(A, x, b) to solve the linear system \f$ Ax=b \f$. - /// 1. transfer matrix and vectors to MTL datatypes - /// 2. call Runner::solve(A, x, b) - /// 3. transfer solution back to AMDiS \ref SystemVector - template< typename MatrixT, typename VectorT, typename Mapper > - int solve(const MatrixT& A, VectorT& x, VectorT& b, Mapper& mapper, - bool createMatrixData, - bool storeMatrixData) - { FUNCNAME("MTL4SolverBase::solve()"); - - #ifdef HAVE_PARALLEL_DOMAIN_AMDIS - MPI::COMM_WORLD.Barrier(); - #endif - Timer t; - if (createMatrixData) { - initMatrix(matrix, mapper); - - MatMap< const MatrixT, Mapper > matMap(A, mapper); - matrix << matMap; - - runner.init(A, matrix); - } - - VectorType mtl_x; - initVector(mtl_x); - VecMap< VectorT, Mapper > xVecMap(x, mapper); - mtl_x << xVecMap; - - VectorType mtl_b; - initVector(mtl_b); - VecMap< VectorT, Mapper > bVecMap(b, mapper); - mtl_b << bVecMap; - - INFO(oem.getInfo(), 8)("fill MTL4 matrix needed %.5f seconds\n", t.elapsed()); - - int error = runner.solve(matrix ,mtl_x, mtl_b); - - mtl_x >> xVecMap; - - runner.exit(); - - return error; - } - - OEMRunner* getRunner() - { - return &runner; - } - - OEMPreconditioner* getLeftPrecon() - { - return runner.getLeftPrecon(); - } - - OEMPreconditioner* getRightPrecon() - { - return runner.getRightPrecon(); - } - - protected: - Runner runner; - LinearSolver& oem; - - private: - MatrixType matrix; - }; - + } // end namespace dispatch } // end namespace AMDiS #endif // AMDIS_MTL4SOLVER_BASE_H diff --git a/AMDiS/src/solver/Mapper.h b/AMDiS/src/solver/Mapper.h index b89b6298c1e2aa6219f38b1c13d6ac2bafdaabaf..22f1a7906d84589ddb78ab54e9928efa54a7a85b 100644 --- a/AMDiS/src/solver/Mapper.h +++ b/AMDiS/src/solver/Mapper.h @@ -39,29 +39,31 @@ namespace AMDiS { * in the block matrix. Then get with \ref row, respective \ref col, * the global matrix index to the assigned local index. **/ - template< typename size_type > + template< typename Derived > struct MapperBase { + typedef MTLTypes::size_type size_type; + /// set the current block row - inline virtual void setRow( unsigned int r) = 0; + inline void setRow( unsigned int r) { self().setRow(r); } /// set the current block columns - inline virtual void setCol( unsigned int c) = 0; + inline void setCol( unsigned int c) { self().setCol(c); } /// return global matrix row, for local row in the current matrix block - inline virtual size_type row(size_type r) const = 0; + inline size_type row(size_type r) const { return self().row(r); } /// return global matrix column, for local column in the current matrix block - inline virtual size_type col(size_type c) const = 0; + inline size_type col(size_type c) const { return self().col(c); } /// return overall number of rows - inline virtual size_type getNumRows() const = 0; + inline size_type getNumRows() const { return self().getNumRows(); } /// return overall number of columns - inline virtual size_type getNumCols() const = 0; + inline size_type getNumCols() const { return self().getNumCols(); } /// return number of components/blocks - inline virtual unsigned int getNumComponents() const = 0; + inline unsigned int getNumComponents() const { return self().getNumComponents(); } inline size_type row(unsigned int block_r, unsigned int block_c, size_type r) { @@ -76,14 +78,19 @@ namespace AMDiS { setCol(block_c); return col(c); } + + Derived& self() { return static_cast<Derived&>(*this); } + const Derived& self() const { return static_cast<const Derived&>(*this); } }; /// Mapper implementation for non-parallel block matrices - struct VectorialMapper : public MapperBase< unsigned int > + struct BlockMapper : public MapperBase< BlockMapper > { + typedef unsigned int size_type; + /// Constructor for block-matrices - VectorialMapper(const SolverMatrix<Matrix<DOFMatrix* > >& sm ) + BlockMapper(const SolverMatrix<Matrix<DOFMatrix* > >& sm ) : nComp(sm.getOriginalMat()->getSize()), rowOffset(0), colOffset(0), nrow(0), ncol(0), sizes(nComp) { @@ -97,7 +104,7 @@ namespace AMDiS { } /// Constructor for single matrix - VectorialMapper(const DOFMatrix* sm ) + BlockMapper(const DOFMatrix* sm ) : nComp(1), rowOffset(0), colOffset(0), nrow(0), ncol(0), @@ -109,7 +116,7 @@ namespace AMDiS { } /// Constructor for system with equal components - VectorialMapper(unsigned int nComp, int nDOFperComp) + BlockMapper(unsigned int nComp, size_type nDOFperComp) : nComp(nComp), rowOffset(0), colOffset(0), nrow(nComp*nDOFperComp), ncol(nrow), @@ -133,18 +140,18 @@ namespace AMDiS { colOffset = sum(c); } - inline unsigned int row(unsigned int r) const { return r + rowOffset; } - inline unsigned int col(unsigned int c) const { return c + colOffset; } + inline size_type row(size_type r) const { return r + rowOffset; } + inline size_type col(size_type c) const { return c + colOffset; } - inline unsigned int getNumRows() const { return nrow; } - inline unsigned int getNumCols() const { return ncol; } + inline size_type getNumRows() const { return nrow; } + inline size_type getNumCols() const { return ncol; } inline unsigned int getNumComponents() const { return nComp; } private: // methods ///compute the sum of sizes from [0, end) - inline unsigned int sum(unsigned int end) const + inline size_type sum(unsigned int end) const { unsigned int ret(0); for (unsigned int i(0); i < end; ++i) @@ -155,12 +162,12 @@ namespace AMDiS { private: // variables unsigned int nComp; - unsigned int rowOffset; - unsigned int colOffset; + size_type rowOffset; + size_type colOffset; unsigned int nrow; unsigned int ncol; - std::vector< unsigned int > sizes; + std::vector< size_type > sizes; }; } diff --git a/AMDiS/src/solver/MatrixStreams.h b/AMDiS/src/solver/MatrixStreams.h index 5d1f2378287284f556827e25be99be57425e08e2..2d43dc870ca722720a2614bf5797c400973d16b9 100644 --- a/AMDiS/src/solver/MatrixStreams.h +++ b/AMDiS/src/solver/MatrixStreams.h @@ -27,7 +27,8 @@ #include "DOFMatrix.h" #include "solver/SolverMatrix.h" #include "SystemVector.h" -#include "Collection.h" +#include "traits/inserter.h" +#include "traits/category.hpp" #ifdef HAVE_SEQ_PETSC #include "solver/PetscTypes.h" @@ -89,7 +90,7 @@ namespace AMDiS { // requires MatrixType to have an inserter template< typename MatrixType, typename Mapper > - void operator<<(MatrixType& matrix, MatMap<Matrix<MatrixType* >, Mapper >& Asolver) + void operator<<(MatrixType& matrix, MatMap<const Matrix<MatrixType* >, Mapper >& Asolver) { Matrix< MatrixType* >& A = *(Asolver.mat); int ns = A.getSize(); @@ -118,9 +119,9 @@ namespace AMDiS { } template< typename Vector, typename CurMap > - void operator<<(Vector& dest, VecMap<DOFVector<double >, CurMap >& rhs) + void operator<<(Vector& dest, VecMap<const DOFVector<double>, CurMap >& rhs) { - DOFVector<double>::Iterator it_x(&rhs.vec, USED_DOFS); + DOFConstIterator<double> it_x(&rhs.vec, USED_DOFS); int counter(0); typedef typename Collection< Vector >::Inserter Inserter ; @@ -134,7 +135,7 @@ namespace AMDiS { } template< typename Vector, typename CurMap > - inline void operator>>(const Vector& dest, VecMap<DOFVector< double >, CurMap >& rhs) + inline void operator>>(const Vector& dest, VecMap<DOFVector<double>, CurMap >& rhs) { DOFVector<double>::Iterator it_x(&rhs.vec, USED_DOFS); int counter(0); @@ -148,7 +149,7 @@ namespace AMDiS { } template< typename Vector, typename CurMap > - void operator<<(Vector& dest, VecMap<SystemVector, CurMap>& rhs) + void operator<<(Vector& dest, VecMap<const SystemVector, CurMap>& rhs) { int ns = rhs.vec.getSize(); // Number of systems. @@ -157,7 +158,7 @@ namespace AMDiS { Inserter swapInserter(dest); mtl::vector::mapped_inserter< Inserter, CurMap > ins(swapInserter, rhs.mapper); for (int i = 0; i < ns; i++) { - DOFVector<double>::Iterator it_source(rhs.vec.getDOFVector(i), USED_DOFS); + DOFConstIterator<double> it_source(rhs.vec.getDOFVector(i), USED_DOFS); int counter(0); rhs.mapper.setRow(i); for (it_source.reset(); !it_source.end(); ++it_source) { @@ -217,6 +218,9 @@ namespace AMDiS { /// create and fill \ref PetscMatrix inline void operator<<(PetscMatrix& mat, const SolverMatrix<Matrix<DOFMatrix*> >& Asolver) { + if (mat.assembled) + mat.destroy(); + const Matrix< DOFMatrix* >& A = *(Asolver.getOriginalMat()); if (mat.isNested) { @@ -242,79 +246,80 @@ namespace AMDiS { // create nested matrix from a vector of block matrices MatCreateNest(PETSC_COMM_SELF, A.getNumRows(), PETSC_NULL, A.getNumCols(), PETSC_NULL, &(mat.nestMat[0]), &mat.matrix); } else { - bool initMatrix = false; - unsigned nRows(0); - unsigned nEntries(0); - std::vector< int > nRowsBlock(A.getNumRows()); - for(int i(0); i < A.getNumRows(); ++i) { - int j(0); - for( ; j<A.getNumCols() && A[i][j] == NULL; ++j) ; - if( j == A.getNumCols() ) { - std::stringstream ss; ss << "ERROR: solver matrix has empty row " << i << "\n"; - throw std::runtime_error(ss.str()); - } - nRowsBlock[i]=num_rows(A[i][j]->getBaseMatrix()); - nRows+=nRowsBlock[i]; - } - std::vector<PetscInt> nnz(nRows); - //initialize the nnz (could be avoided, but gets complicated - for (int i(0); i < nRows; ++i) nnz[i] = 0; - - //build a list of pairs (col, value) for each row - std::vector< std::list< std::pair<int, double > > > rowData(nRows); - //use the standard mapper to build global structure - VectorialMapper mapper(Asolver); - PetscInt maxNnz(0); - for (int i(0); i < A.getNumRows(); ++i) { - mapper.setRow(i); - //compute the number of nonzeros per global row - for (int j(0); j < A.getNumCols(); ++j) { - if (A[i][j] != NULL) { - mapper.setCol(j); - const DOFMatrix::base_matrix_type& mtlMat(A[i][j]->getBaseMatrix()); - for (unsigned k(0); k < nRowsBlock[i]; ++k) { - unsigned curRow(mapper.row(k)); - nnz[curRow] += mtlMat.nnz_local(k); - maxNnz = std::max(maxNnz, nnz[curRow]); - unsigned curPos(mtlMat.ref_major()[k]); - for(unsigned l(0); l < mtlMat.nnz_local(k); ++l, ++curPos) { - rowData[curRow].push_back(std::make_pair(mapper.col(mtlMat.ref_minor()[curPos]), mtlMat.data[curPos])); - } - } - } - } - - } - if (mat.matrix == PETSC_NULL) { - MatCreateSeqAIJ(PETSC_COMM_SELF, nRows, nRows, 0, &(nnz[0]), &mat.matrix); - initMatrix = true; - } - //reduce mallocs.. - std::vector< PetscInt > colIndices(maxNnz); - std::vector< PetscScalar > values(maxNnz); - std::list< std::pair< int, double > >::iterator it; - unsigned j; - for (PetscInt i(0); i < nRows; ++i) { - j=0; it = rowData[i].begin(); - for (; it != rowData[i].end(); ++it, ++j) { - colIndices[j] = it->first; - values[j] = it->second; - } - MatSetValues(mat.matrix, 1, &i, nnz[i], &colIndices[0], &values[0], INSERT_VALUES); - } - if (initMatrix) { - MatAssemblyBegin(mat.matrix, MAT_FINAL_ASSEMBLY); - MatAssemblyEnd(mat.matrix, MAT_FINAL_ASSEMBLY); - } - } + bool initMatrix = false; + unsigned nRows(0); + unsigned nEntries(0); + std::vector< int > nRowsBlock(A.getNumRows()); + for(int i(0); i < A.getNumRows(); ++i) { + int j(0); + for( ; j<A.getNumCols() && A[i][j] == NULL; ++j) ; + if( j == A.getNumCols() ) { + std::stringstream ss; ss << "ERROR: solver matrix has empty row " << i << "\n"; + throw std::runtime_error(ss.str()); + } + nRowsBlock[i]=num_rows(A[i][j]->getBaseMatrix()); + nRows+=nRowsBlock[i]; + } + std::vector<PetscInt> nnz(nRows); + //initialize the nnz (could be avoided, but gets complicated + for (int i(0); i < nRows; ++i) nnz[i] = 0; + + //build a list of pairs (col, value) for each row + std::vector< std::list< std::pair<int, double > > > rowData(nRows); + //use the standard mapper to build global structure + BlockMapper mapper(Asolver); + PetscInt maxNnz(0); + for (int i(0); i < A.getNumRows(); ++i) { + mapper.setRow(i); + //compute the number of nonzeros per global row + for (int j(0); j < A.getNumCols(); ++j) { + if (A[i][j] != NULL) { + mapper.setCol(j); + const DOFMatrix::base_matrix_type& mtlMat(A[i][j]->getBaseMatrix()); + for (unsigned k(0); k < nRowsBlock[i]; ++k) { + unsigned curRow(mapper.row(k)); + nnz[curRow] += mtlMat.nnz_local(k); + maxNnz = std::max(maxNnz, nnz[curRow]); + unsigned curPos(mtlMat.ref_major()[k]); + for(unsigned l(0); l < mtlMat.nnz_local(k); ++l, ++curPos) { + rowData[curRow].push_back(std::make_pair(mapper.col(mtlMat.ref_minor()[curPos]), mtlMat.data[curPos])); + } + } + } + } + + } + if (mat.matrix == PETSC_NULL) { + MatCreateSeqAIJ(PETSC_COMM_SELF, nRows, nRows, 0, &(nnz[0]), &mat.matrix); + initMatrix = true; + } + //reduce mallocs.. + std::vector< PetscInt > colIndices(maxNnz); + std::vector< PetscScalar > values(maxNnz); + std::list< std::pair< int, double > >::iterator it; + unsigned j; + for (PetscInt i(0); i < nRows; ++i) { + j=0; it = rowData[i].begin(); + for (; it != rowData[i].end(); ++it, ++j) { + colIndices[j] = it->first; + values[j] = it->second; + } + MatSetValues(mat.matrix, 1, &i, nnz[i], &colIndices[0], &values[0], INSERT_VALUES); + } + if (initMatrix) { + MatAssemblyBegin(mat.matrix, MAT_FINAL_ASSEMBLY); + MatAssemblyEnd(mat.matrix, MAT_FINAL_ASSEMBLY); + } + } + mat.assembled = true; } /// fill PETSc vector from DOFVector - inline void operator<<(Vec& petscVec, /* const */DOFVector<double>& vec) + inline void operator<<(Vec& petscVec, const DOFVector<double>& vec) { // Traverse all used DOFs in the dof vector. - DOFVector<double>::Iterator dofIt(&vec, USED_DOFS); + DOFConstIterator<double> dofIt(&vec, USED_DOFS); PetscInt index = 0; for (dofIt.reset(); !dofIt.end(); ++dofIt, ++index) { double value = *dofIt; @@ -338,7 +343,7 @@ namespace AMDiS { /// fill PETSc vector from DOFVector - inline void operator<<(Vec& petscVec, /* const */SystemVector& vec) + inline void operator<<(Vec& petscVec, const SystemVector& vec) { #ifdef VecType // PETSc uses MACROS instead of typedefs in Versions 3.3x const VecType vecType; @@ -356,7 +361,7 @@ namespace AMDiS { } else { PetscInt index = 0; for (size_t i = 0; i < static_cast<size_t>(vec.getSize()); i++) { - DOFVector<double>::Iterator dofIt(vec.getDOFVector(i), USED_DOFS); + DOFConstIterator<double> dofIt(vec.getDOFVector(i), USED_DOFS); for (dofIt.reset(); !dofIt.end(); ++dofIt, ++index) { double value = *dofIt; VecSetValue(petscVec, index, value, ADD_VALUES); @@ -405,9 +410,11 @@ namespace AMDiS { /// create and fill \ref PetscVector - inline void operator<<(PetscVector& petscVec, /* const */SystemVector& rhs) + inline void operator<<(PetscVector& petscVec, const SystemVector& rhs) { size_t nComponents = rhs.getSize(); + if (petscVec.assembled) + petscVec.destroy(); // only create nested vector if requested, i.e. flag createNestedVector is set to true if (petscVec.isNested) { @@ -432,8 +439,10 @@ namespace AMDiS { VecCreateSeq(PETSC_COMM_SELF, n, &(petscVec.vector)); petscVec.vector << rhs; } + petscVec.assembled = true; } #endif + } #endif // AMDIS_MATRIXSTREAMS_H diff --git a/AMDiS/src/solver/PetscSolver.cc b/AMDiS/src/solver/PetscSolver.cc index 1b7b3b5f598a4a941a0d19db08020c8963cc08d0..256d885ebbcbe5be527696a97fee2dc9928ac5de 100644 --- a/AMDiS/src/solver/PetscSolver.cc +++ b/AMDiS/src/solver/PetscSolver.cc @@ -29,7 +29,9 @@ namespace AMDiS { PetscRunner::PetscRunner(LinearSolver* oem_) : oem(*oem_), - kspPrefix("") + kspPrefix(""), + zeroStartVector(false), + initialized(false) { PetscParameters params; bool matSolverPackage = false; @@ -85,6 +87,9 @@ namespace AMDiS { void PetscRunner::init(const BlockMatrix& A, const Mat& fullMatrix) { + if (initialized) + exit(); + createSubSolver(ksp, fullMatrix, kspPrefix); // set tolerance options from LinearSolver-parameters @@ -96,6 +101,8 @@ namespace AMDiS { KSPGetPC(ksp, &pc); PCSetFromOptions(pc); + + initialized = true; } @@ -108,9 +115,16 @@ namespace AMDiS { PetscInt nIter = 0; KSPGetIterationNumber(ksp, &nIter); - PetscReal residual_norm = 0.0; + PetscReal residual_norm = -1.0; KSPGetResidualNorm(ksp, &residual_norm); + if (residual_norm <= 0.0) { + Vec r; + VecDuplicate(b, &r); + KSPBuildResidual(ksp, PETSC_NULL, PETSC_NULL, &r); + VecNorm(r, NORM_2, &residual_norm); + } + oem.setErrorCode(solverError); oem.setIterations(nIter); oem.setResidual(residual_norm); diff --git a/AMDiS/src/solver/PetscSolver.h b/AMDiS/src/solver/PetscSolver.h index 322104a4d077a6f7d6ab709b8a83d95983cfd2cc..1ee3e5e0cfda218ba42f92834dc83ca82de5638e 100644 --- a/AMDiS/src/solver/PetscSolver.h +++ b/AMDiS/src/solver/PetscSolver.h @@ -99,6 +99,7 @@ namespace AMDiS { std::string kspPrefix; bool zeroStartVector; + bool initialized; }; @@ -188,7 +189,8 @@ namespace AMDiS { vecSol.destroy(); vecRhs.destroy(); - if (!storeMatrixData){ + + if (!storeMatrixData) { petscMat.destroy(); runner.exit(); } diff --git a/AMDiS/src/solver/PetscTypes.cc b/AMDiS/src/solver/PetscTypes.cc index 368c1e112bb271ffd4b8130dd0478945845de222..082188a45252959ebb4341ed39395f362ab60ecf 100644 --- a/AMDiS/src/solver/PetscTypes.cc +++ b/AMDiS/src/solver/PetscTypes.cc @@ -25,24 +25,30 @@ namespace AMDiS { void PetscMatrix::destroy() { - MatDestroy(&matrix); - matrix = PETSC_NULL; - for (size_t i = 0; i < nestMat.size(); i++) { - if (nestMat[i] != PETSC_NULL) - MatDestroy(&(nestMat[i])); - nestMat[i] = PETSC_NULL; + if (assembled) { + MatDestroy(&matrix); + matrix = PETSC_NULL; + for (size_t i = 0; i < nestMat.size(); i++) { + if (nestMat[i] != PETSC_NULL) + MatDestroy(&(nestMat[i])); + nestMat[i] = PETSC_NULL; + } } + assembled = false; } void PetscVector::destroy() { - VecDestroy(&vector); - vector = PETSC_NULL; - for (size_t i = 0; i < nestVec.size(); i++) { - VecDestroy(&(nestVec[i])); - nestVec[i] = PETSC_NULL; + if (assembled) { + VecDestroy(&vector); + vector = PETSC_NULL; + for (size_t i = 0; i < nestVec.size(); i++) { + VecDestroy(&(nestVec[i])); + nestVec[i] = PETSC_NULL; + } } + assembled = false; } diff --git a/AMDiS/src/solver/PetscTypes.h b/AMDiS/src/solver/PetscTypes.h index d5372eabc7cf7aa953ce1cd178383952ba5712c8..8802c4195d4a55fa592513cb4fe1954698f43f1d 100644 --- a/AMDiS/src/solver/PetscTypes.h +++ b/AMDiS/src/solver/PetscTypes.h @@ -34,29 +34,34 @@ namespace AMDiS { /// pair of nested matrices and blockmatrix struct PetscMatrix { - PetscMatrix() : - matrix(PETSC_NULL), - isNested(false) - {} + PetscMatrix() + : matrix(PETSC_NULL), + isNested(false), + assembled(false) {} std::vector<Mat> nestMat; Mat matrix; void destroy(); bool isNested; + bool assembled; }; /// pair of nested vectors and blockvector struct PetscVector { - PetscVector() : vector(PETSC_NULL), isNested(false) {} + PetscVector() + : vector(PETSC_NULL), + isNested(false), + assembled(false) {} std::vector<Vec> nestVec; Vec vector; void destroy(); bool isNested; + bool assembled; }; diff --git a/AMDiS/src/solver/SolverMatrix.cc b/AMDiS/src/solver/SolverMatrix.cc index fa9fda809afaa982c461e835a5db2b3bef0e4398..e157906b20cc4c728f4c84867b6bf9797c3baf54 100644 --- a/AMDiS/src/solver/SolverMatrix.cc +++ b/AMDiS/src/solver/SolverMatrix.cc @@ -27,10 +27,10 @@ namespace AMDiS { void SolverMatrix< Matrix<DOFMatrix*> >::buildMatrix() const { - VectorialMapper mapper(*this); + BlockMapper mapper(*this); matrix.change_dim(mapper.getNumRows(), mapper.getNumCols()); set_to_zero(matrix); - MatMap< const SolverMatrix< Matrix<DOFMatrix*> >, VectorialMapper > matMap(*this,mapper); + MatMap< const SolverMatrix< Matrix<DOFMatrix*> >, BlockMapper > matMap(*this,mapper); matrix << matMap; } diff --git a/AMDiS/src/solver/UmfPackSolver.h b/AMDiS/src/solver/UmfPackSolver.h index ba79804dd843bb620e4a235054d374ab75da0cce..9c6818455d558a22cced06b7986c5738522a5611 100644 --- a/AMDiS/src/solver/UmfPackSolver.h +++ b/AMDiS/src/solver/UmfPackSolver.h @@ -58,7 +58,11 @@ namespace AMDiS { solver = nullptr; } - solver = new mtl::matrix::umfpack::solver<MatrixType>(fullMatrix, symmetric_strategy, alloc_init); + try { + solver = new mtl::matrix::umfpack::solver<MatrixType>(fullMatrix, symmetric_strategy, alloc_init); + } catch (mtl::matrix::umfpack::error& e) { + ERROR_EXIT("UMFPACK_ERROR(factorize, %d) = %s\n", e.code, e.what()); + } } /// Implementation of \ref MTL4Runner::solve() @@ -67,7 +71,13 @@ namespace AMDiS { FUNCNAME("Umfpack_Runner::solve()"); TEST_EXIT(solver != nullptr)("The umfpack solver was not initialized\n"); - int code = (*solver)(x, b); + + int code = 0; + try { + code = (*solver)(x, b); + } catch (mtl::matrix::umfpack::error& e) { + ERROR_EXIT("UMFPACK_ERROR(solve, %d) = %s\n", e.code, e.what()); + } VectorType r(b); r -= A * x; diff --git a/AMDiS/src/time/RosenbrockAdaptInstationary.cc b/AMDiS/src/time/RosenbrockAdaptInstationary.cc index e7ac7bf5888f2438175d36698bff221343e71f0b..7825c6e884ae8f2d00d330dd0237323a79d0f29a 100644 --- a/AMDiS/src/time/RosenbrockAdaptInstationary.cc +++ b/AMDiS/src/time/RosenbrockAdaptInstationary.cc @@ -42,9 +42,11 @@ namespace AMDiS { minusTauGamma(-1.0), invTauGamma(1.0), minusInvTauGamma(-1.0), + maxRejectedSolverError(3), dbgTimestepStudy(false) { initConstructor(problemStat); + rosenbrockStat->setOldTime(adaptInfo->getStartTime()); } @@ -65,9 +67,11 @@ namespace AMDiS { minusTauGamma(-1.0), invTauGamma(1.0), minusInvTauGamma(-1.0), + maxRejectedSolverError(3), dbgTimestepStudy(false) { initConstructor(&problemStat); + rosenbrockStat->setOldTime(adaptInfo->getStartTime()); } @@ -95,6 +99,8 @@ namespace AMDiS { Parameters::get(name + "->rosenbrock->timestep study", dbgTimestepStudy); Parameters::get(name + "->rosenbrock->timestep study steps", dbgTimesteps); + + Parameters::get(name + "->rosenbrock->max rejected timesteps", maxRejectedSolverError); } @@ -121,9 +127,10 @@ namespace AMDiS { problemIteration->oneIteration(adaptInfo, ESTIMATE); bool rejected = false; - double timeTol = adaptInfo->getTimeTolerance(0); + double timeTol = adaptInfo->getGlobalTimeTolerance(); int studyTimestep = -1; + int rejectedByError = 0; do { if (dbgTimestepStudy) { @@ -153,17 +160,31 @@ namespace AMDiS { // do the iteration problemIteration->beginIteration(adaptInfo); - problemIteration->oneIteration(adaptInfo, FULL_ITERATION); + bool solverError = false; + try { + problemIteration->oneIteration(adaptInfo, FULL_ITERATION); + } catch(...) { + rejectedByError++; + solverError = true; + } problemIteration->endIteration(adaptInfo); - - double errorEst = adaptInfo->getTimeEstSum(0); + + TEST_EXIT(rejectedByError < maxRejectedSolverError) + ("Number of failed timestep iterations, because of solver errors, reached a limit!\n"); + if (!solverError) + rejectedByError = 0; + + double errorEst = getTimeEst(adaptInfo); + double newTimestep = 0.0; double order = rosenbrockMethod->getOrder(); - if (errorEst < timeTol || fixFirstTimesteps > 0 || firstTimestep) { + if (errorEst < timeTol || fixFirstTimesteps > 0 || firstTimestep || solverError) { double fac = 1.0; - if (fixFirstTimesteps > 0) { + if (solverError) { + newTimestep = adaptInfo->getTimestep() * 0.5; + } else if (fixFirstTimesteps > 0) { newTimestep = adaptInfo->getTimestep(); } else { if (firstTimestep || succRejection) { @@ -172,7 +193,7 @@ namespace AMDiS { fac = adaptInfo->getTimestep() / tauAcc * pow((timeTol * estAcc / (errorEst * errorEst)), 1.0 / order); } - fac = std::min(fac, 3.0); + fac = std::max(0.1, std::min(fac, 3.0)); newTimestep = fac * adaptInfo->getTimestep(); newTimestep *= 0.95; } @@ -203,8 +224,8 @@ namespace AMDiS { } - if (errorEst < timeTol || fixFirstTimesteps - || !(adaptInfo->getTimestep()>adaptInfo->getMinTimestep()) ) { + if (errorEst < timeTol || fixFirstTimesteps || solverError + || !(adaptInfo->getTimestep() > adaptInfo->getMinTimestep()) ) { INFO(info, 6)("Accepted timestep at time = %e with timestep = %e\n", adaptInfo->getTime() - adaptInfo->getTimestep(), adaptInfo->getTimestep()); @@ -216,14 +237,22 @@ namespace AMDiS { for (int i = 0; i < adaptInfo->getSize(); i++) INFO(info, 6)("time estimate for component %d = %e\n", i, adaptInfo->getTimeEstSum(i)); + + INFO(info, 6)("Combined time estimate = %e\n", + errorEst); if (errorEst > timeTol) - MSG("Accepted timestep but tolerance not reached \n"); + MSG("Accepted timestep but tolerance TOL = %e not reached \n", timeTol); + + } else { for (int i = 0; i < adaptInfo->getSize(); i++) INFO(info, 6)("time estimate for component %d = %e\n", i, adaptInfo->getTimeEstSum(i)); + + INFO(info, 6)("Combined time estimate = %e\n", + errorEst); INFO(info, 6)("Rejected timestep at time = %e with timestep = %e\n", adaptInfo->getTime() - adaptInfo->getTimestep(), @@ -243,10 +272,24 @@ namespace AMDiS { } while (rejected || (dbgTimestepStudy && (studyTimestep + 1 < static_cast<int>(dbgTimesteps.size())))); - rosenbrockStat->acceptTimestep(); + rosenbrockStat->acceptTimestep(adaptInfo); adaptInfo->setLastProcessedTimestep(adaptInfo->getTimestep()); adaptInfo->incTimestepNumber(); } + + + double RosenbrockAdaptInstationary::getTimeEst(AdaptInfo* adaptInfo) + { + double errorEst = 0.0; + for (int i = 0; i < adaptInfo->getSize(); i++) { + double weight = adaptInfo->getTimeTolerance(i) + rosenbrockStat->getSolution(i)->L2Norm() * adaptInfo->getTimeRelativeTolerance(i); + errorEst += sqr(adaptInfo->getTimeEstCombined(i)) / sqr(weight); + } + + errorEst = sqrt(errorEst / adaptInfo->getSize()); + adaptInfo->setTimeEst(errorEst); + return errorEst; + } } diff --git a/AMDiS/src/time/RosenbrockAdaptInstationary.h b/AMDiS/src/time/RosenbrockAdaptInstationary.h index 2db14b4d5998dc7568e9a2f4f210cba13604f333..6266f3682dcdef38a81daef14008e9791b6d1dec 100644 --- a/AMDiS/src/time/RosenbrockAdaptInstationary.h +++ b/AMDiS/src/time/RosenbrockAdaptInstationary.h @@ -62,6 +62,8 @@ namespace AMDiS { /// Runs the Rosenbrock loop until one timestep is accepted. void oneTimestep(); + + virtual double getTimeEst(AdaptInfo* adaptInfo); /** \brief * This funciton is used only to avoid double code in both constructors. If the @@ -89,6 +91,9 @@ namespace AMDiS { /// If true, more than one of the last timesteps were rejected. bool succRejection; + + /// Maximal nr. of rejected timesteps due to a solver error + int maxRejectedSolverError; /// If greater than 0, than for the first given number of timesteps the timestep /// will be not changed and is set to the very first one. diff --git a/AMDiS/src/time/RosenbrockStationary.cc b/AMDiS/src/time/RosenbrockStationary.cc index b94e48d772fe4e374aae30f68538bd3070663891..f21d9c93e2c5b8df3e6c9cf629d07c8ef7bb7e36 100644 --- a/AMDiS/src/time/RosenbrockStationary.cc +++ b/AMDiS/src/time/RosenbrockStationary.cc @@ -32,12 +32,6 @@ namespace AMDiS { - void RosenbrockStationary::acceptTimestep() - { - *solution = *newUn; - *unVec = *newUn; - } - void RosenbrockStationary::init() { @@ -58,11 +52,40 @@ namespace AMDiS { } } + Flag RosenbrockStationary::oneIteration(AdaptInfo *adaptInfo, Flag toDo) + { + Flag flag = 0, markFlag = 0; + + + if (toDo.isSet(MARK)) + markFlag = problem->markElements(adaptInfo); + else + markFlag = 3; - void RosenbrockStationary::buildAfterCoarsen(AdaptInfo *adaptInfo, Flag flag, + // refine + if (toDo.isSet(ADAPT) && markFlag.isSet(MESH_REFINED)) + flag = problem->refineMesh(adaptInfo); + + // coarsen + if (toDo.isSet(ADAPT) && markFlag.isSet(MESH_COARSENED)) + flag |= problem->coarsenMesh(adaptInfo); + + if (toDo.isSet(BUILD) || toDo.isSet(SOLVE)) { + flag = stageIteration(adaptInfo, toDo, true, true); + estimateTimeError(adaptInfo); + } + + if (toDo.isSet(ESTIMATE)) + problem->estimate(adaptInfo); + + return flag; + } + + + Flag RosenbrockStationary::stageIteration(AdaptInfo *adaptInfo, Flag flag, bool asmMatrix, bool asmVector) { - FUNCNAME("RosenbrockStationary::buildAfterCoarsen()"); + FUNCNAME("RosenbrockStationary::stageIteration()"); TEST_EXIT(tauPtr)("No tau pointer defined in stationary problem!\n"); @@ -73,11 +96,11 @@ namespace AMDiS { *newUn = *unVec; *lowSol = *unVec; -for (int i = 0; i < nComponents; i++) { - std::cout <<"RRDDRX "<< i<<" "<< lowSol->getDOFVector(i)->Int() <<" "<< - newUn->getDOFVector(i)->Int()<<" "<< *tauPtr<<"\n"; - } - for (int i = 0; i < rm->getStages(); i++) { + for (int i = 0; i < rm->getStages(); i++) { + stageTime = oldTime + rm->getAlphaI(i) * (*tauPtr); + tauGammaI = rm->getGammaI(i) * (*tauPtr); + + // stage-solution: u_s(i) = u_old + sum_{j=0}^{i-1} a_ij*U_j *stageSolution = *unVec; for (int j = 0; j < i; j++) { *tmp = *(stageSolutions[j]); @@ -85,11 +108,23 @@ for (int i = 0; i < nComponents; i++) { *stageSolution += *tmp; } + // Dirichlet-BC implemented as additional algebraic equation u = g(x,t) on boundary + // => U_i = -u_s(i) + g(x,t_s(i)) + tau*gamma_i* d_t(g)(t_old) on boundary + // where u_s(i) = ith stage-solution, t_s(i) = ith stage-time for (unsigned int j = 0; j < boundaries.size(); j++) { boundaries[j].vec->interpol(boundaries[j].fct); - *(boundaries[j].vec) -= *(stageSolution->getDOFVector(boundaries[j].row)); + *(boundaries[j].vec) -= *(stageSolution->getDOFVector(boundaries[j].col)); + + if (boundaries[j].fctDt != NULL) { + // time derivative of dirichlet bc is given + DOFVector<double> tmpDt(getFeSpace(boundaries[j].col), "tmp"); + tmpDt.interpol(boundaries[j].fctDt); + tmpDt *= tauGammaI; + *(boundaries[j].vec) += tmpDt; + } } + // timeRhs: sum_{j=0}^{i-1} c_ij / tau * U_j timeRhsVec->set(0.0); for (int j = 0; j < i; j++) { *tmp = *(stageSolutions[j]); @@ -97,7 +132,8 @@ for (int i = 0; i < nComponents; i++) { *timeRhsVec += *tmp; } - ProblemStat::buildAfterCoarsen(adaptInfo, flag, (i == 0), asmVector); + // assemble and solve stage equation + ProblemStat::buildAfterCoarsen(adaptInfo, flag, (i == 0), true); #if defined HAVE_PARALLEL_PETSC // TODO: Problems with reuse of Matrix with parallel PETSC-Solvers // Thus, Rosenbrock not efficient but working (Rainer) @@ -105,13 +141,11 @@ for (int i = 0; i < nComponents; i++) { #else ProblemStat::solve(adaptInfo, i == 0, i + 1 < rm->getStages()); #endif - *(stageSolutions[i]) = *solution; *tmp = *solution; *tmp *= rm->getM1(i); - *newUn += *tmp; *tmp = *solution; @@ -119,15 +153,28 @@ for (int i = 0; i < nComponents; i++) { *lowSol += *tmp; } + stageTime = oldTime + (*tauPtr); + + Flag flag_; + return flag_; + } + + + double RosenbrockStationary::estimateTimeError(AdaptInfo* adaptInfo) + { for (int i = 0; i < nComponents; i++) { (*(lowSol->getDOFVector(i))) -= (*(newUn->getDOFVector(i))); - adaptInfo->setTimeEstSum(lowSol->getDOFVector(i)->L2Norm(), i); + adaptInfo->setTimeEstSum(lowSol->getDOFVector(i)->L2Norm(), i+componentShift); } } - - void RosenbrockStationary::solve(AdaptInfo *adaptInfo, bool, bool) - {} + + void RosenbrockStationary::acceptTimestep(AdaptInfo* adaptInfo) + { + *solution = *newUn; + *unVec = *newUn; + oldTime = adaptInfo->getTime(); + } void RosenbrockStationary::addOperator(Operator &op, int row, int col, @@ -174,7 +221,19 @@ for (int i = 0; i < nComponents; i++) { AbstractFunction<double, WorldVector<double> > *fct) { DOFVector<double>* vec = new DOFVector<double>(componentSpaces[row], "vec"); - RosenbrockBoundary bound = {fct, vec, row, col}; + RosenbrockBoundary bound(fct, NULL, vec, row, col); + boundaries.push_back(bound); + + ProblemStat::addDirichletBC(type, row, col, vec); + } + + + void RosenbrockStationary::addDirichletBC(BoundaryType type, int row, int col, + AbstractFunction<double, WorldVector<double> > *fct, + AbstractFunction<double, WorldVector<double> > *fctDt) + { + DOFVector<double>* vec = new DOFVector<double>(componentSpaces[col], "vec"); + RosenbrockBoundary bound(fct, fctDt, vec, row, col); boundaries.push_back(bound); ProblemStat::addDirichletBC(type, row, col, vec); diff --git a/AMDiS/src/time/RosenbrockStationary.h b/AMDiS/src/time/RosenbrockStationary.h index 6d68df320617677995a3e807f4aa59c725701162..2bf60aebc603218a950600fea52a4b1ad07f8b55 100644 --- a/AMDiS/src/time/RosenbrockStationary.h +++ b/AMDiS/src/time/RosenbrockStationary.h @@ -38,30 +38,74 @@ namespace AMDiS { struct RosenbrockBoundary { + RosenbrockBoundary(AbstractFunction<double, WorldVector<double> >* fct_, + AbstractFunction<double, WorldVector<double> >* fctDt_, + DOFVector<double> *vec_, + int row_, int col_) + : fct(fct_), fctDt(fctDt_), vec(vec_), row(row_), col(col_) {} + AbstractFunction<double, WorldVector<double> > *fct; + AbstractFunction<double, WorldVector<double> > *fctDt; // dt[f](t,x) DOFVector<double> *vec; int row; - int col; }; - + /// Realization of a Rosenbrock time-discretization of M*d_t(X) = F[x] + /** + * 1/(tau*gamma) M*Y_i^k - J(t^k, X^k)[Y_i^k] = F[t_i^k, X_i^k] + sum_{j=1}^{i-1} c_ij / tau * M * Y_j^k + * + * with stageSolution[i]: + * X_i^k = X^k + sum_{j=1}^{i-1} a_ij * Y_j^k + * + * oldTime: t^k, stageTime: t_i^k + * + * and new solution + * X^{k+1} = X^k + sum_{j=1}^{s} m_j * Y_j^k + **/ class RosenbrockStationary : public ProblemStat { public: - RosenbrockStationary(std::string name) + RosenbrockStationary(std::string name, int componentShift_ = 0) : ProblemStat(name), + componentShift(componentShift_), first(true), minusOne(-1.0), + stageTime(0.0), + oldTime(0.0), tauPtr(nullptr), tauGamma(nullptr), minusTauGamma(nullptr), invTauGamma(nullptr), minusInvTauGamma(nullptr) {} + + Flag oneIteration(AdaptInfo *adaptInfo, Flag toDo) override; + + virtual Flag stageIteration(AdaptInfo *adaptInfo, Flag flag, + bool asmMatrix, bool asmVector); + + virtual double estimateTimeError(AdaptInfo* adaptInfo); + + /// update solution vector and oldTime value + void acceptTimestep(AdaptInfo* adaptInfo); + + /// Add operators of function F + virtual void addOperator(Operator &op, int row, int col, + double *factor = nullptr, double *estFactor = nullptr); + + /// Add operators of jacobian J = d_X(F) + virtual void addJacobianOperator(Operator &op, int row, int col, + double *factor = nullptr, double *estFactor = nullptr); + + virtual void addTimeOperator(int i, int j); + + // getting methods + // _________________________________________________________________________ + DOFVector<double>* getUnVec(int i) { return unVec->getDOFVector(i); @@ -77,35 +121,54 @@ namespace AMDiS { return timeRhsVec->getDOFVector(i); } - void acceptTimestep(); - - void buildAfterCoarsen(AdaptInfo *adaptInfo, Flag flag, - bool asmMatrix, bool asmVector); - - void solve(AdaptInfo *adaptInfo, bool a = true, bool b = false); + double* getTauGamma() + { + return tauGamma; + } - void setRosenbrockMethod(RosenbrockMethod *method) + double* getTau() { - rm = method; - init(); + return tauPtr; } - void reset() + double* getMinusTauGamma() { - first = true; - stageSolution->set(0.0); - unVec->set(0.0); - for (int i = 0; i < rm->getStages(); i++) - stageSolutions[i]->set(0.0); + return minusTauGamma; } - void addOperator(Operator &op, int row, int col, - double *factor = nullptr, double *estFactor = nullptr); + double* getInvTauGamma() + { + return invTauGamma; + } - void addJacobianOperator(Operator &op, int row, int col, - double *factor = nullptr, double *estFactor = nullptr); + double* getMinusInvTauGamma() + { + return minusInvTauGamma; + } + + double* getStageTime() + { + return &stageTime; + } + + double* getOldTime() + { + return &oldTime; + } + + double* getTauGammaI() + { + return &tauGammaI; + } - void addTimeOperator(int i, int j); + // setting methods + // _________________________________________________________________________ + + void setRosenbrockMethod(RosenbrockMethod *method) + { + rm = method; + init(); + } void setTau(double *ptr) { @@ -119,84 +182,51 @@ namespace AMDiS { invTauGamma = ptr2; minusInvTauGamma = ptr3; } - - double* getTauGamma() + + void setOldTime(double t) { - return tauGamma; + oldTime = t; } - - double* getMinusTauGamma() + + void setStageTime(double t) { - return minusTauGamma; + stageTime = t; } - double* getInvTauGamma() - { - return invTauGamma; - } - double* getMinusInvTauGamma() - { - return minusInvTauGamma; - } + // boundary conditions + // _________________________________________________________________________ /// Adds a Dirichlet boundary condition, where the rhs is given by an /// abstract function. void addDirichletBC(BoundaryType type, int row, int col, - AbstractFunction<double, WorldVector<double> > *b); + AbstractFunction<double, WorldVector<double> > *fct) override; + void addDirichletBC(BoundaryType type, int row, int col, + AbstractFunction<double, WorldVector<double> > *fct, + AbstractFunction<double, WorldVector<double> > *fctDt); + /// Adds a Dirichlet boundary condition, where the rhs is given by a DOF /// vector. void addDirichletBC(BoundaryType type, int row, int col, - DOFVector<double> *vec) + DOFVector<double> *vec) override { FUNCNAME("RosenbrockStationary::addDirichletBC()"); ERROR_EXIT("Not yet supported!\n"); } - /// Adds a Neumann boundary condition, where the rhs is given by an - /// abstract function. - void addNeumannBC(BoundaryType type, int row, int col, - AbstractFunction<double, WorldVector<double> > *n) - { - FUNCNAME("RosenbrockStationary::addNeumannBC()"); - - ERROR_EXIT("Not yet supported!\n"); - } - - /// Adds a Neumann boundary condition, where the rhs is given by an DOF - /// vector. - void addNeumannBC(BoundaryType type, int row, int col, - DOFVector<double> *n) - { - FUNCNAME("RosenbrockStationary::addNeumannBC()"); - - ERROR_EXIT("Not yet supported!\n"); - } - - /// Adds Robin boundary condition. - void addRobinBC(BoundaryType type, int row, int col, - AbstractFunction<double, WorldVector<double> > *n, - AbstractFunction<double, WorldVector<double> > *r) - { - FUNCNAME("RosenbrockStationary::addRobinBC()"); - - ERROR_EXIT("Not yet supported!\n"); - } + protected: + void init(); -#if 0 - /// Adds a periodic boundary condition. - void addPeriodicBC(BoundaryType type, int row, int col) + void reset() { - FUNCNAME("RosenbrockStationary::addPeriodicBC()"); - - ERROR_EXIT("Not yet supported!\n"); + first = true; + stageSolution->set(0.0); + unVec->set(0.0); + for (int i = 0; i < rm->getStages(); i++) + stageSolutions[i]->set(0.0); } -#endif - - protected: - void init(); protected: RosenbrockMethod *rm; @@ -207,10 +237,14 @@ namespace AMDiS { bool first; + int componentShift; + double minusOne; + double stageTime; // t_n + alpha_i*tau + double oldTime; + double tauGammaI; // tau*gamma_i double *tauPtr; - double *tauGamma, *minusTauGamma, *invTauGamma, *minusInvTauGamma; std::vector<RosenbrockBoundary> boundaries; diff --git a/AMDiS/src/traits/at.hpp b/AMDiS/src/traits/at.hpp new file mode 100644 index 0000000000000000000000000000000000000000..4f10c497102b6760562a734c12c7730e45a99446 --- /dev/null +++ b/AMDiS/src/traits/at.hpp @@ -0,0 +1,172 @@ +/****************************************************************************** + * + * AMDiS - Adaptive multidimensional simulations + * + * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. + * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis + * + * Authors: + * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * + * This file is part of AMDiS + * + * See also license.opensource.txt in the distribution. + * + ******************************************************************************/ + + + +/** \file at.hpp */ + +#ifndef AMDIS_TYPE_TRAITS_AT_HPP +#define AMDIS_TYPE_TRAITS_AT_HPP + +#include "AMDiS_fwd.h" +#include "category.hpp" + +namespace AMDiS +{ + namespace traits + { + /// General declaration, used to disable unsupported types + template <typename Collection, class Enable = void> + struct at {}; + + + template <typename T> + struct at<T, typename boost::enable_if< typename has_tag<T, tag::scalar>::type >::type > + { + typedef T value_type; + value_type& operator()(T& v, size_t r) { + TEST_EXIT_DBG(r == 0) + ("Skalars have only 1 component!\n"); + return v; + } + value_type const& operator()(const T& v, size_t r) const { + TEST_EXIT_DBG(r == 0) + ("Skalars have only 1 component!\n"); + return v; + } + value_type& operator()(T& v, size_t r, size_t c) { + TEST_EXIT_DBG(r == 0 && c == 0) + ("Skalars have only 1 row/column!\n"); + return v; + } + value_type const& operator()(const T& v, size_t r, size_t c) const { + TEST_EXIT_DBG(r == 0 && c == 0) + ("Skalars have only 1 row/column!\n"); + return v; + } + }; + + +// == vectors === + + + template <typename T> + struct at<T, typename boost::enable_if + < typename boost::mpl::and_< typename is_vector<T>::type, typename is_mtl<T>::type >::type >::type > + { + typedef typename T::value_type value_type; + value_type& operator()(T& v, size_t r) { + return v[r]; + } + value_type const& operator()(const T& v, size_t r) const { + return v[r]; + } + }; + + /// AMDiS::WorldVector + template <typename Value> + struct at< WorldVector<Value> > + { + typedef Value value_type; + value_type& operator()(WorldVector<Value>& v, size_t r) { + return v[r]; + } + value_type const& operator()(const WorldVector<Value>& v, size_t r) const { + return v[r]; + } + }; + + +// === matrices === + + + template <typename T> + struct at<T, typename boost::enable_if + < typename boost::mpl::and_< typename is_matrix<T>::type, typename is_mtl<T>::type >::type >::type > + { + typedef typename T::value_type value_type; + value_type& operator()(T& v, size_t r, size_t c) { + return v(r,c); + } + value_type const& operator()(const T& v, size_t r, size_t c) { + return v(r,c); + } + }; + + + template <typename Value> + struct at< WorldMatrix<Value> > + { + typedef Value value_type; + value_type& operator()(WorldMatrix<Value>& v, size_t r, size_t c) { + return v[r][c]; + } + value_type const& operator()(const WorldMatrix<Value>& v, size_t r, size_t c) { + return v[r][c]; + } + }; + + } // end namespace traits + + + /// at function for vectors + template <typename Collection> + typename boost::enable_if< typename traits::is_vector<Collection>::type, + typename traits::at<Collection>::value_type const& + >::type + at(const Collection& c, size_t rows) + { + return traits::at<Collection>()(c, rows); + } + + /// at function for vectors + template <typename Collection> + typename boost::enable_if< typename traits::is_vector<Collection>::type, + typename traits::at<Collection>::value_type& + >::type + at(Collection& c, size_t rows) + { + return traits::at<Collection>()(c, rows); + } + + + /// at function for matrices + template <typename Collection> + typename boost::enable_if< typename traits::is_matrix<Collection>::type, + typename traits::at<Collection>::value_type const& + >::type + at(const Collection& c, size_t rows, size_t cols) + { + return traits::at<Collection>()(c, rows, cols); + } + + /// at function for matrices + template <typename Collection> + typename boost::enable_if< typename traits::is_matrix<Collection>::type, + typename traits::at<Collection>::value_type& + >::type + at(Collection& c, size_t rows, size_t cols) + { + return traits::at<Collection>()(c, rows, cols); + } + +} // end namespace AMDiS + +#endif // AMDIS_TYPE_TRAITS_AT_HPP diff --git a/AMDiS/src/traits/category.hpp b/AMDiS/src/traits/category.hpp new file mode 100644 index 0000000000000000000000000000000000000000..e52059e986abb76d13dbc640d1ef55c1af08d6dc --- /dev/null +++ b/AMDiS/src/traits/category.hpp @@ -0,0 +1,239 @@ +/****************************************************************************** + * + * AMDiS - Adaptive multidimensional simulations + * + * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. + * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis + * + * Authors: + * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * + * This file is part of AMDiS + * + * See also license.opensource.txt in the distribution. + * + ******************************************************************************/ + + + +/** \file category.hpp */ + +#ifndef AMDIS_TYPE_TRAITS_CATEGORY_HPP +#define AMDIS_TYPE_TRAITS_CATEGORY_HPP + +#include "AMDiS_fwd.h" +#include "tag.hpp" +#include "types.hpp" + +#include "DOFMatrix.h" + +#include <boost/mpl/if.hpp> +#include <boost/mpl/or.hpp> +#include <boost/type_traits/is_floating_point.hpp> +#include <boost/type_traits/is_signed.hpp> +#include <boost/type_traits/is_unsigned.hpp> + +#include "boost/numeric/mtl/vector/dense_vector.hpp" +#include "boost/numeric/mtl/matrix/dense2D.hpp" +#include "boost/numeric/mtl/matrix/compressed2D.hpp" +#include "boost/numeric/mtl/matrix/coordinate2D.hpp" +#include "boost/numeric/mtl/matrix/morton_dense.hpp" + +namespace AMDiS +{ + namespace traits + { + // categories + // _________________________________________________________________________ + + template<typename T, typename Enabled = void> + struct category + { + typedef tag::unknown tag; + typedef T value_type; + typedef size_t size_type; + }; + + // scalars + template < typename T > + struct category<T, typename boost::enable_if< typename is_numeric<T>::type >::type > + { + typedef tag::scalar tag; + typedef T value_type; +// typedef size_t size_type; + }; + + + // vectors + template<typename T> + struct category<Vector<T> > + { + typedef tag::vector tag; + typedef T value_type; + typedef int size_type; + }; + + template<typename T, GeoIndex d> + struct category<FixVec<T, d> > + { + typedef tag::vector tag; + typedef T value_type; + typedef int size_type; + }; + + template<typename T> + struct category<DimVec<T> > + { + typedef tag::vector tag; + typedef T value_type; + typedef int size_type; + }; + + template<typename T> + struct category<WorldVector<T> > + { + typedef tag::vector tag; + typedef T value_type; + typedef int size_type; + }; + + template<typename T, typename Allocator> + struct category<std::vector<T, Allocator> > + { + typedef tag::vector tag; + typedef T value_type; + typedef size_t size_type; + }; + + template<typename T, typename Parameters> + struct category<mtl::dense_vector<T, Parameters> > + { + typedef tag::vector tag; + typedef typename mtl::dense_vector<T, Parameters>::value_type value_type; + typedef typename mtl::dense_vector<T, Parameters>::size_type size_type; + }; + + template <typename T> + struct category< AMDiS::DOFVector<T> > + { + typedef tag::vector tag; + typedef T value_type; + typedef DegreeOfFreedom size_type; + }; + + template <typename T> + struct category< AMDiS::DOFIndexed<T> > + { + typedef tag::vector tag; + typedef T value_type; + typedef DegreeOfFreedom size_type; + }; + + template <> + struct category< AMDiS::SystemVector > + { + typedef tag::vector tag; + typedef double value_type; + typedef int size_type; + }; + + + // matrices + template<typename T> + struct category<Matrix<T> > + { + typedef tag::matrix tag; + typedef T value_type; + }; + + template<typename T> + struct category<DimMat<T> > + { + typedef tag::matrix tag; + typedef T value_type; + typedef int size_type; + }; + + template<typename T> + struct category<WorldMatrix<T> > + { + typedef tag::matrix tag; + typedef T value_type; + typedef int size_type; + }; + + template<typename T, typename Parameters> + struct category<mtl::dense2D<T, Parameters> > + { + typedef tag::matrix tag; + typedef typename mtl::dense2D<T, Parameters>::value_type value_type; + typedef typename mtl::dense2D<T, Parameters>::size_type size_type; + }; + + template<typename T, typename Parameters> + struct category<mtl::compressed2D<T, Parameters> > + { + typedef tag::matrix tag; + typedef typename mtl::compressed2D<T, Parameters>::value_type value_type; + typedef typename mtl::compressed2D<T, Parameters>::size_type size_type; + }; + + template<typename T, typename Parameters> + struct category<mtl::matrix::coordinate2D<T, Parameters> > + { + typedef tag::matrix tag; + typedef typename mtl::coordinate2D<T, Parameters>::value_type value_type; + typedef typename mtl::coordinate2D<T, Parameters>::size_type size_type; + }; + + template <typename T, std::size_t BitMask, typename Parameters> + struct category<mtl::matrix::morton_dense<T, BitMask, Parameters> > + { + typedef tag::matrix tag; + typedef typename mtl::morton_dense<T, BitMask, Parameters>::value_type value_type; + typedef typename mtl::morton_dense<T, BitMask, Parameters>::size_type size_type; + }; + + template <> + struct category< AMDiS::DOFMatrix > + { + typedef tag::matrix tag; + typedef AMDiS::DOFMatrix::value_type value_type; + typedef AMDiS::DOFMatrix::size_type size_type; + }; + + template < class Matrix > + struct category< AMDiS::SolverMatrix<Matrix> > + { + typedef tag::matrix tag; + }; + + + template < class T > + struct category< const T > : category< T > {}; + + + // operations on tags + // _________________________________________________________________________ + + template< typename T, typename Tag > + struct has_tag : boost::is_same< typename category<T>::tag, Tag > {}; + + template<typename T> + struct is_scalar : has_tag<T, tag::scalar> {}; + + template<typename T> + struct is_vector : has_tag<T, tag::vector> {}; + + template<typename T> + struct is_matrix : has_tag<T, tag::matrix> {}; + + } // end namespace traits + +} // end namespace AMDiS + +#endif // AMDIS_TYPE_TRAITS_CATEGORY_HPP diff --git a/AMDiS/src/traits/inserter.h b/AMDiS/src/traits/inserter.h new file mode 100644 index 0000000000000000000000000000000000000000..85b9f411c02c5c2ed8d50f403b0bda5884e82a32 --- /dev/null +++ b/AMDiS/src/traits/inserter.h @@ -0,0 +1,50 @@ +/****************************************************************************** + * + * AMDiS - Adaptive multidimensional simulations + * + * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. + * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis + * + * Authors: + * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * + * This file is part of AMDiS + * + * See also license.opensource.txt in the distribution. + * + ******************************************************************************/ + + + +/** \file inserter.hpp */ + +#ifndef AMDIS_COLLECTION_INSERTER_HPP +#define AMDIS_COLLECTION_INSERTER_HPP + +#include "MTL4Types.h" + +namespace AMDiS +{ + template<typename T> + struct Collection {}; + + template<> + struct Collection< MTLTypes::MTLMatrix > + { + typedef mtl::matrix::inserter< MTLTypes::MTLMatrix > Inserter; + }; + + template<> + struct Collection< MTLTypes::MTLVector > + { + typedef mtl::vector::inserter< MTLTypes::MTLVector > Inserter; + typedef MTLTypes::MTLMatrix PreconditionMatrix; + }; +} + +#endif // AMDIS_COLLECTION_INSERTER_HPP + diff --git a/AMDiS/src/traits/num_cols.hpp b/AMDiS/src/traits/num_cols.hpp new file mode 100644 index 0000000000000000000000000000000000000000..08f44137280cdff8ab04eb0e32691f5003caaa15 --- /dev/null +++ b/AMDiS/src/traits/num_cols.hpp @@ -0,0 +1,174 @@ +/****************************************************************************** + * + * AMDiS - Adaptive multidimensional simulations + * + * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. + * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis + * + * Authors: + * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * + * This file is part of AMDiS + * + * See also license.opensource.txt in the distribution. + * + ******************************************************************************/ + + + +/** \file num_cols.hpp */ + +#ifndef AMDIS_TYPE_TRAITS_NUM_COLS_HPP +#define AMDIS_TYPE_TRAITS_NUM_COLS_HPP + +#include "AMDiS_fwd.h" +#include "category.hpp" +#include "boost/numeric/mtl/operation/num_cols.hpp" + +namespace AMDiS +{ + namespace traits + { + + template <typename T, typename Enabled = void> + struct num_cols + : ::mtl::traits::num_cols<T> {}; // import mtl-operation by default + + template <typename T> + struct num_cols<T, typename boost::enable_if< typename has_tag<T, tag::scalar>::type >::type > + { + typedef size_t type; + type operator()(const T& v) const { return 1; } + }; + +// == vectors === + + template <typename T> + struct num_cols<T, typename boost::enable_if + < typename boost::mpl::and_< typename is_vector<T>::type, typename is_mtl<T>::type >::type >::type > + { + typedef typename T::size_type type; + type operator()(const T& v) const { return ::mtl::vector::num_cols(v); } + }; + + /// size implementation for AMDiS::Vector + template <typename Value> + struct num_cols< AMDiS::Vector<Value> > + { + typedef typename category< AMDiS::Vector<Value> >::size_type type; + type operator()(const AMDiS::Vector<Value>& v) const { return 1; } + }; + + /// size implementation for AMDiS::FixVec + template <typename Value, AMDiS::GeoIndex d> + struct num_cols< AMDiS::FixVec<Value, d> > + { + typedef typename category< AMDiS::FixVec<Value, d> >::size_type type; + type operator()(const AMDiS::FixVec<Value, d>& v) const { return 1; } + }; + + /// size implementation for AMDiS::DimVec + template <typename Value> + struct num_cols< AMDiS::DimVec<Value> > + { + typedef typename category< AMDiS::DimVec<Value> >::size_type type; + type operator()(const AMDiS::DimVec<Value>& v) const { return 1; } + }; + + /// size implementation for AMDiS::WorldVector + template <typename Value> + struct num_cols< AMDiS::WorldVector<Value> > + { + typedef typename category< AMDiS::WorldVector<Value> >::size_type type; + type operator()(const AMDiS::WorldVector<Value>& v) const { return 1; } + }; + + /// size implementation for AMDiS::DOFVector + template <typename Value> + struct num_cols< AMDiS::DOFVector<Value> > + { + typedef typename category< AMDiS::DOFVector<Value> >::size_type type; + type operator()(const AMDiS::DOFVector<Value>& v) const { return 1; } + }; + +// === matrices === + + template <typename T> + struct num_cols<T, typename boost::enable_if + < typename boost::mpl::and_< typename is_matrix<T>::type, typename is_mtl<T>::type >::type >::type > + { + typedef typename T::size_type type; + type operator()(const T& v) const { return ::mtl::matrix::num_cols(v); } + }; + + /// AMDiS::Matrix + template <typename Value> + struct num_cols< AMDiS::Matrix<Value> > + { + typedef typename category< AMDiS::Matrix<Value> >::size_type type; + type operator()(const AMDiS::Matrix<Value>& v) const + { return v.getNumCols(); } + }; + + /// AMDiS::DimMat + template <typename Value> + struct num_cols< AMDiS::DimMat<Value> > + { + typedef typename category< AMDiS::DimMat<Value> >::size_type type; + type operator()(const AMDiS::DimMat<Value>& v) const + { return v.getNumCols(); } + }; + + /// AMDiS::WorldMatrix + template <typename Value> + struct num_cols< AMDiS::WorldMatrix<Value> > + { + typedef typename category< AMDiS::WorldMatrix<Value> >::size_type type; + type operator()(const AMDiS::WorldMatrix<Value>& v) const + { return v.getNumCols(); } + }; + + /// size implementation for AMDiS::DOFMatrix + template <> + struct num_cols< AMDiS::DOFMatrix > + { + typedef category< AMDiS::DOFMatrix >::size_type type; + type operator()(const AMDiS::DOFMatrix& v) const { return mtl::matrix::num_cols(v.getBaseMatrix()); } + }; + +// === multi-vector or multi-multi-vector === + + /// size implementation for AMDiS::VectorOfFixVecs + template <typename FixVecType> + struct num_cols< AMDiS::VectorOfFixVecs<FixVecType> > + { + typedef typename category< AMDiS::VectorOfFixVecs<FixVecType> >::size_type type; + type operator()(const AMDiS::VectorOfFixVecs<FixVecType>& v) const + { return v.getSize() == 0 ? 0 : v[0].getSize(); } + }; + + /// AMDiS::MatrixOfFixVecs + template <typename FixVecType> + struct num_cols< AMDiS::MatrixOfFixVecs<FixVecType> > + { + typedef typename category< AMDiS::MatrixOfFixVecs<FixVecType> >::size_type type; + type operator()(const AMDiS::MatrixOfFixVecs<FixVecType>& v) const + { return v.getNumberOfColumns(); } + }; + + } // end namespace traits + + template <typename T> + typename traits::num_cols<T>::type + inline num_cols(const T& t) + { + return traits::num_cols<T>()(t); + } + +} // end namespace AMDiS + +#endif // AMDIS_TYPE_TRAITS_NUM_COLS_HPP diff --git a/AMDiS/src/traits/num_rows.hpp b/AMDiS/src/traits/num_rows.hpp new file mode 100644 index 0000000000000000000000000000000000000000..e1372215957bddec352da24ad09d91d88113f1c8 --- /dev/null +++ b/AMDiS/src/traits/num_rows.hpp @@ -0,0 +1,173 @@ +/****************************************************************************** + * + * AMDiS - Adaptive multidimensional simulations + * + * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. + * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis + * + * Authors: + * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * + * This file is part of AMDiS + * + * See also license.opensource.txt in the distribution. + * + ******************************************************************************/ + + + +/** \file num_rows.hpp */ + +#ifndef AMDIS_TYPE_TRAITS_NUM_ROWS_HPP +#define AMDIS_TYPE_TRAITS_NUM_ROWS_HPP + +#include "AMDiS_fwd.h" +#include "category.hpp" +#include "boost/numeric/mtl/operation/num_rows.hpp" + +namespace AMDiS +{ + namespace traits + { + + template <typename T, typename Enabled = void> + struct num_rows + : ::mtl::traits::num_rows<T> {}; // import mtl-operation by default + + template <typename T> + struct num_rows<T, typename boost::enable_if< typename has_tag<T, tag::scalar>::type >::type > + { + typedef size_t type; + type operator()(const T& v) const { return 1; } + }; + +// == vectors === + + template <typename T> + struct num_rows<T, typename boost::enable_if + < typename boost::mpl::and_< typename is_vector<T>::type, typename is_mtl<T>::type >::type >::type > + { + typedef typename T::size_type type; + type operator()(const T& v) const { return ::mtl::vector::num_rows(v); } + }; + + /// size implementation for AMDiS::Vector + template <typename Value> + struct num_rows< AMDiS::Vector<Value> > + { + typedef typename category< AMDiS::Vector<Value> >::size_type type; + type operator()(const AMDiS::Vector<Value>& v) const { return v.getSize(); } + }; + + /// size implementation for AMDiS::FixVec + template <typename Value, AMDiS::GeoIndex d> + struct num_rows< AMDiS::FixVec<Value, d> > + { + typedef typename category< AMDiS::FixVec<Value, d> >::size_type type; + type operator()(const AMDiS::FixVec<Value, d>& v) const { return v.getSize(); } + }; + + /// size implementation for AMDiS::DimVec + template <typename Value> + struct num_rows< AMDiS::DimVec<Value> > + { + typedef typename category< AMDiS::DimVec<Value> >::size_type type; + type operator()(const AMDiS::DimVec<Value>& v) const { return v.getSize(); } + }; + + /// size implementation for AMDiS::WorldVector + template <typename Value> + struct num_rows< AMDiS::WorldVector<Value> > + { + typedef typename category< AMDiS::WorldVector<Value> >::size_type type; + type operator()(const AMDiS::WorldVector<Value>& v) const { return v.getSize(); } + }; + + /// size implementation for AMDiS::DOFVector + template <typename Value> + struct num_rows< AMDiS::DOFVector<Value> > + { + typedef typename category< AMDiS::DOFVector<Value> >::size_type type; + type operator()(const AMDiS::DOFVector<Value>& v) const { return v.getUsedSize(); } + }; + +// === matrices === + + template <typename T> + struct num_rows<T, typename boost::enable_if + < typename boost::mpl::and_< typename is_matrix<T>::type, typename is_mtl<T>::type >::type >::type > + { + typedef typename T::size_type type; + type operator()(const T& v) const { return ::mtl::matrix::num_rows(v); } + }; + + /// AMDiS::Matrix + template <typename Value> + struct num_rows< AMDiS::Matrix<Value> > + { + typedef typename category< AMDiS::Matrix<Value> >::size_type type; + type operator()(const AMDiS::Matrix<Value>& v) const + { return v.getNumRows(); } + }; + + /// AMDiS::DimMat + template <typename Value> + struct num_rows< AMDiS::DimMat<Value> > + { + typedef typename category< AMDiS::DimMat<Value> >::size_type type; + type operator()(const AMDiS::DimMat<Value>& v) const + { return v.getNumRows(); } + }; + + /// AMDiS::WorldMatrix + template <typename Value> + struct num_rows< AMDiS::WorldMatrix<Value> > + { + typedef typename category< AMDiS::WorldMatrix<Value> >::size_type type; + type operator()(const AMDiS::WorldMatrix<Value>& v) const + { return v.getNumRows(); } + }; + + /// size implementation for AMDiS::DOFMatrix + template <> + struct num_rows< AMDiS::DOFMatrix > + { + typedef category< AMDiS::DOFMatrix >::size_type type; + type operator()(const AMDiS::DOFMatrix& v) const { return mtl::matrix::num_rows(v.getBaseMatrix()); } + }; + +// === multi-vector or multi-multi-vector === + + /// size implementation for AMDiS::VectorOfFixVecs + template <typename FixVecType> + struct num_rows< AMDiS::VectorOfFixVecs<FixVecType> > + { + typedef typename category< AMDiS::VectorOfFixVecs<FixVecType> >::size_type type; + type operator()(const AMDiS::VectorOfFixVecs<FixVecType>& v) const { return v.getSize(); } + }; + + /// AMDiS::MatrixOfFixVecs + template <typename FixVecType> + struct num_rows< AMDiS::MatrixOfFixVecs<FixVecType> > + { + typedef typename category< AMDiS::MatrixOfFixVecs<FixVecType> >::size_type type; + type operator()(const AMDiS::MatrixOfFixVecs<FixVecType>& v) const + { return v.getNumberOfRows(); } + }; + + } // end namespace traits + + template <typename T> + typename traits::num_rows<T>::type + inline num_rows(const T& t) + { + return traits::num_rows<T>()(t); + } + +} // end namespace AMDiS + +#endif // AMDIS_TYPE_TRAITS_NUM_ROWS_HPP diff --git a/AMDiS/src/traits/resize.hpp b/AMDiS/src/traits/resize.hpp new file mode 100644 index 0000000000000000000000000000000000000000..bbad5ff6256df9da54781cd9e8d75f829e733366 --- /dev/null +++ b/AMDiS/src/traits/resize.hpp @@ -0,0 +1,123 @@ +/****************************************************************************** + * + * AMDiS - Adaptive multidimensional simulations + * + * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. + * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis + * + * Authors: + * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * + * This file is part of AMDiS + * + * See also license.opensource.txt in the distribution. + * + ******************************************************************************/ + + + +/** \file resize.hpp */ + +#ifndef AMDIS_TYPE_TRAITS_RESIZE_HPP +#define AMDIS_TYPE_TRAITS_RESIZE_HPP + +#include "AMDiS_fwd.h" +#include "category.hpp" + +namespace AMDiS +{ + namespace traits + { + + /// General declaration, used to disable unsupported types + template <typename Collection, class Enable = void> + struct resize {}; + + + template <typename T> + struct resize<T, typename boost::enable_if< typename has_tag<T, tag::scalar>::type >::type > + { + void operator()(T& v, size_t r) const { + TEST_EXIT_DBG(r == 1) + ("Skalars can not be resized!\n"); + } + }; + +// == vectors === + + template <typename T> + struct resize<T, typename boost::enable_if + < typename boost::mpl::and_< typename is_vector<T>::type, typename is_mtl<T>::type >::type >::type > + { + void operator()(T& v, size_t r) const { v.change_dim(r); } + }; + + + /// change_dim implementation for AMDiS WorldVectors + template <typename Value> + struct resize< WorldVector<Value> > + { + void operator()(WorldVector<Value>& v, size_t r) { + TEST_EXIT_DBG(Global::getGeo(WORLD) == r) + ("WorldVectors can not be resized!\n"); + } + }; + + /// change_dim implementation for STL vectors + template <typename Value> + struct resize< std::vector<Value> > + { + void operator()(std::vector<Value>& v, size_t r) { + v.resize(r); + } + }; + + +// === matrices === + + template <typename T> + struct resize<T, typename boost::enable_if + < typename boost::mpl::and_< typename is_matrix<T>::type, typename is_mtl<T>::type >::type >::type > + { + void operator()(T& m, size_t r, size_t c) { return m.change_dim(r,c); } + }; + + /// change_dim implementation for AMDiS WorldMatrices + template <typename Value> + struct resize< WorldMatrix<Value> > + { + void operator()(WorldMatrix<Value>& v, size_t r, size_t c) { +#ifndef NDEBUG + size_t dow = static_cast<size_t>(Global::getGeo(WORLD)); + TEST_EXIT_DBG(dow == r && dow == c) + ("WorldMatrices can not be resized!\n"); +#endif + } + }; + + } // end namespace traits + + + /// resize function for vectors + template <typename Collection> + typename boost::enable_if< typename traits::is_vector<Collection>::type >::type + resize(Collection& c, size_t rows) + { + traits::resize<Collection>()(c, rows); + } + + /// resize function for matrices + template <typename Collection> + typename boost::enable_if< typename traits::is_matrix<Collection>::type >::type + resize(Collection& c, size_t rows, size_t cols) + { + traits::resize<Collection>()(c, rows, cols); + } + +} // end namespace AMDiS + +#endif // AMDIS_TYPE_TRAITS_RESIZE_HPP diff --git a/AMDiS/src/traits/size.hpp b/AMDiS/src/traits/size.hpp new file mode 100644 index 0000000000000000000000000000000000000000..503bc6f7b03be7f7e8136d94b180f074900e6447 --- /dev/null +++ b/AMDiS/src/traits/size.hpp @@ -0,0 +1,176 @@ +/****************************************************************************** + * + * AMDiS - Adaptive multidimensional simulations + * + * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. + * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis + * + * Authors: + * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * + * This file is part of AMDiS + * + * See also license.opensource.txt in the distribution. + * + ******************************************************************************/ + + + +/** \file size.hpp */ + +#ifndef AMDIS_TYPE_TRAITS_SIZE_HPP +#define AMDIS_TYPE_TRAITS_SIZE_HPP + +#include "AMDiS_fwd.h" +#include "category.hpp" +#include "boost/numeric/mtl/operation/size.hpp" + +namespace AMDiS +{ + namespace traits + { + template <typename T, typename Enabled = void> + struct size + : ::mtl::traits::size<T> {}; // import mtl-operation by default + + + template <typename T> + struct size<T, typename boost::enable_if< typename has_tag<T, tag::scalar>::type >::type > + { + typedef size_t type; + type operator()(const T& v) const { return 1; } + }; + +// == vectors === + + template <typename T> + struct size<T, typename boost::enable_if + < typename boost::mpl::and_< typename is_vector<T>::type, typename is_mtl<T>::type >::type >::type > + { + typedef typename T::size_type type; + type operator()(const T& v) const { return ::mtl::vector::size(v); } + }; + + /// size implementation for AMDiS::Vector + template <typename Value> + struct size< AMDiS::Vector<Value> > + { + typedef typename category< AMDiS::Vector<Value> >::size_type type; + type operator()(const AMDiS::Vector<Value>& v) const { return v.getSize(); } + }; + + /// size implementation for AMDiS::FixVec + template <typename Value, AMDiS::GeoIndex d> + struct size< AMDiS::FixVec<Value, d> > + { + typedef typename category< AMDiS::FixVec<Value, d> >::size_type type; + type operator()(const AMDiS::FixVec<Value, d>& v) const { return v.getSize(); } + }; + + /// size implementation for AMDiS::DimVec + template <typename Value> + struct size< AMDiS::DimVec<Value> > + { + typedef typename category< AMDiS::DimVec<Value> >::size_type type; + type operator()(const AMDiS::DimVec<Value>& v) const { return v.getSize(); } + }; + + /// size implementation for AMDiS::WorldVector + template <typename Value> + struct size< AMDiS::WorldVector<Value> > + { + typedef typename category< AMDiS::WorldVector<Value> >::size_type type; + type operator()(const AMDiS::WorldVector<Value>& v) const { return v.getSize(); } + }; + + /// size implementation for AMDiS::DOFVector + template <typename Value> + struct size< AMDiS::DOFVector<Value> > + { + typedef typename category< AMDiS::DOFVector<Value> >::size_type type; + type operator()(const AMDiS::DOFVector<Value>& v) const { return v.getUsedSize(); } + }; + +// === matrices === + + template <typename T> + struct size<T, typename boost::enable_if + < typename boost::mpl::and_< typename is_matrix<T>::type, typename is_mtl<T>::type >::type >::type > + { + typedef typename T::size_type type; + type operator()(const T& v) const { return ::mtl::matrix::size(v); } + }; + + /// AMDiS::Matrix + template <typename Value> + struct size< AMDiS::Matrix<Value> > + { + typedef typename category< AMDiS::Matrix<Value> >::size_type type; + type operator()(const AMDiS::Matrix<Value>& v) const + { return v.getNumRows() * v.getNumCols(); } + }; + + /// AMDiS::DimMat + template <typename Value> + struct size< AMDiS::DimMat<Value> > + { + typedef typename category< AMDiS::DimMat<Value> >::size_type type; + type operator()(const AMDiS::DimMat<Value>& v) const + { return v.getNumRows() * v.getNumCols(); } + }; + + /// AMDiS::WorldMatrix + template <typename Value> + struct size< AMDiS::WorldMatrix<Value> > + { + typedef typename category< AMDiS::WorldMatrix<Value> >::size_type type; + type operator()(const AMDiS::WorldMatrix<Value>& v) const + { return v.getNumRows() * v.getNumCols(); } + }; + + /// size implementation for AMDiS::DOFMatrix + template <> + struct size< AMDiS::DOFMatrix > + { + typedef category< AMDiS::DOFMatrix >::size_type type; + type operator()(const AMDiS::DOFMatrix& v) const { return mtl::matrix::size(v.getBaseMatrix()); } + }; + +// === multi-vector or multi-matrix === + + /// size implementation for AMDiS::VectorOfFixVecs + template <typename FixVecType> + struct size< AMDiS::VectorOfFixVecs<FixVecType> > + { + typedef typename category< AMDiS::VectorOfFixVecs<FixVecType> >::size_type type; + type operator()(const AMDiS::VectorOfFixVecs<FixVecType>& v) const + { return v.getSize() * v.getSizeOfFixVec(); } + }; + + /// AMDiS::MatrixOfFixVecs + template <typename FixVecType> + struct size< AMDiS::MatrixOfFixVecs<FixVecType> > + { + typedef typename category< AMDiS::MatrixOfFixVecs<FixVecType> >::size_type type; + type operator()(const AMDiS::MatrixOfFixVecs<FixVecType>& v) const + { + return v.getNumberOfRows() == 0 ? 0 : v.getNumberOfRows() * v.getNumberOfColumns() * v[0].getSizeOfFixVec(); + } + }; + + } // end namespace traits + + template <typename T> + typename traits::size<T>::type + inline size(const T& t) + { + return traits::size<T>()(t); + } + +} // end namespace AMDiS + +#endif // AMDIS_TYPE_TRAITS_SIZE_HPP diff --git a/AMDiS/src/traits/tag.hpp b/AMDiS/src/traits/tag.hpp new file mode 100644 index 0000000000000000000000000000000000000000..36a9df7f40d60705a8fe98e2ebfd95f9b3972350 --- /dev/null +++ b/AMDiS/src/traits/tag.hpp @@ -0,0 +1,42 @@ +/****************************************************************************** + * + * AMDiS - Adaptive multidimensional simulations + * + * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. + * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis + * + * Authors: + * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * + * This file is part of AMDiS + * + * See also license.opensource.txt in the distribution. + * + ******************************************************************************/ + + + +/** \file tag.hpp */ + +#ifndef AMDIS_TYPE_TRAITS_TAG_HPP +#define AMDIS_TYPE_TRAITS_TAG_HPP + +namespace AMDiS { + + namespace tag + { + struct scalar {}; + struct vector {}; + struct matrix {}; + struct unknown {}; + + struct expression {}; + } + +} // end namespace AMDiS + +#endif // AMDIS_TYPE_TRAITS_TAG_HPP diff --git a/AMDiS/src/traits/types.hpp b/AMDiS/src/traits/types.hpp new file mode 100644 index 0000000000000000000000000000000000000000..020425ceccccae0e52865835053e461f60eb4c3e --- /dev/null +++ b/AMDiS/src/traits/types.hpp @@ -0,0 +1,141 @@ +/****************************************************************************** + * + * AMDiS - Adaptive multidimensional simulations + * + * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. + * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis + * + * Authors: + * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * + * This file is part of AMDiS + * + * See also license.opensource.txt in the distribution. + * + ******************************************************************************/ + + + +/** \file types.hpp */ + +#ifndef AMDIS_TYPE_TRAITS_TYPES_HPP +#define AMDIS_TYPE_TRAITS_TYPES_HPP + +#include "AMDiS_fwd.h" +#include "FixVec.h" + +// mtl4 types +#include "boost/numeric/mtl/vector/dense_vector.hpp" +#include "boost/numeric/mtl/matrix/dense2D.hpp" +#include "boost/numeric/mtl/matrix/compressed2D.hpp" +#include "boost/numeric/mtl/matrix/coordinate2D.hpp" +#include "boost/numeric/mtl/matrix/morton_dense.hpp" + +#include "boost/numeric/ublas/detail/returntype_deduction.hpp" + +namespace AMDiS +{ + namespace traits + { + + // dummy type + typedef boost::numeric::ublas::error_cant_deduce_type no_valid_type; + + // type-traits + // _________________________________________________________________________ + template<typename T> + struct is_integer : boost::mpl::or_ + < + typename boost::is_signed<T>::type, + typename boost::is_unsigned<T>::type + >::type {}; + + template<typename T> + struct is_numeric : boost::mpl::or_ + < + typename boost::is_floating_point<T>::type, + typename is_integer<T>::type + >::type {}; + + + // test for mtl4 types + // _________________________________________________________________________ + template<typename T> + struct is_mtl : boost::mpl::false_ {}; + + template<typename T, typename Param> + struct is_mtl<mtl::dense_vector<T, Param> > : boost::mpl::true_ {}; + + template<typename T, typename Param> + struct is_mtl<mtl::dense2D<T, Param> > : boost::mpl::true_ {}; + + template<typename T, typename Param> + struct is_mtl<mtl::compressed2D<T, Param> > : boost::mpl::true_ {}; + + template<typename T, typename Param> + struct is_mtl<mtl::matrix::coordinate2D<T, Param> > : boost::mpl::true_ {}; + + template<typename T, std::size_t BitMask, typename Param> + struct is_mtl<mtl::matrix::morton_dense<T, BitMask, Param> > : boost::mpl::true_ {}; + + + // test for AMDiS types + // _________________________________________________________________________ + template<typename T> + struct is_amdis : boost::mpl::false_ {}; + + template<typename T> + struct is_amdis<AMDiS::Vector<T> > : boost::mpl::true_ {}; + + template<typename T> + struct is_amdis<AMDiS::Matrix<T> > : boost::mpl::true_ {}; + + template<typename T,GeoIndex d> + struct is_amdis<AMDiS::FixVec<T,d> > : boost::mpl::true_ {}; + + template<typename T> + struct is_amdis<AMDiS::VectorOfFixVecs<T> > : boost::mpl::true_ {}; + + template<typename T> + struct is_amdis<AMDiS::MatrixOfFixVecs<T> > : boost::mpl::true_ {}; + + template<typename T> + struct is_amdis<AMDiS::DimVec<T> > : boost::mpl::true_ {}; + + template<typename T> + struct is_amdis<AMDiS::DimMat<T> > : boost::mpl::true_ {}; + + template<typename T> + struct is_amdis<AMDiS::WorldVector<T> > : boost::mpl::true_ {}; + + template<typename T> + struct is_amdis<AMDiS::WorldMatrix<T> > : boost::mpl::true_ {}; + + template<typename T> + struct is_amdis<AMDiS::DOFVectorBase<T> > : boost::mpl::true_ {}; + + template<typename T> + struct is_amdis<AMDiS::DOFVector<T> > : boost::mpl::true_ {}; + + template<> + struct is_amdis<AMDiS::DOFVectorDOF > : boost::mpl::true_ {}; + + template<> + struct is_amdis<AMDiS::DOFMatrix > : boost::mpl::true_ {}; + + template<> + struct is_amdis<AMDiS::DOFContainer > : boost::mpl::true_ {}; + + template<> + struct is_amdis<AMDiS::SystemVector > : boost::mpl::true_ {}; + + + } // end namespace traits + +} // end namespace AMDiS + +#endif // AMDIS_TYPE_TRAITS_TYPES_HPP diff --git a/extensions/BackgroundMesh.cc b/extensions/BackgroundMesh.cc index b2fc2b6d15872c57db2f98bc7ac19607225eb228..0dc74990d5eb8808a8277112d8c597f260d2178a 100644 --- a/extensions/BackgroundMesh.cc +++ b/extensions/BackgroundMesh.cc @@ -22,7 +22,7 @@ #include <boost/math/special_functions/round.hpp> -namespace experimental { +namespace AMDiS { namespace extensions { std::map<const FiniteElemSpace*, std::pair<int, Box*> > Box::boxMap; @@ -389,4 +389,4 @@ namespace experimental { boxData[nr].push_back(data); } -} +} } diff --git a/extensions/BackgroundMesh.h b/extensions/BackgroundMesh.h index 499acea9ef1fd83f47e365512de6c91586bdfde9..ae3a005e92c7fc84f93beac96f7b275c7a6f540c 100644 --- a/extensions/BackgroundMesh.h +++ b/extensions/BackgroundMesh.h @@ -29,9 +29,7 @@ #define USE_EXPERIMENTAL #endif -namespace experimental { - - using namespace AMDiS; +namespace AMDiS { namespace extensions { typedef WorldVector<double> PointType; @@ -40,7 +38,7 @@ namespace experimental { double d = 0.0; for (unsigned int i = 0; i < n; i++) d += sqr(x[i]-y[i]); - return sqrt(d); + return std::sqrt(d); } inline double distance2(const PointType &x, const PointType &y, unsigned int n) @@ -140,7 +138,7 @@ namespace experimental { std::vector<std::vector<DataType> > boxData; }; -} // end namespace experimental +} } #include "BackgroundMesh.hh" diff --git a/extensions/BackgroundMesh.hh b/extensions/BackgroundMesh.hh index 73d2b8d0d5264044ebaf32a6ceec439847da8b50..ab7615bfcd802717fef072e4a831793afd38eb92 100644 --- a/extensions/BackgroundMesh.hh +++ b/extensions/BackgroundMesh.hh @@ -18,7 +18,7 @@ #include "Tools.h" // tools::Regression -namespace experimental { +namespace AMDiS { namespace extensions { /** * strategies: @@ -148,4 +148,4 @@ namespace experimental { return value; } -} // end namespace experimental +} } diff --git a/extensions/BackgroundMesh2.h b/extensions/BackgroundMesh2.h index 3ddac46c5cd72c8c1f374806138cfdc4155e0a9a..140bb41c18a54177e50be601bb275f0998a1493e 100644 --- a/extensions/BackgroundMesh2.h +++ b/extensions/BackgroundMesh2.h @@ -26,7 +26,7 @@ #define USE_EXPERIMENTAL #endif -namespace experimental { +namespace AMDiS { namespace extensions { typedef WorldVector<double> PointType_; typedef boost::tuple<const MacroElement*, int, unsigned long> ElInfoDataType; // data to recover elInfo @@ -414,7 +414,7 @@ protected: template<typename PointType, typename DataType> std::map<const FiniteElemSpace*, std::pair<int, ElementBox<PointType, DataType>*> > ElementBox<PointType, DataType>::boxMap; -} // end namespace tools +} } #include "BackgroundMesh2.hh" diff --git a/extensions/BackgroundMesh2.hh b/extensions/BackgroundMesh2.hh index 03d3557ed43736c32eaec015036249f1e6b9ff95..8f2b3e43427f85db823860a783a1fc72ce986de8 100644 --- a/extensions/BackgroundMesh2.hh +++ b/extensions/BackgroundMesh2.hh @@ -18,8 +18,8 @@ #include "ElementFunction.h" -namespace experimental { - +namespace AMDiS { namespace extensions { + template<> void ElementBox<PointType_, std::pair<ElInfoDataType, PointType_> >::fillBox(const FiniteElemSpace* feSpace) { @@ -86,4 +86,4 @@ namespace experimental { return value; } -} // end namespace experimental +} } diff --git a/extensions/BoundaryFunctions.h b/extensions/BoundaryFunctions.h index e462096294403968fb18a5b7505af5588c85ee94..8e39125183d347e08a2b27f11f228b2fedcf9dd3 100644 --- a/extensions/BoundaryFunctions.h +++ b/extensions/BoundaryFunctions.h @@ -22,8 +22,10 @@ #include "AMDiS.h" #include <time.h> + +namespace AMDiS { namespace extensions { + using namespace std; -using namespace AMDiS; // parabolic inflow @@ -259,4 +261,6 @@ protected: double endTime; }; +} } + #endif // EXTENSIONS_BOUNDARY_FUNCTIONS_H diff --git a/extensions/ExtendedProblemStat.h b/extensions/ExtendedProblemStat.h index c3c66810e928e7a038f82c806eabbfa02a40f69e..d6f305e1c516879d2bdb8aa36bfa865261f4241c 100644 --- a/extensions/ExtendedProblemStat.h +++ b/extensions/ExtendedProblemStat.h @@ -25,7 +25,7 @@ #include "nonlin/ProblemNonLin.h" #endif -using namespace AMDiS; +namespace AMDiS { namespace extensions { const Flag INIT_EXACT_SOLUTION = 0X10000L; const Flag UPDATE_PERIODIC_BC = 0X20000L; @@ -356,8 +356,8 @@ protected: bool value1set = false; if (asmMatrix) { - typedef mtl::traits::range_generator<tag::row, Matrix>::type c_type; - typedef mtl::traits::range_generator<tag::nz, c_type>::type ic_type; + typedef mtl::traits::range_generator<mtl::tag::row, Matrix>::type c_type; + typedef mtl::traits::range_generator<mtl::tag::nz, c_type>::type ic_type; // if matrix-block for the identity row is NULL, create new DOFMatrix if (getSystemMatrix(row_, col_) == NULL) { @@ -381,8 +381,8 @@ protected: mtl::traits::col<Matrix>::type c(m); mtl::traits::value<Matrix>::type v(m); - c_type cursor(begin<tag::row>(m)+idx_); - for (ic_type icursor(begin<tag::nz>(cursor)), icend(end<tag::nz>(cursor)); icursor != icend; ++icursor) { + c_type cursor(begin<mtl::tag::row>(m)+idx_); + for (ic_type icursor(begin<mtl::tag::nz>(cursor)), icend(end<mtl::tag::nz>(cursor)); icursor != icend; ++icursor) { value1set = value1set || (r(*icursor) == c(*icursor) && col == col_); v(*icursor, (r(*icursor) == c(*icursor) && col == col_ ? 1.0 : 0.0)); } @@ -411,8 +411,8 @@ protected: using namespace mtl; typedef DOFMatrix::base_matrix_type Matrix; - typedef mtl::traits::range_generator<tag::row, Matrix>::type c_type; - typedef mtl::traits::range_generator<tag::nz, c_type>::type ic_type; + typedef mtl::traits::range_generator<mtl::tag::row, Matrix>::type c_type; + typedef mtl::traits::range_generator<mtl::tag::nz, c_type>::type ic_type; size_t numCols = static_cast<size_t>(getNumComponents()); for (size_t col = 0; col < numCols; col++) { @@ -434,8 +434,8 @@ protected: continue; if (asmMatrix) { - c_type cursor(begin<tag::row>(m)+indices[i].first); - for (ic_type icursor(begin<tag::nz>(cursor)), icend(end<tag::nz>(cursor)); icursor != icend; ++icursor) { + c_type cursor(begin<mtl::tag::row>(m)+indices[i].first); + for (ic_type icursor(begin<mtl::tag::nz>(cursor)), icend(end<mtl::tag::nz>(cursor)); icursor != icend; ++icursor) { row_values[i].push_back(std::make_pair(c(*icursor), v(*icursor))); v(*icursor, 0.0); } @@ -483,8 +483,8 @@ protected: using namespace mtl; typedef DOFMatrix::base_matrix_type Matrix; - typedef mtl::traits::range_generator<tag::row, Matrix>::type c_type; - typedef mtl::traits::range_generator<tag::nz, c_type>::type ic_type; + typedef mtl::traits::range_generator<mtl::tag::row, Matrix>::type c_type; + typedef mtl::traits::range_generator<mtl::tag::nz, c_type>::type ic_type; size_t numCols = static_cast<size_t>(getNumComponents()); TEST_EXIT(row_idx.size() == coefficients.size() && row_idx.size() == rhs.size() && rhs.size()>0) @@ -504,8 +504,8 @@ protected: // erase the rows for all row-indices and set rhs values for (size_t i = 0; i < coefficients.size(); i++) { - c_type cursor(begin<tag::row>(m)+row_idx[i]); - for (ic_type icursor(begin<tag::nz>(cursor)), icend(end<tag::nz>(cursor)); icursor != icend; ++icursor) { + c_type cursor(begin<mtl::tag::row>(m)+row_idx[i]); + for (ic_type icursor(begin<mtl::tag::nz>(cursor)), icend(end<mtl::tag::nz>(cursor)); icursor != icend; ++icursor) { v(*icursor, (r(*icursor) == c(*icursor) ? coefficients[i][col] : 0.0)); } (*(getRhsVector(row)))[row_idx[i]] = rhs[i]; @@ -542,4 +542,9 @@ private: std::map<const FiniteElemSpace*, bool> feSpaceVisited; }; + +} } + +using namespace AMDiS::extensions; + #endif // EXTENSIONS_EXTENDED_PROBLEM_STAT_H diff --git a/extensions/GenericLoops.h b/extensions/GenericLoops.h index cddd07c990e22198d47e09f996228f556b8e40d7..9e1d277dce6b25671a39ad3c7d13e08eee2bc966 100644 --- a/extensions/GenericLoops.h +++ b/extensions/GenericLoops.h @@ -24,6 +24,8 @@ #define _GET_TYPE_ boost::tuples::element #define _LENGTH_ boost::tuples::length +namespace AMDiS { namespace extensions { + namespace tools { @@ -176,5 +178,6 @@ namespace tools { }; } // namespace tools +} } #endif // EXTENSIONS_GENERIC_LOOPS_H \ No newline at end of file diff --git a/extensions/GenericLoops_cxx11.h b/extensions/GenericLoops_cxx11.h index 0f708674bc9ce7b776639e3e1f2b75d368f88265..f19a819c6ca7d4f2fac9ed5d9ae57c10a32a7022 100644 --- a/extensions/GenericLoops_cxx11.h +++ b/extensions/GenericLoops_cxx11.h @@ -24,6 +24,8 @@ #define _GET_TYPE_ std::tuple_element #define _LENGTH_ std::tuple_size +namespace AMDiS { namespace extensions { + namespace tools { @@ -177,4 +179,6 @@ namespace tools { } // namespace tools +} } + #endif // EXTENSIONS_GENERIC_LOOPS_H \ No newline at end of file diff --git a/extensions/GeometryTools.cc b/extensions/GeometryTools.cc index 2d174bf24f24984a7b5a16c2555c22ed7861cd9b..b2fb56c98009953685f253e6e0eec452f127b6ea 100644 --- a/extensions/GeometryTools.cc +++ b/extensions/GeometryTools.cc @@ -20,6 +20,8 @@ #define EPSILON FLT_EPSILON +namespace AMDiS { namespace extensions { + namespace meshconv2 { // ############### @@ -1512,3 +1514,5 @@ double volume_tetrahedron(double tet0[], double tet1[], double tet2[], double te } } // end namespace meshconv2 + +} } diff --git a/extensions/GeometryTools.h b/extensions/GeometryTools.h index 0ecd122c358b49eada2b91a749954220b7d51701..8688cf7aa5e561f81bdd357de070a5219df05071 100644 --- a/extensions/GeometryTools.h +++ b/extensions/GeometryTools.h @@ -20,7 +20,8 @@ #define EXTENSIONS_GEOMETRY_TOOLBOX_H #include "FixVec.h" - +namespace AMDiS { namespace extensions { + namespace meshconv2 { /** @@ -245,6 +246,8 @@ double volume_tetrahedron(double tet0[], double tet1[], double tet2[], double te /**@}*/ } // end namespace meshconv2 +} } + #include "GeometryTools.hh" #endif // EXTENSIONS_GEOMETRY_TOOLBOX_H diff --git a/extensions/GeometryTools.hh b/extensions/GeometryTools.hh index 9e7575cc063d667ddb180a9f05212268f9770025..9c580d7a68124541f19ca31785ee86931eae76c3 100644 --- a/extensions/GeometryTools.hh +++ b/extensions/GeometryTools.hh @@ -15,6 +15,7 @@ * ******************************************************************************/ +namespace AMDiS { namespace extensions { namespace meshconv2 { @@ -26,16 +27,16 @@ namespace meshconv2 { Ry = 1.0; S = 1.0; if (dow == 3) { - Rx(1,1) = cos(alpha); Rx(1,2) = -sin(alpha); - Rx(2,1) = sin(alpha); Rx(2,2) = cos(alpha); + Rx(1,1) = std::cos(alpha); Rx(1,2) = -std::sin(alpha); + Rx(2,1) = std::sin(alpha); Rx(2,2) = std::cos(alpha); - Ry(0,0) = cos(beta); Ry(0,2) = sin(beta); - Ry(2,0) = -sin(beta); Ry(2,2) = cos(beta); + Ry(0,0) = std::cos(beta); Ry(0,2) = std::sin(beta); + Ry(2,0) = -std::sin(beta); Ry(2,2) = std::cos(beta); S(0,0) = scale[0]; S(1,1) = scale[1]; S(2,2) = scale[2]; } else if (dow == 2) { - Rx(0,0) = cos(alpha); Rx(0,1) = -sin(alpha); - Rx(1,0) = sin(alpha); Rx(1,1) = cos(alpha); + Rx(0,0) = std::cos(alpha); Rx(0,1) = -std::sin(alpha); + Rx(1,0) = std::sin(alpha); Rx(1,1) = std::cos(alpha); Ry = 1.0; @@ -57,3 +58,5 @@ namespace meshconv2 { } } // end namespace meshconv2 + +} } diff --git a/extensions/GradientCalculations.h b/extensions/GradientCalculations.h index d74ed1953172bc313f668e5f1da9cebde9700412..ec64d34c2775ccb714419c0042e9eea17acc1c53 100644 --- a/extensions/GradientCalculations.h +++ b/extensions/GradientCalculations.h @@ -21,9 +21,7 @@ #include "AMDiS.h" -using namespace AMDiS; - -namespace experimental { +namespace AMDiS { namespace extensions { /// Extended recovery gradient assuming mirror/point symmetry (pointSym=false/true) /// of the solution at domain boundaries @@ -141,6 +139,6 @@ namespace experimental { *grdIt *= 1.0 / (*volIt); } -} // end namespace experimental +} } #endif // EXTENSIONS_GRADIENT_CALCULATIONS_H diff --git a/extensions/Helpers.cc b/extensions/Helpers.cc index 9c54b980ffd0b322ae4c17716c9412e477be0165..9c2e2048126cbc45b21c3018cfdc1b4e996db2ef 100644 --- a/extensions/Helpers.cc +++ b/extensions/Helpers.cc @@ -18,7 +18,7 @@ #include "Helpers.h" -using namespace AMDiS; +namespace AMDiS { namespace extensions { namespace Helpers { @@ -459,3 +459,5 @@ namespace Helpers { } } // end namespace Helpers + +} } diff --git a/extensions/Helpers.h b/extensions/Helpers.h index 0d75b4c010302dd464fbf839fe4b867cb0a816c1..690f80d2b11fbced7d7d5fa98fc1e2516142fb6b 100644 --- a/extensions/Helpers.h +++ b/extensions/Helpers.h @@ -53,11 +53,14 @@ #include "VectorOperations.h" #include "Views.h" +#include "operations/norm.hpp" +#include "operations/product.hpp" #define TEST_WARNING(test) if ((test));else WARNING +namespace AMDiS { namespace extensions { + using namespace std; -using namespace AMDiS; static long random_seed_initial_value = 0; @@ -69,13 +72,13 @@ namespace Helpers { inline double cint(double x) { double intpart; if (modf(x, &intpart) >= 0.5) - return x >=0 ? ceil(x) : floor(x); + return x >=0 ? std::ceil(x) : std::floor(x); else - return x < 0 ? ceil(x) : floor(x); + return x < 0 ? std::ceil(x) : std::floor(x); } inline double round (double r, double places) { - double off = pow(10.0, places); + double off = std::pow(10.0, places); return cint(r*off)/off; } @@ -301,6 +304,8 @@ namespace Helpers { template <class LinearSolver, class Matrix, class EigenVector> inline double inverse_iteration(LinearSolver& solver, const Matrix& A, EigenVector& x, int m) { + using mtl::two_norm; using AMDiS::two_norm; + using mtl::dot; using AMDiS::dot; EigenVector y( size(x) ), res( size(x) ); double lambda = 0.0, lambda_old = 0.0, relErr; @@ -328,6 +333,8 @@ namespace Helpers { template <class LinSolver, class Matrix> inline double condition (LinSolver& solver, const Matrix& A, int m=10) { + using mtl::two_norm; using AMDiS::two_norm; + using mtl::dot; using AMDiS::dot; mtl::dense_vector<double> x(num_rows(A)), y(num_rows(A)); mtl::seed<double> seed; random(x, seed); @@ -337,8 +344,8 @@ namespace Helpers { for (int i = 0; i < m; ++i) { y = A * x; lambda_old = lambda; - lambda = mtl::dot(y,x); - relErr = abs((lambda-lambda_old)/lambda); + lambda = dot(y,x); + relErr = std::abs((lambda-lambda_old)/lambda); if (relErr < 1.e-5) break; x = y / two_norm(y) ; @@ -418,5 +425,8 @@ namespace Helpers { } // end namespace Helpers +} } + +using namespace AMDiS::extensions; #endif // EXTENSIONS_HELPERS_H diff --git a/extensions/MeshFunction_Level.h b/extensions/MeshFunction_Level.h index 313b6a36b6c20497fbb98e3b8df8098045e3868c..4646867066e5df5b5fff7604142ae33713360382 100644 --- a/extensions/MeshFunction_Level.h +++ b/extensions/MeshFunction_Level.h @@ -19,7 +19,7 @@ #ifndef EXTENSIONS_MESH_FUNCTION_LEVEL_H #define EXTENSIONS_MESH_FUNCTION_LEVEL_H -using namespace AMDiS; +namespace AMDiS { namespace extensions { /** \brief @@ -92,9 +92,9 @@ public: if (minPhase < phase && phase < maxPhase) result= lInterface; // auf dem Interface else if (phase > minOuterPhase && phase <= minPhase) - result= std::max(lOuter, static_cast<int>(floor((lOuter+lInterface)/2.0))); + result= std::max(lOuter, static_cast<int>(std::floor((lOuter+lInterface)/2.0))); else if (phase < maxOuterPhase && phase >= maxPhase) - result= std::max(lInner, static_cast<int>(floor((lInner+lInterface)/2.0))); + result= std::max(lInner, static_cast<int>(std::floor((lInner+lInterface)/2.0))); else if (phase > (minPhase+maxPhase)/2.0) result= lInner; return result; @@ -128,7 +128,7 @@ public: if (minPhase < phase && phase < maxPhase) result = lInterface; // auf dem Interface else if ((phase > minOuterPhase && phase <= minPhase) || (phase < maxOuterPhase && phase >= maxPhase)) - result = std::max(lInner, static_cast<int>(floor((lOuter+lInterface)/2.0))); + result = std::max(lInner, static_cast<int>(std::floor((lOuter+lInterface)/2.0))); else if (phase > 0.5) result = lInner; @@ -138,7 +138,7 @@ public: minDist = std::min(minDist, norm(points[i]-x)); } double lambda = std::max(0.0, 1.0 - minDist/radius); - result = std::max(result, static_cast<int>(floor(lOuter+lambda*(lPoints-lOuter)))); + result = std::max(result, static_cast<int>(std::floor(lOuter+lambda*(lPoints-lOuter)))); return result; } @@ -183,7 +183,7 @@ public: } int result = lInner; double lambda = std::max(0.0, 1.0 - minDist/radius); - result = std::max(result, static_cast<int>(floor(lInner+lambda*(lPoints-lInner)))); + result = std::max(result, static_cast<int>(std::floor(lInner+lambda*(lPoints-lInner)))); return result; } @@ -228,7 +228,7 @@ public: localResult= lInner; // im Innern des Gebietes if (((phases[i] > minOuterPhase && phases[i] <= minPhase) || (phases[i] < maxOuterPhase && phases[i] >= maxPhase)) && (i < 1 || phases[i-1] > 0.5)) - localResult= static_cast<int>(floor((lInner + lInterface) / 2.0)); + localResult= static_cast<int>(std::floor((lInner + lInterface) / 2.0)); result= std::max(result, localResult); } return result; @@ -308,10 +308,10 @@ public: result= lInterface; // auf dem Interface else if (std::abs(dist) < fadeOutWidth+interfaceWidth && signInInnerDomain*dist < 0.0) { double lambda = std::abs(dist)/fadeOutWidth - interfaceWidth/fadeOutWidth; - result= static_cast<int>(floor(lambda*lInner+(1.0-lambda)*lInterface)); + result= static_cast<int>(std::floor(lambda*lInner+(1.0-lambda)*lInterface)); } else if (std::abs(dist) < fadeOutWidth+interfaceWidth && signInInnerDomain*dist > 0.0) { double lambda = std::abs(dist)/fadeOutWidth - interfaceWidth/fadeOutWidth; - result= static_cast<int>(floor(lambda*lOuter+(1.0-lambda)*lInterface)); + result= static_cast<int>(std::floor(lambda*lOuter+(1.0-lambda)*lInterface)); } else if (signInInnerDomain*dist < 0.0) result= lInner; return result; @@ -341,4 +341,6 @@ public: } }; +} } + #endif // EXTENSIONS_MESH_FUNCTION_LEVEL_H diff --git a/extensions/MeshIndicator.h b/extensions/MeshIndicator.h index 9e19ae567db4a77c0fd07ef7ba910614025189c4..2d9332284ffffd52945420056bf2067e33e29fd2 100644 --- a/extensions/MeshIndicator.h +++ b/extensions/MeshIndicator.h @@ -20,6 +20,7 @@ #define EXTENSIONS_MESH_INDICATOR_H #include "AMDiS.h" +#include "Helpers.h" using namespace AMDiS; @@ -98,9 +99,9 @@ namespace tools { elInfo = stack.traverseNext(elInfo); } - #ifdef HAVE_PARALLEL_DOMAIN_AMDIS - mpi::globalAdd(value); - #endif +#ifdef HAVE_PARALLEL_DOMAIN_AMDIS + Parallel::mpi::globalAdd(value); +#endif return value; } @@ -141,7 +142,7 @@ namespace tools { } #ifdef HAVE_PARALLEL_DOMAIN_AMDIS - mpi::globalAdd(value); + Parallel::mpi::globalAdd(value); #endif return value; @@ -183,7 +184,7 @@ namespace tools { } #ifdef HAVE_PARALLEL_DOMAIN_AMDIS - mpi::globalAdd(value); + Parallel::mpi::globalAdd(value); #endif return value; @@ -228,7 +229,7 @@ namespace tools { } #ifdef HAVE_PARALLEL_DOMAIN_AMDIS - mpi::globalAdd(value); + Parallel::mpi::globalAdd(value); #endif return value; @@ -277,7 +278,7 @@ namespace tools { } #ifdef HAVE_PARALLEL_DOMAIN_AMDIS - mpi::globalAdd(value); + Parallel::mpi::globalAdd(value); #endif return value; @@ -322,7 +323,7 @@ namespace tools { } #ifdef HAVE_PARALLEL_DOMAIN_AMDIS - mpi::globalAdd(value); + Parallel::mpi::globalAdd(value); #endif return value; @@ -371,7 +372,7 @@ namespace tools { } #ifdef HAVE_PARALLEL_DOMAIN_AMDIS - mpi::globalAdd(value); + Parallel::mpi::globalAdd(value); #endif return value; diff --git a/extensions/MetaTools.h b/extensions/MetaTools.h index 1ec279ca1c6c5754fc8b5dac2269131235b872ad..c34427e440076dcbcb23757864e8e79d014ca973 100644 --- a/extensions/MetaTools.h +++ b/extensions/MetaTools.h @@ -33,6 +33,8 @@ // } // } +namespace AMDiS { namespace extensions { + namespace tools { /** @@ -445,7 +447,7 @@ namespace tools { #endif // ______________________________________________________________________________________________________ // for loops: for<i, n [,{incr,decr}]>, for<mpl::range_c>, for<mpl::vector_c> - +#if 0 template<int I> struct incr { BOOST_STATIC_CONSTANT(int, value = I+1); }; template<int I> struct decr { BOOST_STATIC_CONSTANT(int, value = I-1); }; @@ -515,7 +517,7 @@ namespace tools { { static void loop() { FOR_SUBSEQ<Seq, 0, boost::mpl::size<Seq>::value, F>::loop(); } }; - +#endif //____________________________________________________________________________ // for-each loops @@ -563,4 +565,6 @@ namespace tools { } // namespace tools +} } + #endif // EXTENSIONS_META_TOOLS_H diff --git a/extensions/NewtonCotesQuad.h b/extensions/NewtonCotesQuad.h index e32fbe695ec571dcf32a1db53e940af2e6c04b08..a6739e0bf9ad9d5763ab5221097a3cf77011e257 100644 --- a/extensions/NewtonCotesQuad.h +++ b/extensions/NewtonCotesQuad.h @@ -22,6 +22,8 @@ #include <boost/array.hpp> #include "Tools.h" +namespace AMDiS { namespace extensions { + namespace tools { template<int deg> @@ -61,7 +63,7 @@ namespace tools { static type& provide() { - static Container xi = {{-0.5/sqrt(3.0)+0.5, 0.5/sqrt(3.0)+0.5}}; + static Container xi = {{-0.5/std::sqrt(3.0)+0.5, 0.5/std::sqrt(3.0)+0.5}}; static Container ci = {{0.5, 0.5}}; return *(new type(xi,ci)); } @@ -75,7 +77,7 @@ namespace tools { static type& provide() { - static Container xi = {{-0.5/sqrt(3.0)+0.5, 0.5/sqrt(3.0)+0.5}}; + static Container xi = {{-0.5/std::sqrt(3.0)+0.5, 0.5/std::sqrt(3.0)+0.5}}; static Container ci = {{0.5, 0.5}}; return *(new type(xi,ci)); } @@ -89,7 +91,7 @@ namespace tools { static type& provide() { - static Container xi = {{-sqrt(3.0/5.0)/2.0+0.5, 0.5, sqrt(3.0/5.0)/2.0+0.5}}; + static Container xi = {{-std::sqrt(3.0/5.0)/2.0+0.5, 0.5, std::sqrt(3.0/5.0)/2.0+0.5}}; static Container ci = {{5.0/18.0, 8.0/18.0, 5.0/18.0}}; return *(new type(xi,ci)); } @@ -103,7 +105,7 @@ namespace tools { static type& provide() { - static Container xi = {{-sqrt(3.0/5.0)/2.0+0.5, 0.5, sqrt(3.0/5.0)/2.0+0.5}}; + static Container xi = {{-std::sqrt(3.0/5.0)/2.0+0.5, 0.5, std::sqrt(3.0/5.0)/2.0+0.5}}; static Container ci = {{5.0/18.0, 8.0/18.0, 5.0/18.0}}; return *(new type(xi,ci)); } @@ -117,14 +119,14 @@ namespace tools { static type& provide() { - static Container xi = {{-sqrt(3.0/7.0 + 2.0/7.0 * sqrt(6.0/5.0))/2.0 + 0.5, - -sqrt(3.0/7.0 - 2.0/7.0 * sqrt(6.0/5.0))/2.0 + 0.5, - sqrt(3.0/7.0 - 2.0/7.0 * sqrt(6.0/5.0))/2.0 + 0.5, - sqrt(3.0/7.0 + 2.0/7.0 * sqrt(6.0/5.0))/2.0 + 0.5}}; - static Container ci = {{(18.0-sqrt(30.0))/72.0, - (18.0+sqrt(30.0))/72.0, - (18.0+sqrt(30.0))/72.0, - (18.0-sqrt(30.0))/72.0}}; + static Container xi = {{-std::sqrt(3.0/7.0 + 2.0/7.0 * std::sqrt(6.0/5.0))/2.0 + 0.5, + -std::sqrt(3.0/7.0 - 2.0/7.0 * std::sqrt(6.0/5.0))/2.0 + 0.5, + std::sqrt(3.0/7.0 - 2.0/7.0 * std::sqrt(6.0/5.0))/2.0 + 0.5, + std::sqrt(3.0/7.0 + 2.0/7.0 * std::sqrt(6.0/5.0))/2.0 + 0.5}}; + static Container ci = {{(18.0-std::sqrt(30.0))/72.0, + (18.0+std::sqrt(30.0))/72.0, + (18.0+std::sqrt(30.0))/72.0, + (18.0-std::sqrt(30.0))/72.0}}; return *(new type(xi,ci)); } }; @@ -137,18 +139,20 @@ namespace tools { static type& provide() { - static Container xi = {{-sqrt(3.0/7.0 + 2.0/7.0 * sqrt(6.0/5.0))/2.0 + 0.5, - -sqrt(3.0/7.0 - 2.0/7.0 * sqrt(6.0/5.0))/2.0 + 0.5, - sqrt(3.0/7.0 - 2.0/7.0 * sqrt(6.0/5.0))/2.0 + 0.5, - sqrt(3.0/7.0 + 2.0/7.0 * sqrt(6.0/5.0))/2.0 + 0.5}}; - static Container ci = {{(18.0-sqrt(30.0))/72.0, - (18.0+sqrt(30.0))/72.0, - (18.0+sqrt(30.0))/72.0, - (18.0-sqrt(30.0))/72.0}}; + static Container xi = {{-std::sqrt(3.0/7.0 + 2.0/7.0 * std::sqrt(6.0/5.0))/2.0 + 0.5, + -std::sqrt(3.0/7.0 - 2.0/7.0 * std::sqrt(6.0/5.0))/2.0 + 0.5, + std::sqrt(3.0/7.0 - 2.0/7.0 * std::sqrt(6.0/5.0))/2.0 + 0.5, + std::sqrt(3.0/7.0 + 2.0/7.0 * std::sqrt(6.0/5.0))/2.0 + 0.5}}; + static Container ci = {{(18.0-std::sqrt(30.0))/72.0, + (18.0+std::sqrt(30.0))/72.0, + (18.0+std::sqrt(30.0))/72.0, + (18.0-std::sqrt(30.0))/72.0}}; return *(new type(xi,ci)); } }; } // end namespace +} } + #endif // EXTENSIONS_NEWTON_COTES_QUAD_H diff --git a/extensions/POperators.cc b/extensions/POperators.cc index 3cb94ed407a40b156aa4c0a56df4223ff1be8104..97f1c8200b29163ea1718f0dff9de73d7ab773c8 100644 --- a/extensions/POperators.cc +++ b/extensions/POperators.cc @@ -19,8 +19,9 @@ #include "POperators.h" #include "Helpers.h" +namespace AMDiS { namespace extensions { + using namespace std; -using namespace AMDiS; Phase_SOT::Phase_SOT(DOFVectorBase<double>* phaseDV_, double fac_) : SecondOrderTerm(phaseDV_->getFeSpace()->getBasisFcts()->getDegree()), @@ -1354,3 +1355,5 @@ void VecGrad2_FOT::eval(int nPoints, } } } + +} } diff --git a/extensions/POperators_FOT.h b/extensions/POperators_FOT.h index edb9ce4a23449d305331b457ff5300cf88dbf8f3..92e83b36feb1331a66a535188a0213ab12011440 100644 --- a/extensions/POperators_FOT.h +++ b/extensions/POperators_FOT.h @@ -21,8 +21,9 @@ #include "AMDiS.h" +namespace AMDiS { namespace extensions { + using namespace std; -using namespace AMDiS; /// < factor*phase*grad(u) , grad(psi) > @@ -439,5 +440,6 @@ protected: TertiaryAbstractFunction<WorldVector<double>, double, WorldVector<double>, WorldVector<double> > *vecFct; }; +} } #endif // EXTENSIONS_P_OPERATORS_FOT_H diff --git a/extensions/POperators_SOT.h b/extensions/POperators_SOT.h index 95a84f98fa89b0833287f516edbc83d23568abb9..431e75cec8e73f1511766a671a754ca6c9b69ad1 100644 --- a/extensions/POperators_SOT.h +++ b/extensions/POperators_SOT.h @@ -21,8 +21,9 @@ #include "AMDiS.h" +namespace AMDiS { namespace extensions { + using namespace std; -using namespace AMDiS; /// < factor*phase*grad(u) , grad(psi) > class Phase_SOT : public SecondOrderTerm @@ -178,5 +179,6 @@ double fac; bool symmetric; }; +} } #endif // EXTENSIONS_P_OPERATORS_SOT_H diff --git a/extensions/POperators_ZOT.h b/extensions/POperators_ZOT.h index 72d35e7bf2d001c1a72599c50b95ee6c03fcf9d3..8547c7756fb67af6b40142f965ba6af4b06cb9c3 100644 --- a/extensions/POperators_ZOT.h +++ b/extensions/POperators_ZOT.h @@ -21,8 +21,9 @@ #include "AMDiS.h" +namespace AMDiS { namespace extensions { + using namespace std; -using namespace AMDiS; /// < factor*phase*u , psi > class Phase_ZOT : public ZeroOrderTerm @@ -348,4 +349,6 @@ private: int component; }; +} } + #endif // EXTENSIONS_P_OPERATORS_ZOT_H diff --git a/extensions/PhaseFieldConvert.h b/extensions/PhaseFieldConvert.h index 9fcade42f23c4117eed5c5bdd2bb9197d382768d..204a01c4e8cb17a4ba0ff0537e518f6216bc233e 100644 --- a/extensions/PhaseFieldConvert.h +++ b/extensions/PhaseFieldConvert.h @@ -21,17 +21,17 @@ #include "Helpers.h" -using namespace AMDiS; +namespace AMDiS { namespace extensions { /// \brief /// Converts an AbstractFunction <i>dist</i>, that describes a signed distance function, to -/// a phasefield function <i>p</i>, by \f$ \frac{1}{2}(1 - tanh(s \cdot dist(x) / \epsilon))\f$ +/// a phasefield function <i>p</i>, by \f$ \frac{1}{2}(1 - std::tanh(s \cdot dist(x) / \epsilon))\f$ /// struct SignedDistFctToPhaseField : AbstractFunction<double, WorldVector<double> > { SignedDistFctToPhaseField(double epsilon_, AbstractFunction<double,WorldVector<double> > *dist_, - double scalingFactor_ = 1.0/sqrt(2.0)) + double scalingFactor_ = 1.0/std::sqrt(2.0)) : AbstractFunction<double, WorldVector<double> >(6), epsilon(epsilon_), dist(dist_), @@ -39,7 +39,7 @@ struct SignedDistFctToPhaseField : AbstractFunction<double, WorldVector<double> double operator()(const WorldVector<double> &x) const { - return 0.5 * (1.0 - tanh(scalingFactor * (*dist)(x) / epsilon)); + return 0.5 * (1.0 - std::tanh(scalingFactor * (*dist)(x) / epsilon)); } private: @@ -52,12 +52,12 @@ private: /// \brief /// Converts a DOFVector, that describes a signed distance function, to -/// a phasefield function <i>p</i>, by \f$ \frac{1}{2}(1 - tanh(s \cdot dist / \epsilon))\f$. +/// a phasefield function <i>p</i>, by \f$ \frac{1}{2}(1 - std::tanh(s \cdot dist / \epsilon))\f$. /// You have to use <i>transformDOF</i> to apply this function to the DOFVector <i>dist</i>. /// struct SignedDistToPhaseField : AbstractFunction<double, double> { - SignedDistToPhaseField(double epsilon_ = -1.0, double scalingFactor_ = 1.0/sqrt(2.0)) + SignedDistToPhaseField(double epsilon_ = -1.0, double scalingFactor_ = 1.0/std::sqrt(2.0)) : AbstractFunction<double, double>(6), epsilon(epsilon_), scalingFactor(scalingFactor_) @@ -68,7 +68,7 @@ struct SignedDistToPhaseField : AbstractFunction<double, double> double operator()(const double &dist) const { - return 0.5 * (1.0 - tanh(scalingFactor * dist / epsilon)); + return 0.5 * (1.0 - std::tanh(scalingFactor * dist / epsilon)); } private: @@ -79,12 +79,12 @@ private: /// \brief /// Converts a DOFVector, that describes a signed distance function, to -/// a phasefield function <i>p</i> with values in [-1,1], by \f$ - tanh(s \cdot dist / \epsilon)\f$. +/// a phasefield function <i>p</i> with values in [-1,1], by \f$ - std::tanh(s \cdot dist / \epsilon)\f$. /// You have to use <i>transformDOF</i> to apply this function to the DOFVector <i>dist</i>. /// struct SignedDistToCh : AbstractFunction<double, double> { - SignedDistToCh(double epsilon_ = -1.0, double scalingFactor_ = 1.0/sqrt(2.0)) + SignedDistToCh(double epsilon_ = -1.0, double scalingFactor_ = 1.0/std::sqrt(2.0)) : AbstractFunction<double, double>(6), epsilon(epsilon_), scalingFactor(scalingFactor_) @@ -95,7 +95,7 @@ struct SignedDistToCh : AbstractFunction<double, double> double operator()(const double &dist) const { - return -tanh(scalingFactor * dist / epsilon); + return -std::tanh(scalingFactor * dist / epsilon); } private: @@ -106,7 +106,7 @@ private: /// \brief /// Converts a vector of AbstractFunctions <i>{dist_i}</i>, that describe signed distance functions, to -/// a phasefield function <i>p</i>, by \f$ \frac{1}{2}(1 - tanh(s \cdot \min_i(dist_i(x)) / \epsilon))\f$. +/// a phasefield function <i>p</i>, by \f$ \frac{1}{2}(1 - std::tanh(s \cdot \min_i(dist_i(x)) / \epsilon))\f$. /// The minimum of all distance function describes the union of the areas of negative values, of the /// distance functions. /// @@ -114,7 +114,7 @@ struct SignedDistFctListToPhaseField : AbstractFunction<double, WorldVector<doub { SignedDistFctListToPhaseField(double epsilon_, std::vector<AbstractFunction<double,WorldVector<double> >*> dist_, - double scalingFactor_ = 1.0/sqrt(2.0)) + double scalingFactor_ = 1.0/std::sqrt(2.0)) : AbstractFunction<double, WorldVector<double> >(6), epsilon(epsilon_), dist(dist_), @@ -126,7 +126,7 @@ struct SignedDistFctListToPhaseField : AbstractFunction<double, WorldVector<doub for (size_t i = 0; i < dist.size(); ++i) { d = std::min((*(dist[i]))(x), d); } - return 0.5 * (1.0 - tanh(scalingFactor * d / epsilon)); + return 0.5 * (1.0 - std::tanh(scalingFactor * d / epsilon)); } private: @@ -162,7 +162,7 @@ private: void operator()(const AbstractFunction<double,WorldVector<double> >* v) const { - val = max((*v)(x), val); + val = std::max((*v)(x), val); } void setX(const WorldVector<double> &x_) const @@ -186,7 +186,7 @@ private: /// struct PhaseFieldToSignedDist : AbstractFunction<double, double> { - PhaseFieldToSignedDist(double epsilon_= -1.0, double scalingFactor_ = 1.0/sqrt(2.0)) + PhaseFieldToSignedDist(double epsilon_= -1.0, double scalingFactor_ = 1.0/std::sqrt(2.0)) : AbstractFunction<double, double>(6), epsilon(epsilon_), scalingFactor(scalingFactor_) @@ -238,4 +238,8 @@ struct PhaseFieldToCh : AbstractFunction<double, double> } }; +} } + +using namespace AMDiS::extensions; + #endif // EXTENSIONS_PHASE_FIELD_CONVERT_H diff --git a/extensions/ProblemStatMassConserve.h b/extensions/ProblemStatMassConserve.h index e1512f25fb9316d42c75e3984a73d06886745d1e..4daee757b14fcf970a0fe5841e2c33c16f337591 100644 --- a/extensions/ProblemStatMassConserve.h +++ b/extensions/ProblemStatMassConserve.h @@ -22,12 +22,16 @@ #define PROBLEM_STAT_MASS_CONSERVE #include "ExtendedProblemStat.h" +#include "Refinement.h" +#include <boost/lexical_cast.hpp> + +namespace AMDiS { /// Implementation of ProblemStat to allow for the conservation of mass of one /// solution component, i.e. project the old-solution to the new mesh so that /// the scalar-product is conserved: \f$ (u^*, v) = (u^\text{old}, v) \f$, where \f$ u^*,v \f$ live on the /// new mesh and \f$ u^\text{old} \f$ lives on the old mesh. -struct ProblemStatMassConserve : public ExtendedProblemStat +struct ProblemStatMassConserve : public ExtendedProblemStat, public StandardRefineOperation { /// constructor: create a temporary problem that is initialized with /// similar parameters as the regular one, except one additional component @@ -110,7 +114,7 @@ struct ProblemStatMassConserve : public ExtendedProblemStat for (int i = 1; i < prob2->getNumComponents(); i++) { refSet = -1; - Parameters::get(name + "_tmp->refinement set[" + lexical_cast<string>(i) + "]", + Parameters::get(name + "_tmp->refinement set[" + boost::lexical_cast<string>(i) + "]", refSet); if (refSet < 0) refSet = 0; @@ -242,6 +246,7 @@ struct ProblemStatMassConserve : public ExtendedProblemStat // assemble only one block of the system prob2->addMatrixOperator(*opMnew0,0,0); + prob2->addMatrixOperator(*opMnew0,1,1); prob2->addVectorOperator(*opMold01, 0); } @@ -256,4 +261,6 @@ private: int comp; }; +} + #endif // PROBLEM_STAT_MASS_CONSERVE \ No newline at end of file diff --git a/extensions/ProblemStatMassConserve2.h b/extensions/ProblemStatMassConserve2.h index 9ede8bfe8c304715aa4ae9fe421ff2ac56a90a86..943d4742fbad77bc996d785af567a13e7853637c 100644 --- a/extensions/ProblemStatMassConserve2.h +++ b/extensions/ProblemStatMassConserve2.h @@ -24,6 +24,8 @@ #include "ExtendedProblemStat.h" #include "Refinement.h" +namespace AMDiS { + /// Implementation of ProblemStat to allow for the conservation of mass of one /// solution component, i.e. project the old-solution to the new mesh so that /// the scalar-product is conserved: \f$ (u^*, v) = (u^\text{old}, v) \f$, where \f$ u^*,v \f$ live on the @@ -183,4 +185,6 @@ private: int comp; }; +} + #endif // PROBLEM_STAT_MASS_CONSERVE \ No newline at end of file diff --git a/extensions/Refinement.h b/extensions/Refinement.h index 7ac230a5117b9620bed5f7f1a2173ae12a9a4bce..31494603bda6ab7da558255f28a7017bf3905cf0 100644 --- a/extensions/Refinement.h +++ b/extensions/Refinement.h @@ -21,7 +21,7 @@ #include "ElementFunction.h" -using namespace AMDiS; +namespace AMDiS { namespace extensions { /** \brief @@ -43,7 +43,7 @@ public: globalSize(0) { h0 = getMacroMeshSize(mesh); - reduction = 1.0 / sqrt(2.0); // if dim==2 + reduction = 1.0 / std::sqrt(2.0); // if dim==2 } int getGlobalSize() { return globalSize; } @@ -60,12 +60,12 @@ public: protected: int hToLevel(double h) { - int level = static_cast<int>(floor(log(h / h0) / log(reduction))); + int level = static_cast<int>(std::floor(std::log(h / h0) / std::log(reduction))); return level; } double levelToH(int level) { - double h = pow(reduction,level)*h0; + double h = std::pow(reduction,level)*h0; return h; } @@ -303,8 +303,8 @@ public: return (refineH < currentH ? 1 : (refineH > currentH * (mesh->getDim() == 1 ? 2.0 : (mesh->getDim() == 2 ? - sqrt(2.0) : - sqrt(2.0)/2.0 + 0.5)) ? + std::sqrt(2.0) : + std::sqrt(2.0)/2.0 + 0.5)) ? -1 : 0)); } @@ -563,8 +563,8 @@ public: return (refineH < currentH ? 1 : (refineH > currentH * (mesh->getDim() == 1 ? 2.0 : (mesh->getDim() == 2 ? - sqrt(2.0) : - sqrt(2.0)/2.0 + 0.5)) ? + std::sqrt(2.0) : + std::sqrt(2.0)/2.0 + 0.5)) ? -1 : 0)); } @@ -615,6 +615,10 @@ protected: bool onlyRefine; }; +} } + +using namespace AMDiS::extensions; + #include "Refinement_Level.h" // #include "Refinement_MeshSize.h" diff --git a/extensions/Refinement_DOFView.h b/extensions/Refinement_DOFView.h index c50680faab1924ff755aba587c801b6437a9cbd3..dca94423da5a13be1f43024ea01577a8c804ff83 100644 --- a/extensions/Refinement_DOFView.h +++ b/extensions/Refinement_DOFView.h @@ -23,7 +23,7 @@ #include "Views.h" #include "MeshFunction_Level.h" -using namespace AMDiS; +namespace AMDiS { namespace extensions { /** \brief @@ -500,4 +500,6 @@ public: } }; +} } + #endif // EXTENSIONS_REFINEMENT_DOFVIEW_H diff --git a/extensions/Refinement_Level.h b/extensions/Refinement_Level.h index 1c3c34c1876f00cbf97fd3f3af5670944a10aa5e..b674fc66d23105958922f5a98eb6bcf247382d9a 100644 --- a/extensions/Refinement_Level.h +++ b/extensions/Refinement_Level.h @@ -21,7 +21,7 @@ #include "ElementFunction.h" -using namespace AMDiS; +namespace AMDiS { namespace extensions { class RefinementLevelSimple : public RefinementLevel<WorldVector<double>, int > @@ -452,5 +452,8 @@ private: DOFVector<double>* phase; double tol; }; + +} } + #endif // EXTENSIONS_REFINEMENT_LEVEL_PHASEFIELD_H diff --git a/extensions/Refinement_MeshSize.h b/extensions/Refinement_MeshSize.h index e9a2adb73454460846335fa40db6f343079149cc..f9474027b2bc96e07c59c86bf258cab5e606cca3 100644 --- a/extensions/Refinement_MeshSize.h +++ b/extensions/Refinement_MeshSize.h @@ -19,7 +19,7 @@ #ifndef EXTENSIONS_REFINEMENT_MESHSIZE_H #define EXTENSIONS_REFINEMENT_MESHSIZE_H -using namespace AMDiS; +namespace AMDiS { namespace extensions { /** \brief * Refinement structure to perform local anisotropic refinement depending @@ -262,4 +262,6 @@ private: std::vector<DOFVector<double>*> vecs; }; +} } + #endif // EXTENSIONS_REFINEMENT_MESHSIZE_H diff --git a/extensions/SignedDistFunctors.h b/extensions/SignedDistFunctors.h index 7278c6a550cddcc1881876c4384dbcfb47fc75ec..bb8b2e5e372790e23e865ad034db573f59940a80 100644 --- a/extensions/SignedDistFunctors.h +++ b/extensions/SignedDistFunctors.h @@ -23,8 +23,10 @@ #include "GeometryTools.h" #include "Views.h" + +namespace AMDiS { namespace extensions { + using namespace std; -using namespace AMDiS; /** * A collection of signed-dist function describing several gemoetric objects: @@ -65,9 +67,9 @@ static double signedDist2D(const WorldVector<double> x, const WorldVector<double norm_xy = norm(x_trans, eps); if (x_trans[0] >= 0.0) { - alpha = acos(x_trans[0] / norm_xy); + alpha = std::acos(x_trans[0] / norm_xy); } else { - alpha = 2.0*m_pi - acos(x_trans[0] / norm_xy); + alpha = 2.0*m_pi - std::acos(x_trans[0] / norm_xy); } return (norm_xy - (*radius)(alpha)); @@ -93,14 +95,14 @@ static double signedDist3D(const WorldVector<double> x, const WorldVector<double } norm_xyz = norm(x_trans, eps); - norm_xy = sqrt(sqr(x_trans[0]) + sqr(x_trans[1]) + sqr(eps)); + norm_xy = std::sqrt(sqr(x_trans[0]) + sqr(x_trans[1]) + sqr(eps)); if(x_trans[1]>=0) { - alpha = acos(x_trans[0]/norm_xy); + alpha = std::acos(x_trans[0]/norm_xy); } else { - alpha = 2.0*m_pi - acos(x_trans[0]/norm_xy); + alpha = 2.0*m_pi - std::acos(x_trans[0]/norm_xy); } - beta = 0.5*m_pi - atan(x_trans[2]/norm_xy); + beta = 0.5*m_pi - std::atan(x_trans[2]/norm_xy); return (norm_xyz - (*radius)(alpha, beta)); } @@ -138,7 +140,7 @@ public: radius(radius_), strength(strength_), rotation(rotation_), period(period_) {} double operator()(const double &alpha) const { - double result = 1.0 + strength * cos(period * alpha + rotation); + double result = 1.0 + strength * std::cos(period * alpha + rotation); result *= radius; return result; } @@ -158,7 +160,7 @@ public: radius(radius_), strength(strength_), period(period_) {} double operator()(const double &alpha, const double &beta) const { - double result = 1.0 + strength * (cos(period*alpha) + cos(period*beta) * cos(period*alpha)); + double result = 1.0 + strength * (std::cos(period*alpha) + std::cos(period*beta) * std::cos(period*alpha)); result *= radius; return result; } @@ -177,7 +179,7 @@ public: LemniskateRadius(const double breite_) : breite(breite_) {} double operator()(const double &alpha) const { - double result = 2*cos(2*alpha); + double result = 2*std::cos(2*alpha); result = breite*result; return result; } @@ -194,7 +196,7 @@ public: Lemniskate3D(const double breite_) : breite(breite_) {} double operator()(const double &alpha, const double &beta) const { - double result = 2*breite*cos(2*alpha)*sin(beta); + double result = 2*breite*std::cos(2*alpha)*std::sin(beta); return result; } @@ -210,8 +212,8 @@ public: a(a_), b(b_) {} double operator()(const double &alpha) const { - double x=b*cos(alpha), y=a*sin(alpha); - return a*b / sqrt(x*x+y*y); + double x=b*std::cos(alpha), y=a*std::sin(alpha); + return a*b / std::sqrt(x*x+y*y); } protected: @@ -226,11 +228,11 @@ public: a(a_), b(b_), c(c_) {} double operator()(const double &alpha, const double &beta) const { - double sa = sin(alpha), sb = sin(beta); - double ca = cos(alpha), cb = cos(beta); + double sa = std::sin(alpha), sb = std::sin(beta); + double ca = std::cos(alpha), cb = std::cos(beta); double x = a*sa*cb, y = b*sa*sb, z = c*ca; - return sqrt(x*x+y*y+z*z); + return std::sqrt(x*x+y*y+z*z); } protected: @@ -248,7 +250,7 @@ public: double operator()(const WorldVector<double>& x) const { double x_temp; - x_temp= cos(theta)*x[0] - sin(theta)*x[1]; + x_temp= std::cos(theta)*x[0] - std::sin(theta)*x[1]; return factor*(shift-x_temp); } @@ -318,7 +320,7 @@ private: }; -// simple circle: phi_0(x,y) := sqrt(x^2+y^2)-r +// simple circle: phi_0(x,y) := std::sqrt(x^2+y^2)-r class Circle : public AbstractFunction<double, WorldVector<double> > { public: @@ -333,7 +335,7 @@ public: for(int k=0; k<x.getSize(); k++) { result += sqr(x[k]-midPoint[k]); } - result = sqrt(result)-radius; + result = std::sqrt(result)-radius; return factor * result; } @@ -358,7 +360,7 @@ public: for(int k=0; k<x.getSize(); k++) { result += sqr(x[k]-midPoint[k]); } - result = sqrt(result)-radius; + result = std::sqrt(result)-radius; return -result; } @@ -391,7 +393,7 @@ public: } double minResult = 1.e10; for (size_t j=0; j<pos.size(); j++) { - minResult = std::min(minResult, sqrt(result[j])-radius); + minResult = std::min(minResult, std::sqrt(result[j])-radius); } return -minResult; } @@ -414,8 +416,8 @@ public: result1 += sqr(x[k]-pos1[k]); result2 += sqr(x[k]-pos2[k]); } - result1 = sqrt(result1)-radius; - result2 = sqrt(result2)-radius; + result1 = std::sqrt(result1)-radius; + result2 = std::sqrt(result2)-radius; return -std::min(result1,result2); } @@ -523,7 +525,7 @@ public: if(x.getSize()>2) { result+= sqr(x[2]-midPoint[2])/sqr(c); } - result = sqrt(result) - 1.0; + result = std::sqrt(result) - 1.0; return result; } @@ -545,8 +547,8 @@ public: { double result=0.0; result = sqr(x[0]-midPoint[0])+sqr(x[1]-midPoint[1]); - result = sqr(sqrt(result)-r1)+ sqr(x[2]-midPoint[2]); - result = sqrt(result)-r2; + result = sqr(std::sqrt(result)-r1)+ sqr(x[2]-midPoint[2]); + result = std::sqrt(result)-r2; return result; } @@ -616,4 +618,8 @@ private: double factor; }; +} } + +using namespace AMDiS::extensions; + #endif // EXTENSIONS_SIGNED_DIST_FUNCTORS_H diff --git a/extensions/SingularDirichletBC.h b/extensions/SingularDirichletBC.h deleted file mode 100644 index 7c4aa21ab644228ed493a2b3efbb3f8d35434fd1..0000000000000000000000000000000000000000 --- a/extensions/SingularDirichletBC.h +++ /dev/null @@ -1,556 +0,0 @@ -/****************************************************************************** - * - * Extension of AMDiS - Adaptive multidimensional simulations - * - * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. - * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis - * - * Authors: Simon Praetorius et al. - * - * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * - * See also license.opensource.txt in the distribution. - * - ******************************************************************************/ - - -#ifndef EXTENSIONS_SINGULAR_DIRICHLET_BC_H -#define EXTENSIONS_SINGULAR_DIRICHLET_BC_H - -#include "AMDiS.h" - -namespace AMDiS { - -/** - * data structure that holds DOF-Index and double value for singular dirichlet boundary condition. - **/ -struct SingularDirichletBC { - SingularDirichletBC(int i_, int j_, DegreeOfFreedom idx_, double value_) : - row(i_), col(j_), idx(idx_), value(value_) {} - - int row, col; - DegreeOfFreedom idx; - double value; -}; - -/** - * data structure that holds all periodic associations. - **/ -struct ManualPeriodicBC { - ManualPeriodicBC(size_t row_, std::vector<std::pair<DegreeOfFreedom, DegreeOfFreedom> > &indices_) : - row(row_), indices(indices_) {} - - size_t row; - std::vector<std::pair<DegreeOfFreedom, DegreeOfFreedom> > indices; -}; - -namespace details { - - inline bool dofOnFace(int dim, GeoIndex boundaryPos, int face, Element* el, ElementDofIterator& elDofIter) - { - // all DOFs on the face - if (elDofIter.getPosIndex() == boundaryPos && - elDofIter.getCurrentElementPos() == face) - return true; - - // Vertex DOFs on the face. Since position-number of the face - // is associated with the vertex opposite to the face all vertices - // with position != face number can be collected - if (elDofIter.getPosIndex() == VERTEX && - elDofIter.getCurrentElementPos() != face) - return true; - - // in 3d the DOFs on the edges on the face must be collected - if (dim == 3) { - if (elDofIter.getPosIndex() == EDGE) { - int localEdge = elDofIter.getCurrentElementPos(); - if (el->getEdgeOfFace(face,0) == localEdge || - el->getEdgeOfFace(face,1) == localEdge || - el->getEdgeOfFace(face,2) == localEdge) - return true; - } - } - - return false; - } - - - /** - * traverses the mesh and stores all DegreeOfFreedom, that lie on the boundary with index 'nr' - * and have coordinates that give true in the 'meshIndicator', into a vector of 'indices'. - **/ - inline void getBoundaryIndices(const FiniteElemSpace* feSpace, - BoundaryType nr, - AbstractFunction<bool, WorldVector<double> >* meshIndicator, - std::set<DegreeOfFreedom> &indices) - { - Mesh* mesh = feSpace->getMesh(); - int dim = mesh->getDim(); - const BasisFunction *basFcts = feSpace->getBasisFcts(); - int numBasFcts = basFcts->getNumber(); - std::vector<DegreeOfFreedom> localIndices(numBasFcts); - - ElementDofIterator elDofIter(feSpace, true); - GeoIndex boundaryPos = (dim == 1 ? VERTEX : (dim == 2 ? EDGE : FACE)); - - indices.clear(); - - WorldVector<double> coord; - TraverseStack stack; - ElInfo *elInfo = stack.traverseFirst(mesh, -1, - Mesh::CALL_LEAF_EL | Mesh::FILL_BOUND | Mesh::FILL_COORDS); - while (elInfo) { - for (int face = 0; face < dim + 1; face++) { - if (elInfo->getBoundary(face) == nr) { - if (!meshIndicator) { - elDofIter.reset(elInfo->getElement()); - do { - if (dofOnFace(dim, boundaryPos, face, elInfo->getElement(), elDofIter)) - indices.insert(elDofIter.getDof()); - } while (elDofIter.next()); - } else { - basFcts->getLocalIndices(elInfo->getElement(), feSpace->getAdmin(), localIndices); - for (int i = 0; i < numBasFcts; i++) { - elInfo->coordToWorld(*(basFcts->getCoords(i)), coord); - if ((*meshIndicator)(coord)) - indices.insert(localIndices[i]); - } - } - break; - } - } - - elInfo = stack.traverseNext(elInfo); - } - } - - /** - * traverses the mesh and stores all DegreeOfFreedom, that have coordinates that give true - * in the 'meshIndicator', into a vector of 'indices'. - **/ - inline void getBoundaryIndices(const FiniteElemSpace* feSpace, - AbstractFunction<bool, WorldVector<double> >* meshIndicator, - std::set<DegreeOfFreedom> &indices) - { - Mesh* mesh = feSpace->getMesh(); - int dim = mesh->getDim(); - const BasisFunction *basFcts = feSpace->getBasisFcts(); - int numBasFcts = basFcts->getNumber(); - std::vector<DegreeOfFreedom> localIndices(numBasFcts); - - indices.clear(); - - WorldVector<double> coord; - TraverseStack stack; - ElInfo *elInfo = stack.traverseFirst(mesh, -1, - Mesh::CALL_LEAF_EL | Mesh::FILL_BOUND | Mesh::FILL_COORDS); - while (elInfo) { - for (int face = 0; face < dim + 1; face++) { - if (elInfo->getBoundary(face) != 0) { - basFcts->getLocalIndices(elInfo->getElement(), feSpace->getAdmin(), localIndices); - - for (int i = 0; i < numBasFcts; i++) { - elInfo->coordToWorld(*(basFcts->getCoords(i)), coord); - if ((*meshIndicator)(coord)) - indices.insert(localIndices[i]); - } - break; - } - } - - elInfo = stack.traverseNext(elInfo); - } - } - - inline void getImplicitIndices(const FiniteElemSpace* feSpace, - AbstractFunction<double, WorldVector<double> >* signedDistFct, - std::vector<DegreeOfFreedom> &indices) - { - const BasisFunction *vecBasisFcts = feSpace->getBasisFcts(); - int nVecBasisFcts = vecBasisFcts->getNumber(); - - std::vector<DegreeOfFreedom> vecLocalIndices(nVecBasisFcts); - - DOFVector<short int> visited(feSpace, "visited"); visited.set(0); - WorldVector<double> coord; - TraverseStack stack; - Flag traverseFlag = Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS; - ElInfo *elInfo = stack.traverseFirst(feSpace->getMesh(), -1, traverseFlag); - - while (elInfo) { - Element *el = elInfo->getElement(); - vecBasisFcts->getLocalIndices(el, feSpace->getAdmin(), vecLocalIndices); - - for (int i = 0; i < nVecBasisFcts; i++) { - if ( visited[vecLocalIndices[i]] == 0 ) { - elInfo->coordToWorld(*(vecBasisFcts->getCoords(i)), coord); - if ( (*signedDistFct)(coord) <= DBL_TOL ) { // eventuell nur Koordinaten an Gitterknoten bekommen! - indices.push_back(vecLocalIndices[i]); - } - visited[vecLocalIndices[i]] = 1; - } - } - elInfo = stack.traverseNext(elInfo); - } - } - - inline void getImplicitIndices(const FiniteElemSpace* feSpace, - DOFVector<double>* signedDistDOF, - std::vector<DegreeOfFreedom> &indices) - { - - const BasisFunction *vecBasisFcts = feSpace->getBasisFcts(); - int nVecBasisFcts = vecBasisFcts->getNumber(); - - std::vector<DegreeOfFreedom> vecLocalIndices(nVecBasisFcts); - ElementVector signedDistLocalCoeffs(nVecBasisFcts); - - DimVec<double> *baryCoords = NULL; - DOFVector<short int> visited(feSpace, "visited"); visited.set(0); - TraverseStack stack; - Flag traverseFlag = Mesh::CALL_LEAF_EL; - ElInfo *elInfo = stack.traverseFirst(feSpace->getMesh(), -1, traverseFlag); - - while (elInfo) { - Element *el = elInfo->getElement(); - - vecBasisFcts->getLocalIndices(el, feSpace->getAdmin(), vecLocalIndices); - signedDistDOF->getLocalVector(el, signedDistLocalCoeffs); - - for (int i = 0; i < nVecBasisFcts; i++) { - if ( visited[vecLocalIndices[i]] == 0 ) { - baryCoords = vecBasisFcts->getCoords(i); - - double dist = vecBasisFcts->evalUh(*baryCoords, signedDistLocalCoeffs); - if (dist <= DBL_TOL) { - indices.push_back(vecLocalIndices[i]); - } - visited[vecLocalIndices[i]] = 1; - } - } - elInfo = stack.traverseNext(elInfo); - } - } - - inline void getPeriodicAssociation(const FiniteElemSpace* feSpace, - std::set<DegreeOfFreedom> indices, - AbstractFunction<WorldVector<double>, WorldVector<double> >* periodicMap, - std::vector<std::pair<DegreeOfFreedom, DegreeOfFreedom> > &association) - { - association.clear(); - - DOFVector<WorldVector<double> > coords(feSpace, "coords"); - feSpace->getMesh()->getDofIndexCoords(coords); - std::set<DegreeOfFreedom>::iterator it; - - DegreeOfFreedom idx_; - WorldVector<double> p; - for (it = indices.begin(); it != indices.end(); it++) - { - p = (*periodicMap)(coords[*it]); - TEST_EXIT(coords.getDofIdxAtPoint(p,idx_))("periodic association not found!\n"); - association.push_back(std::make_pair(std::min(*it, idx_), std::max(*it, idx_))); - } - -#if DEBUG != 0 - MSG("Nr of associations: %d\n", association.size()); -#endif - } - - - inline void getDOFValues(const FiniteElemSpace* feSpace, AbstractFunction<double, WorldVector<double> >* values, std::vector<DegreeOfFreedom> &indices, std::vector<double> &dofValues) - { - WorldVector<double> x; - for (size_t i = 0; i < indices.size(); i++) { - if (feSpace->getMesh()->getDofIndexCoords(indices[i], feSpace, x)) - dofValues.push_back((*values)(x)); - } - } - - inline void getDOFValues(const FiniteElemSpace* feSpace, DOFVector<double>* values, std::vector<DegreeOfFreedom> &indices, std::vector<double> &dofValues) - { - for (size_t i = 0; i < indices.size(); i++) { - dofValues.push_back((*values)[indices[i]]); - } - } -} // end namespace - - - -/** - * data structure that holds all possible variation of description of coords and value - * of (singular/implicit) dirichlet boundary condition. - **/ -struct DirichletBcData { - - // init order: - // row, col, posType, valueType, pos, idx, - // signedDistFct, signedDistDOF, boundary_nr, meshIndicator, val0, val1, val2 - - // pos = WorldVector - DirichletBcData(int i_, int j_, WorldVector<double> pos_, double val_) - : row(i_), col(j_), posType(0), valueType(0), - pos(pos_), idx(0), SignedDistFct(NULL), SignedDistDOF(NULL), - boundary_nr(0), meshIndicator(NULL), - val0(val_), val1(NULL), val2(NULL) {} - - DirichletBcData(int i_, int j_, WorldVector<double> pos_, DOFVector<double> &val_) - : row(i_), col(j_), posType(0), valueType(1), - pos(pos_), idx(0), SignedDistFct(NULL), SignedDistDOF(NULL), - boundary_nr(0), meshIndicator(NULL), - val0(0.0), val1(&val_), val2(NULL) {} - - DirichletBcData(int i_, int j_, WorldVector<double> pos_, AbstractFunction<double, WorldVector<double> > &val_) - : row(i_), col(j_), posType(0), valueType(2), - pos(pos_), idx(0), SignedDistFct(NULL), SignedDistDOF(NULL), - boundary_nr(0), meshIndicator(NULL), - val0(0.0), val1(NULL), val2(&val_) {} - - // pos = idx - DirichletBcData(int i_, int j_, DegreeOfFreedom idx_, double val_) - : row(i_), col(j_), posType(1), valueType(0), - idx(idx_), SignedDistFct(NULL), SignedDistDOF(NULL), - boundary_nr(0), meshIndicator(NULL), - val0(val_), val1(NULL), val2(NULL) { pos.set(0.0); } - - DirichletBcData(int i_, int j_, DegreeOfFreedom idx_, DOFVector<double> &val_) - : row(i_), col(j_), posType(1), valueType(1), - idx(idx_), SignedDistFct(NULL), SignedDistDOF(NULL), - boundary_nr(0), meshIndicator(NULL), - val0(0.0), val1(&val_), val2(NULL) { pos.set(0.0); } - - DirichletBcData(int i_, int j_, DegreeOfFreedom idx_, AbstractFunction<double, WorldVector<double> > &val_) - : row(i_), col(j_), posType(1), valueType(2), - idx(idx_), SignedDistFct(NULL), SignedDistDOF(NULL), - boundary_nr(0), meshIndicator(NULL), - val0(0.0), val1(NULL), val2(&val_) { pos.set(0.0); } - - // pos = SignedDistFct - DirichletBcData(int i_, int j_, AbstractFunction<double, WorldVector<double> > *SignedDistFct_, double val_) - : row(i_), col(j_), posType(2), valueType(0), - idx(0), SignedDistFct(SignedDistFct_), SignedDistDOF(NULL), - boundary_nr(0), meshIndicator(NULL), - val0(val_), val1(NULL), val2(NULL) { pos.set(0.0); } - - DirichletBcData(int i_, int j_, AbstractFunction<double, WorldVector<double> > *SignedDistFct_, DOFVector<double> &val_) - : row(i_), col(j_), posType(2), valueType(1), - idx(0), SignedDistFct(SignedDistFct_), SignedDistDOF(NULL), - boundary_nr(0), meshIndicator(NULL), - val0(0.0), val1(&val_), val2(NULL) { pos.set(0.0); } - - DirichletBcData(int i_, int j_, AbstractFunction<double, WorldVector<double> > *SignedDistFct_, AbstractFunction<double, WorldVector<double> > &val_) - : row(i_), col(j_), posType(2), valueType(2), - idx(0), SignedDistFct(SignedDistFct_), SignedDistDOF(NULL), - boundary_nr(0), meshIndicator(NULL), - val0(0.0), val1(NULL), val2(&val_) { pos.set(0.0); } - - // pos = SignedDistDOF - DirichletBcData(int i_, int j_, DOFVector<double> *SignedDistDOF_, double val_) - : row(i_), col(j_), posType(3), valueType(0), - idx(0), SignedDistFct(NULL), SignedDistDOF(SignedDistDOF_), - boundary_nr(0), meshIndicator(NULL), - val0(val_), val1(NULL), val2(NULL) { pos.set(0.0); } - - DirichletBcData(int i_, int j_, DOFVector<double> *SignedDistDOF_, DOFVector<double> &val_) - : row(i_), col(j_), posType(3), valueType(1), - idx(0), SignedDistFct(NULL), SignedDistDOF(SignedDistDOF_), - boundary_nr(0), meshIndicator(NULL), val0(0.0), val1(&val_), val2(NULL) { pos.set(0.0); } - - DirichletBcData(int i_, int j_, DOFVector<double> *SignedDistDOF_, AbstractFunction<double, WorldVector<double> > &val_) - : row(i_), col(j_), posType(3), valueType(2), - idx(0), SignedDistFct(NULL), SignedDistDOF(SignedDistDOF_), - boundary_nr(0), meshIndicator(NULL), - val0(0.0), val1(NULL), val2(&val_) { pos.set(0.0); } - - // pos = meshindicator + boundary_nr - DirichletBcData(int i_, int j_, BoundaryType nr, AbstractFunction<bool, WorldVector<double> > *meshIndicator_, double val_) - : row(i_), col(j_), posType(4), valueType(0), - idx(0), SignedDistFct(NULL), SignedDistDOF(NULL), - boundary_nr(nr), meshIndicator(meshIndicator_), - val0(val_), val1(NULL), val2(NULL) { pos.set(0.0); } - - DirichletBcData(int i_, int j_, BoundaryType nr, AbstractFunction<bool, WorldVector<double> > *meshIndicator_, DOFVector<double> &val_) - : row(i_), col(j_), posType(4), valueType(1), - idx(0), SignedDistFct(NULL), SignedDistDOF(NULL), - boundary_nr(nr), meshIndicator(meshIndicator_), - val0(0.0), val1(&val_), val2(NULL) { pos.set(0.0); } - - DirichletBcData(int i_, int j_, BoundaryType nr, AbstractFunction<bool, WorldVector<double> > *meshIndicator_, AbstractFunction<double, WorldVector<double> > &val_) - : row(i_), col(j_), posType(4), valueType(2), - idx(0), SignedDistFct(NULL), SignedDistDOF(NULL), - boundary_nr(nr), meshIndicator(meshIndicator_), - val0(0.0), val1(NULL), val2(&val_) { pos.set(0.0); } - - - // pos = meshindicator + boundary_nr - DirichletBcData(int i_, int j_, BoundaryTypeContainer nr, double val_) - : row(i_), col(j_), posType(4), valueType(0), - idx(0), SignedDistFct(NULL), SignedDistDOF(NULL), - boundary_nr(nr.b), meshIndicator(NULL), - val0(val_), val1(NULL), val2(NULL) { pos.set(0.0); } - - DirichletBcData(int i_, int j_, BoundaryTypeContainer nr, DOFVector<double> &val_) - : row(i_), col(j_), posType(4), valueType(1), - idx(0), SignedDistFct(NULL), SignedDistDOF(NULL), - boundary_nr(nr.b), meshIndicator(NULL), - val0(0.0), val1(&val_), val2(NULL) { pos.set(0.0); } - - DirichletBcData(int i_, int j_, BoundaryTypeContainer nr, AbstractFunction<double, WorldVector<double> > &val_) - : row(i_), col(j_), posType(4), valueType(2), - idx(0), SignedDistFct(NULL), SignedDistDOF(NULL), - boundary_nr(nr.b), meshIndicator(NULL), - val0(0.0), val1(NULL), val2(&val_) { pos.set(0.0); } - - // pos = meshindicator - DirichletBcData(int i_, int j_, AbstractFunction<bool, WorldVector<double> > *meshIndicator_, double val_) - : row(i_), col(j_), posType(4), valueType(0), - idx(0), SignedDistFct(NULL), SignedDistDOF(NULL), - boundary_nr(0), meshIndicator(meshIndicator_), - val0(val_), val1(NULL), val2(NULL) { pos.set(0.0); } - - DirichletBcData(int i_, int j_, AbstractFunction<bool, WorldVector<double> > *meshIndicator_, DOFVector<double> &val_) - : row(i_), col(j_), posType(4), valueType(1), - idx(0), SignedDistFct(NULL), SignedDistDOF(NULL), - boundary_nr(0), meshIndicator(meshIndicator_), - val0(0.0), val1(&val_), val2(NULL) { pos.set(0.0); } - - DirichletBcData(int i_, int j_, AbstractFunction<bool, WorldVector<double> > *meshIndicator_, AbstractFunction<double, WorldVector<double> > &val_) - : row(i_), col(j_), posType(4), valueType(2), - idx(0), SignedDistFct(NULL), SignedDistDOF(NULL), - boundary_nr(0), meshIndicator(meshIndicator_), - val0(0.0), val1(NULL), val2(&val_) { pos.set(0.0); } - - void addToList(const FiniteElemSpace *feSpace, std::vector<SingularDirichletBC> &list) - { - std::vector<DegreeOfFreedom> indices_; - std::vector<double> values_; - int idx_ = -1; - - switch (posType) { - case 0: // WorldVector - if (val1 == NULL && SignedDistDOF == NULL) { - val1 = new DOFVector<double>(feSpace, "vel1"); - } - if (val1 != NULL) { - if (!val1->getDofIdxAtPoint(pos, idx_)) - idx_ = -1; - } else if (SignedDistDOF != NULL) { - if (!SignedDistDOF->getDofIdxAtPoint(pos, idx_)) - idx_ = -1; - } - if (idx >= 0) - indices_.push_back(idx_); - break; - - case 1: // DegreeOfFreedom - indices_.push_back(idx); - break; - - case 2: // AbstractFunction (signedDistFct) - details::getImplicitIndices(feSpace, SignedDistFct, indices_); - break; - - case 3: // DOFVector (signedDistDOF) - details::getImplicitIndices(feSpace, SignedDistDOF, indices_); - break; - - case 4: - std::set<DegreeOfFreedom> indices__; - if (boundary_nr == 0) - details::getBoundaryIndices(feSpace, meshIndicator, indices__); - else - details::getBoundaryIndices(feSpace, boundary_nr, meshIndicator, indices__); - std::set<DegreeOfFreedom>::iterator it; - for (it = indices__.begin(); it != indices__.end(); it++) - indices_.push_back(*it); - break; - } - - switch (valueType) { - case 0: - values_.resize(indices_.size(), val0); - break; - - case 1: - details::getDOFValues(feSpace, val1, indices_, values_); - break; - - case 2: - details::getDOFValues(feSpace, val2, indices_, values_); - break; - } - - DOFVector<WorldVector<double> > coords(feSpace, "coords"); - feSpace->getMesh()->getDofIndexCoords(coords); - - - for (size_t i = 0; i < indices_.size(); i++) { - list.push_back(SingularDirichletBC(row, col, indices_[i], values_[i])); - } - -#if DEBUG != 0 - MSG("Dirichle BC at %d DOFs added.\n",indices_.size()); -#endif - } - - - int row,col; - -private: - int posType; // 0..WorldVector, 1..DegreeOfFreedom, 2..SignedDistFct, 3..signedDistDOF, 4..meshIndicator - int valueType; // 0..double, 1..DOFVector, 2..AbstractFunction - - // pos - WorldVector<double> pos; - DegreeOfFreedom idx; - AbstractFunction<double, WorldVector<double> > *SignedDistFct; - DOFVector<double> *SignedDistDOF; - - BoundaryType boundary_nr; - AbstractFunction<bool, WorldVector<double> >* meshIndicator; - - // value - double val0; - DOFVector<double> *val1; - AbstractFunction<double, WorldVector<double> > *val2; -}; - - -struct PeriodicBcData { - - // pos = WorldVector - PeriodicBcData(int row_, BoundaryType nr_, AbstractFunction<bool, WorldVector<double> >* meshIndicator_, - AbstractFunction<WorldVector<double>, WorldVector<double> >* periodicMap_) - : row(row_), nr(nr_), meshIndicator(meshIndicator_), periodicMap(periodicMap_) {} - - PeriodicBcData(int row_, AbstractFunction<bool, WorldVector<double> >* meshIndicator_, - AbstractFunction<WorldVector<double>, WorldVector<double> >* periodicMap_) - : row(row_), nr(0), meshIndicator(meshIndicator_), periodicMap(periodicMap_) {} - - void addToList(const FiniteElemSpace *feSpace, std::vector<ManualPeriodicBC> &list) - { - std::set<DegreeOfFreedom> indices; - if (nr == 0) - details::getBoundaryIndices(feSpace, meshIndicator, indices); - else - details::getBoundaryIndices(feSpace, nr, meshIndicator, indices); - - std::vector<std::pair<DegreeOfFreedom, DegreeOfFreedom> > associations; - details::getPeriodicAssociation(feSpace, indices, periodicMap, associations); - list.push_back(ManualPeriodicBC(row, associations)); - } - int row; - -protected: - - - BoundaryType nr; - AbstractFunction<bool, WorldVector<double> >* meshIndicator; - AbstractFunction<WorldVector<double>, WorldVector<double> >* periodicMap; -}; - -} // end namespace - -#endif // EXTENSIONS_SINGULAR_DIRICHLET_BC_H diff --git a/extensions/SingularDirichletBC2.cc b/extensions/SingularDirichletBC2.cc index 9c6a51c936c180835d78d3de0fd452ba73a9966b..75cd8b40fcb9b0c11d3d0a160e2f919b27f40961 100644 --- a/extensions/SingularDirichletBC2.cc +++ b/extensions/SingularDirichletBC2.cc @@ -1,6 +1,8 @@ #include "SingularDirichletBC2.h" -namespace AMDiS { namespace details { +namespace AMDiS { namespace extensions { + + namespace details { // BoundaryType template<> @@ -122,4 +124,6 @@ void getValuesAux<DOFVector<double> >( it->second = val[it->first]; } +} + } } // end namespaces diff --git a/extensions/SingularDirichletBC2.h b/extensions/SingularDirichletBC2.h index 26f88c6a0b424686cc46c26394750603ae637a29..3f506466ec9f75ea05775b6748e94aa2f35996cc 100644 --- a/extensions/SingularDirichletBC2.h +++ b/extensions/SingularDirichletBC2.h @@ -23,7 +23,7 @@ #include "boost/type_traits.hpp" #include <boost/mpl/or.hpp> -namespace AMDiS { +namespace AMDiS { namespace extensions { /** * data structure that holds DOF-Index and double value for singular dirichlet boundary condition. @@ -304,15 +304,14 @@ namespace details { } -} } // end namespace +} // end namespace // #include "SingularDirichletBC2.hh" - -namespace AMDiS { struct DirichletBcDataBase { DirichletBcDataBase(int r, int c) : row(r), col(c) {} + virtual ~DirichletBcDataBase() {}; virtual void addToList(const FiniteElemSpace *feSpace, std::vector<SingularDirichletBC> &list) = 0; int row,col; @@ -385,6 +384,6 @@ protected: AbstractFunction<WorldVector<double>, WorldVector<double> >* periodicMap; }; -} // end namespace +} } // end namespace #endif // EXTENSIONS_SINGULAR_DIRICHLET_BC2_H diff --git a/extensions/Tools.h b/extensions/Tools.h index d425adb8698e0f58770c36b353d9af19e5e24a40..bf7635a3b9b4bde3290ab744aedd6913b884d776 100644 --- a/extensions/Tools.h +++ b/extensions/Tools.h @@ -27,27 +27,9 @@ #include "MetaTools.h" #include "Helpers.h" -namespace tools { +namespace AMDiS { namespace extensions { - struct Random : AbstractFunction<double,WorldVector<double> > - { - Random(double mean_, double amplitude_) : mean(mean_), amplitude(amplitude_) - { - #ifdef HAVE_PARALLEL_DOMAIN_AMDIS - Parallel::mpi::startRand(); - #else - std::srand(Helpers::getRandomSeed()); - #endif - } - double operator()(const WorldVector<double> &x) const - { - return mean + amplitude * (std::rand() / static_cast<double>(RAND_MAX) - 0.5); - } - - private: - double mean; - double amplitude; - }; +namespace tools { /// Quadrature Rules ///____________________________________________________________________________________ @@ -220,4 +202,6 @@ namespace tools { } // end namespace +} } + #endif // EXTENSIONS_TOOLS_H diff --git a/extensions/ValueTypes.h b/extensions/ValueTypes.h index a652a4ee9b05346a1f8f8f7d07003a9d22d20cc0..18e3f152cbec2fbad87fcb0a8d7d92a626f83347 100644 --- a/extensions/ValueTypes.h +++ b/extensions/ValueTypes.h @@ -28,7 +28,7 @@ #include "boost/type_traits.hpp" -using namespace AMDiS; +namespace AMDiS { namespace extensions { template<typename T> struct DOFView; @@ -65,6 +65,6 @@ template<typename T> struct is_matrix< mtl::matrix::dense2D<T> > : public boost: template<typename T> struct is_matrix< mtl::matrix::compressed2D<T> > : public boost::true_type {}; template<typename T> struct is_matrix< WorldMatrix<T> > : public boost::true_type {}; - +} } #endif // EXTENSIONS_VALUE_TYPES_H diff --git a/extensions/VectorOperations.h b/extensions/VectorOperations.h index 31a3df3feacbb23c2f7ded055348c0d410d12b6b..e7dab6e05644a7a9398f261a2c12ba49b0af64c6 100644 --- a/extensions/VectorOperations.h +++ b/extensions/VectorOperations.h @@ -35,7 +35,13 @@ #include <boost/utility/enable_if.hpp> #include <boost/type_traits.hpp> -using namespace AMDiS; +#include "traits/size.hpp" +#include "traits/resize.hpp" +#include "traits/at.hpp" +#include "traits/num_cols.hpp" +#include "traits/num_rows.hpp" + +namespace AMDiS { namespace extensions { template<typename T> const WorldVector<T>& operator*=(WorldVector<T>& v1, const WorldVector<T>& v2) @@ -54,7 +60,7 @@ template<typename T> class compareTol : public std::binary_function<T, T, bool> { public: compareTol(double tol_) : tol(tol_) {} - bool operator()(const T &x, const T &y) const { return sqrt((x-y)*(x-y))<tol; } + bool operator()(const T &x, const T &y) const { return std::sqrt((x-y)*(x-y))<tol; } double tol; }; @@ -95,259 +101,6 @@ public: }; namespace vector_operations { - - namespace traits { - - /// General declaration, used to disable unsupported types - template <typename Collection, class Enable = void> - struct num_rows {}; - - /// size implementation for STL vectors - template <typename Value> - struct num_rows< std::vector<Value> > - { - typedef std::size_t type; - type operator()(const std::vector<Value>& v) { return v.size(); } - }; - - /// size implementation for (1D) arrays interpreted as vectors - template <typename Value, unsigned Size> - struct num_rows<Value[Size]> - { - typedef std::size_t type; - type operator()(const Value[Size]) { return Size; } - }; - - /// size implementation for (2D and higher) arrays interpreted as matrices - template <typename Value, unsigned Rows, unsigned Cols> - struct num_rows<Value[Rows][Cols]> - { - typedef std::size_t type; - type operator()(const Value[Rows][Cols]) { return Rows; } - }; - - /// size implementation for AMDiS WorldVectors - template <typename Value> - struct num_rows< WorldVector<Value> > - { - typedef std::size_t type; - type operator()(const WorldVector<Value>& v) { return static_cast<size_t>(v.getSize()); } - }; - - /// size implementation for AMDiS WorldMatrices - template <typename Value> - struct num_rows< WorldMatrix<Value> > - { - typedef std::size_t type; - type operator()(const WorldMatrix<Value>& v) { return static_cast<size_t>(v.getNumRows()); } - }; - - /// size implementation for arithmetic types (double, float, int, ...) - template <typename Value> - struct num_rows< Value, typename boost::enable_if< boost::is_arithmetic<Value> >::type > - { - typedef std::size_t type; - type operator()(const Value& v) { return 1; } - }; - - //________________________________________________________________________________ - - /// General declaration, used to disable unsupported types - template <typename Collection, class Enable = void> - struct num_cols {}; - - /// size implementation for AMDiS WorldMatrices - template <typename Value> - struct num_cols< WorldMatrix<Value> > - { - typedef std::size_t type; - type operator()(const WorldMatrix<Value>& v) { return static_cast<size_t>(v.getNumCols()); } - }; - - //________________________________________________________________________________ - - /// General declaration, used to disable unsupported types - template <typename Collection, class Enable = void> - struct resize {}; - - /// change_dim implementation for AMDiS WorldVectors - template <typename Value> - struct resize< WorldVector<Value> > - { - typedef void vector_void_type; - void operator()(WorldVector<Value>& v, size_t r) { - TEST_EXIT(Global::getGeo(WORLD) == r) - ("WorldVectors can not be resized!\n"); - } - }; - - /// change_dim implementation for STL vectors - template <typename Value> - struct resize< std::vector<Value> > - { - typedef void vector_void_type; - void operator()(std::vector<Value>& v, size_t r) { - v.resize(r); - } - }; - - /// change_dim implementation for MTL4 vectors - template <typename Value> - struct resize< mtl::dense_vector<Value> > - { - typedef void vector_void_type; - void operator()(mtl::dense_vector<Value>& v, size_t r) { - v.change_dim(r); - } - }; - - // _________________________________________________________________________________ - - /// change_dim implementation for AMDiS WorldMatrices - template <typename Value> - struct resize< WorldMatrix<Value> > - { - typedef void matrix_void_type; - void operator()(WorldMatrix<Value>& v, size_t r, size_t c) { - size_t dow = static_cast<size_t>(Global::getGeo(WORLD)); - TEST_EXIT(dow == r && dow == c) - ("WorldMatrices can not be resized!\n"); - } - }; - - /// change_dim implementation for MTL4 matrix - template <typename Value, typename Param> - struct resize< mtl::matrix::base_matrix<Value, Param> > - { - typedef void matrix_void_type; - void operator()(mtl::matrix::base_matrix<Value, Param>& v, size_t r, size_t c) { - v.change_dim(r,c); - } - }; - - /// change_dim implementation for MTL4 matrix - template <typename Value> - struct resize< mtl::matrix::dense2D<Value> > - { - typedef void matrix_void_type; - void operator()(mtl::matrix::dense2D<Value>& v, size_t r, size_t c) { - v.change_dim(r,c); - } - }; - - /// change_dim implementation for MTL4 matrix - template <typename Value> - struct resize< mtl::matrix::compressed2D<Value> > - { - typedef void matrix_void_type; - void operator()(mtl::matrix::compressed2D<Value>& v, size_t r, size_t c) { - v.change_dim(r,c); - } - }; - - // _________________________________________________________________________________ - - - /// General declaration, used to disable unsupported types - template <typename Collection, class Enable = void> - struct at {}; - - template <typename Value> - struct at< WorldMatrix<Value> > - { - typedef Value type; - type& operator()(WorldMatrix<Value>& v, size_t r, size_t c) { - return v[r][c]; - } - type const& operator()(const WorldMatrix<Value>& v, size_t r, size_t c) { - return v[r][c]; - } - }; - - template <typename Value, typename Param> - struct at< mtl::matrix::base_matrix<Value, Param> > - { - typedef Value type; - type& operator()(mtl::matrix::base_matrix<Value, Param>& v, size_t r, size_t c) { - return v(r,c); - } - type const& operator()(const mtl::matrix::base_matrix<Value, Param>& v, size_t r, size_t c) { - return v(r,c); - } - }; - - template <typename Value> - struct at< mtl::matrix::dense2D<Value> > - { - typedef Value type; - type& operator()(mtl::matrix::dense2D<Value>& v, size_t r, size_t c) { - return v(r,c); - } - type const& operator()(const mtl::matrix::dense2D<Value>& v, size_t r, size_t c) { - return v(r,c); - } - }; - - template <typename Value> - struct at< mtl::matrix::compressed2D<Value> > - { - typedef Value type; - type& operator()(mtl::matrix::compressed2D<Value>& v, size_t r, size_t c) { - return v(r,c); - } - type const& operator()(const mtl::matrix::compressed2D<Value>& v, size_t r, size_t c) { - return v(r,c); - } - }; - } - - /// num_rows function for non-MTL types (uses implicit enable_if) - template <typename Collection> - typename traits::num_rows<Collection>::type - num_rows(const Collection& c) - { - return traits::num_rows<Collection>()(c); - } - - /// num_cols function for non-MTL types (uses implicit enable_if) - template <typename Collection> - typename traits::num_cols<Collection>::type - num_cols(const Collection& c) - { - return traits::num_cols<Collection>()(c); - } - - /// resize function for vectors - template <typename Collection> - typename traits::resize<Collection>::vector_void_type - resize(Collection& c, size_t rows) - { - traits::resize<Collection>()(c, rows); - } - - /// resize function for matrices - template <typename Collection> - typename traits::resize<Collection>::matrix_void_type - resize(Collection& c, size_t rows, size_t cols) - { - traits::resize<Collection>()(c, rows, cols); - } - - /// at function for matrices - template <typename Collection> - typename traits::at<Collection>::type const& - at(const Collection& c, size_t rows, size_t cols) - { - return traits::at<Collection>()(c, rows, cols); - } - - /// at function for matrices - template <typename Collection> - typename traits::at<Collection>::type& - at(Collection& c, size_t rows, size_t cols) - { - return traits::at<Collection>()(c, rows, cols); - } // __________________________________________________________________________ @@ -360,7 +113,7 @@ namespace vector_operations { nullify(value); for (size_t i = 0; i < num_rows(b); ++i) value += sqr(b[i]); - return sqrt(value); + return std::sqrt(value); } /// 2-norm for MTL4 vectors @@ -376,7 +129,7 @@ namespace vector_operations { asum = 0.0; for (size_t i = 0; i < num_rows(M); ++i) { for (size_t j = 0; j < num_cols(M); ++j) - asum += abs(M[i][j]); + asum += std::abs(M[i][j]); } return static_cast<double>(asum); } @@ -458,7 +211,9 @@ namespace vector_operations { typename boost::enable_if< boost::mpl::and_< is_vector<VectorIn>, is_vector<VectorOut> >, void >::type copy(const VectorIn &v, VectorOut &w) { - for (size_t i = 0; i < std::min(num_rows(v), num_rows(w)); i++) + size_t s1 = size(v); + size_t s2 = size(w); + for (size_t i = 0; i < std::min(s1, s2); i++) w[i] = v[i]; } @@ -467,8 +222,8 @@ namespace vector_operations { fillMatrix(const MatrixIn &m_in, MatrixOut &m) { resize(m, num_rows(m_in), num_cols(m_in)); - for (size_t i = 0; i < num_rows(m_in); ++i) { - for (size_t j = 0; j < num_cols(m_in); ++j) { + for (size_t i = 0; i < AMDiS::num_rows(m_in); ++i) { + for (size_t j = 0; j < AMDiS::num_cols(m_in); ++j) { at(m,i,j) = at(m_in,i,j); } } @@ -612,7 +367,7 @@ namespace vector_operations { // create vector of pairs for (size_t i=0; i<vec1.size(); ++i) - order[i] = make_pair(vec1[i], vec2[i]); + order[i] = std::make_pair(vec1[i], vec2[i]); // sort vector of pairs std::sort(order.begin(), order.end(), comp); @@ -675,10 +430,10 @@ namespace vector_operations { } template<typename Vector1, typename Vector2> - typename ProductType<typename ValueType<Vector1>::type, typename ValueType<Vector2>::type>::type + typename AMDiS::traits::mult_type<typename ValueType<Vector1>::type, typename ValueType<Vector2>::type>::type dot(const Vector1 &vec1, const Vector2 &vec2) { - typedef typename ProductType<typename ValueType<Vector1>::type, typename ValueType<Vector2>::type>::type value_type; + typedef typename AMDiS::traits::mult_type<typename ValueType<Vector1>::type, typename ValueType<Vector2>::type>::type value_type; value_type value; nullify(value); size_t N = num_rows(vec1); @@ -691,4 +446,6 @@ namespace vector_operations { } } +} } + #endif // EXTENSIONS_VECTOR_OPERATIONS_H diff --git a/extensions/Views.h b/extensions/Views.h index 80b3f9502e24a2e8806fc32410abaf5e69271977..9f6b33361054934c4524c7556f00f8bf773b531e 100644 --- a/extensions/Views.h +++ b/extensions/Views.h @@ -32,7 +32,7 @@ #include "kdtree_nanoflann_dof.h" #endif -using namespace AMDiS; +namespace AMDiS { namespace extensions { /// Abstract-Function-Views /// ________________________________________________________________________________________________ @@ -160,7 +160,6 @@ struct DOFView : public DOFVector<T> { } #ifdef USE_BACKGROUNDMESH - using namespace experimental; bool use_backgroundmesh = false; Parameters::get("backgroundMesh->enabled",use_backgroundmesh); if (use_backgroundmesh) { @@ -172,7 +171,6 @@ struct DOFView : public DOFVector<T> { } #endif #ifdef USE_KD_TREE - using namespace experimental; bool use_kdtree = false; Parameters::get("KD-Tree->enabled",use_kdtree); if (use_kdtree) { @@ -181,7 +179,6 @@ struct DOFView : public DOFVector<T> { return value; } #endif - DegreeOfFreedom idx = -1; T value = value0; Mesh* mesh = feSpace->getMesh(); @@ -277,13 +274,13 @@ struct RotateView : public DOFView<T> { RotateView(DOFVector<T> &vec_, double alpha) : DOFView<T>(&vec_) { R.setDiag(1.0); - R[0][0] = cos(alpha); R[0][1] = -sin(alpha); - R[1][0] = sin(alpha); R[1][1] = cos(alpha); + R[0][0] = std::cos(alpha); R[0][1] = -std::sin(alpha); + R[1][0] = std::sin(alpha); R[1][1] = std::cos(alpha); } RotateView(DOFVector<T> *vec_, double alpha) : DOFView<T>(vec_) { R.setDiag(1.0); - R[0][0] = cos(alpha); R[0][1] = -sin(alpha); - R[1][0] = sin(alpha); R[1][1] = cos(alpha); + R[0][0] = std::cos(alpha); R[0][1] = -std::sin(alpha); + R[1][0] = std::sin(alpha); R[1][1] = std::cos(alpha); } protected: @@ -387,7 +384,6 @@ T evalAtPoint(const DOFVector<T> &obj, } #ifdef USE_BACKGROUNDMESH - using namespace experimental; bool use_backgroundmesh = false; Parameters::get("backgroundMesh->enabled",use_backgroundmesh); if (use_backgroundmesh) { @@ -399,7 +395,6 @@ T evalAtPoint(const DOFVector<T> &obj, } #endif #ifdef USE_KD_TREE - using namespace experimental; bool use_kdtree = false; Parameters::get("KD-Tree->enabled",use_kdtree); if (use_kdtree) { @@ -564,4 +559,8 @@ inline void transformDOF_coords(Vector1 &vec1, Vector2 &vec2, Vector3 &vec3, Vec } } +} } + +using namespace AMDiS::extensions; + #endif // EXTENSIONS_VIEWS_H diff --git a/extensions/VtuReader.h b/extensions/VtuReader.h deleted file mode 100644 index 1761830cd7f0c01494acf177783d5b06bbefab18..0000000000000000000000000000000000000000 --- a/extensions/VtuReader.h +++ /dev/null @@ -1,244 +0,0 @@ -/****************************************************************************** - * - * Extension of AMDiS - Adaptive multidimensional simulations - * - * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. - * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis - * - * Authors: Simon Praetorius et al. - * - * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * - * See also license.opensource.txt in the distribution. - * - ******************************************************************************/ - - -/** \file VtuReader.h */ - -#ifndef AMDIS_VTUREADER_H -#define AMDIS_VTUREADER_H - -#include <cstring> -#include "DOFVector.h" -#include "Mesh.h" -#include "boost/filesystem.hpp" -#include "pugixml.hpp" -#include "kdtree_nanoflann.h" -#include "VectorOperations.h" - -namespace AMDiS { - - namespace VtuReader { - - /// Copies the values of a VTU-file to a DOF vector. - template<typename T> - inline void readValue(std::string filename, - Mesh *mesh, - DOFVector<T> *dofVector, - std::string componentName); - - /// Copies the values of a VTU-file to a vector of DOF vectors. - template<typename T> - inline void readValue(std::string filename, - Mesh *mesh, - std::vector<DOFVector<T>*> dofVectors, - std::vector<std::string> componentNames); - - - namespace details { - - template<typename T> - struct LessPairEps - { - LessPairEps() : eps(1.e-7) {} - bool operator()(const std::pair<WorldVector<double>, T>& lhs, const std::pair<WorldVector<double>, T>& rhs) const - { - return (lhs.first.getSize()==1 ? vertexi_compare1(lhs.first, rhs.first) : - (lhs.first.getSize()==2 ? vertexi_compare2(lhs.first, rhs.first) : - (lhs.first.getSize()==3 ? vertexi_compare3(lhs.first, rhs.first) : false))); - } - bool operator()(const std::pair<WorldVector<double>, T>& lhs, const WorldVector<double>& rhs) const - { - return (lhs.first.getSize()==1 ? vertexi_compare1(lhs.first, rhs) : - (lhs.first.getSize()==2 ? vertexi_compare2(lhs.first, rhs) : - (lhs.first.getSize()==3 ? vertexi_compare3(lhs.first, rhs) : false))); - } - bool operator()(const WorldVector<double>& lhs, const std::pair<WorldVector<double>, T>& rhs) const - { - return (lhs.getSize()==1 ? vertexi_compare1(lhs, rhs.first) : - (lhs.getSize()==2 ? vertexi_compare2(lhs, rhs.first) : - (lhs.getSize()==3 ? vertexi_compare3(lhs, rhs.first) : false))); - } - bool operator()(const WorldVector<double>& lhs, const WorldVector<double>& rhs) const - { - return (lhs.getSize()==1 ? vertexi_compare1(lhs, rhs) : - (lhs.getSize()==2 ? vertexi_compare2(lhs, rhs) : - (lhs.getSize()==3 ? vertexi_compare3(lhs, rhs) : false))); - } - private: - double eps; - - //returns true if vertex lhs is "smaller" than vertex rhs - //----------------------------------------< vertexi_compare1 > - bool vertexi_compare1(const WorldVector<double> lhs, const WorldVector<double> rhs) const { - return (lhs[0]-rhs[0]>eps); - } - - //----------------------------------------< vertexi_compare2 > - bool vertexi_compare2(const WorldVector<double> lhs, const WorldVector<double> rhs) const { - return (lhs[0]-rhs[0]>eps) - || (abs(lhs[0]-rhs[0])<=eps && lhs[1]-rhs[1]>eps); - } - - //----------------------------------------< vertexi_compare3 > - bool vertexi_compare3(const WorldVector<double> lhs, const WorldVector<double> rhs) const { - return (lhs[0]-rhs[0]>eps) - || (abs(lhs[0]-rhs[0])<=eps && lhs[1]-rhs[1]>eps) - || (abs(lhs[0]-rhs[0])<=eps && abs(lhs[1]-rhs[1])<=eps - && lhs[2]-rhs[2]>eps); - } - }; - - inline void valueVector2type(std::vector<double> p, double& value) - { - if (p.size() == 0) - throw(std::runtime_error("Not enough data for assignment!\n")); - value = p[0]; - } - - inline void valueVector2type(std::vector<double> p, WorldVector<double>& value) - { - if (static_cast<int>(p.size()) != Global::getGeo(WORLD)) - throw(std::runtime_error("Not enough data for assignment!\n")); - for (int i = 0; i < Global::getGeo(WORLD); i++) - value[i] = p[i]; - } - - inline void valueVector2type(std::vector<double> p, std::vector<double>& value) - { - if (p.size() == 0) - throw(std::runtime_error("Not enough data for assignment!\n")); - for (size_t i = 0; i < p.size(); i++) - value.push_back(p[i]); - } - - inline void string2pointList(std::string& input, std::vector<WorldVector<double> >& pointList) - { - int dow = Global::getGeo(WORLD); - int dowExplicit = 3; - - std::vector<std::string> valueStringList; - std::stringstream ss(input); - std::string buf; - while (ss >> buf) - valueStringList.push_back(buf); - - pointList.clear(); - - std::vector<std::string>::iterator it; - size_t j = 0; - for (it = valueStringList.begin(); it != valueStringList.end();j++) { - WorldVector<double> p; - for (int i = 0; i < dowExplicit && it != valueStringList.end(); i++, it++) - if (i < dow) - p[i] = boost::lexical_cast<double>(*it); - pointList.push_back(p); - } - } - - template<typename T> - inline void string2valueList(std::string& input, std::vector<T>& valueList, int numComponent = 1, int numComponentMax = -1) - { - if (numComponentMax < 0) - numComponentMax = numComponent; - - std::vector<std::string> valueStringList; - std::stringstream ss(input); - std::string buf; - while (ss >> buf) - valueStringList.push_back(buf); - - valueList.clear(); - - std::vector<std::string>::iterator it; - for (it = valueStringList.begin(); it != valueStringList.end();) { - std::vector<double> p; - for (int i = 0; i < numComponentMax && it != valueStringList.end(); i++, it++) - if (i < numComponent) - p.push_back(boost::lexical_cast<double>(*it)); - T value; valueVector2type(p, value); - valueList.push_back(value); - } - } - - template<typename T> - inline void string2dataMap(std::string& strPoints, std::string& strValues, std::map<WorldVector<double>, T, LessPairEps<T> >& dataList, int numComponent = 1, int numComponentMax = -1) - { - int dow = Global::getGeo(WORLD); - int dowExplicit = 3; - if (numComponentMax < 0) - numComponentMax = numComponent; - std::string buf; - - std::vector<std::string> pointStringList; - std::stringstream ss1(strPoints); - while (ss1 >> buf) - pointStringList.push_back(buf); - - std::vector<std::string> valueStringList; - std::stringstream ss2(strValues); - while (ss2 >> buf) - valueStringList.push_back(buf); - - if (pointStringList.size()/dowExplicit != valueStringList.size()/numComponentMax) - throw(std::runtime_error("Coordinates and values do not match! nPoints=" - + boost::lexical_cast<std::string>(pointStringList.size()/dowExplicit) - + ", nValues=" - + boost::lexical_cast<std::string>(valueStringList.size()/numComponentMax))); - - std::vector<std::string>::iterator it1, it2; - it1 = pointStringList.begin(); - it2 = valueStringList.begin(); - for (; it1 != pointStringList.end() && it2 != valueStringList.end();) { - WorldVector<double> p; - for (int i = 0; i < dowExplicit && it1 != pointStringList.end(); i++, it1++) - if (i < dow) - p[i] = boost::lexical_cast<double>(*it1); - - std::vector<double> v; - for (int i = 0; i < numComponentMax && it2 != valueStringList.end(); i++, it2++) - if (i < numComponent) - v.push_back(boost::lexical_cast<double>(*it2)); - T value; valueVector2type(v, value); - - dataList[p] = value; - } - } - - // find point in mesh using KD-tree structure - inline size_t getNearestIndex(experimental::KD_Tree& tree, WorldVector<double>& x) - { - // do a knn search - const size_t num_nnp = 1; - std::vector<size_t> ret_indexes(num_nnp); - std::vector<double> out_dists_sqr(num_nnp); - - nanoflann::KNNResultSet<double> resultSet(num_nnp); - resultSet.init(&ret_indexes[0], &out_dists_sqr[0] ); - - tree.index->findNeighbors(resultSet, x.begin(), nanoflann::SearchParams(10)); - return ret_indexes[0]; - } - - } // end namespace details - - } // end namespace VtuReader - -} // end namespace AMDiS - -#include "VtuReader.hh" - -#endif // AMDIS_VTUREADER_H diff --git a/extensions/VtuReader.hh b/extensions/VtuReader.hh deleted file mode 100644 index 847e9ec916838da22ba7ce6804b019959ac87c9e..0000000000000000000000000000000000000000 --- a/extensions/VtuReader.hh +++ /dev/null @@ -1,129 +0,0 @@ -/****************************************************************************** - * - * Extension of AMDiS - Adaptive multidimensional simulations - * - * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. - * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis - * - * Authors: Simon Praetorius et al. - * - * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * - * See also license.opensource.txt in the distribution. - * - ******************************************************************************/ - - -/** \file VtuReader.hh */ - -namespace AMDiS { - - namespace VtuReader { - - /** \brief - * - * The DOF vector must have been created by a corresponding mesh file. The - * function now reads the corresponding VTU file and - * copies the values to the correct positions in the DOF vector. - */ - template<typename T> - void readValue(std::string filename, - Mesh *mesh, - DOFVector<T> *dofVector, - std::string componentName) - { - std::vector<DOFVector<T>*> dofVectors; dofVectors.push_back(dofVector); - std::vector<std::string> componentNames; componentNames.push_back(componentName); - - readValue(filename, mesh, dofVectors, componentNames); - } - - template<typename T> - void readValue(std::string filename, - Mesh *mesh, - std::vector<DOFVector<T>*> dofVectors, - std::vector<std::string> componentNames) - { - using namespace pugi; - using namespace VtuReader::details; - - FUNCNAME("VtuReader::readValue()"); - - TEST_EXIT(filename != "")("Filename not specified!\n"); - TEST_EXIT(mesh)("no mesh specified\n"); - TEST_EXIT(dofVectors.size() > 0)("no DOF vectors specified\n"); - TEST_EXIT(componentNames.size() > 0)("no componentName specified\n"); - - if(!boost::filesystem::exists(filename)) - throw(std::runtime_error(filename + " does not exist!")); - - xml_document vtu; - if(!vtu.load_file(filename.c_str())) - throw(std::runtime_error("Could not load vtu file! Error in xml structure.")); - - xml_node VTKFile = vtu.child("VTKFile"); - xml_node UnstructuredGrid = VTKFile.child("UnstructuredGrid"); - xml_node Piece = UnstructuredGrid.child("Piece"); - xml_node PointData = Piece.child("PointData"); - xml_node Points = Piece.child("Points"); - - std::string points = Points.child_value("DataArray"); - typedef std::vector<WorldVector<double> > PL; - PL pointList; - string2pointList(points, pointList); - - std::vector<std::vector<T> > valueList(dofVectors.size()); - T test; - - for (xml_node DataArray = PointData.child("DataArray"); DataArray; DataArray = DataArray.next_sibling("DataArray")) { - std::string Name = DataArray.attribute("Name").value(); - for (size_t i = 0; i < componentNames.size(); i++) { - if (Name == componentNames[i]) { - std::string values = DataArray.last_child().value(); - int nComponents = -1; - if (DataArray.attribute("NumberOfComponents")) - nComponents = DataArray.attribute("NumberOfComponents").as_int(); - if (nComponents != -1 && static_cast<int>(vector_operations::num_rows(test)) > nComponents) - throw(std::runtime_error("Can not store values in DOFVector with given value type. Too many components!")); - string2valueList(values, valueList[i], vector_operations::num_rows(test), nComponents); - break; - } - } - } - for (size_t i = 0; i < dofVectors.size(); i++) { - if (valueList[i].size() == 0) - throw(std::runtime_error("no values found for component name '"+componentNames[i]+"'!")); - if (pointList.size() != valueList[i].size()) - throw(std::runtime_error("Coordinates and values["+boost::lexical_cast<std::string>(i)+"] do not match!")); - } - - DOFVector<WorldVector<double> > coords(dofVectors[0]->getFeSpace(), "coords"); - dofVectors[0]->getFeSpace()->getMesh()->getDofIndexCoords(coords); - - experimental::KD_Tree tree(Global::getGeo(WORLD), pointList, 10); - tree.index->buildIndex(); - - DOFIterator<WorldVector<double> > it_coords(&coords, USED_DOFS); - std::vector<DOFIterator<T>*> it_results; - for (size_t i = 0; i < dofVectors.size(); i++) { - it_results.push_back(new DOFIterator<T>(dofVectors[i], USED_DOFS)); - it_results[i]->reset(); - } - for (it_coords.reset(); !it_coords.end(); ++it_coords) { - size_t idx = getNearestIndex(tree, *it_coords); - - for (size_t i = 0; i < dofVectors.size(); i++) { - if (valueList[i].size() > idx) - *(*it_results[i]) = valueList[i][idx]; - (*it_results[i])++; - } - } - - - MSG("VTU file read from: %s\n", filename.c_str()); - } - } // end namespace VtuReader - -} // end namespace diff --git a/extensions/base_problems/BaseProblem.h b/extensions/base_problems/BaseProblem.h index f51a38b4b4229b13d42d2e061657612175aa988f..30df9b87c05075cfd9d8bdc8192f791f68533d81 100644 --- a/extensions/base_problems/BaseProblem.h +++ b/extensions/base_problems/BaseProblem.h @@ -21,10 +21,9 @@ #include "AMDiS.h" #include "time/RosenbrockStationary.h" #include "CouplingTimeInterface.h" -#include "VtuReader.h" #include "pugixml.hpp" -using namespace AMDiS; +namespace AMDiS { namespace base_problems { const Flag MESH_ADOPTED = 1<<2; const Flag DATA_ADOPTED = 1<<3; @@ -144,8 +143,8 @@ public: ProblemType *getProblem(int number = 0) { - if (number < 0 || number >= getNumProblems()) - throw(std::runtime_error("problem with given number does not exist")); + TEST_EXIT(number >= 0 && number < getNumProblems()) + ("problem with given number does not exist\n"); if (number == 0) return prob; @@ -155,10 +154,8 @@ public: ProblemType *getProblem(std::string name_) { - if (name_ == "prob") - return prob; - else - throw(std::runtime_error("problem with given name '" + name_ + "' does not exist")); + TEST_EXIT(name_ == "prob")("problem with given name '%s' does not exist\n", name_.c_str()); + return prob; } void setProblem(ProblemType *prob_, bool destroy = true) @@ -229,8 +226,12 @@ private: }; -#include "BaseProblem.hh" - typedef BaseProblem<ProblemStat> StandardBaseProblem; +} } + +using namespace AMDiS::base_problems; + +#include "BaseProblem.hh" + #endif // BASE_PROBLEM_H diff --git a/extensions/base_problems/BaseProblem.hh b/extensions/base_problems/BaseProblem.hh index 73c949cb4e2d618e064ff9f9fe97bc1f83b1dd36..f727522964908de7c6731602a21fa21f853714e8 100644 --- a/extensions/base_problems/BaseProblem.hh +++ b/extensions/base_problems/BaseProblem.hh @@ -14,7 +14,8 @@ * See also license.opensource.txt in the distribution. * ******************************************************************************/ -using namespace AMDiS; + +namespace AMDiS { namespace base_problems { template<typename ProblemType> BaseProblem<ProblemType>::BaseProblem(const std::string &name_, bool createProblem_) @@ -62,7 +63,6 @@ void BaseProblem<ProblemType>::initialize(Flag initFlag, TEST_EXIT(prob)("Problem must be created! Add flag createProblem=true to constructor!\n"); prob->initialize(initFlag, adoptProblem, adoptFlag); - ProblemInstatBase::initialize(INIT_ALL); dim = getMesh()->getDim(); } @@ -72,6 +72,7 @@ Flag BaseProblem<ProblemType>::initDataFromFile(AdaptInfo *adaptInfo) { FUNCNAME("BaseProblem::initDataFromFile()"); using namespace AMDiS::io; + using namespace AMDiS::extensions; Flag initFlag; bool readDataFromFile = false; @@ -95,10 +96,6 @@ Flag BaseProblem<ProblemType>::initDataFromFile(AdaptInfo *adaptInfo) if (!file_exists(filename)) throw(std::runtime_error("The file '" + filename + "' does not exist!")); -// std::vector<DOFVector<double>*> solutions; -// for (int i = 0; i < prob->getNumComponents(); i++) -// solutions.push_back(prob->getSolution()->getDOFVector(i)); -// ArhReader::read(filename, prob->getMesh(), solutions); readFile(filename, prob->getSolution()); } else if (readFormat == "dat") @@ -111,9 +108,8 @@ Flag BaseProblem<ProblemType>::initDataFromFile(AdaptInfo *adaptInfo) std::string filename = ""; for (int i = 0; i < prob->getNumComponents(); i++) { Parameters::get(name + "->value file["+boost::lexical_cast<std::string>(i)+"]",filename); - if (!file_exists(filename)) - throw(std::runtime_error("The file '" + filename + "'does not exist!")); - ValueReader::readValue(filename,prob->getMesh(),prob->getSolution()->getDOFVector(i),prob->getMesh()->getMacroFileInfo()); + TEST_EXIT(file_exists(filename))("The file '%s'does not exist!\n", filename.c_str()); + ValueReader::readValue(filename, prob->getMesh(), prob->getSolution()->getDOFVector(i), prob->getMesh()->getMacroFileInfo()); } } else if (readFormat == "vtu") @@ -124,14 +120,14 @@ Flag BaseProblem<ProblemType>::initDataFromFile(AdaptInfo *adaptInfo) return initFlag; int arh_idx = -1, vtu_idx = -1; for (size_t i = 0; i < filenames.size(); i++) { - if (!file_exists(filenames[i])) - throw(std::runtime_error("The file '" + filenames[i] + "' does not exist!")); + TEST_EXIT(file_exists(filenames[i]))("The file '%s' does not exist!\n", (filenames[i]).c_str()); if (filenames[i].find(".vtu") != std::string::npos) vtu_idx = i; else if (filenames[i].find(".arh") != std::string::npos) arh_idx = i; - else - throw(std::runtime_error("The file '" + filenames[i] + "' must have the extension .arh or .vtu!")); + else { + ERROR_EXIT("The file '%s' must have the extension .arh or .vtu!\n", (filenames[i]).c_str()); + } } if (arh_idx >= 0) { ArhReader::read(filenames[arh_idx], prob->getMesh()); @@ -149,9 +145,10 @@ Flag BaseProblem<ProblemType>::initDataFromFile(AdaptInfo *adaptInfo) solutions.push_back(prob->getSolution()->getDOFVector(readComponents[i])); names.push_back(prob->getComponentName(readComponents[i])); } - VtuReader::readValue(filenames[vtu_idx], prob->getMesh(), solutions, names); - } else - throw(std::runtime_error("You have to specify a .vtu file!")); + VtkReader::readByName(filenames[vtu_idx], solutions, names); + } else { + ERROR_EXIT("You have to specify a .vtu file!\n"); + } } else if (readFormat == "multi-vtu") { @@ -164,14 +161,14 @@ Flag BaseProblem<ProblemType>::initDataFromFile(AdaptInfo *adaptInfo) return initFlag; int arh_idx = -1, vtu_idx = -1; for (size_t i = 0; i < filenames.size(); i++) { - if (!file_exists(filenames[i])) - throw(std::runtime_error("The file '" + filenames[i] + "' does not exist!")); + TEST_EXIT(file_exists(filenames[i]))("The file '%s' does not exist!\n", (filenames[i]).c_str()); if (filenames[i].find(".vtu") != std::string::npos) vtu_idx = i; else if (filenames[i].find(".arh") != std::string::npos) arh_idx = i; - else - throw(std::runtime_error("The file '" + filenames[i] + "' must have the extension .arh or .vtu!")); + else { + ERROR_EXIT("The file '%s' must have the extension .arh or .vtu!\n", (filenames[i]).c_str()); + } } if (arh_idx >= 0) { ArhReader::read(filenames[arh_idx], prob->getMesh()); @@ -189,13 +186,14 @@ Flag BaseProblem<ProblemType>::initDataFromFile(AdaptInfo *adaptInfo) solutions.push_back(prob->getSolution()->getDOFVector(readComponents[i])); names.push_back(prob->getComponentName(readComponents[i])); } - VtuReader::readValue(filenames[vtu_idx], prob->getMesh(), solutions, names); - } else - throw(std::runtime_error("You have to specify a .vtu file!")); + io::VtkReader::readByName(filenames[vtu_idx], solutions, names); + } else { + ERROR_EXIT("You have to specify a .vtu file!\n"); + } } } else { - throw(std::runtime_error("Parameter 'read data from file' set to 'true', but no parameter 'read format' specified!")); + ERROR_EXIT("Parameter 'read data from file' set to 'true', but no parameter 'read format' specified!\n"); } bool readPvdFromFile = false; @@ -226,8 +224,8 @@ void BaseProblem<ProblemType>::initFileWriterFromFile(AdaptInfo* adaptInfo, AMDi return; xml_document vtu; - if(!vtu.load_file((fileWriter.getFilename() + ".pvd").c_str())) - throw(std::runtime_error("Could not load pvd file! Error in xml structure.")); + TEST_EXIT(vtu.load_file((fileWriter.getFilename() + ".pvd").c_str())) + ("Could not load pvd file! Error in xml structure.\n"); xml_node VTKFile = vtu.child("VTKFile"); xml_node Collection = VTKFile.child("Collection"); @@ -349,3 +347,5 @@ void BaseProblem<ProblemType>::addTimeOperator(RosenbrockStationary *prob, int i { prob->addTimeOperator(i,j); } + +} } diff --git a/extensions/base_problems/BaseProblem_RB.h b/extensions/base_problems/BaseProblem_RB.h index 5e273519da6b4f70abf0ec144e876c0f507d3501..8af3c81f209bc30d7b0b157b51db3f389510d952 100644 --- a/extensions/base_problems/BaseProblem_RB.h +++ b/extensions/base_problems/BaseProblem_RB.h @@ -22,16 +22,14 @@ #include "BaseProblem.h" #include "time/ExtendedRosenbrockStationary.h" -using namespace AMDiS; +namespace AMDiS { namespace base_problems { -/** BaseProblems for Rosenbrock time-discretization - */ - -class BaseProblem_RB : public BaseProblem<ExtendedRosenbrockStationary> +/// BaseProblems for Rosenbrock time-discretization +class BaseProblem_RB : public BaseProblem<extensions::ExtendedRosenbrockStationary> { public: // typedefs - typedef BaseProblem<ExtendedRosenbrockStationary> super; + typedef BaseProblem<extensions::ExtendedRosenbrockStationary> super; // Rosenbrock methods //_________________________________________________________________________ @@ -95,4 +93,6 @@ protected: double minus1; }; +} } + #endif // BASE_PROBLEM_RB_H diff --git a/extensions/base_problems/BaseProblem_RB0.h b/extensions/base_problems/BaseProblem_RB0.h index fdb3c7e2a4e1729796723a3008a0f05d2eadd360..7026fb28427d793d291a2d89460a243feda2b823 100644 --- a/extensions/base_problems/BaseProblem_RB0.h +++ b/extensions/base_problems/BaseProblem_RB0.h @@ -7,11 +7,9 @@ #include "BaseProblem.h" // #include "time/ExtendedRosenbrockStationary.h" -using namespace AMDiS; - -/** BaseProblems for Rosenbrock time-discretization - */ +namespace AMDiS { namespace base_problems { +///BaseProblems for Rosenbrock time-discretization class BaseProblem_RB0 : public BaseProblem<RosenbrockStationary> { public: // typedefs @@ -60,4 +58,6 @@ protected: double minus1; }; +} } + #endif // BASE_PROBLEM_RB_H \ No newline at end of file diff --git a/extensions/base_problems/CahnHilliard.cc b/extensions/base_problems/CahnHilliard.cc index cc53abc2b1066d70bff330c90df795fb34af8a2c..f185590a8f07968f1ba7ff3d908e241021eba01f 100644 --- a/extensions/base_problems/CahnHilliard.cc +++ b/extensions/base_problems/CahnHilliard.cc @@ -1,248 +1,11 @@ -/****************************************************************************** - * - * Extension of AMDiS - Adaptive multidimensional simulations - * - * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. - * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis - * - * Authors: Simon Praetorius et al. - * - * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * - * See also license.opensource.txt in the distribution. - * - ******************************************************************************/ #include "CahnHilliard.h" -// #include "Views.h" -#include "SignedDistFunctors.h" -#include "PhaseFieldConvert.h" +#include "ProblemStat.h" +#include "ExtendedProblemStat.h" -#include "HL_SignedDistTraverse.h" -#include "Recovery.h" -#include "GenericZeroOrderTerm.h" - -using namespace AMDiS; - -namespace details { - -template<typename P> -CahnHilliard<P>::CahnHilliard(const std::string &name_) : - super(name_), - useMobility(false), - useReinit(false), - doubleWell(0), - gamma(1.0), - eps(0.1), - minusEps(-0.1), - epsInv(10.0), - minusEpsInv(-10.0), - epsSqr(0.01), - minusEpsSqr(-0.01) -{ - // parameters for CH - Parameters::get(name_ + "->use mobility", useMobility); // mobility - Parameters::get(name_ + "->gamma", gamma); // mobility - Parameters::get(name_ + "->epsilon", eps); // interface width +namespace AMDiS { namespace base_problems { - // type of double well: 0= [0,1], 1= [-1,1] - Parameters::get(name_ + "->double-well type", doubleWell); - - Parameters::get(name_ + "->use reinit", useReinit); - - // transformation of the parameters - minusEps = -eps; - epsInv = 1.0/eps; - minusEpsInv = -epsInv; - epsSqr = sqr(eps); - minusEpsSqr = -epsSqr; -} - - -template<typename P> -void CahnHilliard<P>::solveInitialProblem(AdaptInfo *adaptInfo) -{ - Flag initFlag = self::initDataFromFile(adaptInfo); - - if (!initFlag.isSet(DATA_ADOPTED)) { - int initialInterface = 0; - Initfile::get(self::name + "->initial interface", initialInterface); - double initialEps = eps; - Initfile::get(self::name + "->initial epsilon", initialEps); - - if (initialInterface == 0) { - /// horizontale Linie - double a= 0.0, dir= -1.0; - Initfile::get(self::name + "->line->pos", a); - Initfile::get(self::name + "->line->direction", dir); - self::prob->getSolution()->getDOFVector(0)->interpol(new Plane(a, dir)); - } - else if (initialInterface == 1) { - /// schraege Linie - double theta = m_pi/4.0; - self::prob->getSolution()->getDOFVector(0)->interpol(new PlaneRotation(0.0, theta, 1.0)); - transformDOFInterpolation(self::prob->getSolution()->getDOFVector(0),new PlaneRotation(0.0, -theta, -1.0), new AMDiS::Min<double>); - } - else if (initialInterface == 2) { - /// Ellipse - double a= 1.0, b= 1.0; - Initfile::get(self::name + "->ellipse->a", a); - Initfile::get(self::name + "->ellipse->b", b); - self::prob->getSolution()->getDOFVector(0)->interpol(new Ellipse(a,b)); - } - else if (initialInterface == 3) { - /// zwei horizontale Linien - double a= 0.75, b= 0.375; - Initfile::get(self::name + "->lines->pos1", a); - Initfile::get(self::name + "->lines->pos2", b); - self::prob->getSolution()->getDOFVector(0)->interpol(new Plane(a, -1.0)); - transformDOFInterpolation(self::prob->getSolution()->getDOFVector(0),new Plane(b, 1.0), new AMDiS::Max<double>); - } - else if (initialInterface == 4) { - /// Kreis - double radius= 1.0; - Initfile::get(self::name + "->kreis->radius", radius); - self::prob->getSolution()->getDOFVector(0)->interpol(new Circle(radius)); - } else if (initialInterface == 5) { - /// Rechteck - double width = 0.5; - double height = 0.3; - WorldVector<double> center; center.set(0.5); - Initfile::get(self::name + "->rectangle->width", width); - Initfile::get(self::name + "->rectangle->height", height); - Initfile::get(self::name + "->rectangle->center", center); - self::prob->getSolution()->getDOFVector(0)->interpol(new Rectangle(width, height, center)); - } - - // TODO: Redistancing einfügen! - if (useReinit) { - FiniteElemSpace* feSpace = FiniteElemSpace::provideFeSpace( - const_cast<DOFAdmin*>(self::getMesh()->getVertexAdmin()), - Lagrange::getLagrange(self::getMesh()->getDim(), 1), - self::getMesh(), - "P1"); - DOFVector<double> tmp(feSpace, "tmp"); - tmp.interpol(self::prob->getSolution()->getDOFVector(0)); - - HL_SignedDistTraverse reinit("reinit", self::getMesh()->getDim()); - reinit.calcSignedDistFct(adaptInfo, &tmp); - -#ifndef HAVE_PARALLEL_DOMAIN_AMDIS - Recovery recovery(L2_NORM, 1); - recovery.recoveryUh(&tmp, *self::prob->getSolution()->getDOFVector(0)); -#else - self::prob->getSolution()->getDOFVector(0)->interpol(&tmp); -#endif - } - - - /// create phase-field from signed-dist-function - if (doubleWell == 0) { - forEachDOF(self::prob->getSolution()->getDOFVector(0), - new SignedDistToPhaseField(initialEps)); - } else { - forEachDOF(self::prob->getSolution()->getDOFVector(0), - new SignedDistToCh(initialEps)); - } - } -} - - -template<typename P> -void CahnHilliard<P>::fillOperators() -{ - const FiniteElemSpace* feSpace = self::prob->self::getFeSpace(); - int degree = feSpace->getBasisFcts()->getDegree(); + // explicit template instantiation + template class detail::CahnHilliard<ProblemStat>; + template class detail::CahnHilliard<extensions::ExtendedProblemStat>; - DOFVector<double>* c = self::prob->getSolution()->getDOFVector(0); - DOFVector<double>* mu = self::prob->getSolution()->getDOFVector(1); - - // c - Operator *opChMnew = new Operator(feSpace, feSpace); - addZOT(opChMnew, constant(1.0)); -// opChMnew->addTerm(new Simple_ZOT); - Operator *opChMold = new Operator(feSpace, feSpace); - addZOT(opChMold, valueOf(c)); -// opChMold->addTerm(new VecAtQP_ZOT(self::prob->getSolution()->getDOFVector(0))); - // -nabla*(grad(c)) - Operator *opChL = new Operator(feSpace, feSpace); - addSOT(opChL, constant(1.0) ); -// opChL->addTerm(new Simple_SOT); - - // div(M(c)grad(mu)), with M(c)=gamma/4*(c^2-1)^2 - Operator *opChLM = new Operator(feSpace, feSpace); - if (useMobility) { - if (doubleWell == 0) - addSOT(opChLM_, function_(MobilityCH0_(gamma), valueOf(c)) ); -// opChLM->addTerm(new VecAtQP_SOT( -// self::prob->getSolution()->getDOFVector(0), -// new MobilityCH0(gamma, degree))); - else - addSOT(opChLM, function_(MobilityCH1_(gamma), valueOf(c)) ); -// opChLM->addTerm(new VecAtQP_SOT( -// self::prob->getSolution()->getDOFVector(0), -// new MobilityCH1(gamma, degree))); - } else - addSOT(opChLM, constant(gamma) ); -// opChLM->addTerm(new Simple_SOT(gamma)); - - // -2*c_old^3 + 3/2*c_old^2 - Operator *opChMPowExpl = new Operator(feSpace, feSpace); - addZOT(opChMPowExpl, -2.0 * pow<3>(valueOf(c))); -// opChMPowExpl->addTerm(new VecAtQP_ZOT( -// self::prob->getSolution()->getDOFVector(0), -// new AMDiS::Pow<3>(-2.0, 3*degree))); - if (doubleWell == 0) { - addZOT(opChMPowExpl, (3.0/2.0) * pow<2>(valueOf(c))); -// opChMPowExpl->addTerm(new VecAtQP_ZOT( -// self::prob->getSolution()->getDOFVector(0), -// new AMDiS::Pow<2>(3.0/2.0, 2*degree))); - } - - // -3*c_old^2 * c - Operator *opChMPowImpl = new Operator(feSpace, feSpace); - addZOT(opChMPowImpl, -3.0 * pow<2>(valueOf(c))); -// opChMPowImpl->addTerm(new VecAtQP_ZOT( -// self::prob->getSolution()->getDOFVector(0), -// new AMDiS::Pow<2>(-3.0, 2*degree))); - if (doubleWell == 0) { - addZOT(opChMPowImpl, 3.0 * valueOf(c) - 0.5); -// opChMPowImpl->addTerm(new VecAtQP_ZOT( -// self::prob->getSolution()->getDOFVector(0), -// NULL, 3.0)); - opChMPowImpl->addTerm(new Simple_ZOT(-0.5)); - } else { - addZOT(opChMPowImpl, constant(1.0)); -// opChMPowImpl->addZeroOrderTerm(new Simple_ZOT(1.0)); - } - - // mu + eps^2*laplace(c) + c - 3*(c_old^2)*c = -2*c_old^3 [+ BC] - // ---------------------------------------------------------------------- - self::prob->addMatrixOperator(*opChMPowImpl,0,0); /// < -3*phi*c*c_old^2 , psi > - self::prob->addMatrixOperator(*opChL,0,0, &minusEpsSqr); /// < -eps^2*phi*grad(c) , grad(psi) > - self::prob->addMatrixOperator(*opChMnew,0,1); /// < phi*mu , psi > - // . . . vectorOperators . . . . . . . . . . . . . . . - self::prob->addVectorOperator(*opChMPowExpl,0); /// < -2*phi*c_old^3 , psi > - - - // dt(c) = laplace(mu) - u*grad(c) - // ----------------------------------- - self::prob->addMatrixOperator(*opChMnew,1,0, self::getInvTau()); /// < phi*c/tau , psi > - self::prob->addMatrixOperator(*opChLM,1,1); /// < phi*grad(mu) , grad(psi) > - // . . . vectorOperators . . . . . . . . . . . . . . . - self::prob->addVectorOperator(*opChMold,1, self::getInvTau()); /// < phi*c^old/tau , psi > - -} - - -template<typename P> -void CahnHilliard<P>::finalizeData() -{ - self::setAssembleMatrixOnlyOnce_butTimestepChange(0,1); - self::setAssembleMatrixOnlyOnce_butTimestepChange(1,0); - if (!useMobility) - self::setAssembleMatrixOnlyOnce_butTimestepChange(1,1); -} - -} // end namespace details +} } diff --git a/extensions/base_problems/CahnHilliard.h b/extensions/base_problems/CahnHilliard.h index 6a4d9a29c60dd1245e450c6ce18063df23579852..e22f54b0ff8ba93d166d4f4b44c8fa3c20c4d863 100644 --- a/extensions/base_problems/CahnHilliard.h +++ b/extensions/base_problems/CahnHilliard.h @@ -21,10 +21,14 @@ #include "AMDiS.h" #include "BaseProblem.h" #include "chns.h" -#include "GenericOperatorTerm.h" +#include "operations/functors.hpp" +namespace AMDiS { namespace base_problems { + namespace detail { + struct c_; // name for the concentration component + template<typename ProblemStatType> class CahnHilliard : public BaseProblem<ProblemStatType> { @@ -74,7 +78,7 @@ namespace detail { gamma(gamma_), delta(1.e-6) { } - typedef double value_type; + typedef double result_type; int getDegree(int d0) const { return d0 * 4; } double operator()(const double &ch) const @@ -96,7 +100,7 @@ namespace detail { gamma(gamma_), delta(1.e-6) { } - typedef double value_type; + typedef double result_type; int getDegree(int d0) const { return d0 * 4; } double operator()(const double &ch) const @@ -113,9 +117,10 @@ namespace detail { } // end namespace detail -#include "CahnHilliard.hh" +typedef detail::CahnHilliard<AMDiS::ProblemStat> CahnHilliard; -typedef ::detail::CahnHilliard<AMDiS::ProblemStat> CahnHilliard; +} } +#include "CahnHilliard.hh" #endif // CAHN_HILLIARD_H diff --git a/extensions/base_problems/CahnHilliard.hh b/extensions/base_problems/CahnHilliard.hh index 11705842edc754e5940ccd93f32c3e2a9a1a46b0..2e8835a57fcfe02f1345208efcb09a486f515362 100644 --- a/extensions/base_problems/CahnHilliard.hh +++ b/extensions/base_problems/CahnHilliard.hh @@ -14,15 +14,16 @@ * See also license.opensource.txt in the distribution. * ******************************************************************************/ -// #include "CahnHilliard.h" -// #include "Views.h" + + #include "SignedDistFunctors.h" #include "PhaseFieldConvert.h" #include "HL_SignedDistTraverse.h" #include "Recovery.h" +#include "GenericOperatorTerm.h" -using namespace AMDiS; +namespace AMDiS { namespace base_problems { namespace detail { @@ -62,6 +63,7 @@ CahnHilliard<P>::CahnHilliard(const std::string &name_) : template<typename P> void CahnHilliard<P>::solveInitialProblem(AdaptInfo *adaptInfo) { + using namespace AMDiS::extensions; Flag initFlag = self::initDataFromFile(adaptInfo); if (!initFlag.isSet(DATA_ADOPTED)) { @@ -114,7 +116,6 @@ void CahnHilliard<P>::solveInitialProblem(AdaptInfo *adaptInfo) self::prob->getSolution()->getDOFVector(0)->interpol(new Rectangle(width, height, center)); } - // TODO: Redistancing einfügen! if (useReinit) { FiniteElemSpace* feSpace = FiniteElemSpace::provideFeSpace( const_cast<DOFAdmin*>(self::getMesh()->getVertexAdmin()), @@ -147,74 +148,74 @@ void CahnHilliard<P>::solveInitialProblem(AdaptInfo *adaptInfo) } } - template<typename P> void CahnHilliard<P>::fillOperators() { - const FiniteElemSpace* feSpace = self::prob->getFeSpace(); - int degree = feSpace->getBasisFcts()->getDegree(); + const FiniteElemSpace* feSpace0 = self::prob->getFeSpace(0); + const FiniteElemSpace* feSpace1 = self::prob->getFeSpace(1); DOFVector<double>* c = self::prob->getSolution()->getDOFVector(0); - DOFVector<double>* mu = self::prob->getSolution()->getDOFVector(1); +// DOFVector<double>* mu = self::prob->getSolution()->getDOFVector(1); - // c - Operator *opChMnew = new Operator(feSpace, feSpace); - addZOT(opChMnew, constant(1.0)); - Operator *opChMold = new Operator(feSpace, feSpace); - addZOT(opChMold, valueOf(c)); // -nabla*(grad(c)) - Operator *opChL = new Operator(feSpace, feSpace); - addSOT(opChL, constant(1.0) ); + Operator *opChL = new Operator(feSpace0, feSpace0); + addSOT(opChL, 1.0); // div(M(c)grad(mu)), with M(c)=gamma/4*(c^2-1)^2 - Operator *opChLM = new Operator(feSpace, feSpace); + Operator *opChLM = new Operator(feSpace1, feSpace1); if (useMobility) { if (doubleWell == 0) addSOT(opChLM, function_(MobilityCH0_(gamma), valueOf(c)) ); else addSOT(opChLM, function_(MobilityCH1_(gamma), valueOf(c)) ); } else - addSOT(opChLM, constant(gamma) ); + addSOT(opChLM, gamma ); // -2*c_old^3 + 3/2*c_old^2 - Operator *opChMPowExpl = new Operator(feSpace, feSpace); - addZOT(opChMPowExpl, -2.0 * pow<3>(valueOf(c))); - if (doubleWell == 0) - addZOT(opChMPowExpl, (3.0/2.0) * pow<2>(valueOf(c))); - - // -3*c_old^2 * c - Operator *opChMPowImpl = new Operator(feSpace, feSpace); - addZOT(opChMPowImpl, -3.0 * pow<2>(valueOf(c))); - if (doubleWell == 0) - addZOT(opChMPowImpl, 3.0 * valueOf(c) - 0.5); - else - addZOT(opChMPowImpl, constant(1.0)); + Operator *opChWExpl = new Operator(feSpace0, feSpace0); + Operator *opChWImpl = new Operator(feSpace0, feSpace0); + if (doubleWell == 0) { + addZOT(opChWExpl, -2.0*pow<3>(valueOf(c)) + 1.5*pow<2>(valueOf(c))); + addZOT(opChWImpl, -3.0*pow<2>(valueOf(c)) + 3.0*valueOf(c) - 0.5); + } else { + addZOT(opChWExpl, -2.0*pow<3>(valueOf(c))); + addZOT(opChWImpl, -3.0*pow<2>(valueOf(c)) + 1.0); + } + // mu + eps^2*laplace(c) + c - 3*(c_old^2)*c = -2*c_old^3 [+ BC] // ---------------------------------------------------------------------- - self::prob->addMatrixOperator(*opChMPowImpl,0,0); /// < -3*phi*c*c_old^2 , psi > - self::prob->addMatrixOperator(*opChL,0,0, &minusEpsSqr); /// < -eps^2*phi*grad(c) , grad(psi) > - self::prob->addMatrixOperator(*opChMnew,0,1); /// < phi*mu , psi > + self::prob->addMatrixOperator(*opChWImpl, 0, 0); /// < -3*phi*c*c_old^2 , psi > + self::prob->addMatrixOperator(*opChL, 0, 0, &minusEpsSqr, &minusEpsSqr); /// < -eps^2*phi*grad(c) , grad(psi) > // . . . vectorOperators . . . . . . . . . . . . . . . - self::prob->addVectorOperator(*opChMPowExpl,0); /// < -2*phi*c_old^3 , psi > + self::prob->addVectorOperator(*opChWExpl, 0); /// < -2*phi*c_old^3 , psi > + Operator *opM01new = new Operator(feSpace0, feSpace1); + addZOT(opM01new, 1.0); + self::prob->addMatrixOperator(*opM01new, 0, 1); /// < phi*mu , psi > // dt(c) = laplace(mu) - u*grad(c) // ----------------------------------- - self::prob->addMatrixOperator(*opChMnew,1,0, self::getInvTau()); /// < phi*c/tau , psi > - self::prob->addMatrixOperator(*opChLM,1,1); /// < phi*grad(mu) , grad(psi) > + Operator *opM10new = new Operator(feSpace1, feSpace0); + addZOT(opM10new, 1.0); + self::prob->addMatrixOperator(*opM10new, 1, 0, self::getInvTau(), self::getInvTau()); /// < phi*c/tau , psi > + self::prob->addMatrixOperator(*opChLM, 1, 1); /// < phi*grad(mu) , grad(psi) > // . . . vectorOperators . . . . . . . . . . . . . . . - self::prob->addVectorOperator(*opChMold,1, self::getInvTau()); /// < phi*c^old/tau , psi > + Operator *opChMold = new Operator(feSpace1, feSpace0); + addZOT(opChMold, valueOf(c)); + self::prob->addVectorOperator(*opChMold, 1, self::getInvTau(), self::getInvTau()); /// < phi*c^old/tau , psi > } template<typename P> void CahnHilliard<P>::finalizeData() { - self::setAssembleMatrixOnlyOnce_butTimestepChange(0,1); - self::setAssembleMatrixOnlyOnce_butTimestepChange(1,0); - if (!useMobility) - self::setAssembleMatrixOnlyOnce_butTimestepChange(1,1); +// self::setAssembleMatrixOnlyOnce_butTimestepChange(0,1); +// self::setAssembleMatrixOnlyOnce_butTimestepChange(1,0); +// if (!useMobility) +// self::setAssembleMatrixOnlyOnce_butTimestepChange(1,1); } } // end namespace detail + +} } diff --git a/extensions/base_problems/CahnHilliardNavierStokes.cc b/extensions/base_problems/CahnHilliardNavierStokes.cc index b4db1a6637e448fe57fac0b72f3dd8f602a3798b..6681a8588f01d1ffe5de5fb7a902b07ff8471cca 100644 --- a/extensions/base_problems/CahnHilliardNavierStokes.cc +++ b/extensions/base_problems/CahnHilliardNavierStokes.cc @@ -20,7 +20,7 @@ #include "PhaseFieldConvert.h" #include "POperators.h" -using namespace AMDiS; +namespace AMDiS { namespace base_problems { CahnHilliardNavierStokes::CahnHilliardNavierStokes(const std::string &name_) : super(name_), @@ -136,6 +136,8 @@ void CahnHilliardNavierStokes::transferInitialSolution(AdaptInfo *adaptInfo) void CahnHilliardNavierStokes::fillOperators() { + using namespace AMDiS::extensions; + // variable order: // (c, mu, u0, u1 [, u2], p) @@ -326,6 +328,8 @@ void CahnHilliardNavierStokes::fillOperators() void CahnHilliardNavierStokes::addLaplaceTerm(int i) { + using namespace AMDiS::extensions; + /// < alpha*[grad(u)+grad(u)^t] , grad(psi) > if (laplaceType == 1) { for (size_t j = 0; j < dow; ++j) { @@ -347,3 +351,5 @@ void CahnHilliardNavierStokes::closeTimestep(AdaptInfo *adaptInfo) fileWriter->writeFiles(adaptInfo, false); writeFiles(adaptInfo, false); } + +} } diff --git a/extensions/base_problems/CahnHilliardNavierStokes.h b/extensions/base_problems/CahnHilliardNavierStokes.h index 0a7942eca1415f0e19dacef4bc393b692023f8af..b5cb2f84d1c886b1134ffbff2e16e9dd284087ad 100644 --- a/extensions/base_problems/CahnHilliardNavierStokes.h +++ b/extensions/base_problems/CahnHilliardNavierStokes.h @@ -23,13 +23,13 @@ #include "ExtendedProblemStat.h" #include "HL_SignedDistTraverse.h" -using namespace AMDiS; +namespace AMDiS { namespace base_problems { -class CahnHilliardNavierStokes : public BaseProblem<ExtendedProblemStat> +class CahnHilliardNavierStokes : public BaseProblem<extensions::ExtendedProblemStat> { public: // definition of types - typedef BaseProblem<ExtendedProblemStat> super; + typedef BaseProblem<extensions::ExtendedProblemStat> super; public: // public methods @@ -188,4 +188,6 @@ class Pow3Functor : public AbstractFunction<double,double> double factor; }; +} } + #endif // CAHN_HILLIARD_H diff --git a/extensions/base_problems/CahnHilliardNavierStokes_RB.cc b/extensions/base_problems/CahnHilliardNavierStokes_RB.cc index 02ec13f728c94afef1e942b339c88003dd556d63..c6a0bf43f5f911e24483076eac3ad75b9f4fb7f6 100644 --- a/extensions/base_problems/CahnHilliardNavierStokes_RB.cc +++ b/extensions/base_problems/CahnHilliardNavierStokes_RB.cc @@ -20,7 +20,7 @@ #include "PhaseFieldConvert.h" #include "POperators.h" -using namespace AMDiS; +namespace AMDiS { namespace base_problems { CahnHilliardNavierStokes_RB::CahnHilliardNavierStokes_RB(const std::string &name_) : super(name_), @@ -395,3 +395,5 @@ void CahnHilliardNavierStokes_RB::closeTimestep(AdaptInfo *adaptInfo) fileWriter->writeFiles(adaptInfo, false); writeFiles(adaptInfo, false); } + +} } diff --git a/extensions/base_problems/CahnHilliardNavierStokes_RB.h b/extensions/base_problems/CahnHilliardNavierStokes_RB.h index 70fd2c4dd296d9f9ee75ae7aed9270b4fa708c32..a524247a2daf68f8cda0b824d1c13bdc6d57924d 100644 --- a/extensions/base_problems/CahnHilliardNavierStokes_RB.h +++ b/extensions/base_problems/CahnHilliardNavierStokes_RB.h @@ -22,7 +22,7 @@ #include "BaseProblem_RB.h" #include "HL_SignedDistTraverse.h" -using namespace AMDiS; +namespace AMDiS { namespace base_problems { class CahnHilliardNavierStokes_RB : public BaseProblem_RB { @@ -284,4 +284,6 @@ class DoubleWell1Diff : public AbstractFunction<double,double> double factor; }; +} } + #endif // CAHN_HILLIARD_H diff --git a/extensions/base_problems/CahnHilliardNavierStokes_TwoPhase.cc b/extensions/base_problems/CahnHilliardNavierStokes_TwoPhase.cc index 228d769d38b190b07364cd1a650de29ff3c611dd..6743b4ea2669d3b0c0754c4247febd913542a1f5 100644 --- a/extensions/base_problems/CahnHilliardNavierStokes_TwoPhase.cc +++ b/extensions/base_problems/CahnHilliardNavierStokes_TwoPhase.cc @@ -20,7 +20,7 @@ #include "PhaseFieldConvert.h" #include "POperators.h" -using namespace AMDiS; +namespace AMDiS { namespace base_problems { CahnHilliardNavierStokes_TwoPhase::CahnHilliardNavierStokes_TwoPhase(const std::string &name_) : super(name_), @@ -450,3 +450,5 @@ void CahnHilliardNavierStokes_TwoPhase::closeTimestep(AdaptInfo *adaptInfo) fileWriter->writeFiles(adaptInfo, false); writeFiles(adaptInfo, false); } + +} } diff --git a/extensions/base_problems/CahnHilliardNavierStokes_TwoPhase.h b/extensions/base_problems/CahnHilliardNavierStokes_TwoPhase.h index 15ac30ea3edb54d557966320896c2015fd51c822..a211c43e95d5a2cfcba72a0f176d23783f86b1ec 100644 --- a/extensions/base_problems/CahnHilliardNavierStokes_TwoPhase.h +++ b/extensions/base_problems/CahnHilliardNavierStokes_TwoPhase.h @@ -24,13 +24,13 @@ #include "HL_SignedDistTraverse.h" #include "chns.h" -using namespace AMDiS; +namespace AMDiS { namespace base_problems { -class CahnHilliardNavierStokes_TwoPhase : public BaseProblem<ExtendedProblemStat> +class CahnHilliardNavierStokes_TwoPhase : public BaseProblem<extensions::ExtendedProblemStat> { public: // definition of types - typedef BaseProblem<ExtendedProblemStat> super; + typedef BaseProblem<extensions::ExtendedProblemStat> super; public: // public methods @@ -108,4 +108,6 @@ protected: // protected variables FileVectorWriter *fileWriter; }; +} } + #endif // CAHN_HILLIARD_H diff --git a/extensions/base_problems/CahnHilliardNavierStokes_TwoPhase_RB.cc b/extensions/base_problems/CahnHilliardNavierStokes_TwoPhase_RB.cc index 3be87481447f0d449e054975de221b4243b49d6e..65250f50f441e009e15c013c3f46598993c725e7 100644 --- a/extensions/base_problems/CahnHilliardNavierStokes_TwoPhase_RB.cc +++ b/extensions/base_problems/CahnHilliardNavierStokes_TwoPhase_RB.cc @@ -20,7 +20,7 @@ #include "PhaseFieldConvert.h" #include "POperators.h" -using namespace AMDiS; +namespace AMDiS { namespace base_problems { CahnHilliardNavierStokes_TwoPhase_RB::CahnHilliardNavierStokes_TwoPhase_RB(const std::string &name_) : super(name_), @@ -515,3 +515,5 @@ void CahnHilliardNavierStokes_TwoPhase_RB::closeTimestep(AdaptInfo *adaptInfo) fileWriter->writeFiles(adaptInfo, false); writeFiles(adaptInfo, false); } + +} } diff --git a/extensions/base_problems/CahnHilliardNavierStokes_TwoPhase_RB.h b/extensions/base_problems/CahnHilliardNavierStokes_TwoPhase_RB.h index c6b91db2b7cf87b3bf7e7ebf079092477fee9d3e..2384669824fd7044f03f2fa29ddaacdbcfb1e60f 100644 --- a/extensions/base_problems/CahnHilliardNavierStokes_TwoPhase_RB.h +++ b/extensions/base_problems/CahnHilliardNavierStokes_TwoPhase_RB.h @@ -22,7 +22,7 @@ #include "BaseProblem_RB.h" #include "chns.h" -using namespace AMDiS; +namespace AMDiS { namespace base_problems { class CahnHilliardNavierStokes_TwoPhase_RB : public BaseProblem_RB { @@ -109,5 +109,6 @@ protected: // protected variables FileVectorWriter *fileWriter; }; +} } #endif // CAHN_HILLIARD_H diff --git a/extensions/base_problems/CahnHilliard_RB.cc b/extensions/base_problems/CahnHilliard_RB.cc index 3e9ddda36678ef9dc6b4d678549ff31e7e2a8d54..22e52035a5929d6ca6026262909d86045df7ca95 100644 --- a/extensions/base_problems/CahnHilliard_RB.cc +++ b/extensions/base_problems/CahnHilliard_RB.cc @@ -20,7 +20,7 @@ #include "PhaseFieldConvert.h" #include "Tools.h" -using namespace AMDiS; +namespace AMDiS { namespace base_problems { CahnHilliard_RB::CahnHilliard_RB(const std::string &name_) : super(name_), @@ -70,6 +70,8 @@ void CahnHilliard_RB::initData() void CahnHilliard_RB::solveInitialProblem(AdaptInfo *adaptInfo) { + using namespace AMDiS::extensions; + Flag initFlag = initDataFromFile(adaptInfo); if (!initFlag.isSet(DATA_ADOPTED)) { @@ -80,7 +82,7 @@ void CahnHilliard_RB::solveInitialProblem(AdaptInfo *adaptInfo) if (initialInterface == -1) { /// random values - prob->getSolution()->getDOFVector(0)->interpol(new tools::Random(0.5 - doubleWell*0.5, 1.0 + doubleWell)); + prob->getSolution()->getDOFVector(0)->interpol(new AMDiS::Random(0.5 - doubleWell*0.5, 1.0 + doubleWell)); } else if (initialInterface == 0) { /// horizontale Linie @@ -245,3 +247,5 @@ void CahnHilliard_RB::fillOperators() prob->addVectorOperator(*opChMExpl, 1); } } + +} } diff --git a/extensions/base_problems/CahnHilliard_RB.h b/extensions/base_problems/CahnHilliard_RB.h index fa98e3557464a49382829ac6c7e0e577975404f3..57e4d6feb89f451b67659e01e433e57b4904cc8c 100644 --- a/extensions/base_problems/CahnHilliard_RB.h +++ b/extensions/base_problems/CahnHilliard_RB.h @@ -24,7 +24,7 @@ #include "HL_SignedDistTraverse.h" #include "chns.h" -using namespace AMDiS; +namespace AMDiS { namespace base_problems { class CahnHilliard_RB : public BaseProblem_RB { @@ -67,4 +67,6 @@ protected: // protected variables double minusEpsSqr; }; +} } + #endif // CAHN_HILLIARD_RB_H diff --git a/extensions/base_problems/CouplingBaseProblem.h b/extensions/base_problems/CouplingBaseProblem.h index 9a151410670ebd83de2b5384bdbeed000411c0da..d12de90a546124eee84ccf6a55f7c89cd115b525 100644 --- a/extensions/base_problems/CouplingBaseProblem.h +++ b/extensions/base_problems/CouplingBaseProblem.h @@ -12,8 +12,7 @@ #include "BaseProblem.h" #include "ProblemInstat.h" -using namespace AMDiS; - +namespace AMDiS { namespace base_problems { /** * \ingroup Problem @@ -23,10 +22,10 @@ using namespace AMDiS; template<class ProblemType=ProblemStat, class BaseProblemType=BaseProblem<ProblemStat> > class CouplingBaseProblem : public CouplingIterationInterface, public CouplingTimeInterface, - public AMDiS::detail::CouplingProblemStat<ProblemType> + public detail::CouplingProblemStat<ProblemType> { public: - typedef AMDiS::detail::CouplingProblemStat<ProblemType> CProblemStat; + typedef detail::CouplingProblemStat<ProblemType> CProblemStat; CouplingBaseProblem(std::string name_, BaseProblemType *prob0_, @@ -120,5 +119,6 @@ protected: std::string name; }; +} } #endif // COUPLING_BASE_PROBLEM_H diff --git a/extensions/base_problems/CouplingBaseProblem2.h b/extensions/base_problems/CouplingBaseProblem2.h index 382d9c23c4f7f4d2d42d8be41e3f41da8597052f..35b802f5ee665f8e601ae39619c8508a3e9c194c 100644 --- a/extensions/base_problems/CouplingBaseProblem2.h +++ b/extensions/base_problems/CouplingBaseProblem2.h @@ -25,7 +25,7 @@ #define MAX_NUM_COUPLED_PROBLEMS 10 -namespace AMDiS { +namespace AMDiS { namespace base_problems { namespace detail { @@ -101,10 +101,10 @@ template<class ProblemType=ProblemStat, BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(MAX_NUM_COUPLED_PROBLEMS, class BaseProblemType, void) > class CouplingBaseProblem : public CouplingIterationInterface, public CouplingTimeInterface, - public detail::CouplingProblemStat<ProblemType> + public AMDiS::detail::CouplingProblemStat<ProblemType> { public: - typedef detail::CouplingProblemStat<ProblemType> CProblemStat; + typedef AMDiS::detail::CouplingProblemStat<ProblemType> CProblemStat; typedef typename boost::tuples::detail::tie_mapper < BOOST_PP_ENUM_PARAMS(MAX_NUM_COUPLED_PROBLEMS, BaseProblemType) >::type BaseProblemsTupleType; @@ -142,6 +142,7 @@ public: ProblemStatSeq *adoptProblem = NULL, Flag adoptFlag = INIT_NOTHING) override { + using namespace AMDiS::extensions; tools::FOR_EACH< detail::AddProblem >::loop2(*this, baseProblems); tools::FOR_EACH< detail::AddIterationInterface >::loop2(*this, baseProblems); tools::FOR_EACH< detail::AddTimeInterface >::loop2(*this, baseProblems); @@ -158,6 +159,8 @@ public: virtual void initTimeInterface() { + using namespace AMDiS::extensions; + tools::FOR_EACH< detail::InitData >::loop(baseProblems); initData(); @@ -203,6 +206,7 @@ public: template<typename BaseProblemType> BaseProblemType *getBaseProblem(std::string name_) { + using namespace AMDiS::extensions; BaseProblemType *prob = NULL; tools::FOR_EACH< detail::FindBaseProblem >::loop1(baseProblems, name_, prob); if (prob) @@ -213,6 +217,7 @@ public: ProblemType *getProblem(std::string name_) { + using namespace AMDiS::extensions; ProblemType *prob = NULL; tools::FOR_EACH< detail::FindProblem >::loop1(baseProblems, name_, prob); if (prob) @@ -230,6 +235,6 @@ protected: std::string name; }; -} // end namespace AMDiS +} } // end namespace base_problems, AMDiS #endif // COUPLING_BASE_PROBLEM_H diff --git a/extensions/base_problems/CouplingBaseProblem_RB.h b/extensions/base_problems/CouplingBaseProblem_RB.h index 579e146b728e30f6bea08a363b27aa5958e155c3..a5482ffd044da651ace5ee9340b418a1f7522cd1 100644 --- a/extensions/base_problems/CouplingBaseProblem_RB.h +++ b/extensions/base_problems/CouplingBaseProblem_RB.h @@ -13,8 +13,7 @@ #include "CouplingBaseProblem.h" #include "time/ExtendedRosenbrockStationary.h" -using namespace AMDiS; - +namespace AMDiS { namespace base_problems { /** * \ingroup Problem @@ -136,5 +135,6 @@ public: } }; +} } #endif // COUPLED_BASE_PROBLEM_RB_H diff --git a/extensions/base_problems/DiffuseDomainFsi.cc b/extensions/base_problems/DiffuseDomainFsi.cc index 61e80498180f8f59cb8b7a13ba3f6d165a0d84f7..1fe67f263b12e1bdce12be4dc016a8c045ae0cec 100644 --- a/extensions/base_problems/DiffuseDomainFsi.cc +++ b/extensions/base_problems/DiffuseDomainFsi.cc @@ -16,8 +16,10 @@ ******************************************************************************/ #include "DiffuseDomainFsi.h" + +namespace AMDiS { namespace base_problems { + using namespace std; -using namespace AMDiS; DiffuseDomainFsi::DiffuseDomainFsi(const std::string &name_) : super(name_), @@ -289,3 +291,5 @@ void DiffuseDomainFsi::addLaplaceTerm(int i) opGradP2->addTerm(new PartialDerivative_ZOT(phase,i, -1.0)); prob->addMatrixOperator(*opGradP2, i, dow); } + +} } diff --git a/extensions/base_problems/DiffuseDomainFsi.h b/extensions/base_problems/DiffuseDomainFsi.h index 19b512e2a3445211020040472b1c2eb04af5b390..c794ebcf72c97f2d0d70dad7877b17cc9ef65416 100644 --- a/extensions/base_problems/DiffuseDomainFsi.h +++ b/extensions/base_problems/DiffuseDomainFsi.h @@ -24,7 +24,7 @@ #include "Helpers.h" #include "POperators.h" -using namespace AMDiS; +namespace AMDiS { namespace base_problems { /** \ingroup NavierStokes_TaylorHood * \brief @@ -34,11 +34,11 @@ using namespace AMDiS; * div(phase*u) = grad(phase)*u * (1-phase)*(dt(eta_j)+u*grad(eta_j)) = (1-phase)*u_j; j=1...d */ -class DiffuseDomainFsi : public BaseProblem<ExtendedProblemStat> +class DiffuseDomainFsi : public BaseProblem<extensions::ExtendedProblemStat> { public: // typedefs - typedef BaseProblem<ExtendedProblemStat> super; + typedef BaseProblem<extensions::ExtendedProblemStat> super; public: // methods @@ -195,4 +195,6 @@ private: double factor; }; +} } + #endif // DIFFUSE_DOMAIN_FSI_H diff --git a/extensions/base_problems/LinearElasticity.cc b/extensions/base_problems/LinearElasticity.cc index 3b2f3804cef5a10d8c11a98b37cafeff20834a52..f21660bbbb46e05ce10bda7dcf5ccb7d8639de0c 100644 --- a/extensions/base_problems/LinearElasticity.cc +++ b/extensions/base_problems/LinearElasticity.cc @@ -17,8 +17,9 @@ #include "LinearElasticity.h" #include "POperators.h" +namespace AMDiS { namespace base_problems { + using namespace std; -using namespace AMDiS; LinearElasticity::LinearElasticity(const std::string &name_) : super(name_), @@ -84,6 +85,8 @@ void LinearElasticity::transferInitialSolution(AdaptInfo *adaptInfo) void LinearElasticity::fillOperators() { + using namespace AMDiS::extensions; + WorldVector<DOFVector<double>* > velocity; for (size_t i = 0; i < dow; i++) velocity[i] = prob->getSolution()->getDOFVector(i+dow); @@ -195,3 +198,5 @@ void LinearElasticity::closeTimestep(AdaptInfo *adaptInfo) fileWriter->writeFiles(adaptInfo, false); writeFiles(adaptInfo, false); } + +} } diff --git a/extensions/base_problems/LinearElasticity.h b/extensions/base_problems/LinearElasticity.h index 36f3959be0502f514eacdcbd31490fa4f215df6c..e3c1d5c7c54116944ffa5e51da58d59c813f85a2 100644 --- a/extensions/base_problems/LinearElasticity.h +++ b/extensions/base_problems/LinearElasticity.h @@ -22,17 +22,17 @@ #include "BaseProblem.h" #include "ExtendedProblemStat.h" -using namespace AMDiS; +namespace AMDiS { namespace base_problems { /** \ingroup Elasticity * \brief * Elastodynamics – the wave equation */ -class LinearElasticity : public BaseProblem<ExtendedProblemStat> +class LinearElasticity : public BaseProblem<extensions::ExtendedProblemStat> { public: // typedefs - typedef BaseProblem<ExtendedProblemStat> super; + typedef BaseProblem<extensions::ExtendedProblemStat> super; public: // methods @@ -68,4 +68,7 @@ protected: // variables FileVectorWriter *fileWriter; }; + +} } + #endif // LINEAR_ELASTICITY_H diff --git a/extensions/base_problems/LinearElasticityPhase.cc b/extensions/base_problems/LinearElasticityPhase.cc index 39d517efd7b42f26c9011741cc2cab336d8a1764..1723149e9b1184410b2bc3166c07002bbaabd35c 100644 --- a/extensions/base_problems/LinearElasticityPhase.cc +++ b/extensions/base_problems/LinearElasticityPhase.cc @@ -17,8 +17,9 @@ #include "LinearElasticityPhase.h" #include "POperators.h" +namespace AMDiS { namespace base_problems { + using namespace std; -using namespace AMDiS; LinearElasticityPhase::LinearElasticityPhase(const std::string &name_) : super(name_), @@ -101,6 +102,7 @@ void LinearElasticityPhase::transferInitialSolution(AdaptInfo *adaptInfo) void LinearElasticityPhase::fillOperators() { + using namespace AMDiS::extensions; // fill operators for prob for (size_t i = 0; i < dow; ++i) { /// dt(u) - v = 0 @@ -160,6 +162,7 @@ void LinearElasticityPhase::fillOperators() void LinearElasticityPhase::fillBoundaryConditions() { + using namespace AMDiS::extensions; /// neumann boundary condition for (size_t i = 0; i < dow; i++) { Operator *opNeumannForce = new Operator(getFeSpace(i), getFeSpace(i)); @@ -204,3 +207,5 @@ void LinearElasticityPhase::closeTimestep(AdaptInfo *adaptInfo) fileWriter->writeFiles(adaptInfo, false); writeFiles(adaptInfo, false); } + +} } diff --git a/extensions/base_problems/LinearElasticityPhase.h b/extensions/base_problems/LinearElasticityPhase.h index adc205f657fb06bb3442df4530590b2348372aae..63167bbe1a6b0d26206d9225aa44aad28317f988 100644 --- a/extensions/base_problems/LinearElasticityPhase.h +++ b/extensions/base_problems/LinearElasticityPhase.h @@ -22,17 +22,17 @@ #include "BaseProblem.h" #include "ExtendedProblemStat.h" -using namespace AMDiS; +namespace AMDiS { namespace base_problems { /** \ingroup Elasticity * \brief * Elastodynamics – the wave equation */ -class LinearElasticityPhase : public BaseProblem<ExtendedProblemStat> +class LinearElasticityPhase : public BaseProblem<extensions::ExtendedProblemStat> { public: // typedefs - typedef BaseProblem<ExtendedProblemStat> super; + typedef BaseProblem<extensions::ExtendedProblemStat> super; public: // methods @@ -159,4 +159,6 @@ private: double factor; }; +} } + #endif // LINEAR_ELASTICITY_H diff --git a/extensions/base_problems/NavierStokesCahnHilliard.cc b/extensions/base_problems/NavierStokesCahnHilliard.cc index 7e0faf25ad8c029130325d01593f4fbfda7bcf6c..e2b127d8318e662bcbdfb01e46dfdebb0a59ecc2 100644 --- a/extensions/base_problems/NavierStokesCahnHilliard.cc +++ b/extensions/base_problems/NavierStokesCahnHilliard.cc @@ -19,7 +19,7 @@ #include "SignedDistFunctors.h" #include "PhaseFieldConvert.h" -using namespace AMDiS; +namespace AMDiS { namespace base_problems { NavierStokesCahnHilliard::NavierStokesCahnHilliard(const std::string &name_, bool createProblem) : super(name_, createProblem), @@ -145,8 +145,7 @@ void NavierStokesCahnHilliard::closeTimestep(AdaptInfo *adaptInfo) void NavierStokesCahnHilliard::transferInitialSolution(AdaptInfo *adaptInfo) -{ FUNCNAME("NavierStokesCahnHilliard::transferInitialSolution()"); - +{ calcVelocity(); fileWriter->writeFiles(adaptInfo, false); @@ -171,6 +170,7 @@ void NavierStokesCahnHilliard::initTimestep(AdaptInfo *adaptInfo) void NavierStokesCahnHilliard::solveInitialProblem(AdaptInfo *adaptInfo) { + using namespace extensions; // meshFunction for klocal refinement around the interface of the phasefield-DOFVector refFunction = new PhaseFieldRefinement(prob->getMesh()); @@ -201,6 +201,7 @@ void NavierStokesCahnHilliard::solveInitialProblem(AdaptInfo *adaptInfo) void NavierStokesCahnHilliard::solveInitialProblem2(AdaptInfo *adaptInfo) { + using namespace extensions; Flag initFlag = initDataFromFile(adaptInfo); int comp = 2+dow; @@ -273,6 +274,7 @@ void NavierStokesCahnHilliard::solveInitialProblem2(AdaptInfo *adaptInfo) void NavierStokesCahnHilliard::fillOperators() { + using namespace extensions; const FiniteElemSpace* feSpace = prob->getFeSpace(0); int comp = dow+2, comp2 = dow+1; int degree = prob->getFeSpace(comp)->getBasisFcts()->getDegree(); @@ -447,3 +449,5 @@ void NavierStokesCahnHilliard::addLaplaceTerm(int i) } + +} } diff --git a/extensions/base_problems/NavierStokesCahnHilliard.h b/extensions/base_problems/NavierStokesCahnHilliard.h index 6e1499aaebf8240b9637645ea3733300019806c2..8f0865bdb0cc8d3bca7b0d11d7c6091d3d85d0aa 100644 --- a/extensions/base_problems/NavierStokesCahnHilliard.h +++ b/extensions/base_problems/NavierStokesCahnHilliard.h @@ -27,8 +27,7 @@ #endif - -using namespace AMDiS; +namespace AMDiS { namespace base_problems { class NavierStokesCahnHilliard : public BaseProblem<ProblemStat> { @@ -116,8 +115,8 @@ protected: // protected variables unsigned dow; // dimension of the world unsigned dim; - PhaseFieldRefinement* refFunction; - RefinementLevelDOF *refinement; + extensions::PhaseFieldRefinement* refFunction; + extensions::RefinementLevelDOF *refinement; double sigma, minus1; // coupling parameter to calculate the surface tension double surfaceTension;// := sigma/epsilon @@ -196,4 +195,4 @@ private: double val2; }; - +} } diff --git a/extensions/base_problems/NavierStokesPhase_Chorin.cc b/extensions/base_problems/NavierStokesPhase_Chorin.cc index 7365a113dbb5faba5a17cb3eadc05dafd1e01270..7c00c6e604d44bd30bcb604659895f20545207c1 100644 --- a/extensions/base_problems/NavierStokesPhase_Chorin.cc +++ b/extensions/base_problems/NavierStokesPhase_Chorin.cc @@ -18,8 +18,9 @@ #define UPDATE_VELOCITY_SYSTEM +namespace AMDiS { namespace base_problems { + using namespace std; -using namespace AMDiS; NavierStokesPhase_Chorin::NavierStokesPhase_Chorin(const std::string &name_, WorldVector<AbstractFunction<double, WorldVector<double> >* > initialVelocityFcts_, DiffuseDomain* geometryProb_) : super(name_, initialVelocityFcts_), @@ -285,3 +286,4 @@ void NavierStokesPhase_Chorin::closeTimestep(AdaptInfo *adaptInfo) } }; +} } \ No newline at end of file diff --git a/extensions/base_problems/NavierStokesPhase_Chorin.h b/extensions/base_problems/NavierStokesPhase_Chorin.h index ce98644f13e09cf98bbbad95be343d263d46d325..272eceb2836ce8828ea1e43e3e13eef47d5b8402 100644 --- a/extensions/base_problems/NavierStokesPhase_Chorin.h +++ b/extensions/base_problems/NavierStokesPhase_Chorin.h @@ -36,7 +36,7 @@ #define UNTEN 3 #define OBEN 4 -using namespace AMDiS; +namespace AMDiS { namespace base_problems { /** \ingroup NavierStokesPhase_Chorin * \brief @@ -84,4 +84,7 @@ protected: // variables private: }; + +} } + #endif // NAVIER_STOKES_CHORIN_H diff --git a/extensions/base_problems/NavierStokesPhase_TaylorHood.cc b/extensions/base_problems/NavierStokesPhase_TaylorHood.cc index f8595a48eefa6b961b76058aa1f957c19ff07e93..9ed5ac89ad6027b65dea098d640c2c8509d9a592 100644 --- a/extensions/base_problems/NavierStokesPhase_TaylorHood.cc +++ b/extensions/base_problems/NavierStokesPhase_TaylorHood.cc @@ -16,8 +16,9 @@ ******************************************************************************/ #include "NavierStokesPhase_TaylorHood.h" +namespace AMDiS { namespace base_problems { + using namespace std; -using namespace AMDiS; NavierStokesPhase_TaylorHood::NavierStokesPhase_TaylorHood(const std::string &name_) : super(name_), @@ -57,7 +58,7 @@ void NavierStokesPhase_TaylorHood::initData() super::initData(); phaseOld = new DOFVector<double>(getFeSpace(0), "phaseOld"); - dbc_factor = beta/pow(epsilon, alpha); + dbc_factor = beta/std::pow(epsilon, alpha); } @@ -75,6 +76,8 @@ void NavierStokesPhase_TaylorHood::transferInitialSolution(AdaptInfo *adaptInfo) void NavierStokesPhase_TaylorHood::fillOperators() { FUNCNAME("NavierStokesPhase_TaylorHood::fillOperators()"); + using namespace extensions; + WorldVector<DOFVector<double>* > vel; for (size_t i = 0; i < dow; i++) vel[i] = prob->getSolution()->getDOFVector(i); @@ -164,6 +167,8 @@ void NavierStokesPhase_TaylorHood::fillOperators() void NavierStokesPhase_TaylorHood::addLaplaceTerm(int i) { + using namespace extensions; + /// < alpha*[grad(u)+grad(u)^t] , grad(psi) > if (laplaceType == 1) { for (unsigned j = 0; j < dow; ++j) { @@ -182,7 +187,8 @@ void NavierStokesPhase_TaylorHood::addLaplaceTerm(int i) void NavierStokesPhase_TaylorHood::fillBoundaryConditions() { FUNCNAME("NavierStokesPhase_TaylorHood::fillBoundaryConditions()"); - + using namespace extensions; + for (size_t i = 0; i < dow; ++i) { /// dirichlet boundary condition /// beta/eps^alpha (1-phase)*(u_i - g_i) @@ -245,3 +251,5 @@ void NavierStokesPhase_TaylorHood::writeFiles(AdaptInfo *adaptInfo, bool force) super::writeFiles(adaptInfo, force); fileWriterPhase->writeFiles(adaptInfo, false); } + +} } diff --git a/extensions/base_problems/NavierStokesPhase_TaylorHood.h b/extensions/base_problems/NavierStokesPhase_TaylorHood.h index 7f1e1478ae535f8eb4290797726a827b439309f6..377b81dc58f39e13cba6d1da8c965fea4bf32eae 100644 --- a/extensions/base_problems/NavierStokesPhase_TaylorHood.h +++ b/extensions/base_problems/NavierStokesPhase_TaylorHood.h @@ -21,7 +21,7 @@ #include "NavierStokes_TaylorHood.h" #include "ExtendedProblemStat.h" -using namespace AMDiS; +namespace AMDiS { namespace base_problems { /** \ingroup NavierStokes_TaylorHood * \brief @@ -30,11 +30,11 @@ using namespace AMDiS; * dt(phase*u_j) + phase*u*grad(u_j) = phase*d_j(p) - nu*div(phase*grad(u_j)) - beta/eps^alpha (1-phase)*(u_j - g_j); j=1...d * div(phase*u) = grad(phase)*g */ -class NavierStokesPhase_TaylorHood : public ::detail::NavierStokes_TaylorHood<ExtendedProblemStat> +class NavierStokesPhase_TaylorHood : public detail::NavierStokes_TaylorHood<extensions::ExtendedProblemStat> { public: // typedefs - typedef ::detail::NavierStokes_TaylorHood<ExtendedProblemStat> super; + typedef detail::NavierStokes_TaylorHood<extensions::ExtendedProblemStat> super; public: // methods @@ -154,4 +154,6 @@ private: double factor; }; +} } + #endif // NAVIER_STOKES_PHASE_TAYLOR_HOOD_H diff --git a/extensions/base_problems/NavierStokes_Chorin.cc b/extensions/base_problems/NavierStokes_Chorin.cc index 5fb7c594d1cc8de9f15ac20ba3ea5b566331bdb9..35e8417dfa340d7cb4016dc9690b672dce748548 100644 --- a/extensions/base_problems/NavierStokes_Chorin.cc +++ b/extensions/base_problems/NavierStokes_Chorin.cc @@ -18,8 +18,9 @@ #define UPDATE_VELOCITY_SYSTEM +namespace AMDiS { namespace base_problems { + using namespace std; -using namespace AMDiS; NavierStokes_Chorin::NavierStokes_Chorin(const std::string &name_, WorldVector<AbstractFunction<double, WorldVector<double> >* > initialVelocityFcts_) : ProblemInstatBase(name_,NULL), @@ -608,3 +609,5 @@ void NavierStokes_Chorin::writeFiles(AdaptInfo *adaptInfo, bool force) pressureProb->writeFiles(adaptInfo, force); correctorProb->writeFiles(adaptInfo, force); }; + +} } diff --git a/extensions/base_problems/NavierStokes_Chorin.h b/extensions/base_problems/NavierStokes_Chorin.h index 159257df638968b8fafba288336e7ea99b30c381..74ae3499a51d141a45709d5571eef710ef477fd8 100644 --- a/extensions/base_problems/NavierStokes_Chorin.h +++ b/extensions/base_problems/NavierStokes_Chorin.h @@ -31,7 +31,7 @@ #define UNTEN 3 #define OBEN 4 -using namespace AMDiS; +namespace AMDiS { namespace base_problems { /** \ingroup NavierStokes_Chorin * \brief @@ -228,4 +228,7 @@ protected: private: }; + +} } + #endif // NAVIER_STOKES_CHORIN_H diff --git a/extensions/base_problems/NavierStokes_TH_MultiPhase.cc b/extensions/base_problems/NavierStokes_TH_MultiPhase.cc new file mode 100644 index 0000000000000000000000000000000000000000..a2899ef5f3940b5fdd8910144b599156d54aebdc --- /dev/null +++ b/extensions/base_problems/NavierStokes_TH_MultiPhase.cc @@ -0,0 +1,11 @@ +#include "NavierStokes_TH_MultiPhase.h" +#include "ProblemStat.h" +#include "ExtendedProblemStat.h" + +namespace AMDiS { namespace base_problems { + + // explicit template instantiation + template class detail::NavierStokes_TH_MultiPhase<ProblemStat>; + template class detail::NavierStokes_TH_MultiPhase<extensions::ExtendedProblemStat>; + +} } diff --git a/extensions/base_problems/NavierStokes_TH_MultiPhase.h b/extensions/base_problems/NavierStokes_TH_MultiPhase.h index b80c9f759d633358a8f2f63318dc5470a2c08d3b..b7e421e125bbdc65f3a61c3b85ebad988a9ec4b1 100644 --- a/extensions/base_problems/NavierStokes_TH_MultiPhase.h +++ b/extensions/base_problems/NavierStokes_TH_MultiPhase.h @@ -19,11 +19,10 @@ #include "NavierStokes_TaylorHood.h" +namespace AMDiS { namespace base_problems { namespace detail { -using namespace AMDiS; - /** \ingroup NavierStokes_TaylorHood * \brief * Navier-Stokes multi-phase problem, using Taylor Hood elements @@ -169,8 +168,10 @@ using namespace AMDiS; } -#include "NavierStokes_TH_MultiPhase.hh" +typedef base_problems::detail::NavierStokes_TH_MultiPhase<AMDiS::ProblemStat> NavierStokes_TH_MultiPhase; -typedef ::detail::NavierStokes_TH_MultiPhase<AMDiS::ProblemStat> NavierStokes_TH_MultiPhase; +} } + +#include "NavierStokes_TH_MultiPhase.hh" #endif // NAVIER_STOKES_TAYLOR_HOOD_MULTIPHASE_H diff --git a/extensions/base_problems/NavierStokes_TH_MultiPhase.hh b/extensions/base_problems/NavierStokes_TH_MultiPhase.hh index d9b0e7271a0eb3d52d6647393e17e104c7f29334..47c75066ceaa07ad29564ee9f592af6209347339 100644 --- a/extensions/base_problems/NavierStokes_TH_MultiPhase.hh +++ b/extensions/base_problems/NavierStokes_TH_MultiPhase.hh @@ -18,11 +18,10 @@ // #include "parallel/MeshDistributor.h" // #endif +namespace AMDiS { namespace base_problems { namespace detail { -using namespace AMDiS; - template<typename P> NavierStokes_TH_MultiPhase<P>::NavierStokes_TH_MultiPhase(const std::string &name_, bool createProblem) : super(name_, createProblem), @@ -106,6 +105,8 @@ void NavierStokes_TH_MultiPhase<P>::initTimestep(AdaptInfo *adaptInfo) template<typename P> void NavierStokes_TH_MultiPhase<P>::fillOperators() { + using namespace extensions; + int degree_u = self::prob->getFeSpace(0)->getBasisFcts()->getDegree(); // int degree_p = self::prob->getFeSpace(self::dow)->getBasisFcts()->getDegree(); @@ -198,6 +199,7 @@ void NavierStokes_TH_MultiPhase<P>::fillOperators() template<typename P> void NavierStokes_TH_MultiPhase<P>::addLaplaceTerm(int i) { + using namespace extensions; /// < alpha*[grad(u)+grad(u)^t] , grad(psi) > if (viscosity1 != viscosity2 && viscosityPhase) { for (unsigned j = 0; j < self::dow; ++j) { @@ -219,3 +221,4 @@ void NavierStokes_TH_MultiPhase<P>::addLaplaceTerm(int i) } // end namespace detail +} } diff --git a/extensions/base_problems/NavierStokes_TH_MultiPhase_RB.cc b/extensions/base_problems/NavierStokes_TH_MultiPhase_RB.cc index cc58f14b2322d12b0ea4fd972cbcb291285f7ba8..30b33ee66c6532f6d65e32ae0d90373532b70409 100644 --- a/extensions/base_problems/NavierStokes_TH_MultiPhase_RB.cc +++ b/extensions/base_problems/NavierStokes_TH_MultiPhase_RB.cc @@ -16,8 +16,9 @@ ******************************************************************************/ #include "NavierStokes_TH_MultiPhase_RB.h" +namespace AMDiS { namespace base_problems { + using namespace std; -using namespace AMDiS; NavierStokes_TH_MultiPhase_RB::NavierStokes_TH_MultiPhase_RB(const std::string &name_, bool createProblem) : super(name_, createProblem), @@ -77,6 +78,7 @@ void NavierStokes_TH_MultiPhase_RB::initTimestep(AdaptInfo *adaptInfo) void NavierStokes_TH_MultiPhase_RB::fillOperators() { + using namespace extensions; int degree_u = prob->getFeSpace(0)->getBasisFcts()->getDegree(); // int degree_p = prob->getFeSpace(dow)->getBasisFcts()->getDegree(); @@ -176,6 +178,7 @@ void NavierStokes_TH_MultiPhase_RB::fillOperators() void NavierStokes_TH_MultiPhase_RB::addLaplaceTerm(int i) { + using namespace extensions; /// < alpha*[grad(u)+grad(u)^t] , grad(psi) > if (viscosity1 != viscosity2 && viscosityPhase) { for (size_t j = 0; j < dow; ++j) { @@ -199,3 +202,4 @@ void NavierStokes_TH_MultiPhase_RB::addLaplaceTerm(int i) prob->addMatrixOperator(*opLaplaceUi, i, i); } +} } diff --git a/extensions/base_problems/NavierStokes_TH_MultiPhase_RB.h b/extensions/base_problems/NavierStokes_TH_MultiPhase_RB.h index b8da6c58cba031f4ec989730d24c2bd326fb73e1..b8d6340139525a87eab7d4bb9cf8a679788e7c15 100644 --- a/extensions/base_problems/NavierStokes_TH_MultiPhase_RB.h +++ b/extensions/base_problems/NavierStokes_TH_MultiPhase_RB.h @@ -20,7 +20,7 @@ #include "NavierStokes_TaylorHood_RB.h" -using namespace AMDiS; +namespace AMDiS { namespace base_problems { /** \ingroup NavierStokes_TaylorHood * \brief @@ -159,5 +159,7 @@ private: double val2; }; +} } + #endif // NAVIER_STOKES_TAYLOR_HOOD_MULTIPHASE_H diff --git a/extensions/base_problems/NavierStokes_TaylorHood.cc b/extensions/base_problems/NavierStokes_TaylorHood.cc index 302ed8e921e544df5700e6191e5a735dafcfa6cf..7e21b2b8fbc7caecc2b54e9f677a3af5b993ebe8 100644 --- a/extensions/base_problems/NavierStokes_TaylorHood.cc +++ b/extensions/base_problems/NavierStokes_TaylorHood.cc @@ -1,238 +1,11 @@ -/****************************************************************************** - * - * Extension of AMDiS - Adaptive multidimensional simulations - * - * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. - * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis - * - * Authors: Simon Praetorius et al. - * - * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * - * See also license.opensource.txt in the distribution. - * - ******************************************************************************/ #include "NavierStokes_TaylorHood.h" +#include "ProblemStat.h" +#include "ExtendedProblemStat.h" -using namespace AMDiS; - -NavierStokes_TaylorHood::NavierStokes_TaylorHood(const std::string &name_, bool createProblem) : - super(name_, createProblem), - velocity(NULL), - laplaceType(0), - nonLinTerm(2), - oldTimestep(0.0), - viscosity(1.0), - density(1.0), - minus1(-1.0), - theta(0.5+1.e-2), - theta1(1-theta), - minusTheta1(-theta1), - fileWriter(NULL) -{ - // fluid viscosity - Initfile::get(name + "->viscosity", viscosity); - // fluid density - Initfile::get(name + "->density", density); - - // type of laplace operator: - // 0... div(nu*grad(u)), - // 1... div(0.5*nu*(grad(u)+grad(u)^T)) - Initfile::get(name + "->laplace operator", laplaceType); - - // type of non-linear term: - // 0... u^old*grad(u_i^old), - // 1... u*grad(u_i^old), - // 2... u^old*grad(u_i) - // 3... (1)+(2)-(0) - Initfile::get(name + "->non-linear term", nonLinTerm); - - // theta-scheme parameter - Initfile::get(name + "->theta", theta); - theta1 = 1.0-theta; - minusTheta1 = -theta1; - - // volume force - force.set(0.0); - Initfile::get(name + "->force", force); - - oldSolution.resize(dow); - for (size_t i = 0; i < dow; i++) - oldSolution[i] = NULL; -} - - -NavierStokes_TaylorHood::~NavierStokes_TaylorHood() -{ - if (velocity != NULL) { - delete velocity; - velocity = NULL; - } - - for (size_t i = 0; i < dow; i++) { - if (oldSolution[i] != NULL) - delete oldSolution[i]; - oldSolution[i] = NULL; - } - - if (fileWriter) { - delete fileWriter; - fileWriter = NULL; - } -} - - -void NavierStokes_TaylorHood::initData() -{ - if (velocity == NULL) - velocity = new DOFVector<WorldVector<double> >(getFeSpace(0), "velocity"); - - for (size_t i = 0; i < dow; i++) - oldSolution[i] = new DOFVector<double>(getFeSpace(i), "old(v_"+Helpers::toString(i)+")"); - - fileWriter = new FileVectorWriter(name + "->velocity->output", getFeSpace()->getMesh(), velocity); - - super::initData(); -} - - -void NavierStokes_TaylorHood::transferInitialSolution(AdaptInfo *adaptInfo) -{ - calcVelocity(); - for (size_t i = 0; i < dow; i++) - oldSolution[i]->copy(*prob->getSolution()->getDOFVector(i)); - - super::transferInitialSolution(adaptInfo); -} - - -void NavierStokes_TaylorHood::fillOperators() -{ - WorldVector<DOFVector<double>* > vel; - for (size_t k = 0; k < dow; k++) - vel[k] = prob->getSolution()->getDOFVector(k); +namespace AMDiS { namespace base_problems { - const FiniteElemSpace* feSpace_u = getFeSpace(0); - const FiniteElemSpace* feSpace_p = getFeSpace(dow); + // explicit template instantiation + template class detail::NavierStokes_TaylorHood<ProblemStat>; + template class detail::NavierStokes_TaylorHood<extensions::ExtendedProblemStat>; - // fill operators for prob - for (size_t i = 0; i < dow; ++i) { - /// < (1/tau)*u'_i , psi > - Operator *opTime = new Operator(feSpace_u, feSpace_u); - opTime->addTerm(new Simple_ZOT(density)); - prob->addMatrixOperator(*opTime, i, i, getInvTau(), getInvTau()); - - /// < (1/tau)*u_i^old , psi > - Operator *opTimeOld = new Operator(feSpace_u, feSpace_u); - opTimeOld->addTerm(new Phase_ZOT(getOldSolution(i), density)); - prob->addVectorOperator(*opTimeOld, i, getInvTau(), getInvTau()); - - /// < u^old*grad(u_i^old) , psi > - if (nonLinTerm == 0 || nonLinTerm == 3) { - Operator *opUGradU0 = new Operator(feSpace_u, feSpace_u); - opUGradU0->addTerm(new WorldVec_FOT(vel, density), GRD_PHI); - opUGradU0->setUhOld(prob->getSolution()->getDOFVector(i)); - if (nonLinTerm == 0) - prob->addVectorOperator(*opUGradU0, i); - else - prob->addVectorOperator(*opUGradU0, i, &minus1, &minus1); - } - - /// < u*grad(u_i^old) , psi > - if (nonLinTerm == 1 || nonLinTerm == 3) { - for (size_t k = 0; k < dow; ++k) { - Operator *opUGradU1 = new Operator(feSpace_u, feSpace_u); - opUGradU1->addTerm(new PartialDerivative_ZOT( - prob->getSolution()->getDOFVector(i), k, density)); - prob->addMatrixOperator(*opUGradU1, i, k); - } - } - - /// < u^old*grad(u_i) , psi > - if (nonLinTerm == 2 || nonLinTerm == 3) { - for (size_t k = 0; k < dow; ++k) { - Operator *opUGradU2 = new Operator(feSpace_u, feSpace_u); - opUGradU2->addTerm(new VecAndPartialDerivative_FOT( - vel[k], k, density), GRD_PHI); - prob->addMatrixOperator(*opUGradU2, i, i); - } - } - - /// Diffusion-Operator - addLaplaceTerm(i); - - /// < p , d_i(psi) > - Operator *opGradP = new Operator(feSpace_u, feSpace_p); - opGradP->addTerm(new PartialDerivative_FOT(i, -1.0), GRD_PSI); - prob->addMatrixOperator(*opGradP, i, dow); - - /// external force, i.e. gravitational force - if (std::abs(force[i]) > DBL_TOL) { - Operator *opForce = new Operator(feSpace_u, feSpace_u); - opForce->addTerm(new Simple_ZOT(density*force[i])); - prob->addVectorOperator(*opForce, i); - } - } - - /// div(u) = 0 - for (size_t i = 0; i < dow; ++i) { - /// < d_i(u'_i) , psi > - Operator *opDivU = new Operator(feSpace_p, feSpace_u); - opDivU->addTerm(new PartialDerivative_FOT(i), GRD_PHI); - prob->addMatrixOperator(*opDivU, dow, i); - } - - Operator *opNull = new Operator(feSpace_p, feSpace_p); - opNull->addTerm(new Simple_ZOT(0.0)); - prob->addMatrixOperator(*opNull, dow, dow); -} - - -void NavierStokes_TaylorHood::addLaplaceTerm(int i) -{ - const FiniteElemSpace* feSpace_u = getFeSpace(0); - - /// < alpha*[grad(u)+grad(u)^t] , grad(psi) > - if (laplaceType == 1) { - for (size_t j = 0; j < dow; ++j) { - Operator *opLaplaceUi1 = new Operator(feSpace_u, feSpace_u); - opLaplaceUi1->addTerm(new MatrixIJ_SOT(j, i, viscosity)); - prob->addMatrixOperator(*opLaplaceUi1, i, j, &theta, &theta); - - if (std::abs(minusTheta1) > DBL_TOL) { - opLaplaceUi1->setUhOld(prob->getSolution()->getDOFVector(j)); - prob->addVectorOperator(*opLaplaceUi1, i, &minusTheta1, &minusTheta1); - } - } - } - - /// < alpha*grad(u'_i) , grad(psi) > - Operator *opLaplaceUi = new Operator(feSpace_u, feSpace_u); - opLaplaceUi->addTerm(new Simple_SOT(viscosity)); - prob->addMatrixOperator(*opLaplaceUi, i, i, &theta, &theta); - - if (std::abs(minusTheta1) > DBL_TOL) { - opLaplaceUi->setUhOld(prob->getSolution()->getDOFVector(i)); - prob->addVectorOperator(*opLaplaceUi, i, &minusTheta1, &minusTheta1); - } -} - - -void NavierStokes_TaylorHood::closeTimestep(AdaptInfo *adaptInfo) -{ - calcVelocity(); - for (size_t i = 0; i < dow; i++) - oldSolution[i]->copy(*prob->getSolution()->getDOFVector(i)); - - super::closeTimestep(adaptInfo); -} - - -void NavierStokes_TaylorHood::writeFiles(AdaptInfo *adaptInfo, bool force) -{ - super::writeFiles(adaptInfo, force); - fileWriter->writeFiles(adaptInfo, false); -} - +} } diff --git a/extensions/base_problems/NavierStokes_TaylorHood.h b/extensions/base_problems/NavierStokes_TaylorHood.h index 328585f7e39486c56c5004ba08fc5e8419272a90..be0c948336069ad5057bd06cc23133f84f4f13e9 100644 --- a/extensions/base_problems/NavierStokes_TaylorHood.h +++ b/extensions/base_problems/NavierStokes_TaylorHood.h @@ -21,12 +21,12 @@ #include "AMDiS.h" #include "BaseProblem.h" #include "ExtendedProblemStat.h" +#include "GenericOperatorTerm.h" +namespace AMDiS { namespace base_problems { namespace detail -{ - using namespace AMDiS; - +{ /** \ingroup NavierStokes_TaylorHood * \brief * Navier-Stokes problem, using Taylor Hood elements @@ -84,18 +84,10 @@ namespace detail void calcVelocity() { - if (self::dow == 1) - transformDOF(self::prob->getSolution()->getDOFVector(0), - velocity, new AMDiS::Vec1WorldVec<double>); - else if (self::dow == 2) - transformDOF(self::prob->getSolution()->getDOFVector(0), - self::prob->getSolution()->getDOFVector(1), - velocity, new AMDiS::Vec2WorldVec<double>); - else if (self::dow == 3) - transformDOF(self::prob->getSolution()->getDOFVector(0), - self::prob->getSolution()->getDOFVector(1), - self::prob->getSolution()->getDOFVector(2), - velocity, new AMDiS::Vec3WorldVec<double>); + WorldVector<DOFVector<double>*> vel; + for (size_t i = 0; i < self::dow; i++) + vel[i] = self::prob->getSolution()->getDOFVector(i); + *velocity << valueOf(vel); } int laplaceType; @@ -118,11 +110,12 @@ namespace detail } // end namespace detail -#include "NavierStokes_TaylorHood.hh" +typedef detail::NavierStokes_TaylorHood<AMDiS::ProblemStat> NavierStokes_TaylorHood; -typedef ::detail::NavierStokes_TaylorHood<AMDiS::ProblemStat> NavierStokes_TaylorHood; +} } +#include "NavierStokes_TaylorHood.hh" #endif // NAVIER_STOKES_TAYLOR_HOOD_H diff --git a/extensions/base_problems/NavierStokes_TaylorHood.hh b/extensions/base_problems/NavierStokes_TaylorHood.hh index d3ad31b217121958c0247ff6256af3da82bd5183..abc07537acb5914de38a47abd0f8904dd3706a8c 100644 --- a/extensions/base_problems/NavierStokes_TaylorHood.hh +++ b/extensions/base_problems/NavierStokes_TaylorHood.hh @@ -18,10 +18,10 @@ #include "Helpers.h" #include "POperators.h" +namespace AMDiS { namespace base_problems { + namespace detail { -using namespace AMDiS; - template<typename P> NavierStokes_TaylorHood<P>::NavierStokes_TaylorHood(const std::string &name_, bool createProblem) : super(name_, createProblem), @@ -70,8 +70,7 @@ NavierStokes_TaylorHood<P>::NavierStokes_TaylorHood(const std::string &name_, bo template<typename P> NavierStokes_TaylorHood<P>::~NavierStokes_TaylorHood() -{ FUNCNAME("NavierStokes_TaylorHood::~NavierStokes_TaylorHood()"); - +{ if (velocity != NULL) { delete velocity; velocity = NULL; @@ -92,13 +91,12 @@ NavierStokes_TaylorHood<P>::~NavierStokes_TaylorHood() template<typename P> void NavierStokes_TaylorHood<P>::initData() -{ FUNCNAME("NavierStokes_TaylorHood::initTimeInterface()"); - +{ if (velocity == NULL) velocity = new DOFVector<WorldVector<double> >(self::getFeSpace(0), "velocity"); for (size_t i = 0; i < self::dow; i++) - oldSolution[i] = new DOFVector<double>(self::getFeSpace(i), "old(v_"+Helpers::toString(i)+")"); + oldSolution[i] = new DOFVector<double>(self::getFeSpace(i), "old(v_"+extensions::Helpers::toString(i)+")"); #ifdef HAVE_PARALLEL_DOMAIN_AMDIS for (size_t i = 0; i < self::dow; i++) @@ -113,8 +111,7 @@ void NavierStokes_TaylorHood<P>::initData() template<typename P> void NavierStokes_TaylorHood<P>::transferInitialSolution(AdaptInfo *adaptInfo) -{ FUNCNAME("NavierStokes_TaylorHood::transferInitialSolution()"); - +{ calcVelocity(); for (size_t i = 0; i < self::dow; i++) oldSolution[i]->copy(*self::prob->getSolution()->getDOFVector(i)); @@ -125,8 +122,8 @@ void NavierStokes_TaylorHood<P>::transferInitialSolution(AdaptInfo *adaptInfo) template<typename P> void NavierStokes_TaylorHood<P>::fillOperators() -{ FUNCNAME("NavierStokes_TaylorHood::fillOperators()"); - +{ + using namespace extensions; WorldVector<DOFVector<double>* > vel; for (size_t k = 0; k < self::dow; k++) vel[k] = self::prob->getSolution()->getDOFVector(k); @@ -138,18 +135,18 @@ void NavierStokes_TaylorHood<P>::fillOperators() for (size_t i = 0; i < self::dow; ++i) { /// < (1/tau)*u'_i , psi > Operator *opTime = new Operator(feSpace_u, feSpace_u); - opTime->addTerm(new Simple_ZOT(density)); + addZOT(opTime, density); self::prob->addMatrixOperator(*opTime, i, i, self::getInvTau(), self::getInvTau()); /// < (1/tau)*u_i^old , psi > Operator *opTimeOld = new Operator(feSpace_u, feSpace_u); - opTimeOld->addTerm(new Phase_ZOT(getOldSolution(i), density)); + addZOT(opTimeOld, valueOf(getOldSolution(i)) * density); self::prob->addVectorOperator(*opTimeOld, i, self::getInvTau(), self::getInvTau()); /// < u^old*grad(u_i^old) , psi > if (nonLinTerm == 0 || nonLinTerm == 3) { Operator *opUGradU0 = new Operator(feSpace_u, feSpace_u); - opUGradU0->addTerm(new WorldVec_FOT(vel, density), GRD_PHI); + addFOT(opUGradU0, valueOf(vel) * density, GRD_PHI); opUGradU0->setUhOld(self::prob->getSolution()->getDOFVector(i)); if (nonLinTerm == 0) self::prob->addVectorOperator(*opUGradU0, i); @@ -161,8 +158,7 @@ void NavierStokes_TaylorHood<P>::fillOperators() if (nonLinTerm == 1 || nonLinTerm == 3) { for (size_t k = 0; k < self::dow; ++k) { Operator *opUGradU1 = new Operator(feSpace_u, feSpace_u); - opUGradU1->addTerm(new PartialDerivative_ZOT( - self::prob->getSolution()->getDOFVector(i), k, density)); + addZOT(opUGradU1, derivativeOf(vel[i], k) * density); self::prob->addMatrixOperator(*opUGradU1, i, k); } } @@ -171,8 +167,7 @@ void NavierStokes_TaylorHood<P>::fillOperators() if (nonLinTerm == 2 || nonLinTerm == 3) { for (size_t k = 0; k < self::dow; ++k) { Operator *opUGradU2 = new Operator(feSpace_u, feSpace_u); - opUGradU2->addTerm(new VecAndPartialDerivative_FOT( - vel[k], k, density), GRD_PHI); + addFOT(opUGradU2, valueOf(vel[k]) * density, k, GRD_PHI); self::prob->addMatrixOperator(*opUGradU2, i, i); } } @@ -182,13 +177,13 @@ void NavierStokes_TaylorHood<P>::fillOperators() /// < p , d_i(psi) > Operator *opGradP = new Operator(feSpace_u, feSpace_p); - opGradP->addTerm(new PartialDerivative_FOT(i, -1.0), GRD_PSI); + addFOT(opGradP, -1.0, i, GRD_PSI); self::prob->addMatrixOperator(*opGradP, i, self::dow); /// external force, i.e. gravitational force if (std::abs(force[i]) > DBL_TOL) { Operator *opForce = new Operator(feSpace_u, feSpace_u); - opForce->addTerm(new Simple_ZOT(density*force[i])); + addZOT(opForce, (density*force[i]) ); self::prob->addVectorOperator(*opForce, i); } } @@ -197,27 +192,27 @@ void NavierStokes_TaylorHood<P>::fillOperators() for (size_t i = 0; i < self::dow; ++i) { /// < d_i(u'_i) , psi > Operator *opDivU = new Operator(feSpace_p, feSpace_u); - opDivU->addTerm(new PartialDerivative_FOT(i), GRD_PHI); + addFOT(opDivU, 1.0, i, GRD_PHI); self::prob->addMatrixOperator(*opDivU, self::dow, i); } Operator *opNull = new Operator(feSpace_p, feSpace_p); - opNull->addTerm(new Simple_ZOT(0.0)); + addZOT(opNull, 0.0); self::prob->addMatrixOperator(*opNull, self::dow, self::dow); } template<typename P> void NavierStokes_TaylorHood<P>::addLaplaceTerm(int i) -{ FUNCNAME("NavierStokes_TaylorHood::addLaplaceTerm()"); - +{ + using namespace extensions; const FiniteElemSpace* feSpace_u = self::getFeSpace(0); /// < alpha*[grad(u)+grad(u)^t] , grad(psi) > if (self::laplaceType == 1) { for (size_t j = 0; j < self::dow; ++j) { Operator *opLaplaceUi1 = new Operator(feSpace_u, feSpace_u); - opLaplaceUi1->addTerm(new MatrixIJ_SOT(j, i, viscosity)); + addSOT(opLaplaceUi1, viscosity, j, i); self::prob->addMatrixOperator(*opLaplaceUi1, i, j, &theta, &theta); if (std::abs(minusTheta1) > DBL_TOL) { @@ -229,7 +224,7 @@ void NavierStokes_TaylorHood<P>::addLaplaceTerm(int i) /// < alpha*grad(u'_i) , grad(psi) > Operator *opLaplaceUi = new Operator(feSpace_u, feSpace_u); - opLaplaceUi->addTerm(new Simple_SOT(viscosity)); + addSOT(opLaplaceUi, viscosity); self::prob->addMatrixOperator(*opLaplaceUi, i, i, &theta, &theta); if (std::abs(minusTheta1) > DBL_TOL) { @@ -241,8 +236,7 @@ void NavierStokes_TaylorHood<P>::addLaplaceTerm(int i) template<typename P> void NavierStokes_TaylorHood<P>::closeTimestep(AdaptInfo *adaptInfo) -{ FUNCNAME("NavierStokes_TaylorHood::closeTimestep()"); - +{ calcVelocity(); for (size_t i = 0; i < self::dow; i++) oldSolution[i]->copy(*self::prob->getSolution()->getDOFVector(i)); @@ -253,10 +247,11 @@ void NavierStokes_TaylorHood<P>::closeTimestep(AdaptInfo *adaptInfo) template<typename P> void NavierStokes_TaylorHood<P>::writeFiles(AdaptInfo *adaptInfo, bool force) -{ FUNCNAME("NavierStokesPhase_TaylorHood::closeTimestep()"); - +{ super::writeFiles(adaptInfo, force); self::fileWriter->writeFiles(adaptInfo, false); } -} // end namespace detail \ No newline at end of file +} // end namespace detail + +} } diff --git a/extensions/base_problems/NavierStokes_TaylorHood_RB.cc b/extensions/base_problems/NavierStokes_TaylorHood_RB.cc index b139415eafd908fccfc242de7dc5878c548474bd..05999c187083633414bcde0841812613059eb506 100644 --- a/extensions/base_problems/NavierStokes_TaylorHood_RB.cc +++ b/extensions/base_problems/NavierStokes_TaylorHood_RB.cc @@ -16,7 +16,7 @@ ******************************************************************************/ #include "NavierStokes_TaylorHood_RB.h" -using namespace AMDiS; +namespace AMDiS { namespace base_problems { NavierStokes_TaylorHood_RB::NavierStokes_TaylorHood_RB(const std::string &name_, bool createProblem) : super(name_, createProblem), @@ -75,6 +75,8 @@ void NavierStokes_TaylorHood_RB::transferInitialSolution(AdaptInfo *adaptInfo) void NavierStokes_TaylorHood_RB::fillOperators() { + using namespace extensions; + WorldVector<DOFVector<double>*> U; WorldVector<DOFVector<double>*> U_old; for (unsigned i = 0; i < dow; ++i) { @@ -136,6 +138,8 @@ void NavierStokes_TaylorHood_RB::fillOperators() void NavierStokes_TaylorHood_RB::addLaplaceTerm(int i) { + using namespace extensions; + /// < alpha*[grad(u)+grad(u)^t] , grad(psi) > if (laplaceType == 1) { for (unsigned j = 0; j < dow; ++j) { @@ -163,3 +167,4 @@ void NavierStokes_TaylorHood_RB::closeTimestep(AdaptInfo *adaptInfo) writeFiles(adaptInfo, false); } +} } diff --git a/extensions/base_problems/NavierStokes_TaylorHood_RB.h b/extensions/base_problems/NavierStokes_TaylorHood_RB.h index e2d15f2d00dc1b70a55ebbfab125aa9af46f2fe1..0cc46063f2ca32d089c800e80cbbff75ed2c585a 100644 --- a/extensions/base_problems/NavierStokes_TaylorHood_RB.h +++ b/extensions/base_problems/NavierStokes_TaylorHood_RB.h @@ -23,7 +23,7 @@ #include "POperators.h" #include "BaseProblem_RB.h" -using namespace AMDiS; +namespace AMDiS { namespace base_problems { /** \ingroup NavierStokes_TaylorHood * \brief @@ -90,5 +90,8 @@ protected: // variables FileVectorWriter *fileWriter; }; + +} } + #endif // NAVIER_STOKES_TAYLOR_HOOD_RB_H diff --git a/extensions/base_problems/PhaseFieldCrystal.cc b/extensions/base_problems/PhaseFieldCrystal.cc index e6f936202dfdd52ec0eb797d710217c4c8970e5f..37522fec06cc6fa22ed71f4e3d138a03c06c6dec 100644 --- a/extensions/base_problems/PhaseFieldCrystal.cc +++ b/extensions/base_problems/PhaseFieldCrystal.cc @@ -1,142 +1,11 @@ -/****************************************************************************** - * - * Extension of AMDiS - Adaptive multidimensional simulations - * - * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. - * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis - * - * Authors: Simon Praetorius et al. - * - * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * - * See also license.opensource.txt in the distribution. - * - ******************************************************************************/ #include "PhaseFieldCrystal.h" +#include "ProblemStat.h" +#include "ExtendedProblemStat.h" -using namespace AMDiS; - -PhaseFieldCrystal::PhaseFieldCrystal(const std::string &name_, bool createProblem) : - super(name_, createProblem), - useMobility(false), - tempParameter(-0.6), - r(-0.4), // temperature deviation - q(sqrt(3.0)/2.0), // lattice constant - density(-0.3), // mean density - two(2.0), - minus2(-2.0) -{ - Parameters::get(name + "->r",r); - Parameters::get(name + "->density", density); - Parameters::get(name + "->q", q); - Parameters::get(name + "->use mobility", useMobility); - tempParameter= -(1.0+r); - - q /= sqrt(3.0)/2.0; - q2 = 1.0/sqr(q); - twoQ2 = 2.0*q2; -} - - -void PhaseFieldCrystal::fillOperators() -{ - int degree = prob->getFeSpace(0)->getBasisFcts()->getDegree(); - - // phi*rho - Operator *opMnew = new Operator(prob->getFeSpace(0), prob->getFeSpace(0)); - ZeroOrderTerm *simple_zot = new Simple_ZOT; - operatorTermList.push_back(simple_zot); - opMnew->addTerm(simple_zot); - operatorList.push_back(opMnew); - - Operator *opMold = new Operator(prob->getFeSpace(0), prob->getFeSpace(0)); - ZeroOrderTerm *vecAtQP_zot = new VecAtQP_ZOT(prob->getSolution()->getDOFVector(0)); - operatorTermList.push_back(vecAtQP_zot); - opMold->addTerm(vecAtQP_zot); - operatorList.push_back(opMold); - - // -nabla*(phi*grad(rho)) - Operator *opL = new Operator(prob->getFeSpace(0), prob->getFeSpace(0)); - SecondOrderTerm *simple_sot = new Simple_SOT; - operatorTermList.push_back(simple_sot); - opL->addTerm(simple_sot); - operatorList.push_back(opL); - - double M0 = 1.0; - Parameters::get(name + "->M0", M0); - Operator *opLM = new Operator(prob->getFeSpace(0), prob->getFeSpace(0)); - SecondOrderTerm *mobility_sot; - if (useMobility) // non-constant mobility - mobility_sot = new VecAtQP_SOT( - prob->getSolution()->getDOFVector(0), - new MobilityPfc(density, M0, degree)); - else // constant mobility - mobility_sot = new Simple_SOT(M0); - operatorTermList.push_back(mobility_sot); - opLM->addTerm(mobility_sot); - operatorList.push_back(opLM); - - // -2*rho_old^3 - Operator *opMPowExpl = new Operator(prob->getFeSpace(0), prob->getFeSpace(0)); - ZeroOrderTerm *pow3_zot = new VecAtQP_ZOT(prob->getSolution()->getDOFVector(0),new AMDiS::Pow<3>(-2.0, 3*degree)); - operatorTermList.push_back(pow3_zot); - opMPowExpl->addTerm(pow3_zot); - operatorList.push_back(opMPowExpl); +namespace AMDiS { namespace base_problems { - // -3*rho_old^2 - Operator *opMPowImpl = new Operator(prob->getFeSpace(0), prob->getFeSpace(0)); - ZeroOrderTerm *pow2_zot = new VecAtQP_ZOT(prob->getSolution()->getDOFVector(0),new AMDiS::Pow<2>(-3.0, 2*degree)); - operatorTermList.push_back(pow2_zot); - opMPowImpl->addTerm(pow2_zot); - operatorList.push_back(opMPowImpl); - - // 0 = nu-laplace(rho) - // ------------------- - prob->addMatrixOperator(opL, 0, 0, &q2, &q2); // -laplace(rho) - prob->addMatrixOperator(opMnew, 0, 2); // nu - - // dt(rho) = laplace(mu) - u*grad(rho) - // ----------------------------------- - prob->addMatrixOperator(opMnew, 1, 0, getInvTau(), getInvTau()); - prob->addMatrixOperator(opLM, 1, 1); // -laplace(mu) - // . . . vectorOperators . . . . . . . . . . . . . . . - prob->addVectorOperator(opMold, 1, getInvTau(), getInvTau()); - - // mu-2*nu-laplace(nu)-(1+r)*rho = (rho_old^3) + ExtPot - // ---------------------------------------------------------------------- - prob->addMatrixOperator(opMnew, 2, 0, &tempParameter, &tempParameter); // -phi*(1+r)*rho - prob->addMatrixOperator(opMPowImpl, 2, 0); // -3*rho*rho_old^2 - prob->addMatrixOperator(opL, 2, 0, &twoQ2, &twoQ2); // -2*phi*laplace(rho) * psi - prob->addMatrixOperator(opMnew, 2, 1); // phi*mu * psi - prob->addMatrixOperator(opL, 2, 2, &q2, &q2); // phi*grad(nu) * grad(psi) - // . . . vectorOperators . . . . . . . . . . . . . . . - prob->addVectorOperator(opMPowExpl, 2); // -2*phi^old*rho_old^3 - - // ===== ADD a zero-.operator ALL blocks ============== - Operator *opZero = new Operator(prob->getFeSpace(0), prob->getFeSpace(0)); - ZeroOrderTerm *zero_zot = new Simple_ZOT(0.0); - operatorTermList.push_back(zero_zot); - opZero->addTerm(zero_zot); - operatorList.push_back(opZero); - - prob->addMatrixOperator(opZero, 0, 1); - prob->addMatrixOperator(opZero, 1, 2); -} - - -void PhaseFieldCrystal::finalizeData() -{ - setAssembleMatrixOnlyOnce_butTimestepChange(0,0); - setAssembleMatrixOnlyOnce_butTimestepChange(0,2); - - setAssembleMatrixOnlyOnce_butTimestepChange(1,0); - if (!useMobility) - setAssembleMatrixOnlyOnce_butTimestepChange(1,1); - - setAssembleMatrixOnlyOnce_butTimestepChange(2,1); - setAssembleMatrixOnlyOnce_butTimestepChange(2,2); -} - + // explicit template instantiation + template class detail::PhaseFieldCrystal<ProblemStat>; + template class detail::PhaseFieldCrystal<extensions::ExtendedProblemStat>; +} } diff --git a/extensions/base_problems/PhaseFieldCrystal.h b/extensions/base_problems/PhaseFieldCrystal.h index 6faea9860252a0c2acebc5759e5c9fda31903b49..a0c2c8049dc8042da6c8ffc414fa1116481447e4 100644 --- a/extensions/base_problems/PhaseFieldCrystal.h +++ b/extensions/base_problems/PhaseFieldCrystal.h @@ -1,19 +1,4 @@ -/****************************************************************************** - * - * Extension of AMDiS - Adaptive multidimensional simulations - * - * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. - * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis - * - * Authors: Simon Praetorius et al. - * - * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * - * See also license.opensource.txt in the distribution. - * - ******************************************************************************/ +/** \file PhaseFieldCrystal.h */ #ifndef PHASE_FIELD_CRYSTAL_H #define PHASE_FIELD_CRYSTAL_H @@ -22,82 +7,52 @@ #include "BaseProblem.h" #include "ExtendedProblemStat.h" -using namespace AMDiS; +namespace AMDiS { namespace base_problems { -/** Phase-field Crystal problem -*/ -class PhaseFieldCrystal : public BaseProblem<ExtendedProblemStat> -{ -public: // typedefs +namespace detail { - typedef BaseProblem<ExtendedProblemStat> super; - -public: // methods - - PhaseFieldCrystal(const std::string &name_, bool createProblem = true); - ~PhaseFieldCrystal() {}; - - void fillOperators() override; - void finalizeData() override; - - void setDensity(double density_) + /** Phase-field Crystal problem: + * + * mu = psi^3 + (1+r)*psi + 2*laplace(psi) + laplace(nu) + * d_t(psi) = div( (psi + 1.5) * grad(mu) ) + * nu = laplace(psi) + */ + template<typename ProblemStatType> + class PhaseFieldCrystal : public BaseProblem<ProblemStatType> { - density = density_; - } + public: // typedefs + + typedef PhaseFieldCrystal<ProblemStatType> self; + typedef BaseProblem<ProblemStatType> super; -protected: // methods - - double* getTempParameter() { return &tempParameter; } - -protected: // variables - - bool useMobility; - - double tempParameter; - double r; - double q; - double q2; - double rho0; - double density; - double two; - double twoQ2; - double minus2; -}; - - -/** \ingroup MainInstat - * \brief - * Abstract function to calculate the pure PFC-Energy - */ -class Energy : public BinaryAbstractFunction<double,double,double> -{ public: - Energy() : BinaryAbstractFunction<double,double,double>(4) { } + + PhaseFieldCrystal(const std::string &name_, bool createProblem = true); + ~PhaseFieldCrystal() {} - double operator()(const double &rho, const double &mu) const { - return -0.25*sqr(sqr(rho)) + 0.5*rho*mu; } -}; + DOFVector<double>* getDensity() { return self::prob->getSolution(1); } + double calcEnergy(); + void fillOperators() override ; + void fillBoundaryConditions() override {}; -class MobilityPfc : public AbstractFunction<double,double> -{ - public: - MobilityPfc(double density_ = -0.3, double factor_ = 1.0, int degree=1) : - AbstractFunction<double,double>(degree+1), - density(density_), - factor(factor_), - delta(1.e-6) { } - - double operator()(const double &rho) const - { - double mobility= std::abs(rho + 1.5)*factor; - return std::max(mobility, 0.0); - } - protected: + + bool useMobility; + + double r; + double rho0; double density; - double factor; - double delta; -}; + double M0; + }; + +} // end namespace detail + +typedef detail::PhaseFieldCrystal<AMDiS::ProblemStat> PhaseFieldCrystal; + + +} } + +#include "PhaseFieldCrystal.hh" #endif // PHASE_FIELD_CRYSTAL_H diff --git a/extensions/base_problems/PhaseFieldCrystal.hh b/extensions/base_problems/PhaseFieldCrystal.hh new file mode 100644 index 0000000000000000000000000000000000000000..acec2f6688dccb060274bb81d024d753dc65f10e --- /dev/null +++ b/extensions/base_problems/PhaseFieldCrystal.hh @@ -0,0 +1,95 @@ + +#include "GenericOperatorTerm.h" + +namespace AMDiS { namespace base_problems { + + namespace detail + { + template<typename P> + PhaseFieldCrystal<P>::PhaseFieldCrystal(const std::string &name_, bool createProblem) : + super(name_, createProblem), + useMobility(false), + r(-0.4), // temperature deviation + rho0(1.0), // liquid density + density(-0.3), // mean density + M0(1.0) // mobility + { + Parameters::get(name_ + "->r",r); + Parameters::get(name_ + "->rho0", rho0); + Parameters::get(name_ + "->density", density); + Parameters::get(name_ + "->M0", M0); + Parameters::get(name_ + "->use mobility", useMobility); + } + + + template<typename P> + void PhaseFieldCrystal<P>::fillOperators() + { + const FiniteElemSpace* feSpace0 = self::prob->getFeSpace(0); + const FiniteElemSpace* feSpace1 = self::prob->getFeSpace(1); + const FiniteElemSpace* feSpace2 = self::prob->getFeSpace(2); + + DOFVector<double>* rho = self::prob->getSolution(1); + + // dt(rho) = laplace(mu) - u*grad(rho) + // ----------------------------------- + Operator *opM11 = new Operator(feSpace1, feSpace1); + addZOT(opM11, 1.0); + self::prob->addMatrixOperator(opM11, 1, 1); + + Operator *opLM = new Operator(feSpace1, feSpace0); + if (useMobility) + addSOT(opLM, max(abs_(valueOf(rho) + 1.5)*M0, 1.e-5)); + else + addSOT(opLM, M0); + self::prob->addMatrixOperator(opLM, 1, 0, self::getTau(), self::getTau()); // -laplace(mu) + + // . . . vectorOperators . . . . . . . . . . . . . . . + Operator *opMold = new Operator(feSpace1); + addZOT(opMold, valueOf(rho)); + self::prob->addVectorOperator(opMold, 1); + + // mu-2*nu-laplace(nu)-(1+r)*rho = (rho_old^3) + ExtPot - eps^2/(rho_old+0.9) + // ---------------------------------------------------------------------- + Operator *op01 = new Operator(feSpace0, feSpace1); + addZOT(op01, -(1.0 + ref_(r)) - 3.0 * pow<2>(valueOf(rho)) ); + addSOT(op01, 2.0); + self::prob->addMatrixOperator(op01, 0, 1); + + Operator *op00 = new Operator(feSpace0, feSpace0); + addZOT(op00, 1.0); + self::prob->addMatrixOperator(op00, 0, 0); + + Operator *op02 = new Operator(feSpace0, feSpace2); + addSOT(op02, 1.0); + self::prob->addMatrixOperator(op02, 0, 2); + + // . . . vectorOperators . . . . . . . . . . . . . . . + Operator *op0 = new Operator(feSpace0); + addZOT(op0, -2.0 * pow<3>(valueOf(rho)) ); + self::prob->addVectorOperator(op0, 0); + + // 0 = nu-laplace(rho) + // ------------------- + Operator *op21 = new Operator(feSpace2, feSpace1); + addSOT(op21, 1.0); + self::prob->addMatrixOperator(op21, 2, 1); // -laplace(rho) + + Operator *op22 = new Operator(feSpace2, feSpace2); + addZOT(op22, 1.0); + self::prob->addMatrixOperator(op22, 2, 2); // nu + } + + + template<typename P> + double PhaseFieldCrystal<P>::calcEnergy() + { + DOFVector<double>* rho = self::prob->getSolution(1); + DOFVector<double>* mu = self::prob->getSolution(0); + + return integrate( 0.5*valueOf(rho)*valueOf(mu) - 0.25*pow<4>(valueOf(rho)) ); + } + + } // end namespace detail + +} } diff --git a/extensions/base_problems/PhaseFieldCrystal_Phase.cc b/extensions/base_problems/PhaseFieldCrystal_Phase.cc index d5fbdca4b0fae1398437258fef0e03f7958e801b..ce0f0e583db4e8f692c937dd2ec2de6eaee956fe 100644 --- a/extensions/base_problems/PhaseFieldCrystal_Phase.cc +++ b/extensions/base_problems/PhaseFieldCrystal_Phase.cc @@ -1,98 +1,11 @@ -/****************************************************************************** - * - * Extension of AMDiS - Adaptive multidimensional simulations - * - * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. - * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis - * - * Authors: Simon Praetorius et al. - * - * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * - * See also license.opensource.txt in the distribution. - * - ******************************************************************************/ #include "PhaseFieldCrystal_Phase.h" +#include "ProblemStat.h" +#include "ExtendedProblemStat.h" -using namespace std; -using namespace AMDiS; - -PhaseFieldCrystal_Phase::PhaseFieldCrystal_Phase(const std::string &name_) : - PhaseFieldCrystal(name_), - phase(NULL), - phaseDisturbed(NULL) -{} - - -PhaseFieldCrystal_Phase::~PhaseFieldCrystal_Phase() -{ - delete phase; - delete phaseDisturbed; -} - - -void PhaseFieldCrystal_Phase::initTimeInterface() -{ - PhaseFieldCrystal::initTimeInterface(); -} - - -void PhaseFieldCrystal_Phase::fillOperators() -{ - int degree = prob->getFeSpace(0)->getBasisFcts()->getDegree(); - - // phi*rho - Operator *opMnew = new Operator(prob->getFeSpace(0), prob->getFeSpace(0)); - opMnew->addTerm(new VecAtQP_ZOT(phaseDisturbed)); - Operator *opMold = new Operator(prob->getFeSpace(0), prob->getFeSpace(0)); - opMold->addTerm(new VecAtQP_ZOT(phaseDisturbed)); - - // -nabla*(phi*grad(rho)) - Operator *opL = new Operator(prob->getFeSpace(0), prob->getFeSpace(0)); - opL->addTerm(new Phase_SOT(phaseDisturbed)); +namespace AMDiS { namespace base_problems { - Operator *opLM = new Operator(prob->getFeSpace(0), prob->getFeSpace(0)); - if (useMobility) // non-constant mobility - opLM->addTerm(new Vec2AtQP_SOT( - phaseDisturbed, - prob->getSolution()->getDOFVector(0), - new MobilityPhasePfc(density, rho0, degree))); - else // constant mobility - opLM->addTerm(new VecAtQP_SOT(phaseDisturbed)); - - // -(1+r)*phi*rho - Operator *opMTemp = new Operator(prob->getFeSpace(0), prob->getFeSpace(0)); - opMTemp->addZeroOrderTerm(new VecAtQP_ZOT(phaseDisturbed)); - // -2*rho_old^3 - Operator *opMPowExpl = new Operator(prob->getFeSpace(0), prob->getFeSpace(0)); - opMPowExpl->addZeroOrderTerm(new MultVecAtQP_ZOT(phaseDisturbed, prob->getSolution()->getDOFVector(0), new AMDiS::Id<double>(degree), new AMDiS::Pow<3>(-2.0, 3*degree))); - // -3*rho_old^2 - Operator *opMPowImpl = new Operator(prob->getFeSpace(0), prob->getFeSpace(0)); - opMPowImpl->addZeroOrderTerm(new MultVecAtQP_ZOT(phaseDisturbed, prob->getSolution()->getDOFVector(0), new AMDiS::Id<double>(degree), new AMDiS::Pow<2>(-3.0, 2*degree))); - - // 0 = nu-laplace(rho) - // ------------------- - prob->addMatrixOperator(opL, 0, 0); // -laplace(rho) - prob->addMatrixOperator(opMnew, 0, 2); // nu - - // dt(rho) = laplace(mu) - u*grad(rho) - // ----------------------------------- - prob->addMatrixOperator(opMnew, 1, 0, getInvTau()); - prob->addMatrixOperator(opLM, 1, 1); // -laplace(mu) - // . . . vectorOperators . . . . . . . . . . . . . . . - opMold->setUhOld(prob->getSolution()->getDOFVector(0)); - prob->addVectorOperator(opMold, 1, getInvTau()); + // explicit template instantiation + template class detail::PhaseFieldCrystal_Phase<ProblemStat>; + template class detail::PhaseFieldCrystal_Phase<extensions::ExtendedProblemStat>; - // mu-2*nu-laplace(nu)-(1+r)*rho = (rho_old^3) + ExtPot - eps^2/(rho_old+0.9) - // ---------------------------------------------------------------------- - prob->addMatrixOperator(opMTemp, 2, 0, getTempParameter()); // -phi*(1+r)*rho - prob->addMatrixOperator(opMPowImpl, 2, 0); // -3*rho*rho_old^2 - prob->addMatrixOperator(opL, 2, 0, &two); // -2*phi*laplace(rho) * psi - prob->addMatrixOperator(opMnew, 2, 1); // phi*mu * psi - prob->addMatrixOperator(opL, 2, 2); // phi*grad(nu) * grad(psi) - // prob.addMatrixOperator(opMnew,2,2,&minus2); - // . . . vectorOperators . . . . . . . . . . . . . . . - prob->addVectorOperator(opMPowExpl, 2); // -2*phi^old*rho_old^3 -} +} } diff --git a/extensions/base_problems/PhaseFieldCrystal_Phase.h b/extensions/base_problems/PhaseFieldCrystal_Phase.h index da737b35ccbb0e0a5b9b0a0ba82cd18620d591dc..5e1b0510009e53b78fcab8181bc764fb50d3d809 100644 --- a/extensions/base_problems/PhaseFieldCrystal_Phase.h +++ b/extensions/base_problems/PhaseFieldCrystal_Phase.h @@ -19,81 +19,61 @@ #define PHASE_FIELD_CRYSTAL_PHASE_H #include "PhaseFieldCrystal.h" -#include "PhaseFieldConvert.h" -#include "POperators.h" +#include "GenericOperatorTerm.h" -using namespace AMDiS; +namespace AMDiS { namespace base_problems { -/** Phase-field Crystal problem in diffuse domain - */ -class PhaseFieldCrystal_Phase : public PhaseFieldCrystal -{ -public: // typedefs + namespace detail + { + + /** Phase-field Crystal problem in diffuse domain + */ + template<typename ProblemStatType> + class PhaseFieldCrystal_Phase : public PhaseFieldCrystal<ProblemStatType> + { + public: // typedefs - typedef PhaseFieldCrystal super; + typedef PhaseFieldCrystal_Phase<ProblemStatType> self; + typedef PhaseFieldCrystal<ProblemStatType> super; -public: // methods + public: // methods - PhaseFieldCrystal_Phase(const std::string &name_); - ~PhaseFieldCrystal_Phase(); + PhaseFieldCrystal_Phase(const std::string &name_); + ~PhaseFieldCrystal_Phase(); - void initTimeInterface(); + DOFVector<double> *getPhase() + { + return phase; + } - DOFVector<double> *getPhase() - { - return phase; - } + void setPhase(DOFVector<double>* phase_) + { + if (phase == NULL) + phase = new DOFVector<double>(self::prob->getFeSpace(1), "phase"); + if (phaseDisturbed == NULL) + phaseDisturbed = new DOFVector<double>(self::prob->getFeSpace(1), "phaseDisturbed"); - void setPhase(DOFVector<double>* phase_) - { - if (phase == NULL) - phase = new DOFVector<double>(prob->getFeSpace(0), "phase"); - if (phaseDisturbed == NULL) - phaseDisturbed = new DOFVector<double>(prob->getFeSpace(0), "phaseDisturbed"); + phase->interpol(phase_); + *phaseDisturbed << max(valueOf(phase), 1.e-6); + }; - phase->interpol(phase_); - transformDOF(phase, 1.e-6, phaseDisturbed, new Max<double>); - }; + void fillOperators() override; + + double calcEnergy(); - void fillOperators(); + private: // variables -private: // variables + DOFVector<double> *phase; + DOFVector<double> *phaseDisturbed; + }; + + } // end namespace detail - DOFVector<double> *phase; - DOFVector<double> *phaseDisturbed; -}; +typedef detail::PhaseFieldCrystal_Phase<AMDiS::ProblemStat> PhaseFieldCrystal_Phase; -///Abstract function to calculate the pure PFC-Energy -class EnergyPhase : public TertiaryAbstractFunction<double,double,double,double> -{ - public: - EnergyPhase() : TertiaryAbstractFunction<double,double,double,double>(5) { } +} } - double operator()(const double &phase, const double &rho, const double &mu) const { - return phase * (-0.25*sqr(sqr(rho)) + 0.5*rho*mu); } -}; - -/// AbstractFunction that defines the pfc-mobility, depending on the density an minimal density -class MobilityPhasePfc : public BinaryAbstractFunction<double,double,double> -{ - public: - MobilityPhasePfc(double density_ = -0.3, double factor_ = 1.0, int degree=1) : - BinaryAbstractFunction<double,double,double>(2*degree + 1), - density(density_), - factor(factor_), - delta(1.e-6) { } - - double operator()(const double &phase, const double &rho) const - { - double mobility= abs(rho - 3.0*density)*factor; - return std::max(phase*mobility, delta); - } - - protected: - double density; - double factor; - double delta; -}; +#include "PhaseFieldCrystal_Phase.hh" #endif // PHASE_FIELD_CRYSTAL_PHASE_H diff --git a/extensions/base_problems/PhaseFieldCrystal_Phase.hh b/extensions/base_problems/PhaseFieldCrystal_Phase.hh new file mode 100644 index 0000000000000000000000000000000000000000..b65cc9a29abfde42d9761f0d08c74837f44b7695 --- /dev/null +++ b/extensions/base_problems/PhaseFieldCrystal_Phase.hh @@ -0,0 +1,92 @@ +namespace AMDiS { namespace base_problems { + + namespace detail + { + +template<typename P> +PhaseFieldCrystal_Phase<P>::PhaseFieldCrystal_Phase(const std::string &name_) : + super(name_), + phase(NULL), + phaseDisturbed(NULL) +{} + + +template<typename P> +PhaseFieldCrystal_Phase<P>::~PhaseFieldCrystal_Phase() +{ + delete phase; + delete phaseDisturbed; +} + + +template<typename P> +void PhaseFieldCrystal_Phase<P>::fillOperators() +{ + const FiniteElemSpace* feSpace0 = self::prob->getFeSpace(0); + const FiniteElemSpace* feSpace1 = self::prob->getFeSpace(1); + const FiniteElemSpace* feSpace2 = self::prob->getFeSpace(2); + + DOFVector<double>* rho = self::prob->getSolution(1); + + // dt(rho) = laplace(mu) - u*grad(rho) + // ----------------------------------- + Operator *opM11 = new Operator(feSpace1, feSpace1); + addZOT(opM11, valueOf(phaseDisturbed)); + self::prob->addMatrixOperator(opM11, 1, 1); + + Operator *opLM = new Operator(feSpace1, feSpace0); + if (super::useMobility) + addSOT(opLM, valueOf(phaseDisturbed) * max(abs_(valueOf(rho) + 1.5)*super::M0, 1.e-5)); + else + addSOT(opLM, valueOf(phaseDisturbed) * super::M0); + self::prob->addMatrixOperator(opLM, 1, 0, self::getTau(), self::getTau()); // -laplace(mu) + + // . . . vectorOperators . . . . . . . . . . . . . . . + Operator *opMold = new Operator(feSpace1); + addZOT(opMold, valueOf(rho) * valueOf(phaseDisturbed)); + self::prob->addVectorOperator(opMold, 1); + + // mu-2*nu-laplace(nu)-(1+r)*rho = (rho_old^3) + ExtPot - eps^2/(rho_old+0.9) + // ---------------------------------------------------------------------- + Operator *op01 = new Operator(feSpace0, feSpace1); + addZOT(op01, valueOf(phaseDisturbed) * ( -(1.0 + ref_(super::r)) - 3.0 * pow<2>(valueOf(rho)) ) ); + addSOT(op01, 2.0 * valueOf(phaseDisturbed)); + self::prob->addMatrixOperator(op01, 0, 1); + + Operator *op00 = new Operator(feSpace0, feSpace0); + addZOT(op00, valueOf(phaseDisturbed)); + self::prob->addMatrixOperator(op00, 0, 0); + + Operator *op02 = new Operator(feSpace0, feSpace2); + addSOT(op02, valueOf(phaseDisturbed)); + self::prob->addMatrixOperator(op02, 0, 2); + + // . . . vectorOperators . . . . . . . . . . . . . . . + Operator *op0 = new Operator(feSpace0); + addZOT(op0, -2.0 * valueOf(phaseDisturbed) * pow<3>(valueOf(rho)) ); + self::prob->addVectorOperator(op0, 0); + + // 0 = nu-laplace(rho) + // ------------------- + Operator *op21 = new Operator(feSpace2, feSpace1); + addSOT(op21, valueOf(phaseDisturbed)); + self::prob->addMatrixOperator(op21, 2, 1); // -laplace(rho) + + Operator *op22 = new Operator(feSpace2, feSpace2); + addZOT(op22, valueOf(phaseDisturbed)); + self::prob->addMatrixOperator(op22, 2, 2); // nu +} + + +template<typename P> +double PhaseFieldCrystal_Phase<P>::calcEnergy() +{ + DOFVector<double>* rho = self::prob->getSolution(1); + DOFVector<double>* mu = self::prob->getSolution(0); + + return integrate( valueOf(phase) * ( 0.5*valueOf(rho)*valueOf(mu) - 0.25*pow<4>(valueOf(rho)) ) ); +} + +} // end namespace detail + +} } diff --git a/extensions/base_problems/PhaseFieldCrystal_RB.cc b/extensions/base_problems/PhaseFieldCrystal_RB.cc index 526517830b6a5d64124c3cef1c9f05bc3a8eb027..3970a799dbeb50115da9869bf6bdbec0ddcbe2a7 100644 --- a/extensions/base_problems/PhaseFieldCrystal_RB.cc +++ b/extensions/base_problems/PhaseFieldCrystal_RB.cc @@ -16,8 +16,9 @@ ******************************************************************************/ #include "PhaseFieldCrystal_RB.h" +namespace AMDiS { namespace base_problems { + using namespace std; -using namespace AMDiS; PhaseFieldCrystal_RB::PhaseFieldCrystal_RB(const std::string &name_, bool createProblem) : super(name_, createProblem), @@ -128,3 +129,5 @@ void PhaseFieldCrystal_RB::fillOperators() void PhaseFieldCrystal_RB::fillBoundaryConditions() { } + +} } diff --git a/extensions/base_problems/PhaseFieldCrystal_RB.h b/extensions/base_problems/PhaseFieldCrystal_RB.h index c986c9d136383832cdcd96208ef0c37193c9554d..881f48e4e678e5153b71c70db9e7d1076844b546 100644 --- a/extensions/base_problems/PhaseFieldCrystal_RB.h +++ b/extensions/base_problems/PhaseFieldCrystal_RB.h @@ -21,7 +21,8 @@ #include "AMDiS.h" #include "BaseProblem_RB.h" -using namespace AMDiS; + +namespace AMDiS { namespace base_problems { /** Phase-field Crystal problem */ @@ -118,4 +119,6 @@ class MobilityPfcDiff : public AbstractFunction<double,double> double rho0; }; +} } + #endif // PHASE_FIELD_CRYSTAL_H diff --git a/extensions/base_problems/PolarizationField.cc b/extensions/base_problems/PolarizationField.cc new file mode 100644 index 0000000000000000000000000000000000000000..bb97e0779cdafb7775a5b7c16ab8901127fd983b --- /dev/null +++ b/extensions/base_problems/PolarizationField.cc @@ -0,0 +1,11 @@ +#include "PolarizationField.h" +#include "ProblemStat.h" +#include "ExtendedProblemStat.h" + +namespace AMDiS { namespace base_problems { + + // explicit template instantiation + template class detail::PolarizationField<ProblemStat>; + template class detail::PolarizationField<extensions::ExtendedProblemStat>; + +} } diff --git a/extensions/base_problems/PolarizationField.h b/extensions/base_problems/PolarizationField.h index 1439641ba02e240aae023c9025675e8e916570d1..7ca6159ab9444dd028bd144668eedaad7ed43d34 100644 --- a/extensions/base_problems/PolarizationField.h +++ b/extensions/base_problems/PolarizationField.h @@ -22,10 +22,10 @@ #include "BaseProblem.h" #include "GenericOperatorTerm.h" -namespace detail -{ - using namespace AMDiS; +namespace AMDiS { namespace base_problems { +namespace detail +{ /** \ingroup BaseProblems * \brief * Simulation of the relaxation of an orientation field (polarization field). @@ -103,18 +103,10 @@ namespace detail void calcVectorField() { - if (self::dow == 1) - transformDOF(self::prob->getSolution()->getDOFVector(0), - vectorField, new AMDiS::Vec1WorldVec<double>); - else if (self::dow == 2) - transformDOF(self::prob->getSolution()->getDOFVector(0), - self::prob->getSolution()->getDOFVector(1), - vectorField, new AMDiS::Vec2WorldVec<double>); - else if (self::dow == 3) - transformDOF(self::prob->getSolution()->getDOFVector(0), - self::prob->getSolution()->getDOFVector(1), - self::prob->getSolution()->getDOFVector(2), - vectorField, new AMDiS::Vec3WorldVec<double>); + WorldVector<DOFVector<double>*> P; + for (size_t i = 0; i < self::dow; i++) + P[i] = self::prob->getSolution()->getDOFVector(i); + *vectorField << valueOf(P); } double oldTimestep; @@ -134,11 +126,11 @@ namespace detail } // end namespace detail -#include "PolarizationField.hh" - -typedef ::detail::PolarizationField<AMDiS::ProblemStat> PolarizationField; +typedef detail::PolarizationField<AMDiS::ProblemStat> PolarizationField; +} } +#include "PolarizationField.hh" #endif // POLARIZATION_FIELD_H diff --git a/extensions/base_problems/PolarizationField.hh b/extensions/base_problems/PolarizationField.hh index 0a8d5c33e09ed30249b0de511549a6dd0eb4ee5d..513968a4a8263e81064da8b7c778fc6edf153108 100644 --- a/extensions/base_problems/PolarizationField.hh +++ b/extensions/base_problems/PolarizationField.hh @@ -17,9 +17,9 @@ #include "Helpers.h" -namespace detail { +namespace AMDiS { namespace base_problems { -using namespace AMDiS; +namespace detail { template<typename P> PolarizationField<P>::PolarizationField(const std::string &name_) : @@ -86,6 +86,11 @@ void PolarizationField<P>::initData() for (size_t i = 0; i < self::dow; i++) oldSolution[i] = new DOFVector<double>(self::getFeSpace(i), "old(v_"+Helpers::toString(i)+")"); +#ifdef HAVE_PARALLEL_DOMAIN_AMDIS + for (size_t i = 0; i < self::dow; i++) + Parallel::MeshDistributor::globalMeshDistributor->addInterchangeVector(oldSolution[i]); +#endif + fileWriter = new FileVectorWriter(self::name + "->vectorField->output", self::getFeSpace()->getMesh(), vectorField); super::initData(); @@ -116,7 +121,7 @@ void PolarizationField<P>::fillOperators() for (size_t i = 0; i < self::dow; ++i) { /// < (1/tau)*P_i , psi > Operator *opTime = new Operator(feSpace, feSpace); - addZOT(opTime, constant(1.0)); + addZOT(opTime, 1.0); self::prob->addMatrixOperator(*opTime, i, i, self::getInvTau(), self::getInvTau()); /// < (1/tau)*P_i^old , psi > @@ -126,8 +131,8 @@ void PolarizationField<P>::fillOperators() /// Diffusion-Operator Operator *opLaplace = new Operator(feSpace, feSpace); - addSOT(opLaplace, constant(alpha2)); - addZOT(opLaplace, constant(alpha4)); + addSOT(opLaplace, alpha2); + addZOT(opLaplace, alpha4); self::prob->addMatrixOperator(*opLaplace, i, i+self::dow); } @@ -135,12 +140,12 @@ void PolarizationField<P>::fillOperators() for (size_t i = 0; i < self::dow; ++i) { /// < P# , psi > Operator *opM = new Operator(feSpace, feSpace); - addZOT(opM, constant(1.0)); + addZOT(opM, 1.0); self::prob->addMatrixOperator(*opM, i+self::dow, i+self::dow); /// < (-C1 - C4*P^2)*P , psi > Operator *opNonlin = new Operator(feSpace, feSpace); - addZOT(opNonlin, (-C1 - C4 * pow<2>(valueOf(vectorField))) ); + addZOT(opNonlin, (-C1 - C4 * unary_dot(valueOf(vectorField))) ); self::prob->addMatrixOperator(*opNonlin, i+self::dow, i); for (size_t j = 0; j < self::dow; ++j) { @@ -150,14 +155,14 @@ void PolarizationField<P>::fillOperators() } Operator *opNonlin3 = new Operator(feSpace, feSpace); - addZOT(opNonlin3, (-2.0*C4) * valueOf(vec[i]) * pow<2>(valueOf(vectorField)) ); + addZOT(opNonlin3, (-2.0*C4) * valueOf(vec[i]) * unary_dot(valueOf(vectorField)) ); self::prob->addVectorOperator(*opNonlin3, i+self::dow); } fillLaplacian(); Operator *opNull = new Operator(feSpace, feSpace); - addZOT(opNull, constant(0.0)); + addZOT(opNull, 0.0); for (size_t i = 0; i < self::dow; ++i) { for (size_t j = i+1; j < self::dow; ++j) { @@ -179,7 +184,7 @@ void PolarizationField<P>::fillLaplacian() for (size_t i = 0; i < self::dow; ++i) { /// < -K*grad(P) , grad(psi) > Operator *opL = new Operator(feSpace, feSpace); - addSOT(opL, constant(-K)); + addSOT(opL, -K); self::prob->addMatrixOperator(*opL, i+self::dow, i); } } @@ -206,4 +211,6 @@ void PolarizationField<P>::writeFiles(AdaptInfo *adaptInfo, bool force) self::fileWriter->writeFiles(adaptInfo, false); } -} // end namespace detail \ No newline at end of file +} // end namespace detail + +} } diff --git a/extensions/base_problems/PolarizationField_RB.h b/extensions/base_problems/PolarizationField_RB.h index 089f44d2a9faa33e58706e0d8f9e301bdc5adb27..6ef6bf913855dd1ec0652bc3cd76cd24e3ff3e87 100644 --- a/extensions/base_problems/PolarizationField_RB.h +++ b/extensions/base_problems/PolarizationField_RB.h @@ -23,9 +23,10 @@ #include "GenericOperatorTerm.h" +namespace AMDiS { namespace base_problems { + namespace detail { - using namespace AMDiS; /** \ingroup BaseProblems * \brief @@ -128,11 +129,12 @@ namespace detail } // end namespace detail -#include "PolarizationField_RB.hh" - typedef ::detail::PolarizationField_RB<AMDiS::ProblemStat> PolarizationField_RB; +} } +#include "PolarizationField_RB.hh" + #endif // POLARIZATION_FIELD_RB_H diff --git a/extensions/base_problems/PolarizationField_RB.hh b/extensions/base_problems/PolarizationField_RB.hh index 31ff00c8ec8e6139a02053a6e5b954645241dcf2..3e66ef2a87d36b8e8557d473b7ac287fefc4e0ac 100644 --- a/extensions/base_problems/PolarizationField_RB.hh +++ b/extensions/base_problems/PolarizationField_RB.hh @@ -17,9 +17,9 @@ #include "Helpers.h" -namespace detail { +namespace AMDiS { namespace base_problems { -using namespace AMDiS; +namespace detail { template<typename P> PolarizationField_RB<P>::PolarizationField_RB(const std::string &name_) : @@ -184,4 +184,6 @@ void PolarizationField_RB<P>::writeFiles(AdaptInfo *adaptInfo, bool force) self::fileWriter->writeFiles(adaptInfo, false); } -} // end namespace detail \ No newline at end of file +} // end namespace detail + +} } \ No newline at end of file diff --git a/extensions/base_problems/QuasiCrystal.cc b/extensions/base_problems/QuasiCrystal.cc index a7a480971fadc1c3b43ddd38ed4adcb6f2c34926..0b4892633c0ec62732733cae26c30ed8b519bb1f 100644 --- a/extensions/base_problems/QuasiCrystal.cc +++ b/extensions/base_problems/QuasiCrystal.cc @@ -1,116 +1,11 @@ #include "QuasiCrystal.h" +#include "ProblemStat.h" +#include "ExtendedProblemStat.h" -using namespace std; -using namespace AMDiS; - -QuasiCrystal::QuasiCrystal(const std::string &name_) : - super(name_), - q(2.0*cos(m_pi/12.0)), - r(-0.015), - c(50.0), - alpha(1.0), - density(0.0), // mean density - two(2.0), - minus2(-2.0), - three(3.0), - minus3(-3.0) -{ - Parameters::get(name + "->r",r); - Parameters::get(name + "->c", c); - Parameters::get(name + "->q", q); - Parameters::get(name + "->density", density); - Parameters::get(name + "->alpha", alpha); -}; - - -void QuasiCrystal::fillOperators() -{ FUNCNAME("QuasiCrystal::fillOperators()"); - - // - Operator *opM = new Operator(prob->getFeSpace(0), prob->getFeSpace(0)); - opM->addTerm(new Simple_ZOT); - Operator *opMold = new Operator(prob->getFeSpace(0), prob->getFeSpace(0)); - opMold->addTerm(new VecAtQP_ZOT(prob->getSolution()->getDOFVector(0), NULL)); - - // - Operator *opL = new Operator(prob->getFeSpace(0), prob->getFeSpace(0)); - opL->addTerm(new Simple_SOT); - Operator *opL1 = new Operator(prob->getFeSpace(0), prob->getFeSpace(0)); - opL1->addTerm(new Simple_SOT(2.0*sqr(q)*c*(1.0+sqr(q)))); - Operator *opL2 = new Operator(prob->getFeSpace(0), prob->getFeSpace(0)); - opL2->addTerm(new Simple_SOT(sqr(1.0+sqr(q))+2.0*sqr(q))); - Operator *opL3 = new Operator(prob->getFeSpace(0), prob->getFeSpace(0)); - opL3->addTerm(new Simple_SOT(2.0*(1.0+sqr(q)))); - - // - Operator *opLin = new Operator(prob->getFeSpace(0), prob->getFeSpace(0)); - opLin->addZeroOrderTerm(new Simple_ZOT(-c*sqr(sqr(q))-r)); - - Operator *opPow1 = new Operator(prob->getFeSpace(0), prob->getFeSpace(0)); - opPow1->addZeroOrderTerm(new VecAtQP_ZOT(prob->getSolution()->getDOFVector(0))); - // - Operator *opPow2 = new Operator(prob->getFeSpace(0), prob->getFeSpace(0)); - opPow2->addZeroOrderTerm(new VecAtQP_ZOT(prob->getSolution()->getDOFVector(0),new Pow2Functor(1.0))); - // - Operator *opPow3 = new Operator(prob->getFeSpace(0), prob->getFeSpace(0)); - opPow3->addZeroOrderTerm(new VecAtQP_ZOT(prob->getSolution()->getDOFVector(0),new Pow3Functor(1.0))); - - // mu - c*laplace(nu) - laplace1(rho) + lin(rho) + [2rho'-3(rho')^2]*rho = (rho')^2-2*(rho')^3 - // -------------------------------------------------------------------------------------------- - prob->addMatrixOperator(opL1, 0, 0); // -laplace1(rho) - prob->addMatrixOperator(opLin, 0, 0); // lin(rho) - prob->addMatrixOperator(opPow1, 0, 0, &two, &two); // 2rho' * rho - prob->addMatrixOperator(opPow2, 0, 0, &minus3, &minus3); // -3(rho')^2 * rho - - prob->addMatrixOperator(opM, 0, 1); // mu - prob->addMatrixOperator(opL, 0, 2, &c, &c); // -c*laplace(nu) - - prob->addVectorOperator(opPow2, 0); - prob->addVectorOperator(opPow3, 0, &minus2, &minus2); +namespace AMDiS { namespace base_problems { - setAssembleMatrixOnlyOnce_butTimestepChange(0,1); - setAssembleMatrixOnlyOnce_butTimestepChange(0,2); + // explicit template instantiation + template class detail::QuasiCrystal<ProblemStat>; + template class detail::QuasiCrystal<extensions::ExtendedProblemStat>; - // dt(rho) - laplace(mu) = 0 - // ----------------------------------- - prob->addMatrixOperator(opM, 1, 0, getInvTau(), getInvTau()); - prob->addMatrixOperator(opL, 1, 1); // -laplace(mu) - // . . . vectorOperators . . . . . . . . . . . . . . . - prob->addVectorOperator(opMold, 1, getInvTau(), getInvTau()); - - setAssembleMatrixOnlyOnce_butTimestepChange(1,0); - setAssembleMatrixOnlyOnce_butTimestepChange(1,1); - - // nu - laplace2(rho) - laplace(psi) = 0 - // ---------------------------------------------------------------------- - prob->addMatrixOperator(opL2, 2, 0); // -laplace2(rho) - prob->addMatrixOperator(opM, 2, 2); // nu - prob->addMatrixOperator(opL, 2, 3); // -laplace(psi) - - setAssembleMatrixOnlyOnce_butTimestepChange(2,0); - setAssembleMatrixOnlyOnce_butTimestepChange(2,2); - setAssembleMatrixOnlyOnce_butTimestepChange(2,3); - - // psi - laplace3(rho) - laplace(theta) = 0 - // ---------------------------------------------------------------------- - prob->addMatrixOperator(opL3, 3, 0); // -laplace3(rho) - prob->addMatrixOperator(opM, 3, 3); // psi - prob->addMatrixOperator(opL, 3, 4); // -laplace(theta) - - setAssembleMatrixOnlyOnce_butTimestepChange(3,0); - setAssembleMatrixOnlyOnce_butTimestepChange(3,3); - setAssembleMatrixOnlyOnce_butTimestepChange(3,4); - - // theta - laplace(rho) = 0 - // ---------------------------------------------------------------------- - prob->addMatrixOperator(opL, 4, 0); // -laplace(rho) - prob->addMatrixOperator(opM, 4, 4); // theta - - setAssembleMatrixOnlyOnce_butTimestepChange(4,0); - setAssembleMatrixOnlyOnce_butTimestepChange(4,4); -}; - - -void QuasiCrystal::fillBoundaryConditions() -{ FUNCNAME("QuasiCrystal::fillBoundaryConditions()"); -}; +} } diff --git a/extensions/base_problems/QuasiCrystal.h b/extensions/base_problems/QuasiCrystal.h index 6ec240bbd78c8a3e3ceeca8267947d5d6eb6c603..57264b9e611c89a3d9226c244445bee7553f77cc 100644 --- a/extensions/base_problems/QuasiCrystal.h +++ b/extensions/base_problems/QuasiCrystal.h @@ -7,84 +7,53 @@ #include "BaseProblem.h" #include "ExtendedProblemStat.h" -using namespace AMDiS; +namespace AMDiS { namespace base_problems { -/** Phase-field Crystal problem - */ -class QuasiCrystal : public BaseProblem<ExtendedProblemStat> -{ -public: // typedefs +namespace detail { - typedef BaseProblem<ExtendedProblemStat> super; + /** Quasicrystal Phase-field Crystal problem + */ + template<typename ProblemStatType> + class QuasiCrystal : public BaseProblem<ProblemStatType> + { + public: // typedefs -public: + typedef QuasiCrystal<ProblemStatType> self; + typedef BaseProblem<ProblemStatType> super; - QuasiCrystal(const std::string &name_); - ~QuasiCrystal() {}; - - virtual void fillOperators(); - virtual void fillBoundaryConditions(); - -protected: + public: - bool useMobility; + QuasiCrystal(const std::string &name_); + ~QuasiCrystal() {}; - double q; - double r; - double c; - double alpha; - double density; - - double two; - double minus2; - double three; - double minus3; -}; + void fillOperators() override; + void fillBoundaryConditions() {} override; + + void finalizeData() override; + protected: -/** \ingroup MainInstat - * \brief - * Abstract function to calculate the pure PFC-Energy - */ -// class Energy : public BinaryAbstractFunction<double,double,double> -// { -// public: -// Energy() : BinaryAbstractFunction<double,double,double>(4) { } -// -// double operator()(const double &rho, const double &mu) const { -// return -0.25*sqr(sqr(rho)) + 0.5*rho*mu; } -// }; + bool useMobility; + double q; + double r; + double c; + double alpha; + double density; + + double two; + double minus2; + double three; + double minus3; + }; -class Pow2Functor : public AbstractFunction<double,double> -{ - public: - Pow2Functor(double factor_=1.0) : - AbstractFunction<double,double>(2), - factor(factor_) { } - double operator()(const double &ch) const - { - return factor * sqr(ch); - } +} // end namespace detail - protected: - double factor; -}; +typedef detail::QuasiCrystal<AMDiS::ProblemStat> QuasiCrystal; +} } -class Pow3Functor : public AbstractFunction<double,double> -{ - public: - Pow3Functor(double factor_=1.0) : - AbstractFunction<double,double>(3), - factor(factor_) { } - double operator()(const double &ch) const - { - return factor * sqr(ch) * ch; - } +#include "QuasiCrystal.hh" - protected: - double factor; -}; #endif // PHASE_FIELD_CRYSTAL_H diff --git a/extensions/base_problems/QuasiCrystal.hh b/extensions/base_problems/QuasiCrystal.hh new file mode 100644 index 0000000000000000000000000000000000000000..ad186eacdd3a0138757352214bbf8edc7e298a16 --- /dev/null +++ b/extensions/base_problems/QuasiCrystal.hh @@ -0,0 +1,120 @@ + +#include "GenericOperatorTerm.h" + +namespace AMDiS { namespace base_problems { + + namespace detail { + + using namespace std; + + template<typename P> + QuasiCrystal<P>::QuasiCrystal(const std::string &name_) : + super(name_), + q(2.0*std::cos(m_pi/12.0)), + r(-0.015), + c(50.0), + alpha(1.0), + density(0.0), // mean density + two(2.0), + minus2(-2.0), + three(3.0), + minus3(-3.0) + { + Parameters::get(name_ + "->r",r); + Parameters::get(name_ + "->c", c); + Parameters::get(name_ + "->q", q); + Parameters::get(name_ + "->density", density); + Parameters::get(name_ + "->alpha", alpha); + } + + + template<typename P> + void QuasiCrystal<P>::fillOperators() + { FUNCNAME("QuasiCrystal::fillOperators()"); + + const FiniteElemSpace* feSpace = self::getFeSpace(0); + + DOFVector<double>* rho = self::prob->getSolution()->getDOFVector(0); +// DOFVector<double>* mu = self::prob->getSolution()->getDOFVector(1); + + // mass-matrix + Operator *opM = new Operator(feSpace, feSpace); + addZOT(opM, 1.0); + + // laplace-matrix + Operator *opL = new Operator(feSpace, feSpace); + addSOT(opL, 1.0); + + // mu - c*laplace(nu) - laplace1(rho) + lin(rho) + [2rho'-3(rho')^2]*rho = (rho')^2-2*(rho')^3 + // -------------------------------------------------------------------------------------------- + Operator *op00 = new Operator(feSpace, feSpace); + addSOT(op00, (2.0*sqr(q)*c*(1.0+sqr(q)))); + addZOT(op00, (-c*sqr(sqr(q)) - r) + 2.0 * valueOf(rho) - 3.0 * pow<2>(valueOf(rho))); + self::prob->addMatrixOperator(op00, 0, 0); + + self::prob->addMatrixOperator(opM, 0, 1); // mu + self::prob->addMatrixOperator(opL, 0, 2, &c, &c); // -c*laplace(nu) + + Operator *op0 = new Operator(feSpace); + addZOT(op0, pow<2>(valueOf(rho)) - 2.0 * pow<3>(valueOf(rho))); + self::prob->addVectorOperator(op0, 0); + + // dt(rho) - laplace(mu) = 0 + // ----------------------------------- + self::prob->addMatrixOperator(opM, 1, 0, self::getInvTau(), self::getInvTau()); + self::prob->addMatrixOperator(opL, 1, 1); // -laplace(mu) + + // . . . vectorOperators . . . . . . . . . . . . . . . + Operator *opMold = new Operator(feSpace); + addZOT(opMold, valueOf(rho)); + self::prob->addVectorOperator(opMold, 1, self::getInvTau(), self::getInvTau()); + + // nu - laplace2(rho) - laplace(psi) = 0 + // ---------------------------------------------------------------------- + Operator *opL2 = new Operator(feSpace, feSpace); + addSOT(opL2, (sqr(1.0+sqr(q))+2.0*sqr(q))); + self::prob->addMatrixOperator(opL2, 2, 0); // -laplace2(rho) + + self::prob->addMatrixOperator(opM, 2, 2); // nu + self::prob->addMatrixOperator(opL, 2, 3); // -laplace(psi) + + // psi - laplace3(rho) - laplace(theta) = 0 + // ---------------------------------------------------------------------- + Operator *opL3 = new Operator(feSpace, feSpace); + addSOT(opL3, (2.0*(1.0+sqr(q)))); + self::prob->addMatrixOperator(opL3, 3, 0); // -laplace3(rho) + + self::prob->addMatrixOperator(opM, 3, 3); // psi + self::prob->addMatrixOperator(opL, 3, 4); // -laplace(theta) + + // theta - laplace(rho) = 0 + // ---------------------------------------------------------------------- + self::prob->addMatrixOperator(opL, 4, 0); // -laplace(rho) + self::prob->addMatrixOperator(opM, 4, 4); // theta + } + + + template<typename P> + void QuasiCrystal<P>::finalizeData() + { + self::setAssembleMatrixOnlyOnce_butTimestepChange(0,1); + self::setAssembleMatrixOnlyOnce_butTimestepChange(0,2); + + self::setAssembleMatrixOnlyOnce_butTimestepChange(1,0); + self::setAssembleMatrixOnlyOnce_butTimestepChange(1,1); + + self::setAssembleMatrixOnlyOnce_butTimestepChange(2,0); + self::setAssembleMatrixOnlyOnce_butTimestepChange(2,2); + self::setAssembleMatrixOnlyOnce_butTimestepChange(2,3); + + self::setAssembleMatrixOnlyOnce_butTimestepChange(3,0); + self::setAssembleMatrixOnlyOnce_butTimestepChange(3,3); + self::setAssembleMatrixOnlyOnce_butTimestepChange(3,4); + + self::setAssembleMatrixOnlyOnce_butTimestepChange(4,0); + self::setAssembleMatrixOnlyOnce_butTimestepChange(4,4); + } + + } // end namespace detail + +} } // end namespaces diff --git a/extensions/base_problems/QuasiCrystal_RB.cc b/extensions/base_problems/QuasiCrystal_RB.cc index 11d7ebb8738f7bf0f72c1a04c163c19530f12f83..7967a31e5a2ff84446e7d139d8a307a517c2dc07 100644 --- a/extensions/base_problems/QuasiCrystal_RB.cc +++ b/extensions/base_problems/QuasiCrystal_RB.cc @@ -1,7 +1,8 @@ #include "QuasiCrystal_RB.h" +namespace AMDiS { namespace base_problems { + using namespace std; -using namespace AMDiS; QuasiCrystal_RB::QuasiCrystal_RB(const std::string &name_) : super(name_), @@ -155,3 +156,5 @@ void QuasiCrystal_RB::fillOperators() void QuasiCrystal_RB::fillBoundaryConditions() { FUNCNAME("QuasiCrystal_RB::fillBoundaryConditions()"); }; + +} } \ No newline at end of file diff --git a/extensions/base_problems/QuasiCrystal_RB.h b/extensions/base_problems/QuasiCrystal_RB.h index 76eb846beb5ae7a64c01bc8520526b03ec9783be..81ffed4b80a043b52f96478be37817e2565ae4b9 100644 --- a/extensions/base_problems/QuasiCrystal_RB.h +++ b/extensions/base_problems/QuasiCrystal_RB.h @@ -6,7 +6,7 @@ #include "AMDiS.h" #include "BaseProblem_RB.h" -using namespace AMDiS; +namespace AMDiS { namespace base_problems { /** Phase-field Crystal problem */ @@ -87,4 +87,6 @@ class Pow3Functor : public AbstractFunction<double,double> double factor; }; +} } + #endif // PHASE_FIELD_CRYSTAL_H diff --git a/extensions/base_problems/VacancyPhaseFieldCrystal.cc b/extensions/base_problems/VacancyPhaseFieldCrystal.cc index 5fb2f4ce7b8a72a34eafda0b39c33cc02bb05404..0fe310920da2e995faaa696d58ccc6fae1bcbf92 100644 --- a/extensions/base_problems/VacancyPhaseFieldCrystal.cc +++ b/extensions/base_problems/VacancyPhaseFieldCrystal.cc @@ -1,7 +1,8 @@ #include "VacancyPhaseFieldCrystal_Base.h" +namespace AMDiS { namespace base_problems { + using namespace std; -using namespace AMDiS; VacancyPhaseFieldCrystal::VacancyPhaseFieldCrystal(const std::string &name_, bool createProblem) : super(name_, createProblem), @@ -113,3 +114,5 @@ void VacancyPhaseFieldCrystal::fillOperators() // mu prob->addMatrixOperator(opM, 2, 1); }; + +} } diff --git a/extensions/base_problems/VacancyPhaseFieldCrystal.h b/extensions/base_problems/VacancyPhaseFieldCrystal.h index 64386276ea593affd545e360617ec52cb8df8714..351f9608e08889af47a67cc0342fef527b04f653 100644 --- a/extensions/base_problems/VacancyPhaseFieldCrystal.h +++ b/extensions/base_problems/VacancyPhaseFieldCrystal.h @@ -6,7 +6,7 @@ #include "AMDiS.h" #include "BaseProblem.h" -using namespace AMDiS; +namespace AMDiS { namespace base_problems { /** Phase-field Crystal problem */ @@ -74,4 +74,6 @@ class MobilityPfc : public AbstractFunction<double,double> double delta; }; +} } + #endif // PHASE_FIELD_CRYSTAL_H diff --git a/extensions/base_problems/chns.h b/extensions/base_problems/chns.h index 4d719ed0e32b1e7cdb61ea93715a33975bad04c7..92a641accfcfd3ae193a72177be0f9a5c6c34910 100644 --- a/extensions/base_problems/chns.h +++ b/extensions/base_problems/chns.h @@ -20,7 +20,7 @@ #include "AMDiS.h" -using namespace AMDiS; +namespace AMDiS { namespace base_problems { /** \brief * Abstract function for Cahn-Hilliard mobility @@ -245,4 +245,6 @@ private: double factor; }; +} } + #endif // CHNS_FUNCTORS_H diff --git a/extensions/demo/other/CMakeLists.txt b/extensions/demo/other/CMakeLists.txt index cdb89b62521e79e5c9df952a7d69ff1c01b53cb8..0a0c2c05bf672999869d729f64ca228596ea0a59 100644 --- a/extensions/demo/other/CMakeLists.txt +++ b/extensions/demo/other/CMakeLists.txt @@ -43,9 +43,10 @@ set(base_problems_dir ${extensions_dir}/base_problems) # target_link_libraries("rosenbrockTest" ${BASIS_LIBS}) - set(navierStokesDd src/navierStokes_diffuseDomain.cc) - add_executable("navierStokesDd" ${navierStokesDd}) - target_link_libraries("navierStokesDd" ${BASIS_LIBS}) + # in parallel only + # set(navierStokesDd src/navierStokes_diffuseDomain.cc ${extensions_dir}/preconditioner/PetscSolverNavierStokes2.cc) + # add_executable("navierStokesDd" ${navierStokesDd}) + # target_link_libraries("navierStokesDd" ${BASIS_LIBS}) set(navierStokesDd2 src/navierStokes_diffuseDomain2.cc) diff --git a/extensions/demo/other/init/cahnHilliard.dat.2d b/extensions/demo/other/init/cahnHilliard.dat.2d index 07d1f0f39c942d2cd14f96d52cce32d058cb4c09..9d2820cbbb8041cefc106107a5dfc6a4b0f40c0c 100644 --- a/extensions/demo/other/init/cahnHilliard.dat.2d +++ b/extensions/demo/other/init/cahnHilliard.dat.2d @@ -46,12 +46,12 @@ ch->space->mesh: mesh %parallel->repartitioning->imbalance: -1 % ================== SOLVER ====================================== -ch->space->solver: petsc-ch %direct +ch->space->solver: direct ch->space->solver->use old initial guess: 1 -%ch->space->solver->backend: mtl -%ch->space->solver->petsc prefix: ch -%ch->space->solver->symmetric strategy: 0 -%ch->space->solver->store symbolic: 0 +ch->space->solver->backend: mtl +ch->space->solver->petsc prefix: ch +ch->space->solver->symmetric strategy: 0 +ch->space->solver->store symbolic: 0 ch->space->solver->max iteration: 200 ch->space->solver->tolerance: 1.e-8 ch->space->solver->info: 10 diff --git a/extensions/demo/other/src/cahnHilliard_navierStokes.cc b/extensions/demo/other/src/cahnHilliard_navierStokes.cc index 7fd2381e93a009d02e2669fc291a608fbf085842..ab5fdfcc38762dfab90a60381e85cfc300c510a0 100644 --- a/extensions/demo/other/src/cahnHilliard_navierStokes.cc +++ b/extensions/demo/other/src/cahnHilliard_navierStokes.cc @@ -22,14 +22,14 @@ #include "CouplingBaseProblem2.h" #endif #include "CahnHilliard.h" -#include "ProblemStatMassConserve2.h" +#include "ProblemStatMassConserve2.h" // using COARSE_RESTRICT #include "NavierStokes_TaylorHood.h" #include "Refinement.h" #include "MeshFunction_Level.h" using namespace AMDiS; -typedef ::detail::CahnHilliard<ProblemStatMassConserve2> CHType; +typedef base_problems::detail::CahnHilliard<ProblemStatMassConserve2> CHType; typedef NavierStokes_TaylorHood NSType; class CahnHilliardNavierStokes : public CouplingBaseProblem< ProblemStat, CHType, NSType > @@ -92,7 +92,7 @@ public: // methods out << c << "\n"; // activate mass-conservative coarsening - refinement->setRefineOperation(adaptInfo, chProb->getProblem()); +// refinement->setRefineOperation(adaptInfo, chProb->getProblem()); } /// Called at the end of each timestep. @@ -110,6 +110,7 @@ public: // methods out << c << "\n"; refinement->refine(1); + // checkMeshChange } virtual void fillCouplingOperators() @@ -117,14 +118,14 @@ public: // methods double M0 = 1.0; Parameters::get(name + "->M0",M0); + DOFVector<double>* c = chProb->getSolution()->getDOFVector(0); + DOFVector<double>* mu = chProb->getSolution()->getDOFVector(1); + // < grad(mu) * c , theta > for (size_t i = 0; i < dow; i++) { Operator *opCGradMu = new Operator(nsProb->getFeSpace(i), chProb->getFeSpace(0)); - opCGradMu->addTerm(new VecAndPartialDerivative_ZOT( - chProb->getSolution()->getDOFVector(1), - chProb->getSolution()->getDOFVector(0), - i, M0)); + addZOT(opCGradMu, M0 * valueOf(mu) * derivativeOf(c, i) ); nsProb->getProblem(0)->addVectorOperator(opCGradMu, i); } @@ -132,10 +133,8 @@ public: // methods for (size_t i = 0; i < dow; i++) { Operator *opUGradC = new Operator(chProb->getFeSpace(1), chProb->getFeSpace(0)); - opUGradC->addTerm(new VecAndPartialDerivative_FOT( - nsProb->getSolution()->getDOFVector(i), // u_i - i), GRD_PSI); - chProb->getProblem()->addMatrixOperator(opUGradC, 1, 0, &minus1, &minus1); + addFOT(opUGradC, -valueOf(nsProb->getSolution()->getDOFVector(i)), i, GRD_PSI ); + chProb->getProblem()->addMatrixOperator(opUGradC, 1, 0); } } diff --git a/extensions/demo/other/src/fsi_explicit/navierStokes.h b/extensions/demo/other/src/fsi_explicit/navierStokes.h index 93a7d9a13cf27ce7b75e13b874874b94788d2939..21b1d9040e8ed0f2d742a994d091933baa1e5aad 100644 --- a/extensions/demo/other/src/fsi_explicit/navierStokes.h +++ b/extensions/demo/other/src/fsi_explicit/navierStokes.h @@ -21,6 +21,8 @@ #include "AMDiS.h" #include "GeometryTools.h" +using namespace AMDiS; + struct InflowBC : AbstractFunction<double, WorldVector<double> > { InflowBC(double H_=4.1, double Um_=1.5) : H(H_), Um(Um_) {} diff --git a/extensions/demo/other/src/movingMesh.cc b/extensions/demo/other/src/movingMesh.cc index 2dd3f064aec65f050ac0c108177fcf37619e22ef..0816445e252b8ce8a163aee9ae83f3d02b16c182 100644 --- a/extensions/demo/other/src/movingMesh.cc +++ b/extensions/demo/other/src/movingMesh.cc @@ -98,7 +98,7 @@ public: { MSG("closeTimestep()\n"); super::closeTimestep(adaptInfo); - VtkWriter::writeFile(displacementDOF, "displacement_fluid.vtu"); + io::VtkWriter::writeFile(displacementDOF, "displacement_fluid.vtu"); } private: @@ -183,7 +183,7 @@ public: { MSG("closeTimestep()\n"); super::closeTimestep(adaptInfo); - VtkWriter::writeFile(displacementDOF, "displacement_solid.vtu"); + io::VtkWriter::writeFile(displacementDOF, "displacement_solid.vtu"); } private: diff --git a/extensions/demo/other/src/movingMesh.h b/extensions/demo/other/src/movingMesh.h index abacd9d30bff0aead179b95ad35e21fa37ceb47c..60924baaf0fbcf77a726aa6935af3cf3463f6c7c 100644 --- a/extensions/demo/other/src/movingMesh.h +++ b/extensions/demo/other/src/movingMesh.h @@ -307,7 +307,7 @@ public: DOFVector<double> displacement(elastProb->getFeSpace(), "displacement"); displacement.interpol(beamDisplacement); - VtkWriter::writeFile(&displacement, "displacement.vtu"); + io::VtkWriter::writeFile(&displacement, "displacement.vtu"); // flag->move(elastProb->getDeformation()); updateMesh(elastProb->getSolution(), parametricCoords1, parametric1); diff --git a/extensions/demo/other/src/navierStokes.h b/extensions/demo/other/src/navierStokes.h index 0f09d764318d4084538882bd97779c204f43ffca..e00149007cdb6cdb66748c143065eae134a3903c 100644 --- a/extensions/demo/other/src/navierStokes.h +++ b/extensions/demo/other/src/navierStokes.h @@ -19,6 +19,8 @@ #include "AMDiS.h" #include "GeometryTools.h" +using namespace AMDiS; + struct InflowBC : AbstractFunction<double, WorldVector<double> > { InflowBC(double H_=4.1, double Um_=1.5) : H(H_), Um(Um_) {} diff --git a/extensions/demo/other/src/polarizationField_navierStokes.cc b/extensions/demo/other/src/polarizationField_navierStokes.cc index a6e0066bb5ab9efc6762302d965c4c400d01eebb..841ffde89a9284cb72051f6a8e6407d68469b74d 100644 --- a/extensions/demo/other/src/polarizationField_navierStokes.cc +++ b/extensions/demo/other/src/polarizationField_navierStokes.cc @@ -89,10 +89,10 @@ public: /// -struct MyNavierStokes : public ::detail::NavierStokes_TaylorHood<ExtendedProblemStat> +struct MyNavierStokes : public base_problems::detail::NavierStokes_TaylorHood<ExtendedProblemStat> { public: - typedef ::detail::NavierStokes_TaylorHood<ExtendedProblemStat> super; + typedef base_problems::detail::NavierStokes_TaylorHood<ExtendedProblemStat> super; public: MyNavierStokes(std::string name) diff --git a/extensions/demo/pfc/CMakeLists.txt b/extensions/demo/pfc/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..ae50297f6fe55d45c4cf5d1aeef54c88fd394294 --- /dev/null +++ b/extensions/demo/pfc/CMakeLists.txt @@ -0,0 +1,18 @@ +project("extensions_demo_pfc") +cmake_minimum_required(VERSION 2.8) + +find_package(AMDIS REQUIRED) + +if(AMDIS_FOUND) + message("amdis was found\n") + include(${AMDIS_USE_FILE}) + SET(BASIS_LIBS ${AMDIS_LIBRARIES}) +endif(AMDIS_FOUND) + +set(pfc src/pfc.cc) +add_executable("pfc" ${pfc}) +target_link_libraries("pfc" ${BASIS_LIBS}) + +set(pfc_rb src/pfc_rb.cc) +add_executable("pfc_rb" ${pfc_rb}) +target_link_libraries("pfc_rb" ${BASIS_LIBS}) diff --git a/extensions/demo/pfc/init/pfc.dat.2d b/extensions/demo/pfc/init/pfc.dat.2d new file mode 100644 index 0000000000000000000000000000000000000000..505ab9cd667f184a2917c69c7565c5a2d050a4a8 --- /dev/null +++ b/extensions/demo/pfc/init/pfc.dat.2d @@ -0,0 +1,52 @@ +dimension of world: 2 + +% =================== MESH ================================ +mesh->macro file name: ./macro/macro.square.2d +%mesh->periodic file: ./macro/periodic.square.per +mesh->global refinements: 10 +mesh->check: 0 + +lattice: 4*M_PI/sqrt(3) +mesh->scale mesh: 1 +mesh->dimension: [4*${lattice}, 2*sqrt(3)*${lattice}] + +% ============== USER-PARAMETER ========================== +pfc->r: -0.4 +pfc->rho0: 1.0 +pfc->density: -0.3 +pfc->use mobility: 0 + +pfc->density amplitude: 0.2 + +% ============= PROBLEM-SPACE ================================== +pfc->space->mesh: mesh +pfc->space->components: 3 +pfc->space->polynomial degree[0]: 1 +pfc->space->polynomial degree[1]: 1 +pfc->space->polynomial degree[2]: 1 +pfc->space->dim: 2 + + +% ================== SOLVER ====================================== +#include "init/pfc_solver.inc" + + +% ==================== TIMESTEPS =============================== +adapt->timestep: 1.e-1 +adapt->max timestep: 1e+10 +adapt->min timestep: 1e-10 +adapt->start time: 0.0 +adapt->end time: 10000.0 + + +% =================== OUTPUT ========================================= +pfc->space->output->filename: ./output/pfc.2d +pfc->space->output->ParaView animation: 1 +pfc->space->output->ParaView format: 1 +pfc->space->output->write every i-th timestep: 1 +pfc->space->output->append index: 1 +pfc->space->output->index length: 9 +pfc->space->output->index decimals: 7 + + +WAIT: 1 diff --git a/extensions/demo/pfc/init/pfc_rb.dat.2d b/extensions/demo/pfc/init/pfc_rb.dat.2d new file mode 100644 index 0000000000000000000000000000000000000000..657672aac927f3379d115bc4a2455c58ce05b9ec --- /dev/null +++ b/extensions/demo/pfc/init/pfc_rb.dat.2d @@ -0,0 +1,62 @@ +dimension of world: 2 + +% =================== MESH ================================ +mesh->macro file name: ./macro/macro.square.2d +%mesh->periodic file: ./macro/periodic.square.per +mesh->global refinements: 10 +mesh->check: 0 + +lattice: 4*M_PI/sqrt(3) +mesh->scale mesh: 1 +mesh->dimension: [4*${lattice}, 2*sqrt(3)*${lattice}] + +% ============== USER-PARAMETER ========================== +pfc->r: -0.4 +pfc->rho0: 1.0 +pfc->density: -0.3 +pfc->use mobility: 0 +pfc->M0: 1 + +pfc->density amplitude: 0.2 + +% ============= PROBLEM-SPACE ================================== +pfc->space->mesh: mesh +pfc->space->components: 3 +pfc->space->polynomial degree[0]: 1 +pfc->space->polynomial degree[1]: 1 +pfc->space->polynomial degree[2]: 1 +pfc->space->dim: 2 + + +% ================== SOLVER ====================================== +#include "init/pfc_solver.inc" + + +% ==================== TIMESTEPS =============================== +adapt->timestep: 1.e-1 +adapt->max timestep: 5e+1 +adapt->min timestep: 1e-4 +adapt->start time: 0.0 +adapt->end time: 10000.0 + +adapt->rosenbrock method: ros3Pw +adapt->time tolerance: 1.0 + +adapt[0]->sum factor: 0.0 +adapt[1]->sum factor: 1.0 +adapt[2]->sum factor: 0.0 + +adapt[1]->time tolerance: 0.005 + + +% =================== OUTPUT ========================================= +pfc->space->output->filename: ./output/pfc_rb.2d +pfc->space->output->ParaView animation: 1 +pfc->space->output->ParaView format: 1 +pfc->space->output->write every i-th timestep: 1 +pfc->space->output->append index: 1 +pfc->space->output->index length: 9 +pfc->space->output->index decimals: 7 + + +WAIT: 1 diff --git a/extensions/demo/pfc/init/pfc_rb.mtl.dat.2d b/extensions/demo/pfc/init/pfc_rb.mtl.dat.2d new file mode 100644 index 0000000000000000000000000000000000000000..4085cd815077a49d3215e6571245b014349f6e80 --- /dev/null +++ b/extensions/demo/pfc/init/pfc_rb.mtl.dat.2d @@ -0,0 +1,62 @@ +dimension of world: 2 + +% =================== MESH ================================ +mesh->macro file name: ./macro/macro.square.2d +%mesh->periodic file: ./macro/periodic.square.per +mesh->global refinements: 10 +mesh->check: 0 + +lattice: 4*M_PI/sqrt(3) +mesh->scale mesh: 1 +mesh->dimension: [4*${lattice}, 2*sqrt(3)*${lattice}] + +% ============== USER-PARAMETER ========================== +pfc->r: -0.4 +pfc->rho0: 1.0 +pfc->density: -0.3 +pfc->use mobility: 0 +pfc->M0: 1 + +pfc->density amplitude: 0.2 + +% ============= PROBLEM-SPACE ================================== +pfc->space->mesh: mesh +pfc->space->components: 3 +pfc->space->polynomial degree[0]: 1 +pfc->space->polynomial degree[1]: 1 +pfc->space->polynomial degree[2]: 1 +pfc->space->dim: 2 + + +% ================== SOLVER ====================================== +#include "init/pfc_solver.mtl.inc" + + +% ==================== TIMESTEPS =============================== +adapt->timestep: 1.e-1 +adapt->max timestep: 5e+1 +adapt->min timestep: 1e-4 +adapt->start time: 0.0 +adapt->end time: 10000.0 + +adapt->rosenbrock method: ros3Pw +adapt->time tolerance: 1.0 + +adapt[0]->sum factor: 0.0 +adapt[1]->sum factor: 1.0 +adapt[2]->sum factor: 0.0 + +adapt[1]->time tolerance: 0.005 + + +% =================== OUTPUT ========================================= +pfc->space->output->filename: ./output/pfc_rb.2d +pfc->space->output->ParaView animation: 1 +pfc->space->output->ParaView format: 1 +pfc->space->output->write every i-th timestep: 1 +pfc->space->output->append index: 1 +pfc->space->output->index length: 9 +pfc->space->output->index decimals: 7 + + +WAIT: 1 diff --git a/extensions/demo/pfc/init/pfc_solver.inc b/extensions/demo/pfc/init/pfc_solver.inc new file mode 100644 index 0000000000000000000000000000000000000000..a51fb9c7645bafc2dd213c1b8a84c1f37aaa7164 --- /dev/null +++ b/extensions/demo/pfc/init/pfc_solver.inc @@ -0,0 +1,29 @@ +%pfc->space->solver->backend: p_petsc +pfc->space->solver->petsc prefix: pfc_ +pfc->space->solver: pfc +pfc->space->solver->ksp_type: fgmres +pfc->space->solver->ksp: -pfc_ksp_type fgmres -pfc_ksp_gmres_modifiedgramschmidt +pfc->space->solver->orthogonalization: 1 +pfc->space->solver->max iteration: 500 +pfc->space->solver->info: 10 +pfc->space->solver->print cycle: 10 +pfc->space->solver->restart: 30 +pfc->space->solver->tolerance: 1.e-6 +pfc->space->solver->calc residual: 1 + +precon_pfc_M->max iteration: 1000 +%precon_pfc_M->tolerance: 0 +precon_pfc_M->relative tolerance: 1.e-3 +precon_pfc_M->use direct solver: 0 + +precon_pfc_MpL->max iteration: 1000 +%precon_pfc_MpL->tolerance: 0 +precon_pfc_MpL->relative tolerance: 1.e-3 +precon_pfc_MpL->use direct solver: 0 + +precon_pfc_MpL2->max iteration: 1000 +%precon_pfc_MpL2->tolerance: 0 +precon_pfc_MpL2->relative tolerance: 1.e-3 +precon_pfc_MpL2->use direct solver: 0 +precon_pfc_MpL2->solver: cg +precon_pfc_MpL2->use AMG: 0 \ No newline at end of file diff --git a/extensions/demo/pfc/init/pfc_solver.mtl.inc b/extensions/demo/pfc/init/pfc_solver.mtl.inc new file mode 100644 index 0000000000000000000000000000000000000000..cb199c5aab273b53e7e6db2886df9e03fd06d71f --- /dev/null +++ b/extensions/demo/pfc/init/pfc_solver.mtl.inc @@ -0,0 +1,25 @@ +pfc->space->solver: fgmres +pfc->space->solver->orthogonalization: 1 +pfc->space->solver->max iteration: 500 +pfc->space->solver->info: 10 +pfc->space->solver->print cycle: 10 +pfc->space->solver->restart: 30 +pfc->space->solver->tolerance: 1.e-6 +pfc->space->solver->right precon: pfc + +precon_pfc_M->max iteration: 1000 +%precon_pfc_M->tolerance: 0 +precon_pfc_M->relative tolerance: 1.e-3 +precon_pfc_M->use direct solver: 0 + +precon_pfc_MpL->max iteration: 1000 +%precon_pfc_MpL->tolerance: 0 +precon_pfc_MpL->relative tolerance: 1.e-3 +precon_pfc_MpL->use direct solver: 0 + +precon_pfc_MpL2->max iteration: 1000 +%precon_pfc_MpL2->tolerance: 0 +precon_pfc_MpL2->relative tolerance: 1.e-3 +precon_pfc_MpL2->use direct solver: 0 +precon_pfc_MpL2->solver: cg +precon_pfc_MpL2->use AMG: 0 \ No newline at end of file diff --git a/extensions/demo/pfc/macro/macro.square.2d b/extensions/demo/pfc/macro/macro.square.2d new file mode 100644 index 0000000000000000000000000000000000000000..7d310bfbb624959589f9fa057df7154400383bed --- /dev/null +++ b/extensions/demo/pfc/macro/macro.square.2d @@ -0,0 +1,47 @@ +DIM: 2 +DIM_OF_WORLD: 2 + +number of elements: 8 +number of vertices: 9 + +vertex coordinates: +-1 -1 +0 -1 +1 -1 +-1 0 +0 0 +1 0 +-1 1 +0 1 +1 1 + +element vertices: +0 4 3 +4 0 1 +1 5 4 +5 1 2 +3 7 6 +7 3 4 +4 8 7 +8 4 5 + +element boundaries: +0 1 0 +3 0 0 +0 0 0 +3 2 0 +4 1 0 +0 0 0 +4 0 0 +0 2 0 + +element neighbours: +5 -1 1 +-1 2 0 +7 1 3 +-1 -1 2 +-1 -1 5 +0 6 4 +-1 5 7 +2 -1 6 + diff --git a/extensions/demo/pfc/macro/pfc_mesh.111.2d b/extensions/demo/pfc/macro/pfc_mesh.111.2d new file mode 100644 index 0000000000000000000000000000000000000000..2e39fd0962e8e75143245e96dab182768754dd91 --- /dev/null +++ b/extensions/demo/pfc/macro/pfc_mesh.111.2d @@ -0,0 +1,47 @@ +DIM: 2 +DIM_OF_WORLD: 2 + +number of elements: 8 +number of vertices: 9 + +vertex coordinates: +0.0 0.0 +0.5 0.0 +1.0 0.0 +0.0 0.5 +0.5 0.5 +1.0 0.5 +0.0 1.0 +0.5 1.0 +1.0 1.0 + +element vertices: +0 4 3 +4 0 1 +1 5 4 +5 1 2 +3 7 6 +7 3 4 +4 8 7 +8 4 5 + +element boundaries: +0 1 0 +3 0 0 +0 0 0 +3 2 0 +4 1 0 +0 0 0 +4 0 0 +0 2 0 + +element neighbours: +5 -1 1 +-1 2 0 +7 1 3 +-1 -1 2 +-1 -1 5 +0 6 4 +-1 5 7 +2 -1 6 + diff --git a/extensions/demo/pfc/macro/pfc_mesh.111.3d b/extensions/demo/pfc/macro/pfc_mesh.111.3d new file mode 100644 index 0000000000000000000000000000000000000000..9279bd637cdf09337060235b5a6e142f8abf8326 --- /dev/null +++ b/extensions/demo/pfc/macro/pfc_mesh.111.3d @@ -0,0 +1,185 @@ +DIM: 3 +DIM_OF_WORLD: 3 + +number of elements: 48 +number of vertices: 27 + +vertex coordinates: +0 0 0 +1 0 0 +2 0 0 +0 1 0 +1 1 0 +2 1 0 +0 2 0 +1 2 0 +2 2 0 +0 0 1 +1 0 1 +2 0 1 +0 1 1 +1 1 1 +2 1 1 +0 2 1 +1 2 1 +2 2 1 +0 0 2 +1 0 2 +2 0 2 +0 1 2 +1 1 2 +2 1 2 +0 2 2 +1 2 2 +2 2 2 + +element vertices: +0 13 4 1 +0 13 10 1 +0 13 10 9 +0 13 4 3 +0 13 12 3 +0 13 12 9 +2 13 10 1 +2 13 4 1 +2 13 4 5 +2 13 14 5 +2 13 14 11 +2 13 10 11 +6 13 4 3 +6 13 12 3 +6 13 4 7 +6 13 16 7 +6 13 16 15 +6 13 12 15 +8 13 4 5 +8 13 14 5 +8 13 4 7 +8 13 16 7 +8 13 14 17 +8 13 16 17 +18 13 10 9 +18 13 12 9 +18 13 10 19 +18 13 22 19 +18 13 22 21 +18 13 12 21 +20 13 10 19 +20 13 22 19 +20 13 22 23 +20 13 14 23 +20 13 14 11 +20 13 10 11 +24 13 22 25 +24 13 16 25 +24 13 22 21 +24 13 12 21 +24 13 16 15 +24 13 12 15 +26 13 14 17 +26 13 16 17 +26 13 14 23 +26 13 22 23 +26 13 22 25 +26 13 16 25 + +element boundaries: +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 +0 1 0 0 + +element neighbours: +7 -1 1 3 +6 -1 0 2 +24 -1 5 1 +12 -1 4 0 +13 -1 3 5 +25 -1 2 4 +1 -1 7 11 +0 -1 6 8 +18 -1 9 7 +19 -1 8 10 +34 -1 11 9 +35 -1 10 6 +3 -1 13 14 +4 -1 12 17 +20 -1 15 12 +21 -1 14 16 +40 -1 17 15 +41 -1 16 13 +8 -1 19 20 +9 -1 18 22 +14 -1 21 18 +15 -1 20 23 +42 -1 23 19 +43 -1 22 21 +2 -1 25 26 +5 -1 24 29 +30 -1 27 24 +31 -1 26 28 +38 -1 29 27 +39 -1 28 25 +26 -1 31 35 +27 -1 30 32 +45 -1 33 31 +44 -1 32 34 +10 -1 35 33 +11 -1 34 30 +46 -1 37 38 +47 -1 36 40 +28 -1 39 36 +29 -1 38 41 +16 -1 41 37 +17 -1 40 39 +22 -1 43 44 +23 -1 42 47 +33 -1 45 42 +32 -1 44 46 +36 -1 47 45 +37 -1 46 43 + diff --git a/extensions/demo/pfc/src/pfc.cc b/extensions/demo/pfc/src/pfc.cc new file mode 100644 index 0000000000000000000000000000000000000000..d57cd94910da7ce71a55bc3ee62b2db6cac56eeb --- /dev/null +++ b/extensions/demo/pfc/src/pfc.cc @@ -0,0 +1,117 @@ +#include "AMDiS.h" +#include "Helpers.h" +#include "PhaseFieldCrystal.h" + +#if (defined HAVE_SEQ_PETSC) || (defined HAVE_PETSC) +#include "preconditioner/PetscPreconPfc.h" +#endif +#ifdef HAVE_PARALLEL_DOMAIN_AMDIS +#include "preconditioner/PetscSolverPfc.h" +#endif +#if (!defined HAVE_SEQ_PETSC) && (!defined HAVE_PETSC) && (!defined HAVE_PARALLEL_DOMAIN_AMDIS) +#include "preconditioner/MTLPreconPfc.h" +#endif + +#include "GenericOperatorTerm.h" + +using namespace AMDiS; + +class PfcPC : public PhaseFieldCrystal +{ +public: + typedef PhaseFieldCrystal super; + +public: + PfcPC(std::string name) : PhaseFieldCrystal(name) { } + + /// initialize the preconditioners, i.e. set parameters + void initData() + { + super::initData(); + + // sequential PFC preconditioner +#if (defined HAVE_SEQ_PETSC) || (defined HAVE_PETSC) + PetscPreconPfc* runner = dynamic_cast<PetscPreconPfc*>(prob->getSolver()->getRunner()); + if (runner) { + dynamic_cast<PetscSolver<PetscPreconPfc>*>(prob->getSolver())->setNested(true); + runner->setData(getTau()); + } +#endif + + // parallel PFC preconditioner +#ifdef HAVE_PARALLEL_DOMAIN_AMDIS + Parallel::PetscSolverPfc* solver = dynamic_cast<Parallel::PetscSolverPfc*>(prob->getSolver()); + if (solver) + solver->setData(getTau()); +#endif + + // sequential PFC preconditioner using MTL +#if (!defined HAVE_SEQ_PETSC) && (!defined HAVE_PETSC) && (!defined HAVE_PARALLEL_DOMAIN_AMDIS) + using AMDiS::extensions::MTLPreconPfc; + MTLPreconPfc* precon = dynamic_cast<MTLPreconPfc*>(prob->getSolver()->getRightPrecon()); + if (precon) + precon->setData(getTau()); +#endif + } + + /// generate initial solution for evolution equation + void solveInitialProblem(AdaptInfo *adaptInfo) + { FUNCNAME("PFC_Demo::solveInitialProblem()"); + + Flag initFlag = initDataFromFile(adaptInfo); + if (initFlag.isSet(DATA_ADOPTED)) + return; + + double amplitude = 0.1; + Parameters::get(name + "->density amplitude",amplitude); + + DOFVector<double>* rho = prob->getSolution()->getDOFVector(1); + *rho << eval(new Random(density, amplitude)); + } +}; + + +int main(int argc, char** argv) +{ FUNCNAME("main"); + + AMDiS::init(argc, argv); + Timer t; + + // add preconditioner / solver to the parameter list. Must be added before problem is initialized. +#if (defined HAVE_SEQ_PETSC) || (defined HAVE_PETSC) + CreatorMap<LinearSolver>::addCreator("petsc_pfc", new PetscSolver<PetscPreconPfc>::Creator); +#endif + +#ifdef HAVE_PARALLEL_DOMAIN_AMDIS + CreatorMap<LinearSolver>::addCreator("p_petsc_pfc", new Parallel::PetscSolverPfc::Creator); +#endif + +#if (!defined HAVE_SEQ_PETSC) && (!defined HAVE_PETSC) && (!defined HAVE_PARALLEL_DOMAIN_AMDIS) + using AMDiS::extensions::MTLPreconPfc; + CreatorMap<BasePreconditioner>::addCreator("pfc", new MTLPreconPfc::Creator); +#endif + + // create and initialize the PFC BaseProblem + PfcPC pfcProb("pfc"); + pfcProb.initialize(INIT_ALL); + + // Adapt-Infos + AdaptInfo adaptInfo("adapt", pfcProb.getNumComponents()); + AdaptInstationary adaptInstat("adapt", pfcProb, adaptInfo, pfcProb, adaptInfo); + + // Scale Mesh + bool scaleMesh = false; + Initfile::get("mesh->scale mesh",scaleMesh); + if (scaleMesh) { + WorldVector<double> scale; scale.set(1.0); + Initfile::get("mesh->dimension",scale); + Helpers::scaleMesh(pfcProb.getMesh(), scale); + } + + pfcProb.initTimeInterface(); // fill operators and BC + int error_code = adaptInstat.adapt(); + + MSG("elapsed time= %f sec\n", t.elapsed()); + AMDiS::finalize(); + return error_code; +} diff --git a/extensions/demo/pfc/src/pfc_rb.cc b/extensions/demo/pfc/src/pfc_rb.cc new file mode 100644 index 0000000000000000000000000000000000000000..aaabe226f68e22cafd7971d7d11e6aeca9a6f317 --- /dev/null +++ b/extensions/demo/pfc/src/pfc_rb.cc @@ -0,0 +1,236 @@ +#include "AMDiS.h" +#include "Helpers.h" +#include "PhaseFieldCrystal.h" + +#if (defined HAVE_SEQ_PETSC) || (defined HAVE_PETSC) +#include "preconditioner/PetscPreconPfc.h" +#endif +#ifdef HAVE_PARALLEL_DOMAIN_AMDIS +#include "preconditioner/PetscSolverPfc.h" +#endif +#if (!defined HAVE_SEQ_PETSC) && (!defined HAVE_PETSC) && (!defined HAVE_PARALLEL_DOMAIN_AMDIS) +#include "preconditioner/MTLPreconPfc.h" +#endif + +#include "GenericOperatorTerm.h" + +using namespace AMDiS; + +class PFC_RosenbrockStationary : public RosenbrockStationary +{ +public: + PFC_RosenbrockStationary(std::string name) : RosenbrockStationary(name) {}; + + void addTimeOperator(int row, int col) override + { + FUNCNAME("PFC_RosenbrockStationary::addTimeOperator()"); + MSG("PFC_RosenbrockStationary::addTimeOperator()\n"); + + Operator *op = new Operator(componentSpaces[row], componentSpaces[col]); + addZOT(op, 1.0 / rm->getGamma() ); + ProblemStat::addMatrixOperator(op, row, col); + + Operator *opRhs = new Operator(componentSpaces[row]); + addZOT(opRhs, valueOf(timeRhsVec->getDOFVector(col)) ); + ProblemStat::addVectorOperator(opRhs, row, tauPtr, tauPtr); + } +}; + +class PfcPC : public base_problems::detail::PhaseFieldCrystal<PFC_RosenbrockStationary> +{ +public: + typedef base_problems::detail::PhaseFieldCrystal<PFC_RosenbrockStationary> super; + +public: + PfcPC(std::string name) : super(name) { } + + /// initialize the preconditioners, i.e. set parameters + void initData() override + { + super::initData(); + + // sequential PFC preconditioner +#if (defined HAVE_SEQ_PETSC) || (defined HAVE_PETSC) + PetscPreconPfc* runner = dynamic_cast<PetscPreconPfc*>(prob->getSolver()->getRunner()); + if (runner) { + dynamic_cast<PetscSolver<PetscPreconPfc>*>(prob->getSolver())->setNested(true); + runner->setData(getTau()); + } +#endif + + // parallel PFC preconditioner +#ifdef HAVE_PARALLEL_DOMAIN_AMDIS + Parallel::PetscSolverPfc* solver = dynamic_cast<Parallel::PetscSolverPfc*>(prob->getSolver()); + if (solver) + solver->setData(getTau()); +#endif + + // sequential PFC preconditioner using MTL +#if (!defined HAVE_SEQ_PETSC) && (!defined HAVE_PETSC) && (!defined HAVE_PARALLEL_DOMAIN_AMDIS) + using AMDiS::extensions::MTLPreconPfc; + MTLPreconPfc* precon = dynamic_cast<MTLPreconPfc*>(prob->getSolver()->getRightPrecon()); + if (precon) + precon->setData(getTau()); +#endif + } + + /// generate initial solution for evolution equation + void solveInitialProblem(AdaptInfo *adaptInfo) override + { FUNCNAME("PFC_Demo::solveInitialProblem()"); + + Flag initFlag = initDataFromFile(adaptInfo); + if (initFlag.isSet(DATA_ADOPTED)) + return; + + double amplitude = 0.1; + Parameters::get(name + "->density amplitude",amplitude); + + DOFVector<double>* rho = prob->getSolution()->getDOFVector(1); + *rho << eval(new Random(density, amplitude)); + } + + /// add Rosenbrock operators + void fillOperators() override + { + const FiniteElemSpace* feSpace0 = prob->getFeSpace(0); + const FiniteElemSpace* feSpace1 = prob->getFeSpace(1); + const FiniteElemSpace* feSpace2 = prob->getFeSpace(2); + + DOFVector<double>* mu = prob->getStageSolution(0); + DOFVector<double>* rho = prob->getStageSolution(1); + DOFVector<double>* nu = prob->getStageSolution(2); + + DOFVector<double>* mu_old = prob->getUnVec(0); + DOFVector<double>* rho_old = prob->getUnVec(1); + + // F = -mu_s + (1+r)*rho_s + 2*laplace(rho_s) + laplace(nu_s) + rho_s^3 + // -J = mu - (1+r)*rho - 2*laplace(rho) - laplace(nu) - 3*rho_old^2 * rho + // ---------------------------------------------------------------------- + Operator *op01_lhs = new Operator(feSpace0, feSpace1); + addZOT(op01_lhs, -(1.0 + r) - 3.0 * pow<2>(valueOf(rho_old)) ); + addSOT(op01_lhs, 2.0); + prob->addMatrixOperator(op01_lhs, 0, 1); + + Operator *op00_lhs = new Operator(feSpace0, feSpace0); + addZOT(op00_lhs, 1.0); + prob->addMatrixOperator(op00_lhs, 0, 0); + + Operator *op02_lhs = new Operator(feSpace0, feSpace2); + addSOT(op02_lhs, 1.0); + prob->addMatrixOperator(op02_lhs, 0, 2); + + // ------- // + + Operator *op01_rhs0 = new Operator(feSpace0, feSpace1); + addSOT(op01_rhs0, -2.0); + op01_rhs0->setUhOld(rho); + prob->addVectorOperator(op01_rhs0, 0); + + Operator *op01_rhs1 = new Operator(feSpace0, feSpace1); + addZOT(op01_rhs1, ((1.0 + r) + pow<2>(valueOf(rho)))*valueOf(rho) - valueOf(mu) ); + prob->addVectorOperator(op01_rhs1, 0); + + Operator *op02_rhs = new Operator(feSpace0, feSpace2); + addSOT(op02_rhs, -1.0); + op02_rhs->setUhOld(nu); + prob->addVectorOperator(op02_rhs, 0); + + // dt(rho) = laplace(mu) + // ----------------------------------- + prob->addTimeOperator(1, 1); + + Operator *opLM_lhs0 = new Operator(feSpace1, feSpace0); + Operator *opLM_rhs = new Operator(feSpace1, feSpace0); + if (useMobility) { + addSOT(opLM_lhs0, max(abs_(valueOf(rho_old) + 1.5)*M0, 1.e-5)); + + // ------- // + Operator *opLM_lhs1 = new Operator(feSpace1, feSpace0); + addFOT(opLM_lhs1, gradientOf(mu_old), GRD_PSI); + + prob->addMatrixOperator(opLM_lhs0, 1, 0, prob->getTau(), prob->getTau()); + prob->addMatrixOperator(opLM_lhs1, 1, 1, prob->getTau(), prob->getTau()); + + // ------- // + addSOT(opLM_rhs, -max(abs_(valueOf(rho) + 1.5)*M0, 1.e-5)); + opLM_rhs->setUhOld(mu); + prob->addVectorOperator(opLM_rhs, 1, prob->getTau(), prob->getTau()); + } else { + addSOT(opLM_lhs0, M0); + prob->addMatrixOperator(opLM_lhs0, 1, 0, prob->getTau(), prob->getTau()); + + // ------- // + addSOT(opLM_rhs, -M0); + opLM_rhs->setUhOld(mu); + prob->addVectorOperator(opLM_rhs, 1, prob->getTau(), prob->getTau()); + } + + // F =-nu + laplace(rho) + // -J = nu - laplace(rho) + // ------------------- + Operator *op21_lhs = new Operator(feSpace2, feSpace1); + addSOT(op21_lhs, 1.0); + prob->addMatrixOperator(op21_lhs, 2, 1); + + Operator *op22_lhs = new Operator(feSpace2, feSpace2); + addZOT(op22_lhs, 1.0); + prob->addMatrixOperator(op22_lhs, 2, 2); // nu + + // ------- // + + Operator *op21_rhs = new Operator(feSpace2, feSpace1); + addSOT(op21_rhs, -1.0); + op21_rhs->setUhOld(rho); + prob->addVectorOperator(op21_rhs, 2); + + Operator *op22_rhs = new Operator(feSpace2, feSpace2); + addZOT(op22_rhs, -valueOf(nu)); + prob->addVectorOperator(op22_rhs, 2); // nu + } +}; + + +int main(int argc, char** argv) +{ FUNCNAME("main"); + + AMDiS::init(argc, argv); + Timer t; + + // add preconditioner / solver to the parameter list. Must be added before problem is initialized. +#if (defined HAVE_SEQ_PETSC) || (defined HAVE_PETSC) + CreatorMap<LinearSolver>::addCreator("petsc_pfc", new PetscSolver<PetscPreconPfc>::Creator); +#endif + +#ifdef HAVE_PARALLEL_DOMAIN_AMDIS + CreatorMap<LinearSolver>::addCreator("p_petsc_pfc", new Parallel::PetscSolverPfc::Creator); +#endif + +#if (!defined HAVE_SEQ_PETSC) && (!defined HAVE_PETSC) && (!defined HAVE_PARALLEL_DOMAIN_AMDIS) + using AMDiS::extensions::MTLPreconPfc; + CreatorMap<BasePreconditioner>::addCreator("pfc", new MTLPreconPfc::Creator); +#endif + + // create and initialize the PFC BaseProblem + PfcPC pfcProb("pfc"); + pfcProb.initialize(INIT_ALL); + + // Adapt-Infos + AdaptInfo adaptInfo("adapt", pfcProb.getNumComponents()); + RosenbrockAdaptInstationary adaptInstat("adapt", pfcProb.getProblem(), &adaptInfo, &pfcProb, &adaptInfo); + pfcProb.initTimeInterface(); // fill operators and BC + + // Scale Mesh + bool scaleMesh = false; + Initfile::get("mesh->scale mesh",scaleMesh); + if (scaleMesh) { + WorldVector<double> scale; scale.set(1.0); + Initfile::get("mesh->dimension",scale); + Helpers::scaleMesh(pfcProb.getMesh(), scale); + } + + int error_code = adaptInstat.adapt(); + + MSG("elapsed time= %f sec\n", t.elapsed()); + AMDiS::finalize(); + return error_code; +} diff --git a/extensions/kdtree_nanoflann.h b/extensions/kdtree_nanoflann.h index 717487690f19ba8adf2ee7d7caf79dd685de7876..4b7917e4949ee90892d2001aad88361bc4f7963b 100644 --- a/extensions/kdtree_nanoflann.h +++ b/extensions/kdtree_nanoflann.h @@ -37,10 +37,9 @@ #include "FixVec.h" +namespace AMDiS { namespace extensions { using namespace nanoflann; -using namespace AMDiS; -namespace experimental { /** A simple vector-of-vectors adaptor for nanoflann, without duplicating the storage. * The i'th vector represents a point in the state space. @@ -145,6 +144,6 @@ struct KDTreeVectorOfWorldVectorsAdaptor typedef KDTreeVectorOfWorldVectorsAdaptor<std::vector<WorldVector<double> >, double > KD_Tree; -} // end namespace experimental +} } #endif diff --git a/extensions/kdtree_nanoflann_dof.h b/extensions/kdtree_nanoflann_dof.h index 55ab6fce35c66162d3413168e34f2e8b4f04517b..98494855e1f46300bfb6043d29ff58084dd35704 100644 --- a/extensions/kdtree_nanoflann_dof.h +++ b/extensions/kdtree_nanoflann_dof.h @@ -26,10 +26,9 @@ #include "AMDiS.h" +namespace AMDiS { namespace extensions { + using namespace nanoflann; -using namespace AMDiS; - -namespace experimental { /** A simple vector-of-vectors adaptor for nanoflann, without duplicating the storage. * The i'th vector represents a point in the state space. @@ -192,6 +191,6 @@ namespace experimental { return kdtreeMap_Dof[feSpace].second; } -} // end namespace +} } #endif // EXTENSIONS_KDTREE_NANOFLANN_DOF_H diff --git a/extensions/kdtree_nanoflann_double.h b/extensions/kdtree_nanoflann_double.h index bd8cbdc82dc6be5a4fcf4e3a85938359b91dd3f7..60c6ddcfe717d552aa9f26626e0cc988be1429fa 100644 --- a/extensions/kdtree_nanoflann_double.h +++ b/extensions/kdtree_nanoflann_double.h @@ -24,10 +24,9 @@ #include <cstdlib> #include <iostream> +namespace AMDiS { namespace extensions { + using namespace nanoflann; -using namespace AMDiS; - -namespace experimental { /** A simple vector-of-vectors adaptor for nanoflann, without duplicating the storage. * The i'th vector represents a point in the state space. @@ -119,6 +118,6 @@ struct KDTreeVectorOfDoublesAdaptor typedef KDTreeVectorOfDoublesAdaptor<std::vector<double>, double > KD_Tree_Double; -} // end namespace experimental +} } #endif // EXTENSIONS_KDTREE_NANOFLANN_DOUBLE_H diff --git a/extensions/kdtree_nanoflann_mesh.h b/extensions/kdtree_nanoflann_mesh.h index aa2eadaa4fd373542db47caa2b644ed954f2a62d..9af66d6942e829ddb77ede96903c3d99fb463bb9 100644 --- a/extensions/kdtree_nanoflann_mesh.h +++ b/extensions/kdtree_nanoflann_mesh.h @@ -28,10 +28,10 @@ #include "ElementFunction.h" #include "GeometryTools.h" -using namespace nanoflann; -using namespace AMDiS; -namespace experimental { +namespace AMDiS { namespace extensions { + +using namespace nanoflann; // ===================================================================================== typedef WorldVector<double> PointType; @@ -273,6 +273,7 @@ typedef std::vector<DataType> VectorOfDataType; return kdtreeMap_M[feSpace].second; } -} // end namespace experimental + +} } #endif // EXTENSIONS_KDTREE_NANOFLANN_MESH_H diff --git a/extensions/preconditioner/BlockPreconditioner.h b/extensions/preconditioner/BlockPreconditioner.h index d2b8357d0aaa877d7a8002c07789b1757ddf8b74..d5f2161c7d6d2bd936ec1e55f452a53330e4fff7 100644 --- a/extensions/preconditioner/BlockPreconditioner.h +++ b/extensions/preconditioner/BlockPreconditioner.h @@ -36,7 +36,7 @@ namespace AMDiS { A = &A_; fullMatrix = &fullMatrix_; - VectorialMapper mapper(A_); + BlockMapper mapper(A_); rows.resize(mapper.getNumComponents()); int start = 0; for (int i = 0; i < mapper.getNumComponents(); i++) { diff --git a/extensions/preconditioner/CahnHilliard_.cc b/extensions/preconditioner/CahnHilliard_.cc index 795b233cd0946c354f6bc42141953d4f11da0d6f..03151202c3c94bc7543a99511a181c50d5769dbc 100644 --- a/extensions/preconditioner/CahnHilliard_.cc +++ b/extensions/preconditioner/CahnHilliard_.cc @@ -22,8 +22,8 @@ #include "HL_SignedDistTraverse.h" #include "Recovery.h" -using namespace AMDiS; - +namespace AMDiS { namespace base_problems { + CahnHilliard_::CahnHilliard_(const std::string &name_) : super(name_), useMobility(false), @@ -58,6 +58,7 @@ CahnHilliard_::CahnHilliard_(const std::string &name_) : void CahnHilliard_::solveInitialProblem(AdaptInfo *adaptInfo) { + using namespace extensions; Flag initFlag = initDataFromFile(adaptInfo); if (!initFlag.isSet(DATA_ADOPTED)) { @@ -215,3 +216,4 @@ void CahnHilliard_::fillOperators() } +} } diff --git a/extensions/preconditioner/CahnHilliard_.h b/extensions/preconditioner/CahnHilliard_.h index 9da54bc0cc5f15f742268dc595096d1e7a342c25..4c7bde8095a5a7a257287be39093adafa1154569 100644 --- a/extensions/preconditioner/CahnHilliard_.h +++ b/extensions/preconditioner/CahnHilliard_.h @@ -22,7 +22,7 @@ #include "BaseProblem.h" #include "chns.h" -using namespace AMDiS; +namespace AMDiS { namespace base_problems { class CahnHilliard_ : public BaseProblem<ProblemStat> { @@ -61,6 +61,6 @@ protected: // protected variables double minusEpsSqr; }; - +} } #endif // CAHN_HILLIARD_PRECON_H diff --git a/extensions/preconditioner/MTLPreconCahnHilliard.h b/extensions/preconditioner/MTLPreconCahnHilliard.h index 55de585ea3be0f74a1b080a9c5f22f23fd16e528..f5f19dbc19b921ed608419da803b61d70d96f5c4 100644 --- a/extensions/preconditioner/MTLPreconCahnHilliard.h +++ b/extensions/preconditioner/MTLPreconCahnHilliard.h @@ -20,8 +20,9 @@ #include "AMDiS.h" #include "BlockPreconditioner.h" +namespace AMDiS { namespace extensions { + using namespace std; -using namespace AMDiS; template< typename MatrixType = MTLTypes::MTLMatrix, typename VectorType = MTLTypes::MTLVector > struct MTLPreconCahnHilliard : BlockPreconditioner @@ -133,6 +134,8 @@ protected: double* delta; }; +} } + #include "MTLPreconCahnHilliard.hh" #endif // MTL_CH_PRECONDITIONER_H diff --git a/extensions/preconditioner/MTLPreconCahnHilliard.hh b/extensions/preconditioner/MTLPreconCahnHilliard.hh index cf37b736251ea3fcbcf7162dd43a99653580bc61..e64f0ec2d14033510cfe4e12e3621f938af3b093 100644 --- a/extensions/preconditioner/MTLPreconCahnHilliard.hh +++ b/extensions/preconditioner/MTLPreconCahnHilliard.hh @@ -15,6 +15,8 @@ * ******************************************************************************/ +namespace AMDiS { namespace extensions { + template< typename MatrixType, typename VectorType > void MTLPreconCahnHilliard< MatrixType, VectorType >::init(const BlockMatrix& A_, const MTLMatrix& fullMatrix_) { FUNCNAME("MTLPreconCahnHilliard::init()"); @@ -71,3 +73,5 @@ void MTLPreconCahnHilliard< MatrixType, VectorType >::solve(const MTLVector& b, solveMpL(x2, x1); x1 = y1 - factor * (y2 - x2); } + +} } \ No newline at end of file diff --git a/extensions/preconditioner/MTLPreconPfc.h b/extensions/preconditioner/MTLPreconPfc.h index 3d2b073a666a3ada7c1357d5c30f06e834f62c95..4294bbb93156cc3ce724c40bda7a92e7fdf7958e 100644 --- a/extensions/preconditioner/MTLPreconPfc.h +++ b/extensions/preconditioner/MTLPreconPfc.h @@ -19,10 +19,12 @@ #include "AMDiS.h" #include "BlockPreconditioner.h" -// #include "TimeTracer.h" -using namespace std; -using namespace AMDiS; +#include <boost/numeric/mtl/interface/umfpack_solve.hpp> + +namespace AMDiS { namespace extensions { + +using namespace std; using namespace AMDiS::MTLTypes; struct MTLPreconPfc : BlockPreconditioner @@ -42,7 +44,9 @@ struct MTLPreconPfc : BlockPreconditioner MTLPreconPfc(std::string name) : BlockPreconditioner(), name(name), - tau(NULL) + tau(NULL), + PId(NULL), PDiagM(NULL), PDiagMpL(NULL), PDiagMpL2(NULL), + solverM(NULL), solverMpL(NULL), solverMpL2(NULL) { } virtual ~MTLPreconPfc() @@ -63,6 +67,9 @@ struct MTLPreconPfc : BlockPreconditioner if (PDiagM) { delete PDiagM; PDiagM = NULL; } if (PDiagMpL) { delete PDiagMpL; PDiagMpL = NULL; } if (PDiagMpL2) { delete PDiagMpL2; PDiagMpL2 = NULL; } + if (solverM) { delete solverM; solverM = NULL; } + if (solverMpL) { delete solverMpL; solverMpL = NULL; } + if (solverMpL2) { delete solverMpL2; solverMpL2 = NULL; } } virtual void solve(const MTLVector& b, MTLVector& x) const; @@ -70,33 +77,58 @@ struct MTLPreconPfc : BlockPreconditioner template <typename VectorX, typename VectorB> void solveM(VectorX& x, const VectorB& b, int nIter = -1) const { -// TimeTracer t("solveM"); - itl::basic_iteration<double> iter(b, 5, 0, 1.e-6); - x = 0.0; - itl::cg(getM(), x, b, *PDiagM, *PId, iter); -// std::cout << "................ residual(M) = " << solverM->getResidual() << "\n"; + int nIterM=5; + double rtolM=1.e-6,tolM=0; + bool useDirectSolver = false; + Parameters::get("precon_pfc_M->max iteration", nIterM); + Parameters::get("precon_pfc_M->tolerance", tolM); + Parameters::get("precon_pfc_M->relative tolerance", rtolM); + Parameters::get("precon_pfc_M->use direct solver", useDirectSolver); + if (useDirectSolver && solverM) + (*solverM)(x,b); + else { + itl::basic_iteration<double> iter(b, nIterM, rtolM, tolM); + x = 0.0; + itl::cg(getM(), x, b, *PDiagM, *PId, iter); + } } template <typename VectorX, typename VectorB> void solveMpL(VectorX& x, const VectorB& b) const { -// TimeTracer t("solveMpL"); - itl::basic_iteration<double> iter(b, 20, 0, 1.e-6); - x = 0.0; - itl::cg(MpL, x, b, *PDiagMpL, *PId, iter); -// std::cout << "............. residual(MpK) = " << solverMpL->getResidual() << "\n"; - + int nIterMpL=20; + double rtolMpL=1.e-6,tolMpL=0; + bool useDirectSolver = false; + Parameters::get("precon_pfc_MpL->max iteration", nIterMpL); + Parameters::get("precon_pfc_MpL->tolerance", tolMpL); + Parameters::get("precon_pfc_MpL->relative tolerance", rtolMpL); + Parameters::get("precon_pfc_MpL->use direct solver", useDirectSolver); + if (useDirectSolver && solverMpL) + (*solverMpL)(x,b); + else { + itl::basic_iteration<double> iter(b, nIterMpL, rtolMpL, tolMpL); + x = 0.0; + itl::cg(MpL, x, b, *PDiagMpL, *PId, iter); + } } template <typename VectorX, typename VectorB> void solveMpL2(VectorX& x, const VectorB& b) const { -// TimeTracer t("solveMpL2"); - itl::basic_iteration<double> iter(b, 10, 0, 1.e-6); - x = 0.0; - itl::cg(MpL2, x, b, *PDiagMpL2, *PId, iter); -// std::cout << "............. residual(MpK) = " << solverMpL->getResidual() << "\n"; - + int nIterMpL2=10; + double rtolMpL2=1.e-6,tolMpL2=0; + bool useDirectSolver = false; + Parameters::get("precon_pfc_MpL2->max iteration", nIterMpL2); + Parameters::get("precon_pfc_MpL2->tolerance", tolMpL2); + Parameters::get("precon_pfc_MpL2->relative tolerance", rtolMpL2); + Parameters::get("precon_pfc_MpL2->use direct solver", useDirectSolver); + if (useDirectSolver && solverMpL2) + (*solverMpL2)(x,b); + else { + itl::basic_iteration<double> iter(b, nIterMpL2, rtolMpL2, tolMpL2); + x = 0.0; + itl::cg(MpL2, x, b, *PDiagMpL2, *PId, iter); + } } @@ -116,12 +148,18 @@ protected: itl::pc::diagonal<MTLTypes::MTLMatrix, double> *PDiagM; itl::pc::diagonal<MTLTypes::MTLMatrix, double> *PDiagMpL; itl::pc::diagonal<MTLTypes::MTLMatrix, double> *PDiagMpL2; - + + mtl::matrix::umfpack::solver<MTLTypes::MTLMatrix> *solverM; + mtl::matrix::umfpack::solver<MTLTypes::MTLMatrix> *solverMpL; + mtl::matrix::umfpack::solver<MTLTypes::MTLMatrix> *solverMpL2; + std::string name; double* tau; }; +} } + #include "MTLPreconPfc.hh" #endif // MTL_PFC_PRECONDITIONER_H diff --git a/extensions/preconditioner/MTLPreconPfc.hh b/extensions/preconditioner/MTLPreconPfc.hh index 684420fa7cbfe6a23ff8bc5848cb1e6137f27c34..28ddde0e21a41ab3404a53f62eca20ac4995e3b9 100644 --- a/extensions/preconditioner/MTLPreconPfc.hh +++ b/extensions/preconditioner/MTLPreconPfc.hh @@ -15,44 +15,49 @@ * ******************************************************************************/ +namespace AMDiS { namespace extensions { + void MTLPreconPfc::init(const BlockMatrix& A_, const MTLMatrix& fullMatrix_) { - assert(tau != NULL); -// TimeTracer t0("MTLPreconPfc::init"); - + assert(tau != NULL); super::init(A_, fullMatrix_); typedef typename mtl::Collection<MTLMatrix>::size_type size_type; typedef typename mtl::Collection<MTLMatrix>::value_type value_type; size_type n = num_rows(getM()); - double delta = sqrt(getTau()); - double eps = sqrt(0.5); + double delta = std::sqrt(getTau()); // helper-matrix MpL = M + delta*L MpL.change_dim(n, n); MpL = getM() + delta*getL(); - // helper-matrix MpL = M + eps*sqrt(delta)*L + // helper-matrix MpL = M + sqrt(delta)*L MpL2.change_dim(n, n); - MpL2 = getM() + ( eps*sqrt(delta) ) * getL(); + MpL2 = getM() + ( std::sqrt(delta) ) * getL(); + bool useDirectSolverM = false, + useDirectSolverMpL = false, + useDirectSolverMpL2 = false; + Parameters::get("precon_pfc_M->use direct solver", useDirectSolverM); + Parameters::get("precon_pfc_MpL->use direct solver", useDirectSolverMpL); + Parameters::get("precon_pfc_MpL2->use direct solver", useDirectSolverMpL2); + PId = new itl::pc::identity<MTLTypes::MTLMatrix, double>(getM()); - PDiagM = new itl::pc::diagonal<MTLTypes::MTLMatrix, double>(getM()); - PDiagMpL = new itl::pc::diagonal<MTLTypes::MTLMatrix, double>(MpL); - PDiagMpL2 = new itl::pc::diagonal<MTLTypes::MTLMatrix, double>(MpL2); -// { -// mtl::io::matrix_market_ostream outM("M.mtx"); -// mtl::io::matrix_market_ostream outL("L.mtx"); -// mtl::io::matrix_market_ostream outMpL("MpL.mtx"); -// mtl::io::matrix_market_ostream outMpL2("MpL2.mtx"); -// outM << getM(); -// outL << getL(); -// outMpL << MpL; -// outMpL2 << MpL2; -// } + if (useDirectSolverM) + solverM = new mtl::matrix::umfpack::solver<MTLTypes::MTLMatrix>(getM()); + else + PDiagM = new itl::pc::diagonal<MTLTypes::MTLMatrix, double>(getM()); + if (useDirectSolverMpL) + solverMpL = new mtl::matrix::umfpack::solver<MTLTypes::MTLMatrix>(MpL); + else + PDiagMpL = new itl::pc::diagonal<MTLTypes::MTLMatrix, double>(MpL); + if (useDirectSolverMpL2) + solverMpL2 = new mtl::matrix::umfpack::solver<MTLTypes::MTLMatrix>(MpL2); + else + PDiagMpL2 = new itl::pc::diagonal<MTLTypes::MTLMatrix, double>(MpL2); // temporary variables y0.change_dim(num_rows(getM())); @@ -64,7 +69,6 @@ void MTLPreconPfc::init(const BlockMatrix& A_, const MTLMatrix& fullMatrix_) void MTLPreconPfc::solve(const MTLVector& b, MTLVector& x) const { FUNCNAME("MTLPreconPfc::solve()"); -// TimeTracer t0("PreconPfc::solve"); x.change_dim(num_rows(b)); const MTLVector b0(b[rows[0]]); @@ -75,7 +79,7 @@ void MTLPreconPfc::solve(const MTLVector& b, MTLVector& x) const MTLVector x1(x[rows[1]]); MTLVector x2(x[rows[2]]); - double delta = sqrt(getTau()); + double delta = std::sqrt(getTau()); solveM(y0, b0); // M*y0 = b0 y1 = getL() * y0; // y1 = K*y0 @@ -94,3 +98,5 @@ void MTLPreconPfc::solve(const MTLVector& b, MTLVector& x) const tmp = b2 - getL() * x1; // tmp := b2 - K*x1 solveM(x2, tmp); } + +} } diff --git a/extensions/preconditioner/MTLPreconPfc_diag.h b/extensions/preconditioner/MTLPreconPfc_diag.h new file mode 100644 index 0000000000000000000000000000000000000000..2c6c6b4581ebce62e2f2ee885710640073a1d7fb --- /dev/null +++ b/extensions/preconditioner/MTLPreconPfc_diag.h @@ -0,0 +1,177 @@ +/****************************************************************************** + * + * Extension of AMDiS - Adaptive multidimensional simulations + * + * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. + * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis + * + * Authors: Simon Praetorius et al. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * + * See also license.opensource.txt in the distribution. + * + ******************************************************************************/ +#ifndef MTL_PFC_PRECONDITIONER_DIAG_H +#define MTL_PFC_PRECONDITIONER_DIAG_H + +#include "AMDiS.h" +#include "BlockPreconditioner.h" + +namespace AMDiS { namespace extensions { + +using namespace std; +using namespace AMDiS::MTLTypes; + +struct MTLPreconPfcDiag : BlockPreconditioner +{ + typedef BlockPreconditioner super; + + class Creator : public PreconditionCreator + { + public: + virtual ~Creator() {} + + BasePreconditioner* create() { + return new MTLPreconPfcDiag(this->name); + } + }; + + MTLPreconPfcDiag(std::string name) + : BlockPreconditioner(), + name(name), + tau(NULL), + PId(NULL), PDiagM(NULL), PDiagMpL(NULL), PDiagS(NULL), + solverM(NULL), solverMpL(NULL), solverS(NULL) + { } + + virtual ~MTLPreconPfcDiag() + { + exit(); + } + + void setData(double* tau_) + { + tau = tau_; + } + + virtual void init(const typename super::BlockMatrix& A, const MTLTypes::MTLMatrix& fullMatrix); + + virtual void exit() + { + if (PId) { delete PId; PId = NULL; } + if (PDiagM) { delete PDiagM; PDiagM = NULL; } + if (PDiagMpL) { delete PDiagMpL; PDiagMpL = NULL; } + if (PDiagS) { delete PDiagS; PDiagS = NULL; } + if (solverM) { delete solverM; solverM = NULL; } + if (solverMpL) { delete solverMpL; solverMpL = NULL; } + if (solverS) { delete solverS; solverS = NULL; } + } + + virtual void solve(const MTLVector& b, MTLVector& x) const; + + template <typename VectorX, typename VectorB> + void solveM(VectorX& x, const VectorB& b, int nIter = -1) const + { + int nIterM=5; + double rtolM=0.0, tolM=0.0; + bool useDirectSolver = false; + Parameters::get("precon_pfc_M->max iteration", nIterM); + Parameters::get("precon_pfc_M->tolerance", tolM); + Parameters::get("precon_pfc_M->relative tolerance", rtolM); + Parameters::get("precon_pfc_M->use direct solver", useDirectSolver); + if (useDirectSolver && solverM) + (*solverM)(x,b); + else { + itl::basic_iteration<double> iter(b, nIterM, rtolM, tolM); + x = 0.0; + itl::cg(getM(), x, b, *PDiagM, *PId, iter); + } + } + + template <typename VectorX, typename VectorB> + void solveMpL(VectorX& x, const VectorB& b) const + { + int nIterMpL=20; + double rtolMpL=0.0, tolMpL=0.0; + bool useDirectSolver = false; + Parameters::get("precon_pfc_MpL->max iteration", nIterMpL); + Parameters::get("precon_pfc_MpL->tolerance", tolMpL); + Parameters::get("precon_pfc_MpL->relative tolerance", rtolMpL); + Parameters::get("precon_pfc_MpL->use direct solver", useDirectSolver); + if (useDirectSolver && solverMpL) + (*solverMpL)(x,b); + else { + itl::basic_iteration<double> iter(b, nIterMpL, rtolMpL, tolMpL); + x = 0.0; + itl::cg(MpL, x, b, *PDiagMpL, *PId, iter); + } + } + + template <typename VectorX, typename VectorB> + void solveS(VectorX& x, const VectorB& b) const + { + int nIterMpL2=10; + double rtolMpL2=0.0, tolMpL2=0.0; + bool useDirectSolver = false; + Parameters::get("precon_pfc_MpL2->max iteration", nIterMpL2); + Parameters::get("precon_pfc_MpL2->tolerance", tolMpL2); + Parameters::get("precon_pfc_MpL2->relative tolerance", rtolMpL2); + Parameters::get("precon_pfc_MpL2->use direct solver", useDirectSolver); + if (useDirectSolver && solverS) + (*solverS)(x,b); + else { + itl::basic_iteration<double> iter(b, nIterMpL2, rtolMpL2, tolMpL2); + x = 0.0; + + std::string solver = "cg"; + Parameters::get("precon_pfc_MpL2->solver", solver); + if (solver == "cg") + itl::cg(S, x, b, *PDiagS, *PId, iter); + else if (solver == "gmres") + itl::gmres(S, x, b, *PDiagS, *PId, iter, 30); + else if (solver == "tfqmr") + itl::tfqmr(S, x, b, *PDiagS, *PId, iter); + else if (solver == "bicgstab") + itl::bicgstab(S, x, b, *PDiagS, iter); + else + throw std::runtime_error("unknown sub-solver"); + } + } + + + const MTLMatrix& getM() const { return A->getSubMatrix(2,2); } + const MTLMatrix& getL() const { return A->getSubMatrix(2,1); } + double getTau() const { return *tau; } + +protected: + MTLMatrix MpL; + MTLMatrix MinvL; + MTLMatrix S; + + mutable MTLVector y0; + mutable MTLVector y1; + mutable MTLVector tmp; + + itl::pc::identity<MTLTypes::MTLMatrix, double> *PId; + itl::pc::diagonal<MTLTypes::MTLMatrix, double> *PDiagM; + itl::pc::diagonal<MTLTypes::MTLMatrix, double> *PDiagMpL; + itl::pc::diagonal<MTLTypes::MTLMatrix, double> *PDiagS; + + mtl::matrix::umfpack::solver<MTLTypes::MTLMatrix> *solverM; + mtl::matrix::umfpack::solver<MTLTypes::MTLMatrix> *solverMpL; + mtl::matrix::umfpack::solver<MTLTypes::MTLMatrix> *solverS; + + std::string name; + + double* tau; +}; + +} } + +#include "MTLPreconPfc_diag.hh" + +#endif // MTL_PFC_PRECONDITIONER_H + diff --git a/extensions/preconditioner/MTLPreconPfc_diag.hh b/extensions/preconditioner/MTLPreconPfc_diag.hh new file mode 100644 index 0000000000000000000000000000000000000000..7f56614ffcfbd0dcb0ffabc99f62bfeccab78b8f --- /dev/null +++ b/extensions/preconditioner/MTLPreconPfc_diag.hh @@ -0,0 +1,117 @@ +/****************************************************************************** + * + * Extension of AMDiS - Adaptive multidimensional simulations + * + * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. + * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis + * + * Authors: Simon Praetorius et al. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * + * See also license.opensource.txt in the distribution. + * + ******************************************************************************/ + +namespace AMDiS { namespace extensions { + +void MTLPreconPfcDiag::init(const BlockMatrix& A_, const MTLMatrix& fullMatrix_) +{ + assert(tau != NULL); + + super::init(A_, fullMatrix_); + + typedef typename mtl::Collection<MTLMatrix>::size_type size_type; + typedef typename mtl::Collection<MTLMatrix>::value_type value_type; + size_type n = num_rows(getM()); + + double delta = std::sqrt(getTau()); + + // helper-matrix MpL = M + delta*L + MpL.change_dim(n, n); + MpL = getM() + delta*getL(); + + // helper-matrix MpL = M + sqrt(delta)*L + S.change_dim(n, n); + MinvL.change_dim(n, n); + MinvL = diagonal(diagonal(getM())); + invert_diagonal(MinvL); + MinvL *= getL(); + + S = getM() - ( 2.0 * delta ) * getL() + delta * getL() * MinvL; + + bool useDirectSolverM = false, + useDirectSolverMpL = false, + useDirectSolverMpL2 = false; + Parameters::get("precon_pfc_M->use direct solver", useDirectSolverM); + Parameters::get("precon_pfc_MpL->use direct solver", useDirectSolverMpL); + Parameters::get("precon_pfc_MpL2->use direct solver", useDirectSolverMpL2); + + PId = new itl::pc::identity<MTLTypes::MTLMatrix, double>(getM()); + + if (useDirectSolverM) { + try { + solverM = new mtl::matrix::umfpack::solver<MTLTypes::MTLMatrix>(getM(), UMFPACK_STRATEGY_SYMMETRIC, 0.7); + } catch (mtl::matrix::umfpack::error& e) { + ERROR_EXIT("UMFPACK_ERROR(M, %d) = %s\n", e.code, e.what()); + } + } else + PDiagM = new itl::pc::diagonal<MTLTypes::MTLMatrix, double>(getM()); + if (useDirectSolverMpL) { + try { + solverMpL = new mtl::matrix::umfpack::solver<MTLTypes::MTLMatrix>(MpL, UMFPACK_STRATEGY_SYMMETRIC, 0.7); + } catch (mtl::matrix::umfpack::error& e) { + ERROR_EXIT("UMFPACK_ERROR(MpL, %d) = %s\n", e.code, e.what()); + } + } else + PDiagMpL = new itl::pc::diagonal<MTLTypes::MTLMatrix, double>(MpL); + if (useDirectSolverMpL2) { + try { + solverS = new mtl::matrix::umfpack::solver<MTLTypes::MTLMatrix>(S, UMFPACK_STRATEGY_SYMMETRIC, 0.7); + } catch (mtl::matrix::umfpack::error& e) { + ERROR_EXIT("UMFPACK_ERROR(MpL2, %d) = %s\n", e.code, e.what()); + } + } else + PDiagS = new itl::pc::diagonal<MTLTypes::MTLMatrix, double>(S); + + // temporary variables + y0.change_dim(num_rows(getM())); + y1.change_dim(num_rows(getM())); + tmp.change_dim(num_rows(getM())); +} + + +void MTLPreconPfcDiag::solve(const MTLVector& b, MTLVector& x) const +{ FUNCNAME("MTLPreconPfcDiag::solve()"); + + x.change_dim(num_rows(b)); + + const MTLVector b0(b[rows[0]]); + const MTLVector b1(b[rows[1]]); + const MTLVector b2(b[rows[2]]); + + MTLVector x0(x[rows[0]]); + MTLVector x1(x[rows[1]]); + MTLVector x2(x[rows[2]]); + + double delta = std::sqrt(getTau()); + + solveM(y0, b0); // M*y0 = b0 + y1 = getL() * y0; // y1 = K*y0 + tmp = b1 - getTau()*y1; // tmp := b1 - tau*y1 + + solveMpL(y1, tmp); // (M + delta*K) * y1 = tmp + x0 = y0 + (1.0/delta)*y1; // x0 = y0 + (1/delta)*y1 + + tmp = getM() * y1; // tmp := M*y1 + solveS(x1, tmp); // (M+eps*sqrt(delta)K) * x1 = tmp + + x0-= (1.0/delta)*x1; // x0 = x0 - (1/delta)*x1 = y0 + (1/delta)*(y1 - x1) + + tmp = b2 - getL() * x1; // tmp := b2 - K*x1 + solveM(x2, tmp); +} + +} } diff --git a/extensions/preconditioner/PetscPreconPfc.cc b/extensions/preconditioner/PetscPreconPfc.cc index f37324e73284bb403bcc94fa82ff206b6305db09..fb64056de5c4f512c34ca39e645853587675827c 100644 --- a/extensions/preconditioner/PetscPreconPfc.cc +++ b/extensions/preconditioner/PetscPreconPfc.cc @@ -84,7 +84,6 @@ namespace AMDiS { double delta = sqrt(*tau); - double eps = sqrt(0.5); MatNestGetSubMat(matrix, 2, 2, &data.matM); MatNestGetSubMat(matrix, 2, 1, &data.matK); @@ -93,7 +92,7 @@ namespace AMDiS { MatAXPY(MpK, delta, data.matK, SAME_NONZERO_PATTERN); MatDuplicate(data.matM, MAT_COPY_VALUES, &MpK2); - MatAXPY(MpK2, eps*sqrt(delta), data.matK, SAME_NONZERO_PATTERN); + MatAXPY(MpK2, sqrt(delta), data.matK, SAME_NONZERO_PATTERN); // init sub-solvers createSubSolver(data.kspM, data.matM, "mass_"); @@ -102,10 +101,31 @@ namespace AMDiS { data.delta = delta; data.tau = *tau; + + + int nIterM=5, nIterMpL=20, nIterMpL2=10; + double tolM=PETSC_DEFAULT, tolMpL=PETSC_DEFAULT, tolMpL2=PETSC_DEFAULT; + double rtolM=PETSC_DEFAULT, rtolMpL=PETSC_DEFAULT, rtolMpL2=PETSC_DEFAULT; + Parameters::get("precon_pfc_M->max iteration", nIterM); + Parameters::get("precon_pfc_MpL->max iteration", nIterMpL); + Parameters::get("precon_pfc_MpL2->max iteration", nIterMpL2); + Parameters::get("precon_pfc_M->tolerance", tolM); + Parameters::get("precon_pfc_MpL->tolerance", tolMpL); + Parameters::get("precon_pfc_MpL2->tolerance", tolMpL2); + Parameters::get("precon_pfc_M->relative tolerance", rtolM); + Parameters::get("precon_pfc_MpL->relative tolerance", rtolMpL); + Parameters::get("precon_pfc_MpL2->relative tolerance", rtolMpL2); + + bool useAMG = false; + Parameters::get("precon_pfc_MpL2->use AMG", useAMG); - setSolver(data.kspM, "mass_", KSPCG, PCJACOBI, 0.0, 1e-8, 5); - setSolver(data.kspMpK, "MpK_", KSPCG, PCJACOBI, 0.0, 1e-6, 20); - setSolver(data.kspMpK2, "MpK2_", KSPCG, PCJACOBI, 0.0, 1e-6, 10); + setSolver(data.kspM, "M_", KSPCG, PCJACOBI, rtolM, tolM, nIterM); + setSolver(data.kspMpK, "MpK_", KSPCG, PCJACOBI, rtolMpL, tolMpL, nIterMpL); + if (!useAMG) { + setSolver(data.kspMpK2, "MpK2_", KSPCG, PCJACOBI, rtolMpL2, tolMpL2, nIterMpL2); + } else { + setSolver(data.kspMpK2, "MpK2_", KSPRICHARDSON, PCHYPRE, rtolMpL2, tolMpL2, nIterMpL2); + } } diff --git a/extensions/preconditioner/PetscPreconPfcDiag.cc b/extensions/preconditioner/PetscPreconPfcDiag.cc new file mode 100644 index 0000000000000000000000000000000000000000..b1f7d65555765cda97f71e026555b8429773abc9 --- /dev/null +++ b/extensions/preconditioner/PetscPreconPfcDiag.cc @@ -0,0 +1,158 @@ +/****************************************************************************** + * + * Extension of AMDiS - Adaptive multidimensional simulations + * + * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. + * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis + * + * Authors: Simon Praetorius et al. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * + * See also license.opensource.txt in the distribution. + * + ******************************************************************************/ +#include "PetscPreconPfcDiag.h" +// #include "TimeTracer.h" + +namespace AMDiS { + + using namespace std; + + /// solve Pfc Preconditioner + PetscErrorCode pcPfcDiagShell(PC pc, Vec b, Vec x) // solve Px=b + { FUNCNAME("pcPfcShell()"); + + void *ctx; + PCShellGetContext(pc, &ctx); + PfcDiagData* data = static_cast<PfcDiagData*>(ctx); + + Vec b1, b2, b3, x1, x2, x3; + VecNestGetSubVec(b, 0, &b1); + VecNestGetSubVec(b, 1, &b2); + VecNestGetSubVec(b, 2, &b3); + + VecNestGetSubVec(x, 0, &x1); + VecNestGetSubVec(x, 1, &x2); + VecNestGetSubVec(x, 2, &x3); + + + // Hilfsvariablen + Vec y1, y2, tmp; + VecDuplicate(b1, &y1); + VecDuplicate(b1, &y2); + VecDuplicate(b1, &tmp); + + KSPSolve(data->kspM, b1, y1); // M*y1 = b1 + MatMult(data->matK, y1, tmp); // tmp := K*y1 + VecAYPX(tmp, -(data->tau), b2); // tmp := b2 - tau*tmp + + KSPSolve(data->kspMpK, tmp, y2); // (M+sqrt(tau)K)*y2 = tmp + + MatMult(data->matM, y2, tmp); // tmp := M*y2 + KSPSolve(data->kspS, tmp, x2); // MpK2*x2 = tmp + + VecCopy(x2, x1); // x1 := x2 + VecAXPBYPCZ(x1, 1.0, 1.0/(data->delta), -1.0/(data->delta), y1, y2); // x1 = 1*y1 + factor*y2 - factor*x1 + + MatMult(data->matK, x2, tmp); // tmp := K*x2 + VecAYPX(tmp, -1.0, b3); // tmp := b3 - tmp + + KSPSolve(data->kspM, tmp, x3); // M*x3 = tmp + + VecDestroy(&y1); + VecDestroy(&y2); + VecDestroy(&tmp); + + return 0; + } + + + void PetscPreconPfcDiag::init(const BlockMatrix& A, const Mat& matrix) + { + assert(tau != NULL); + PetscRunner::init(A, matrix); + + // init shell preconditioner + PCSetType(getPc(), PCSHELL); + PCShellSetApply(getPc(), pcPfcDiagShell); + PCShellSetContext(getPc(), &data); + + + double delta = sqrt(*tau); + + MatNestGetSubMat(matrix, 2, 2, &data.matM); + MatNestGetSubMat(matrix, 2, 1, &data.matK); + + MatDuplicate(data.matM, MAT_COPY_VALUES, &MpK); + MatAXPY(MpK, delta, data.matK, SAME_NONZERO_PATTERN); + + // create Matrix S + Mat DK; + MatDuplicate(data.matK, MAT_COPY_VALUES, &DK); + MatDuplicate(data.matM, MAT_COPY_VALUES, &matS); + + Vec x; // need to initialize vector + PetscInt n_rows, n_cols; + MatGetSize(data.matM, &n_rows,&n_cols); + VecCreateSeq(PETSC_COMM_SELF, n_rows, &x); + + MatGetDiagonal(data.matM, x); + VecReciprocal(x); + MatDiagonalScale(DK, x, PETSC_NULL); // DK := M_D^(-1)*K + MatMatMult(data.matK, DK, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &matS); // S := K*DK + MatAYPX(matS, delta, data.matM, DIFFERENT_NONZERO_PATTERN); // S = delta*S + M + MatAXPY(matS, (-2.0*delta), data.matK, DIFFERENT_NONZERO_PATTERN); // S = S - 2*delta*K + VecDestroy(&x); + MatDestroy(&DK); + + // init sub-solvers + createSubSolver(data.kspM, data.matM, "mass_"); + createSubSolver(data.kspMpK, MpK, "MpK_"); + createSubSolver(data.kspS, matS, "MpK2_"); + + data.delta = delta; + data.tau = *tau; + + int nIterM=5, nIterMpL=20, nIterMpL2=10; + double tolM=PETSC_DEFAULT, tolMpL=PETSC_DEFAULT, tolMpL2=PETSC_DEFAULT; + double rtolM=PETSC_DEFAULT, rtolMpL=PETSC_DEFAULT, rtolMpL2=PETSC_DEFAULT; + Parameters::get("precon_pfc_M->max iteration", nIterM); + Parameters::get("precon_pfc_MpL->max iteration", nIterMpL); + Parameters::get("precon_pfc_MpL2->max iteration", nIterMpL2); + Parameters::get("precon_pfc_M->tolerance", tolM); + Parameters::get("precon_pfc_MpL->tolerance", tolMpL); + Parameters::get("precon_pfc_MpL2->tolerance", tolMpL2); + Parameters::get("precon_pfc_M->relative tolerance", rtolM); + Parameters::get("precon_pfc_MpL->relative tolerance", rtolMpL); + Parameters::get("precon_pfc_MpL2->relative tolerance", rtolMpL2); + + bool useAMG = false; + Parameters::get("precon_pfc_MpL2->use AMG", useAMG); + + setSolver(data.kspM, "M_", KSPCG, PCJACOBI, rtolM, tolM, nIterM); + setSolver(data.kspMpK, "MpK_", KSPCG, PCJACOBI, rtolMpL, tolMpL, nIterMpL); + if (!useAMG) { + setSolver(data.kspS, "MpK2_", KSPCG, PCJACOBI, rtolMpL2, tolMpL2, nIterMpL2); + } else { + setSolver(data.kspS, "MpK2_", KSPRICHARDSON, PCHYPRE, rtolMpL2, tolMpL2, nIterMpL2); + } + } + + + void PetscPreconPfcDiag::exit() + { + FUNCNAME("PetscPreconPfcDiag::exit()"); + + MatDestroy(&MpK); + MatDestroy(&matS); + + KSPDestroy(&data.kspM); + KSPDestroy(&data.kspMpK); + KSPDestroy(&data.kspS); + + PetscRunner::exit(); + } +} diff --git a/extensions/preconditioner/PetscPreconPfcDiag.h b/extensions/preconditioner/PetscPreconPfcDiag.h new file mode 100644 index 0000000000000000000000000000000000000000..1c626487402f0fb7249682b3ee29e59d1238f725 --- /dev/null +++ b/extensions/preconditioner/PetscPreconPfcDiag.h @@ -0,0 +1,59 @@ +/****************************************************************************** + * + * Extension of AMDiS - Adaptive multidimensional simulations + * + * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. + * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis + * + * Authors: Simon Praetorius et al. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * + * See also license.opensource.txt in the distribution. + * + ******************************************************************************/ + +#ifndef AMDIS_PETSC_PRECON_PFC_DIAG_H +#define AMDIS_PETSC_PRECON_PFC_DIAG_H + +#include "solver/PetscSolver.h" + +namespace AMDiS { + + using namespace std; + + struct PfcDiagData { + KSP kspM, kspMpK, kspS; + Mat matM, matK; + double delta, tau; + }; + + class PetscPreconPfcDiag : public PetscRunner + { + public: + PetscPreconPfcDiag(LinearSolver* oem_) + : PetscRunner(oem_), + tau(NULL) + { } + + void setData(double *tauPtr) + { + tau = tauPtr; + } + + void init(const BlockMatrix& A, const Mat& fullMatrix); + void exit(); + + private: + Mat MpK; + Mat matS; + PfcDiagData data; + + double *tau; + }; + +} + +#endif // AMDIS_PETSC_PRECON_PFC_H diff --git a/extensions/preconditioner/PetscSolverPfc.cc b/extensions/preconditioner/PetscSolverPfc.cc index 303aa1e855eb335d678bd707dd14a5581b699b58..a3b9b9ddced053da2ef853a8e2877df0c2b89baf 100644 --- a/extensions/preconditioner/PetscSolverPfc.cc +++ b/extensions/preconditioner/PetscSolverPfc.cc @@ -102,7 +102,6 @@ namespace AMDiS { namespace Parallel { PCShellSetContext(getPc(), &data); double delta = sqrt(*tau); - double eps = sqrt(0.5); const FiniteElemSpace *feSpace = componentSpaces[0]; @@ -135,7 +134,7 @@ namespace AMDiS { namespace Parallel { // create MpK2-matrix DOFMatrix matrixMpK2(feSpace, feSpace); Operator laplaceOp3(feSpace, feSpace); - Simple_SOT sot3(eps*sqrt(delta)); + Simple_SOT sot3(sqrt(delta)); laplaceOp3.addTerm(&zot); laplaceOp3.addTerm(&sot3); matrixMpK2.assembleOperator(laplaceOp3); @@ -159,10 +158,30 @@ namespace AMDiS { namespace Parallel { // === Setup preconditioner data === data.delta = delta; data.tau = (*tau); + + int nIterM=5, nIterMpL=20, nIterMpL2=10; + double tolM=PETSC_DEFAULT, tolMpL=PETSC_DEFAULT, tolMpL2=PETSC_DEFAULT; + double rtolM=PETSC_DEFAULT, rtolMpL=PETSC_DEFAULT, rtolMpL2=PETSC_DEFAULT; + Parameters::get("precon_pfc_M->max iteration", nIterM); + Parameters::get("precon_pfc_MpL->max iteration", nIterMpL); + Parameters::get("precon_pfc_MpL2->max iteration", nIterMpL2); + Parameters::get("precon_pfc_M->tolerance", tolM); + Parameters::get("precon_pfc_MpL->tolerance", tolMpL); + Parameters::get("precon_pfc_MpL2->tolerance", tolMpL2); + Parameters::get("precon_pfc_M->relative tolerance", rtolM); + Parameters::get("precon_pfc_MpL->relative tolerance", rtolMpL); + Parameters::get("precon_pfc_MpL2->relative tolerance", rtolMpL2); + + bool useAMG = false; + Parameters::get("precon_pfc_MpL2->use AMG", useAMG); - petsc_helper::setSolver(data.kspM, "M_", KSPCG, PCBJACOBI, 0.0, 1e-8, 5); - petsc_helper::setSolver(data.kspMpK, "MpK_", KSPCG, PCBJACOBI, 0.0, 1e-6, 20); - petsc_helper::setSolver(data.kspMpK2, "MpK2_", KSPCG, PCBJACOBI, 0.0, 1e-6, 10); + petsc_helper::setSolver(data.kspM, "M_", KSPCG, PCJACOBI, rtolM, tolM, nIterM); + petsc_helper::setSolver(data.kspMpK, "MpK_", KSPCG, PCJACOBI, rtolMpL, tolMpL, nIterMpL); + if (!useAMG) { + petsc_helper::setSolver(data.kspMpK2, "MpK2_", KSPCG, PCJACOBI, rtolMpL2, tolMpL2, nIterMpL2); + } else { + petsc_helper::setSolver(data.kspMpK2, "MpK2_", KSPRICHARDSON, PCHYPRE, rtolMpL2, tolMpL2, nIterMpL2); + } } diff --git a/extensions/preconditioner/PetscSolverPfc_diag.cc b/extensions/preconditioner/PetscSolverPfc_diag.cc new file mode 100644 index 0000000000000000000000000000000000000000..249eaf8ab3128f84d7e231f86436399397877d85 --- /dev/null +++ b/extensions/preconditioner/PetscSolverPfc_diag.cc @@ -0,0 +1,233 @@ +/****************************************************************************** + * + * Extension of AMDiS - Adaptive multidimensional simulations + * + * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. + * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis + * + * Authors: Simon Praetorius et al. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * + * See also license.opensource.txt in the distribution. + * + ******************************************************************************/ + +#include "PetscSolverPfc_diag.h" +#include "parallel/PetscHelper.h" +#include "parallel/PetscSolverGlobalMatrix.h" + +namespace AMDiS { namespace Parallel { + + using namespace std; + + /// solve Pfc Preconditioner + PetscErrorCode pcPfcDiagShell(PC pc, Vec b, Vec x) // solve Px=b + { FUNCNAME("pcPfcDiagShell()"); + + void *ctx; + PCShellGetContext(pc, &ctx); + PfcDiagData* data = static_cast<PfcDiagData*>(ctx); + + Vec b1, b2, b3, x1, x2, x3; + VecNestGetSubVec(b, 0, &b1); + VecNestGetSubVec(b, 1, &b2); + VecNestGetSubVec(b, 2, &b3); + + VecNestGetSubVec(x, 0, &x1); + VecNestGetSubVec(x, 1, &x2); + VecNestGetSubVec(x, 2, &x3); + + + // Hilfsvariablen + Vec y1, y2, tmp; + VecDuplicate(b1, &y1); + VecDuplicate(b1, &y2); + VecDuplicate(b1, &tmp); + + KSPSolve(data->kspM, b1, y1); // M*y1 = b1 + MatMult(data->matK, y1, tmp); // tmp := K*y1 + VecAYPX(tmp, -(data->tau), b2); // tmp := b2 - tau*tmp + + KSPSolve(data->kspMpK, tmp, y2); // (M+sqrt(tau)K)*y2 = tmp + + + MatMult(data->matM, y2, tmp); // tmp := M*y2 + KSPSolve(data->kspS, tmp, x2); + + VecCopy(x2, x1); // x1 := x2 + VecAXPBYPCZ(x1, 1.0, 1.0/(data->delta), -1.0/(data->delta), y1, y2); // x1 = 1*y1 + factor*y2 - factor*x1 + + MatMult(data->matK, x2, tmp); // tmp := K*x2 + VecAYPX(tmp, -1.0, b3); // tmp := b3 - tmp + + KSPSolve(data->kspM, tmp, x3); // M*x3 = tmp + + VecDestroy(&y1); + VecDestroy(&y2); + VecDestroy(&tmp); + + return 0; + } + + void PetscSolverPfcDiag::initSolver(KSP &ksp) + { + // Create FGMRES based outer solver + KSPCreate(meshDistributor->getMpiComm(0), &ksp); + KSPSetOperators(ksp, getMatInterior(), getMatInterior(), SAME_NONZERO_PATTERN); + if (getInfo() >= 10) + KSPMonitorSet(ksp, KSPMonitorDefault, PETSC_NULL, PETSC_NULL); + else if (getInfo() >= 20) + KSPMonitorSet(ksp, KSPMonitorTrueResidualNorm, PETSC_NULL, PETSC_NULL); + petsc_helper::setSolver(ksp, "pfc_", KSPFGMRES, PCNONE, getRelative(), getTolerance(), getMaxIterations()); + KSPSetFromOptions(ksp); + + + if (useOldInitialGuess) + KSPSetInitialGuessNonzero(ksp, PETSC_TRUE); + } + + + void PetscSolverPfcDiag::initPreconditioner(PC pc) + { + FUNCNAME("PetscSolverPfcDiag::initPreconditioner()"); + + TEST_EXIT(tau)("tau pointer not set!\n"); + + PCSetType(getPc(), PCSHELL); + PCShellSetApply(getPc(), pcPfcDiagShell); + PCShellSetContext(getPc(), &data); + + double delta = sqrt(*tau); + + const FiniteElemSpace *feSpace = componentSpaces[0]; + + // create mass-matrix + DOFMatrix matrixM(feSpace, feSpace); + Operator massOp(feSpace, feSpace); + Simple_ZOT zot; + massOp.addTerm(&zot); + matrixM.assembleOperator(massOp); + + solverM = createSubSolver(0, "M_"); + solverM->fillPetscMatrix(&matrixM); + data.matM = solverM->getMatInterior(); + data.kspM = solverM->getSolver(); + + // create MpK-matrix + DOFMatrix matrixMpK(feSpace, feSpace); + Operator laplaceOp2(feSpace, feSpace); + Simple_SOT sot2(delta); + laplaceOp2.addTerm(&zot); + laplaceOp2.addTerm(&sot2); + matrixMpK.assembleOperator(laplaceOp2); + + solverMpK = createSubSolver(0, "MpK_"); + solverMpK->fillPetscMatrix(&matrixMpK); + matMpK = solverMpK->getMatInterior(); + data.kspMpK = solverMpK->getSolver(); + + + // create MpK2-matrix + + // create laplace-matrix + DOFMatrix matrixK(feSpace, feSpace); + Operator laplaceOp(feSpace, feSpace); + Simple_SOT sot; + laplaceOp.addTerm(&sot); + matrixK.assembleOperator(laplaceOp); + + solverK = createSubSolver(0, "K_"); + solverK->fillPetscMatrix(&matrixK); + data.matK = solverK->getMatInterior(); + + // create Matrix S + solverS = createSubSolver(0, "MpK2_"); + solverS->fillPetscMatrix(&matrixM); // just to create a dummy matrix + matS = solverS->getMatInterior(); + data.kspS = solverS->getSolver(); + + Vec x; // need to initialize vector + solverS->createVec(*solverS->getDofMapping(), x); + Mat DK; + MatDuplicate(data.matK, MAT_COPY_VALUES, &DK); + + MatGetDiagonal(data.matM, x); + VecReciprocal(x); + MatDiagonalScale(DK, x, PETSC_NULL); // DK := M_D^(-1)*K + MatMatMult(data.matK, DK, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &matS); // S := K*DK + MatAYPX(matS, delta, data.matM, DIFFERENT_NONZERO_PATTERN); // S = delta*S + M + MatAXPY(matS, (-2.0*delta), data.matK, DIFFERENT_NONZERO_PATTERN); // S = S - 2*sqrt(delta)*K + VecDestroy(&x); + MatDestroy(&DK); + KSPSetOperators(data.kspS, matS, matS, SAME_NONZERO_PATTERN); + + // === Setup preconditioner data === + data.delta = delta; + data.tau = (*tau); + + int nIterM=5, nIterMpL=20, nIterMpL2=10; + double tolM=1.e-6, tolMpL=1.e-6, tolMpL2=1.e-6; + Parameters::get("precon_pfc_M->max iteration", nIterM); + Parameters::get("precon_pfc_MpL->max iteration", nIterMpL); + Parameters::get("precon_pfc_MpL2->max iteration", nIterMpL2); + Parameters::get("precon_pfc_M->tolerance", tolM); + Parameters::get("precon_pfc_MpL->tolerance", tolMpL); + Parameters::get("precon_pfc_MpL2->tolerance", tolMpL2); + + petsc_helper::setSolver(data.kspM, "M_", KSPCG, PCBJACOBI, 0.0, tolM, nIterM); + petsc_helper::setSolver(data.kspMpK, "MpK_", KSPCG, PCBJACOBI, 0.0, tolMpL, nIterMpL); + petsc_helper::setSolver(data.kspS, "MpK2_", KSPCG, PCBJACOBI, 0.0, tolMpL2, nIterMpL2); + } + + + void PetscSolverPfcDiag::exitPreconditioner(PC pc) + { + FUNCNAME("PetscSolverPfcDiag::exit()"); + +// MatDestroy(&matMpK); +// MatDestroy(&matMpK2); + + solverM->destroyMatrixData(); + solverK->destroyMatrixData(); + solverMpK->destroyMatrixData(); + solverS->destroyMatrixData(); + + solverM->destroyVectorData(); + solverK->destroyVectorData(); + solverMpK->destroyVectorData(); + solverS->destroyVectorData(); + + delete solverM; + solverM = NULL; + delete solverK; + solverK = NULL; + delete solverMpK; + solverMpK = NULL; + delete solverS; + solverS = NULL; + } + + + PetscSolver* PetscSolverPfcDiag::createSubSolver(int component, + string kspPrefix) + { + FUNCNAME("PetscSolverPfcDiag::createSubSolver()"); + + vector<const FiniteElemSpace*> fe; + fe.push_back(componentSpaces[component]); + + PetscSolver* subSolver = new PetscSolverGlobalMatrix(""); + subSolver->setKspPrefix(kspPrefix.c_str()); + subSolver->setMeshDistributor(meshDistributor, 0); + subSolver->init(fe, fe); + + ParallelDofMapping &subDofMap = subSolver->getDofMap(); + subDofMap[0] = dofMap[component]; + subDofMap.update(); + + return subSolver; + } +} } diff --git a/extensions/preconditioner/PetscSolverPfc_diag.h b/extensions/preconditioner/PetscSolverPfc_diag.h new file mode 100644 index 0000000000000000000000000000000000000000..0dd3a91b43266e79e6b013ec3e016cda919d75c4 --- /dev/null +++ b/extensions/preconditioner/PetscSolverPfc_diag.h @@ -0,0 +1,87 @@ +/****************************************************************************** + * + * Extension of AMDiS - Adaptive multidimensional simulations + * + * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved. + * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis + * + * Authors: Simon Praetorius et al. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * + * See also license.opensource.txt in the distribution. + * + ******************************************************************************/ + +#ifndef AMDIS_PETSC_PRECON_PFC_DIAG_H +#define AMDIS_PETSC_PRECON_PFC_DIAG_H + +#include "parallel/PetscSolverGlobalBlockMatrix.h" + +namespace AMDiS { namespace Parallel { + + struct PfcDiagData { + KSP kspM, kspMpK, kspS; + Mat matM, matK, matS; + double delta, tau; + }; + + class PetscSolverPfcDiag : public PetscSolverGlobalBlockMatrix + { + public: + /// Creator class + class Creator : public LinearSolverCreator + { + public: + virtual ~Creator() {} + + /// Returns a new PetscSolver object. + LinearSolver* create() + { + return new PetscSolverPfcDiag(this->name); + } + }; + + PetscSolverPfcDiag(std::string name) + : PetscSolverGlobalBlockMatrix(name), + solverM(NULL), + solverK(NULL), + solverMpK(NULL), + solverS(NULL), + useOldInitialGuess(false), + tau(NULL) + { + Parameters::get(initFileStr + "->use old initial guess", useOldInitialGuess); + } + + void setData(double *tauPtr) + { + tau = tauPtr; + } + + protected: + void initSolver(KSP &ksp); + + void initPreconditioner(PC pc); + void exitPreconditioner(PC pc); + + PetscSolver* createSubSolver(int component, std::string kspPrefix); + + private: + Mat matMpK; + Mat matS; + PfcDiagData data; + + PetscSolver *solverM, *solverK, *solverMpK, *solverS; + + bool useOldInitialGuess; + SystemVector* solution; + + double *tau; + }; + +} } + +#endif // AMDIS_PETSC_PRECON_PFC_DIAG_H diff --git a/extensions/preconditioner/PhaseFieldCrystal_.cc b/extensions/preconditioner/PhaseFieldCrystal_.cc index 8d822dcacaff940eb44170ac2d71b44c85c0d028..8928d4c129a9d096960cd538a5a94fd5b53005b9 100644 --- a/extensions/preconditioner/PhaseFieldCrystal_.cc +++ b/extensions/preconditioner/PhaseFieldCrystal_.cc @@ -1,7 +1,8 @@ #include "PhaseFieldCrystal_.h" +namespace AMDiS { namespace base_problems { + using namespace std; -using namespace AMDiS; PhaseFieldCrystal_::PhaseFieldCrystal_(const std::string &name_, bool createProblem) : super(name_, createProblem), @@ -83,3 +84,5 @@ void PhaseFieldCrystal_::fillOperators() void PhaseFieldCrystal_::fillBoundaryConditions() {} + +} } diff --git a/extensions/preconditioner/PhaseFieldCrystal_.h b/extensions/preconditioner/PhaseFieldCrystal_.h index bf8770b02304fd6ffa0f3e4c650b46a91d47d52f..58fe938fdd9a6f20034228e232c8e6d5457c9b90 100644 --- a/extensions/preconditioner/PhaseFieldCrystal_.h +++ b/extensions/preconditioner/PhaseFieldCrystal_.h @@ -7,15 +7,15 @@ #include "BaseProblem.h" #include "ExtendedProblemStat.h" -using namespace AMDiS; +namespace AMDiS { namespace base_problems { /** Phase-field Crystal problem */ -class PhaseFieldCrystal_ : public BaseProblem<ExtendedProblemStat> +class PhaseFieldCrystal_ : public BaseProblem<extensions::ExtendedProblemStat> { public: // typedefs - typedef BaseProblem<ExtendedProblemStat> super; + typedef BaseProblem<extensions::ExtendedProblemStat> super; public: @@ -75,4 +75,6 @@ class MobilityPfc : public AbstractFunction<double,double> double delta; }; +} } + #endif // PHASE_FIELD_CRYSTAL_PRECON_H_ diff --git a/extensions/time/ExtendedRosenbrockAdaptInstationary.h b/extensions/time/ExtendedRosenbrockAdaptInstationary.h index ab95806afdbf4289dadba4bd687a572ad1016c83..f74b3e41652ec23fb3825f5a547eafadf23f2103 100644 --- a/extensions/time/ExtendedRosenbrockAdaptInstationary.h +++ b/extensions/time/ExtendedRosenbrockAdaptInstationary.h @@ -27,7 +27,7 @@ #include "AdaptInstationary.h" #include "CreatorMap.h" -namespace AMDiS { +namespace AMDiS { namespace extensions { template<typename ProblemStationary> class ExtendedRosenbrockAdaptInstationary : public AdaptInstationary @@ -56,6 +56,14 @@ namespace AMDiS { ProblemTimeInterface &problemInstat, AdaptInfo &initialInfo, time_t initialTimestamp = 0); + + ExtendedRosenbrockAdaptInstationary(std::string name, + ProblemIterationInterface &problemStat, + ProblemStationary &rosenbrockStat_, + AdaptInfo &info, + ProblemTimeInterface &problemInstat, + AdaptInfo &initialInfo, + time_t initialTimestamp = 0); /// Runs the Rosenbrock loop until one timestep is accepted. void oneTimestep(); @@ -66,7 +74,7 @@ namespace AMDiS { * removed, remove also this function. * TODO: Remove if obsolete constructor will be removed. */ - void initConstructor(ProblemStationary *problemStat); + void initConstructor(); void reset(); @@ -107,7 +115,7 @@ namespace AMDiS { }; -} +} } #include "ExtendedRosenbrockAdaptInstationary.hh" diff --git a/extensions/time/ExtendedRosenbrockAdaptInstationary.hh b/extensions/time/ExtendedRosenbrockAdaptInstationary.hh index 18c83144d2630a121daa3df3f2f7e45f2bfecaf3..8b4e865ee35ceb7d1dd503f7e699cc22ca4dd38e 100644 --- a/extensions/time/ExtendedRosenbrockAdaptInstationary.hh +++ b/extensions/time/ExtendedRosenbrockAdaptInstationary.hh @@ -21,7 +21,7 @@ #include "ProblemTimeInterface.h" #include "VectorOperations.h" -namespace AMDiS { +namespace AMDiS { namespace extensions { template<typename ProblemStationary> ExtendedRosenbrockAdaptInstationary<ProblemStationary>::ExtendedRosenbrockAdaptInstationary(std::string name, @@ -62,13 +62,36 @@ namespace AMDiS { dbgTimestepStudy(false) { FUNCNAME("ExtendedRosenbrockAdaptInstationary::ExtendedRosenbrockAdaptInstationary()"); - initConstructor(&problemStat); + initConstructor(); rosenbrockStat->setOldTime(adaptInfo->getStartTime()); } template<typename ProblemStationary> - void ExtendedRosenbrockAdaptInstationary<ProblemStationary>::initConstructor(ProblemStationary *problemStat) + ExtendedRosenbrockAdaptInstationary<ProblemStationary>::ExtendedRosenbrockAdaptInstationary(std::string name, + ProblemIterationInterface &problemStat, + ProblemStationary &rosenbrockStat_, + AdaptInfo &info, + ProblemTimeInterface &problemInstat, + AdaptInfo &initialInfo, + time_t initialTimestamp) + : AdaptInstationary(name, problemStat, info, problemInstat, initialInfo, initialTimestamp), + rosenbrockStat(&rosenbrockStat_), + firstTimestep(true), + lastTimestepRejected(false), + succRejection(false), + fixFirstTimesteps(0), + tau(1.0), + dbgTimestepStudy(false) + { + FUNCNAME("ExtendedRosenbrockAdaptInstationary::ExtendedRosenbrockAdaptInstationary()"); + initConstructor(); + rosenbrockStat->setOldTime(adaptInfo->getStartTime()); + } + + + template<typename ProblemStationary> + void ExtendedRosenbrockAdaptInstationary<ProblemStationary>::initConstructor() { FUNCNAME("ExtendedRosenbrockAdaptInstationary::initConstructor()"); @@ -278,4 +301,5 @@ namespace AMDiS { adaptInfo->setLastProcessedTimestep(adaptInfo->getTimestep()); adaptInfo->incTimestepNumber(); } -} + +} } diff --git a/extensions/time/ExtendedRosenbrockStationary.cc b/extensions/time/ExtendedRosenbrockStationary.cc index c913e43d024c4e1cf57efd07824292051288284b..8afa4c834a090d73e11f6a3c67e632a302c04843 100644 --- a/extensions/time/ExtendedRosenbrockStationary.cc +++ b/extensions/time/ExtendedRosenbrockStationary.cc @@ -28,10 +28,10 @@ #include "parallel/MeshDistributor.h" #endif -using namespace AMDiS; +namespace AMDiS { namespace extensions { void ExtendedRosenbrockStationary::initialize(Flag initFlag, - ProblemStat *adoptProblem, + ProblemStatSeq *adoptProblem, Flag adoptFlag) { FUNCNAME("ExtendedRosenbrockStationary::initialize()"); @@ -273,7 +273,7 @@ using namespace AMDiS; } - void ExtendedRosenbrockStationary::addDirichletBC(BoundaryType type, int row, int col, + void ExtendedRosenbrockStationary::addDirichletBC_RB(BoundaryType type, int row, int col, AbstractFunction<double, WorldVector<double> > *fct, AbstractFunction<double, WorldVector<double> > *fctDt) { @@ -285,69 +285,77 @@ using namespace AMDiS; } - void ExtendedRosenbrockStationary::addDirichletBC(WorldVector<double> *pos, int row, int col, - AbstractFunction<double, WorldVector<double> > *fct) + void ExtendedRosenbrockStationary::addDirichletBC_RB(WorldVector<double> *pos, int row, int col, + AbstractFunction<double, WorldVector<double> > *fct, + AbstractFunction<double, WorldVector<double> > *fctDt) { DOFVector<double>* vec = new DOFVector<double>(componentSpaces[col], "vec"); - MyRosenbrockBoundary bound(fct, NULL, vec, row, col); + MyRosenbrockBoundary bound(fct, fctDt, vec, row, col); boundaries.push_back(bound); super::addDirichletBC(pos, row, col, vec); } - void ExtendedRosenbrockStationary::addDirichletBC(DofIndex *idx, int row, int col, - AbstractFunction<double, WorldVector<double> > *fct) + void ExtendedRosenbrockStationary::addDirichletBC_RB(DofIndex *idx, int row, int col, + AbstractFunction<double, WorldVector<double> > *fct, + AbstractFunction<double, WorldVector<double> > *fctDt) { DOFVector<double>* vec = new DOFVector<double>(componentSpaces[col], "vec"); - MyRosenbrockBoundary bound(fct, NULL, vec, row, col); + MyRosenbrockBoundary bound(fct, fctDt, vec, row, col); boundaries.push_back(bound); super::addDirichletBC(idx, row, col, vec); } - void ExtendedRosenbrockStationary::addDirichletBC(AbstractFunction<double, WorldVector<double> > *signedDist, int row, int col, - AbstractFunction<double, WorldVector<double> > *fct) + void ExtendedRosenbrockStationary::addDirichletBC_RB(AbstractFunction<double, WorldVector<double> > *signedDist, int row, int col, + AbstractFunction<double, WorldVector<double> > *fct, + AbstractFunction<double, WorldVector<double> > *fctDt) { DOFVector<double>* vec = new DOFVector<double>(componentSpaces[col], "vec"); - MyRosenbrockBoundary bound(fct, NULL, vec, row, col); + MyRosenbrockBoundary bound(fct, fctDt, vec, row, col); boundaries.push_back(bound); super::addDirichletBC(signedDist, row, col, vec); } - void ExtendedRosenbrockStationary::addDirichletBC(DOFVector<double> *signedDist, int row, int col, - AbstractFunction<double, WorldVector<double> > *fct) + void ExtendedRosenbrockStationary::addDirichletBC_RB(DOFVector<double> *signedDist, int row, int col, + AbstractFunction<double, WorldVector<double> > *fct, + AbstractFunction<double, WorldVector<double> > *fctDt) { DOFVector<double>* vec = new DOFVector<double>(componentSpaces[col], "vec"); - MyRosenbrockBoundary bound(fct, NULL, vec, row, col); + MyRosenbrockBoundary bound(fct, fctDt, vec, row, col); boundaries.push_back(bound); super::addDirichletBC(signedDist, row, col, vec); } - void ExtendedRosenbrockStationary::addDirichletBC(BoundaryType nr, AbstractFunction<bool, WorldVector<double> >* meshIndicator, + void ExtendedRosenbrockStationary::addDirichletBC_RB(BoundaryType nr, AbstractFunction<bool, WorldVector<double> >* meshIndicator, int row, int col, - AbstractFunction<double, WorldVector<double> > *fct) + AbstractFunction<double, WorldVector<double> > *fct, + AbstractFunction<double, WorldVector<double> > *fctDt) { DOFVector<double>* vec = new DOFVector<double>(componentSpaces[col], "vec"); - MyRosenbrockBoundary bound(fct, NULL, vec, row, col); + MyRosenbrockBoundary bound(fct, fctDt, vec, row, col); boundaries.push_back(bound); super::addDirichletBC(nr, meshIndicator, row, col, vec); } - void ExtendedRosenbrockStationary::addDirichletBC(AbstractFunction<bool, WorldVector<double> >* meshIndicator, + void ExtendedRosenbrockStationary::addDirichletBC_RB(AbstractFunction<bool, WorldVector<double> >* meshIndicator, int row, int col, - AbstractFunction<double, WorldVector<double> > *fct) + AbstractFunction<double, WorldVector<double> > *fct, + AbstractFunction<double, WorldVector<double> > *fctDt) { DOFVector<double>* vec = new DOFVector<double>(componentSpaces[col], "vec"); - MyRosenbrockBoundary bound(fct, NULL, vec, row, col); + MyRosenbrockBoundary bound(fct, fctDt, vec, row, col); boundaries.push_back(bound); super::addDirichletBC(meshIndicator, row, col, vec); } + +} } diff --git a/extensions/time/ExtendedRosenbrockStationary.h b/extensions/time/ExtendedRosenbrockStationary.h index 6a841989035a34ea0aca2da385c41afabfe841fd..d01ccabbaffea0991b60ca5406febb329382d5c2 100644 --- a/extensions/time/ExtendedRosenbrockStationary.h +++ b/extensions/time/ExtendedRosenbrockStationary.h @@ -31,7 +31,7 @@ #include "parallel/ParallelProblemStat.h" #endif -using namespace AMDiS; +namespace AMDiS { namespace extensions { struct MyRosenbrockBoundary { @@ -76,11 +76,12 @@ using namespace AMDiS; } - virtual void initialize(Flag initFlag, - ProblemStat *adoptProblem = NULL, - Flag adoptFlag = INIT_NOTHING); + void initialize(Flag initFlag, + ProblemStatSeq *adoptProblem = NULL, + Flag adoptFlag = INIT_NOTHING) override; - virtual Flag oneIteration(AdaptInfo *adaptInfo, Flag toDo); + Flag oneIteration(AdaptInfo *adaptInfo, Flag toDo) override; + Flag stageIteration(AdaptInfo *adaptInfo, Flag flag, bool asmMatrix, bool asmVector); @@ -218,9 +219,9 @@ using namespace AMDiS; } /// Adds a Dirichlet boundary condition, where the rhs is given by an AbstractFunction. - void addDirichletBC(BoundaryType type, int row, int col, - AbstractFunction<double, WorldVector<double> > *b, - AbstractFunction<double, WorldVector<double> > *bDt = NULL); + void addDirichletBC_RB(BoundaryType type, int row, int col, + AbstractFunction<double, WorldVector<double> > *b, + AbstractFunction<double, WorldVector<double> > *bDt = NULL); /// Adds a Dirichlet boundary condition, where the rhs is given by a DOFVector. void addDirichletBC(BoundaryType type, int row, int col, @@ -234,25 +235,31 @@ using namespace AMDiS; // special boundary conditions defined in ExtendedProblemStat // _________________________________________________________________ - void addDirichletBC(WorldVector<double> *pos, int row, int col, - AbstractFunction<double, WorldVector<double> > *fct); + void addDirichletBC_RB(WorldVector<double> *pos, int row, int col, + AbstractFunction<double, WorldVector<double> > *fct, + AbstractFunction<double, WorldVector<double> > *bDt = NULL); - void addDirichletBC(DofIndex *idx, int row, int col, - AbstractFunction<double, WorldVector<double> > *fct); + void addDirichletBC_RB(DofIndex *idx, int row, int col, + AbstractFunction<double, WorldVector<double> > *fct, + AbstractFunction<double, WorldVector<double> > *bDt = NULL); - void addDirichletBC(AbstractFunction<double, WorldVector<double> > *signedDist, int row, int col, - AbstractFunction<double, WorldVector<double> > *fct); + void addDirichletBC_RB(AbstractFunction<double, WorldVector<double> > *signedDist, int row, int col, + AbstractFunction<double, WorldVector<double> > *fct, + AbstractFunction<double, WorldVector<double> > *bDt = NULL); - void addDirichletBC(DOFVector<double> *signedDist, int row, int col, - AbstractFunction<double, WorldVector<double> > *fct); + void addDirichletBC_RB(DOFVector<double> *signedDist, int row, int col, + AbstractFunction<double, WorldVector<double> > *fct, + AbstractFunction<double, WorldVector<double> > *bDt = NULL); - void addDirichletBC(BoundaryType nr, AbstractFunction<bool, WorldVector<double> >* meshIndicator, - int row, int col, - AbstractFunction<double, WorldVector<double> > *fct); + void addDirichletBC_RB(BoundaryType nr, AbstractFunction<bool, WorldVector<double> >* meshIndicator, + int row, int col, + AbstractFunction<double, WorldVector<double> > *fct, + AbstractFunction<double, WorldVector<double> > *bDt = NULL); - void addDirichletBC(AbstractFunction<bool, WorldVector<double> >* meshIndicator, - int row, int col, - AbstractFunction<double, WorldVector<double> > *fct); + void addDirichletBC_RB(AbstractFunction<bool, WorldVector<double> >* meshIndicator, + int row, int col, + AbstractFunction<double, WorldVector<double> > *fct, + AbstractFunction<double, WorldVector<double> > *bDt = NULL); protected: void init(); @@ -299,5 +306,6 @@ using namespace AMDiS; std::vector<double> errorEstWeights; }; +} } #endif // MY_ROSENBROCKSTATIONARY_H