├── .clang-format ├── .gitmodules ├── CMakeLists.txt ├── Documentation ├── CMakeLists.txt ├── Doxyfile.in ├── DoxygenLayout.xml └── customdoxygen.css ├── LICENCE ├── README.md ├── build_lib.sh ├── cmake ├── CorrectWindowsPaths.cmake ├── FindBLACS.cmake ├── FindBLAS.cmake ├── FindLAPACK.cmake ├── FindMETIS.cmake ├── FindMUMPS.cmake ├── FindPARMETIS.cmake ├── FindPETSC.cmake ├── FindPORD.cmake ├── FindPYTHON.cmake ├── FindPackageMultipass.cmake ├── FindRAPIDYAML.cmake ├── FindSCALAPACK.cmake ├── FindSCOTCH.cmake ├── FindUMFPACK.cmake ├── ResolveCompilerPaths.cmake └── cmake-modules-master │ ├── CorrectWindowsPaths.cmake │ ├── FindFFTW.cmake │ ├── FindGSL.cmake │ ├── FindGit.cmake │ ├── FindITAPS.cmake │ ├── FindNetCDF.cmake │ ├── FindPETSc.cmake │ ├── FindPackageMultipass.cmake │ ├── LICENSE │ ├── README │ └── ResolveCompilerPaths.cmake ├── cpp ├── CMakeLists.txt ├── FESpace │ ├── BDM1.cpp │ ├── BDM2.cpp │ ├── CMakeLists.txt │ ├── FESpace.cpp │ ├── FESpace.hpp │ ├── GTypeOfFE.cpp │ ├── GTypeOfFE.hpp │ ├── GTypeOfFE_Sum.cpp │ ├── GTypeOfFE_Sum.hpp │ ├── Ned0.cpp │ ├── P0.cpp │ ├── P1.cpp │ ├── P1dc.cpp │ ├── P2.cpp │ ├── P2BR.cpp │ ├── P2dc.cpp │ ├── P3.cpp │ ├── P3dc.cpp │ ├── P4.cpp │ ├── QuadratureFormular.cpp │ ├── QuadratureFormular.hpp │ ├── RT0.cpp │ ├── RT1.cpp │ ├── RT2.cpp │ ├── expression.cpp │ ├── expression.hpp │ ├── expression.tpp │ ├── finiteElement.cpp │ ├── finiteElement.hpp │ ├── funfem_util.hpp │ ├── integrationFunFEM.hpp │ ├── interpolation.hpp │ ├── limiter.cpp │ ├── limiter.hpp │ ├── macroElement.cpp │ ├── macroElement.hpp │ ├── normsFunFEM.hpp │ ├── operationTypeFE.hpp │ ├── paraview.cpp │ ├── paraview.hpp │ ├── restriction.hpp │ ├── transformation.cpp │ └── transformation.hpp ├── algoim │ ├── bernstein.hpp │ ├── binomial.hpp │ ├── booluarray.hpp │ ├── gaussquad.hpp │ ├── hocp.hpp │ ├── hyperrectangle.hpp │ ├── interval.hpp │ ├── kdtree.hpp │ ├── multiloop.hpp │ ├── newtoncp.hpp │ ├── polyset.hpp │ ├── quadrature_general.hpp │ ├── quadrature_multipoly.hpp │ ├── real.hpp │ ├── sparkstack.hpp │ ├── stencilpoly.hpp │ ├── tanhsinh.hpp │ ├── utility.hpp │ ├── uvector.hpp │ └── xarray.hpp ├── common │ ├── AlgoimInterface.cpp │ ├── AlgoimInterface.hpp │ ├── AlgoimInterface.tpp │ ├── CMakeLists.txt │ ├── GenericElement.hpp │ ├── GenericInterface.hpp │ ├── GenericMesh.cpp │ ├── GenericMesh.hpp │ ├── GenericVertex.hpp │ ├── Label.hpp │ ├── Mesh1dn.cpp │ ├── Mesh1dn.hpp │ ├── Mesh2dn.cpp │ ├── Mesh2dn.hpp │ ├── Mesh3dn.cpp │ ├── Mesh3dn.hpp │ ├── RNM.hpp │ ├── RNM_op.hpp │ ├── RNM_opc.hpp │ ├── RNM_tpl.hpp │ ├── SparseMatMap.cpp │ ├── SparseMatMap.hpp │ ├── base_interface.cpp │ ├── base_interface.hpp │ ├── cut_mesh.cpp │ ├── cut_mesh.hpp │ ├── cut_mesh.tpp │ ├── cut_method.cpp │ ├── cut_method.hpp │ ├── dataStruct1D.cpp │ ├── dataStruct1D.hpp │ ├── dataStruct2D.cpp │ ├── dataStruct2D.hpp │ ├── dataStruct3D.cpp │ ├── dataStruct3D.hpp │ ├── fracture.hpp │ ├── geometry.cpp │ ├── geometry.hpp │ ├── global.cpp │ ├── global.hpp │ ├── interface_levelSet.cpp │ ├── interface_levelSet.hpp │ ├── interface_levelSet.tpp │ ├── libmesh5.c │ ├── libmesh5.h │ ├── logger.cpp │ ├── logger.hpp │ ├── marker.cpp │ ├── marker.hpp │ ├── parametrization.cpp │ ├── parametrization.hpp │ ├── point.hpp │ ├── spline.cpp │ ├── spline.hpp │ └── time_interface.hpp ├── concept │ └── function.hpp ├── cutfem.hpp ├── example │ ├── CMakeLists.txt │ ├── convection_diffusion │ │ ├── bulk.cpp │ │ ├── coupled.cpp │ │ ├── merging.cpp │ │ ├── output_bulk.dat │ │ └── output_coupled.dat │ ├── darcy_fictitious │ │ ├── DF_example1.cpp │ │ ├── DF_example2.cpp │ │ ├── darcy_B0B_example1.cpp │ │ └── darcy_B0B_example2.cpp │ ├── darcy_interface │ │ ├── DI_example1.cpp │ │ ├── DI_example1_3D.cpp │ │ └── DI_example2.cpp │ ├── hyberbolic_conservation_law │ │ ├── DG_CutFEM_ex_1.cpp │ │ ├── DG_CutFEM_ex_2.cpp │ │ ├── limiter_accuracy_conservation_test.cpp │ │ ├── limiter_burger_equation.cpp │ │ ├── limiter_non_smooth_initial_data.cpp │ │ └── limiter_smooth_solution.cpp │ ├── meshing.cpp │ ├── navier_stokes │ │ ├── navier_stokes_raising_drop_2D.cpp │ │ ├── navier_stokes_surfactant_example2.cpp │ │ └── taylor_green_vortex.cpp │ ├── stokes │ │ ├── fictitious_problem │ │ │ ├── stokes_fictitious_RT_example2.cpp │ │ │ ├── stokes_fictitious_example1.cpp │ │ │ ├── stokes_fictitious_vorticity_example1.cpp │ │ │ └── stokes_fictitious_vorticity_example2.cpp │ │ ├── interface_problem │ │ │ ├── stokesRT_dynamic_drop.cpp │ │ │ └── stokesRT_static_drop.cpp │ │ └── stokes_erik.hpp │ └── tests │ │ └── test_dg_time.cpp ├── num │ ├── DA.hpp │ ├── gnuplot.hpp │ ├── matlab.cpp │ ├── matlab.hpp │ ├── print_container.hpp │ ├── redirectOutput.hpp │ ├── sort_array.hpp │ ├── timer.hpp │ └── util.hpp ├── parallel │ ├── CMakeLists.txt │ ├── cfmpi.cpp │ ├── cfmpi.hpp │ ├── cfmpi.tpp │ ├── cfomp.hpp │ ├── dummy_cfmpi.hpp │ ├── partitioner.cpp │ └── partitioner.hpp ├── problem │ ├── AlgoimBaseCutProblem.hpp │ ├── AlgoimBaseCutProblem.tpp │ ├── AlgoimIntegration.hpp │ ├── CMakeLists.txt │ ├── CutFEM_parameter.cpp │ ├── CutFEM_parameter.hpp │ ├── baseCutProblem.hpp │ ├── baseCutProblem_Function.hpp │ ├── baseProblem.cpp │ ├── baseProblem.hpp │ ├── baseProblem_Function.hpp │ ├── extension.cpp │ ├── extension.hpp │ ├── generalNorm.hpp │ ├── itemVF.cpp │ ├── itemVF.hpp │ ├── levelSet.cpp │ ├── levelSet.hpp │ ├── mapping.hpp │ ├── problem.cpp │ ├── problem.hpp │ ├── projection.hpp │ ├── reinitialization.cpp │ ├── reinitialization.hpp │ ├── reinitialization.tpp │ ├── solver_advection.hpp │ ├── solver_curvature.hpp │ ├── solver_stokes.hpp │ ├── testFunction.cpp │ ├── testFunction.hpp │ └── time_scheme.hpp └── solver │ ├── CMakeLists.txt │ ├── solver.cpp │ ├── solver.hpp │ ├── solverMumps.cpp │ ├── solverMumps.hpp │ └── solverMumpsMPI.cpp ├── cutFEMConfig.in └── julia ├── condition_number_cd.jl └── stokes_rhs.ipynb /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "SuiteSparse"] 2 | path = SuiteSparse 3 | url = https://github.com/DrTimothyAldenDavis/SuiteSparse.git -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.16) 2 | project(libCutFEM VERSION 0.1 LANGUAGES CXX) 3 | 4 | ## ############################## 5 | ## Options 6 | ## ############################## 7 | 8 | option(USE_MPI "Perform a parallel computation" OFF) 9 | option(USE_OMP "Perform a parallel omp computation" OFF) 10 | option(USE_UMFPACK "Found the UMFpack library" ON) 11 | option(USE_LAPACK "Found the lapacke library" OFF) 12 | option(USE_MUMPS "Found the MUMPS library" OFF) 13 | 14 | option(CUTFEM_BUILD_DEBUG "Build to allow debugging" OFF) 15 | option(CUTFEM_BUILD_EXAMPLE "Build the cpp example" ON) 16 | option(CUTFEM_CREATE_DOCS "Build library documentation (requires Doxygen and Graphviz/Dot to be installed)" OFF) 17 | 18 | configure_file(cutFEMConfig.in cutFEMConfig.h) 19 | configure_file(cutFEMConfig.in ../cpp/cutFEMConfig.h) 20 | 21 | 22 | ## ############################## 23 | ## Configuration 24 | ## ############################## 25 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib/) 26 | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib/) 27 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/) 28 | set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/") 29 | 30 | 31 | 32 | if(${CUTFEM_BUILD_DEBUG}) 33 | set(CMAKE_BUILD_TYPE Debug) 34 | endif() 35 | 36 | 37 | 38 | 39 | if(${CUTFEM_CREATE_DOCS}) 40 | add_subdirectory(Documentation/) 41 | endif() 42 | 43 | add_subdirectory(cpp/) 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /Documentation/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #======================================================================================================================= 2 | # Set up Doxygen API documentation 3 | #======================================================================================================================= 4 | # check if Doxygen is installed 5 | find_package(Doxygen) 6 | if (DOXYGEN_FOUND) 7 | # set input and output files 8 | set(DOXYGEN_IN ${CMAKE_CURRENT_LIST_DIR}/Doxyfile.in) 9 | set(DOXYGEN_OUT ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile) 10 | # set(DOXYGEN_SOURCE ${CMAKE_CURRENT_LIST_DIR}/../OpenXLSX/headers) 11 | set(DOXYGEN_QUIET YES) 12 | 13 | # request to configure the file 14 | configure_file(${DOXYGEN_IN} ${DOXYGEN_OUT})# @ONLY) 15 | message("Doxygen build started") 16 | 17 | # note the option ALL which allows to build the docs together with the application 18 | add_custom_target(Documentation 19 | COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT} 20 | WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} 21 | COMMENT "Generating API documentation with Doxygen" 22 | VERBATIM) 23 | else (DOXYGEN_FOUND) 24 | message("Doxygen need to be installed to generate the doxygen documentation") 25 | endif (DOXYGEN_FOUND) 26 | 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # About 2 | This library contains implementations of CutFEM algorithms on simple numerical examples. It is maintained and developed by Thomas Frachon, Sebastian Myrbäck and Erik Nilsson at the Department of Mathematics, KTH Royal Institute of Technology, Stockholm, Sweden. 3 | 4 | 5 | # Installing the CutFEM Library 6 | 7 | 1. **Install dependencies** 8 | * For default configuration, you need to install Cmake and UMFPACK. You need to be able to run C++20, so make sure you have a compatible compiler. 9 | * To use e.g. MUMPS, you need to install mumps and mpi. 10 | 11 | 2. **Clone** 12 | ``` 13 | git clone https://github.com/CutFEM/CutFEM-Library.git 14 | ``` 15 | 3. **Configure** 16 | ``` 17 | cd CutFEM-Library 18 | mkdir build 19 | cd build 20 | cmake .. 21 | ``` 22 | 4. **Compile** \ 23 | If you want to compile all files in the [cpp/example](cpp/example) folder, write ```make```. 24 | 25 | 5. **Run** 26 | Compiling creates an executable file in the ```build/bin``` folder. To run a file with executable name `````` run the code by writing ```./bin/```. 27 | 28 | 7. **Other settings** \ 29 | If you want to configure the library with other settings, such as being able to use mumps for solving linear systems, you can change the settings in the [CMakeLists.txt](CMakeLists.txt) file. 30 | 31 | 32 | # Reproducing data 33 | 34 | ### *A High-Order Conservative Cut Finite Element Method for Problems in Time-Dependent Domains*, 2024, S. Myrbäck, S. Zahedi. [Link here](https://www.sciencedirect.com/science/article/pii/S0045782524005012) 35 | 36 | This paper presents a conservative space-time CutFEM for solving convection-diffusion equations in bulk, or bulk-surface domains. 37 | 38 | The files are located in [cpp/example/convection_diffusion](cpp/example/convection_diffusion/) and consist of two files: [bulk.cpp](cpp/example/convection_diffusion/bulk.cpp), and [coupled.cpp](cpp/example/convection_diffusion/coupled.cpp). 39 | 40 | To run them you first need to build them, by writing e.g. ```make -j4 bulk```, unless you've already built them when installing the library above. 41 | 42 | To execute and run the files, there are several options/parameters to choose from: 43 | 44 | #### Bulk 45 | 46 | 1. **Example**: ```circle/kite``` 47 | 2. **Method**: ```conservative/non_conservative``` 48 | 3. **Polynomial order in space**: ```1/2/3``` 49 | 4. **Polynomial order in time**: ```0/1/2/3``` 50 | 5. **Ghost-penalty stabilization technique**: ```fullstab/macro``` 51 | 52 | These options are set by defining preprocessor variables before the main function, e.g. ```#define circle```. Other user variables, such as stabilization constant, macroelement parameter, and number of quadrature nodes in time and space, are changed inside the main function. The code is then executed as: 53 | 54 | ``` 55 | ./bin/bulk 56 | ``` 57 | 58 | 59 | #### Coupled 60 | 61 | 1. **Method**: ```conservative/non_conservative``` 62 | 2. **Polynomial order in space**: ```1/2``` 63 | 3. **Polynomial order in time**: ```0/1/2/3``` 64 | 4. **Ghost-penalty stabilization technique**: ```fullstab/macro``` 65 | 66 | Stabilization constants, macroelement parameters, number of quadrature nodes in time and space, etc, are changed inside the main function. The code is then executed as: 67 | 68 | ``` 69 | ./bin/coupled 70 | ``` 71 | Convergence history is printed both in the terminal and in the files "output_bulk.dat" and "output_coupled.dat". 72 | 73 | 74 | ### *A divergence preserving cut finite element method for Darcy flow*, 2024, Thomas Frachon, Erik Nilsson, Sara Zahedi 75 | To create the Darcy problem to reproduce results using Python: 76 | 1 - All options can be OFF apart from CUTFEM_BUILD_PYTHON_WRAPPER 77 | 2. "cmake ..; make -j4;" 78 | 2 - Go to the python folder 79 | "cd ../../python/darcy;" 80 | 3 - In the darcy_wrapper.py file one must link to the library. Verify that the good extension is used. 81 | 4 - run darcy.py 82 | 83 | 84 | Note: It is important to turn off the options for finding libraries if they are not installed, otherwise the compilation will not succeed. 85 | 86 | Note: When compiling the python library, the MPI option should be turned off. 87 | 88 | On another hand, to update all modules (test, solver etc) one can do 89 | "git submodule update --init --recursive" 90 | 91 | 92 | # TO INSTALL A SUBMODULE 93 | git submodule update --init --recusive submodule_name 94 | 95 | # TO INSTALL UMFPACK 96 | 1. add the module SuiteSparse 97 | "git submodule update --init --SuiteSparse" 98 | 2. Go to UMFPACK folder 99 | "make local; make install; 100 | 3. Fixe the cmake/FindUMFPACK.cmake 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /build_lib.sh: -------------------------------------------------------------------------------- 1 | cd build 2 | CC=/usr/bin/gcc-10 CXX=/usr/bin/g++-10 cmake -G "Unix Makefiles" .. 3 | -------------------------------------------------------------------------------- /cmake/CorrectWindowsPaths.cmake: -------------------------------------------------------------------------------- 1 | # CorrectWindowsPaths - this module defines one macro 2 | # 3 | # CONVERT_CYGWIN_PATH( PATH ) 4 | # This uses the command cygpath (provided by cygwin) to convert 5 | # unix-style paths into paths useable by cmake on windows 6 | 7 | macro (CONVERT_CYGWIN_PATH _path) 8 | if (WIN32) 9 | EXECUTE_PROCESS(COMMAND cygpath.exe -m ${${_path}} 10 | OUTPUT_VARIABLE ${_path}) 11 | string (STRIP ${${_path}} ${_path}) 12 | endif (WIN32) 13 | endmacro (CONVERT_CYGWIN_PATH) 14 | 15 | -------------------------------------------------------------------------------- /cmake/FindBLACS.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Module to find the library BLACS 3 | # 4 | 5 | # 6 | # If BLACS is found, it will set the following variables. Otherwise, 7 | # BLACS_FOUND will be set to false 8 | # 9 | # BLACS_FOUND True if MUMPS is found 10 | # BLACS_LIBRARIES METIS_librarie 11 | 12 | set (BLACS_DIR "/afs/kth.se/home/f/r/frachon/lib/gcc/lib") 13 | 14 | set(BLACS_FOUND "NO") 15 | 16 | #if BLACS_DIR is specified 17 | if(BLACS_DIR) 18 | find_path(BLACS_LIBRARY_DIR 19 | NAMES blacs_MPI-LINUX-0.a 20 | PATHS ${BLACS_DIR} 21 | NO_DEFAULT_PATH) 22 | endif() 23 | 24 | # otherwise look for standard places 25 | find_path(BLACS_LIBRARY_DIR 26 | NAMES blacs_MPI-LINUX-0.a 27 | PATHS 28 | /opt/BLACS/lib 29 | /usr/local/BLACS/lib 30 | /usr/local/lib 31 | /usr/lib 32 | ~/lib/lib) 33 | 34 | if(BLACS_LIBRARY_DIR) 35 | set(BLACS_FOUND YES) 36 | 37 | find_library(BLACS_LIBRARY 38 | NAMES blacs_MPI-LINUX-0.a 39 | PATHS ${BLACS_LIBRARY_DIR} 40 | NO_DEFAULT_PATH) 41 | 42 | find_library(BLACS_Cinit_LIBRARY 43 | NAMES blacsCinit_MPI-LINUX-0.a 44 | PATHS ${BLACS_LIBRARY_DIR} 45 | NO_DEFAULT_PATH) 46 | 47 | find_library(BLACS_F77init_LIBRARY 48 | NAMES blacsF77init_MPI-LINUX-0.a 49 | PATHS ${BLACS_LIBRARY_DIR} 50 | NO_DEFAULT_PATH) 51 | 52 | set(BLACS_LIBRARIES ${BLACS_LIBRARY} ${BLACS_Cinit_LIBRARY} ${BLACS_F77init_LIBRARY}) 53 | 54 | mark_as_advanced(BLACS_LIBRARY_DIR BLACS_LIBRARY BLACS_Cinit_LIBRARY BLACS_F77init_LIBRARY) 55 | else() 56 | if(BLACS_FIND_REQUIRED) 57 | message( "BLACS_library = ${BLACS_LIBRARY}") 58 | message(FATAL_ERROR "BLACS not found, please set BLACS_DIR to your BLACS install directory") 59 | endif() 60 | endif() 61 | -------------------------------------------------------------------------------- /cmake/FindLAPACK.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Module to find the library LAPACK 3 | # 4 | 5 | # LAPACK_FOUND - set to true if a library implementing the LAPACK interface 6 | # is found 7 | # LAPACK_LINKER_FLAGS - uncached list of required linker flags (excluding -l 8 | # and -L). 9 | # LAPACK_LIBRARIES - uncached list of libraries (using full path name) to 10 | # link against to use LAPACK 11 | 12 | # set(LAPACK_LIBRARIES_DIR "/home/f/r/frachon/lib/lapack-3.7.0/") 13 | set(LAPACK_FOUND "NO") 14 | 15 | find_path(LAPACK_INCLUDES 16 | NAMES 17 | lapacke.h 18 | PATHS 19 | /opt/homebrew/Cellar/lapack/3.10.1_1 20 | /opt/homebrew/Cellar/lapack/3.10.1_1/include/ 21 | /usr/local/opt/lapack/include/ 22 | /usr/include/ 23 | /usr/lib/lapack 24 | 25 | ) 26 | 27 | ##message(" LAPACK INCLUDE : ${LAPACK_INCLUDES}") 28 | 29 | # otherwise look for standard places 30 | find_path(LAPACK_LIBRARY_DIR 31 | NAMES liblapacke.dylib 32 | PATHS 33 | /opt/homebrew/Cellar/lapack/3.10.1_1 34 | /usr/local/opt/lapack/lib/ 35 | /usr/lib/lapack 36 | /opt/homebrew/Cellar/lapack/3.10.1_1/lib/ 37 | /opt 38 | /usr/local/lib 39 | /usr/lib 40 | ~/lib/lib) 41 | 42 | ##message(" LAPACK LIB DIR : ${LAPACK_LIBRARY_DIR}") 43 | 44 | if(LAPACK_LIBRARY_DIR) 45 | set(LAPACK_FOUND YES) 46 | 47 | find_library(LAPACK_LIBRARY 48 | NAMES lapacke 49 | PATHS ${LAPACK_LIBRARY_DIR} 50 | NO_DEFAULT_PATH) 51 | 52 | set(LAPACK_LIBRARIES ${LAPACK_LIBRARY}) 53 | set(LAPACK_MODULES_DIR ${LAPACK_LIBRARY_DIR}) 54 | ##message( "LAPACK_library = ${LAPACK_LIBRARIES}") 55 | 56 | mark_as_advanced(LAPACK_LIBRARY_DIR LAPACK_LIBRARY LAPACK_MODULES_DIR) 57 | else() 58 | if(LAPACK_FIND_REQUIRED) 59 | ##message( "LAPACK_library = ${LAPACK_LIBRARY}") 60 | message(FATAL_ERROR "LAPACK not found, please set LAPACK_DIR to your LAPACK install directory") 61 | endif() 62 | endif() 63 | -------------------------------------------------------------------------------- /cmake/FindMETIS.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Module to find the library METIS 3 | # 4 | 5 | # 6 | # If METIS is found, it will set the following variables. Otherwise, 7 | # METIS_FOUND will be set to false 8 | # 9 | # METIS_FOUND True if MUMPS is found 10 | # METIS_LIBRARIES METIS_librarie 11 | 12 | set(METIS_INCLUDES "/home/f/r/frachon/lib/metis/5.1.0/include") 13 | set(METIS_LIBRARIES "/home/f/r/frachon/lib/metis/5.1.0/build/libmetis/libmetis.a") 14 | set(METIS_FOUND YES) 15 | 16 | message( "METIS_include = ${METIS_INCLUDES}") 17 | message( "METIS_libraries = ${METIS_LIBRARIES}") 18 | -------------------------------------------------------------------------------- /cmake/FindMUMPS.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Module to find the library MUMPS 3 | # 4 | 5 | # 6 | # If MUMPS is found, it will set the following variables. Otherwise, 7 | # MUMPS_FOUND will be set to false 8 | # 9 | # MUMPS_FOUND True if MUMPS is found 10 | # MUMPS_LIBRARIES MUMPS_librarie 11 | # MUMPS_INCLUDE_DIR where to find mumps_compat.h 12 | 13 | set(MUMPS_FOUND "NO") 14 | 15 | #if MUMPS_DIR is specified 16 | if(MUMPS_DIR) 17 | set(MUMPS_INCLUDE_DIR ${MUMPS_DIR}/include) 18 | set(MUMPS_LIBRARY_DIR ${MUMPS_DIR}/lib) 19 | else() 20 | find_path (MUMPS_INCLUDE_DIR 21 | NAMES dmumps_struc.h 22 | PATHS 23 | /usr/local/Cellar/brewsci-mumps/5.2.1/include 24 | /opt/homebrew/Cellar/brewsci-mumps/5.3.5/include 25 | # /Users/thomasfrachon/lib/MUMPS_5.6.2/include 26 | /opt/homebrew/Cellar/brewsci-mumps/5.6.2/include 27 | /usr/local/MUMPS/include 28 | /usr/local/include 29 | /opt/MUMPS/include 30 | /usr/include/MUMPS 31 | /usr/include 32 | ~/lib/include) 33 | 34 | if(USE_MPI) 35 | message(" Search for MPI MUMPS") 36 | find_path(MUMPS_LIBRARY_DIR 37 | NAMES libmumps_common.dylib libdmumps.dylib libpord.dylib 38 | libmumps_common.a libdmumps.a libpord.a 39 | # NAMES libmumps_common.a libdmumps.a libpord.a 40 | 41 | PATHS 42 | /usr/local/Cellar/brewsci-mumps/5.2.1/lib 43 | /opt/homebrew/Cellar/brewsci-mumps/5.3.5/lib 44 | # /Users/thomasfrachon/lib/MUMPS_5.6.2/lib 45 | /opt/homebrew/Cellar/brewsci-mumps/5.6.2/lib 46 | /opt/MUMPS/lib 47 | /usr/local/MUMPS/lib 48 | /usr/local/lib 49 | /usr/lib/x86_64-linux-gnu 50 | /usr/lib 51 | ~/lib/lib) 52 | else() 53 | message(" Search for SEQ MUMPS") 54 | find_path(MUMPS_LIBRARY_DIR 55 | NAMES 56 | libmumps_common_seq.a libdmumps_seq.a libpord_seq.a 57 | # libmumps_common.a libdmumps.a libpord.a 58 | PATHS 59 | /usr/local/Cellar/brewsci-mumps/5.2.1/lib 60 | /opt/homebrew/Cellar/brewsci-mumps/5.3.5/lib 61 | # /Users/thomasfrachon/lib/MUMPS_5.6.2/libs 62 | /opt/homebrew/Cellar/brewsci-mumps/5.6.2/lib 63 | /opt/MUMPS/lib 64 | /usr/local/MUMPS/lib 65 | /usr/local/lib 66 | /usr/lib/x86_64-linux-gnu/ 67 | /usr/lib 68 | ~/lib/lib) 69 | 70 | message(" library directory = ${MUMPS_LIBRARY_DIR}") 71 | 72 | endif() 73 | 74 | endif() 75 | 76 | if(MUMPS_INCLUDE_DIR AND MUMPS_LIBRARY_DIR) 77 | set(MUMPS_FOUND YES) 78 | 79 | if(USE_MPI) 80 | find_library(MUMPS_COMMON_LIBRARY 81 | NAMES mumps_common 82 | PATHS ${MUMPS_LIBRARY_DIR} 83 | NO_DEFAULT_PATH) 84 | 85 | find_library(MUMPS_D_LIBRARY 86 | NAMES dmumps 87 | PATHS ${MUMPS_LIBRARY_DIR} 88 | NO_DEFAULT_PATH) 89 | find_library(MUMPS_PORD_LIBRARY 90 | NAMES pord 91 | PATHS ${MUMPS_LIBRARY_DIR} 92 | /usr/lib/x86_64-linux-gnu 93 | NO_DEFAULT_PATH) 94 | else() 95 | find_library(MUMPS_COMMON_LIBRARY 96 | NAMES mumps_common_seq 97 | PATHS ${MUMPS_LIBRARY_DIR} 98 | /usr/lib/x86_64-linux-gnu 99 | NO_DEFAULT_PATH) 100 | 101 | find_library(MUMPS_D_LIBRARY 102 | NAMES dmumps_seq 103 | PATHS ${MUMPS_LIBRARY_DIR} 104 | /usr/lib/x86_64-linux-gnu 105 | NO_DEFAULT_PATH) 106 | find_library(MUMPS_PORD_LIBRARY 107 | NAMES pord_seq 108 | PATHS ${MUMPS_LIBRARY_DIR} 109 | /usr/lib/x86_64-linux-gnu 110 | NO_DEFAULT_PATH) 111 | endif() 112 | 113 | 114 | find_library(MUMPS_PARMETIS_LIBRARY 115 | NAMES parmetis 116 | PATHS 117 | /usr/lib 118 | /usr/lib/x86_64-linux-gnu 119 | /usr/local/Cellar/brewsci-parmetis/4.0.3_1/lib 120 | /opt/homebrew/Cellar/brewsci-parmetis/4.0.3_1/lib 121 | NO_DEFAULT_PATH) 122 | 123 | # set(SCOTCH_LIBRARY_DIR /usr/lib ) 124 | # find_library(SCOTCH_esmumps_LIBRARY 125 | # NAMES esmumps 126 | # PATHS ${SCOTCH_LIBRARY_DIR} 127 | # NO_DEFAULT_PATH) 128 | 129 | find_library(SCOTCH_scotch_LIBRARY 130 | NAMES scotch scotch-6 131 | PATHS /usr/lib 132 | /opt/homebrew/Cellar/scotch/7.0.2/lib 133 | /opt/homebrew/Cellar/scotch/7.0.4/lib 134 | /opt/homebrew/Cellar/scotch/7.0.5/lib 135 | /usr/lib/x86_64-linux-gnu 136 | /usr/local/Cellar/brewsci-scotch/6.0.4/lib 137 | NO_DEFAULT_PATH) 138 | 139 | find_library(SCOTCH_scotcherr_LIBRARY 140 | NAMES scotcherr scotcherr-6 141 | PATHS /usr/lib 142 | /usr/lib/x86_64-linux-gnu 143 | /opt/homebrew/Cellar/scotch/7.0.2/lib 144 | /opt/homebrew/Cellar/scotch/7.0.4/lib 145 | /opt/homebrew/Cellar/scotch/7.0.5/lib 146 | /usr/local/Cellar/brewsci-scotch/6.0.4/lib 147 | NO_DEFAULT_PATH) 148 | 149 | set(SCOTCH_LIBRARIES ${SCOTCH_scotcherr_LIBRARY} ${SCOTCH_scotch_LIBRARY}) 150 | # ${SCOTCH_esmumps_LIBRARY}) 151 | 152 | set(MUMPS_LIBRARIES ${MUMPS_COMMON_LIBRARY} ${MUMPS_D_LIBRARY} ${SCOTCH_LIBRARIES} ${MUMPS_PARMETIS_LIBRARY} ${MUMPS_PORD_LIBRARY}) 153 | 154 | set(MUMPS_INCLUDES ${MUMPS_INCLUDE_DIR}) 155 | 156 | message( "-- MUMPS_library FOUND") 157 | message( " MUMPS_includes = ${MUMPS_INCLUDES}") 158 | message( " MUMPS_library = ${MUMPS_LIBRARIES}") 159 | 160 | else() 161 | if(MUMPS_FIND_REQUIRED) 162 | message( "MUMPS_include_dirs = ${MUMPS_INCLUDE_DIR}") 163 | message( "MUMPS_library = ${MUMPS_LIBRARIES}") 164 | message(FATAL_ERROR "MUMPS not found, please set MUMPS_DIR to your MUMPS install directory") 165 | endif() 166 | endif() -------------------------------------------------------------------------------- /cmake/FindPARMETIS.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Module to find the library METIS 3 | # 4 | 5 | # 6 | # If METIS is found, it will set the following variables. Otherwise, 7 | # METIS_FOUND will be set to false 8 | # 9 | # METIS_FOUND True if MUMPS is found 10 | # METIS_LIBRARIES METIS_librarie 11 | 12 | set(PARMETIS_INCLUDES "/home/f/r/frachon/lib/parmetis/4.0.3/include") 13 | set(PARMETIS_LIBRARIES "/home/f/r/frachon/lib/parmetis/4.0.3/build/Linux-x86_64/libparmetis/libparmetis.a") 14 | set(PARMETIS_FOUND YES) 15 | 16 | message( "PARMETIS_include = ${PARMETIS_INCLUDES}") 17 | message( "PARMETIS_libraries = ${PARMETIS_LIBRARIES}") 18 | -------------------------------------------------------------------------------- /cmake/FindPETSC.cmake: -------------------------------------------------------------------------------- 1 | # - Try to find PETSc 2 | # Once done this will define 3 | # 4 | # PETSC_FOUND - system has PETSc 5 | # PETSC_INCLUDES - the PETSc include directories 6 | # PETSC_LIBRARIES - Link these to use PETSc 7 | # PETSC_COMPILER - Compiler used by PETSc, helpful to find a compatible MPI 8 | # PETSC_DEFINITIONS - Compiler switches for using PETSc 9 | # PETSC_MPIEXEC - Executable for running MPI programs 10 | # PETSC_VERSION - Version string (MAJOR.MINOR.SUBMINOR) 11 | # 12 | # Usage: 13 | # find_package(PETSc COMPONENTS CXX) - required if build --with-clanguage=C++ --with-c-support=0 14 | # find_package(PETSc COMPONENTS C) - standard behavior of checking build using a C compiler 15 | # find_package(PETSc) - same as above 16 | # 17 | # Setting these changes the behavior of the search 18 | # PETSC_DIR - directory in which PETSc resides 19 | # PETSC_ARCH - build architecture 20 | # 21 | # Redistribution and use is allowed according to the terms of the BSD license. 22 | # For details see the accompanying COPYING-CMAKE-SCRIPTS file. 23 | # 24 | 25 | 26 | 27 | set(PETSC_DIR /usr/lib/petscdir/3.7.3/x86_64-linux-gnu-real ) 28 | set(PETSC_ARCH ) 29 | #set(PETSC_INCLUDES ${PETSC_DIR}/include) 30 | #set(PETSC_LIBRARIES ${PETSC_DIR}/lib/libpetsc_real.so.3.7.3) 31 | #set(PETSC_MPIEXE ${PETSC_DIR}/bin/petscmpiexec) 32 | #set (PETSC_DEFINITIONS "-D__INSDIR__=" CACHE STRING "PETSc definitions" FORCE) 33 | 34 | 35 | 36 | set (PETSC_EXECUTABLE_RUNS YES CACHE BOOL "Disable checking if this setup works" FORCE) 37 | 38 | set (PETSC_FOUND YES CACHE BOOL "PETSc was found (manually)" FORCE) 39 | 40 | set (PETSC_INCLUDES ${PETSC_DIR}/include CACHE STRING 41 | "Semicolon-delimited list of PETSc include directories" FORCE) 42 | 43 | set (PETSC_LIBRARIES ${PETSC_DIR}/lib/libpetsc_real.so.3.7.3 CACHE STRING 44 | "Semicolon-delimited list of PETSc libraries" FORCE) 45 | 46 | set (PETSC_COMPILER "/usr/lib/openmpi/lib/" CACHE FILEPATH 47 | "PETSc compiler; helpful to find a compatible MPI" FORCE) 48 | 49 | set (PETSC_DEFINITIONS "-D__INSDIR__=" CACHE STRING 50 | "PETSc definitions" FORCE) 51 | 52 | set (PETSC_MPIEXEC ${PETSC_DIR}"/bin/petscmpiexec" CACHE FILEPATH 53 | "Executable for running PETSc MPI programs" FORCE) 54 | 55 | set (PETSC_VERSION "" CACHE STRING 56 | "PETSc version: MAJOR.MINOR.SUBMINOR" FORCE) 57 | 58 | mark_as_advanced (PETSC_INCLUDES PETSC_LIBRARIES 59 | PETSC_COMPILER PETSC_DEFINITIONS 60 | PETSC_MPIEXEC PETSC_EXECUTABLE_RUNS PETSC_VERSION) 61 | 62 | 63 | message("dir = " ${PETSC_DIR}) 64 | message("arch = " ${PETSC_ARCH}) 65 | message("includes = " ${PETSC_INCLUDES}) 66 | message("librarie = " ${PETSC_LIBRARIES}) 67 | message("compiler = " ${PETSC_COMPILER}) 68 | message("definition = " ${PETSC_DEFINITIONS}) 69 | message("mpiexe = " ${PETSC_MPIEXE}) 70 | message("version = " ${PETSC_VERSION}) 71 | -------------------------------------------------------------------------------- /cmake/FindPORD.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Module to find the library PORD 3 | # 4 | 5 | # 6 | # If PORD is found, it will set the following variables. Otherwise, 7 | # PORD_FOUND will be set to false 8 | # 9 | # PORD_FOUND True if PORD is found 10 | # PORD_LIBRARIES PORD_librarie 11 | 12 | 13 | set(PORD_FOUND "NO") 14 | 15 | #if PORD_DIR is specified 16 | if(PORD_DIR) 17 | find_path(PORD_LIBRARY_DIR 18 | NAMES libpord.so 19 | PATHS ${PORD_DIR}/lib 20 | NO_DEFAULT_PATH) 21 | endif() 22 | 23 | # otherwise look for standard places 24 | find_path(PORD_LIBRARY_DIR 25 | NAMES libpord.so 26 | PATHS 27 | /opt/PORD/lib 28 | /usr/local/PORD/lib 29 | /usr/local/lib 30 | /usr/lib 31 | ~/lib/lib) 32 | 33 | if(PORD_LIBRARY_DIR) 34 | set(PORD_FOUND YES) 35 | 36 | find_library(PORD_LIBRARY 37 | NAMES pord 38 | PATHS ${PORD_LIBRARY_DIR} 39 | NO_DEFAULT_PATH) 40 | 41 | set(PORD_LIBRARIES ${PORD_LIBRARY}) 42 | 43 | mark_as_advanced(PORD_LIBRARY_DIR PORD_LIBRARY) 44 | else() 45 | if(PORD_FIND_REQUIRED) 46 | message( "PORD_library = ${PORD_LIBRARY}") 47 | message(FATAL_ERROR "PORD not found, please set PORD_DIR to your PORD install directory") 48 | endif() 49 | endif() 50 | -------------------------------------------------------------------------------- /cmake/FindPYTHON.cmake: -------------------------------------------------------------------------------- 1 | 2 | 3 | # set(PYTHON_INCLUDES /usr/local/Cellar/python@3.10/3.10.9/Frameworks/Python.framework/Versions/3.10/include/python3.10/ 4 | # /usr/local/lib/python3.10/site-packages/numpy/core/include) 5 | # set(PYTHON_LIBRARIES /usr/local/Cellar/python@3.10/3.10.9/Frameworks/Python.framework/Versions/3.10/lib/libpython3.10.dylib) 6 | # set(PYTHON_DIR /usr/local/Cellar/python@3.10/3.10.9/Frameworks/Python.framework/Versions/3.10) 7 | 8 | 9 | set(PYTHON_FOUND "NO") 10 | 11 | 12 | find_path (PYTHON_INCLUDE_DIR 13 | NAMES Python.h 14 | PATHS 15 | /usr/local/Cellar/python@3.10/3.10.9/Frameworks/Python.framework/Versions/3.10/include/python3.10/ 16 | /opt/homebrew/opt/python@3.10/Frameworks/Python.framework/Versions/3.10/include/python3.10 17 | /usr/include/python3.8/ 18 | ) 19 | 20 | find_path(MATPLOTLIBCPP_DIR 21 | NAMES 22 | matplotlibcpp.h 23 | PATHS 24 | /Users/thomasfrachon/lib/matplotlib-cpp 25 | ) 26 | 27 | find_path (NUMPY_INCLUDE_DIR 28 | NAMES numpy/arrayobject.h 29 | PATHS 30 | /usr/local/lib/python3.10/site-packages/numpy/core/include 31 | /usr/lib/python3/dist-packages/numpy/core/include/ 32 | /opt/homebrew/lib/python3.10/site-packages/numpy/core/include 33 | ) 34 | 35 | find_path(PYTHON_LIBRARY_DIR 36 | NAMES 37 | libpython3.10.dylib 38 | libpython3.8.so 39 | PATHS 40 | /usr/lib/x86_64-linux-gnu/ 41 | /usr/local/Cellar/python@3.10/3.10.9/Frameworks/Python.framework/Versions/3.10/lib/ 42 | /opt/homebrew/opt/python@3.10/Frameworks/Python.framework/Versions/3.10/lib 43 | ) 44 | 45 | 46 | if(PYTHON_INCLUDE_DIR AND NUMPY_INCLUDE_DIR AND PYTHON_LIBRARY_DIR AND MATPLOTLIBCPP_DIR) 47 | set(PYTHON_FOUND YES) 48 | 49 | find_library(PYTHON_LIBRARY 50 | NAMES 51 | libpython3.10.dylib 52 | libpython3.8.so 53 | PATHS ${PYTHON_LIBRARY_DIR} 54 | NO_DEFAULT_PATH 55 | ) 56 | 57 | 58 | set(PYTHON_LIBRARIES ${PYTHON_LIBRARY} ) 59 | 60 | set(PYTHON_INCLUDES ${PYTHON_INCLUDE_DIR} ${NUMPY_INCLUDE_DIR} ${MATPLOTLIBCPP_DIR}) 61 | 62 | message( "-- PYTHON_library FOUND") 63 | message( STATUS "PYTHON & NUMPY includes = ${PYTHON_INCLUDES}") 64 | message( STATUS "PYTHON library = ${PYTHON_LIBRARIES}") 65 | 66 | else() 67 | message( STATUS "PYTHON include dirs = ${PYHTON_INCLUDE_DIR}") 68 | message( STATUS "PYTHON library = ${PYTHON_LIBRARIES}") 69 | endif() 70 | 71 | -------------------------------------------------------------------------------- /cmake/FindPackageMultipass.cmake: -------------------------------------------------------------------------------- 1 | # PackageMultipass - this module defines two macros 2 | # 3 | # FIND_PACKAGE_MULTIPASS (Name CURRENT 4 | # STATES VAR0 VAR1 ... 5 | # DEPENDENTS DEP0 DEP1 ...) 6 | # 7 | # This function creates a cache entry _CURRENT which 8 | # the user can set to "NO" to trigger a reconfiguration of the package. 9 | # The first time this function is called, the values of 10 | # _VAR0, ... are saved. If _CURRENT 11 | # is false or if any STATE has changed since the last time 12 | # FIND_PACKAGE_MULTIPASS() was called, then CURRENT will be set to "NO", 13 | # otherwise CURRENT will be "YES". IF not CURRENT, then 14 | # _DEP0, ... will be FORCED to NOTFOUND. 15 | # Example: 16 | # find_path (FOO_DIR include/foo.h) 17 | # FIND_PACKAGE_MULTIPASS (Foo foo_current 18 | # STATES DIR 19 | # DEPENDENTS INCLUDES LIBRARIES) 20 | # if (NOT foo_current) 21 | # # Make temporary files, run programs, etc, to determine FOO_INCLUDES and FOO_LIBRARIES 22 | # endif (NOT foo_current) 23 | # 24 | # MULTIPASS_SOURCE_RUNS (Name INCLUDES LIBRARIES SOURCE RUNS LANGUAGE) 25 | # Always runs the given test, use this when you need to re-run tests 26 | # because parent variables have made old cache entries stale. The LANGUAGE 27 | # variable is either C or CXX indicating which compiler the test should 28 | # use. 29 | # MULTIPASS_C_SOURCE_RUNS (Name INCLUDES LIBRARIES SOURCE RUNS) 30 | # DEPRECATED! This is only included for backwards compatability. Use 31 | # the more general MULTIPASS_SOURCE_RUNS instead. 32 | # Always runs the given test, use this when you need to re-run tests 33 | # because parent variables have made old cache entries stale. 34 | 35 | macro (FIND_PACKAGE_MULTIPASS _name _current) 36 | string (TOUPPER ${_name} _NAME) 37 | set (_args ${ARGV}) 38 | list (REMOVE_AT _args 0 1) 39 | 40 | set (_states_current "YES") 41 | list (GET _args 0 _cmd) 42 | if (_cmd STREQUAL "STATES") 43 | list (REMOVE_AT _args 0) 44 | list (GET _args 0 _state) 45 | while (_state AND NOT _state STREQUAL "DEPENDENTS") 46 | # The name of the stored value for the given state 47 | set (_stored_var PACKAGE_MULTIPASS_${_NAME}_${_state}) 48 | if (NOT "${${_stored_var}}" STREQUAL "${${_NAME}_${_state}}") 49 | set (_states_current "NO") 50 | endif (NOT "${${_stored_var}}" STREQUAL "${${_NAME}_${_state}}") 51 | set (${_stored_var} "${${_NAME}_${_state}}" CACHE INTERNAL "Stored state for ${_name}." FORCE) 52 | list (REMOVE_AT _args 0) 53 | list (GET _args 0 _state) 54 | endwhile (_state AND NOT _state STREQUAL "DEPENDENTS") 55 | endif (_cmd STREQUAL "STATES") 56 | 57 | set (_stored ${_NAME}_CURRENT) 58 | if (NOT ${_stored}) 59 | set (${_stored} "YES" CACHE BOOL "Is the configuration for ${_name} current? Set to \"NO\" to reconfigure." FORCE) 60 | set (_states_current "NO") 61 | endif (NOT ${_stored}) 62 | 63 | set (${_current} ${_states_current}) 64 | if (NOT ${_current} AND PACKAGE_MULTIPASS_${_name}_CALLED) 65 | message (STATUS "Clearing ${_name} dependent variables") 66 | # Clear all the dependent variables so that the module can reset them 67 | list (GET _args 0 _cmd) 68 | if (_cmd STREQUAL "DEPENDENTS") 69 | list (REMOVE_AT _args 0) 70 | foreach (dep ${_args}) 71 | set (${_NAME}_${dep} "NOTFOUND" CACHE INTERNAL "Cleared" FORCE) 72 | endforeach (dep) 73 | endif (_cmd STREQUAL "DEPENDENTS") 74 | set (${_NAME}_FOUND "NOTFOUND" CACHE INTERNAL "Cleared" FORCE) 75 | endif () 76 | set (PACKAGE_MULTIPASS_${name}_CALLED YES CACHE INTERNAL "Private" FORCE) 77 | endmacro (FIND_PACKAGE_MULTIPASS) 78 | 79 | 80 | macro (MULTIPASS_SOURCE_RUNS includes libraries source runs language) 81 | include (Check${language}SourceRuns) 82 | # This is a ridiculous hack. CHECK_${language}_SOURCE_* thinks that if the 83 | # *name* of the return variable doesn't change, then the test does 84 | # not need to be re-run. We keep an internal count which we 85 | # increment to guarantee that every test name is unique. If we've 86 | # gotten here, then the configuration has changed enough that the 87 | # test *needs* to be rerun. 88 | if (NOT MULTIPASS_TEST_COUNT) 89 | set (MULTIPASS_TEST_COUNT 00) 90 | endif (NOT MULTIPASS_TEST_COUNT) 91 | math (EXPR _tmp "${MULTIPASS_TEST_COUNT} + 1") # Why can't I add to a cache variable? 92 | set (MULTIPASS_TEST_COUNT ${_tmp} CACHE INTERNAL "Unique test ID") 93 | set (testname MULTIPASS_TEST_${MULTIPASS_TEST_COUNT}_${runs}) 94 | set (CMAKE_REQUIRED_INCLUDES ${includes}) 95 | set (CMAKE_REQUIRED_LIBRARIES ${libraries}) 96 | if(${language} STREQUAL "C") 97 | check_c_source_runs ("${source}" ${testname}) 98 | elseif(${language} STREQUAL "CXX") 99 | check_cxx_source_runs ("${source}" ${testname}) 100 | endif() 101 | set (${runs} "${${testname}}") 102 | endmacro (MULTIPASS_SOURCE_RUNS) 103 | 104 | macro (MULTIPASS_C_SOURCE_RUNS includes libraries source runs) 105 | multipass_source_runs("${includes}" "${libraries}" "${source}" ${runs} "C") 106 | endmacro (MULTIPASS_C_SOURCE_RUNS) 107 | -------------------------------------------------------------------------------- /cmake/FindRAPIDYAML.cmake: -------------------------------------------------------------------------------- 1 | # set(RAPID_YAML_LIB "/Users/thomas/Documents/university/cutFEM/libcutfem/rapidyaml/build/libryml.a") 2 | set(RAPID_YAML_INCLUDE "/Users/thomas/Documents/university/cutFEM/libcutfem/rapidyaml/") -------------------------------------------------------------------------------- /cmake/FindSCALAPACK.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Module to find the library SCALAPACK 3 | # 4 | 5 | # 6 | # If SCALAPACK is found, it will set the following variables. Otherwise, 7 | # SCALAPACK_FOUND will be set to false 8 | # 9 | # SCALAPACK_FOUND True if MUMPS is found 10 | # SCALAPACK_LIBRARIES METIS_librarie 11 | 12 | #set (SCALAPACK_DIR "/NOBACKUP/frachon/lib/gcc/scalapack-2.0.2/build/lib/") 13 | #set (SCALAPACK_DIR "/afs/kth.se/home/f/r/frachon/lib/gcc/lib") 14 | 15 | 16 | set(SCALAPACK_FOUND "NO") 17 | 18 | #if SCALAPACK_DIR is specified 19 | if(SCALAPACK_DIR) 20 | find_path(SCALAPACK_LIBRARY_DIR 21 | # NAMES libscalapack.so 22 | NAMES libscalapack-openmpi.so 23 | PATHS ${SCALAPACK_DIR} 24 | NO_DEFAULT_PATH) 25 | endif() 26 | 27 | # otherwise look for standard places 28 | find_path(SCALAPACK_LIBRARY_DIR 29 | # NAMES libscalapack.so 30 | NAMES libscalapack-openmpi.so 31 | PATHS 32 | /opt/SCALAPACK/lib 33 | /usr/local/SCALAPACK/lib 34 | /usr/local/lib 35 | /usr/lib 36 | ~/lib/lib) 37 | 38 | if(SCALAPACK_LIBRARY_DIR) 39 | set(SCALAPACK_FOUND YES) 40 | 41 | find_library(SCALAPACK_LIBRARY 42 | # NAMES scalapack 43 | NAMES scalapack-openmpi 44 | PATHS ${SCALAPACK_LIBRARY_DIR} 45 | NO_DEFAULT_PATH) 46 | 47 | set(SCALAPACK_LIBRARIES ${SCALAPACK_LIBRARY}) 48 | 49 | mark_as_advanced(SCALAPACK_LIBRARY_DIR SCALAPACK_LIBRARY) 50 | message( "-- SCALAPACK_library FOUND") 51 | else() 52 | if(SCALAPACK_FIND_REQUIRED) 53 | message( "SCALAPACK_library = ${SCALAPACK_LIBRARY}") 54 | message(FATAL_ERROR "SCALAPACK not found, please set SCALAPACK_DIR to your SCALAPACK install directory") 55 | endif() 56 | endif() 57 | -------------------------------------------------------------------------------- /cmake/FindSCOTCH.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Module to find the library SCOTCH 3 | # 4 | 5 | # 6 | # If SCOTTH is found, it will set the following variables. Otherwise, 7 | # SCOTCH_FOUND will be set to false 8 | # 9 | # SCOTCH_FOUND True if SCOTCH is found 10 | # SCOTCH_LIBRARIES SCOTCH_librarie 11 | 12 | #set (SCOTCH_DIR "/afs/kth.se/home/f/r/frachon/lib/scotch_6.0.4/lib") 13 | set(SCOTCH_DIR "/opt/homebrew/Cellar/scotch/7.0.2") 14 | set(SCOTCH_FOUND "NO") 15 | 16 | #if SCOTCH_DIR is specified 17 | if(SCOTCH_DIR) 18 | find_path(SCOTCH_LIBRARY_DIR 19 | NAMES libesmumps.a libscotch.a libscotcherr.a 20 | PATHS ${SCOTCH_DIR}/lib 21 | NO_DEFAULT_PATH) 22 | endif() 23 | 24 | # otherwise look for standard places 25 | find_path(SCOTCH_LIBRARY_DIR 26 | NAMES libesmumps.a libscotch.a libscotcherr.a 27 | PATHS 28 | /opt/SCOTCH/lib 29 | /opt/homebrew/Cellar/scotch/7.0.2 30 | /usr/local/lib 31 | /usr/lib 32 | ~/lib/lib) 33 | 34 | if(SCOTCH_LIBRARY_DIR) 35 | set(SCOTCH_FOUND YES) 36 | 37 | find_library(SCOTCH_esmumps_LIBRARY 38 | NAMES esmumps 39 | PATHS ${SCOTCH_LIBRARY_DIR} 40 | NO_DEFAULT_PATH) 41 | 42 | find_library(SCOTCH_scotch_LIBRARY 43 | NAMES scotch 44 | PATHS ${SCOTCH_LIBRARY_DIR} 45 | NO_DEFAULT_PATH) 46 | 47 | find_library(SCOTCH_scotcherr_LIBRARY 48 | NAMES scotcherr 49 | PATHS ${SCOTCH_LIBRARY_DIR} 50 | NO_DEFAULT_PATH) 51 | 52 | set(SCOTCH_LIBRARIES ${SCOTCH_scotcherr_LIBRARY} ${SCOTCH_scotch_LIBRARY} ${SCOTCH_esmumps_LIBRARY}) 53 | 54 | mark_as_advanced(SCOTCH_LIBRARY_DIR SCOTCH_scotcherr_LIBRARY SCOTCH_scotch_LIBRARY SCOTCH_esmumps_LIBRARY) 55 | message( "-- SCOTCH_library FOUND") 56 | else() 57 | if(SCOTCH_FIND_REQUIRED) 58 | message( "SCOTCH_library = ${SCOTCH_LIBRARY}") 59 | message(FATAL_ERROR "SCOTCH not found, please set SCOTCH_DIR to your SCOTCH install directory") 60 | endif() 61 | endif() 62 | -------------------------------------------------------------------------------- /cmake/FindUMFPACK.cmake: -------------------------------------------------------------------------------- 1 | # Umfpack lib usually requires linking to a blas library. 2 | # It is up to the user of this module to find a BLAS and link to it. 3 | 4 | #set(INCLUDE_INSTALL_DIR "/NOBACKUP/frachon/lib/SuiteSparse/include") 5 | #set(INCLUDE_INSTALL_DIR "/usr/local/Cellar/suite-sparse/5.6.0/include") 6 | set(INCLUDE_INSTALL_DIR "/usr/include/suitesparse") 7 | 8 | if (UMFPACK_INCLUDES AND UMFPACK_LIBRARIES) 9 | set(UMFPACK_FIND_QUIETLY TRUE) 10 | endif (UMFPACK_INCLUDES AND UMFPACK_LIBRARIES) 11 | 12 | 13 | find_path(UMFPACK_INCLUDES 14 | NAMES 15 | umfpack.h 16 | PATHS 17 | /usr/local/Cellar/suite-sparse/5.6.0/include 18 | /usr/include/suitesparse/ 19 | /opt/homebrew/include 20 | $ENV{UMFPACKDIR} 21 | ${INCLUDE_INSTALL_DIR} 22 | PATH_SUFFIXES 23 | SuiteSparse 24 | ufsparse 25 | suitesparse 26 | ) 27 | 28 | 29 | find_library(UMFPACK_LIBRARIES umfpack PATHS $ENV{UMFPACKDIR} ${LIB_INSTALL_DIR}) 30 | if(UMFPACK_LIBRARIES) 31 | if (NOT UMFPACK_LIBDIR) 32 | get_filename_component(UMFPACK_LIBDIR ${UMFPACK_LIBRARIES} PATH) 33 | endif(NOT UMFPACK_LIBDIR) 34 | find_library(COLAMD_LIBRARY colamd PATHS ${UMFPACK_LIBDIR} $ENV{UMFPACKDIR} ${LIB_INSTALL_DIR}) 35 | if (COLAMD_LIBRARY) 36 | set(UMFPACK_LIBRARIES ${UMFPACK_LIBRARIES} ${COLAMD_LIBRARY}) 37 | endif (COLAMD_LIBRARY) 38 | 39 | find_library(AMD_LIBRARY amd PATHS ${UMFPACK_LIBDIR} $ENV{UMFPACKDIR} ${LIB_INSTALL_DIR}) 40 | if (AMD_LIBRARY) 41 | set(UMFPACK_LIBRARIES ${UMFPACK_LIBRARIES} ${AMD_LIBRARY}) 42 | endif (AMD_LIBRARY) 43 | find_library(SUITESPARSE_LIBRARY SuiteSparse PATHS ${UMFPACK_LIBDIR} $ENV{UMFPACKDIR} ${LIB_INSTALL_DIR}) 44 | if (SUITESPARSE_LIBRARY) 45 | set(UMFPACK_LIBRARIES ${UMFPACK_LIBRARIES} ${SUITESPARSE_LIBRARY}) 46 | endif (SUITESPARSE_LIBRARY) 47 | endif(UMFPACK_LIBRARIES) 48 | include(FindPackageHandleStandardArgs) 49 | find_package_handle_standard_args(UMFPACK DEFAULT_MSG 50 | UMFPACK_INCLUDES UMFPACK_LIBRARIES) 51 | 52 | message(STATUS "umfpack_include = ${UMFPACK_INCLUDES}") 53 | message(STATUS "umfpack_libraries = ${UMFPACK_LIBRARIES}") 54 | -------------------------------------------------------------------------------- /cmake/ResolveCompilerPaths.cmake: -------------------------------------------------------------------------------- 1 | # ResolveCompilerPaths - this module defines two macros 2 | # 3 | # RESOLVE_LIBRARIES (XXX_LIBRARIES LINK_LINE) 4 | # This macro is intended to be used by FindXXX.cmake modules. 5 | # It parses a compiler link line and resolves all libraries 6 | # (-lfoo) using the library path contexts (-L/path) in scope. 7 | # The result in XXX_LIBRARIES is the list of fully resolved libs. 8 | # Example: 9 | # 10 | # RESOLVE_LIBRARIES (FOO_LIBRARIES "-L/A -la -L/B -lb -lc -ld") 11 | # 12 | # will be resolved to 13 | # 14 | # FOO_LIBRARIES:STRING="/A/liba.so;/B/libb.so;/A/libc.so;/usr/lib/libd.so" 15 | # 16 | # if the filesystem looks like 17 | # 18 | # /A: liba.so libc.so 19 | # /B: liba.so libb.so 20 | # /usr/lib: liba.so libb.so libc.so libd.so 21 | # 22 | # and /usr/lib is a system directory. 23 | # 24 | # Note: If RESOLVE_LIBRARIES() resolves a link line differently from 25 | # the native linker, there is a bug in this macro (please report it). 26 | # 27 | # RESOLVE_INCLUDES (XXX_INCLUDES INCLUDE_LINE) 28 | # This macro is intended to be used by FindXXX.cmake modules. 29 | # It parses a compile line and resolves all includes 30 | # (-I/path/to/include) to a list of directories. Other flags are ignored. 31 | # Example: 32 | # 33 | # RESOLVE_INCLUDES (FOO_INCLUDES "-I/A -DBAR='\"irrelevant -I/string here\"' -I/B") 34 | # 35 | # will be resolved to 36 | # 37 | # FOO_INCLUDES:STRING="/A;/B" 38 | # 39 | # assuming both directories exist. 40 | # Note: as currently implemented, the -I/string will be picked up mistakenly (cry, cry) 41 | include (CorrectWindowsPaths) 42 | 43 | macro (RESOLVE_LIBRARIES LIBS LINK_LINE) 44 | string (REGEX MATCHALL "((-L|-l|-Wl)([^\" ]+|\"[^\"]+\")|[^\" ]+\\.(a|so|dll|lib))" _all_tokens "${LINK_LINE}") 45 | set (_libs_found "") 46 | set (_directory_list "") 47 | foreach (token ${_all_tokens}) 48 | if (token MATCHES "-L([^\" ]+|\"[^\"]+\")") 49 | # If it's a library path, add it to the list 50 | string (REGEX REPLACE "^-L" "" token ${token}) 51 | string (REGEX REPLACE "//" "/" token ${token}) 52 | convert_cygwin_path(token) 53 | list (APPEND _directory_list ${token}) 54 | elseif (token MATCHES "^(-l([^\" ]+|\"[^\"]+\")|[^\" ]+\\.(a|so|dll|lib))") 55 | # It's a library, resolve the path by looking in the list and then (by default) in system directories 56 | if (WIN32) #windows expects "libfoo", linux expects "foo" 57 | string (REGEX REPLACE "^-l" "lib" token ${token}) 58 | else (WIN32) 59 | string (REGEX REPLACE "^-l" "" token ${token}) 60 | endif (WIN32) 61 | set (_root "") 62 | if (token MATCHES "^/") # We have an absolute path 63 | #separate into a path and a library name: 64 | string (REGEX MATCH "[^/]*\\.(a|so|dll|lib)$" libname ${token}) 65 | string (REGEX MATCH ".*[^${libname}$]" libpath ${token}) 66 | convert_cygwin_path(libpath) 67 | set (_directory_list ${_directory_list} ${libpath}) 68 | set (token ${libname}) 69 | endif (token MATCHES "^/") 70 | set (_lib "NOTFOUND" CACHE FILEPATH "Cleared" FORCE) 71 | find_library (_lib ${token} HINTS ${_directory_list} ${_root}) 72 | if (_lib) 73 | string (REPLACE "//" "/" _lib ${_lib}) 74 | list (APPEND _libs_found ${_lib}) 75 | else (_lib) 76 | message (STATUS "Unable to find library ${token}") 77 | endif (_lib) 78 | endif (token MATCHES "-L([^\" ]+|\"[^\"]+\")") 79 | endforeach (token) 80 | set (_lib "NOTFOUND" CACHE INTERNAL "Scratch variable" FORCE) 81 | # only the LAST occurence of each library is required since there should be no circular dependencies 82 | if (_libs_found) 83 | list (REVERSE _libs_found) 84 | list (REMOVE_DUPLICATES _libs_found) 85 | list (REVERSE _libs_found) 86 | endif (_libs_found) 87 | set (${LIBS} "${_libs_found}") 88 | endmacro (RESOLVE_LIBRARIES) 89 | 90 | macro (RESOLVE_INCLUDES INCS COMPILE_LINE) 91 | string (REGEX MATCHALL "-I([^\" ]+|\"[^\"]+\")" _all_tokens "${COMPILE_LINE}") 92 | set (_incs_found "") 93 | foreach (token ${_all_tokens}) 94 | string (REGEX REPLACE "^-I" "" token ${token}) 95 | string (REGEX REPLACE "//" "/" token ${token}) 96 | convert_cygwin_path(token) 97 | if (EXISTS ${token}) 98 | list (APPEND _incs_found ${token}) 99 | else (EXISTS ${token}) 100 | message (STATUS "Include directory ${token} does not exist") 101 | endif (EXISTS ${token}) 102 | endforeach (token) 103 | list (REMOVE_DUPLICATES _incs_found) 104 | set (${INCS} "${_incs_found}") 105 | endmacro (RESOLVE_INCLUDES) 106 | -------------------------------------------------------------------------------- /cmake/cmake-modules-master/CorrectWindowsPaths.cmake: -------------------------------------------------------------------------------- 1 | # CorrectWindowsPaths - this module defines one macro 2 | # 3 | # CONVERT_CYGWIN_PATH( PATH ) 4 | # This uses the command cygpath (provided by cygwin) to convert 5 | # unix-style paths into paths useable by cmake on windows 6 | 7 | macro (CONVERT_CYGWIN_PATH _path) 8 | if (WIN32) 9 | EXECUTE_PROCESS(COMMAND cygpath.exe -m ${${_path}} 10 | OUTPUT_VARIABLE ${_path}) 11 | string (STRIP ${${_path}} ${_path}) 12 | endif (WIN32) 13 | endmacro (CONVERT_CYGWIN_PATH) 14 | 15 | -------------------------------------------------------------------------------- /cmake/cmake-modules-master/FindFFTW.cmake: -------------------------------------------------------------------------------- 1 | # - Find FFTW 2 | # Find the native FFTW includes and library 3 | # 4 | # FFTW_INCLUDES - where to find fftw3.h 5 | # FFTW_LIBRARIES - List of libraries when using FFTW. 6 | # FFTW_FOUND - True if FFTW found. 7 | 8 | if (FFTW_INCLUDES) 9 | # Already in cache, be silent 10 | set (FFTW_FIND_QUIETLY TRUE) 11 | endif (FFTW_INCLUDES) 12 | 13 | find_path (FFTW_INCLUDES fftw3.h) 14 | 15 | find_library (FFTW_LIBRARIES NAMES fftw3) 16 | 17 | # handle the QUIETLY and REQUIRED arguments and set FFTW_FOUND to TRUE if 18 | # all listed variables are TRUE 19 | include (FindPackageHandleStandardArgs) 20 | find_package_handle_standard_args (FFTW DEFAULT_MSG FFTW_LIBRARIES FFTW_INCLUDES) 21 | 22 | mark_as_advanced (FFTW_LIBRARIES FFTW_INCLUDES) 23 | -------------------------------------------------------------------------------- /cmake/cmake-modules-master/FindGSL.cmake: -------------------------------------------------------------------------------- 1 | # - Find GSL 2 | # Find the native GSL includes and library 3 | # 4 | # GSL_INCLUDES - where to find gsl/gsl_*.h, etc. 5 | # GSL_LIBRARIES - List of libraries when using GSL. 6 | # GSL_FOUND - True if GSL found. 7 | 8 | 9 | if (GSL_INCLUDES) 10 | # Already in cache, be silent 11 | set (GSL_FIND_QUIETLY TRUE) 12 | endif (GSL_INCLUDES) 13 | 14 | find_path (GSL_INCLUDES gsl/gsl_math.h) 15 | 16 | find_library (GSL_LIB NAMES gsl) 17 | 18 | set (GSL_CBLAS_LIB "" CACHE FILEPATH "If your program fails to link 19 | (usually because GSL is not automatically linking a CBLAS and no other 20 | component of your project provides a CBLAS) then you may need to point 21 | this variable to a valid CBLAS. Usually GSL is distributed with 22 | libgslcblas.{a,so} (next to GSL_LIB) which you may use if an optimized 23 | CBLAS is unavailable.") 24 | 25 | set (GSL_LIBRARIES "${GSL_LIB}" "${GSL_CBLAS_LIB}") 26 | 27 | # handle the QUIETLY and REQUIRED arguments and set GSL_FOUND to TRUE if 28 | # all listed variables are TRUE 29 | include (FindPackageHandleStandardArgs) 30 | find_package_handle_standard_args (GSL DEFAULT_MSG GSL_LIBRARIES GSL_INCLUDES) 31 | 32 | mark_as_advanced (GSL_LIB GSL_CBLAS_LIB GSL_INCLUDES) 33 | -------------------------------------------------------------------------------- /cmake/cmake-modules-master/FindGit.cmake: -------------------------------------------------------------------------------- 1 | SET(Git_FOUND FALSE) 2 | 3 | FIND_PROGRAM(Git_EXECUTABLE git 4 | DOC "git command line client") 5 | MARK_AS_ADVANCED(Git_EXECUTABLE) 6 | 7 | IF(Git_EXECUTABLE) 8 | SET(Git_FOUND TRUE) 9 | MACRO(Git_WC_INFO dir prefix) 10 | EXECUTE_PROCESS(COMMAND ${Git_EXECUTABLE} rev-list -n 1 HEAD 11 | WORKING_DIRECTORY ${dir} 12 | ERROR_VARIABLE Git_error 13 | OUTPUT_VARIABLE ${prefix}_WC_REVISION_HASH 14 | OUTPUT_STRIP_TRAILING_WHITESPACE) 15 | if(NOT ${Git_error} EQUAL 0) 16 | MESSAGE(SEND_ERROR "Command \"${Git_EXECUTBALE} rev-list -n 1 HEAD\" in directory ${dir} failed with output:\n${Git_error}") 17 | ELSE(NOT ${Git_error} EQUAL 0) 18 | EXECUTE_PROCESS(COMMAND ${Git_EXECUTABLE} name-rev ${${prefix}_WC_REVISION_HASH} 19 | WORKING_DIRECTORY ${dir} 20 | OUTPUT_VARIABLE ${prefix}_WC_REVISION_NAME 21 | OUTPUT_STRIP_TRAILING_WHITESPACE) 22 | ENDIF(NOT ${Git_error} EQUAL 0) 23 | ENDMACRO(Git_WC_INFO) 24 | ENDIF(Git_EXECUTABLE) 25 | 26 | IF(NOT Git_FOUND) 27 | IF(NOT Git_FIND_QUIETLY) 28 | MESSAGE(STATUS "Git was not found") 29 | ELSE(NOT Git_FIND_QUIETLY) 30 | if(Git_FIND_REQUIRED) 31 | MESSAGE(FATAL_ERROR "Git was not found") 32 | ENDIF(Git_FIND_REQUIRED) 33 | ENDIF(NOT Git_FIND_QUIETLY) 34 | ENDIF(NOT Git_FOUND) 35 | -------------------------------------------------------------------------------- /cmake/cmake-modules-master/FindNetCDF.cmake: -------------------------------------------------------------------------------- 1 | # - Find NetCDF 2 | # Find the native NetCDF includes and library 3 | # 4 | # NETCDF_INCLUDES - where to find netcdf.h, etc 5 | # NETCDF_LIBRARIES - Link these libraries when using NetCDF 6 | # NETCDF_FOUND - True if NetCDF found including required interfaces (see below) 7 | # 8 | # Your package can require certain interfaces to be FOUND by setting these 9 | # 10 | # NETCDF_CXX - require the C++ interface and link the C++ library 11 | # NETCDF_F77 - require the F77 interface and link the fortran library 12 | # NETCDF_F90 - require the F90 interface and link the fortran library 13 | # 14 | # The following are not for general use and are included in 15 | # NETCDF_LIBRARIES if the corresponding option above is set. 16 | # 17 | # NETCDF_LIBRARIES_C - Just the C interface 18 | # NETCDF_LIBRARIES_CXX - C++ interface, if available 19 | # NETCDF_LIBRARIES_F77 - Fortran 77 interface, if available 20 | # NETCDF_LIBRARIES_F90 - Fortran 90 interface, if available 21 | # 22 | # Normal usage would be: 23 | # set (NETCDF_F90 "YES") 24 | # find_package (NetCDF REQUIRED) 25 | # target_link_libraries (uses_f90_interface ${NETCDF_LIBRARIES}) 26 | # target_link_libraries (only_uses_c_interface ${NETCDF_LIBRARIES_C}) 27 | 28 | if (NETCDF_INCLUDES AND NETCDF_LIBRARIES) 29 | # Already in cache, be silent 30 | set (NETCDF_FIND_QUIETLY TRUE) 31 | endif (NETCDF_INCLUDES AND NETCDF_LIBRARIES) 32 | 33 | find_path (NETCDF_INCLUDES netcdf.h 34 | HINTS NETCDF_DIR ENV NETCDF_DIR) 35 | 36 | find_library (NETCDF_LIBRARIES_C NAMES netcdf) 37 | mark_as_advanced(NETCDF_LIBRARIES_C) 38 | 39 | set (NetCDF_has_interfaces "YES") # will be set to NO if we're missing any interfaces 40 | set (NetCDF_libs "${NETCDF_LIBRARIES_C}") 41 | 42 | get_filename_component (NetCDF_lib_dirs "${NETCDF_LIBRARIES_C}" PATH) 43 | 44 | macro (NetCDF_check_interface lang header libs) 45 | if (NETCDF_${lang}) 46 | find_path (NETCDF_INCLUDES_${lang} NAMES ${header} 47 | HINTS "${NETCDF_INCLUDES}" NO_DEFAULT_PATH) 48 | find_library (NETCDF_LIBRARIES_${lang} NAMES ${libs} 49 | HINTS "${NetCDF_lib_dirs}" NO_DEFAULT_PATH) 50 | mark_as_advanced (NETCDF_INCLUDES_${lang} NETCDF_LIBRARIES_${lang}) 51 | if (NETCDF_INCLUDES_${lang} AND NETCDF_LIBRARIES_${lang}) 52 | list (INSERT NetCDF_libs 0 ${NETCDF_LIBRARIES_${lang}}) # prepend so that -lnetcdf is last 53 | else (NETCDF_INCLUDES_${lang} AND NETCDF_LIBRARIES_${lang}) 54 | set (NetCDF_has_interfaces "NO") 55 | message (STATUS "Failed to find NetCDF interface for ${lang}") 56 | endif (NETCDF_INCLUDES_${lang} AND NETCDF_LIBRARIES_${lang}) 57 | endif (NETCDF_${lang}) 58 | endmacro (NetCDF_check_interface) 59 | 60 | NetCDF_check_interface (CXX netcdfcpp.h netcdf_c++) 61 | NetCDF_check_interface (F77 netcdf.inc netcdff) 62 | NetCDF_check_interface (F90 netcdf.mod netcdff) 63 | 64 | set (NETCDF_LIBRARIES "${NetCDF_libs}" CACHE STRING "All NetCDF libraries required for interface level") 65 | 66 | # handle the QUIETLY and REQUIRED arguments and set NETCDF_FOUND to TRUE if 67 | # all listed variables are TRUE 68 | include (FindPackageHandleStandardArgs) 69 | find_package_handle_standard_args (NetCDF DEFAULT_MSG NETCDF_LIBRARIES NETCDF_INCLUDES NetCDF_has_interfaces) 70 | 71 | mark_as_advanced (NETCDF_LIBRARIES NETCDF_INCLUDES) 72 | -------------------------------------------------------------------------------- /cmake/cmake-modules-master/FindPackageMultipass.cmake: -------------------------------------------------------------------------------- 1 | # PackageMultipass - this module defines two macros 2 | # 3 | # FIND_PACKAGE_MULTIPASS (Name CURRENT 4 | # STATES VAR0 VAR1 ... 5 | # DEPENDENTS DEP0 DEP1 ...) 6 | # 7 | # This function creates a cache entry _CURRENT which 8 | # the user can set to "NO" to trigger a reconfiguration of the package. 9 | # The first time this function is called, the values of 10 | # _VAR0, ... are saved. If _CURRENT 11 | # is false or if any STATE has changed since the last time 12 | # FIND_PACKAGE_MULTIPASS() was called, then CURRENT will be set to "NO", 13 | # otherwise CURRENT will be "YES". IF not CURRENT, then 14 | # _DEP0, ... will be FORCED to NOTFOUND. 15 | # Example: 16 | # find_path (FOO_DIR include/foo.h) 17 | # FIND_PACKAGE_MULTIPASS (Foo foo_current 18 | # STATES DIR 19 | # DEPENDENTS INCLUDES LIBRARIES) 20 | # if (NOT foo_current) 21 | # # Make temporary files, run programs, etc, to determine FOO_INCLUDES and FOO_LIBRARIES 22 | # endif (NOT foo_current) 23 | # 24 | # MULTIPASS_SOURCE_RUNS (Name INCLUDES LIBRARIES SOURCE RUNS LANGUAGE) 25 | # Always runs the given test, use this when you need to re-run tests 26 | # because parent variables have made old cache entries stale. The LANGUAGE 27 | # variable is either C or CXX indicating which compiler the test should 28 | # use. 29 | # MULTIPASS_C_SOURCE_RUNS (Name INCLUDES LIBRARIES SOURCE RUNS) 30 | # DEPRECATED! This is only included for backwards compatability. Use 31 | # the more general MULTIPASS_SOURCE_RUNS instead. 32 | # Always runs the given test, use this when you need to re-run tests 33 | # because parent variables have made old cache entries stale. 34 | 35 | macro (FIND_PACKAGE_MULTIPASS _name _current) 36 | string (TOUPPER ${_name} _NAME) 37 | set (_args ${ARGV}) 38 | list (REMOVE_AT _args 0 1) 39 | 40 | set (_states_current "YES") 41 | list (GET _args 0 _cmd) 42 | if (_cmd STREQUAL "STATES") 43 | list (REMOVE_AT _args 0) 44 | list (GET _args 0 _state) 45 | while (_state AND NOT _state STREQUAL "DEPENDENTS") 46 | # The name of the stored value for the given state 47 | set (_stored_var PACKAGE_MULTIPASS_${_NAME}_${_state}) 48 | if (NOT "${${_stored_var}}" STREQUAL "${${_NAME}_${_state}}") 49 | set (_states_current "NO") 50 | endif (NOT "${${_stored_var}}" STREQUAL "${${_NAME}_${_state}}") 51 | set (${_stored_var} "${${_NAME}_${_state}}" CACHE INTERNAL "Stored state for ${_name}." FORCE) 52 | list (REMOVE_AT _args 0) 53 | list (GET _args 0 _state) 54 | endwhile (_state AND NOT _state STREQUAL "DEPENDENTS") 55 | endif (_cmd STREQUAL "STATES") 56 | 57 | set (_stored ${_NAME}_CURRENT) 58 | if (NOT ${_stored}) 59 | set (${_stored} "YES" CACHE BOOL "Is the configuration for ${_name} current? Set to \"NO\" to reconfigure." FORCE) 60 | set (_states_current "NO") 61 | endif (NOT ${_stored}) 62 | 63 | set (${_current} ${_states_current}) 64 | if (NOT ${_current} AND PACKAGE_MULTIPASS_${_name}_CALLED) 65 | message (STATUS "Clearing ${_name} dependent variables") 66 | # Clear all the dependent variables so that the module can reset them 67 | list (GET _args 0 _cmd) 68 | if (_cmd STREQUAL "DEPENDENTS") 69 | list (REMOVE_AT _args 0) 70 | foreach (dep ${_args}) 71 | set (${_NAME}_${dep} "NOTFOUND" CACHE INTERNAL "Cleared" FORCE) 72 | endforeach (dep) 73 | endif (_cmd STREQUAL "DEPENDENTS") 74 | set (${_NAME}_FOUND "NOTFOUND" CACHE INTERNAL "Cleared" FORCE) 75 | endif () 76 | set (PACKAGE_MULTIPASS_${name}_CALLED YES CACHE INTERNAL "Private" FORCE) 77 | endmacro (FIND_PACKAGE_MULTIPASS) 78 | 79 | 80 | macro (MULTIPASS_SOURCE_RUNS includes libraries source runs language) 81 | include (Check${language}SourceRuns) 82 | # This is a ridiculous hack. CHECK_${language}_SOURCE_* thinks that if the 83 | # *name* of the return variable doesn't change, then the test does 84 | # not need to be re-run. We keep an internal count which we 85 | # increment to guarantee that every test name is unique. If we've 86 | # gotten here, then the configuration has changed enough that the 87 | # test *needs* to be rerun. 88 | if (NOT MULTIPASS_TEST_COUNT) 89 | set (MULTIPASS_TEST_COUNT 00) 90 | endif (NOT MULTIPASS_TEST_COUNT) 91 | math (EXPR _tmp "${MULTIPASS_TEST_COUNT} + 1") # Why can't I add to a cache variable? 92 | set (MULTIPASS_TEST_COUNT ${_tmp} CACHE INTERNAL "Unique test ID") 93 | set (testname MULTIPASS_TEST_${MULTIPASS_TEST_COUNT}_${runs}) 94 | set (CMAKE_REQUIRED_INCLUDES ${includes}) 95 | set (CMAKE_REQUIRED_LIBRARIES ${libraries}) 96 | if(${language} STREQUAL "C") 97 | check_c_source_runs ("${source}" ${testname}) 98 | elseif(${language} STREQUAL "CXX") 99 | check_cxx_source_runs ("${source}" ${testname}) 100 | endif() 101 | set (${runs} "${${testname}}") 102 | endmacro (MULTIPASS_SOURCE_RUNS) 103 | 104 | macro (MULTIPASS_C_SOURCE_RUNS includes libraries source runs) 105 | multipass_source_runs("${includes}" "${libraries}" "${source}" ${runs} "C") 106 | endmacro (MULTIPASS_C_SOURCE_RUNS) 107 | -------------------------------------------------------------------------------- /cmake/cmake-modules-master/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright $(git shortlog -s) 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, this 11 | list of conditions and the following disclaimer in the documentation and/or 12 | other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 18 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 21 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | -------------------------------------------------------------------------------- /cmake/cmake-modules-master/README: -------------------------------------------------------------------------------- 1 | A collection of CMake modules, these can mostly be used independently. 2 | 3 | The utilities for writing robust Find* modules might be useful until 4 | CMake takes static libraries and multiple active configurations 5 | seriously. 6 | 7 | http://www.cmake.org/Wiki/CMake:Improving_Find*_Modules 8 | -------------------------------------------------------------------------------- /cmake/cmake-modules-master/ResolveCompilerPaths.cmake: -------------------------------------------------------------------------------- 1 | # ResolveCompilerPaths - this module defines two macros 2 | # 3 | # RESOLVE_LIBRARIES (XXX_LIBRARIES LINK_LINE) 4 | # This macro is intended to be used by FindXXX.cmake modules. 5 | # It parses a compiler link line and resolves all libraries 6 | # (-lfoo) using the library path contexts (-L/path) in scope. 7 | # The result in XXX_LIBRARIES is the list of fully resolved libs. 8 | # Example: 9 | # 10 | # RESOLVE_LIBRARIES (FOO_LIBRARIES "-L/A -la -L/B -lb -lc -ld") 11 | # 12 | # will be resolved to 13 | # 14 | # FOO_LIBRARIES:STRING="/A/liba.so;/B/libb.so;/A/libc.so;/usr/lib/libd.so" 15 | # 16 | # if the filesystem looks like 17 | # 18 | # /A: liba.so libc.so 19 | # /B: liba.so libb.so 20 | # /usr/lib: liba.so libb.so libc.so libd.so 21 | # 22 | # and /usr/lib is a system directory. 23 | # 24 | # Note: If RESOLVE_LIBRARIES() resolves a link line differently from 25 | # the native linker, there is a bug in this macro (please report it). 26 | # 27 | # RESOLVE_INCLUDES (XXX_INCLUDES INCLUDE_LINE) 28 | # This macro is intended to be used by FindXXX.cmake modules. 29 | # It parses a compile line and resolves all includes 30 | # (-I/path/to/include) to a list of directories. Other flags are ignored. 31 | # Example: 32 | # 33 | # RESOLVE_INCLUDES (FOO_INCLUDES "-I/A -DBAR='\"irrelevant -I/string here\"' -I/B") 34 | # 35 | # will be resolved to 36 | # 37 | # FOO_INCLUDES:STRING="/A;/B" 38 | # 39 | # assuming both directories exist. 40 | # Note: as currently implemented, the -I/string will be picked up mistakenly (cry, cry) 41 | include (CorrectWindowsPaths) 42 | 43 | macro (RESOLVE_LIBRARIES LIBS LINK_LINE) 44 | string (REGEX MATCHALL "((-L|-l|-Wl)([^\" ]+|\"[^\"]+\")|[^\" ]+\\.(a|so|dll|lib))" _all_tokens "${LINK_LINE}") 45 | set (_libs_found "") 46 | set (_directory_list "") 47 | foreach (token ${_all_tokens}) 48 | if (token MATCHES "-L([^\" ]+|\"[^\"]+\")") 49 | # If it's a library path, add it to the list 50 | string (REGEX REPLACE "^-L" "" token ${token}) 51 | string (REGEX REPLACE "//" "/" token ${token}) 52 | convert_cygwin_path(token) 53 | list (APPEND _directory_list ${token}) 54 | elseif (token MATCHES "^(-l([^\" ]+|\"[^\"]+\")|[^\" ]+\\.(a|so|dll|lib))") 55 | # It's a library, resolve the path by looking in the list and then (by default) in system directories 56 | if (WIN32) #windows expects "libfoo", linux expects "foo" 57 | string (REGEX REPLACE "^-l" "lib" token ${token}) 58 | else (WIN32) 59 | string (REGEX REPLACE "^-l" "" token ${token}) 60 | endif (WIN32) 61 | set (_root "") 62 | if (token MATCHES "^/") # We have an absolute path 63 | #separate into a path and a library name: 64 | string (REGEX MATCH "[^/]*\\.(a|so|dll|lib)$" libname ${token}) 65 | string (REGEX MATCH ".*[^${libname}$]" libpath ${token}) 66 | convert_cygwin_path(libpath) 67 | set (_directory_list ${_directory_list} ${libpath}) 68 | set (token ${libname}) 69 | endif (token MATCHES "^/") 70 | set (_lib "NOTFOUND" CACHE FILEPATH "Cleared" FORCE) 71 | find_library (_lib ${token} HINTS ${_directory_list} ${_root}) 72 | if (_lib) 73 | string (REPLACE "//" "/" _lib ${_lib}) 74 | list (APPEND _libs_found ${_lib}) 75 | else (_lib) 76 | message (STATUS "Unable to find library ${token}") 77 | endif (_lib) 78 | endif (token MATCHES "-L([^\" ]+|\"[^\"]+\")") 79 | endforeach (token) 80 | set (_lib "NOTFOUND" CACHE INTERNAL "Scratch variable" FORCE) 81 | # only the LAST occurence of each library is required since there should be no circular dependencies 82 | if (_libs_found) 83 | list (REVERSE _libs_found) 84 | list (REMOVE_DUPLICATES _libs_found) 85 | list (REVERSE _libs_found) 86 | endif (_libs_found) 87 | set (${LIBS} "${_libs_found}") 88 | endmacro (RESOLVE_LIBRARIES) 89 | 90 | macro (RESOLVE_INCLUDES INCS COMPILE_LINE) 91 | string (REGEX MATCHALL "-I([^\" ]+|\"[^\"]+\")" _all_tokens "${COMPILE_LINE}") 92 | set (_incs_found "") 93 | foreach (token ${_all_tokens}) 94 | string (REGEX REPLACE "^-I" "" token ${token}) 95 | string (REGEX REPLACE "//" "/" token ${token}) 96 | convert_cygwin_path(token) 97 | if (EXISTS ${token}) 98 | list (APPEND _incs_found ${token}) 99 | else (EXISTS ${token}) 100 | message (STATUS "Include directory ${token} does not exist") 101 | endif (EXISTS ${token}) 102 | endforeach (token) 103 | list (REMOVE_DUPLICATES _incs_found) 104 | set (${INCS} "${_incs_found}") 105 | endmacro (RESOLVE_INCLUDES) 106 | -------------------------------------------------------------------------------- /cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | set(CMAKE_CXX_STANDARD 20) 3 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 4 | 5 | set(CMAKE_CXX_FLAGS_SILENT "-Qunused-arguments") 6 | 7 | 8 | if(USE_OMP) 9 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_SILENT} ${LDFLAGS} -L/opt/homebrew/opt/libomp/lib/ -fopenmp -std=c++2a -fPIC -O3") 10 | include_directories(/opt/homebrew/opt/libomp/include) 11 | else() 12 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LDFLAGS} -std=c++2a -fPIC -O3") 13 | endif() 14 | 15 | 16 | if(USE_MPI) 17 | find_package(MPI ) 18 | include_directories(${MPI_CXX_INCLUDE_DIR}) 19 | set(CMAKE_CXX_COMPILER ${MPI_CXX_COMPILER}) 20 | endif() 21 | 22 | add_subdirectory(parallel) 23 | list(APPEND CUTFEM_LIBS parallel) 24 | add_subdirectory(common) 25 | list(APPEND CUTFEM_LIBS common) 26 | add_subdirectory(FESpace) 27 | list(APPEND CUTFEM_LIBS FESpace) 28 | add_subdirectory(solver) 29 | list(APPEND CUTFEM_LIBS solver) 30 | add_subdirectory(problem) 31 | list(APPEND CUTFEM_LIBS problem) 32 | 33 | 34 | add_library(cutfem INTERFACE) 35 | target_link_libraries(cutfem INTERFACE 36 | parallel 37 | common 38 | FESpace 39 | solver 40 | problem 41 | ) 42 | 43 | if(${CUTFEM_BUILD_EXAMPLE}) 44 | add_subdirectory(example/) 45 | endif() 46 | 47 | -------------------------------------------------------------------------------- /cpp/FESpace/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | set(FESPACE_SOURCES 3 | ${CMAKE_CURRENT_SOURCE_DIR}/QuadratureFormular.cpp 4 | ${CMAKE_CURRENT_SOURCE_DIR}/P0.cpp 5 | ${CMAKE_CURRENT_SOURCE_DIR}/P1.cpp 6 | ${CMAKE_CURRENT_SOURCE_DIR}/P1dc.cpp 7 | ${CMAKE_CURRENT_SOURCE_DIR}/P2.cpp 8 | ${CMAKE_CURRENT_SOURCE_DIR}/P2dc.cpp 9 | ${CMAKE_CURRENT_SOURCE_DIR}/P3dc.cpp 10 | ${CMAKE_CURRENT_SOURCE_DIR}/P3.cpp 11 | ${CMAKE_CURRENT_SOURCE_DIR}/P4.cpp 12 | ${CMAKE_CURRENT_SOURCE_DIR}/RT0.cpp 13 | #RT1.cpp 14 | ${CMAKE_CURRENT_SOURCE_DIR}/RT2.cpp 15 | ${CMAKE_CURRENT_SOURCE_DIR}/BDM1.cpp 16 | ${CMAKE_CURRENT_SOURCE_DIR}/BDM2.cpp 17 | ${CMAKE_CURRENT_SOURCE_DIR}/Ned0.cpp 18 | ${CMAKE_CURRENT_SOURCE_DIR}/P2BR.cpp 19 | ${CMAKE_CURRENT_SOURCE_DIR}/transformation.cpp 20 | ${CMAKE_CURRENT_SOURCE_DIR}/finiteElement.cpp 21 | ${CMAKE_CURRENT_SOURCE_DIR}/GTypeOfFE.cpp 22 | ${CMAKE_CURRENT_SOURCE_DIR}/FESpace.cpp 23 | #CutFESpace.cpp 24 | ${CMAKE_CURRENT_SOURCE_DIR}/expression.cpp 25 | ${CMAKE_CURRENT_SOURCE_DIR}/macroElement.cpp 26 | #limiter.cpp 27 | ${CMAKE_CURRENT_SOURCE_DIR}/paraview.cpp 28 | ) 29 | 30 | 31 | add_library(FESpace SHARED ${FESPACE_SOURCES}) 32 | target_include_directories(FESpace 33 | PUBLIC 34 | "${CMAKE_CURRENT_SOURCE_DIR}" 35 | "${PROJECT_BINARY_DIR}") 36 | if(USE_MPI) 37 | target_link_libraries(FESpace PRIVATE common parallel) 38 | else() 39 | target_link_libraries(FESpace PRIVATE common) 40 | endif() 41 | 42 | -------------------------------------------------------------------------------- /cpp/FESpace/FESpace.cpp: -------------------------------------------------------------------------------- 1 | #include "FESpace.hpp" 2 | -------------------------------------------------------------------------------- /cpp/FESpace/finiteElement.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CutFEM-Library. 3 | 4 | CutFEM-Library is free software: you can redistribute it and/or modify it under 5 | the terms of the GNU General Public License as published by the Free Software 6 | Foundation, either version 3 of the License, or (at your option) any later 7 | version. 8 | 9 | CutFEM-Library is distributed in the hope that it will be useful, but WITHOUT 10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License along with 14 | CutFEM-Library. If not, see 15 | */ 16 | #include "finiteElement.hpp" 17 | 18 | template <> 19 | std::vector *>> BaseFE_Array::FE_ = { 20 | {&DataFE::P0, &DataFE::P0}, 21 | {&DataFE::P1, &DataFE::P1}, 22 | {&DataFE::P2, &DataFE::P2}, 23 | {&DataFE::P3, &DataFE::P3}, 24 | {&DataFE::P4, &DataFE::P4}}; 25 | 26 | template <> 27 | BaseFE_Array::BaseFE_Array(int k) : GTypeOfFESum(this->FE_.at(k)) {} 28 | Lagrange2::Lagrange2(int k) : BaseFE_Array(k){}; 29 | 30 | template <> 31 | std::vector *>> BaseFE_Array::FE_ = { 32 | {&DataFE::P0, &DataFE::P0}, 33 | {&DataFE::P1, &DataFE::P1}, 34 | {&DataFE::P2, &DataFE::P2}, 35 | {&DataFE::P3, &DataFE::P3}}; 36 | 37 | template <> 38 | BaseFE_Array::BaseFE_Array(int k) : GTypeOfFESum(this->FE_.at(k)) {} 39 | LagrangeQuad2::LagrangeQuad2(int k) : BaseFE_Array(k){}; 40 | 41 | template <> 42 | std::vector *>> BaseFE_Array::FE_ = { 43 | {&DataFE::P0, &DataFE::P0, &DataFE::P0}, 44 | {&DataFE::P1, &DataFE::P1, &DataFE::P1}, 45 | {&DataFE::P2, &DataFE::P2, &DataFE::P2}}; 46 | 47 | template <> 48 | BaseFE_Array::BaseFE_Array(int k) : GTypeOfFESum(this->FE_.at(k)) {} 49 | Lagrange3::Lagrange3(int k) : BaseFE_Array(k){}; 50 | 51 | template <> 52 | std::vector *>> BaseFE_Array::FE_ = { 53 | {&DataFE::P0, &DataFE::P0}, 54 | {&DataFE::P1dc, &DataFE::P1dc}, 55 | {&DataFE::P2dc, &DataFE::P2dc}, 56 | {&DataFE::P3dc, &DataFE::P3dc}}; 57 | 58 | template <> 59 | BaseFE_Array::BaseFE_Array(int k) : GTypeOfFESum(this->FE_.at(k)) {} 60 | LagrangeDC2::LagrangeDC2(int k) : BaseFE_Array(k){}; 61 | 62 | // const GTypeOfFE *TaylorHood2::FE_[3] = {&DataFE::P2, &DataFE::P2, 63 | // &DataFE::P1}; //&DataFE::P2; 64 | // // const GTypeOfFE *Lagrange2::FE_[5][2] = 65 | // { 66 | 67 | // const GTypeOfFE *TaylorHood3::FE_[4] = {&DataFE::P2, &DataFE::P2, &DataFE::P2, 68 | // &DataFE::P1}; //&DataFE::P2; 69 | 70 | // template<> 71 | // const GTypeOfFE* Lagrange3::FE_[3][3] = 72 | // {{&DataFE::P0,&DataFE::P0,&DataFE::P0}, 73 | // {&DataFE::P1,&DataFE::P1,&DataFE::P1}//, 74 | // // {&DataFE::P2,&DataFE::P2,&DataFE::P2} 75 | // // ,{&DataFE::P3,&DataFE::P3,&DataFE::P3} 76 | // }; 77 | -------------------------------------------------------------------------------- /cpp/FESpace/finiteElement.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CutFEM-Library. 3 | 4 | CutFEM-Library is free software: you can redistribute it and/or modify it under 5 | the terms of the GNU General Public License as published by the Free Software 6 | Foundation, either version 3 of the License, or (at your option) any later 7 | version. 8 | 9 | CutFEM-Library is distributed in the hope that it will be useful, but WITHOUT 10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License along with 14 | CutFEM-Library. If not, see 15 | */ 16 | #ifndef FINITE_ELEMENT_HPP 17 | #define FINITE_ELEMENT_HPP 18 | 19 | #include "GTypeOfFE_Sum.hpp" 20 | #include "../concept/function.hpp" 21 | 22 | enum class ContinuityType { continuous, discontinuous }; 23 | 24 | template class BaseFE_Array : public GTypeOfFESum { 25 | public: 26 | static std::vector *>> FE_; 27 | BaseFE_Array(int k); 28 | }; 29 | 30 | class Lagrange2 : public BaseFE_Array { 31 | public: 32 | Lagrange2(int k); 33 | }; 34 | class LagrangeQuad2 : public BaseFE_Array { 35 | public: 36 | LagrangeQuad2(int k); 37 | }; 38 | 39 | class Lagrange3 : public BaseFE_Array { 40 | public: 41 | Lagrange3(int k); 42 | }; 43 | 44 | class LagrangeDC2 : public BaseFE_Array { 45 | public: 46 | LagrangeDC2(int k); 47 | }; 48 | 49 | // class TaylorHood2 : public GTypeOfFESum { 50 | // typedef KN *> FEarray; 51 | // static const GTypeOfFE *FE_[3]; 52 | 53 | // public: 54 | // TaylorHood2() : GTypeOfFESum(FEarray(3, FE_)) {} 55 | // }; 56 | 57 | // class TaylorHood3 : public GTypeOfFESum { 58 | // typedef KN *> FEarray; 59 | // static const GTypeOfFE *FE_[4]; 60 | 61 | // public: 62 | // TaylorHood3() : GTypeOfFESum(FEarray(4, FE_)) {} 63 | // }; 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /cpp/FESpace/paraview.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CutFEM-Library. 3 | 4 | CutFEM-Library is free software: you can redistribute it and/or modify it under 5 | the terms of the GNU General Public License as published by the Free Software 6 | Foundation, either version 3 of the License, or (at your option) any later 7 | version. 8 | 9 | CutFEM-Library is distributed in the hope that it will be useful, but WITHOUT 10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License along with 14 | CutFEM-Library. If not, see 15 | */ 16 | #include "paraview.hpp" 17 | 18 | template <> 19 | void Paraview::ParaviewMesh::build(const ActiveMesh &Vh) { 20 | return buildNoCut(Vh); 21 | } 22 | template <> 23 | void Paraview::ParaviewMesh::build(const ActiveMesh &Vh) { 24 | return buildNoCut(Vh); 25 | } 26 | template <> 27 | void Paraview::ParaviewMesh::build(const ActiveMesh &Vh) { 28 | return buildCut(Vh); 29 | } 30 | template <> 31 | void Paraview::ParaviewMesh::build(const ActiveMesh &Vh) { 32 | return buildCut(Vh); 33 | } 34 | 35 | // template<> void Paraview::ParaviewMesh::build(const FESpace & Vh, 36 | // Fun_h* levelSet) { 37 | // return buildNoCut(Vh, levelSet); 38 | // } 39 | // template<> void Paraview::ParaviewMesh::build(const FESpace & Vh, 40 | // Fun_h* levelSet) { 41 | // return buildNoCut(Vh, levelSet); 42 | // } 43 | // template<> void Paraview::ParaviewMesh::build(const FESpace & Vh, 44 | // Fun_h* levelSet) { 45 | // return buildCut(Vh, levelSet); 46 | // } 47 | // template<> void Paraview::ParaviewMesh::build(const FESpace & Vh, 48 | // Fun_h* levelSet) { 49 | // return buildCut(Vh, levelSet); 50 | // } 51 | -------------------------------------------------------------------------------- /cpp/FESpace/restriction.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CutFEM-Library. 3 | 4 | CutFEM-Library is free software: you can redistribute it and/or modify it under 5 | the terms of the GNU General Public License as published by the Free Software 6 | Foundation, either version 3 of the License, or (at your option) any later 7 | version. 8 | 9 | CutFEM-Library is distributed in the hope that it will be useful, but WITHOUT 10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License along with 14 | CutFEM-Library. If not, see 15 | */ 16 | #ifndef RESTRICTION_HPP_ 17 | #define RESTRICTION_HPP_ 18 | 19 | #include "../common/RNM.hpp" 20 | #include "FESpace.hpp" 21 | 22 | template 23 | void restriction(const M &Vh, const KN &fh, const M &cutVh, 24 | KN &g) { 25 | 26 | g.init(cutVh.NbDoF()); 27 | g = 0.0; 28 | 29 | for (int k = 0; k < cutVh.NbElement(); ++k) { 30 | const int kb = cutVh.idxElementInBackMesh(k); 31 | const int kg = Vh.idxElementFromBackMesh(kb); 32 | 33 | const typename M::FElement &FK(cutVh[k]); 34 | const typename M::FElement &FKg(Vh[kg]); 35 | assert(FK.NbDoF() == FKg.NbDoF()); 36 | for (int ic = 0; ic < Vh.N; ++ic) { 37 | for (int i = FK.dfcbegin(ic); i < FK.dfcend(ic); ++i) { 38 | g(FK(i)) = fh(FKg(i)); 39 | } 40 | } 41 | } 42 | } 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /cpp/FESpace/transformation.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CutFEM-Library. 3 | 4 | CutFEM-Library is free software: you can redistribute it and/or modify it under 5 | the terms of the GNU General Public License as published by the Free Software 6 | Foundation, either version 3 of the License, or (at your option) any later 7 | version. 8 | 9 | CutFEM-Library is distributed in the hope that it will be useful, but WITHOUT 10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License along with 14 | CutFEM-Library. If not, see 15 | */ 16 | #include "transformation.hpp" 17 | 18 | // template<> void Transformation::compute_inverse<2>() { 19 | // this->det = F_t(0,0)*F_t(1,1) - F_t(0,1)*F_t(1,0); 20 | // invF_t(0,0) = F_t(1,1); 21 | // invF_t(1,1) = F_t(0,0); 22 | // invF_t(0,1) = -F_t(0,1); 23 | // invF_t(1,0) = -F_t(1,0); 24 | // invF_t /= det; 25 | // } 26 | // template<> void Transformation::compute_inverse<3>() { 27 | // this->det = F_t(0,0)*F_t(1,1) - F_t(0,1)*F_t(1,0); 28 | // invF_t(0,0) = F_t(1,1); 29 | // invF_t(1,1) = F_t(0,0); 30 | // invF_t(0,1) = -F_t(0,1); 31 | // invF_t(1,0) = -F_t(1,0); 32 | // invF_t /= det; 33 | // assert(0); 34 | // } 35 | 36 | // template<> void Linear_Transformation::init() { 37 | // for(int i=0;icompute_inverse<2>(); 43 | // } 44 | // template<> void Linear_Transformation::init() { 45 | // for(int i=0;icompute_inverse<3>(); 51 | // } 52 | // 53 | // template<> Linear_Transformation::Linear_Transformation(const Quad2& 54 | // T) : Transformation(2) { 55 | // A[0] = T[0]; 56 | // A[1] = T[1]; 57 | // A[2] = T[3]; 58 | // init(); 59 | // } 60 | // template<> Linear_Transformation::Linear_Transformation(const Hexa& T) 61 | // : Transformation(3) { 62 | // A[0] = T[0]; 63 | // A[1] = T[1]; 64 | // A[2] = T[3]; 65 | // A[3] = T[4]; 66 | // init(); 67 | // } 68 | 69 | // template<> Linear_Transformation::Linear_Transformation(const Quad2& 70 | // T) : Transformation(2) { 71 | // A[0] = T[0]; 72 | // A[1] = T[1]; 73 | // A[2] = T[3]; 74 | // init(); 75 | // } 76 | -------------------------------------------------------------------------------- /cpp/FESpace/transformation.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CutFEM-Library. 3 | 4 | CutFEM-Library is free software: you can redistribute it and/or modify it under 5 | the terms of the GNU General Public License as published by the Free Software 6 | Foundation, either version 3 of the License, or (at your option) any later 7 | version. 8 | 9 | CutFEM-Library is distributed in the hope that it will be useful, but WITHOUT 10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License along with 14 | CutFEM-Library. If not, see 15 | */ 16 | #ifndef TRANSFORMATION_HPP 17 | #define TRANSFORMATION_HPP 18 | 19 | #include "../common/RNM.hpp" 20 | #include "../common/dataStruct2D.hpp" 21 | #include "../common/dataStruct3D.hpp" 22 | #include 23 | 24 | template class Transformation { 25 | 26 | protected: 27 | struct Memory { 28 | // number of element to remember 29 | const int n = 2; 30 | }; 31 | static const int N = E::Rd::d; 32 | 33 | struct LocalTransformation { 34 | KNM DF, invF_t; 35 | R detDF; 36 | LocalTransformation() : DF(N, N), invF_t(N, N) {} 37 | }; 38 | 39 | std::map mapK; 40 | LocalTransformation *transformation; 41 | 42 | Transformation() {} 43 | 44 | // template void compute_inverse(); 45 | void initialize(const E &K){}; // new local transfo or give the existing one 46 | void transform_phi(const E &K, KNMK_ &bfMat); 47 | virtual void init(const E &K) = 0; 48 | }; 49 | 50 | template class PiolaContravariant : public Transformation { 51 | 52 | public: 53 | PiolaContravariant() {} 54 | 55 | private: 56 | void init(const E &K) { 57 | 58 | this->initialize(K); 59 | for (int i = 0; i < this->N; ++i) { 60 | for (int j = 0; j < this->N; ++j) { 61 | this->transformation->DF(i, j) = K[j + 1][i] - K[0][i]; 62 | } 63 | } 64 | this->transformation->detDF = 65 | this->transformation->DF(0, 0) * this->transformation->DF(1, 1) - 66 | this->transformation->DF(0, 1) * this->transformation->DF(1, 0); 67 | } 68 | }; 69 | 70 | // template 71 | // class Linear_Transformation : public Transformation { 72 | // 73 | // typedef typename E::Rd Rd; 74 | // static const int D = Rd::d; 75 | // static const int nv = E::nv; 76 | // 77 | // Rd A[Rd::d+1]; 78 | // 79 | // public: 80 | // Linear_Transformation(const E& T) ; 81 | // void transform_gradient(const Rd phi_hat[nv], KN_& f0i, int d_i); 82 | // 83 | // private: 84 | // void init(); 85 | // 86 | // }; 87 | // 88 | // 89 | // // d_i derivative of the ith bf is the d_i line of 90 | // // the matrix invJ multiply by the ith bf_hat 91 | // // the last input is op_dx, op_dy, op_dz so we have to do -1; 92 | // template 93 | // void Linear_Transformation::transform_gradient(const Rd dphi_hat[nv], 94 | // KN_& f0i, int d_i){ 95 | // assert(1<=d_i && d_i<=D); 96 | // int op = d_i-1; 97 | // for(int i=0; i 10 | #include 11 | #include 12 | #include "real.hpp" 13 | 14 | namespace algoim 15 | { 16 | struct Binomial 17 | { 18 | // Compute a row of binomial coefficients binom(n,i), i = 0,...,n; 19 | // it is assumed that 'out' has length at least n+1 20 | static void compute_row(int n, real* out) 21 | { 22 | out[0] = 1; 23 | if (n == 0) 24 | return; 25 | out[1] = n; 26 | for (int k = 2; k <= n/2; ++k) 27 | out[k] = (out[k - 1] * (n + 1 - k)) / k; 28 | for (int k = 0; k <= n/2; ++k) 29 | out[n-k] = out[k]; 30 | } 31 | 32 | // Compute (and cache) all binomial coefficients binom(n,i), i = 0,...,n; 33 | // for n small enough, the row is obtained directly from a dense table; 34 | // for n large, the row is computed and cached in a sparse hash table 35 | static const real* row(int n) 36 | { 37 | static constexpr int m = 31; 38 | static const auto precomputed = []() 39 | { 40 | std::array d; 41 | int i = 0; 42 | for (int n = 0; n <= m; ++n) 43 | { 44 | compute_row(n, &d[i]); 45 | i += n + 1; 46 | } 47 | return d; 48 | }(); 49 | 50 | if (n <= m) 51 | return &precomputed[ (n*(n+1))/2 ]; 52 | 53 | // All other n are stored in a thread_local hash table 54 | static thread_local std::unordered_map> coeff; 55 | auto& b = coeff[n]; 56 | if (b.empty()) 57 | { 58 | b.resize(n + 1); 59 | compute_row(n, b.data()); 60 | } 61 | return b.data(); 62 | }; 63 | 64 | // returns the binomial coefficient (n \\ i) 65 | static real c(int n, int i) 66 | { 67 | return row(n)[i]; 68 | } 69 | }; 70 | } // namespace algoim 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /cpp/algoim/booluarray.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ALGOIM_BOOLUARRAY_HPP 2 | #define ALGOIM_BOOLUARRAY_HPP 3 | 4 | // algoim::booluarray 5 | 6 | #include 7 | #include "uvector.hpp" 8 | 9 | namespace algoim 10 | { 11 | namespace booluarray_detail 12 | { 13 | constexpr int pow(int base, int exp) 14 | { 15 | return exp == 0 ? 1 : base * pow(base, exp - 1); 16 | } 17 | 18 | template 19 | constexpr int furl(const uvector& i) 20 | { 21 | int ind = i(0); 22 | for (int j = 1; j < N; ++j) 23 | ind = ind * E + i(j); 24 | return ind; 25 | } 26 | } 27 | 28 | // booluarray implements a simple N-dimensional array of booleans, with 29 | // compile-time extent E across all dimensions; it is essentially a basic 30 | // specialisation of uarray 31 | template 32 | class booluarray 33 | { 34 | constexpr static int size = booluarray_detail::pow(E, N); 35 | std::bitset bits; 36 | public: 37 | booluarray() {} 38 | 39 | booluarray(bool val) 40 | { 41 | if (val) 42 | bits.set(); 43 | } 44 | 45 | bool operator() (const uvector& i) const 46 | { 47 | return bits[booluarray_detail::furl(i)]; 48 | } 49 | 50 | auto operator() (const uvector& i) 51 | { 52 | return bits[booluarray_detail::furl(i)]; 53 | } 54 | 55 | // returns true iff the entire array is false 56 | bool none() const 57 | { 58 | return bits.none(); 59 | } 60 | }; 61 | } // namespace algoim 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /cpp/algoim/hyperrectangle.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ALGOIM_HYPERRECTANGLE_HPP 2 | #define ALGOIM_HYPERRECTANGLE_HPP 3 | 4 | // algoim::HyperRectangle 5 | 6 | #include "real.hpp" 7 | #include "uvector.hpp" 8 | 9 | namespace algoim 10 | { 11 | // HyperRectangle describes the extent of a hyperrectangle, i.e., the set of points 12 | // x = (x(0), ..., x(i), ..., x(N-1)) such that xmin(i) <= x(i) <= xmax(i) for all i. 13 | template 14 | struct HyperRectangle 15 | { 16 | uvector,2> range; 17 | 18 | HyperRectangle(const uvector& min, const uvector& max) : range{min, max} {} 19 | 20 | const uvector& side(int s) const 21 | { 22 | return range(s); 23 | } 24 | 25 | const uvector& min() const 26 | { 27 | return range(0); 28 | } 29 | 30 | T& min(int i) 31 | { 32 | return range(0)(i); 33 | } 34 | 35 | T min(int i) const 36 | { 37 | return range(0)(i); 38 | } 39 | 40 | const uvector& max() const 41 | { 42 | return range(1); 43 | } 44 | 45 | T& max(int i) 46 | { 47 | return range(1)(i); 48 | } 49 | 50 | T max(int i) const 51 | { 52 | return range(1)(i); 53 | } 54 | 55 | uvector extent() const 56 | { 57 | return range(1) - range(0); 58 | } 59 | 60 | T extent(int i) const 61 | { 62 | return range(1)(i) - range(0)(i); 63 | } 64 | 65 | uvector midpoint() const 66 | { 67 | return (range(0) + range(1)) * 0.5; 68 | } 69 | 70 | real midpoint(int i) const 71 | { 72 | return (range(0)(i) + range(1)(i)) * 0.5; 73 | } 74 | 75 | bool operator==(const HyperRectangle& x) const 76 | { 77 | for (int dim = 0; dim < N; ++dim) 78 | if (range(0)(dim) != x.range(0)(dim) || range(1)(dim) != x.range(1)(dim)) 79 | return false; 80 | return true; 81 | } 82 | }; 83 | } // namespace algoim 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /cpp/algoim/multiloop.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ALGOIM_MULTILOOP_HPP 2 | #define ALGOIM_MULTILOOP_HPP 3 | 4 | // algoim::MultiLoop for writing N-dimensional nested for loops 5 | 6 | #include "uvector.hpp" 7 | 8 | namespace algoim 9 | { 10 | // MultiLoop is essentially an N-dimensional iterator for looping over the 11 | // coordinates of a Cartesian grid having indices min(0) <= i < max(0), 12 | // min(1) <= j < max(1), min(2) <= k < max(2), etc. The ordering is such that 13 | // dimension N-1 is inner-most, i.e., iterates the fastest, while dimension 14 | // 0 is outer-most and iterates the slowest. 15 | template 16 | class MultiLoop 17 | { 18 | uvector i; 19 | const uvector min, max; 20 | bool valid; 21 | public: 22 | MultiLoop(const uvector& min, const uvector& max) 23 | : i(min), min(min), max(max), valid(all(min < max)) 24 | {} 25 | 26 | MultiLoop& operator++() 27 | { 28 | for (int dim = N - 1; dim >= 0; --dim) 29 | { 30 | if (++i(dim) < max(dim)) 31 | return *this; 32 | i(dim) = min(dim); 33 | } 34 | valid = false; 35 | return *this; 36 | } 37 | 38 | const uvector& operator()() const 39 | { 40 | return i; 41 | } 42 | 43 | int operator()(int index) const 44 | { 45 | return i(index); 46 | } 47 | 48 | bool operator~() const 49 | { 50 | return valid; 51 | } 52 | }; 53 | } // namespace algoim 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /cpp/algoim/polyset.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ALGOIM_POLYSET_HPP 2 | #define ALGOIM_POLYSET_HPP 3 | 4 | // algoim::PolySet 5 | 6 | #include 7 | #include 8 | #include "booluarray.hpp" 9 | 10 | namespace algoim 11 | { 12 | // PolySet implements a simple container to hold one or more Bernstein polynomials 13 | // and their associated masks 14 | template 15 | struct PolySet 16 | { 17 | struct Poly 18 | { 19 | uvector ext; // Degree/extent of polynomial 20 | size_t offset; // Offset into buffer, storing the xarray polynomial data 21 | booluarray mask; // Mask 22 | }; 23 | std::vector buff; // Memory buffer containing polynomial data 24 | std::vector items; // Record of contained polynomials 25 | 26 | // Access polynomial by index 27 | xarray poly(size_t ind) 28 | { 29 | assert(0 <= ind && ind < items.size()); 30 | return xarray(&buff[items[ind].offset], items[ind].ext); 31 | } 32 | 33 | // Access mask by index 34 | booluarray& mask(size_t ind) 35 | { 36 | assert(0 <= ind && ind < items.size()); 37 | return items[ind].mask; 38 | } 39 | 40 | // Add a polynomial/mask pair to the container 41 | void push_back(const xarray& p, const booluarray& m) 42 | { 43 | items.push_back({p.ext(), buff.size(), m}); 44 | buff.resize(buff.size() + p.size()); 45 | poly(items.size() - 1) = p; 46 | } 47 | 48 | size_t count() const 49 | { 50 | return items.size(); 51 | } 52 | }; 53 | } // namespace algoim 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /cpp/algoim/real.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ALGOIM_REAL_HPP 2 | #define ALGOIM_REAL_HPP 3 | 4 | // Header file for defining algoim::real; by default, algoim::real is a typedef for double. 5 | // High precision arithmetic can be used with Algoim by redefining algoim::real as another 6 | // type (e.g., the quadruple-double type qd_real as provided by the QD library). Additional 7 | // modifications may be necessary depending on the end application; e.g., the quadrature 8 | // methods would need high precision versions of eigenvalue and SVD solvers; for further 9 | // details and suggestions, see Algoim's GitHub page. 10 | 11 | namespace algoim 12 | { 13 | // typedef for algoim::real 14 | using real = double; 15 | } // namespace algoim 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /cpp/algoim/sparkstack.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ALGOIM_SPARKSTACK_HPP 2 | #define ALGOIM_SPARKSTACK_HPP 3 | 4 | // algoim::SparkStack implements a fast, thread-safe, stack-based allocator, 5 | // similar in function to alloca() but with additional guarantees regarding 6 | // portability, alignment, and type consistency. 7 | 8 | #include 9 | #include "uvector.hpp" 10 | 11 | namespace algoim 12 | { 13 | template 14 | class xarray; 15 | 16 | template 17 | class SparkStack 18 | { 19 | static constexpr size_t capacity = 1u << 23; 20 | static constexpr int capacity_line = __LINE__ - 1; 21 | 22 | template 23 | static size_t alloc(T** ptr, size_t len, R... rest) 24 | { 25 | if (pos() + len > capacity) 26 | { 27 | std::cerr << "SparkStack: capacity=" << capacity << " and pos=" << pos() << " insufficient for request len=" << len << '\n'; 28 | std::cerr << " consider increasing const 'capacity', defined on line " << capacity_line << " in file " << __FILE__ << '\n'; 29 | throw std::bad_alloc(); 30 | } 31 | *ptr = base() + pos(); 32 | pos() += len; 33 | if constexpr (sizeof...(rest) == 0) 34 | return len; 35 | else 36 | return len + alloc(rest...); 37 | } 38 | 39 | static T* base() 40 | { 41 | static thread_local std::vector buff(capacity); 42 | return buff.data(); 43 | } 44 | 45 | static ptrdiff_t& pos() 46 | { 47 | static thread_local ptrdiff_t pos_ = 0; 48 | return pos_; 49 | }; 50 | 51 | size_t len_; 52 | 53 | SparkStack(const SparkStack&) = delete; 54 | SparkStack(SparkStack&&) = delete; 55 | SparkStack& operator=(const SparkStack&) = delete; 56 | SparkStack& operator=(SparkStack&&) = delete; 57 | 58 | public: 59 | 60 | // With parameters x0, n0, x1, n1, x2, n2, ..., allocate n0 elements and assign to x0, etc. 61 | template 62 | explicit SparkStack(T** ptr, size_t len, R&&... rest) 63 | { 64 | len_ = alloc(ptr, len, rest...); 65 | } 66 | 67 | // With parameters value, x0, n0, x1, n1, x2, n2, ..., allocate n0 elements and assign to x0, ..., 68 | // and assign the given value to all n0*n1*n2*... values allocated 69 | template 70 | explicit SparkStack(T value, T** ptr, size_t len, R&&... rest) 71 | { 72 | T* start = base() + pos(); 73 | len_ = alloc(ptr, len, rest...); 74 | for (int i = 0; i < len_; ++i) 75 | *(start + i) = value; 76 | } 77 | 78 | // For each i, allocate ext(i) elements and assign to ptr(i) 79 | template 80 | explicit SparkStack(uvector& ptr, const uvector& ext) 81 | { 82 | len_ = 0; 83 | for (int i = 0; i < N; ++i) 84 | len_ += alloc(&ptr(i), ext(i)); 85 | } 86 | 87 | // Allocate enough elements for one or more xarray's having pre-set extent 88 | template 89 | explicit SparkStack(xarray&... a) 90 | { 91 | len_ = (alloc(&a.data_, a.size()) + ...); 92 | } 93 | 94 | // Release memory when the SparkStack object goes out of scope 95 | ~SparkStack() 96 | { 97 | pos() -= len_; 98 | } 99 | }; 100 | 101 | #define algoim_CONCAT2(x, y) x ## y 102 | #define algoim_CONCAT(x, y) algoim_CONCAT2(x, y) 103 | #define algoim_spark_alloc(T, ...) SparkStack algoim_CONCAT(spark_alloc_var_, __LINE__)(__VA_ARGS__) 104 | #define algoim_spark_alloc_def(T, val, ...) SparkStack algoim_CONCAT(spark_alloc_var_, __LINE__)(val, __VA_ARGS__) 105 | #define algoim_spark_alloc_vec(T, ptr, ext) SparkStack algoim_CONCAT(spark_alloc_var_, __LINE__)(ptr, ext) 106 | 107 | } // namespace algoim 108 | 109 | #endif 110 | -------------------------------------------------------------------------------- /cpp/algoim/stencilpoly.hpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CutFEM/CutFEM-Library/2ebe5342078f70ae219b9fc5226edde3e8bc2854/cpp/algoim/stencilpoly.hpp -------------------------------------------------------------------------------- /cpp/algoim/utility.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ALGOIM_UTILITY_HPP 2 | #define ALGOIM_UTILITY_HPP 3 | 4 | // Minor utility methods used throughout Algoim 5 | 6 | namespace algoim::util 7 | { 8 | static_assert(std::is_same_v, "Warning: pi constant may require redefining when real != double"); 9 | static constexpr double pi = 3.141592653589793238462643383279502884197169399375105820974944592307816; 10 | 11 | // square of u 12 | template 13 | constexpr auto sqr(T u) 14 | { 15 | return u*u; 16 | } 17 | 18 | // cube of u 19 | template 20 | constexpr auto cube(T u) 21 | { 22 | return u*u*u; 23 | } 24 | 25 | // sign of u: 26 | // -1, if u < 0, 27 | // +1, if u > 0, 28 | // 0, otherwise 29 | template 30 | constexpr int sign(T u) noexcept 31 | { 32 | return (T(0) < u) - (u < T(0)); 33 | } 34 | 35 | // collapse an N-dimensional multi-index into a scalar integer according to its location 36 | // in an N-dimensional grid of the given extent, such that the lowest dimension iterates 37 | // the slowest, and the highest dimension corresponds to the inner-most loop, consistent 38 | // with MultiLoop semantics. For example, 39 | // furl( {i,j}, {m,n} ) = i*n + j 40 | // furl( {i,j,k}, {m,n,o} ) = i*n*o + j*o + k 41 | template 42 | int furl(const uvector& i, const uvector& ext) 43 | { 44 | int ind = i(0); 45 | for (int j = 1; j < N; ++j) 46 | ind = ext(j) * ind + i(j); 47 | return ind; 48 | } 49 | 50 | // compute a Givens rotation 51 | template 52 | void givens_get(const T& a, const T& b, T& c, T& s) 53 | { 54 | using std::abs; 55 | using std::sqrt; 56 | if (b == 0.0) 57 | { 58 | c = 1.0; 59 | s = 0.0; 60 | } 61 | else if (abs(b) > abs(a)) 62 | { 63 | T tmp = a / b; 64 | s = T(1) / sqrt(1.0 + tmp*tmp); 65 | c = tmp * s; 66 | } 67 | else 68 | { 69 | T tmp = b / a; 70 | c = T(1) / sqrt(1.0 + tmp*tmp); 71 | s = tmp * c; 72 | } 73 | }; 74 | 75 | // apply a Givens rotation 76 | template 77 | void givens_rotate(T& x, T& y, T c, T s) 78 | { 79 | T a = x, b = y; 80 | x = c * a + s * b; 81 | y = -s * a + c * b; 82 | }; 83 | } // namespace algoim::util 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /cpp/common/AlgoimInterface.cpp: -------------------------------------------------------------------------------- 1 | #include "AlgoimInterface.hpp" 2 | 3 | // template 4 | // bool AlgoimInterface::isCutFace(int k, int ifac) const { 5 | // assert(0); 6 | // // int i1 = Element::nvedge[ifac][0]; 7 | // // int i2 = Element::nvedge[ifac][1]; 8 | // // if (phi(this->backMesh->operator[](k).at(i1)) * phi(this->backMesh->operator[](k).at(i2)) < 0) 9 | // // return true; 10 | // return false; 11 | // } -------------------------------------------------------------------------------- /cpp/common/AlgoimInterface.hpp: -------------------------------------------------------------------------------- 1 | 2 | #ifndef ALGOIM_INTERFACE_HPP 3 | #define ALGOIM_INTERFACE_HPP 4 | 5 | #include "interface_levelSet.hpp" 6 | #include "../algoim/quadrature_general.hpp" 7 | 8 | /** 9 | * @brief Interface class that uses the algoim quadrature generation to find cut elements. 10 | * 11 | * @tparam M Mesh type 12 | * @tparam L Algoim level set type 13 | */ 14 | template class AlgoimInterface : public Interface { 15 | using mesh_t = M; 16 | using Element = typename mesh_t::Element; 17 | using Rd = typename mesh_t::Rd; 18 | static const int nve = Rd::d; 19 | using Face = FaceInterface; 20 | using ElementIdx = SortArray; 21 | 22 | // save cut elements as a map of background mesh index of cut element, and corresponding interface quadrature rule 23 | 24 | L phi; 25 | const int quadrature_order = 5; 26 | int number_of_cut_elements{0}; 27 | std::map> cut_elements; 28 | 29 | public: 30 | AlgoimInterface(const mesh_t &Mesh, const L &phi_, int label = 0); 31 | 32 | std::map> get_cut_elements() { return cut_elements; } 33 | int get_nb_cut_elements() { return cut_elements.size(); } 34 | SignElement get_SignElement(int k) const override; 35 | Partition get_partition(int k) const override; 36 | 37 | Partition get_partition_face(const typename Element::Face &face, int k, 38 | int ifac) const override; 39 | void cut_partition(Physical_Partition &local_partition, std::vector &new_element_idx, 40 | std::list &erased_element, int sign_part) const override; 41 | 42 | double measure(const Face &f) const override; 43 | 44 | bool isCutFace(int k, int ifac) const override; 45 | 46 | bool isCut(int k) const override; 47 | 48 | Rd normal(int k, std::span x) const override; 49 | 50 | R measure(int i) const override; 51 | 52 | Rd mapToPhysicalFace(int ifac, const typename Element::RdHatBord x) const override; 53 | 54 | size_t size() const override { return cut_elements.size(); } 55 | 56 | double get_t() { return phi.t; } 57 | 58 | private: 59 | void make_algoim_patch(int label); 60 | }; 61 | 62 | #include "AlgoimInterface.tpp" 63 | 64 | #endif -------------------------------------------------------------------------------- /cpp/common/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | set(COMMON_SOURCES 3 | ${CMAKE_CURRENT_SOURCE_DIR}/global.cpp 4 | ${CMAKE_CURRENT_SOURCE_DIR}/logger.cpp 5 | ${CMAKE_CURRENT_SOURCE_DIR}/dataStruct1D.cpp 6 | ${CMAKE_CURRENT_SOURCE_DIR}/dataStruct2D.cpp 7 | ${CMAKE_CURRENT_SOURCE_DIR}/dataStruct3D.cpp 8 | ${CMAKE_CURRENT_SOURCE_DIR}/GenericMesh.cpp 9 | ${CMAKE_CURRENT_SOURCE_DIR}/Mesh1dn.cpp 10 | ${CMAKE_CURRENT_SOURCE_DIR}/Mesh2dn.cpp 11 | ${CMAKE_CURRENT_SOURCE_DIR}/Mesh3dn.cpp 12 | ${CMAKE_CURRENT_SOURCE_DIR}/base_interface.cpp 13 | ${CMAKE_CURRENT_SOURCE_DIR}/interface_levelSet.cpp 14 | ${CMAKE_CURRENT_SOURCE_DIR}/AlgoimInterface.cpp 15 | ${CMAKE_CURRENT_SOURCE_DIR}/cut_mesh.cpp 16 | ${CMAKE_CURRENT_SOURCE_DIR}/cut_method.cpp 17 | ${CMAKE_CURRENT_SOURCE_DIR}/SparseMatMap.cpp 18 | ${CMAKE_CURRENT_SOURCE_DIR}/geometry.cpp 19 | # ${CMAKE_CURRENT_SOURCE_DIR}/marker.cpp 20 | # ${CMAKE_CURRENT_SOURCE_DIR}/parametrization.cpp 21 | # ${CMAKE_CURRENT_SOURCE_DIR}/spline.cpp 22 | ) 23 | 24 | # add_library(common SHARED ${COMMON_SOURCES}) 25 | 26 | add_library(common SHARED "") 27 | add_library(common::common ALIAS common) 28 | target_sources(common PRIVATE ${COMMON_SOURCES}) 29 | 30 | target_include_directories(common 31 | PRIVATE 32 | "${CMAKE_CURRENT_SOURCE_DIR}" 33 | "${CMAKE_CURRENT_BINARY_DIR}" 34 | "${PROJECT_BINARY_DIR}") 35 | 36 | if(USE_MPI) 37 | target_link_libraries(common PRIVATE parallel) 38 | else() 39 | target_link_libraries(common) 40 | endif() 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /cpp/common/GenericMesh.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CutFEM-Library. 3 | 4 | CutFEM-Library is free software: you can redistribute it and/or modify it under 5 | the terms of the GNU General Public License as published by the Free Software 6 | Foundation, either version 3 of the License, or (at your option) any later 7 | version. 8 | 9 | CutFEM-Library is distributed in the hope that it will be useful, but WITHOUT 10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License along with 14 | CutFEM-Library. If not, see 15 | */ 16 | /* 17 | 18 | This file is part of Freefem++ 19 | 20 | Freefem++ is free software; you can redistribute it and/or modify 21 | it under the terms of the GNU Lesser General Public License as published by 22 | the Free Software Foundation; either version 2.1 of the License, or 23 | (at your option) any later version. 24 | 25 | Freefem++ is distributed in the hope that it will be useful, 26 | but WITHOUT ANY WARRANTY; without even the implied warranty of 27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 28 | GNU Lesser General Public License for more details. 29 | 30 | You should have received a copy of the GNU Lesser General Public License 31 | along with Freefem++; if not, write to the Free Software 32 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 33 | */ 34 | 35 | #include "GenericMesh.hpp" 36 | 37 | template void GenericMesh::BuildAdj() { 38 | if (TheAdjacencesLink != 0) 39 | return; // already build 40 | 41 | BuildAdjacencyOfMesh> a(*this); 42 | } 43 | 44 | template BuildAdjacencyOfMesh::BuildAdjacencyOfMesh(GMesh &m) : mesh(m) { 45 | initializeArray(); 46 | 47 | findAdjacencyElement(); 48 | 49 | findBoundaryElement(); 50 | } 51 | 52 | template void BuildAdjacencyOfMesh::initializeArray() { 53 | mesh.TheAdjacencesLink = new int[mesh.nea * mesh.nt]; 54 | mesh.BoundaryElementHeadLink = new int[mesh.nbe]; 55 | } 56 | 57 | template void BuildAdjacencyOfMesh::findAdjacencyElement() { 58 | nk = 0, nba = 0; 59 | ne = 0; 60 | for (int k = 0; k < mesh.nt; ++k) { 61 | for (int i = 0; i < mesh.nea; ++i) { 62 | addFace(k, i); 63 | } 64 | } 65 | } 66 | 67 | template void BuildAdjacencyOfMesh::addFace(const int k, const int i) { 68 | SArray a(mesh.itemadj(k, i)); // sort nodes on the adj item 69 | auto p = h.find(a); 70 | if (p == h.end()) { 71 | ne++; 72 | addFaceFirstTime(a); 73 | } else { 74 | addFaceAlreadySeen(p, a); 75 | } 76 | ++nk; 77 | } 78 | 79 | template void BuildAdjacencyOfMesh::addFaceFirstTime(const SArray &a) { 80 | h[a] = nk; 81 | mesh.TheAdjacencesLink[nk] = -1; 82 | nba++; 83 | } 84 | 85 | template 86 | void BuildAdjacencyOfMesh::addFaceAlreadySeen(typename std::map::iterator p, const SArray &a) { 87 | assert(p->second >= 0); 88 | mesh.TheAdjacencesLink[nk] = p->second; 89 | mesh.TheAdjacencesLink[p->second] = nk; 90 | 91 | p->second = -1 - nk; 92 | nba--; 93 | } 94 | 95 | template void BuildAdjacencyOfMesh::findBoundaryElement() { 96 | for (int k = 0; k < mesh.nbe; ++k) { 97 | addBoundary(k); 98 | } 99 | } 100 | 101 | template void BuildAdjacencyOfMesh::addBoundary(const int k) { 102 | int err = 0; 103 | SArray a(mesh.itembe(k)); 104 | auto p = h.find(a); 105 | if (p == h.end()) { 106 | err++; 107 | if (err == 1) 108 | std::cerr << "Err Border element not in mesh \n"; 109 | if (err < 10) 110 | std::cerr << " \t " << k << " " << a << std::endl; 111 | } else { 112 | mesh.BoundaryElementHeadLink[k] = p->second < 0 ? -p->second - 1 : p->second; 113 | } 114 | } 115 | 116 | template void GenericMesh::BuildBound() { 117 | mes = 0.; 118 | mesb = 0.; 119 | 120 | for (int i = 0; i < nt; i++) 121 | mes += this->elements[i].measure(); 122 | 123 | for (int i = 0; i < nbe; i++) 124 | mesb += this->be(i).measure(); 125 | } 126 | 127 | template class GenericMesh; 128 | template class GenericMesh; 129 | template class GenericMesh; 130 | template class GenericMesh; 131 | template class GenericMesh; 132 | 133 | template class BuildAdjacencyOfMesh>; 134 | template class BuildAdjacencyOfMesh>; 135 | template class BuildAdjacencyOfMesh>; 136 | template class BuildAdjacencyOfMesh>; 137 | template class BuildAdjacencyOfMesh>; 138 | -------------------------------------------------------------------------------- /cpp/common/GenericVertex.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CutFEM-Library. 3 | 4 | CutFEM-Library is free software: you can redistribute it and/or modify it under 5 | the terms of the GNU General Public License as published by the Free Software 6 | Foundation, either version 3 of the License, or (at your option) any later 7 | version. 8 | 9 | CutFEM-Library is distributed in the hope that it will be useful, but WITHOUT 10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License along with 14 | CutFEM-Library. If not, see 15 | */ 16 | /* 17 | 18 | This file is part of Freefem++ 19 | 20 | Freefem++ is free software; you can redistribute it and/or modify 21 | it under the terms of the GNU Lesser General Public License as published by 22 | the Free Software Foundation; either version 2.1 of the License, or 23 | (at your option) any later version. 24 | 25 | Freefem++ is distributed in the hope that it will be useful, 26 | but WITHOUT ANY WARRANTY; without even the implied warranty of 27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 28 | GNU Lesser General Public License for more details. 29 | 30 | You should have received a copy of the GNU Lesser General Public License 31 | along with Freefem++; if not, write to the Free Software 32 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 33 | */ 34 | 35 | #ifndef COMMON_GENERIC_VERTEX_HPP 36 | #define COMMON_GENERIC_VERTEX_HPP 37 | 38 | #include "Label.hpp" 39 | #include "point.hpp" 40 | /* 41 | * Class of the generic vertex 42 | * 43 | */ 44 | template class GenericVertex : public Rn, public Label { 45 | template friend class GenericMesh; 46 | 47 | friend inline std::ostream &operator<<(std::ostream &f, const GenericVertex &v) { 48 | f << (const Rn &)v << ' ' << (const Label &)v; 49 | return f; 50 | } 51 | friend inline std::istream &operator>>(std::istream &f, GenericVertex &v) { 52 | f >> (Rn &)v >> (Label &)v; 53 | return f; 54 | } 55 | 56 | public: 57 | using value_type = typename Rn::value_type; 58 | typedef Rn Rd; 59 | static const int d = Rd::d; 60 | 61 | GenericVertex() : Rd(), Label(){}; //,normal(0) {}; 62 | GenericVertex(const Rd &P, int r = 0) : Rd(P), Label(r){}; //,normal(0){} 63 | 64 | private: // pas de copie pour ne pas prendre l'adresse 65 | GenericVertex(const GenericVertex &); 66 | void operator=(const GenericVertex &); 67 | }; 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /cpp/common/Label.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CutFEM-Library. 3 | 4 | CutFEM-Library is free software: you can redistribute it and/or modify it under 5 | the terms of the GNU General Public License as published by the Free Software 6 | Foundation, either version 3 of the License, or (at your option) any later 7 | version. 8 | 9 | CutFEM-Library is distributed in the hope that it will be useful, but WITHOUT 10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License along with 14 | CutFEM-Library. If not, see 15 | */ 16 | /* 17 | 18 | This file is part of Freefem++ 19 | 20 | Freefem++ is free software; you can redistribute it and/or modify 21 | it under the terms of the GNU Lesser General Public License as published by 22 | the Free Software Foundation; either version 2.1 of the License, or 23 | (at your option) any later version. 24 | 25 | Freefem++ is distributed in the hope that it will be useful, 26 | but WITHOUT ANY WARRANTY; without even the implied warranty of 27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 28 | GNU Lesser General Public License for more details. 29 | 30 | You should have received a copy of the GNU Lesser General Public License 31 | along with Freefem++; if not, write to the Free Software 32 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 33 | */ 34 | 35 | #ifndef COMMON_LABEL_HPP 36 | #define COMMON_LABEL_HPP 37 | 38 | #include 39 | 40 | class Label { // reference number for the physics 41 | friend inline std::ostream &operator<<(std::ostream &f, const Label &r) { 42 | f << r.lab; 43 | return f; 44 | } 45 | friend inline std::istream &operator>>(std::istream &f, Label &r) { 46 | f >> r.lab; 47 | return f; 48 | } 49 | 50 | public: 51 | int lab; 52 | Label(int r = 0) : lab(r) {} 53 | bool onGamma() const { return lab; } 54 | }; 55 | #endif 56 | -------------------------------------------------------------------------------- /cpp/common/Mesh1dn.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CutFEM-Library. 3 | 4 | CutFEM-Library is free software: you can redistribute it and/or modify it under 5 | the terms of the GNU General Public License as published by the Free Software 6 | Foundation, either version 3 of the License, or (at your option) any later 7 | version. 8 | 9 | CutFEM-Library is distributed in the hope that it will be useful, but WITHOUT 10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License along with 14 | CutFEM-Library. If not, see 15 | */ 16 | /* 17 | 18 | This file is part of Freefem++ 19 | 20 | Freefem++ is free software; you can redistribute it and/or modify 21 | it under the terms of the GNU Lesser General Public License as published by 22 | the Free Software Foundation; either version 2.1 of the License, or 23 | (at your option) any later version. 24 | 25 | Freefem++ is distributed in the hope that it will be useful, 26 | but WITHOUT ANY WARRANTY; without even the implied warranty of 27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 28 | GNU Lesser General Public License for more details. 29 | 30 | You should have received a copy of the GNU Lesser General Public License 31 | along with Freefem++; if not, write to the Free Software 32 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 33 | */ 34 | 35 | #include 36 | #include 37 | #include "RNM.hpp" 38 | #include "libmesh5.h" 39 | #include "Mesh1dn.hpp" 40 | 41 | long verbosity = 2; 42 | 43 | Mesh1::Mesh1(const char *filename) { // read the mesh 44 | 45 | int nt, nv, nbe; 46 | int ok = 0; // load(filename); 47 | if (ok) { 48 | std::ifstream f(filename); 49 | if (!f) { 50 | std::cerr << "Mesh1::Mesh1 Erreur openning " << filename << std::endl; 51 | exit(1); 52 | } 53 | if (verbosity) 54 | std::cout << " Read On file \"" << filename << "\"" << std::endl; 55 | f >> nv >> nt >> nbe; 56 | this->set(nv, nt, nbe); 57 | if (verbosity) 58 | std::cout << " -- Nb of Vertex " << nv << " " 59 | << " Nb of Seg " << nt << " , Nb of border Vertex " << nbe << std::endl; 60 | assert(f.good() && nt && nv); 61 | for (int i = 0; i < nv; i++) { 62 | f >> this->vertices[i]; 63 | assert(f.good()); 64 | } 65 | mes = 0; 66 | for (int i = 0; i < nt; i++) { 67 | this->t(i).Read1(f, this->vertices, nv); 68 | mes += t(i).measure(); 69 | } 70 | mesb = 0.; 71 | for (int i = 0; i < nbe; i++) { 72 | this->be(i).Read1(f, this->vertices, nv); 73 | mesb += be(i).measure(); 74 | } 75 | } 76 | BuildBound(); 77 | BuildAdj(); 78 | 79 | if (verbosity) 80 | std::cout << " - mesh mesure = " << mes << " border mesure: " << mesb << std::endl; 81 | } 82 | 83 | Mesh1::Mesh1(int nx, R orx, R lx) { 84 | 85 | int mv = nx; 86 | int mt = (nx - 1); 87 | int mbe = 2; 88 | const R hx = lx / (nx - 1); 89 | 90 | this->set(mv, mt, mbe); 91 | 92 | for (int i = 0; i < nx; i++) { 93 | vertices[i].X() = i * hx + orx; 94 | } 95 | 96 | for (int k = 0; k < nx - 1; k++) { 97 | int iv[2] = {k, k + 1}; 98 | elements[k].set(vertices, iv, 0); 99 | } 100 | 101 | int iv[1] = {0}; 102 | be(0).set(vertices, iv, 0); 103 | iv[0] = nx - 1; 104 | be(1).set(vertices, iv, 1); 105 | 106 | BuildBound(); 107 | BuildAdj(); 108 | } 109 | -------------------------------------------------------------------------------- /cpp/common/Mesh1dn.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CutFEM-Library. 3 | 4 | CutFEM-Library is free software: you can redistribute it and/or modify it under 5 | the terms of the GNU General Public License as published by the Free Software 6 | Foundation, either version 3 of the License, or (at your option) any later 7 | version. 8 | 9 | CutFEM-Library is distributed in the hope that it will be useful, but WITHOUT 10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License along with 14 | CutFEM-Library. If not, see 15 | */ 16 | /* 17 | 18 | This file is part of Freefem++ 19 | 20 | Freefem++ is free software; you can redistribute it and/or modify 21 | it under the terms of the GNU Lesser General Public License as published by 22 | the Free Software Foundation; either version 2.1 of the License, or 23 | (at your option) any later version. 24 | 25 | Freefem++ is distributed in the hope that it will be useful, 26 | but WITHOUT ANY WARRANTY; without even the implied warranty of 27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 28 | GNU Lesser General Public License for more details. 29 | 30 | You should have received a copy of the GNU Lesser General Public License 31 | along with Freefem++; if not, write to the Free Software 32 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 33 | */ 34 | #ifndef COMMON_MESH1DN_HPP_ 35 | #define COMMON_MESH1DN_HPP_ 36 | 37 | #include "GenericMesh.hpp" 38 | #include 39 | 40 | typedef GenericVertex Vertex1; 41 | 42 | // class SignPatternTrait1; 43 | class RefPatch2; 44 | // class RefPartition1; 45 | // class Partition1; 46 | 47 | class Mesh1 : public GenericMesh { 48 | public: 49 | // typedef SignPatternTrait1 SignPattern; 50 | typedef RefPatch2 RefPatch; 51 | // typedef RefPartition1 RefPartition; 52 | // typedef Partition1 Partition; 53 | 54 | Mesh1(int nx, R orx, R lx); // build structured mesh 55 | Mesh1(const char *); // 56 | const Element *Find(R1 P, R1 &Phat, bool &outside, 57 | const Element *tstart) const; 58 | 59 | private: 60 | int load(const std::string &filename); 61 | Mesh1(const Mesh1 &); // pas de construction par copie 62 | void operator=(const Mesh1 &); // pas affectation par copy 63 | }; 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /cpp/common/Mesh2dn.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CutFEM-Library. 3 | 4 | CutFEM-Library is free software: you can redistribute it and/or modify it under 5 | the terms of the GNU General Public License as published by the Free Software 6 | Foundation, either version 3 of the License, or (at your option) any later 7 | version. 8 | 9 | CutFEM-Library is distributed in the hope that it will be useful, but WITHOUT 10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License along with 14 | CutFEM-Library. If not, see 15 | */ 16 | /* 17 | 18 | This file is part of Freefem++ 19 | 20 | Freefem++ is free software; you can redistribute it and/or modify 21 | it under the terms of the GNU Lesser General Public License as published by 22 | the Free Software Foundation; either version 2.1 of the License, or 23 | (at your option) any later version. 24 | 25 | Freefem++ is distributed in the hope that it will be useful, 26 | but WITHOUT ANY WARRANTY; without even the implied warranty of 27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 28 | GNU Lesser General Public License for more details. 29 | 30 | You should have received a copy of the GNU Lesser General Public License 31 | along with Freefem++; if not, write to the Free Software 32 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 33 | */ 34 | 35 | #ifndef COMMON_MESH2DN_HPP_ 36 | #define COMMON_MESH2DN_HPP_ 37 | 38 | #include "dataStruct2D.hpp" 39 | #include "GenericMesh.hpp" 40 | #include 41 | 42 | class Mesh2 : public GenericMesh { 43 | public: 44 | static const int D = 2; 45 | 46 | Mesh2() : GenericMesh() {} 47 | Mesh2(const std::string filename, MeshFormat type_mesh); // build from mesh generated by Freefem 48 | Mesh2(int nx, int ny, R orx, R ory, R lx, R ly); // build structured mesh 49 | void init(int nx, int ny, R orx, R ory, R lx, R ly); // build structured mesh 50 | 51 | private: 52 | Mesh2(const Mesh2 &); // no copy constructor 53 | void operator=(const Mesh2 &); // no copy allowed 54 | 55 | void readMeshGmsh(std::ifstream &f); 56 | void readMeshFreefem(std::ifstream &f); 57 | 58 | friend Mesh2 refine(const Mesh2 &Th); 59 | friend Mesh2 refine_barycentric(const Mesh2 &Th); 60 | }; 61 | 62 | class MeshQuad2 : public GenericMesh { 63 | public: 64 | static const int D = 2; 65 | MeshQuad2(int nx, int ny, R orx, R ory, R lx, R ly); // build structured mesh 66 | 67 | private: 68 | MeshQuad2(const MeshQuad2 &); // no copy constructor 69 | void operator=(const MeshQuad2 &); // no copy allowed 70 | }; 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /cpp/common/Mesh3dn.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CutFEM-Library. 3 | 4 | CutFEM-Library is free software: you can redistribute it and/or modify it under 5 | the terms of the GNU General Public License as published by the Free Software 6 | Foundation, either version 3 of the License, or (at your option) any later 7 | version. 8 | 9 | CutFEM-Library is distributed in the hope that it will be useful, but WITHOUT 10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License along with 14 | CutFEM-Library. If not, see 15 | */ 16 | /* 17 | 18 | This file is part of Freefem++ 19 | 20 | Freefem++ is free software; you can redistribute it and/or modify 21 | it under the terms of the GNU Lesser General Public License as published by 22 | the Free Software Foundation; either version 2.1 of the License, or 23 | (at your option) any later version. 24 | 25 | Freefem++ is distributed in the hope that it will be useful, 26 | but WITHOUT ANY WARRANTY; without even the implied warranty of 27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 28 | GNU Lesser General Public License for more details. 29 | 30 | You should have received a copy of the GNU Lesser General Public License 31 | along with Freefem++; if not, write to the Free Software 32 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 33 | */ 34 | 35 | #ifndef COMMON_MESH3DN_HPP_ 36 | #define COMMON_MESH3DN_HPP_ 37 | 38 | #include 39 | #include "dataStruct3D.hpp" 40 | #include "GenericMesh.hpp" 41 | 42 | class Mesh3 : public GenericMesh { 43 | 44 | public: 45 | static const int D = 3; 46 | 47 | Mesh3() {} 48 | //Mesh3(const std::string); 49 | Mesh3(const std::string filename, MeshFormat type_mesh); 50 | Mesh3(int nnv, int nnt, int nnbe, Vertex3 *vv, Tet *tt, Triangle3 *bb); 51 | Mesh3(int nnv, int nnbe, Vertex3 *vv, Triangle3 *bb); // surface mesh 52 | Mesh3(int nx, int ny, int nz, R orx, R ory, R orz, R lx, R ly, R lz); 53 | 54 | private: 55 | void readmsh(std::ifstream &f); 56 | void readMeshGmsh(std::ifstream &f); 57 | 58 | Mesh3(const Mesh3 &); // pas de construction par copie 59 | void operator=(const Mesh3 &); // pas affectation par copy 60 | }; 61 | 62 | class MeshHexa : public GenericMesh { 63 | public: 64 | static const int D = 3; 65 | 66 | MeshHexa(int nx, int ny, int nz, R orx, R ory, R orz, R lx, R ly, 67 | R lz); // build structured mesh 68 | private: 69 | MeshHexa(const MeshHexa &); // no copy constructor 70 | void operator=(const MeshHexa &); // no copy allowed 71 | }; 72 | 73 | template void setLabelBorder(Mesh &Th, R3 normal, int newLabel) { 74 | typedef typename Mesh::Rd Rd; 75 | for (int ifac = 0; ifac < Th.nbe; ifac += 1) { 76 | // for( int ifac = Th.first_element(); ifac < Th.last_boundary_element(); 77 | // ifac+=Th.next_element()) { 78 | typename Mesh::BorderElement &face(Th.be(ifac)); 79 | int ifaceK; // index of face of triangle corresp to edge (0,1,2) 80 | const int k = Th.BoundaryElement(ifac, 81 | ifaceK); // index of element (triangle), ifaceK gets modified inside 82 | 83 | int ib = ifaceK; 84 | if (Th.ElementAdj(k, ib) != -1) 85 | continue; // not on the boundary. Because mesh built with buildlayers 86 | // in freefem++ 87 | 88 | const typename Mesh::Element &T(Th[k]); 89 | Rd normal_ext = T.N(ifaceK); 90 | 91 | Rd diff_normal(normal - normal_ext); 92 | if (diff_normal.norm() < 1e-15) { 93 | face.lab = newLabel; 94 | } 95 | } 96 | } 97 | 98 | typedef Mesh3 MeshT3; 99 | typedef MeshHexa MeshQ3; 100 | 101 | #endif 102 | -------------------------------------------------------------------------------- /cpp/common/RNM_op.hpp: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | 4 | This file is part of Freefem++ 5 | 6 | Freefem++ is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | 11 | Freefem++ is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public License 17 | along with Freefem++; if not, write to the Free Software 18 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | template KN_ &KN_::operator oper(const Mul_KNM_KN_ &u) { 22 | assert(SameShape(u.A.shapei) && !constant()); 23 | R *l(v); 24 | KN_ li(u.A(0, '.')); // first line 25 | for (long i = 0; i < n; i++, l += step, ++li) 26 | *l oper(li, u.b); 27 | return *this; 28 | } 29 | 30 | template KN_ &KN_::operator oper(const Add_KN_ &u) { 31 | assert(u.a.N() == N()); 32 | long stepa(u.a.step), stepb(u.b.step); 33 | R *l(v); 34 | R *aa(u.a), *bb(u.b); 35 | for (long i = 0; i < n; i++, l += step, aa += stepa, bb += stepb) 36 | *l oper *aa + *bb; 37 | return *this; 38 | } 39 | 40 | template KN_ &KN_::operator oper(const DotMul_KN_ &u) { 41 | assert(u.a.N() == N()); 42 | long stepa(u.a.step), stepb(u.b.step); 43 | R *l(v); 44 | R *aa(u.a), *bb(u.b); 45 | for (long i = 0; i < n; i++, l += step, aa += stepa, bb += stepb) 46 | *l oper(*aa) * (*bb); 47 | return *this; 48 | } 49 | 50 | template KN_ &KN_::operator oper(const Sub_KN_ &u) { 51 | assert(u.a.N() == N()); 52 | long stepa(u.a.step), stepb(u.b.step); 53 | R *l(v); 54 | R *aa(u.a), *bb(u.b); 55 | for (long i = 0; i < n; i++, l += step, aa += stepa, bb += stepb) 56 | *l oper *aa - *bb; 57 | return *this; 58 | } 59 | 60 | template KN_ &KN_::operator oper(const Mulc_KN_ &u) { 61 | assert(u.a.N() == N()); 62 | long stepa(u.a.step); 63 | R *l(v); 64 | R *aa(u.a), bb(u.b); 65 | for (long i = 0; i < n; i++, l += step, aa += stepa) 66 | *l oper *aa *bb; 67 | return *this; 68 | } 69 | 70 | template KN_ &KN_::operator oper(const Add_Mulc_KN_ &u) { 71 | assert(u.a.N() == N()); 72 | const long stepa(u.a.step), stepb(u.b.step); 73 | const R ca(u.ca), cb(u.cb); 74 | R *l(v); 75 | const R *aa(u.a), *bb(u.b); 76 | for (long i = 0; i < n; i++, l += step, aa += stepa, bb += stepb) 77 | *l oper *aa *ca + *bb *cb; 78 | return *this; 79 | } 80 | -------------------------------------------------------------------------------- /cpp/common/RNM_opc.hpp: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | 4 | This file is part of Freefem++ 5 | 6 | Freefem++ is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU Lesser General Public License as published by 8 | the Free Software Foundation; either version 2.1 of the License, or 9 | (at your option) any later version. 10 | 11 | Freefem++ is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public License 17 | along with Freefem++; if not, write to the Free Software 18 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | template inline KN_ &KN_::operator oper(R a) { 21 | R *l(v); 22 | for (long i = 0; i < n; i++, l += step) 23 | *l oper a; 24 | return *this; 25 | } 26 | 27 | template inline KNM_ &KNM_::operator oper(R a) { 28 | if (IsVector1()) 29 | KN_::operator oper(a); 30 | else { 31 | KN_ lj(operator()('.', 0)); // (.,.,O) 32 | for (long j = 0; j < M(); ++j, ++lj) 33 | lj oper a; 34 | } 35 | return *this; 36 | } 37 | 38 | template inline KNMK_ &KNMK_::operator oper(R a) { 39 | if (IsVector1()) 40 | KN_::operator oper(a); 41 | else { 42 | KNM_ lj(operator()('.', '.', 0)); // (.,.,O) 43 | long j = K(); 44 | while (j--) { 45 | lj oper a; 46 | ++lj; 47 | } 48 | } 49 | return *this; 50 | } 51 | 52 | template inline KN_ &KN_::operator oper(const KN_ &u) { 53 | assert(u.n == n); 54 | R *l(v); 55 | const R *r(u); 56 | for (long i = 0; i < n; i++, l += step, r += u.step) 57 | *l oper *r; 58 | return *this; 59 | } 60 | 61 | template inline KNM_ &KNM_::operator oper(const KNM_ &u) { 62 | assert(N() == u.N() && M() == u.M()); 63 | if (IsVector1() && u.IsVector1() && 64 | shapei.step == u.shapei.step) // modif 2011 (thank to Oka) 65 | KN_::operator oper(u); // modif FH jan 2004 66 | else { 67 | KN_ lj(operator()('.', 0)); // (.,O) 68 | KN_ uj(u('.', 0)); 69 | long j = M(); 70 | while (j--) { 71 | lj oper uj; 72 | ++lj; 73 | ++uj; 74 | } 75 | } 76 | return *this; 77 | } 78 | 79 | template inline KNMK_ &KNMK_::operator oper(const KNMK_ &u) { 80 | assert(N() == u.N() && M() == u.M() && K() == u.K()); 81 | 82 | if (IsVector1() && u.IsVector1() && u.N() == N() && 83 | shapei.step == u.shapei.step) // modif 2011 (thank to Oka) 84 | KN_::operator oper(u); // modif FH 2004 85 | else { 86 | assert(K() == u.K()); 87 | KNM_ lj(operator()('.', '.', 0)); // (.,O) 88 | KNM_ uj(u('.', '.', 0)); 89 | long j = K(); 90 | while (j--) { 91 | lj oper uj; 92 | ++lj; 93 | ++uj; 94 | } 95 | } 96 | return *this; 97 | } 98 | 99 | #undef oper 100 | -------------------------------------------------------------------------------- /cpp/common/base_interface.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "base_interface.hpp" 3 | -------------------------------------------------------------------------------- /cpp/common/cut_mesh.cpp: -------------------------------------------------------------------------------- 1 | #include "time_interface.hpp" 2 | #include "cut_mesh.hpp" 3 | -------------------------------------------------------------------------------- /cpp/common/dataStruct1D.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CutFEM-Library. 3 | 4 | CutFEM-Library is free software: you can redistribute it and/or modify it under 5 | the terms of the GNU General Public License as published by the Free Software 6 | Foundation, either version 3 of the License, or (at your option) any later 7 | version. 8 | 9 | CutFEM-Library is distributed in the hope that it will be useful, but WITHOUT 10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License along with 14 | CutFEM-Library. If not, see 15 | */ 16 | 17 | /* 18 | 19 | This file is part of Freefem++ 20 | 21 | Freefem++ is free software; you can redistribute it and/or modify 22 | it under the terms of the GNU Lesser General Public License as published by 23 | the Free Software Foundation; either version 2.1 of the License, or 24 | (at your option) any later version. 25 | 26 | Freefem++ is distributed in the hope that it will be useful, 27 | but WITHOUT ANY WARRANTY; without even the implied warranty of 28 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 29 | GNU Lesser General Public License for more details. 30 | 31 | You should have received a copy of the GNU Lesser General Public License 32 | along with Freefem++; if not, write to the Free Software 33 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 34 | */ 35 | 36 | #include "dataStruct1D.hpp" 37 | 38 | const std::vector R1::KHat = {R1(0.), R1(1.)}; 39 | 40 | /// @brief Static mumber for Point1 41 | template <> 42 | const std::vector> GenericElement::nvedge = {{}}; 43 | template <> 44 | const std::vector> GenericElement::nvface = {{}}; 45 | template <> 46 | const std::vector> GenericElement::nvhyperFace = { 47 | {}}; 48 | template <> 49 | const std::vector> GenericElement::edgeOfFace = { 50 | {}}; 51 | template <> 52 | const std::vector> GenericElement::faceOfEdge = { 53 | {}}; 54 | template <> 55 | const std::vector> 56 | GenericElement::commonVertOfEdges = {{}}; 57 | 58 | /// @brief Static mumber for Seg1 59 | template <> 60 | const std::vector> GenericElement::nvedge = {{0, 1}}; 61 | template <> 62 | const std::vector> GenericElement::nvface{{}}; 63 | template <> 64 | const std::vector> GenericElement::nvhyperFace = { 65 | {0}, {1}}; 66 | template <> 67 | const std::vector> GenericElement::edgeOfFace = {{}}; 68 | template <> 69 | const std::vector> GenericElement::faceOfEdge = {{}}; 70 | template <> 71 | const std::vector> 72 | GenericElement::commonVertOfEdges = {{}}; 73 | -------------------------------------------------------------------------------- /cpp/common/geometry.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CutFEM-Library. 3 | 4 | CutFEM-Library is free software: you can redistribute it and/or modify it under 5 | the terms of the GNU General Public License as published by the Free Software 6 | Foundation, either version 3 of the License, or (at your option) any later 7 | version. 8 | 9 | CutFEM-Library is distributed in the hope that it will be useful, but WITHOUT 10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License along with 14 | CutFEM-Library. If not, see 15 | */ 16 | #include "geometry.hpp" 17 | 18 | double geometry::measure_hyper_simplex(R2 N[2]) { 19 | R2 u(N[0], N[1]); 20 | return u.norm(); 21 | } 22 | double geometry::measure_hyper_simplex(R3 N[3]) { 23 | 24 | R3 u(N[0], N[1]); 25 | R3 v(N[0], N[2]); 26 | return Norme2(0.5 * (u ^ v)); 27 | } 28 | 29 | template <> double geometry::mesure_simplex<1>(R2 N[2]) { 30 | return measure_hyper_simplex(N); 31 | } 32 | template <> double geometry::mesure_simplex<2>(R2 N[3]) { 33 | return std::fabs(det(N[0], N[1], N[2])) * 0.5; 34 | } 35 | 36 | template <> double geometry::mesure_simplex<1>(R3 N[2]) { 37 | R3 u(N[0], N[1]); 38 | return u.norm(); 39 | } 40 | template <> double geometry::mesure_simplex<2>(R3 N[3]) { 41 | return measure_hyper_simplex(N); 42 | } 43 | template <> double geometry::mesure_simplex<3>(R3 N[4]) { 44 | R3 AB(N[0], N[1]); 45 | R3 AC(N[0], N[2]); 46 | R3 AD(N[0], N[3]); 47 | return std::fabs(det(AB, AC, AD)) / 6.; 48 | } 49 | 50 | R2 geometry::map_point_to_simplex(const R2 N[3], const R2 Phat) { 51 | R2 P = (1 - Phat.sum()) * N[0] + Phat[0] * N[1] + Phat[1] * N[2]; 52 | return P; 53 | } 54 | R3 geometry::map_point_to_simplex(const R3 N[4], const R3 Phat) { 55 | R3 P = (1 - Phat.sum()) * N[0] + Phat[0] * N[1] + Phat[1] * N[2] + 56 | Phat[2] * N[3]; 57 | return P; 58 | } 59 | 60 | R2 geometry::map_point_to_simplex(const R2 N[2], const R1 Phat) { 61 | R2 P = (1 - Phat[0]) * N[0] + Phat[0] * N[1]; 62 | return P; 63 | } 64 | R3 geometry::map_point_to_simplex(const R3 N[3], const R2 Phat) { 65 | 66 | R3 P = (1 - Phat.sum()) * N[0] + Phat[0] * N[1] + Phat[1] * N[2]; 67 | return P; 68 | } 69 | 70 | template <> bool geometry::Segment::is_between(const R2 C) const { 71 | assert(0); 72 | return true; 73 | } 74 | 75 | geometry::Droite geometry::equation(const R2 a, const R2 b) { 76 | Droite d; 77 | if (!(b.x - a.x)) 78 | d.pente = b.x; 79 | else 80 | d.pente = (b.y - a.y) / (b.x - a.x); 81 | d.ord_or = a.y - a.x * d.pente; 82 | return d; 83 | } 84 | 85 | bool geometry::p_boncote(const R2 a, const R2 b, const R2 c, const R2 p) { 86 | // teste si la droite est perpendiculaire à l'axe des abcisses 87 | // et retourne le resultat en conséquence 88 | 89 | if (a.x == b.x) { 90 | return ((p.x - a.x) * (c.x - a.x) >= -globalVariable::Epsilon); 91 | } 92 | 93 | Droite d; 94 | d = equation(a, b); 95 | return ((d.pente * c.x + d.ord_or - c.y) * 96 | (d.pente * p.x + d.ord_or - p.y) >= 97 | -globalVariable::Epsilon); 98 | } 99 | bool geometry::p_dans_triangle(const typename Mesh2::Element &K, const R2 P) { 100 | return ((p_boncote(K[0], K[1], K[2], P)) && 101 | (p_boncote(K[2], K[1], K[0], P)) && 102 | (p_boncote(K[0], K[2], K[1], P))); 103 | } 104 | bool geometry::p_dans_triangle(const R2 P, R2 a, R2 b, R2 c) { 105 | return ((p_boncote(a, b, c, P)) && (p_boncote(c, b, a, P)) && 106 | (p_boncote(a, c, b, P))); 107 | } 108 | int geometry::find_triangle_contenant_p(const Mesh2 &Th, const R2 P, 109 | int k_init) { 110 | 111 | int idx_elt = k_init; 112 | int count = 0; 113 | 114 | // std::ofstream plot; 115 | // plot.open("node.dat", std::ofstream::out); 116 | // plot<< P << std::endl; 117 | // plot.close(); 118 | // plot.open("searchElement.dat", std::ofstream::out); 119 | while (!p_dans_triangle(Th[idx_elt], P)) { 120 | 121 | const typename Mesh2::Element &K(Th[idx_elt]); 122 | // passe au triangle voisin qui est dans la "direction" de p 123 | // première arête 124 | 125 | int iface; 126 | if (!p_boncote(K[0], K[1], K[2], P)) { 127 | iface = 2; 128 | } else { 129 | if (!p_boncote(K[1], K[2], K[0], P)) { 130 | iface = 0; 131 | } else { 132 | iface = 1; 133 | } 134 | } 135 | idx_elt = Th.ElementAdj(idx_elt, iface); 136 | } 137 | return idx_elt; 138 | } 139 | -------------------------------------------------------------------------------- /cpp/common/geometry.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CutFEM-Library. 3 | 4 | CutFEM-Library is free software: you can redistribute it and/or modify it under 5 | the terms of the GNU General Public License as published by the Free Software 6 | Foundation, either version 3 of the License, or (at your option) any later 7 | version. 8 | 9 | CutFEM-Library is distributed in the hope that it will be useful, but WITHOUT 10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License along with 14 | CutFEM-Library. If not, see 15 | */ 16 | #ifndef COMMON_GEOMETRY_HPP 17 | #define COMMON_GEOMETRY_HPP 18 | 19 | #include "Mesh2dn.hpp" 20 | 21 | namespace geometry { 22 | 23 | template struct Segment { 24 | Rd A; 25 | Rd B; 26 | 27 | Segment(Rd a, Rd b) : A(a), B(b) {} 28 | bool is_between(const Rd C) const; 29 | }; 30 | 31 | // equation cartesienne d'une droite 32 | typedef struct coefDroite { 33 | double pente; 34 | double ord_or; 35 | } Droite; 36 | 37 | struct Interval { 38 | double v_min, v_max; 39 | Interval(double a, double b) : v_min(a), v_max(b) {} 40 | Interval operator*(double x) const { return Interval(x * v_min, x * v_max); } 41 | Interval operator+(double x) const { return Interval(x + v_min, x + v_max); } 42 | }; 43 | 44 | Droite equation(const R2 a, const R2 b); 45 | bool p_boncote(const R2 a, const R2 b, const R2 c, const R2 p); 46 | bool p_dans_triangle(const typename Mesh2::Element &K, const R2 P); 47 | bool p_dans_triangle(const R2 P, R2 a, R2 b, R2 c); 48 | int find_triangle_contenant_p(const Mesh2 &Th, const R2 P, int k_init = 0); 49 | 50 | R3 map_point_to_simplex(const R3 N[4], const R3 P); 51 | R2 map_point_to_simplex(const R2 N[3], const R2 P); 52 | // maps to face simplex 53 | R3 map_point_to_simplex(const R3 N[3], const R2 P); 54 | R2 map_point_to_simplex(const R2 N[2], const R1 P); 55 | 56 | R measure_hyper_simplex(R2 N[2]); 57 | R measure_hyper_simplex(R3 N[3]); 58 | 59 | // change to template maybe 60 | template R mesure_simplex(R2 N[d + 1]); 61 | template R mesure_simplex(R3 N[d + 1]); 62 | } // namespace geometry 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /cpp/common/global.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CutFEM-Library. 3 | 4 | CutFEM-Library is free software: you can redistribute it and/or modify it under 5 | the terms of the GNU General Public License as published by the Free Software 6 | Foundation, either version 3 of the License, or (at your option) any later 7 | version. 8 | 9 | CutFEM-Library is distributed in the hope that it will be useful, but WITHOUT 10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License along with 14 | CutFEM-Library. If not, see 15 | */ 16 | #include "global.hpp" 17 | 18 | int globalVariable::verbose = 1; 19 | double globalVariable::UnSetMesure = -1e+200; 20 | double globalVariable::Epsilon = 21 | 1e-13; // * std::numeric_limits::epsilon(); 22 | double globalVariable::DoubleEpsC = 1e-9; 23 | double globalVariable::Pi = 3.14159265359; 24 | double globalVariable::pi = 3.14159265359; 25 | -------------------------------------------------------------------------------- /cpp/common/global.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CutFEM-Library. 3 | 4 | CutFEM-Library is free software: you can redistribute it and/or modify it under 5 | the terms of the GNU General Public License as published by the Free Software 6 | Foundation, either version 3 of the License, or (at your option) any later 7 | version. 8 | 9 | CutFEM-Library is distributed in the hope that it will be useful, but WITHOUT 10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License along with 14 | CutFEM-Library. If not, see 15 | */ 16 | #ifndef COMMON_GLOBAL_HPP 17 | #define COMMON_GLOBAL_HPP 18 | 19 | // #include 20 | namespace globalVariable { 21 | extern int verbose; 22 | extern double UnSetMesure; 23 | extern double DoubleEpsC; 24 | extern double Epsilon; 25 | extern double Pi; 26 | extern double pi; 27 | 28 | }; // namespace globalVariable 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /cpp/common/interface_levelSet.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CutFEM-Library. 3 | 4 | CutFEM-Library is free software: you can redistribute it and/or modify it under 5 | the terms of the GNU General Public License as published by the Free Software 6 | Foundation, either version 3 of the License, or (at your option) any later 7 | version. 8 | 9 | CutFEM-Library is distributed in the hope that it will be useful, but WITHOUT 10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License along with 14 | CutFEM-Library. If not, see 15 | */ 16 | #include "interface_levelSet.hpp" 17 | 18 | template <> 19 | void InterfaceLevelSet::cut_partition( 20 | Physical_Partition &local_partition, 21 | std::vector &new_element_idx, std::list &erased_element, 22 | int sign_part) const { 23 | new_element_idx.resize(0); 24 | erased_element.resize(0); 25 | byte ls[3]; 26 | const Element &T(local_partition.T); 27 | int kb = (*this->backMesh)(T); 28 | for (int k = 0; k < local_partition.nb_element(0); 29 | ++k) { // 0 is just useless. Not needed by this class 30 | 31 | // BUILD ELEMENT 32 | const CutElement K = local_partition.get_element(k); 33 | assert(0); 34 | // The fun should be given in input. Don't wanna save it in the class 35 | // for(int i=0;i<3;++i) ls[i] = util::sign(fun.eval(kb, K[i])); 36 | 37 | // COMPUTE THE PARTITION 38 | const RefPartition &patch( 39 | RefPartition::instance(ls)); 40 | 41 | // interface i CUT THIS LOCAL ELEMENT k 42 | if (patch.is_cut()) { 43 | erased_element.push_back(k); 44 | 45 | // LOOP OVER ELEMENTS IN PATCH 46 | // need to get only the part corresponding to the sign 47 | for (auto it = patch.element_begin(); it != patch.element_end(); 48 | ++it) { 49 | 50 | // if(patch.whatSign(it) != sign_part && patch.whatSign(it) != 0) 51 | // continue; 52 | if (patch.whatSign(it) != sign_part) 53 | continue; 54 | 55 | // create the Nodes 56 | // std::cout << " index node to create " << std::endl; 57 | int idx_begin = local_partition.nb_node(); 58 | ElementIdx idx_array(idx_begin, idx_begin + 1, idx_begin + 2); 59 | for (int i = 0; i < 3; ++i) { 60 | Uint idx = (*it)[i]; 61 | // std::cout << idx << std::endl; 62 | // 63 | if (idx < 3) { 64 | local_partition.add_node(K[idx]); 65 | // std::cout << K[idx] << std::endl; 66 | 67 | } else { 68 | int i0 = Triangle2::nvedge[idx - 3][0]; 69 | int i1 = Triangle2::nvedge[idx - 3][1]; 70 | assert(0); 71 | // Here we should give the function so we dont need it in the 72 | // class Interface. 73 | // local_partition.add_node(get_intersection_node(kb,K[i0], 74 | // K[i1])); 75 | } 76 | } 77 | // ADD THE INDICES 78 | new_element_idx.push_back(idx_array); 79 | } 80 | 81 | // std::cout << " local element " << k << " is cut" << std::endl; 82 | } 83 | 84 | else { 85 | // std::cout << " local element " << k << " is not cut" << std::endl; 86 | // has to be removed if not in domain 87 | if (patch.whatSign() != sign_part) { 88 | erased_element.push_back(k); 89 | }; 90 | } 91 | } 92 | } 93 | 94 | template <> bool InterfaceLevelSet::isCutFace(int k, int ifac) const { 95 | 96 | for (int e = 0; e < Element::Face::ne; ++e) { 97 | int id_edge = Element::edgeOfFace[ifac][e]; 98 | int i1 = Element::nvedge[id_edge][0]; 99 | int i2 = Element::nvedge[id_edge][1]; 100 | if (ls_[this->backMesh->at(k, i1)] * ls_[this->backMesh->at(k, i2)] < 0) 101 | return true; 102 | } 103 | return false; 104 | } 105 | 106 | template <> bool InterfaceLevelSet::isCutFace(int k, int ifac) const { 107 | int i1 = Element::nvedge[ifac][0]; 108 | int i2 = Element::nvedge[ifac][1]; 109 | if (ls_[this->backMesh->at(k, i1)] * ls_[this->backMesh->at(k, i2)] < 0) 110 | return true; 111 | return false; 112 | } 113 | 114 | template <> bool InterfaceLevelSet::isCutFace(int k, int ifac) const { 115 | for (int e = 0; e < Element::Face::ne; ++e) { 116 | int id_edge = Element::edgeOfFace[ifac][e]; 117 | int i1 = Element::nvedge[id_edge][0]; 118 | int i2 = Element::nvedge[id_edge][1]; 119 | if (ls_[this->backMesh->at(k, i1)] * ls_[this->backMesh->at(k, i2)] < 0) 120 | return true; 121 | } 122 | return false; 123 | } 124 | 125 | template <> 126 | bool InterfaceLevelSet::isCutFace(int k, int ifac) const { 127 | int i1 = Element::nvedge[ifac][0]; 128 | int i2 = Element::nvedge[ifac][1]; 129 | if (ls_[this->backMesh->at(k, i1)] * ls_[this->backMesh->at(k, i2)] < 0) 130 | return true; 131 | return false; 132 | } 133 | -------------------------------------------------------------------------------- /cpp/common/logger.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CutFEM-Library. 3 | 4 | CutFEM-Library is free software: you can redistribute it and/or modify it under 5 | the terms of the GNU General Public License as published by the Free Software 6 | Foundation, either version 3 of the License, or (at your option) any later 7 | version. 8 | 9 | CutFEM-Library is distributed in the hope that it will be useful, but WITHOUT 10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License along with 14 | CutFEM-Library. If not, see 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include "logger.hpp" 27 | 28 | CutFEMLogger &operator<<(CutFEMLogger &logger, const std::string &message) { 29 | if (message == logger::endl) { 30 | logger.flushMessage(); 31 | } else { 32 | logger.addMessage(message); 33 | } 34 | return logger; 35 | } 36 | 37 | CutFEMLogger &LOG(const Severity severity) { return CutFEMLogger::get()(severity); } 38 | 39 | CutFEMLogger &LOG(int line, const char *source_file, const Severity severity) { 40 | return CutFEMLogger::get()(line, source_file, severity); 41 | } 42 | -------------------------------------------------------------------------------- /cpp/common/parametrization.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CutFEM-Library. 3 | 4 | CutFEM-Library is free software: you can redistribute it and/or modify it under 5 | the terms of the GNU General Public License as published by the Free Software 6 | Foundation, either version 3 of the License, or (at your option) any later 7 | version. 8 | 9 | CutFEM-Library is distributed in the hope that it will be useful, but WITHOUT 10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License along with 14 | CutFEM-Library. If not, see 15 | */ 16 | #include "parametrization.hpp" 17 | 18 | LinearParametrization::LinearParametrization(const std::vector &x, 19 | const std::vector &y) { 20 | this->init(x, y); 21 | } 22 | 23 | void LinearParametrization::init(const std::vector &x, 24 | const std::vector &y) { 25 | 26 | int n = x.size() - 1; 27 | nb_interval = n; 28 | 29 | std::vector b(n); 30 | for (int i = 1; i < n; ++i) 31 | b[i] = (y[i + 1] - y[i]) / (x[i + 1] - x[i]); 32 | 33 | myLineSet = new LineSet[n]; 34 | for (int i = 0; i < n; ++i) { 35 | mySplineSet[i].a = y[i]; 36 | mySplineSet[i].b = b[i]; 37 | mySplineSet[i].x = x[i]; 38 | } 39 | return; 40 | } 41 | std::vector 42 | -------------------------------------------------------------------------------- /cpp/common/parametrization.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CutFEM-Library. 3 | 4 | CutFEM-Library is free software: you can redistribute it and/or modify it under 5 | the terms of the GNU General Public License as published by the Free Software 6 | Foundation, either version 3 of the License, or (at your option) any later 7 | version. 8 | 9 | CutFEM-Library is distributed in the hope that it will be useful, but WITHOUT 10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License along with 14 | CutFEM-Library. If not, see 15 | */ 16 | #ifndef COMMON_PARAMETRIZATION_HPP 17 | #define COMMON_PARAMETRIZATION_HPP 18 | 19 | class CurveParametrization { 20 | 21 | public: 22 | virtual R2 evalutate(double t) const = 0; 23 | virtual R2 evalutate(int i, double t) const = 0; 24 | }; 25 | 26 | class LinearParametrization : public CurveParametrization { 27 | 28 | public: 29 | int nb_interval; 30 | 31 | struct LineSet { 32 | double a; // constant 33 | double b; // 1st order coefficient 34 | double x; // starting x value 35 | }; 36 | 37 | LineSet *myLineSet; 38 | LinearParametrization(const std::vector &x, 39 | const std::vector &y); 40 | void init(const std::vector &x, const std::vector &y); 41 | 42 | ~LinearParametrization() { delete[] myLineSet; } 43 | 44 | private: 45 | LinearParametrization(const LinearParametrization &); 46 | void operator=(const LinearParametrization &); 47 | }; 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /cpp/common/spline.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CutFEM-Library. 3 | 4 | CutFEM-Library is free software: you can redistribute it and/or modify it under 5 | the terms of the GNU General Public License as published by the Free Software 6 | Foundation, either version 3 of the License, or (at your option) any later 7 | version. 8 | 9 | CutFEM-Library is distributed in the hope that it will be useful, but WITHOUT 10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License along with 14 | CutFEM-Library. If not, see 15 | */ 16 | #ifndef COMMON_SPLINE_HPP 17 | #define COMMON_SPLINE_HPP 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include "R2.hpp" 25 | #include "parametrization.hpp" 26 | 27 | class Spline2D; 28 | 29 | // A 2D cubic spline 30 | class Spline { 31 | public: 32 | Spline(){}; 33 | Spline(const vector &x, const vector &y); 34 | 35 | private: 36 | // The fitted points 37 | vector X; 38 | vector Y; 39 | 40 | /// The coefficients of the spline curve between two points 41 | struct SplineSet { 42 | double a; // constant 43 | double b; // 1st order coefficient 44 | double c; // 2nd order coefficient 45 | double d; // 3rd order coefficient 46 | double x; // starting x value 47 | void print() const { 48 | std::cout << " x_0 = " << x << std::endl; 49 | std::cout << "p(x) = " << a << " + " << b << "x + " << c << "x^2 + " 50 | << d << "x^3 " << std::endl; 51 | } 52 | }; 53 | 54 | // The coefficients of the spline curves between all points 55 | SplineSet *mySplineSet; 56 | 57 | void init(const vector &x, const vector &y); 58 | 59 | public: 60 | /** Get the Y value of the spline curves for a particular X 61 | input x 62 | return the y value 63 | */ 64 | double evaluate(const double) const; 65 | double evaluate(int i, const double) const; 66 | 67 | double operator()(const double a) const { return evaluate(a); } 68 | /* Compute the y value of the spline derivative for a particular x 69 | input x 70 | return the value y of the diff in x 71 | */ 72 | double diff(const double) const; 73 | double ddiff(const double) const; 74 | /* Write in a file the spline to display it with gnuplot 75 | input N: number of points between two points of the set 76 | input filename: the files in which the solution is written 77 | output err: error in the computation or not 78 | */ 79 | int gnuplot(int, string); 80 | friend void display_spline2d(const Spline &, const Spline &, string, int); 81 | friend class Spline2D; 82 | ~Spline() { delete[] mySplineSet; } 83 | 84 | private: 85 | Spline(const Spline &); 86 | void operator=(const Spline &); 87 | }; 88 | 89 | class Spline2D : public CurveParametrization { 90 | 91 | Spline splineX; 92 | Spline splineY; 93 | 94 | int nb_node; 95 | 96 | public: 97 | Spline2D(const vector &t, const vector &x, 98 | const vector &y) 99 | : splineX(t, x), splineY(t, y) { 100 | nb_node = t.size(); 101 | assert((x.size() == nb_node) && (y.size() == nb_node)); 102 | } 103 | Spline2D(const vector &t, const vector &x); 104 | 105 | public: 106 | R2 evaluate(double t) const; 107 | R2 evaluate(int i, double t) const; 108 | int gnuplot(int, string); 109 | 110 | // ~Spline2D(){delete []splineX; delete splineY;} 111 | private: 112 | Spline2D(const Spline2D &); 113 | void operator=(const Spline2D &); 114 | }; 115 | 116 | void display_spline2d(const Spline &, const Spline &, string, int = 10); 117 | 118 | #endif 119 | -------------------------------------------------------------------------------- /cpp/common/time_interface.hpp: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | This file is part of CutFEM-Library. 4 | 5 | CutFEM-Library is free software: you can redistribute it and/or modify it under 6 | the terms of the GNU General Public License as published by the Free Software 7 | Foundation, either version 3 of the License, or (at your option) any later 8 | version. 9 | 10 | CutFEM-Library is distributed in the hope that it will be useful, but WITHOUT 11 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 12 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License along with 15 | CutFEM-Library. If not, see 16 | */ 17 | 18 | #ifndef COMMON_BASE_TIME_INTERFACE_HPP_ 19 | #define COMMON_BASE_TIME_INTERFACE_HPP_ 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include "../concept/function.hpp" 26 | #include "interface_levelSet.hpp" 27 | #include "AlgoimInterface.hpp" 28 | 29 | template class TimeInterface { 30 | public: 31 | using interface_t = Interface; 32 | using mesh_t = Mesh; 33 | 34 | private: 35 | std::vector> interface_; 36 | int n_; 37 | const QuadratureFormular1d *time_quadrature_; 38 | 39 | public: 40 | TimeInterface(const QuadratureFormular1d &qTime) : interface_(qTime.n), n_(qTime.n), time_quadrature_(&qTime) {} 41 | 42 | TimeInterface(const QuadratureFormular1d *qTime) : interface_(qTime->n), n_(qTime->n), time_quadrature_(qTime) {} 43 | 44 | TimeInterface(int nt) : interface_(nt), n_(nt), time_quadrature_(Lobatto(exactLobatto_nPt(nt))) {} 45 | 46 | /// @brief Copy constructor is removed 47 | TimeInterface(const TimeInterface &) = delete; 48 | 49 | /// @brief Assigment is removed 50 | void operator=(const TimeInterface &) = delete; 51 | 52 | /// @brief Move constructor 53 | TimeInterface(TimeInterface &&v) = default; 54 | 55 | /// @brief Move assignment 56 | TimeInterface &operator=(TimeInterface &&v) = default; 57 | 58 | /// @brief Destructor 59 | ~TimeInterface() = default; 60 | 61 | template void init(int i, const Mesh &Th, const Fct &ls) { 62 | assert(0 <= i && i < n_); 63 | if constexpr (typeFunFEM) { 64 | interface_[i] = std::make_unique>(Th, ls); 65 | } else { 66 | interface_[i] = std::make_unique>(Th, ls); 67 | } 68 | } 69 | // template void init(const Mesh &Th, const KN &ls); 70 | // { 71 | // assert(n_ == ls.size()); 72 | // for (int i = 0; i < n_; ++i) { 73 | // // interface_[i] = std::make_unique(Th, ls[i]); 74 | // if constexpr (typeFunFEM) { 75 | // interface_[i] = std::make_unique < InterfaceLevelset(Th, ls[i]); 76 | // } else { 77 | // interface_[i] = std::make_unique < AlgoimInterface(Th, ls[i]); 78 | // } 79 | // } 80 | // } 81 | 82 | interface_t *operator[](int i) const { 83 | assert(0 <= i && i < n_); 84 | return interface_[i].get(); 85 | } 86 | interface_t *operator()(int i) const { 87 | assert(0 <= i && i < n_); 88 | return interface_[i].get(); 89 | } 90 | 91 | int size() const { return n_; } 92 | const QuadratureFormular1d *get_quadrature_time() const { return time_quadrature_; } 93 | 94 | const std::vector> &interface() const { return interface_; } 95 | }; 96 | #endif -------------------------------------------------------------------------------- /cpp/cutfem.hpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include "concept/function.hpp" 19 | 20 | #include "parallel/cfmpi.hpp" 21 | #include "parallel/cfomp.hpp" 22 | 23 | #include "common/global.hpp" 24 | #include "common/Mesh3dn.hpp" 25 | #include "common/time_interface.hpp" 26 | #include "common/logger.hpp" 27 | 28 | #include "num/DA.hpp" 29 | #include "num/print_container.hpp" 30 | #include "num/util.hpp" 31 | #include "num/matlab.hpp" 32 | 33 | #include "FESpace/expression.hpp" 34 | #include "FESpace/integrationFunFEM.hpp" 35 | #include "FESpace/paraview.hpp" 36 | #include "FESpace/funfem_util.hpp" 37 | 38 | #include "solver/solver.hpp" 39 | 40 | #include "problem/baseProblem.hpp" 41 | #include "problem/generalNorm.hpp" 42 | #include "problem/projection.hpp" 43 | #include "problem/solver_advection.hpp" 44 | #include "problem/solver_curvature.hpp" 45 | #include "problem/solver_stokes.hpp" 46 | #include "problem/time_scheme.hpp" 47 | 48 | -------------------------------------------------------------------------------- /cpp/example/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | find_package(PYTHON) 3 | 4 | message(${CMAKE_SOURCE_DIR}) 5 | 6 | function(add_example FULL_NAME) 7 | get_filename_component(EXE_NAME ${FULL_NAME} NAME_WLE ) 8 | add_executable(${EXE_NAME} ${FULL_NAME}) 9 | target_link_libraries(${EXE_NAME} PRIVATE cutfem ${PYTHON_LIBRARIES}) 10 | target_include_directories(${EXE_NAME} PRIVATE ${CMAKE_CURRENT_BINARY_DIR} 11 | ${CMAKE_SOURCE_DIR} 12 | ${PYTHON_INCLUDES}) 13 | endfunction() 14 | 15 | add_example(meshing.cpp) 16 | 17 | add_example(hyberbolic_conservation_law/DG_CutFEM_ex_1.cpp) 18 | add_example(hyberbolic_conservation_law/DG_CutFEM_ex_2.cpp) 19 | 20 | add_example(hyberbolic_conservation_law/limiter_smooth_solution.cpp) 21 | add_example(hyberbolic_conservation_law/limiter_accuracy_conservation_test.cpp) 22 | add_example(hyberbolic_conservation_law/limiter_non_smooth_initial_data.cpp) 23 | 24 | 25 | add_example(darcy_fictitious/DF_example1.cpp) 26 | 27 | 28 | add_example(darcy_interface/DI_example1.cpp) 29 | add_example(darcy_interface/DI_example1_3D.cpp) 30 | add_example(darcy_interface/DI_example2.cpp) 31 | 32 | 33 | add_example(convection_diffusion/bulk.cpp) 34 | add_example(convection_diffusion/coupled.cpp) 35 | add_example(convection_diffusion/merging.cpp) 36 | 37 | # add_example(navier_stokes/navier_stokes_raising_drop_2D.cpp) 38 | 39 | 40 | 41 | # if(PYTHON_FOUND) 42 | # add_example(stokes/fictitious_problem/stokes_fictitious_example1.cpp) 43 | # add_example(stokes/fictitious_problem/stokes_fictitious_vorticity_example1.cpp) 44 | # add_example(stokes/interface_problem/stokesRT_static_drop.cpp) 45 | # add_example(stokes/interface_problem/stokesRT_dynamic_drop.cpp) 46 | # endif() 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /cpp/example/convection_diffusion/output_bulk.dat: -------------------------------------------------------------------------------- 1 | Example: circle 2 | Method: conservative 3 | Polynomial order time: 2 4 | Polynomial order space: 2 5 | Stabilization: macro 6 | Macroelement parameter: 0.5 7 | Stabilization constant: 1 8 | Quadrature order time: 5 9 | Quadrature order space: 5 10 | Tfinal: 0.1 11 | 12 | h, dt, L2(Omega(T)), H1(Omega(T)), L2(L2(Omega(t), 0, T)), L2(H1(Omega(t), 0, T)), e_c(T) 13 | 0.1000000000000000, 0.0333333333333333, 0.0050350794489303, 0.2316835696144388, 0.0008744644067235, 0.0400618522349701, 1.2143064331837650e-17 14 | 0.0500000000000000, 0.0166666666666667, 0.0004490707163221, 0.0321540225472617, 0.0000826534684096, 0.0058096616984719, 4.7531423241764514e-16 15 | -------------------------------------------------------------------------------- /cpp/example/convection_diffusion/output_coupled.dat: -------------------------------------------------------------------------------- 1 | Method: conservative 2 | Polynomial order time: 1 3 | Polynomial order space: 1 4 | Stabilization: macro 5 | delta_bulk: 0.7 6 | delta_surf: 0.5 7 | tau_F_bulk: 1 8 | tau_F_surf: 1 9 | tau_G: 1 10 | Quadrature order time: 3 11 | Quadrature order space: 3 12 | Tfinal: 0.1 13 | 14 | --------------------- 15 | h, dt, L2(Omega(T)), L2(Gamma(T)), L2(L2(Omega(t), 0, T)), L2(L2(Gamma(t)), 0, T)), e_c(T) 16 | 0.1,0.025,0.00143697,0.00543796,0.00028384,0.00135848,1.65146e-15 17 | 0.05,0.0125,0.000339975,0.00151374,8.06397e-05,0.000372689,4.14252e-15 18 | 0.025,0.00625,7.92832e-05,0.000358961,1.88237e-05,0.000103941,2.04489e-14 19 | -------------------------------------------------------------------------------- /cpp/example/meshing.cpp: -------------------------------------------------------------------------------- 1 | #include "cpp/cutfem.hpp" 2 | 3 | using mesh_t = Mesh2; 4 | using funtest_t = TestFunction; 5 | using fct_t = FunFEM; 6 | using paraview_t = Paraview; 7 | 8 | int main(int argc, char **argv) { 9 | 10 | globalVariable::verbose = 0; 11 | MPIcf cfMPI(argc, argv); 12 | 13 | int nx = 2; 14 | 15 | for (int i = 0; i < 5; ++i) { 16 | mesh_t Kh(nx, nx, 0., 0., 1., 1.); 17 | Kh.info(); 18 | 19 | mesh_t Kh_ref = refine_barycentric(Kh); 20 | 21 | nx = 2 * (nx - 1) + 1; 22 | 23 | paraview_t writer(Kh, "meshing" + std::to_string(i) + ".vtk"); 24 | paraview_t writer2(Kh_ref, "meshing_ref" + std::to_string(i) + ".vtk"); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /cpp/example/stokes/interface_problem/stokesRT_static_drop.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CutFEM-Library. 3 | 4 | CutFEM-Library is free software: you can redistribute it and/or modify it under 5 | the terms of the GNU General Public License as published by the Free Software 6 | Foundation, either version 3 of the License, or (at your option) any later 7 | version. 8 | 9 | CutFEM-Library is distributed in the hope that it will be useful, but WITHOUT 10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License along with 14 | CutFEM-Library. If not, see 15 | */ 16 | 17 | #include "../cutfem.hpp" 18 | #include "matplotlibcpp.h" 19 | 20 | using mesh_t = Mesh2; 21 | using funtest_t = TestFunction; 22 | using fct_t = FunFEM; 23 | using cutmesh_t = ActiveMesh; 24 | using space_t = GFESpace; 25 | using cutspace_t = CutFESpace; 26 | using gamma_t = InterfaceLevelSet; 27 | using paraview_t = Paraview; 28 | 29 | namespace plt = matplotlibcpp; 30 | 31 | /// @brief Example of Stokes interface problem with zero velocity 32 | /// @details We just want to illustrate that one get exact pressure jump 33 | int main(int argc, char **argv) { 34 | 35 | MPIcf cfMPI(argc, argv); 36 | 37 | // Paramers in problem 38 | double rad = 0.6; // Radius of the drop 39 | double sigma = 5.; 40 | // Viscosity in both subdomains 41 | CutFEMParameter mu(1., 1.); 42 | 43 | double delta = 0.25; 44 | 45 | auto p_exact = [sigma, rad](R2 P, int component, int domain) { return (domain == 0) ? 0 : sigma / (rad); }; 46 | auto Gamma = [rad](R2 P, int i) { return sqrt(P[0] * P[0] + P[1] * P[1]) - rad; }; 47 | 48 | int n_iter = 1; 49 | int nx = 20; 50 | std::cout << " How many iteration? " << std::endl; 51 | std::cin >> n_iter; 52 | std::cout << " Save solution in vtk file for paraview? [0/1]?" << std::endl; 53 | int save_vtk = 0; 54 | std::cin >> save_vtk; 55 | 56 | std::vector h; 57 | std::vector error_u; 58 | std::vector error_p; 59 | std::vector error_div; 60 | std::vector max_div; 61 | 62 | for (int i = 0; i < n_iter; ++i) { 63 | 64 | mesh_t Kh(nx, nx, -1., -1., 2., 2.); 65 | Kh.info(); 66 | 67 | // Finite element space for the levelset function 68 | space_t Lh(Kh, DataFE::P1); 69 | // Interpolation of the levelset function 70 | fct_t levelSet(Lh, Gamma); 71 | // Interface 72 | gamma_t interface(Kh, levelSet); 73 | // Active mesh 74 | cutmesh_t Khi(Kh, interface); 75 | 76 | // Build spaces and cut spaces 77 | space_t Wh(Kh, DataFE::BDM1); 78 | space_t Qh(Kh, DataFE::P0); 79 | cutspace_t Vh(Khi, Wh); 80 | cutspace_t Ph(Khi, Qh); 81 | 82 | // Zero right hand side and velocity on the boundary 83 | fct_t gh(Vh), fh(Vh); 84 | 85 | // Solve Stokes interface problem 86 | auto data_stokes = solver::cutfem::stokes::solve(Vh, Ph, interface, gh, fh, mu, sigma / rad, delta); 87 | 88 | // Extract solution 89 | std::span data_uh{std::span(data_stokes.data(), Vh.get_nb_dof())}; 90 | std::span data_ph{std::span(data_stokes.data() + Vh.get_nb_dof(), Ph.get_nb_dof())}; 91 | fct_t uh(Vh, data_uh); 92 | fct_t ph(Ph, data_ph); 93 | 94 | // Plot the solution 95 | if (MPIcf::IamMaster() && save_vtk) { 96 | paraview_t writer(Khi, "stokes_interface_static_drop_" + std::to_string(i) + ".vtk"); 97 | writer.add(uh, "velocity", 0, 2); 98 | writer.add(ph, "pressure", 0, 1); 99 | } 100 | 101 | auto dxu = dx(uh.expr(0)); 102 | auto dyu = dy(uh.expr(1)); 103 | 104 | double errorL2_u = L2normCut(uh, 0, 2); 105 | double errorL2_p = L2normCut(ph, p_exact, 0, 1); 106 | double errorL2_div = L2normCut(fabs(dxu + dyu), Khi); 107 | double errorLinfty_div = maxNormCut(dxu + dyu, Khi); 108 | 109 | h.push_back(Khi[0].hElement()); 110 | error_u.push_back(errorL2_u); 111 | error_p.push_back(errorL2_p); 112 | error_div.push_back(errorL2_div); 113 | max_div.push_back(errorLinfty_div); 114 | 115 | nx = 2 * nx - 1; 116 | } 117 | 118 | LOG_INFO << "L2 error u : \n " << error_u << logger::endl; 119 | LOG_INFO << "L2 error p : \n " << error_p << logger::endl; 120 | LOG_INFO << "L2 error div : \n " << error_div << logger::endl; 121 | LOG_INFO << "Max error div : \n " << max_div << logger::endl; 122 | 123 | plt::figure(); 124 | plt::title("Stokes: Static drop"); 125 | plt::plot(h, error_p, {{"label", "$|| p_h - p_{ex}||_{L^2}$"}, {"marker", "+"}}); 126 | plt::plot(h, error_u, {{"label", "$|| u_h - u_{ex}||_{L^2}$"}, {"marker", "*"}}); 127 | plt::plot(h, error_div, {{"label", "$|| div(u_h)||_{L^2}$"}, {"marker", "o"}}); 128 | plt::plot(h, max_div, {{"label", "max($div(u_h)$)"}, {"marker", "d"}}); 129 | plt::xlabel("mesh size h"); 130 | plt::legend(); 131 | plt::tight_layout(); 132 | plt::show(); 133 | } 134 | -------------------------------------------------------------------------------- /cpp/num/matlab.cpp: -------------------------------------------------------------------------------- 1 | #include "matlab.hpp" 2 | 3 | // void matlab::Export(std::map,R> & dF, std::string filename) { 4 | // std::ofstream plot; 5 | // plot.open(filename.c_str(), std::ofstream::out); 6 | // plot << std::setprecision(18); 7 | // for (std::map,R>::const_iterator q=dF.begin(); 8 | // q != dF.end(); ++q) 9 | // { 10 | // plot << q->first.first + 1 << "\t" << q->first.second + 1 11 | // << "\t" << q->second << std::endl; 12 | // } 13 | // plot.close(); 14 | // } 15 | -------------------------------------------------------------------------------- /cpp/num/matlab.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CutFEM-Library. 3 | 4 | CutFEM-Library is free software: you can redistribute it and/or modify it under 5 | the terms of the GNU General Public License as published by the Free Software 6 | Foundation, either version 3 of the License, or (at your option) any later 7 | version. 8 | 9 | CutFEM-Library is distributed in the hope that it will be useful, but WITHOUT 10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License along with 14 | CutFEM-Library. If not, see 15 | */ 16 | #ifndef MATLAB_HPP 17 | #define MATLAB_HPP 18 | 19 | #include 20 | #include "../common/RNM.hpp" 21 | typedef double R; 22 | 23 | namespace matlab { 24 | template 25 | void Export(const Vector &a, const A &mapp, std::string filename); 26 | template void Export(const Vector &a, std::string filename); 27 | 28 | template 29 | void Export(std::map, R> &dF, std::string filename); 30 | 31 | template 32 | void Export(std::map, R> &dF, const A &mapp, 33 | std::string filename); 34 | 35 | template 36 | void loadVector(Vector &v, int nv, std::string filename); 37 | // template 38 | // void ExportM(const KNM & a, std::string filename); 39 | } // namespace matlab 40 | 41 | namespace matlab { 42 | // template 43 | // void matlab::ExportM(const KNM & a, std::string filename) { 44 | // std::ofstream plot; 45 | // plot.open(filename.c_str(), std::ofstream::out); 46 | // plot << std::setprecision(16); 47 | // for(int i=0;i 57 | void loadVector(Vector &v, int nv, std::string filename) { 58 | std::ifstream f(filename); 59 | if (!f) 60 | std::cout << " Connot open file" << std::endl; 61 | std::cout << " Load File \"" << filename << "\" in a vector " << nv 62 | << std::endl; 63 | 64 | v.resize(nv); 65 | for (int i = 0; i < nv; i++) 66 | f >> v[i]; 67 | std::cout << " DONE " << std::endl; 68 | f.close(); 69 | } 70 | 71 | template void Export(const Vector &a, std::string filename) { 72 | std::ofstream plot; 73 | plot.open(filename.c_str(), std::ofstream::out); 74 | plot << std::setprecision(16); 75 | for (int i = 0; i < a.size(); ++i) 76 | plot << a[i] << std::endl; 77 | plot.close(); 78 | } 79 | 80 | template 81 | void Export(const Vector &a, const A &mapp, std::string filename) { 82 | std::ofstream plot; 83 | plot.open(filename.c_str(), std::ofstream::out); 84 | plot << std::setprecision(16); 85 | for (int i = 0; i < a.size(); ++i) 86 | plot << a(mapp.iperm(i)) << std::endl; 87 | plot.close(); 88 | } 89 | 90 | template 91 | void Export(std::map, R> &dF, std::string filename) { 92 | std::ofstream plot; 93 | plot.open(filename.c_str(), std::ofstream::out); 94 | plot << std::setprecision(16); 95 | for (std::map, R>::const_iterator q = dF.begin(); 96 | q != dF.end(); ++q) { 97 | plot << q->first.first + 1 << "\t" << q->first.second + 1 << "\t" 98 | << q->second << std::endl; 99 | } 100 | plot.close(); 101 | } 102 | 103 | template 104 | void Export(std::map, R> &dF, const A &mapp, 105 | std::string filename) { 106 | std::ofstream plot; 107 | plot.open(filename.c_str(), std::ofstream::out); 108 | plot << std::setprecision(18); 109 | for (std::map, R>::const_iterator q = dF.begin(); 110 | q != dF.end(); ++q) { 111 | plot << mapp.iperm(q->first.first) + 1 << "\t" 112 | << mapp.iperm(q->first.second) + 1 << "\t" << q->second << std::endl; 113 | } 114 | plot.close(); 115 | } 116 | 117 | template void Export(const Mesh &mesh) { 118 | std::ofstream plot; 119 | plot.open("nodes.dat", std::ofstream::out); 120 | for (int i = 0; i < mesh.nbVertices(); ++i) { 121 | plot << mesh(i).x << "\t" << mesh(i).y << std::endl; 122 | } 123 | plot.close(); 124 | 125 | plot.open("elements.dat", std::ofstream::out); 126 | for (int k = 0; k < mesh.nbElmts(); ++k) { 127 | const typename Mesh::Element &T(mesh[k]); 128 | for (int i = 0; i < 3; ++i) 129 | plot << mesh(T[i]) << "\t"; 130 | plot << "0" << std::endl; 131 | } 132 | plot.close(); 133 | 134 | plot.open("edges.dat", std::ofstream::out); 135 | for (int k = 0; k < mesh.nbBrdElmts(); ++k) { 136 | const typename Mesh::BorderElement &T(mesh.be(k)); 137 | for (int i = 0; i < 2; ++i) 138 | plot << mesh(T[i]) << "\t"; 139 | for (int i = 0; i < 5; ++i) 140 | plot << "0 \t"; 141 | 142 | plot << std::endl; 143 | } 144 | plot.close(); 145 | } 146 | 147 | } // namespace matlab 148 | #endif 149 | -------------------------------------------------------------------------------- /cpp/num/print_container.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CutFEM-Library. 3 | 4 | CutFEM-Library is free software: you can redistribute it and/or modify it under 5 | the terms of the GNU General Public License as published by the Free Software 6 | Foundation, either version 3 of the License, or (at your option) any later 7 | version. 8 | 9 | CutFEM-Library is distributed in the hope that it will be useful, but WITHOUT 10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License along with 14 | CutFEM-Library. If not, see 15 | */ 16 | #ifndef NUM_PRINT_CONTAINER_HPP 17 | #define NUM_PRINT_CONTAINER_HPP 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | template std::ostream &operator<<(std::ostream &o, const std::vector &v) { 27 | o << "["; 28 | if (v.empty()) { 29 | o << "]"; 30 | return o; 31 | } 32 | // For every item except the last write "Item, " 33 | int i = 0; 34 | for (auto it = v.begin(); it != --v.end(); it++, ++i) { 35 | o << *it << ((i % 5) == 4 ? "\n\t" : "\t"); 36 | } 37 | // Write out the last item 38 | o << v.back() << "]"; 39 | return o; 40 | } 41 | 42 | template std::ostream &operator<<(std::ostream &o, const std::set &v) { 43 | o << "{"; 44 | if (v.empty()) { 45 | o << "}"; 46 | return o; 47 | } 48 | // For every item except the last write "Item, " 49 | int i = 0; 50 | for (auto it = v.begin(); it != --v.end(); it++, ++i) { 51 | o << *it << ((i % 5) == 4 ? "\n\t" : "\t"); 52 | } 53 | // Write out the last item 54 | o << *v.rbegin() << "}"; 55 | return o; 56 | } 57 | 58 | template std::ostream &operator<<(std::ostream &o, const std::array &v) { 59 | o << "["; 60 | // For every item except the last write "Item, " 61 | int i = 0; 62 | for (const auto &a : v) { 63 | o << a << ((i % 5) == 4 ? "\n\t" : "\t"); 64 | ++i; 65 | } 66 | // Write out the last item 67 | o << "]"; 68 | return o; 69 | } 70 | 71 | template std::ostream &operator<<(std::ostream &o, const std::pair &m) { 72 | o << "{ " << m.first << " , " << m.second << " }"; 73 | return o; 74 | } 75 | 76 | template std::ostream &operator<<(std::ostream &o, const std::map &m) { 77 | o << "{"; 78 | if (m.empty()) { 79 | o << "}"; 80 | return o; 81 | } 82 | // For every pair except the last write "Key: Value, " 83 | for (auto it = m.begin(); it != --m.end(); it++) { 84 | const auto &[key, value] = *it; 85 | o << key << ": " << value << "\n"; 86 | } 87 | // Write out the last item 88 | const auto &[key, value] = *--m.end(); 89 | o << key << ": " << value << "}"; 90 | return o; 91 | } 92 | 93 | template 94 | std::ostream &operator<<(std::ostream &o, const std::unordered_map &m) { 95 | o << "{"; 96 | if (m.empty()) { 97 | o << "}"; 98 | return o; 99 | } 100 | for (auto it = m.begin(); it != m.end(); it++) { 101 | const auto &[key, value] = *it; 102 | o << key << ": " << value << ", "; 103 | } 104 | o << "}"; 105 | return o; 106 | } 107 | 108 | template 109 | std::ostream &print(std::ostream &o, const TupType &_tup, std::index_sequence) { 110 | o << "("; 111 | (..., (o << (I == 0 ? "" : ", ") << std::get(_tup))); 112 | o << ")\n"; 113 | return o; 114 | } 115 | template std::ostream &operator<<(std::ostream &o, const std::tuple &_tup) { 116 | return print(o, _tup, std::make_index_sequence()); 117 | } 118 | 119 | template std::ostream &operator<<(std::ostream &o, const std::span &v) { 120 | o << "["; 121 | if (v.empty()) { 122 | o << "]"; 123 | return o; 124 | } 125 | // For every item except the last write "Item, " 126 | int i = 0; 127 | for (auto it = v.begin(); it != --v.end(); it++, ++i) { 128 | o << *it << ((i % 5) == 4 ? "\n\t" : "\t"); 129 | } 130 | // Write out the last item 131 | o << v.back() << "]"; 132 | return o; 133 | } 134 | 135 | #endif 136 | 137 | // 138 | -------------------------------------------------------------------------------- /cpp/num/redirectOutput.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CutFEM-Library. 3 | 4 | CutFEM-Library is free software: you can redistribute it and/or modify it under 5 | the terms of the GNU General Public License as published by the Free Software 6 | Foundation, either version 3 of the License, or (at your option) any later 7 | version. 8 | 9 | CutFEM-Library is distributed in the hope that it will be useful, but WITHOUT 10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License along with 14 | CutFEM-Library. If not, see 15 | */ 16 | #ifndef REDIRECTOUTPUT_HPP_ 17 | #define REDIRECTOUTPUT_HPP_ 18 | 19 | #include 20 | #include 21 | #include 22 | // #include "../parallel/cfmpi.hpp" 23 | 24 | struct CoutFileAndScreen { 25 | std::ofstream outFile; 26 | ~CoutFileAndScreen(void) { outFile.close(); } 27 | 28 | CoutFileAndScreen(std::string path2File) : outFile(path2File.c_str()) { 29 | if (!MPIcf::IamMaster()) 30 | outFile.close(); 31 | } 32 | 33 | CoutFileAndScreen &operator<<(std::ostream &(*pfun)(std::ostream &)) { 34 | pfun(outFile); 35 | pfun(std::cout); 36 | return *this; 37 | } 38 | }; 39 | 40 | template CoutFileAndScreen &operator<<(CoutFileAndScreen &st, T val) { 41 | if (st.outFile.is_open()) 42 | st.outFile << val; 43 | std::cout << val; 44 | return st; 45 | }; 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /cpp/num/timer.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CutFEM-Library. 3 | 4 | CutFEM-Library is free software: you can redistribute it and/or modify it under 5 | the terms of the GNU General Public License as published by the Free Software 6 | Foundation, either version 3 of the License, or (at your option) any later 7 | version. 8 | 9 | CutFEM-Library is distributed in the hope that it will be useful, but WITHOUT 10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License along with 14 | CutFEM-Library. If not, see 15 | */ 16 | #include 17 | ////========================================================//// 18 | ////////////========= Timer =========/////////////////// 19 | 20 | inline double CPUtime() { 21 | #ifdef SYSTIMES 22 | struct tms buf; 23 | if (times(&buf) != -1) 24 | return ((double)buf.tms_utime + (double)buf.tms_stime) / (long)sysconf(_SC_CLK_TCK); 25 | else 26 | #endif 27 | return ((double)clock()) / CLOCKS_PER_SEC; 28 | } 29 | -------------------------------------------------------------------------------- /cpp/parallel/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ## Dependencies 2 | find_package(MPI) 3 | 4 | 5 | set(PARALLEL_SOURCES 6 | cfmpi.cpp 7 | ) 8 | 9 | ## ###################### 10 | ## Build rules 11 | ## ###################### 12 | add_library(parallel SHARED ${PARALLEL_SOURCES}) 13 | 14 | 15 | target_include_directories(parallel 16 | PRIVATE 17 | ${CMAKE_CURRENT_SOURCE_DIR} 18 | ${MPI_CXX_INCLUDE_PATH}) 19 | 20 | -------------------------------------------------------------------------------- /cpp/parallel/cfmpi.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CutFEM-Library. 3 | 4 | CutFEM-Library is free software: you can redistribute it and/or modify it under 5 | the terms of the GNU General Public License as published by the Free Software 6 | Foundation, either version 3 of the License, or (at your option) any later 7 | version. 8 | 9 | CutFEM-Library is distributed in the hope that it will be useful, but WITHOUT 10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License along with 14 | CutFEM-Library. If not, see 15 | */ 16 | #include "cfmpi.hpp" 17 | 18 | #if defined(USE_MPI) 19 | 20 | //----------------- Static Members --------------------------- 21 | int MPIcf::my_rank_ = 0; 22 | int MPIcf::size_ = 1; 23 | bool MPIcf::usePetsc_ = true; 24 | MuteStdOstream *MPIcf::mute_ = 0; 25 | MPI_Request *MPIcf::rq = 0; 26 | int MPIcf::loopDivision = 0; 27 | const MPI_Comm &MPIcf::Communicator_ = MPI_COMM_WORLD; 28 | 29 | // constructor of the class 30 | MPIcf::MPIcf(int &argc, char **&argv) { 31 | MPI_Init(&argc, &argv); // initialize MPI 32 | MPI_Comm_rank(MPI_COMM_WORLD, &my_rank_); // set the rank 33 | MPI_Comm_size(MPI_COMM_WORLD, &size_); // set the size 34 | 35 | mute_ = new MuteStdOstream(); // mute ostream for non master 36 | muteStdOstreams(); 37 | 38 | std::cout << "init parallel rank " << my_rank_ << " of " << size_ << std::endl; 39 | // PetscInitialize(&argc, &argv, NULL, NULL); 40 | } 41 | 42 | MPIcf::MPIcf() { 43 | 44 | MPI_Init(nullptr, nullptr); // initialize MPI 45 | 46 | MPI_Comm_rank(MPI_COMM_WORLD, &my_rank_); // set the rank 47 | MPI_Comm_size(MPI_COMM_WORLD, &size_); // set the size 48 | 49 | mute_ = new MuteStdOstream(); // mute ostream for non master 50 | muteStdOstreams(); 51 | std::cout << "init parallel rank " << my_rank_ << " of " << size_ << std::endl; 52 | 53 | usePetsc_ = false; 54 | } 55 | 56 | MPIcf::~MPIcf() { 57 | 58 | // if(usePetsc_)PetscFinalize(); 59 | 60 | MPI_Finalize(); 61 | std::cout << " \n MPI finalized correctly \n" << std::flush; 62 | 63 | size_ = 0; 64 | RecoverStdOstreams(); 65 | delete mute_; 66 | } 67 | 68 | #endif -------------------------------------------------------------------------------- /cpp/parallel/cfmpi.tpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CutFEM-Library. 3 | 4 | CutFEM-Library is free software: you can redistribute it and/or modify it under 5 | the terms of the GNU General Public License as published by the Free Software 6 | Foundation, either version 3 of the License, or (at your option) any later 7 | version. 8 | 9 | CutFEM-Library is distributed in the hope that it will be useful, but WITHOUT 10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License along with 14 | CutFEM-Library. If not, see 15 | */ 16 | 17 | template inline long MPIcf::Bcast(T &a, int who, int size) { return WBcast(&a, size, who, Communicator_); } 18 | 19 | template inline long MPIcf::Bcast(T &a, int who, int size, const MPI_Comm &comm) { 20 | return WBcast(&a, size, who, comm); 21 | } 22 | 23 | template inline long MPIcf::Bcast(const KN &a, int who) { 24 | assert(&a); 25 | CheckContigueKN(a); 26 | return WBcast((T *)a, a.N(), who, Communicator_); 27 | } 28 | template inline long MPIcf::Bcast(std::span a, int who) { 29 | assert(a.data()); 30 | return WBcast(a.data(), a.size(), who, Communicator_); 31 | } 32 | template inline long MPIcf::Bcast(const KN &a, int who, const MPI_Comm &comm) { 33 | assert(&a); 34 | CheckContigueKN(a); 35 | return WBcast((T *)a, a.N(), who, comm); 36 | } 37 | 38 | template inline void MPIcf::Reduce(const T &myData, T &globalData, int size, const MPI_Op &op, int root) { 39 | MPI_Reduce(&myData, &globalData, size, MPI_TYPE::TYPE(), op, root, Communicator_); 40 | } 41 | 42 | template inline void MPIcf::Reduce(const KN &myData, KN &globalData, const MPI_Op &op, int root) { 43 | MPI_Reduce((T *)(myData), (T *)globalData, myData.size(), MPI_TYPE::TYPE(), op, root, Communicator_); 44 | } 45 | 46 | template 47 | inline void MPIcf::Reduce(std::span myData, std::span globalData, const MPI_Op &op, int root) { 48 | MPI_Reduce(myData.data(), globalData.data(), myData.size(), MPI_TYPE::TYPE(), op, root, Communicator_); 49 | } 50 | 51 | template inline void MPIcf::AllReduce(const T &myData, T &globalData, const MPI_Op &op) { 52 | MPI_Allreduce(&myData, &globalData, 1, MPI_TYPE::TYPE(), op, Communicator_); 53 | } 54 | 55 | template inline void MPIcf::AllReduce(const T &myData, T &globalData, int size, const MPI_Op &op) { 56 | MPI_Allreduce(&myData, &globalData, size, MPI_TYPE::TYPE(), op, Communicator_); 57 | } 58 | 59 | template inline void MPIcf::AllReduce(const T *myData, T *globalData, int size, const MPI_Op &op) { 60 | MPI_Allreduce(myData, globalData, size, MPI_TYPE::TYPE(), op, Communicator_); 61 | } 62 | 63 | template inline void MPIcf::AllReduce(const KN &myData, KN &globalData, const MPI_Op &op) { 64 | CheckContigueKN(myData); 65 | MPI_Allreduce((T *)(myData), globalData, myData.size(), MPI_TYPE::TYPE(), op, Communicator_); 66 | } 67 | 68 | template inline void MPIcf::Scan(const T &myData, T &globalData, const MPI_Op &op) { 69 | MPI_Scan(&myData, &globalData, 1, MPI_TYPE::TYPE(), op, Communicator_); 70 | } 71 | -------------------------------------------------------------------------------- /cpp/parallel/cfomp.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CutFEM-Library. 3 | 4 | CutFEM-Library is free software: you can redistribute it and/or modify it under 5 | the terms of the GNU General Public License as published by the Free Software 6 | Foundation, either version 3 of the License, or (at your option) any later 7 | version. 8 | 9 | CutFEM-Library is distributed in the hope that it will be useful, but WITHOUT 10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License along with 14 | CutFEM-Library. If not, see 15 | */ 16 | #ifndef _CPP_PARALLEL_CFOMP_HPP_ 17 | #define _CPP_PARALLEL_CFOMP_HPP_ 18 | 19 | #include 20 | 21 | #include "../cutFEMConfig.h" 22 | 23 | inline int cutfem_get_max_threads() { return std::thread::hardware_concurrency(); } 24 | 25 | #ifdef USE_OMP 26 | #include 27 | #else 28 | 29 | inline void omp_set_num_threads(int n) {}; 30 | inline int omp_get_thread_num() { return 0; } 31 | inline int omp_get_num_threads() { return 1; } 32 | inline int omp_get_max_threads() { return 1; } 33 | 34 | #endif 35 | #endif -------------------------------------------------------------------------------- /cpp/parallel/dummy_cfmpi.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CutFEM-Library. 3 | 4 | CutFEM-Library is free software: you can redistribute it and/or modify it under 5 | the terms of the GNU General Public License as published by the Free Software 6 | Foundation, either version 3 of the License, or (at your option) any later 7 | version. 8 | 9 | CutFEM-Library is distributed in the hope that it will be useful, but WITHOUT 10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License along with 14 | CutFEM-Library. If not, see 15 | */ 16 | #ifndef PARALLEL_DUMMY_CFMPI_HPP 17 | #define PARALLEL_DUMMY_CFMPI_HPP 18 | 19 | #include "../num/util.hpp" 20 | 21 | // Dummy mpi class for seq compilation 22 | class MPIcf { 23 | public: 24 | MPIcf(int &argc, char **&argv) {} 25 | MPIcf() {} 26 | 27 | static int my_rank() { return 0; } 28 | static int size() { return 1; } 29 | 30 | static bool IamMaster() { return true; } 31 | static int Master() { return 0; } 32 | 33 | static inline double Wtime() { return CPUtime(); }; 34 | 35 | static inline const int first_element(int n) { return 0; } 36 | static inline const int next_element(int n) { return 1; } 37 | static inline const int last_element(int n) { return n; } 38 | 39 | template static inline void Bcast(T &a, int who, int size) {} 40 | }; 41 | #endif // PARALLEL_DUMMY_CFMPI_HPP 42 | -------------------------------------------------------------------------------- /cpp/parallel/partitioner.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CutFEM-Library. 3 | 4 | CutFEM-Library is free software: you can redistribute it and/or modify it under 5 | the terms of the GNU General Public License as published by the Free Software 6 | Foundation, either version 3 of the License, or (at your option) any later 7 | version. 8 | 9 | CutFEM-Library is distributed in the hope that it will be useful, but WITHOUT 10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License along with 14 | CutFEM-Library. If not, see 15 | */ 16 | #include "partitioner.hpp" 17 | #include "../problem/solver.hpp" 18 | 19 | void MetisMatrixOrdering::buildGraphOfMatrix( 20 | const std::map, double> &M) { 21 | 22 | // beginAdjacencyNodes_ = new idx_t[nbOfVertices_+1]; 23 | // adjacencyArray_ = new idx_t[M.size()]; 24 | 25 | beginAdjacencyNodes_.resize(nbOfVertices_ + 1); 26 | adjacencyArray_.resize(M.size()); 27 | 28 | int k = 0; 29 | beginAdjacencyNodes_[0] = 0; 30 | 31 | for (typename std::map, double>::const_iterator q = 32 | M.begin(); 33 | q != M.end(); ++q) { 34 | int i = q->first.first - iStart_; 35 | int j = q->first.second; 36 | if (i + iStart_ == j) 37 | continue; 38 | beginAdjacencyNodes_[i + 1] = k + 1; 39 | adjacencyArray_[k] = q->first.second; 40 | ++k; 41 | } 42 | } 43 | 44 | void MetisMatrixOrdering::performOrdering() { 45 | 46 | // perm_ = new idx_t[nbOfVertices_]; 47 | // iperm_ = new idx_t[nbOfVertices_]; 48 | perm_.resize(nbOfVertices_); 49 | iperm_.resize(nbOfVertices_); 50 | 51 | int msg = METIS_NodeND(&nbOfVertices_, beginAdjacencyNodes_, adjacencyArray_, 52 | nullptr, nullptr, perm_, iperm_); 53 | } 54 | 55 | void ParMetisMatrixOrdering::performOrdering() { 56 | 57 | idx_t numflag = 0; 58 | idx_t wgtflag = 0; 59 | idx_t option[3]; 60 | option[0] = 0; 61 | idx_t ncon = 1; 62 | idx_t nparts = MPIcf::size(); 63 | idx_t dbglvl = 5; 64 | perm_.resize(indexDistribution_[MPIcf::size()]); 65 | perm_ = 0.0; 66 | iperm_.resize(indexDistribution_[MPIcf::size()]); 67 | iperm_ = 0.0; 68 | 69 | int *pointerToIperm_ = perm_ + indexDistribution_[MPIcf::my_rank()]; 70 | 71 | idx_t *size = new idx_t[2 * MPIcf::size()]; 72 | idx_t edgecut = 0; 73 | KN tpwgts; 74 | tpwgts = 1.0; 75 | KN ubvec; 76 | ubvec = 1.05; 77 | 78 | MPI_Comm theCommunicator; 79 | MPIcf::Dup(theCommunicator); 80 | 81 | int msg = ParMETIS_V32_NodeND( 82 | indexDistribution_, beginAdjacencyNodes_, adjacencyArray_, nullptr, 83 | &numflag, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, &dbglvl, 84 | pointerToIperm_, size, &theCommunicator); 85 | 86 | MPIcf::AllReduce(perm_, iperm_, MPI_SUM); 87 | 88 | // int msg = ParMETIS_V3_PartKway(indexDistribution_, beginAdjacencyNodes_, 89 | // adjacencyArray_, nullptr, nullptr, &wgtflag, &numflag, &ncon, &nparts, 90 | // tpwgts, ubvec, option, & edgecut, perm_, &theCommunicator); 91 | 92 | delete[] size; 93 | } 94 | 95 | void ParMetisMatrixOrdering::computeIndexBeginEnd() { 96 | 97 | MPIcf::Scan(nbOfVertices_, iEnd_, MPI_SUM); 98 | iStart_ = iEnd_ - nbOfVertices_; 99 | } 100 | 101 | void ParMetisMatrixOrdering::setIndexDistribution() { 102 | 103 | KN idxDist(MPIcf::size() + 1); 104 | idxDist = 0.0; 105 | KN idxDistRecv(MPIcf::size() + 1); 106 | idxDistRecv = 0.0; 107 | for (int i = MPIcf::my_rank() + 1; i <= MPIcf::size(); ++i) 108 | idxDist(i) = nbOfVertices_; 109 | 110 | MPIcf::AllReduce(idxDist, idxDistRecv, MPI_SUM); 111 | 112 | // indexDistribution_ = new idx_t[idxDist.size()]; 113 | indexDistribution_.resize(idxDist.size()); 114 | 115 | for (int i = 0; i <= MPIcf::size(); ++i) 116 | indexDistribution_[i] = idxDistRecv[i]; 117 | } 118 | 119 | void ConsecutiveMatrixOrdering::performOrdering() { 120 | 121 | // perm_ = new idx_t[nbOfVertices_]; 122 | 123 | // int k=0, i0=-1; 124 | // for (typename std::map,double>::const_iterator 125 | // q=M.begin(); 126 | // q != M.end(); ++q) 127 | // { 128 | // int i =q->first.first; 129 | 130 | // if(i0 != i) { 131 | // perm_[i] = k; 132 | // ++k; 133 | // } 134 | 135 | // } 136 | // assert(k==M.size()); 137 | } 138 | -------------------------------------------------------------------------------- /cpp/problem/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | set(PROBLEM_SOURCES 4 | ${CMAKE_CURRENT_SOURCE_DIR}/CutFEM_parameter.cpp 5 | ${CMAKE_CURRENT_SOURCE_DIR}/testFunction.cpp 6 | ${CMAKE_CURRENT_SOURCE_DIR}/itemVF.cpp 7 | ${CMAKE_CURRENT_SOURCE_DIR}/problem.cpp 8 | ${CMAKE_CURRENT_SOURCE_DIR}/baseProblem.cpp 9 | ${CMAKE_CURRENT_SOURCE_DIR}/levelSet.cpp 10 | #GenericMapping.cpp 11 | # ${CMAKE_CURRENT_SOURCE_DIR}/extension.cpp 12 | # levelSet.cpp 13 | # reinitialization.cpp 14 | 15 | ) 16 | add_library(problem SHARED ${PROBLEM_SOURCES}) 17 | target_include_directories(problem 18 | INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) 19 | 20 | if(USE_MPI) 21 | target_link_libraries(problem PRIVATE parallel common FESpace solver ) 22 | else() 23 | target_link_libraries(problem PRIVATE common FESpace solver ) 24 | endif() -------------------------------------------------------------------------------- /cpp/problem/itemVF.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CutFEM-Library. 3 | 4 | CutFEM-Library is free software: you can redistribute it and/or modify it under 5 | the terms of the GNU General Public License as published by the Free Software 6 | Foundation, either version 3 of the License, or (at your option) any later 7 | version. 8 | 9 | CutFEM-Library is distributed in the hope that it will be useful, but WITHOUT 10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License along with 14 | CutFEM-Library. If not, see 15 | */ 16 | #include "itemVF.hpp" 17 | -------------------------------------------------------------------------------- /cpp/problem/problem.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CutFEM-Library. 3 | 4 | CutFEM-Library is free software: you can redistribute it and/or modify it under 5 | the terms of the GNU General Public License as published by the Free Software 6 | Foundation, either version 3 of the License, or (at your option) any later 7 | version. 8 | 9 | CutFEM-Library is distributed in the hope that it will be useful, but WITHOUT 10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License along with 14 | CutFEM-Library. If not, see 15 | */ 16 | #include "problem.hpp" 17 | 18 | template <> 19 | const QuadratureFormular1d & 20 | QuadratureOfProblem::get_quadrature_formular_dK() const { 21 | return *QF_Simplex(order_space_element_quadrature_); 22 | } 23 | template <> 24 | const QuadratureFormular1d & 25 | QuadratureOfProblem::get_quadrature_formular_dK() const { 26 | return *QF_Simplex(order_space_element_quadrature_); 27 | } 28 | template <> 29 | const QuadratureFormular2d & 30 | QuadratureOfProblem::get_quadrature_formular_dK() const { 31 | return *QF_Simplex(order_space_element_quadrature_); 32 | } 33 | template <> 34 | const QuadratureFormular2d & 35 | QuadratureOfProblem::get_quadrature_formular_dK() const { 36 | return *QF_Quad(order_space_element_quadrature_); 37 | } 38 | 39 | template <> 40 | const QuadratureFormular2d & 41 | QuadratureOfProblem::get_quadrature_formular_K() const { 42 | return *QF_Simplex(order_space_element_quadrature_); 43 | } 44 | template <> 45 | const QuadratureFormular2d & 46 | QuadratureOfProblem::get_quadrature_formular_K() const { 47 | return *QF_Quad(order_space_element_quadrature_); 48 | } 49 | template <> 50 | const QuadratureFormular3d & 51 | QuadratureOfProblem::get_quadrature_formular_K() const { 52 | return *QF_Simplex(order_space_element_quadrature_); 53 | } 54 | template <> 55 | const QuadratureFormular3d & 56 | QuadratureOfProblem::get_quadrature_formular_K() const { 57 | return *QF_Hexa(order_space_element_quadrature_); 58 | } 59 | 60 | // QUADRATURE FOR CUT ELEMENT AND FACE 61 | template <> 62 | const QuadratureFormular3d & 63 | QuadratureOfProblem::get_quadrature_formular_cutK() const { 64 | return *QF_Simplex(order_space_element_quadrature_); 65 | } 66 | template <> 67 | const QuadratureFormular3d & 68 | QuadratureOfProblem::get_quadrature_formular_cutK() const { 69 | return *QF_Simplex(order_space_element_quadrature_); 70 | } 71 | template <> 72 | const QuadratureFormular2d & 73 | QuadratureOfProblem::get_quadrature_formular_cutFace() const { 74 | return *QF_Simplex(order_space_element_quadrature_); 75 | } 76 | template <> 77 | const QuadratureFormular2d & 78 | QuadratureOfProblem::get_quadrature_formular_cutFace() const { 79 | return *QF_Simplex(order_space_element_quadrature_); 80 | } 81 | 82 | template <> 83 | const QuadratureFormular2d & 84 | QuadratureOfProblem::get_quadrature_formular_cutK() const { 85 | return *QF_Simplex(order_space_element_quadrature_); 86 | } 87 | template <> 88 | const QuadratureFormular2d & 89 | QuadratureOfProblem::get_quadrature_formular_cutK() const { 90 | return *QF_Simplex(order_space_element_quadrature_); 91 | } 92 | template <> 93 | const QuadratureFormular1d & 94 | QuadratureOfProblem::get_quadrature_formular_cutFace() const { 95 | return *QF_Simplex(order_space_element_quadrature_); 96 | } 97 | template <> 98 | const QuadratureFormular1d & 99 | QuadratureOfProblem::get_quadrature_formular_cutFace() const { 100 | return *QF_Simplex(order_space_element_quadrature_); 101 | } 102 | -------------------------------------------------------------------------------- /cpp/problem/solver_advection.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CutFEM-Library. 3 | 4 | CutFEM-Library is free software: you can redistribute it and/or modify it under 5 | the terms of the GNU General Public License as published by the Free Software 6 | Foundation, either version 3 of the License, or (at your option) any later 7 | version. 8 | 9 | CutFEM-Library is distributed in the hope that it will be useful, but WITHOUT 10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License along with 14 | CutFEM-Library. If not, see 15 | */ 16 | 17 | #ifndef CUTFEM_CPP_PROBLEM_SOLVER_ADVECTION_HPP 18 | #define CUTFEM_CPP_PROBLEM_SOLVER_ADVECTION_HPP 19 | 20 | #include "baseProblem.hpp" 21 | 22 | template class StreamLineDiffusion : public DefaultExpression { 23 | 24 | using fct_t = FunFEM; 25 | 26 | public: 27 | StreamLineDiffusion(const fct_t &u, double hh, double ddt) : U(u), h(hh), dt(ddt) {} 28 | 29 | double evalOnBackMesh(const int k, int dom, const R *x, const R t, const R *normal) const final { 30 | double ux = U.eval(k, x, 0, op_id); 31 | double uy = U.eval(k, x, 1, op_id); 32 | return 2. / std::sqrt(1. / (dt * dt) + sqrt(ux * ux + uy * uy) / (h * h)); 33 | } 34 | 35 | private: 36 | const fct_t &U; 37 | double h; 38 | double dt; 39 | }; 40 | 41 | namespace solver { 42 | 43 | namespace fem { 44 | 45 | namespace advection { 46 | 47 | namespace streamline_diffusion { 48 | 49 | /// @brief Solve PDE advection in R2 using Crang Nicolson scheme for the time derivative 50 | /// @param u_init Solution at time n 51 | /// @param betap velocity field at time n 52 | /// @param beta velocity at time n+1 53 | /// @param dt time step 54 | /// @return vector containing the dof of the solution 55 | std::vector solve(const FunFEM &u_init, const FunFEM &betap, const FunFEM &beta, 56 | double dt) { 57 | 58 | const auto &Vh = u_init.getSpace(); 59 | const auto &Th = Vh.Th; 60 | FEM problem(Vh); 61 | TestFunction u(Vh, 1), v(Vh, 1); 62 | 63 | double h = Th[0].hElement(); 64 | auto U = beta.exprList(); 65 | auto Up = betap.exprList(); 66 | auto u0 = u_init.expr(); 67 | 68 | auto tauSD = std::make_shared>(beta, h, dt); 69 | 70 | problem.addBilinear((u + (U * (0.5 * dt * grad(u))), v + U * (tauSD * grad(v))), Th); 71 | problem.addLinear(innerProduct(u0 - 0.5 * dt * (Up[0] * dx(u0) + Up[1] * dy(u0)), v + U * (tauSD * grad(v))), Th); 72 | 73 | problem.solve(); 74 | 75 | return problem.rhs_; 76 | } 77 | 78 | } // namespace streamline_diffusion 79 | } // namespace advection 80 | } // namespace fem 81 | } // namespace solver 82 | 83 | #endif -------------------------------------------------------------------------------- /cpp/problem/testFunction.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CutFEM-Library. 3 | 4 | CutFEM-Library is free software: you can redistribute it and/or modify it under 5 | the terms of the GNU General Public License as published by the Free Software 6 | Foundation, either version 3 of the License, or (at your option) any later 7 | version. 8 | 9 | CutFEM-Library is distributed in the hope that it will be useful, but WITHOUT 10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License along with 14 | CutFEM-Library. If not, see 15 | */ 16 | #include "testFunction.hpp" 17 | 18 | void f_id(RNMK_ &x, int cu, int du) {} 19 | void f_ln(RNMK_ &x, int cu, int du) { 20 | for (int i = 0; i < x.N(); ++i) { 21 | x(i, cu, du) = std::log(x(i, cu, du)); 22 | } 23 | } 24 | 25 | std::string whichOperator(int op) { 26 | std::string s; 27 | if (op == 0) 28 | s = "t "; 29 | else if (op == 1) 30 | s = "dt "; 31 | else if (op == -1) 32 | s = " "; 33 | else 34 | s = " "; 35 | 36 | return s; 37 | } 38 | 39 | std::string whichOperator(int op, int cu) { 40 | std::string s; 41 | if (op == 0) 42 | s = "u" + std::to_string(cu); 43 | else if (op == 1) 44 | s = "dx(u" + std::to_string(cu) + ")"; 45 | else if (op == 2) 46 | s = "dy(u" + std::to_string(cu) + ")"; 47 | else if (op == 3) 48 | s = "dz(u" + std::to_string(cu) + ")"; 49 | else if (op == op_dxx) 50 | s = "dxx(u" + std::to_string(cu) + ")"; 51 | else if (op == op_dxy) 52 | s = "dxy(u" + std::to_string(cu) + ")"; 53 | else if (op == op_dxz) 54 | s = "dxz(u" + std::to_string(cu) + ")"; 55 | else if (op == op_dyy) 56 | s = "dyy(u" + std::to_string(cu) + ")"; 57 | else if (op == op_dyz) 58 | s = "dyz(u" + std::to_string(cu) + ")"; 59 | else if (op == op_dzz) 60 | s = "dzz(u" + std::to_string(cu) + ")"; 61 | else 62 | s = "no Op"; 63 | 64 | return s; 65 | } 66 | std::string whichOperatorV(int op, int cu) { 67 | std::string s; 68 | if (op == 0) 69 | s = "v" + std::to_string(cu); 70 | else if (op == 1) 71 | s = "dx(v" + std::to_string(cu) + ")"; 72 | else if (op == 2) 73 | s = "dy(v" + std::to_string(cu) + ")"; 74 | else if (op == 3) 75 | s = "dz(v" + std::to_string(cu) + ")"; 76 | else if (op == op_dxx) 77 | s = "dxx(v" + std::to_string(cu) + ")"; 78 | else if (op == op_dxy) 79 | s = "dxy(v" + std::to_string(cu) + ")"; 80 | else if (op == op_dxz) 81 | s = "dxz(v" + std::to_string(cu) + ")"; 82 | else if (op == op_dyy) 83 | s = "dyy(v" + std::to_string(cu) + ")"; 84 | else if (op == op_dyz) 85 | s = "dyz(v" + std::to_string(cu) + ")"; 86 | else if (op == op_dzz) 87 | s = "dzz(v" + std::to_string(cu) + ")"; 88 | else 89 | s = "no Op"; 90 | 91 | return s; 92 | } 93 | -------------------------------------------------------------------------------- /cpp/problem/time_scheme.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file cpp/problem/time_scheme.hpp 3 | * @brief 4 | * 5 | * @copyright 6 | 7 | CutFEM-Library is free software: you can redistribute it and/or modify it under 8 | the terms of the GNU General Public License as published by the Free Software 9 | Foundation, either version 3 of the License, or (at your option) any later 10 | version. 11 | 12 | CutFEM-Library is distributed in the hope that it will be useful, but WITHOUT 13 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 14 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License along with 17 | CutFEM-Library. If not, see 18 | */ 19 | 20 | #ifndef CUTFEM_TIME_SCHEME_HPP 21 | #define CUTFEM_TIME_SCHEME_HPP 22 | namespace Scheme { 23 | 24 | namespace RK3 { 25 | 26 | template 27 | void step1(InputIt first0, InputIt last0, InputIt first1, double dt, OutputIt r_first) { 28 | while (first0 != last0) { 29 | *r_first++ = *first0++ + dt * *first1++; 30 | } 31 | } 32 | 33 | template 34 | void step2(InputIt first0, InputIt last0, InputIt first1, InputIt first2, double dt, OutputIt r_first) { 35 | while (first0 != last0) { 36 | *r_first++ = 3. / 4 * *first0++ + 1. / 4 * *first1++ + 1. / 4 * dt * *first2++; 37 | } 38 | } 39 | 40 | template 41 | void step3(InputIt first0, InputIt last0, InputIt first1, InputIt first2, double dt, OutputIt r_first) { 42 | while (first0 != last0) { 43 | *r_first++ = 1. / 3 * *first0++ + 2. / 3 * *first1++ + 2. / 3 * dt * *first2++; 44 | } 45 | } 46 | } // namespace RK3 47 | } // namespace Scheme 48 | 49 | #endif -------------------------------------------------------------------------------- /cpp/solver/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | if(${USE_UMFPACK}) 3 | find_package(UMFPACK) 4 | if(UMFPACK_LIBRARIES) 5 | include_directories(${UMFPACK_INCLUDES}) 6 | list(APPEND LINK_LIBRARY ${UMFPACK_LIBRARIES}) 7 | # option(USE_UMFPACK "Found the UMFpack library" ON) 8 | else() 9 | message("Not Found UMFPACK") 10 | endif() 11 | endif() 12 | if(${USE_LAPACK}) 13 | find_package(LAPACK) 14 | if(LAPACK_LIBRARIES) 15 | include_directories(${LAPACK_INCLUDES}) 16 | list(APPEND LINK_LIBRARY ${LAPACK_LIBRARIES}) 17 | message("Found LAPACK") 18 | else() 19 | message("Not Found LAPACK") 20 | endif() 21 | endif() 22 | if(${USE_MUMPS}) 23 | find_package(MUMPS REQUIRED) 24 | 25 | if(MUMPS_LIBRARIES AND USE_MPI) 26 | include_directories(${MUMPS_INCLUDES}) 27 | list(APPEND LINK_LIBRARY ${MUMPS_LIBRARIES}) 28 | # option(USE_MUMPS "Found the mumps library" ON) 29 | message("Found MUMPS") 30 | else() 31 | if(USE_MPI) 32 | message("Not Found MUMPS") 33 | elseif(MUMPS_LIBRARIES) 34 | include_directories(${MUMPS_INCLUDES}) 35 | list(APPEND LINK_LIBRARY ${MUMPS_LIBRARIES}) 36 | # option(USE_MUMPS "Found the mumps library" ON) 37 | message("Found seq MUMPS") 38 | else() 39 | message("Not Found MUMPS") 40 | endif() 41 | endif() 42 | endif() 43 | 44 | 45 | # configure_file(../../cutFEMConfig.in ../../cutFEMConfig.h) 46 | 47 | set(SOLVER_SOURCES 48 | ${CMAKE_CURRENT_SOURCE_DIR}/solver.cpp 49 | ) 50 | 51 | if(USE_MUMPS AND USE_MPI) 52 | list(APPEND SOLVER_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/solverMumpsMPI.cpp) 53 | list(APPEND LINK_LIBRARY parallel) 54 | elseif(USE_MUMPS) 55 | list(APPEND SOLVER_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/solverMumps.cpp) 56 | endif() 57 | 58 | add_library(solver SHARED ${SOLVER_SOURCES}) 59 | target_include_directories(solver 60 | PRIVATE 61 | "${CMAKE_CURRENT_SOURCE_DIR}" 62 | "${CMAKE_CURRENT_BINARY_DIR}" 63 | "${PROJECT_BINARY_DIR}" 64 | ) 65 | target_link_libraries(solver PRIVATE common::common ${LINK_LIBRARY}) 66 | -------------------------------------------------------------------------------- /cpp/solver/solver.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CutFEM-Library. 3 | 4 | CutFEM-Library is free software: you can redistribute it and/or modify it under 5 | the terms of the GNU General Public License as published by the Free Software 6 | Foundation, either version 3 of the License, or (at your option) any later 7 | version. 8 | 9 | CutFEM-Library is distributed in the hope that it will be useful, but WITHOUT 10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License along with 14 | CutFEM-Library. If not, see 15 | */ 16 | #ifndef SOLVER_HPP_ 17 | #define SOLVER_HPP_ 18 | #include 19 | #include "../cutFEMConfig.h" 20 | #include "../num/util.hpp" 21 | #include "../parallel/cfmpi.hpp" 22 | 23 | struct ProblemOption { 24 | int order_space_element_quadrature_ = 5; 25 | int order_space_bord_quadrature_ = 5; 26 | int order_time_quadrature_ = 1; 27 | std::string solver_name_ = "mumps"; 28 | bool clear_matrix_ = true; 29 | int verbose_ = 0; 30 | }; 31 | 32 | namespace solver { 33 | 34 | // void umfpack(std::map, R> &, Rn &, bool); 35 | void umfpack(std::map, R> &, std::span, bool); 36 | 37 | void LAPACK(Rnm &a, Rn &b); 38 | } // namespace solver 39 | class Solver { 40 | 41 | double get_Time() const { return MPIcf::Wtime(); } 42 | 43 | public: 44 | int verbose_ = 0; 45 | bool clearMatrix_ = true; 46 | // std::string reordering = "none"; 47 | std::string solver_name_ = "default"; 48 | 49 | Solver(const ProblemOption &option) { 50 | clearMatrix_ = option.clear_matrix_; 51 | solver_name_ = option.solver_name_; 52 | verbose_ = option.verbose_; 53 | } 54 | 55 | // void solve(std::map, R> &A, Rn &b); 56 | void solve(std::map, R> &A, std::span b); 57 | }; 58 | 59 | #endif 60 | 61 | // void MUMPS(std::map,R> &, Rn &, const int) ; 62 | // void MUMPS(std::map,R> &, Rn &, const int, const 63 | // MatrixOrdering*) ; 64 | // void MUMPS(std::map,R> &, Rn &, const MatrixOrdering*) ; 65 | // void MUMPS(std::map,R> &, Rn &) ; 66 | 67 | // void PETSC_Sequential(std::map,R> &, Rn &); 68 | // // void PETSC_Parallel(std::map,R> &, Rn &); 69 | // void PETSC(std::map,R> &, Rn &); 70 | 71 | // namespace solver 72 | // namespace toolPETSC { 73 | // inline int whatProc(const int i, const int * Iend, const int nproc); 74 | // inline void map2AIJ(std::map,R> & Amap, 75 | // KN& Iv, KN& Jv, KN& a); 76 | // int getLocalSize(int sizeGlob, int&Istart, int& Iend); 77 | // void transform2PETSCformat(std::map,R> & Amap, 78 | // int Istart, int Iend); 79 | 80 | // } -------------------------------------------------------------------------------- /cpp/solver/solverMumps.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of CutFEM-Library. 3 | 4 | CutFEM-Library is free software: you can redistribute it and/or modify it under 5 | the terms of the GNU General Public License as published by the Free Software 6 | Foundation, either version 3 of the License, or (at your option) any later 7 | version. 8 | 9 | CutFEM-Library is distributed in the hope that it will be useful, but WITHOUT 10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License along with 14 | CutFEM-Library. If not, see 15 | */ 16 | #ifndef SOLVER_MUMPS_HPP_ 17 | #define SOLVER_MUMPS_HPP_ 18 | 19 | #include "solver.hpp" 20 | #include "dmumps_c.h" 21 | 22 | enum MatrixFormat { centralized, distributed }; 23 | class MUMPS { 24 | 25 | typedef std::map, R> matmap; 26 | 27 | static const int JOB_INIT_ = -1; 28 | static const int JOB_ANALYSIS_ = 1; 29 | static const int JOB_FACTORIZATION_ = 2; 30 | static const int JOB_SOLVE_ = 3; 31 | static const int JOB_ALL_ = 6; 32 | static const int JOB_END_ = -2; 33 | static const int USE_COMM_WORLD_ = -987654; 34 | bool cleanMatrix = true; 35 | 36 | public: 37 | // int verbose = 0; 38 | // std::string reordering = "none"; 39 | MatrixFormat matrixFormat = centralized; 40 | 41 | R timeAnalysis_, timeFactorization_, timeSolving_; 42 | 43 | private: 44 | matmap &mat; 45 | // Rn &rhs; 46 | std::span rhs; 47 | 48 | DMUMPS_STRUC_C mumps_par; 49 | KN IRN_loc, JCN_loc; 50 | std::vector A_loc, rhsG; 51 | 52 | public: 53 | // MUMPS(const Solver &, matmap &, Rn &); 54 | MUMPS(const Solver &, matmap &, std::span); 55 | 56 | private: 57 | void initializeSetting(); 58 | void setFormatMatrix(); 59 | void setDoF(); 60 | void saveMatrixToCSR(); 61 | void analyzeMatrix(); 62 | void factorizationMatrix(); 63 | void solvingLinearSystem(); 64 | void info(); 65 | 66 | int mumps_info(int i) { return mumps_par.info[i - 1]; } 67 | int mumps_icntl(int i) { return mumps_par.icntl[i - 1]; } 68 | 69 | public: 70 | ~MUMPS() { 71 | mumps_par.job = JOB_END_; 72 | dmumps_c(&mumps_par); 73 | } 74 | }; 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /cutFEMConfig.in: -------------------------------------------------------------------------------- 1 | #cmakedefine USE_MPI 2 | #cmakedefine USE_UMFPACK 3 | #cmakedefine USE_LAPACK 4 | #cmakedefine USE_MUMPS 5 | #cmakedefine USE_OMP 6 | -------------------------------------------------------------------------------- /julia/condition_number_cd.jl: -------------------------------------------------------------------------------- 1 | # Import required modules 2 | using LinearAlgebra, SparseArrays, DelimitedFiles 3 | 4 | #path = "../output_files/paper/example2/data/" 5 | #path = "/Users/sebastianmyrback/Documents/KTH/forskning/development/output_files/stokes/fictitious/data/" 6 | path = "/NOBACKUP/smyrback/output_files/paper/circle1/data/" 7 | 8 | n = 5 9 | condition_numbers = zeros(n) 10 | 11 | for i=1:n 12 | println(string(i) * "/" * string(n)) 13 | A = readdlm(path * "mat_" * string(i) * ".dat") 14 | A = sparse(A[:,1], A[:,2], A[:,3]) 15 | 16 | #condition_numbers[i] = cond(A, 1) # condest norm 17 | condition_numbers[i] = cond(Matrix(A), 2) # spectral norm 18 | println("condition number = " * string(condition_numbers[i]) * "\n") 19 | end 20 | 21 | # Display the result 22 | println("condition_number = ", condition_numbers) 23 | -------------------------------------------------------------------------------- /julia/stokes_rhs.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 6, 6 | "metadata": {}, 7 | "outputs": [ 8 | { 9 | "name": "stdout", 10 | "output_type": "stream", 11 | "text": [ 12 | "RHS of momentum equation: [20*x*(x**2 - y**2) + 2*x*(10*x**2 - 10*y**2) - 32*y + 16, 32*x - 20*y*(x**2 - y**2) - 2*y*(10*x**2 - 10*y**2) - 16]\n", 13 | "RHS of continuity equation: (2 - 4*y)*(2*x - 1) + (4*x - 2)*(2*y - 1)\n" 14 | ] 15 | } 16 | ], 17 | "source": [ 18 | "import sympy as sp\n", 19 | "import numpy as np\n", 20 | "\n", 21 | "# Define the variables\n", 22 | "x, y = sp.symbols('x y')\n", 23 | "\n", 24 | "# Define the solution u\n", 25 | "u = [2 * (x * x - x + 0.25 + y * y - y) * (2 * y - 1), -2 * (x * x - x + 0.25 + y * y - y) * (2 * x - 1)] \n", 26 | "\n", 27 | "# Define the pressure p\n", 28 | "p = 10 * (x * x - y * y) * (x * x - y * y) # replace with your pressure function\n", 29 | "\n", 30 | "# Compute the gradient of each component of u\n", 31 | "grad_u = [[sp.diff(u_i, x_j) for x_j in (x, y)] for u_i in u]\n", 32 | "\n", 33 | "# Compute the divergence of u\n", 34 | "div_u = sum(sp.diff(u_i, x_i) for u_i, x_i in zip(u, (x, y)))\n", 35 | "\n", 36 | "# Compute the Laplacian of u\n", 37 | "laplacian_u = [sum(sp.diff(grad_u_i_j, x_j) for grad_u_i_j, x_j in zip(grad_u_i, (x, y))) for grad_u_i in grad_u]\n", 38 | "\n", 39 | "# Compute the gradient of p\n", 40 | "grad_p = [sp.diff(p, x_i) for x_i in (x, y)]\n", 41 | "\n", 42 | "# Compute the RHS of the momentum equation in the Stokes equations\n", 43 | "rhs_momentum = [- lap_u_i + grad_p_i for lap_u_i, grad_p_i in zip(laplacian_u, grad_p)]\n", 44 | "\n", 45 | "# Compute the RHS of the continuity equation in the Stokes equations\n", 46 | "rhs_continuity = div_u\n", 47 | "\n", 48 | "# Print the RHS functions\n", 49 | "print(\"RHS of momentum equation:\", rhs_momentum)\n", 50 | "print(\"RHS of continuity equation:\", rhs_continuity)\n", 51 | "\n", 52 | "# rhs_momentum_cpp = [sp.ccode(rhs) for rhs in rhs_momentum]\n", 53 | "# rhs_continuity_cpp = sp.ccode(rhs_continuity)\n", 54 | "\n", 55 | "# # Print the RHS functions in C++ format\n", 56 | "# print(\"RHS of momentum equation in C++:\", rhs_momentum_cpp)\n", 57 | "# print(\"RHS of continuity equation in C++:\", rhs_continuity_cpp)" 58 | ] 59 | } 60 | ], 61 | "metadata": { 62 | "kernelspec": { 63 | "display_name": "Python 3", 64 | "language": "python", 65 | "name": "python3" 66 | }, 67 | "language_info": { 68 | "codemirror_mode": { 69 | "name": "ipython", 70 | "version": 3 71 | }, 72 | "file_extension": ".py", 73 | "mimetype": "text/x-python", 74 | "name": "python", 75 | "nbconvert_exporter": "python", 76 | "pygments_lexer": "ipython3", 77 | "version": "3.10.9" 78 | } 79 | }, 80 | "nbformat": 4, 81 | "nbformat_minor": 2 82 | } 83 | --------------------------------------------------------------------------------