diff --git a/3rdparty/Makefile.am b/3rdparty/Makefile.am index 9daec3194..90937dcad 100755 --- a/3rdparty/Makefile.am +++ b/3rdparty/Makefile.am @@ -191,12 +191,13 @@ lib/WHERE.boost: ./getall # to reinstall mpi under window afer clean reinstall-msmpi: -if test -f "$$MSMPI_INC"/mpif.h ; then \ - echo " copy msmpi in 3rdparty form $$MSMPI_INC and $$MSMPI_LIB64 or $$MSMPI_LIB32" ; \ + echo " copy msmpi in 3rdparty form $$MSMPI_INC and $$MSMPI_LIB64 or $$MSMPI_LIB32" ;\ mkdir -p include/msmpi ;\ mkdir -p lib/msmpi ;\ cp "$$MSMPI_INC"/*.h include/msmpi ;\ - sed 's/INT_PTR_KIND()/@SIZEOF_PTR@/' <"$$MSMPI_INC"/mpif.h >include/msmpi/mpif.h ;\ - grep KIND include/msmpi/mpif.h; \ + sed 's/INT_PTR_KIND()/@SIZEOF_PTR@/' <"$$MSMPI_INC"/mpif.h >include/msmpi/mpif.h ;\ + sed 's/MPI_Status array_of_statuses\[\]/MPI_Status\* array_of_statuses/' < "$$MSMPI_INC"/mpi.h > include/msmpi/mpi.h ;\ + grep KIND include/msmpi/mpif.h;\ test "@SIZEOF_PTR@" -eq 8 && cp "$$MSMPI_INC"/x64/*.h include/msmpi && cp "$$MSMPI_LIB64"/*.lib lib/msmpi ;\ test "@SIZEOF_PTR@" -eq 4 && cp "$$MSMPI_INC"/x86/*.h include/msmpi && cp "$$MSMPI_LIB32"/*.lib lib/msmpi ;\ fi @@ -232,7 +233,10 @@ install-exec-local: cp -rp lib $(DESTDIR)$(ff_prefix_dir) cp -rp include $(DESTDIR)$(ff_prefix_dir) cp -rp bin $(DESTDIR)$(ff_prefix_dir) - + -if test -f boost/done.tag ; then \ + $(mkinstalldirs) -m 755 $(DESTDIR)$(ff_prefix_dir)/boost ; \ + cp -rp boost $(DESTDIR)$(ff_prefix_dir) ; \ + fi clean-local: -rm -rf tag-* include lib bin WHERE-LD -mkdir include lib bin diff --git a/3rdparty/ff-petsc/Makefile b/3rdparty/ff-petsc/Makefile index ff56c863d..ee57a0fa7 100644 --- a/3rdparty/ff-petsc/Makefile +++ b/3rdparty/ff-petsc/Makefile @@ -22,8 +22,6 @@ # headeralh default=0 freefem make multipleauthors start=19/03/10 upmc include Makefile.inc -mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST))) -dir3rdparty := $(abspath $(dir $(mkfile_path))/..) DIR_INSTALL_REAL:=$(FF_prefix_petsc)/r DIR_INSTALL_COMPLEX:=$(FF_prefix_petsc)/c @@ -45,28 +43,6 @@ PETSC_DOWNLOAD_C := --with-metis-dir=$(DIR_INSTALL_REAL) \ --with-suitesparse-dir=$(DIR_INSTALL_REAL) \ --with-parmetis-dir=$(DIR_INSTALL_REAL) \ --with-tetgen-dir=$(DIR_INSTALL_REAL) -ifeq ($(PETSC_PKG),yes) -pkg_dir=$(abspath $(dir $(mkfile_path))/pkg) -PETSC_DOWNLOAD := --download-scalapack=$(pkg_dir)/pkg-scalapack.tar.gz \ - --download-metis=$(pkg_dir)/pkg-metis.tar.gz \ - --download-ptscotch=$(pkg_dir)/scotch-v6.0.9.tar.gz \ - --download-mumps=$(pkg_dir)/pkg-mumps.tar.gz \ - --download-hypre=$(pkg_dir)/hypre.tar.gz \ - --download-parmetis=$(pkg_dir)/pkg-parmetis.tar.gz \ - --download-superlu=$(pkg_dir)/superlu.tar.gz \ - --download-suitesparse=$(pkg_dir)/SuiteSparse-5.7.1.tar.gz \ - --download-tetgen=$(pkg_dir)/tetgen1.5.1.tar.gz \ - --download-slepc=$(pkg_dir)/slepc.tar.gz \ - --download-hpddm=$(pkg_dir)/hpddm.tar.gz -ifeq ($(FFCMAKE),no) -PETSC_DOWNLOAD := $(PETSC_DOWNLOAD) --download-cmake=$(pkg_dir)/cmake.tar.gz -endif -PETSC_DOWNLOAD_C := $(PETSC_DOWNLOAD_C) --download-slepc=$(pkg_dir)/slepc.tar.gz -ifeq ($(WIN32DLLTARGET),) -PETSC_DOWNLOAD := $(PETSC_DOWNLOAD) --download-hpddm=$(pkg_dir)/hpddm.tar.gz -PETSC_DOWNLOAD_C := $(PETSC_DOWNLOAD_C) --download-hpddm=$(pkg_dir)/hpddm.tar.gz -endif -else PETSC_DOWNLOAD := --download-metis --download-ptscotch \ --download-hypre --download-parmetis \ --download-mmg --download-parmmg \ @@ -76,36 +52,61 @@ ifeq ($(FFCMAKE),no) PETSC_DOWNLOAD := $(PETSC_DOWNLOAD) --download-cmake endif PETSC_DOWNLOAD_C := $(PETSC_DOWNLOAD_C) --download-slepc --download-hpddm --download-htool -endif ifeq ($(FF_generic_petsc), yes) FLAGS_MTUNE := -mtune=generic else FLAGS_MTUNE := -mtune=native endif -COMMON_FLAGS := MAKEFLAGS='' --with-debugging=0 COPTFLAGS='-O3 $(FLAGS_MTUNE)' CXXOPTFLAGS='-O3 $(FLAGS_MTUNE)' FOPTFLAGS='-O3 $(FLAGS_MTUNE)' --with-cxx-dialect=C++11 --with-ssl=0 --with-x=0 --with-fortran-bindings=0 --with-cudac=0 +COMMON_FLAGS := MAKEFLAGS='' --with-debugging=0 COPTFLAGS='-O3 $(FLAGS_MTUNE)' CXXOPTFLAGS='-O3 $(FLAGS_MTUNE)' FOPTFLAGS='-O3 $(FLAGS_MTUNE)' --with-cxx-dialect=11 --with-ssl=0 --with-x=0 --with-fortran-bindings=0 --with-cudac=0 + +ifneq ($(wildcard ~/.petsc_pkg),) + COMMON_FLAGS += --with-packages-download-dir=~/.petsc_pkg +endif + +ifeq ($(FC),) +COMMON_FLAGS += --with-fc=0 +PETSC_DOWNLOAD += --download-superlu_dist +PETSC_DOWNLOAD_C += --with-superlu_dist-dir=$(DIR_INSTALL_REAL) +endif + ifeq ($(WIN32DLLTARGET),) ## Not on windows.... -ifeq ($(MPICC)$(MPICXX)$(MPIFC),) +ifeq ($(MPICC)$(MPICXX),) PETSC_DOWNLOAD += --with-cc='$(CC)' --with-cxx='$(CXX)' --download-mpich PETSC_DOWNLOAD_C += --with-mpi-dir=$(DIR_INSTALL_REAL) ifneq ($(FC),) -PETSC_DOWNLOAD += --with-fc='$(FC)' --download-scalapack --download-mumps --download-slepc-configure-arguments="--download-arpack=https://github.com/prj-/arpack-ng/archive/b64dccb.tar.gz" +PETSC_DOWNLOAD += --with-fc='$(FC)' +ifneq ($(wildcard ~/.petsc_pkg),) +PETSC_DOWNLOAD += --download-slepc-configure-arguments="--download-arpack --with-packages-download-dir=~/.petsc_pkg" +else +PETSC_DOWNLOAD += --download-slepc-configure-arguments="--download-arpack=https://github.com/prj-/arpack-ng/archive/9fc0c71.tar.gz" +endif +ifneq ($(TOOL_DYLIB_scalapack)$(TOOL_DYLIB_mumps),) +PETSC_DOWNLOAD += --download-scalapack --download-mumps PETSC_DOWNLOAD_C += --with-scalapack-dir=$(DIR_INSTALL_REAL) --with-mumps-dir=$(DIR_INSTALL_REAL) # --download-slepc-configure-arguments="--with-arpack-dir=$(DIR_INSTALL_REAL)" else -COMMON_FLAGS += --with-fc=0 +PETSC_DOWNLOAD += --download-superlu_dist +PETSC_DOWNLOAD_C += --with-superlu_dist-dir=$(DIR_INSTALL_REAL) +endif endif else COMMON_FLAGS += --with-cc='$(MPICC)' --with-cxx='$(MPICXX)' ifneq ($(MPIFC),) COMMON_FLAGS += --with-fc='$(MPIFC)' -PETSC_DOWNLOAD += --download-scalapack --download-mumps --download-slepc-configure-arguments="--download-arpack=https://github.com/prj-/arpack-ng/archive/b64dccb.tar.gz" +ifneq ($(wildcard ~/.petsc_pkg),) +PETSC_DOWNLOAD += --download-slepc-configure-arguments="--download-arpack --with-packages-download-dir=~/.petsc_pkg" +else +PETSC_DOWNLOAD += --download-slepc-configure-arguments="--download-arpack=https://github.com/prj-/arpack-ng/archive/9fc0c71.tar.gz" +endif +ifneq ($(TOOL_DYLIB_scalapack)$(TOOL_DYLIB_mumps),) +PETSC_DOWNLOAD += --download-scalapack --download-mumps PETSC_DOWNLOAD_C += --with-scalapack-dir=$(DIR_INSTALL_REAL) --with-mumps-dir=$(DIR_INSTALL_REAL) # --download-slepc-configure-arguments="--with-arpack-dir=$(DIR_INSTALL_REAL)" else -COMMON_FLAGS += --with-fc=0 PETSC_DOWNLOAD += --download-superlu_dist PETSC_DOWNLOAD_C += --with-superlu_dist-dir=$(DIR_INSTALL_REAL) endif endif +endif else ## On windows.... COMMON_FLAGS += --with-shared-libraries=0 \ @@ -115,6 +116,7 @@ COMMON_FLAGS += --with-shared-libraries=0 \ FFLAGS='$(FCFLAGS)' \ --with-mpi-lib='$(MPI_LIB)' \ --with-mpi-include='$(MPI_INC_DIR)' \ + CXXPPFLAGS='-I$(MPI_INC_DIR)' \ --with-mpiexec='/C/Program\ Files/Microsoft\ MPI/Bin/mpiexec' PETSC_DOWNLOAD += '--download-metis-cmake-arguments=-G "MSYS Makefiles"' \ '--download-parmetis-cmake-arguments=-G "MSYS Makefiles"' \ @@ -124,10 +126,20 @@ PETSC_DOWNLOAD += '--download-metis-cmake-arguments=-G "MSYS Makefiles"' \ '--download-hypre-configure-arguments=--build=x86_64-linux-gnu --host=x86_64-linux-gnu' ifneq ($(FC),) COMMON_FLAGS += --with-fc='$(FC)' -PETSC_DOWNLOAD += --download-scalapack --download-mumps --download-slepc-configure-arguments="--download-arpack=https://github.com/prj-/arpack-ng/archive/b64dccb.tar.gz" +ifneq ($(wildcard ~/.petsc_pkg),) +PETSC_DOWNLOAD += --download-slepc-configure-arguments="--download-arpack --with-packages-download-dir=~/.petsc_pkg" +else +PETSC_DOWNLOAD += --download-slepc-configure-arguments="--download-arpack=https://github.com/prj-/arpack-ng/archive/9fc0c71.tar.gz" +endif +ifneq ($(TOOL_DYLIB_scalapack)$(TOOL_DYLIB_mumps),) +PETSC_DOWNLOAD += --download-scalapack --download-mumps PETSC_DOWNLOAD_C += --with-scalapack-dir=$(DIR_INSTALL_REAL) --with-mumps-dir=$(DIR_INSTALL_REAL) # --download-slepc-configure-arguments="--with-arpack-dir=$(DIR_INSTALL_REAL)" else -COMMON_FLAGS += --with-fc=0 +PETSC_DOWNLOAD += --download-superlu_dist '--download-superlu_dist-cmake-arguments=-DMPI_GUESS_LIBRARY_NAME=MSMPI -G "MSYS Makefiles" -DXSDK_ENABLE_Fortran=OFF' +PETSC_DOWNLOAD_C += --with-superlu_dist-dir=$(DIR_INSTALL_REAL) +endif +else +PETSC_DOWNLOAD += '--download-superlu_dist-cmake-arguments=-DMPI_GUESS_LIBRARY_NAME=MSMPI -G "MSYS Makefiles"' endif endif @@ -148,8 +160,8 @@ all-local: @echo " make petsc-slepc " DIRPKG=../pkg -VERSION=3.16.1 -VERSION_SLEPC=3.16.0 +VERSION=3.17.0 +VERSION_SLEPC=3.016.2 PACKAGE=../pkg/petsc-$(VERSION).tar.gz SRCDIR=petsc-$(VERSION) MPI_DIR:=$(shell dirname $(MPI_INC_DIR)) @@ -222,8 +234,10 @@ $(SRCDIR)/tag-conf-real:$(SRCDIR)/tag-tar cd $(SRCDIR) && ./configure --prefix=$(DIR_INSTALL_REAL) \ $(FLAGS_CONF_PETSC_REAL) PETSC_ARCH=fr test -f $(SRCDIR)/fr/lib/petsc/conf/petscvariables + mkdir -p $(SRCDIR)/fc/externalpackages || true + cp -r $(SRCDIR)/fr/externalpackages/git.slepc $(SRCDIR)/fr/externalpackages/git.hpddm $(SRCDIR)/fc/externalpackages || true touch $@ -Make-petsc-download.mk:$(SRCDIR)/tag-install-real +Make-petsc-download.mk:$(SRCDIR)/tag-install-real test -e $(DIR_INSTALL_REAL)/lib/petsc/conf/petscvariables egrep 'PETSC_LIB_BASIC|SCALAPACK_|METIS_|MUMPS_|HPDDM_|HTOOL_|TETGEN_|SUPERLU_|MMG_|PTSCOTCH_|SUITESPARSE_' $(DIR_INSTALL_REAL)/lib/petsc/conf/petscvariables | sed 's/-I/ /g'|sort >$@ ifdef COMPLEX_CASE @@ -306,6 +320,8 @@ $(SRCDIR)/tag-tar:$(PACKAGE) -tar xzf $(PACKAGE) -C petsc-$(VERSION) --strip-components 1 ifeq ($(WIN32DLLTARGET),) cd petsc-$(VERSION) && patch -p1 < ../petsc-cmake-seq.patch && cd - +else + cd petsc-$(VERSION) && patch -p1 < ../petsc-scalapack.patch && cd - endif touch $@ $(PACKAGE): diff --git a/3rdparty/ff-petsc/Makefile-PETSc.inc b/3rdparty/ff-petsc/Makefile-PETSc.inc index 0f667b171..32364a220 100644 --- a/3rdparty/ff-petsc/Makefile-PETSc.inc +++ b/3rdparty/ff-petsc/Makefile-PETSc.inc @@ -3,37 +3,21 @@ FF_prefix_petsc=@FF_prefix_petsc@ FF_generic_petsc=@FF_generic_petsc@ CC=@CC@ CXX=@CXX@ -# FC : Fortran 90 compiler FC=@FC@ BLASINC=@BLASINC@ FFCMAKE=@ff_cmake@ BLASLIBS=@BLASLIBS@ LAPACKLIBS=@LAPACKLIBS@ COMPILE_OPENBLAS=@COMPILE_OPENBLAS@ -# Use: -# -DAdd_ if your Fortran compiler adds an underscore at the end -# of symbols, -# -DAdd__ if your Fortran compiler adds 2 underscores, -# -# -DUPPER if your Fortran compiler uses uppercase symbols -# -# leave empty if your Fortran compiler does not change the symbols. -# CFLAGS=@CFLAGS@ FCFLAGS=@FCFLAGS@ -CFLAGSF77=@CFLAGSF77@ MPI_INCLUDE=@MPI_INCLUDE@ MPI_INC_DIR=@MPI_INC_DIR@ MPI_LIB=@MPI_LIB@ -MPI_LIBC=@MPI_LIBC@ -MPI_LIBFC=@MPI_LIBFC@ -MPI_LIB_DIRS=@MPI_LIB_DIRS@ MPICC=@MPICC@ MPICXX=@MPICXX@ MPIFC=@MPIFC@ -MPIPROG=@MPIPROG@ MPIRUN=@MPIRUN@ -MPISCRIPT=@MPISCRIPT@ -prefix=@prefix@ WIN32DLLTARGET=@WIN32DLLTARGET@ - +TOOL_DYLIB_scalapack=@TOOL_DYLIB_scalapack@ +TOOL_DYLIB_mumps=@TOOL_DYLIB_mumps@ diff --git a/3rdparty/ff-petsc/petsc-cmake-seq.patch b/3rdparty/ff-petsc/petsc-cmake-seq.patch index cb4d7636d..b2ab9dc63 100644 --- a/3rdparty/ff-petsc/petsc-cmake-seq.patch +++ b/3rdparty/ff-petsc/petsc-cmake-seq.patch @@ -1,3 +1,20 @@ +diff --git a/config/BuildSystem/config/packages/SuperLU.py b/config/BuildSystem/config/packages/SuperLU.py +index 217743097e..239ac7806d 100644 +--- a/config/BuildSystem/config/packages/SuperLU.py ++++ b/config/BuildSystem/config/packages/SuperLU.py +@@ -52,5 +52,12 @@ class Configure(config.package.CMakePackage): + if item.find('CMAKE_C_FLAGS') >= 0 or item.find('CMAKE_CXX_FLAGS') >= 0: + args[place]=item[:-1]+' '+mangledef+'"' + ++ mpicc = self.framework.getMakeMacro('MPICC_SHOW') ++ mpicxx = self.framework.getMakeMacro('MPICXX_SHOW') ++ if mpicc and mpicxx: ++ args = self.rmArgsStartsWith(args,['-DCMAKE_CXX_COMPILER','-DCMAKE_C_COMPILER']) ++ args.append('-DCMAKE_C_COMPILER="'+mpicc.split(None, 1)[0]+'"') ++ args.append('-DCMAKE_CXX_COMPILER="'+mpicxx.split(None, 1)[0]+'"') ++ + return args + diff --git a/config/BuildSystem/config/packages/metis.py b/config/BuildSystem/config/packages/metis.py index b2d66ab23f..08219fb317 100644 --- a/config/BuildSystem/config/packages/metis.py @@ -16,7 +33,7 @@ index b2d66ab23f..08219fb317 100644 def configureLibrary(self): diff --git a/config/BuildSystem/config/packages/mmg.py b/config/BuildSystem/config/packages/mmg.py -index 43fe0c8981..a574b06fe3 100644 +index dc8ce9817f..4ba1aec2f6 100644 --- a/config/BuildSystem/config/packages/mmg.py +++ b/config/BuildSystem/config/packages/mmg.py @@ -28,4 +28,10 @@ class Configure(config.package.CMakePackage): @@ -31,10 +48,10 @@ index 43fe0c8981..a574b06fe3 100644 + args.append('-DCMAKE_CXX_COMPILER="'+mpicxx.split(None, 1)[0]+'"') return args diff --git a/src/mat/impls/aij/mpi/mumps/mumps.c b/src/mat/impls/aij/mpi/mumps/mumps.c -index 3226ffb961..95f38a899f 100644 +index 8dc6b3fa3e..6d2f3f9bb2 100644 --- a/src/mat/impls/aij/mpi/mumps/mumps.c +++ b/src/mat/impls/aij/mpi/mumps/mumps.c -@@ -1792,11 +1792,7 @@ PetscErrorCode PetscSetMUMPSFromOptions(Mat F, Mat A) +@@ -1770,11 +1770,7 @@ PetscErrorCode PetscSetMUMPSFromOptions(Mat F, Mat A) see https://github.com/pmodels/mpich/issues/5589. This bug was fixed by https://github.com/pmodels/mpich/pull/5590. In short, we could not use distributed RHS with MPICH until v4.0b1. */ @@ -43,179 +60,6 @@ index 3226ffb961..95f38a899f 100644 -#else - mumps->ICNTL20 = 10; /* Distributed dense RHS*/ -#endif - ierr = PetscOptionsMUMPSInt("-mat_mumps_icntl_20","ICNTL(20): give mumps centralized (0) or distributed (10) dense right-hand sides","None",mumps->ICNTL20,&mumps->ICNTL20,&flg);CHKERRQ(ierr); - if (flg && mumps->ICNTL20 != 10 && mumps->ICNTL20 != 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"ICNTL(20)=%d is not supported by the PETSc/MUMPS interface. Allowed values are 0, 10\n",(int)mumps->ICNTL20); + PetscCall(PetscOptionsMUMPSInt("-mat_mumps_icntl_20","ICNTL(20): give mumps centralized (0) or distributed (10) dense right-hand sides","None",mumps->ICNTL20,&mumps->ICNTL20,&flg)); + PetscCheckFalse(flg && mumps->ICNTL20 != 10 && mumps->ICNTL20 != 0,PETSC_COMM_SELF,PETSC_ERR_SUP,"ICNTL(20)=%d is not supported by the PETSc/MUMPS interface. Allowed values are 0, 10",(int)mumps->ICNTL20); #if PETSC_PKG_MUMPS_VERSION_LT(5,3,0) -diff --git a/config/BuildSystem/config/compilers.py b/config/BuildSystem/config/compilers.py -index 24780f1f9b..eb6d7c515f 100644 ---- a/config/BuildSystem/config/compilers.py -+++ b/config/BuildSystem/config/compilers.py -@@ -364,7 +364,7 @@ class Configure(config.base.Configure): - # Check for '-rpath /sharedlibpath/ or -R /sharedlibpath/' - if arg == '-rpath' or arg == '-R': - lib = next(argIter) -- if lib.startswith('-'): continue # perhaps the path was striped due to quotes? -+ if lib.startswith('-') or lib.startswith('@loader_path'): continue # perhaps the path was striped due to quotes? - if lib.startswith('"') and lib.endswith('"') and lib.find(' ') == -1: lib = lib[1:-1] - lib = os.path.abspath(lib) - if lib in skipdefaultpaths: continue -@@ -964,7 +964,7 @@ class Configure(config.base.Configure): - # Check for '-rpath /sharedlibpath/ or -R /sharedlibpath/' - if arg == '-rpath' or arg == '-R': - lib = next(argIter) -- if lib.startswith('-'): continue # perhaps the path was striped due to quotes? -+ if lib.startswith('-') or lib.startswith('@loader_path'): continue # perhaps the path was striped due to quotes? - if lib.startswith('"') and lib.endswith('"') and lib.find(' ') == -1: lib = lib[1:-1] - lib = os.path.abspath(lib) - if lib in skipdefaultpaths: continue -@@ -1394,7 +1394,7 @@ Otherwise you need a different combination of C, C++, and Fortran compilers") - if arg == '-rpath' or arg == '-R': - lib = next(argIter) - if lib == '\\': lib = next(argIter) -- if lib.startswith('-'): continue # perhaps the path was striped due to quotes? -+ if lib.startswith('-') or lib.startswith('@loader_path'): continue # perhaps the path was striped due to quotes? - if lib.startswith('"') and lib.endswith('"') and lib.find(' ') == -1: lib = lib[1:-1] - lib = os.path.abspath(lib) - if lib in skipdefaultpaths: continue -diff --git a/config/BuildSystem/config/packages/hpddm.py b/config/BuildSystem/config/packages/hpddm.py -index eacc8521e6..0e76e71be9 100644 ---- a/config/BuildSystem/config/packages/hpddm.py -+++ b/config/BuildSystem/config/packages/hpddm.py -@@ -3,7 +3,7 @@ import config.package - class Configure(config.package.Package): - def __init__(self,framework): - config.package.Package.__init__(self,framework) -- self.gitcommit = '832303ecdffd25c34206e5392fb3cf85960490a2' # main oct-09-2021 -+ self.gitcommit = '5fd4ea2cec52b491874ccd3907b53f92f43e5093' # main nov-03-2021 - self.download = ['git://https://github.com/hpddm/hpddm','https://github.com/hpddm/hpddm/archive/'+self.gitcommit+'.tar.gz'] - self.minversion = '2.0.8' - self.versionname = 'HPDDM_VERSION' -@@ -23,13 +23,14 @@ class Configure(config.package.Package): - config.package.Package.setupDependencies(self,framework) - self.setCompilers = framework.require('config.setCompilers',self) - self.sharedLibraries = framework.require('PETSc.options.sharedLibraries',self) -- self.mathlib = framework.require('config.packages.mathlib',self) -+ self.blasLapack = framework.require('config.packages.BlasLapack',self) - self.cxxlibs = framework.require('config.packages.cxxlibs',self) -+ self.mathlib = framework.require('config.packages.mathlib',self) -+ self.flibs = framework.require('config.packages.flibs',self) -+ self.deps = [self.blasLapack,self.cxxlibs,self.mathlib,self.flibs] # KSPHPDDM - self.mpi = framework.require('config.packages.MPI',self) -- self.blasLapack = framework.require('config.packages.BlasLapack',self) - self.slepc = framework.require('config.packages.slepc',self) -- self.deps = [self.blasLapack,self.cxxlibs,self.mathlib] -- self.odeps = [self.mpi,self.slepc] -+ self.odeps = [self.mpi,self.slepc] # KSPHPDDM + PCHPDDM - return - - def Install(self): -@@ -63,50 +64,44 @@ class Configure(config.package.Package): - except RuntimeError as e: - raise RuntimeError('Error copying HPDDM: '+str(e)) - # SLEPc dependency -- if self.mpi.found: -- if self.slepc.found: -- if self.checkSharedLibrariesEnabled(): -- slepcbuilddep = '' -- ldflags = ' '.join(self.setCompilers.sharedLibraryFlags) -- # how can we get the slepc lib? Eventually, we may want to use the variables from the framework -- #cxxflags += self.headers.toStringNoDupes(self.slepc.dinclude) -- #ldflags += self.libraries.toString(self.slepc.dlib) -- dinclude = [incDir]+self.dinclude+[os.path.join(PETSC_DIR,'include'),os.path.join(PETSC_DIR,PETSC_ARCH,'include'),os.path.join(self.petscdir.dir,'include'),os.path.join(self.packageDir,'include')] -- dlib = [os.path.join(libDir,'libslepc.'+self.setCompilers.sharedLibraryExt)] -- cxxflags += ' '+self.headers.toStringNoDupes(dinclude) -- ldflags += ' '+self.libraries.toStringNoDupes(dlib) -- slepcbuilddep = 'slepc-install slepc-build' -- oldFlags = self.compilers.CXXPPFLAGS -- self.compilers.CXXPPFLAGS += ' -I'+incDir -- self.checkVersion() -- self.compilers.CXXPPFLAGS = oldFlags -- # check for Windows-specific define -- if self.sharedLibraries.getMakeMacro('PETSC_DLL_EXPORTS'): -- cxxflags += ' -Dpetsc_EXPORTS' -- # need to explicitly link to PETSc and BLAS on Windows -- ldflags += ' '+self.libraries.toStringNoDupes([os.path.join(libDir,'libpetsc.'+self.setCompilers.sharedLibraryExt),self.libraries.toStringNoDupes(self.blasLapack.lib)]) -- self.addMakeRule('hpddmbuild',slepcbuilddep,\ -- ['@echo "*** Building and installing HPDDM ***"',\ -- '@${RM} -f ${PETSC_ARCH}/lib/petsc/conf/hpddm.errorflg',\ -- '@'+cxx+' '+cxxflags+' '+self.packageDir+'/interface/hpddm_petsc.cpp '+ldflags+' -o '+libDir+os.path.join('/libhpddm_petsc.'+self.setCompilers.sharedLibraryExt)+' > ${PETSC_ARCH}/lib/petsc/conf/hpddm.log 2>&1 || \\\n\ -- (echo "**************************ERROR*************************************" && \\\n\ -- echo "Error building HPDDM. Check ${PETSC_ARCH}/lib/petsc/conf/hpddm.log" && \\\n\ -- echo "********************************************************************" && \\\n\ -- touch '+os.path.join('${PETSC_ARCH}','lib','petsc','conf','hpddm.errorflg')+' && \\\n\ -- exit 1)']) -- if self.argDB['prefix'] and not 'package-prefix-hash' in self.argDB: -- self.addMakeRule('hpddm-build','') -- self.addMakeRule('hpddm-install','hpddmbuild') -- return self.installDir -- else: -- self.addMakeRule('hpddm-build','hpddmbuild') -- self.addMakeRule('hpddm-install','') -- return self.installDir -+ if self.slepc.found: -+ if self.checkSharedLibrariesEnabled(): -+ slepcbuilddep = '' -+ ldflags = ' '.join(self.setCompilers.sharedLibraryFlags) -+ cxxflags += ' '+self.headers.toStringNoDupes(self.dinclude+[os.path.join(PETSC_DIR,'include'),os.path.join(PETSC_DIR,PETSC_ARCH,'include')]) -+ ldflags += ' '+self.libraries.toStringNoDupes(self.dlib) -+ slepcbuilddep = 'slepc-install slepc-build' -+ oldFlags = self.compilers.CXXPPFLAGS -+ self.compilers.CXXPPFLAGS += ' -I'+incDir -+ self.checkVersion() -+ self.compilers.CXXPPFLAGS = oldFlags -+ # check for Windows-specific define -+ if self.sharedLibraries.getMakeMacro('PETSC_DLL_EXPORTS'): -+ cxxflags += ' -Dpetsc_EXPORTS' -+ # need to explicitly link to PETSc and BLAS on Windows -+ ldflags += ' '+self.libraries.toStringNoDupes([os.path.join(libDir,'libpetsc.'+self.setCompilers.sharedLibraryExt),self.libraries.toStringNoDupes(self.blasLapack.lib)]) -+ self.addMakeRule('hpddmbuild',slepcbuilddep,\ -+ ['@echo "*** Building and installing HPDDM ***"',\ -+ '@${RM} -f ${PETSC_ARCH}/lib/petsc/conf/hpddm.errorflg',\ -+ '@'+cxx+' '+cxxflags+' '+os.path.join(self.packageDir,'interface','hpddm_petsc.cpp')+' '+ldflags+' -o '+os.path.join(libDir,'libhpddm_petsc.'+self.setCompilers.sharedLibraryExt)+' > ${PETSC_ARCH}/lib/petsc/conf/hpddm.log 2>&1 || \\\n\ -+ (echo "**************************ERROR*************************************" && \\\n\ -+ echo "Error building HPDDM. Check ${PETSC_ARCH}/lib/petsc/conf/hpddm.log" && \\\n\ -+ echo "********************************************************************" && \\\n\ -+ touch '+os.path.join('${PETSC_ARCH}','lib','petsc','conf','hpddm.errorflg')+' && \\\n\ -+ exit 1)']) -+ if self.argDB['prefix'] and not 'package-prefix-hash' in self.argDB: -+ self.addMakeRule('hpddm-build','') -+ self.addMakeRule('hpddm-install','hpddmbuild') -+ return self.installDir - else: -- self.logPrintBox('***** WARNING: Skipping PCHPDDM installation,\n\ --remove --with-shared-libraries=0 *****') -+ self.addMakeRule('hpddm-build','hpddmbuild') -+ self.addMakeRule('hpddm-install','') -+ return self.installDir - else: -- self.logPrintBox('***** WARNING: Compiling HPDDM with MPI but no SLEPc,\n\ -+ self.logPrintBox('***** WARNING: Skipping PCHPDDM installation,\n\ -+remove --with-shared-libraries=0 *****') -+ else: -+ self.logPrintBox('***** WARNING: Compiling HPDDM without SLEPc,\n\ - PCHPDDM won\'t be available, unless reconfiguring with --download-slepc *****') - self.addMakeRule('hpddm-build','') - self.addMakeRule('hpddm-install','') -diff --git a/config/BuildSystem/config/packages/slepc.py b/config/BuildSystem/config/packages/slepc.py -index bdf0bbe4be..ec77d1e06a 100644 ---- a/config/BuildSystem/config/packages/slepc.py -+++ b/config/BuildSystem/config/packages/slepc.py -@@ -27,6 +27,9 @@ class Configure(config.package.Package): - self.installdir = framework.require('PETSc.options.installDir',self) - self.parch = framework.require('PETSc.options.arch',self) - self.scalartypes = framework.require('PETSc.options.scalarTypes',self) -+ self.cuda = framework.require('config.packages.cuda',self) -+ self.thrust = framework.require('config.packages.thrust',self) -+ self.odeps = [self.cuda,self.thrust] - return - - def Install(self): -@@ -51,6 +54,8 @@ class Configure(config.package.Package): - else: - configargs = '' - -+ self.include = [os.path.join(prefix,'include')] -+ self.lib = [os.path.join(prefix,'lib','libslepc.'+self.setCompilers.sharedLibraryExt)] - self.addDefine('HAVE_SLEPC',1) - self.addMakeMacro('SLEPC','yes') - self.addMakeRule('slepcbuild','', \ diff --git a/3rdparty/ff-petsc/petsc-scalapack.patch b/3rdparty/ff-petsc/petsc-scalapack.patch new file mode 100644 index 000000000..31329d0a8 --- /dev/null +++ b/3rdparty/ff-petsc/petsc-scalapack.patch @@ -0,0 +1,94 @@ +diff --git a/config/BuildSystem/config/packages/scalapack.py b/config/BuildSystem/config/packages/scalapack.py +index 54334c571f..fee9bbf620 100644 +--- a/config/BuildSystem/config/packages/scalapack.py ++++ b/config/BuildSystem/config/packages/scalapack.py +@@ -1,10 +1,11 @@ + import config.package + +-class Configure(config.package.CMakePackage): ++class Configure(config.package.Package): + def __init__(self, framework): +- config.package.CMakePackage.__init__(self, framework) +- self.gitcommit = '5bad7487f496c811192334640ce4d3fc5f88144b' # main mar-18-2022 +- self.download = ['git://https://github.com/Reference-ScaLAPACK/scalapack','https://github.com/Reference-ScaLAPACK/scalapack/archive/'+self.gitcommit+'.tar.gz'] ++ config.package.Package.__init__(self, framework) ++ self.gitcommit = 'v2.2.0-p1' # modification to avoid calling zdotc, zladiv on macOS ++ self.download = ['git://https://bitbucket.org/petsc/pkg-scalapack','https://bitbucket.org/petsc/pkg-scalapack/get/'+self.gitcommit+'.tar.gz'] ++ self.downloaddirnames = ['petsc-pkg-scalapack','scalapack'] + self.includes = [] + self.liblist = [['libscalapack.a'], + ['libmkl_scalapack_lp64.a','libmkl_blacs_intelmpi_lp64.a'], +@@ -16,22 +17,66 @@ class Configure(config.package.CMakePackage): + self.buildLanguages = ['FC'] + self.precisions = ['single','double'] + self.downloadonWindows= 1 +- self.makerulename = 'scalapack' + return + + def setupDependencies(self, framework): +- config.package.CMakePackage.setupDependencies(self, framework) ++ config.package.Package.setupDependencies(self, framework) + self.flibs = framework.require('config.packages.flibs',self) + self.blasLapack = framework.require('config.packages.BlasLapack',self) + self.mpi = framework.require('config.packages.MPI',self) + self.deps = [self.mpi, self.blasLapack, self.flibs] + return + +- def formCMakeConfigureArgs(self): +- args = config.package.CMakePackage.formCMakeConfigureArgs(self) +- args.append('-DLAPACK_LIBRARIES="'+self.libraries.toString(self.blasLapack.dlib)+'"') +- args.append('-DSCALAPACK_BUILD_TESTS=OFF') +- return args ++ def Install(self): ++ import os ++ g = open(os.path.join(self.packageDir,'SLmake.inc'),'w') ++ g.write('SCALAPACKLIB = '+'libscalapack.'+self.setCompilers.AR_LIB_SUFFIX+' \n') ++ g.write('LIBS = '+self.libraries.toString(self.blasLapack.dlib)+'\n') ++ g.write('MPIINC = '+self.headers.toString(self.mpi.include)+'\n') ++ # this mangling information is for both BLAS and the Fortran compiler so cannot use the BlasLapack mangling flag ++ if self.compilers.fortranManglingDoubleUnderscore: ++ fdef = '-Df77IsF2C -DFortranIsF2C' ++ elif self.compilers.fortranMangling == 'underscore': ++ fdef = '-DAdd_' ++ elif self.compilers.fortranMangling == 'caps': ++ fdef = '-DUpCase' ++ else: ++ fdef = '-DNoChange' ++ g.write('CDEFS = '+fdef+'\n') ++ self.pushLanguage('FC') ++ g.write('FC = '+self.getCompiler()+'\n') ++ g.write('FCFLAGS = '+self.updatePackageFFlags(self.getCompilerFlags())+'\n') ++ g.write('FCLOADER = '+self.getLinker()+'\n') ++ g.write('FCLOADFLAGS = '+self.getLinkerFlags()+'\n') ++ self.popLanguage() ++ self.pushLanguage('C') ++ g.write('CC = '+self.getCompiler()+'\n') ++ g.write('CCFLAGS = '+self.updatePackageCFlags(self.getCompilerFlags())+' $(MPIINC)\n') ++ noopt = self.checkNoOptFlag() ++ g.write('CFLAGS = '+noopt+ ' '+self.getSharedFlag(self.getCompilerFlags())+' '+self.getPointerSizeFlag(self.getCompilerFlags())+' '+self.getWindowsNonOptFlags(self.getCompilerFlags())+'\n') ++ ++ g.write('CCLOADER = '+self.getLinker()+'\n') ++ g.write('CCLOADFLAGS = '+self.getLinkerFlags()+'\n') ++ self.popLanguage() ++ g.write('ARCH = '+self.setCompilers.AR+'\n') ++ g.write('ARCHFLAGS = '+self.setCompilers.AR_FLAGS+'\n') ++ g.write('RANLIB = '+self.setCompilers.RANLIB+'\n') ++ g.close() ++ ++ if self.installNeeded('SLmake.inc'): ++ try: ++ output,err,ret = config.package.Package.executeShellCommand('cd '+self.packageDir+' && '+self.make.make+' -f Makefile.parallel cleanlib', timeout=60, log = self.log) ++ except RuntimeError as e: ++ pass ++ try: ++ self.logPrintBox('Compiling and installing ScaLAPACK; this may take several minutes') ++ libDir = os.path.join(self.installDir, self.libdir) ++ output,err,ret = config.package.Package.executeShellCommand('cd '+self.packageDir+' && '+self.make.make_jnp+' -f Makefile.parallel lib && mkdir -p '+libDir+' && cp libscalapack.* '+libDir, timeout=2500, log = self.log) ++ except RuntimeError as e: ++ self.logPrint('Error running make on ScaLAPACK: '+str(e)) ++ raise RuntimeError('Error running make on ScaLAPACK') ++ self.postInstall(output,'SLmake.inc') ++ return self.installDir + + def getSearchDirectories(self): + '''Generate list of possible locations of ScaLAPACK''' diff --git a/3rdparty/getall b/3rdparty/getall index 55fc969db..d3ee7f591 100755 --- a/3rdparty/getall +++ b/3rdparty/getall @@ -171,10 +171,10 @@ download('parmmg','https://github.com/prj-/ParMmg/archive/9cb2f7a22ef590d196d028 'https://github.com/prj-', 'parmmg.zip', '32035de70272121137c0869e8c49e4bd'); -download('PETSc','https://www.mcs.anl.gov/petsc/mirror/release-snapshots/petsc-3.16.1.tar.gz', +download('PETSc','https://www.mcs.anl.gov/petsc/mirror/release-snapshots/petsc-3.17.0.tar.gz', 'https://www.mcs.anl.gov/petsc/mirror/release-snapshots/', - 'petsc-3.16.1.tar.gz', - '14df10a025d3ea2c77c59f370b3646f4'); + 'petsc-3.17.0.tar.gz', + '54ecb6055e7e219aff2c30d99f2f603e'); download('htool','https://github.com/htool-ddm/htool/archive/f0a1542a8c408e1da02478a9843bb12815a680ae.zip', 'https://github.com/htool-ddm/', diff --git a/3rdparty/mumps/Makefile-mumps-5.0.2.inc b/3rdparty/mumps/Makefile-mumps-5.0.2.inc index 211314b1c..1b46e5efc 100644 --- a/3rdparty/mumps/Makefile-mumps-5.0.2.inc +++ b/3rdparty/mumps/Makefile-mumps-5.0.2.inc @@ -153,7 +153,7 @@ CDEFS = @CFLAGSF77@ # Microsoft MPI. mpif.h contains INTEGER MPI_FLOAT_INT / PARAMETER # (MPI_FLOAT_INT=z'8c000000') which requires this. -OPTF = -O @FFLAGS@ @MPI_INCLUDE@ @NO_RANGE_CHECK@ +OPTF = -O @FCFLAGS@ @MPI_INCLUDE@ @NO_RANGE_CHECK@ OPTC = -O -I. @CFLAGS@ @MPI_INCLUDE@ OPTL = -O @FFLAGS@ @MPI_LIBFC@ diff --git a/3rdparty/scalapack/SLmake-scalapack.inc b/3rdparty/scalapack/SLmake-scalapack.inc index 7effb8b6e..6accab241 100644 --- a/3rdparty/scalapack/SLmake-scalapack.inc +++ b/3rdparty/scalapack/SLmake-scalapack.inc @@ -34,7 +34,7 @@ NOOPT = -O0 @CNOFLAGS@ # FFCS - add path to mpi.h (required for MacOS 10.8 + MacPorts OpenMPI) # FFCS - added @CNOFLAGS@ according to upstream changes CCFLAGS = -O3 -Wreturn-type @CFLAGS@ -I'@MPI_INC_DIR@' @CNOFLAGS@ -Wno-implicit-function-declaration -FCFLAGS = -O3 @CNOFLAGS@ +FCFLAGS = -O3 @CNOFLAGS@ @FCFLAGS@ FCLOADER = $(FC) CCLOADER = $(CC) FCLOADFLAGS = $(FCFLAGS) diff --git a/AutoGeneratedFile.tar.gz b/AutoGeneratedFile.tar.gz index 6e4f2dd1c..17e9d1870 100644 Binary files a/AutoGeneratedFile.tar.gz and b/AutoGeneratedFile.tar.gz differ diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f19d7b53..1a7794e82 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,18 +36,78 @@ All notable changes to this project will be documented in this file. ### Fixed - +## [4.11] +### Added +- add computation scalar product of R3 example : ( N'*Tl) +- add tools to do compution with R3 vector see tutorial/calculus.edp +- add an example tutorial/tgv-test.edp see see what tgv do on matrix build. +- add R3 Th.be(k).N to get the normal of boundary element (in all mesh type) +- add R3 Th.be(k)[i].P to get the point (R3) of boundary vertices +- add R3 Th.be(k).measure to get the measure of the boundary elment +- add projection function to a mesh , meshL, MeshS or mesh3 with return a R3 point +- see new example dist-projection.edp example in exemples +- add dxx, dyy, dzz, dxy, .. on P2L finite element +- add tools to compute solid angle : let R3 O; a given point, Th3 a mesh3 and ThS a meshS. + solidangle(O,Th3.be(ke)) // triangular face is the boundary face + solidangle(O,Th3[k],nuface) // triangular face is face nuface of tet Th3[k] + solidangle(O,ThS[k]) // triangular face is ThS[k] + solidangle(O,A,B,C) // triangular face i (A,B,C) + Volume(O,Th3.be(ke)) // O, triangular face is the boundary face + Volume(O,Th3[k],nuface) // O, triangular face is face nuface of tet Th3[k] + Volume(O,ThS[k]) // O, triangular face is ThS[k] + Volume(O,A,B,C) // (O,A,B,C) tet .. +- in bem pluging add array of HMatrix + +- examples/3d/Connectivite-3d.edp or /3dSurf/Connectivite-S.edp of test. +- 3 function mapk, mapkk, mapkk to set a function in fourier space with k parametre + R3 K; // le fourier variable allway 3d (sorry) + int n1=16,n2=8, n3=4; + real[int] tab1(nx,tab2(nx*ny),tab3(nx*ny*nz); + mapk(tab1,K,sqr(K.x)); + mapkk(tab2,ny,K,K.norm2); + mapkkk(tab3,ny,nz,K,K.norm2); + // Remark you can change K by P (current point) +- in SurfaceMesh.ipd fonction to build a Isocaedron and a Sphere from this Isocaedron +- new finite element on MeshS this finite element is the ortogonal of RT0 on surface, or + Nelelec Finite Element on triangle with one DoF per mesh edge and where the DoF is the + current on Edge in orientate edge by number of vertices. +- plugin Element_P3pnc for new 2d finite element P3pnc (P3 + 2 bulles) noncoforming (continuite of P2 mod) + and add 2 examples with this new finite element + examples/plugin/cavityNewtowP3pnc.edp examples/plugin/testFE-P3pnc.edp +- function to set dirichlet Boundary conditon on matrix A (real ou compex) trought an real[int] + (if none zero => set BC ) + setBC(A,au1[],-2); and the example + examples/3d/Elasticity-simple-support-BC.edp + +### Changed +- the beaviour of linear solver UMFPACK, CHOLMOD in case of error , now FreeFEm exit on ExecError like in MUMPS +- PETSc 3.17.0 + +### Deprecated +- + +### Removed +-map function in plugin dfft + +### Fixed +- pow(int,int) now call int version not complex version.. +- correct the normal the N implicite variable on meshL case +- correct version dump in banner FreeFem++ - version 4.10 (V ... +- correct in CPU time on big mesh due to do bad HCode in HashTable.hpp +- bug in array of finite element on meshhS, meshL (ie. `fespace Vh(ThS,[P1,P1]);` ) + + ## [4.10] ### Added - ridgeangle named parameter in ExtractMeshL in msh3 plugin - DG formulation in 1d : add integral of all border of element : `intallBE(ThL)` and unified the notation by adding - `intallBE(ThS)` , `intallBE(Th2)`, `intallBE(Th3)` - + `intallBE(ThS)` , `intallBE(Th2)`, `intallBE(Th3)` `nuVertex` of now the vertex number of element in intallBE0d integral `BoundaryBE`, `InternalBE` to know if border element (BE) is on true boundary of not. update `nElementonB` in case on no manifold data (value greater > 2) in meshL, MeshS case .. - add code to use jump, mean of test functuon on MeshL case. ( not in mesh3 ) to compute RHS. -- add getcwd() function in shell plugin to ghet the current working dir + add code to use jump, mean of test functuon on MeshL case. ( not in mesh3 ) to compute RHS. +- add getcwd() function in shell plugin to get the current working dir - add nuVertex to get the vextex on element in some int? ### Changed @@ -119,7 +179,7 @@ All notable changes to this project will be documented in this file. - Bilaplacian example using Morley FE with PETSc, see `examples/hpddm/bilaplacian-2d-PETSc.edp` - Oseen problem preconditioned by PCD, see `examples/hpddm/oseen-2d-PETSc.edp` - SLEPc polynomial eigenvalue solver `PEPSolve()` -- add trivail example to check periodic boundary condition on meshS , meshL , mesh3 +- add trivial example to check periodic boundary condition on meshS , meshL , mesh3 examples/3d/periodic3.edp examples/3dSurf/periodicS.edp examples/3dCurve/periodicL.edp @@ -451,7 +511,8 @@ All notable changes to this project will be documented in this file. ### Changed - The main distribution is now on Github -[Unreleased]: https://github.com/FreeFem/FreeFem-sources/compare/v4.10..develop +[Unreleased]: https://github.com/FreeFem/FreeFem-sources/compare/v4.11..develop +[4.11]: https://github.com/FreeFem/FreeFem-sources/compare/v4.10..v4.11 [4.10]: https://github.com/FreeFem/FreeFem-sources/compare/v4.9..v4.10 [4.9]: https://github.com/FreeFem/FreeFem-sources/compare/v4.8..v4.9 [4.8]: https://github.com/FreeFem/FreeFem-sources/compare/v4.7-1..v4.8 diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 000000000..408c98d42 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,157 @@ +### GNU LESSER GENERAL PUBLIC LICENSE + +Version 3, 29 June 2007 + +Copyright (C) 2007 Free Software Foundation, Inc. + + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + +This version of the GNU Lesser General Public License incorporates the +terms and conditions of version 3 of the GNU General Public License, +supplemented by the additional permissions listed below. + +#### 0. Additional Definitions. + +As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the +GNU General Public License. + +"The Library" refers to a covered work governed by this License, other +than an Application or a Combined Work as defined below. + +An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + +A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + +The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + +The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + +#### 1. Exception to Section 3 of the GNU GPL. + +You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + +#### 2. Conveying Modified Versions. + +If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + +- a) under this License, provided that you make a good faith effort + to ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or +- b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + +#### 3. Object Code Incorporating Material from Library Header Files. + +The object code form of an Application may incorporate material from a +header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + +- a) Give prominent notice with each copy of the object code that + the Library is used in it and that the Library and its use are + covered by this License. +- b) Accompany the object code with a copy of the GNU GPL and this + license document. + +#### 4. Combined Works. + +You may convey a Combined Work under terms of your choice that, taken +together, effectively do not restrict modification of the portions of +the Library contained in the Combined Work and reverse engineering for +debugging such modifications, if you also do each of the following: + +- a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. +- b) Accompany the Combined Work with a copy of the GNU GPL and this + license document. +- c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. +- d) Do one of the following: + - 0) Convey the Minimal Corresponding Source under the terms of + this License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + - 1) Use a suitable shared library mechanism for linking with + the Library. A suitable mechanism is one that (a) uses at run + time a copy of the Library already present on the user's + computer system, and (b) will operate properly with a modified + version of the Library that is interface-compatible with the + Linked Version. +- e) Provide Installation Information, but only if you would + otherwise be required to provide such information under section 6 + of the GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the Application + with a modified version of the Linked Version. (If you use option + 4d0, the Installation Information must accompany the Minimal + Corresponding Source and Corresponding Application Code. If you + use option 4d1, you must provide the Installation Information in + the manner specified by section 6 of the GNU GPL for conveying + Corresponding Source.) + +#### 5. Combined Libraries. + +You may place library facilities that are a work based on the Library +side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + +- a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities, conveyed under the terms of this License. +- b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + +#### 6. Revised Versions of the GNU Lesser General Public License. + +The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +as you received it specifies that a certain numbered version of the +GNU Lesser General Public License "or any later version" applies to +it, you have the option of following the terms and conditions either +of that published version or of any later version published by the +Free Software Foundation. If the Library as you received it does not +specify a version number of the GNU Lesser General Public License, you +may choose any version of the GNU Lesser General Public License ever +published by the Free Software Foundation. + +If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. \ No newline at end of file diff --git a/Makefile.am b/Makefile.am index 8adc28f90..991fffa7b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -136,7 +136,8 @@ idp/ffddm_functions.idp \ idp/macro_ddm_substructuring.idp \ idp/ffddm_parameters.idp \ idp/macro_ddm.idp \ -idp/CC.idp +idp/CC.idp \ +idp/ElasticLaw2d.idp @@ -281,8 +282,8 @@ bin/script/PostInstall.sh:./Makefile bin/script/PostInstall.m4 FreeFEM-documentation.pdf:Makefile if DOWNLOAD -rm FreeFEM-documentation.pdf.md5 - -$(WGET) https://doc.freefem.org/pdf/FreeFEM-documentation.pdf.md5 - -md5sum -c FreeFEM-documentation.pdf.md5 || (rm FreeFEM-documentation.pdf ; $(WGET) https://doc.freefem.org/pdf/FreeFEM-documentation.pdf) + -$(WGET) https://github.com/FreeFem/FreeFem-doc/raw/pdf/FreeFEM-documentation.pdf.md5 + -md5sum -c FreeFEM-documentation.pdf.md5 || (rm FreeFEM-documentation.pdf ; $(WGET) https://github.com/FreeFem/FreeFem-doc/raw/pdf/FreeFEM-documentation.pdf) else touch FreeFEM-documentation.pdf echo "no downloaded documentation" diff --git a/README.md b/README.md index 2411196c9..0f8bfec48 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ - +
diff --git a/bin/Get-list-dylib-use b/bin/Get-list-dylib-use index 676fa60d8..8d8873682 100755 --- a/bin/Get-list-dylib-use +++ b/bin/Get-list-dylib-use @@ -9,8 +9,8 @@ # egrep '.dylib$'| sort -u \ #|awk -F/ '{ if (f[$NF]!=1 ) print $0; f[$NF]=1;}' ( -(echo export DYLD_PRINT_LIBRARIES=1;ls plugin/seq/*.dylib|grep -v fflapack| awk '{print "src/nw/FreeFem++ -check_plugin ",$0}' )|sh 2>&1|awk '/dyld: loaded:/ {print $3}'| sort -u -(echo export DYLD_PRINT_LIBRARIES=1;ls plugin/mpi/*.dylib|grep -v fflapack| awk '{print "src/mpi/FreeFem++-mpi -check_plugin ",$0}' )|sh 2>&1|awk '/dyld: loaded:/ {print $3}'| sort -u +(echo export DYLD_PRINT_LIBRARIES=1;ls plugin/seq/*.dylib|grep -v fflapack| awk '{print "src/nw/FreeFem++ -check_plugin ",$0}' )|sh 2>&1|awk '$1 ~ /dyld\[[0-9]*\]/ {print $3}'| sort -u +(echo export DYLD_PRINT_LIBRARIES=1;ls plugin/mpi/*.dylib|grep -v fflapack| awk '{print "src/mpi/FreeFem++-mpi -check_plugin ",$0}' )|sh 2>&1|awk '$1 ~ /dyld\[[0-9]*\]/ {print $3}'| sort -u )| sort -u | grep .dylib > etc/list-dylib egrep -v '/usr/lib/|/System/|./plugin/' etc/list-dylib >etc/list-dylib-no-os diff --git a/configure.ac b/configure.ac index d1449cf5e..cd2a782ee 100644 --- a/configure.ac +++ b/configure.ac @@ -9,7 +9,7 @@ # number in debian/changelog. -AC_INIT(FreeFEM,4.10,frederic.hecht@sorbonne-universite.fr,FreeFEM) +AC_INIT([FreeFEM],[4.11],[frederic.hecht@sorbonne-universite.fr],[FreeFEM]) dnl : ${CFLAGS=""} dnl : ${CXXFLAGS=""} dnl : ${FCFLAGS=""} @@ -23,7 +23,7 @@ ff_TEST_FFPP_MPI="../../src/mpi/FreeFem++-mpi" ff_uncompile_plugin="" ff_unlib_plugin="" ff_download_lib="" -AC_PREREQ(2.63) dnl for AC_LANG_CASE and check stuff +AC_PREREQ([2.69]) dnl for AC_LANG_CASE and check stuff dnl AC_CONFIG_SRCDIR(src/FreeFem++-CoCoa) # Automake 1.11 is too old for check ... @@ -115,9 +115,9 @@ m4_define([AC_FF_PETSC_WHERELIB_BASIC],# PETSC_WITH_EXTERNAL_LIB,PETSC_CC_INCLUD m4_define([TOOL_PARAMETERS], [ - AC_ARG_WITH($1_include,AC_HELP_STRING([--with-$1-include=],[Include directives for $1 instead of automatic download])) - AC_ARG_WITH($1_ldflags,AC_HELP_STRING([--with-$1-ldflags=],[Link-time directives for $1 instead of automatic download])) - AC_ARG_ENABLE(download-$1,AC_HELP_STRING([--enable-download_$1],[force the download of $1])) + AC_ARG_WITH($1_include,AS_HELP_STRING([--with-$1-include=],[Include directives for $1 instead of automatic download])) + AC_ARG_WITH($1_ldflags,AS_HELP_STRING([--with-$1-ldflags=],[Link-time directives for $1 instead of automatic download])) + AC_ARG_ENABLE(download-$1,AS_HELP_STRING([--enable-download_$1],[force the download of $1])) if test "$with_$1_include" != "" || test "$with_$1_ldflags" != "" then @@ -131,7 +131,7 @@ m4_define([TOOL_PARAMETERS], ]) m4_define([TOOL_DISABLE], - [AC_ARG_ENABLE($1,AC_HELP_STRING([--disable-$1],[Do not use $1])) + [AC_ARG_ENABLE($1,AS_HELP_STRING([--disable-$1],[Do not use $1])) if test "$enable_$1" = "no" then AC_SUBST([TOOL_COMPILE_$1],"") @@ -164,7 +164,7 @@ m4_define([TOOL_DISABLE], ]) m4_define([TOOL_DISABLE_NO], [ - AC_ARG_ENABLE($1,AC_HELP_STRING([--disable-$1],[Do not use $1])) + AC_ARG_ENABLE($1,AS_HELP_STRING([--disable-$1],[Do not use $1])) if test "$enable_$1" = "no" -o "$enable_$1" = "" then enable_$1=no @@ -265,7 +265,7 @@ else fi # FFCS - build the code for FreeFem++-cs -AC_ARG_ENABLE(ffcs,AC_HELP_STRING([--enable-ffcs],[build FreeFEM for use by FreeFem++-cs])) +AC_ARG_ENABLE(ffcs,AS_HELP_STRING([--enable-ffcs],[build FreeFEM for use by FreeFem++-cs])) if test "$enable_ffcs" = yes then AC_DEFINE_UNQUOTED(ENABLE_FFCS,$enable_ffcs,[build FreeFEM for use by FreeFem++-cs]) @@ -279,7 +279,7 @@ AM_CONDITIONAL([ENABLE_FFCS],[test $enable_ffcs = yes]) ff_AR="ar" ff_ARFLAGS="rv" ff_RANLIB="ranlib" -AC_ARG_ENABLE(fortran,AC_HELP_STRING([--disable-fortran],[No Fortran compiler available ( ARPACK need it)])) +AC_ARG_ENABLE(fortran,AS_HELP_STRING([--disable-fortran],[No Fortran compiler available ( ARPACK need it)])) ff_g2c_lib=""; if test "$enable_fortran" != no @@ -446,7 +446,7 @@ fi # fin test FORTRAN .......... # ---------------------------- -AC_ARG_ENABLE(c,AC_HELP_STRING([--disable-c],[No C compiler available (C BLAS need it)])) +AC_ARG_ENABLE(c,AS_HELP_STRING([--disable-c],[No C compiler available (C BLAS need it)])) if test "$enable_c" != no then AC_PROG_CC @@ -621,7 +621,7 @@ CYGWIN*|MINGW*|MSYS_NT*) if test -z "$ff_glut" ; then ff_glutname="freeglut" if test -x /usr/bin/pkg-config.exe ; then - ff_glut="-lglu32 "`/usr/bin/pkg-config.exe --libs freeglut` + ff_glut="-lglu32 "`/usr/bin/pkg-config.exe --libs --static freeglut` else ff_glut="-l$ff_glutname -mthreads -lglu32 -lopengl32" fi @@ -967,9 +967,9 @@ fi # Looking for useful configuration utilities # ------------------------------------------ -AC_ARG_ENABLE(summary,AC_HELP_STRING([--enable-summary],[Display activated libraries list at the end of the configure process])) +AC_ARG_ENABLE(summary,AS_HELP_STRING([--enable-summary],[Display activated libraries list at the end of the configure process])) -AC_ARG_ENABLE(download,AC_HELP_STRING([--enable-download],[Download missing libraries (BLAS,ARPACK,UMFPACK,...)])) +AC_ARG_ENABLE(download,AS_HELP_STRING([--enable-download],[Download missing libraries (BLAS,ARPACK,UMFPACK,...)])) ## PETSc AC_ARG_WITH(petsc,[ --with-petsc=/usr/local/petsc/conf/petscvariables --without-petsc]) AC_ARG_WITH(prefix_petsc,[ --prefix_petsc=directory where all PETSc/SLEPc will be installed if you download ]) @@ -1031,7 +1031,6 @@ esac AC_FF_PETSC_WHERELIB(mumps,MUMPS_LIB,MUMPS_INCLUDE,$ffconfpetsc) AC_FF_PETSC_WHERELIB(tetgen,TETGEN_LIB,TETGEN_INCLUDE,$ffconfpetsc) AC_FF_PETSC_WHERELIB(hpddm,HPDDM_LIB,HPDDM_INCLUDE,$ffconfpetsc) - AC_FF_PETSC_WHERELIB(htool,HTOOL_LIB,HTOOL_INCLUDE,$ffconfpetsc) AC_FF_PETSC_WHERELIB(superlu,SUPERLU_LIB,SUPERLU_INCLUDE,$ffconfpetsc) AC_FF_PETSC_WHERELIB(mmg,MMG_LIB,MMG_INCLUDE,$ffconfpetsc) AC_FF_PETSC_WHERELIB(parmmg,PARMMG_LIB,PARMMG_INCLUDE,$ffconfpetsc) @@ -1055,8 +1054,8 @@ esac fi fi if test "$ff_slepc_ok" != yes ; then - AC_ARG_WITH(slepc_include,AC_HELP_STRING([--with-slepc-include=],[Include directives for slepc instead of automatic download])) - AC_ARG_WITH(slepc_ldflags,AC_HELP_STRING([--with-slepc-ldflags=],[Link-time directives for slepc instead of automatic download])) + AC_ARG_WITH(slepc_include,AS_HELP_STRING([--with-slepc-include=],[Include directives for slepc instead of automatic download])) + AC_ARG_WITH(slepc_ldflags,AS_HELP_STRING([--with-slepc-ldflags=],[Link-time directives for slepc instead of automatic download])) if test "$with_slepc_include" != "" || test "$with_slepc_ldflags" != "" then # some directives have been specified, use them instead of downloading @@ -1155,8 +1154,8 @@ esac fi fi if test "$ff_slepccomplex_ok" != yes ; then - AC_ARG_WITH(slepccomplex_include,AC_HELP_STRING([--with-slepccomplex-include=],[Include directives for slepccomplex instead of automatic download])) - AC_ARG_WITH(slepccomplex_ldflags,AC_HELP_STRING([--with-slepccomplex-ldflags=],[Link-time directives for slepccomplex instead of automatic download])) + AC_ARG_WITH(slepccomplex_include,AS_HELP_STRING([--with-slepccomplex-include=],[Include directives for slepccomplex instead of automatic download])) + AC_ARG_WITH(slepccomplex_ldflags,AS_HELP_STRING([--with-slepccomplex-ldflags=],[Link-time directives for slepccomplex instead of automatic download])) if test "$with_slepccomplex_include" != "" || test "$with_slepccomplex_ldflags" != "" then # some directives have been specified, use them instead of downloading @@ -1286,7 +1285,7 @@ fi # ---------------- # ALH - 18/9/13 - deactivates FFTW detection for testing purposes -AC_ARG_ENABLE(system_fftw,AC_HELP_STRING([--disable-system-fftw],[Disable the automatic detection of FFTW])) +AC_ARG_ENABLE(system_fftw,AS_HELP_STRING([--disable-system-fftw],[Disable the automatic detection of FFTW])) if test "$enable_system_fftw" != no then @@ -1300,7 +1299,7 @@ if test "$ff_fftw_ok" = yes -a "$ff_fftw_h" = yes then AC_FF_ADDWHERELIB(fftw3,-lfftw3,) else - AC_ARG_ENABLE(download-fftw,AC_HELP_STRING([--enable-download_fftw],[force the download of fftw])) + AC_ARG_ENABLE(download-fftw,AS_HELP_STRING([--enable-download_fftw],[force the download of fftw])) if test "$enable_download_fftw" != no -a "$enable_download" = yes then ff_DOWNLOAD_FFTW=fftw @@ -1331,7 +1330,7 @@ ff_blas_ok=no ff_blas_inc="" # ALH - 18/9/13 - give the option to deactivate system blas for testing purposes -AC_ARG_ENABLE(system-blas,AC_HELP_STRING([--disable-system-blas],[Disable the search for a system-wide BLAS library])) +AC_ARG_ENABLE(system-blas,AS_HELP_STRING([--disable-system-blas],[Disable the search for a system-wide BLAS library])) if test "$ff_where_lib_conf_blaslapack" = 1 ; then echo " use BLAS/Lapack of petsc " # echo " lib: $ff_where_lib_blaslapack inc: $ff_where_inc_blaslapack" @@ -1440,7 +1439,7 @@ then # handle threads when FF is connected to AS' solver. So we need an option to configure FF with the # multithreaded MKL by default. - AC_ARG_ENABLE(mkl_mlt,AC_HELP_STRING([--enable-mkl-mlt],[Link with the multithreaded instead of the monothreaded version of the MKL])) + AC_ARG_ENABLE(mkl_mlt,AS_HELP_STRING([--enable-mkl-mlt],[Link with the multithreaded instead of the monothreaded version of the MKL])) if test "$enable_mkl_mlt" = yes then @@ -1472,7 +1471,7 @@ dnl AC_DEFINE(HAVE_MKL,1, the MKL intel lib is present for BLAS and L AC_MSG_RESULT( [ $ff_warm root: $ff_mkl_root , arch: $ff_mkl_arch , $ff_mkl_lp ... ]) AC_ARG_WITH(blas, - AC_HELP_STRING([--with-blas=library],[Use a specific version of the Blas]), + AS_HELP_STRING([--with-blas=library],[Use a specific version of the Blas]), ff_blas_ok=yes ff_blas_libs="${withval}") @@ -1519,7 +1518,7 @@ fi # <> ALH - 18/9/13 - option to compile the OpenBLAS moved from the FFCS tree to FF tree -AC_ARG_ENABLE(openblas,AC_HELP_STRING([--disable-openblas],[Disable the automatic download of OpenBLAS])) +AC_ARG_ENABLE(openblas,AS_HELP_STRING([--disable-openblas],[Disable the automatic download of OpenBLAS])) if test "$ff_blas_ok" = no && test "$enable_openblas" != no && test "$enable_download" = yes then AC_CHECK_PROG(ff_git,git,yes,no) @@ -1665,7 +1664,7 @@ AC_MSG_CHECKING([for lapack in $LIBS, $ff_blas_libs and -llapack] ) if test "$ff_lapack_ok" = no; then AC_ARG_WITH(lapack, - AC_HELP_STRING([--with-lapack=library],[Use a specific version of Lapack]), + AS_HELP_STRING([--with-lapack=library],[Use a specific version of Lapack]), ff_lapack_ok=yes ff_lapack_lib="${withval}" LIBS="$ff_lapack_lib $LIBS") @@ -1687,7 +1686,7 @@ else fi # Arpack itself -AC_ARG_ENABLE(download-arpack,AC_HELP_STRING([--enable-download_arpack],[force the use download of arpack])) +AC_ARG_ENABLE(download-arpack,AS_HELP_STRING([--enable-download_arpack],[force the use download of arpack])) #echo "****** enable_download_arpack=$enable_download_arpack" if test -z "$ff_arpack_ok"; then @@ -1812,18 +1811,18 @@ if test "$ff_where_lib_conf_suitesparse" = "1" ; then fi #echo "@@@@@@@" ff_save_libs="$LIBS" -AC_ARG_ENABLE(system_umfpack,AC_HELP_STRING([--disable-system-umfpack],[Disable the automatic detection of umfpack, colmod, amd, ....])) +AC_ARG_ENABLE(system_umfpack,AS_HELP_STRING([--disable-system-umfpack],[Disable the automatic detection of umfpack, colmod, amd, ....])) if test "$ff_umfpack_ok" = no -a "$enable_system_umfpack" != no -a "$ff_blas_ok" = yes; then # echo "@@@@@@@qqqq" # User-specified location AC_ARG_WITH(amd, - AC_HELP_STRING([--with-amd=library],[Use a specific version of AMD]), + AS_HELP_STRING([--with-amd=library],[Use a specific version of AMD]), ff_amd_ok=yes ff_umfpack_libs="${withval}") AC_ARG_WITH(umfpack, - AC_HELP_STRING([--with-umfpack=library],[Use a specific version of Umfpack]), + AS_HELP_STRING([--with-umfpack=library],[Use a specific version of Umfpack]), ff_umfpack_ok=yes ff_umfpack_libs="${withval} $ff_umfpack_libs") @@ -2094,6 +2093,9 @@ case "$F77" in *gfortran*) CHECK_COMPILE_FLAG(Fortran 77,[-fallow-argument-mismatch],FFLAGS) CHECK_COMPILE_FLAG(Fortran,[-fallow-argument-mismatch],FCFLAGS) +# -fallow-invalid-boz +CHECK_COMPILE_FLAG(Fortran 77,[-fallow-invalid-boz],FFLAGS) +CHECK_COMPILE_FLAG(Fortran,[-fallow-invalid-boz],FCFLAGS) ;; esac @@ -2383,7 +2385,7 @@ test "$enable_download" = yes -a "$enable_boost" != no && enable_boost=yes test "$ff_cxx11" != yes -o "$ff_mpi" != yes -o \( "$ff_umfpack_ok" != "yes" -a "$ff_mumps_ok" != "yes" \) && enable_hpddm=no test "$ff_cxx11" != yes -o "$ff_mpi" != yes && enable_htool=no -test "$ff_cxx11" != yes -o "$ff_mpi" != yes -o \( "$enable_bemtool" != "yes" -a "$enable_boost" != "yes" \) && enable_bemtool=no +test "$ff_cxx11" != yes -o "$ff_mpi" != yes -o \( "$enable_bemtool" != "yes" -a "$enable_boost" != "yes" \) && enable_bemtool=no FF_PETSC_DYLIB="" if test "$ff_petsc_ok" != no ; then @@ -2405,6 +2407,9 @@ TOOL_DISABLE(bem,["bem.$DYLIB_SUFFIX"]) if test -n "$TOOL_COMPILE_bem" -a -z "$ff_HTOOL_INCLUDE"; then TOOL_COMPILE_htool="htool" fi +if test -z "$TOOL_COMPILE_bem"; then + enable_bemtool=no +fi ## if test "$ff_mkl_ok" = yes ; then @@ -2470,8 +2475,7 @@ AM_CONDITIONAL([UMFPACK], [test "$ff_umfpack_" = yes]) ## # All makefiles -AC_OUTPUT( - Makefile +AC_CONFIG_FILES([Makefile 3rdparty/Makefile 3rdparty/blas/Makefile 3rdparty/arpack/Makefile @@ -2509,7 +2513,8 @@ AC_OUTPUT( examples/3d/Makefile examples/3dSurf/Makefile examples/3dCurve/Makefile -) +]) +AC_OUTPUT AC_MSG_NOTICE([ FreeFEM used download: $enable_download ]) AC_MSG_NOTICE([ -- Dynamic load facility: $ff_dynload ]) diff --git a/etc/config/m4/acmpi.m4 b/etc/config/m4/acmpi.m4 index 9ac845dbb..d72c784a4 100644 --- a/etc/config/m4/acmpi.m4 +++ b/etc/config/m4/acmpi.m4 @@ -118,6 +118,7 @@ esac mkdir -p 3rdparty/lib/msmpi cp "$MSMPI_INC"/*.h 3rdparty/include/msmpi + sed 's/MPI_Status array_of_statuses\[[\]]/MPI_Status\* array_of_statuses/' < "$MSMPI_INC"/mpi.h > 3rdparty/include/msmpi/mpi.h ; grep -v INT_PTR_KIND "$MSMPI_INC"/mpif.h >3rdparty/include/msmpi/mpif.h test "$ff_ptrbit" -eq 64 && cp "$MSMPI_INC"/x64/*.h 3rdparty/include/msmpi test "$ff_ptrbit" -eq 32 && cp "$MSMPI_INC"/x86/*.h 3rdparty/include/msmpi diff --git a/etc/jenkins/change_compiler/change_compiler-Darwin-17.5.0-4_mpich.sh b/etc/jenkins/change_compiler/change_compiler-Darwin-17.5.0-4_mpich.sh deleted file mode 100644 index 029e903bc..000000000 --- a/etc/jenkins/change_compiler/change_compiler-Darwin-17.5.0-4_mpich.sh +++ /dev/null @@ -1,8 +0,0 @@ -export CC=gcc-9 -export CXX=g++-9 -export FC=gfortran-9 -export F77=gfortran-9 -export MPIRUN=/usr/local/mpich3/bin/mpirun -export MPICXX=/usr/local/mpich3/bin/mpicxx -export MPIFC=/usr/local/mpich3/bin/mpif90 -export MPICC=/usr/local/mpich3/bin/mpicc diff --git a/etc/jenkins/change_compiler/change_compiler-Darwin-17.5.0-5_mpich.sh b/etc/jenkins/change_compiler/change_compiler-Darwin-17.5.0-5_mpich.sh index 79a06fca9..f8bcb65bc 100644 --- a/etc/jenkins/change_compiler/change_compiler-Darwin-17.5.0-5_mpich.sh +++ b/etc/jenkins/change_compiler/change_compiler-Darwin-17.5.0-5_mpich.sh @@ -2,7 +2,7 @@ export CC=clang export CXX=clang++ export FC=gfortran-9 export F77=gfortran-9 -export MPIRUN=/usr/local/mpich3/bin/mpirun -export MPICXX=/usr/local/mpich3/bin/mpicxx -export MPIFC=/usr/local/mpich3/bin/mpif90 -export MPICC=/usr/local/mpich3/bin/mpicc +export MPIRUN=/usr/local/mpich4/bin/mpirun +export MPICXX=/usr/local/mpich4/bin/mpicxx +export MPIFC=/usr/local/mpich4/bin/mpif90 +export MPICC=/usr/local/mpich4/bin/mpicc diff --git a/etc/jenkins/change_compiler/change_compiler-Darwin-17.7.0-4_mpich.sh b/etc/jenkins/change_compiler/change_compiler-Darwin-17.7.0-4_mpich.sh new file mode 100644 index 000000000..8c280c9d9 --- /dev/null +++ b/etc/jenkins/change_compiler/change_compiler-Darwin-17.7.0-4_mpich.sh @@ -0,0 +1,8 @@ +export CC=gcc-9 +export CXX=g++-9 +export FC=gfortran-9 +export F77=gfortran-9 +export MPIRUN=/Users/ci/mpich4/bin/mpirun +export MPICXX=/Users/ci/mpich4/bin/mpicxx +export MPIFC=/Users/ci/mpich4/bin/mpif90 +export MPICC=/Users/ci/mpich4/bin/mpicc diff --git a/etc/jenkins/deployRelease/deployDEB-ffpetsc-20.4.sh b/etc/jenkins/deployRelease/deployDEB-ffpetsc-20.4.sh new file mode 100755 index 000000000..323c7a097 --- /dev/null +++ b/etc/jenkins/deployRelease/deployDEB-ffpetsc-20.4.sh @@ -0,0 +1,87 @@ +#!/usr/bin/env bash + +set -x +set -u +set -e + +## Parameters +TOKEN=$1 +ORGANIZATION="FreeFem" +REPOSITORY="FreeFem-sources" +VERSION=`grep AC_INIT configure.ac | cut -d"," -f2` +RELEASE_TAG_NAME="v$VERSION" +distrib=`uname -s`-`uname -r` +OSRELEASE=`lsb_release -r|awk '{print $2}'` +DISTRIB="Ubuntu" + +DEB_NAME="freefem-${VERSION}-amd64-${OSRELEASE}" +GH_DEB_NAME="FreeFEM-${VERSION}-amd64-${OSRELEASE}.deb" +if $1 = "no" ; then +## DEB build +autoreconf -i +./configure --enable-download --enable-optim --enable-generic +./3rdparty/getall -a -o PETSc,Ipopt,NLopt,freeYams,FFTW,Gmm++,MMG3D,mshmet,MUMPS +## compile and install f, libhdf5-dev (>=1.10.4)f-petsc +cd 3rdparty/ff-petsc && make petsc-slepc && cd - +./reconfigure + +make -j4 +make -j4 install +fi +#create FreeFEM Debian package with ff-petsc + +mkdir $DEB_NAME +mkdir $DEB_NAME/DEBIAN +touch $DEB_NAME/DEBIAN/control +echo "Package: freefem" >> $DEB_NAME/DEBIAN/control +echo "Version: "$VERSION >> $DEB_NAME/DEBIAN/control +echo "Section: custom" >> $DEB_NAME/DEBIAN/control +echo "Architecture: amd64" >> $DEB_NAME/DEBIAN/control +echo "Depends: libc6 (>= 2.31), g++ (>= 9.3), gcc (>= 9.3), gfortran (>= 9.3), libgsl-dev (>=2.5), libhdf5-dev (>=1.10.4), liblapack-dev (>= 3.9), libopenmpi-dev (>=4.0.3) ,freeglut3-dev (>= 2.8.1) ">> $DEB_NAME/DEBIAN/control +echo "Maintainer: FreeFEM, Frédéric Hecht " >> $DEB_NAME/DEBIAN/control +echo "Description: FreeFEM, Finite Element Language software" >> $DEB_NAME/DEBIAN/control +echo "Homepage: https://freefem.org" >> $DEB_NAME/DEBIAN/control +mkdir -p $DEB_NAME/usr/local +mkdir -p $DEB_NAME/usr/local/share/FreeFEM +mkdir -p $DEB_NAME/usr/local/bin +mkdir -p $DEB_NAME/usr/local/lib/ff++ +mkdir -p $DEB_NAME/usr/share/doc/freefem + +cp -r /usr/local/ff-petsc/ $DEB_NAME/usr/local/ff-petsc +cp -r /usr/local/lib/ff++/$VERSION $DEB_NAME/usr/local/lib/ff++/$VERSION +cp -r /usr/local/share/FreeFEM/$VERSION $DEB_NAME/usr/local/share/FreeFEM/$VERSION +cp -r /usr/local/bin/FreeFem++ $DEB_NAME/usr/local/bin/FreeFem++ +cp -r /usr/local/bin/FreeFem++-mpi $DEB_NAME/usr/local/bin/FreeFem++-mpi +cp -r /usr/local/bin/FreeFem++-nw $DEB_NAME/usr/local/bin/FreeFem++-nw +cp -r /usr/local/bin/bamg $DEB_NAME/usr/local/bin/bamg +cp -r /usr/local/bin/cvmsh2 $DEB_NAME/usr/local/bin/cvmsh2 +cp -r /usr/local/bin/ff-c++ $DEB_NAME/usr/local/bin/ff-c++ +cp -r /usr/local/bin/ff-get-dep $DEB_NAME/usr/local/bin/ff-get-dep +cp -r /usr/local/bin/ff-mpirun $DEB_NAME/usr/local/bin/ff-mpirun +cp -r /usr/local/bin/ff-pkg-download $DEB_NAME/usr/local/bin/ff-pkg-download +cp -r /usr/local/bin/ffglut $DEB_NAME/usr/local/bin/ffglut +cp -r /usr/local/bin/ffmaster $DEB_NAME/usr/local/bin/ffmaster +cp -r /usr/local/bin/ffmedit $DEB_NAME/usr/local/bin/ffmedit +cp AUTHORS $DEB_NAME/usr/share/doc/freefem/AUTHOR +cp README.md $DEB_NAME/usr/share/doc/freefem/README.md + +dpkg-deb --build $DEB_NAME/ +mv $DEB_NAME.deb $GH_DEB_NAME +exit 0 +## Deploy in GitHub release +RELEASE=`curl 'https://api.github.com/repos/'$ORGANIZATION'/'$REPOSITORY'/releases/tags/'$RELEASE_TAG_NAME` +UPLOAD_URL=`printf "%s" "$RELEASE" | jq -r '.upload_url'` + +if [ -x $UPLOAD_URL ] +then + echo "Release does not exists" + exit 1 +else + RESPONSE=`curl --data-binary "@$GH_DEB_NAME" -H "Authorization: token $TOKEN" -H "Content-Type: application/octet-stream" "$UPLOAD_URL=$GH_DEB_NAME"` +fi + +# clean the VM +rm -rf $DEB_NAME +rm $GH_DEB_NAME + +. ./bin/uninstall-ff++ diff --git a/etc/jenkins/deployRelease/deployDEB-ffpetsc.sh b/etc/jenkins/deployRelease/deployDEB-ffpetsc.sh index eb704087f..1dc35a434 100755 --- a/etc/jenkins/deployRelease/deployDEB-ffpetsc.sh +++ b/etc/jenkins/deployRelease/deployDEB-ffpetsc.sh @@ -20,7 +20,7 @@ GH_DEB_NAME="FreeFEM-${VERSION}-amd64.deb" ## DEB build autoreconf -i ./configure --enable-download --enable-optim --enable-generic -./3rdparty/getall -a -o PETSc,Ipopt,NLopt,freeYams,FFTW,Gmm++,MMG3D,mshmet,MUMPS,htool +./3rdparty/getall -a -o PETSc,Ipopt,NLopt,freeYams,FFTW,Gmm++,MMG3D,mshmet,MUMPS ## compile and install ff-petsc cd 3rdparty/ff-petsc && make petsc-slepc && cd - ./reconfigure diff --git a/etc/jenkins/deployRelease/deployEXE.sh b/etc/jenkins/deployRelease/deployEXE.sh index 9e6d57987..651fa0ab6 100755 --- a/etc/jenkins/deployRelease/deployEXE.sh +++ b/etc/jenkins/deployRelease/deployEXE.sh @@ -16,11 +16,11 @@ GH_EXE_NAME="FreeFEM-${VERSION}-win64.exe" ## EXE build autoreconf -i -./configure --enable-download --enable-optim --enable-generic -./3rdparty/getall -a -o PETSc,Ipopt,NLopt,freeYams,FFTW,Gmm++,MMG3D,mshmet,MUMPS,htool +./configure --enable-download --enable-optim --enable-generic --disable-scalapack --disable-mumps +./3rdparty/getall -a -o PETSc,Ipopt,NLopt,freeYams,FFTW,Gmm++,MMG3D,mshmet,MUMPS ## compile and install ff-petsc cd 3rdparty/ff-petsc && make petsc-slepc && cd - -./reconfigure +./configure --enable-download --enable-optim --enable-generic make cp AUTHORS readme/AUTHORS diff --git a/etc/jenkins/job_Unix/job5_mpich.sh b/etc/jenkins/job_Unix/job5_mpich.sh index b75b664d1..24b8b7853 100755 --- a/etc/jenkins/job_Unix/job5_mpich.sh +++ b/etc/jenkins/job_Unix/job5_mpich.sh @@ -26,7 +26,7 @@ test -f "$change_compiler" && source "$change_compiler" # configuration & build autoreconf -i \ - && ./configure --enable-download --enable-debug --prefix=/builds/workspace/freefem --enable-bemtool=no \ + && ./configure --enable-download --enable-debug --prefix=/builds/workspace/freefem --enable-bem=no \ && ./3rdparty/getall -a -o PETSc,Ipopt,NLopt,freeYams,FFTW,Gmm++,MMG3D,mshmet,MUMPS \ && ./etc/jenkins/blob/build_PETSc.sh \ && ./etc/jenkins/blob/build.sh diff --git a/etc/jenkins/job_Unix/job5_openmpi.sh b/etc/jenkins/job_Unix/job5_openmpi.sh index b96d040b7..00793c28e 100755 --- a/etc/jenkins/job_Unix/job5_openmpi.sh +++ b/etc/jenkins/job_Unix/job5_openmpi.sh @@ -27,7 +27,7 @@ test -f "$change_compiler" && source "$change_compiler" # configuration & build autoreconf -i \ - && ./configure --enable-download --enable-debug --prefix=/builds/workspace/freefem --enable-bemtool=no \ + && ./configure --enable-download --enable-debug --prefix=/builds/workspace/freefem --enable-bem=no \ && ./3rdparty/getall -a -o PETSc,Ipopt,NLopt,freeYams,FFTW,Gmm++,MMG3D,mshmet,MUMPS \ && ./etc/jenkins/blob/build_PETSc.sh \ && ./etc/jenkins/blob/build.sh diff --git a/etc/jenkins/job_Windows/job5.sh b/etc/jenkins/job_Windows/job5.sh index 37d0ad3fd..fa191129d 100755 --- a/etc/jenkins/job_Windows/job5.sh +++ b/etc/jenkins/job_Windows/job5.sh @@ -3,15 +3,15 @@ source shell mingw64 echo "Job 5" -autoreconf -i \ -&& ./configure --enable-generic --enable-optim --enable-download --enable-maintainer-mode \ - CXXFLAGS=-mtune=generic CFLAGS=-mtune=generic FFLAGS=-mtune=generic \ - --prefix=/builds/workspace/freefem FCFLAGS=-fallow-invalid-boz \ - && ./3rdparty/getall -a -o PETSc \ - && cd 3rdparty/ff-petsc && make petsc-slepc \ - && cd ../.. \ - && ./reconfigure \ - && make +autoreconf -i +./configure --enable-generic --enable-optim --enable-download --enable-maintainer-mode \ + --prefix=/builds/workspace/freefem --disable-scalapack --disable-mumps +./3rdparty/getall -a -o PETSc,Ipopt,NLopt,freeYams,FFTW,Gmm++,MMG3D,mshmet,MUMPS +cd 3rdparty/ff-petsc && make petsc-slepc +cd ../.. +./configure --enable-generic --enable-optim --enable-download --enable-maintainer-mode \ + --prefix=/builds/workspace/freefem +make if [ $? -eq 0 ] then diff --git a/examples/3d/Connectivite-3d.edp b/examples/3d/Connectivite-3d.edp new file mode 100644 index 000000000..d08a3df1e --- /dev/null +++ b/examples/3d/Connectivite-3d.edp @@ -0,0 +1,68 @@ +load "msh3" + +mesh3 Th=cube(1,1,1); + + // --------- new stuff ----------------- + int k=0,l=1,e=1; + Th.nbe ; // return the number of boundary element \hfilll + Th.be(k); // return the boundary element k $\in \{0,...,Th.nbe-1\}$ \hfilll + Th.be(k)[l]; // return the vertices l $\in \{0,1\}$ of boundary element k \hfilll + Th.be(k).Element ; // return the triangle contening the boundary element k \hfilll + Th.be(k).whoinElement ; // return the egde number of triangle contening the boundary element k \hfilll + Th.be(k).N ; // return the Normal to be(k) version 4.10.1 + Th.be(k).measure ; // return the measure of be(k) version 4.10.1 + Th[k].adj(e) ; // return adjacent triangle to k by edge e, and change the value of e to \hfilll + Th[k].measure ; // return the measure of element k \hfilll + + // the corresponding edge in the adjacent triangle + Th[k] == Th[k].adj(e) ;// non adjacent triangle return the same + Th[k] != Th[k].adj(e) ;// true adjacent triangle + + cout << " print mesh connectivity " << endl; + int nbelement = Th.nt; + for (int i=0;i " << int(Th[k].adj((ee=e))) << " " << ee + << " adj: " << ( Th[k].adj((ee=e)) != Th[k]) << endl; + } + // note : if k == int(Th[k].adj(ee=e)) not adjacent element + + + int nbboundaryelement = Th.nbe; + Th.be; + for (int k=0;k " << int(Th[k].adj((ee=e))) << " " << ee + << " adj: " << ( Th[k].adj((ee=e)) != Th[k]) << endl; + } + // note : if k == int(Th[k].adj(ee=e)) not adjacent element + + + int nbboundaryelement = Th.nbe; + Th.be; + for (int k=0;k " << int(Th[k].adj((ee=e))) << " " << ee + << " adj: " << ( Th[k].adj((ee=e)) != Th[k]) << endl; + } + // note : if k == int(Th[k].adj(ee=e)) not adjacent element + + + int nbboundaryelement = Th.nbe; + Th.be; + for (int k=0;k uoras, u, x0, rhs; +x0[] = 0; + +int[int] labi = [ffddminterfacelabel]; +meshL ThGamma = extract(HmeshThi,label=labi); // extract subdomain interface as meshL + +real[int] bounds(6); +boundingbox(ThGamma,bounds); + +func d = min(abs(x-bounds[0]), abs(x-bounds[1])); // distance to subdomain interface to define subdomain PMLs + +NewMacro Generate(pr) +/****** ORAS BAND ******/ +IFMACRO(!PMLI) +ffddmsetup(pr#ORAS,HFE,Varf,VarfOptRobin) +ENDIFMACRO +IFMACRO(PMLI) +ffddmsetup(pr#ORAS,HFE,Varf,VarfOpt) +ENDIFMACRO + +ffddmbuildrhs(pr#ORAS,Varfrhs,rhs[]) + +uoras[] = pr#ORASfGMRES(x0[], rhs[], 1.e-6, 2000, "right"); + +pr#ORASwritesummary + +ffddmplot(HFE,real(uoras), Stringification(pr)+"ORAS solution"); + +/****** OSDS ******/ +IFMACRO(!PMLI) +varf vGamma(u, v) = on(ffddminterfacelabel, u=1); +complex[int] onGamma = vGamma(0,HFEVhi,tgv=1); // tag interface dofs +ENDIFMACRO + +IFMACRO(PMLI) +complex[int] onGamma(HFEVhi.ndof); +{ + onGamma = 0; + HFEVhi dg = (d <= lpml*(1+1e-10)); + onGamma.re = dg[]; // tag interface PML dofs +} +ENDIFMACRO + +complex[int] notonGamma(onGamma.n); +notonGamma = 1; +notonGamma -= onGamma; // tag interior dofs + +complex[int] l1(HFEVhi.ndof), trsf(HFEVhi.ndof), rhsi(HFEVhi.ndof); +complex[int] wi(HFEVhi.ndof), vil(HFEVhi.ndof), vir(HFEVhi.ndof); + +macro pr#OSDSmyPREC1 +func complex[int] pr#OSDSPREC1(complex[int] &l) +{ + l1 = notonGamma.*l; /* restrict to interior */ + + wi = pr#ORASaR[mpiRank(Hmeshcommddm)]^-1*l1; /* local solve */ + + for (int i=0; i= 0) + trsf = wi + vil; + HFEupdate(trsf,false); + + if (mpiRank(Hmeshcommddm) == i && i > 0) { + /* apply interface operator */ + rhsi = pr#ORASaR[mpiRank(Hmeshcommddm)]*trsf; + rhsi = onGamma.*rhsi; /* restrict to interface */ + vil = pr#ORASaR[mpiRank(Hmeshcommddm)]^-1*rhsi; + } + + /* perform right to left sweep simultaneously */ + int j = Hmeshnpart-i-1; + /* transfer from right neighbor j+1 to j */ + trsf = 0; + if (mpiRank(Hmeshcommddm) == j+1 && j+1 < Hmeshnpart) + trsf = wi + vir; + HFEupdate(trsf,false); + + if (mpiRank(Hmeshcommddm) == j && j < Hmeshnpart-1) { + /* apply interface operator */ + rhsi = pr#ORASaR[mpiRank(Hmeshcommddm)]*trsf; + rhsi = onGamma.*rhsi; /* restrict to interface */ + vir = pr#ORASaR[mpiRank(Hmeshcommddm)]^-1*rhsi; + } + } + + wi += vil + vir; + + HFEupdate(wi,true); + + return wi; +} +// + +macro pr#DSAmyPREC1 +func complex[int] pr#DSAPREC1(complex[int] &l) +{ + l1 = notonGamma.*l; + + wi = pr#ORASaR[mpiRank(Hmeshcommddm)]^-1*l1; + + for (int i=0; i= 0) + trsf = wi + vil; + HFEupdate(trsf,false); + if (mpiRank(Hmeshcommddm) == i && i > 0) { + rhsi = pr#ORASaR[mpiRank(Hmeshcommddm)]*trsf; + rhsi = onGamma.*rhsi; + vil = pr#ORASaR[mpiRank(Hmeshcommddm)]^-1*rhsi; + } + } + + for (int i=0; i= 0) + trsf = wi + vil; + if (mpiRank(Hmeshcommddm) == j+1 && j+1 < Hmeshnpart) + trsf = wi + vir; + HFEupdate(trsf,false); + if (mpiRank(Hmeshcommddm) == j && j < Hmeshnpart-1) { + rhsi = pr#ORASaR[mpiRank(Hmeshcommddm)]*trsf; + rhsi = onGamma.*rhsi; + vir = pr#ORASaR[mpiRank(Hmeshcommddm)]^-1*rhsi; + } + } + + wi += vil + vir; + + HFEupdate(wi,true); + + return wi; +} +// + +macro pr#OSDSmyA +func complex[int] pr#OSDSA(complex[int] &l) {complex[int] res = pr#ORASA(l); return res;} +// + +ffddmsetupinit(pr#OSDS,HFE) + +u[] = pr#OSDSfGMRES(x0[], rhs[], 1.e-6, 2000, "right"); + +pr#OSDSwritesummary + +ffddmplot(HFE,real(u), Stringification(pr)+"OSDS solution"); + +macro pr#DSAmyA +func complex[int] pr#DSAA(complex[int] &l) {complex[int] res = pr#ORASA(l); return res;} +// +ffddmsetupinit(pr#DSA,HFE) + +u[] = pr#DSAfGMRES(x0[], rhs[], 1.e-6, 2000, "right"); + +pr#DSAwritesummary + +ffddmplot(HFE,real(u), Stringification(pr)+"DSA solution"); +EndMacro + +/* with PML interface conditions */ +{ +macro PMLI()1// +Generate(PML) +} + +/* with Robin interface conditions */ +{ +Generate(ROBIN) +} \ No newline at end of file diff --git a/examples/ffddm/Helmholtz-multitrace.edp b/examples/ffddm/Helmholtz-multitrace.edp new file mode 100644 index 000000000..a70978fed --- /dev/null +++ b/examples/ffddm/Helmholtz-multitrace.edp @@ -0,0 +1,186 @@ +load "msh3" +load "geophysics" + +include "getARGV.idp" + +real gtol = getARGV("-tol",1e-4); + +func Pk = P2; + +real freq = getARGV("-frequency",10.); // frequency +real nppwl = getARGV("-nppwl",5.); // number of points per wavelength + +macro dimension 2// EOM // 2D or 3D +include "ffddm.idp" + +real c0 = 2; + +//Marmousi marm("marmousi.bin"); +func c = c0;//marm(x,y); + +func k = 2*pi*freq/c; + +real k0 = 2*pi*freq/c0; + +real lambda = c0/freq; + +int Robin = 2; +int[int] lab = [Robin,Robin,Robin,Robin]; + +real length = 9.2; +real depth = 3; + +mesh Th = square(nppwl*length/lambda,nppwl*depth/lambda,[x*length,-y*depth],label=lab); + +fespace Uh(Th,P1); +Uh met = c/freq/nppwl; +Th = adaptmesh(Th,met,IsMetric=1,nbvx=1000000); + +func source = exp(-((x-6)^2+y^2)*50*k0); + +ffddmoverlap = 0; +macro mminoverlap()1// +ffddmbuildDmesh(,Th,mpiCommWorld) + +macro def(i)i// EOM +macro init(i)i// EOM +ffddmbuildDfespace( , ,complex,def,init,Pk) + +macro Grad(u) [dx(u),dy(u)] // EOM + +varf vAi(u,v) = int2d(Thi)(-k^2*u*v+Grad(u)'*Grad(v)) + - int1d(Thi,Robin)(1i*k*u*v); + +varf vrhs(u,v) = int2d(Thi)(source*v); + +matrix Ai = vAi(Vhi,Vhi); + +int[int] labG=[ffddminterfacelabel]; +meshL Gammai = extract(Thi,label=labG); + +fespace GammaVhi(Gammai,Pk); + +matrix Ric; +{ + matrix Ri = interpolate(GammaVhi,Vhi); + Ric = Ri; +} + +matrix Ti; +/* +{ +varf vTi(u,v) = int1d(Gammai)(k*u*v); +Ti = vTi(GammaVhi,GammaVhi); +} +*/ +{ +load "bem" +varf vH(u,v) = int1dx1d(Gammai)(Gammai)(BEM(BemKernel("HS",k=1i*k0),u,v)); +HMatrix H = vH(GammaVhi,GammaVhi,commworld=mpiCommSelf,compressor="SVD"); +display(H); +complex[int,int] mdense(GammaVhi.ndof, GammaVhi.ndof); +mdense = H; +Ti = mdense; +if (mpirank == 0) cout << H.infos << endl; +} + +matrix GTi = Ric'*Ti; +GTi = GTi*Ric; + +matrix Li = Ai - 1i*GTi; +set(Li,solver=sparsesolver,commworld=mpiCommSelf,factorize=3); + +matrix mat; + +complex[int] GammaDk = Ric*Dk[mpirank]; +{ + complex[int] Diinv = 1./GammaDk; + matrix mDiinv = Diinv; + mat = mDiinv*Ti; +} + +int[int][int] petscintersection(1 + numberIntersection); +{ + petscintersection[0].resize(arrayIntersection.n); + petscintersection[0] = arrayIntersection; + complex[int] CC; + int[int] II; + for (int j=0; j RR = restrictionIntersection[j]*Ric'; + [II, petscintersection[1 + j], CC] = RR; + if (CC[CC.n-1] == 0) petscintersection[1 + j].resize(CC.n-1); + } +} + +real[int] petscD = GammaDk.re; + +load "PETSc-complex" +Mat Tpetsc(mat, petscintersection, petscD, communicator = mpiCommWorld); + +set(Tpetsc,sparams="-ksp_converged_reason -pc_type lu -ksp_rtol "+gtol); + +complex[int] ti(GammaVhi.ndof), qi(GammaVhi.ndof), di(GammaVhi.ndof), gi(GammaVhi.ndof), Tg(GammaVhi.ndof); +complex[int] ui(Vhi.ndof), vti(Vhi.ndof); + +func complex[int] OP(complex[int] &pi) +{ + ti = Ti*pi; + vti = Ric'*ti; + ui = Li^-1*vti; + + qi = Ric*ui; + qi *= -2i; + + di = pi - qi; + + gi = Ti*di; + + exchange(Tpetsc,gi,scaled=false); + + Tg = 0; + Tg = Tpetsc^-1*gi; + + complex[int] res = qi + 2*Tg; + + return res; +} + +complex[int] rhsi = vrhs(0,Vhi); +update(rhsi,true); + +GammaVhi soli, bi; +{ + complex[int] vi = Li^-1*rhsi; + + bi[] = Ric*vi; + bi[] *= 2i; + + complex[int] tmp = Ric * vi; + complex[int] gi = Ti*tmp; + gi *= 2i; + + exchange(Tpetsc,gi,scaled=false); + + complex[int] ri(gi.n); + ri = Tpetsc^-1*gi; + bi[] -= 2*ri; +} + +Mat OPshell(GammaVhi.ndof); +Mat OPpetsc(OPshell,OP); +set(OPpetsc,sparams = "-ksp_monitor -pc_type none -ksp_rtol "+gtol); + +soli[] = OPpetsc^-1*bi[]; + +complex[int] si = Ti*soli[]; +complex[int] wi = Ric'*si; +wi += rhsi; + +Vhi vi; + +vi[] = Li^-1*wi; + +ffddmplot(,real(vi), "Global solution"); + + + diff --git a/examples/ffddm/Helmholtz_geophysics.edp b/examples/ffddm/Helmholtz_geophysics.edp new file mode 100644 index 000000000..a81a77c18 --- /dev/null +++ b/examples/ffddm/Helmholtz_geophysics.edp @@ -0,0 +1,279 @@ +/* solves the 3D Helmholtz equation with finite-differences using the + 27-point stencil from Operto, S., Virieux, J., Amestoy, P., L’Excellent, + J. Y., Giraud, L., & Ali, H. B. H. (2007). 3D finite-difference + frequency-domain modeling of visco-acoustic wave propagation using a + massively parallel direct solver: A feasibility study. + Geophysics, 72(5), SM195-SM211. + + Details about the GO_3D_OBS crustal geomodel can be found at https://www.geoazur.fr/WIND/bin/view/Main/Data/GO3DOBS + The velocity grid can be downloaded at https://www.geoazur.fr/WIND/pub/nfs/FWI-DATA/GO_3D_OBS/TARGET_PAPERS/v.bin + File 'Helmholtz_geophysics_rhs_pos.txt' contains the coordinates of the 130 right-hand sides representing a seabed node acquisition + +For a simple test run at low frequency, run: + +ff-mpirun -np 4 Helmholtz_geophysics.edp -ns -nw -frequency 0.2 -nppwl 4 -npml 8 -raspart -noGlob -ffddm_overlap 3 -npmlprec 2 -tol 1e-4 -maxit 150 -ffddm_gmres_restart 150 -murhs 20 -maxrhs 20 -ffddm_verbosity 3 -hpddm_H_reuse_preconditioner 1 -hpddm_H_orthogonalization cgs -hpddm_H_krylov_method gmres -hpddm_H_mumps_icntl_35 2 -hpddm_H_mumps_cntl_7 1e-3 -hpddm_H_mumps_icntl_37 0 -hpddm_H_mumps_icntl_36 1 + +For a large-scale 3.75 Hz frequency simulation, run: + +ff-mpirun -np 660 Helmholtz_geophysics.edp -ns -nw -frequency 3.75 -nppwl 4 -npml 8 -raspart -noGlob -ffddm_overlap 3 -npmlprec 2 -tol 1e-4 -maxit 150 -ffddm_gmres_restart 150 -murhs 20 -maxrhs 130 -ffddm_verbosity 3 -hpddm_H_reuse_preconditioner 1 -hpddm_H_orthogonalization cgs -hpddm_H_krylov_method gmres -hpddm_H_mumps_icntl_35 2 -hpddm_H_mumps_cntl_7 1e-3 -hpddm_H_mumps_icntl_37 0 -hpddm_H_mumps_icntl_36 1 +*/ + +load "Helmholtz_FD" // plugin implementing the 27-point FD stencil +load "geophysics" // for loading velocity grids of the geomodels + +include "cube.idp" +include "getARGV.idp" + +macro dimension 3//EOM +include "ffddm.idp" + +real lengthx = 102; //the metric unit is the kilometer +real lengthy = 20; +real depth = 28.3; + +int[int] npmlg(6); + +real freq = getARGV("-frequency",1.); // frequency +real nppwl = getARGV("-nppwl",4.); // number of points per wavelength +npmlg = getARGV("-npml",8); // number of points in the global PMLs +int npmli = getARGV("-npmlprec",2); // number of points in local PMLs for the preconditioner + +int maxit = getARGV("-maxit",400); // maximum number of GMRES iterations +real gmrestol = getARGV("-tol",1e-4); // GMRES relative stopping criterion + +int maxrhs = getARGV("-maxrhs",130); // total number of RHSs to treat +int murhs = getARGV("-murhs",20); // RHSs are treated by blocks of nrhs + +// point source coordinates for the single RHS case +real xs = 12.3; +real ys = 10.5; +real zs = -0.9; + +// file containing the positions of the 130 RHSs mimicking a sparse seabed node acquisition +ifstream f("Helmholtz_geophysics_rhs_pos.txt"); + +complex omega = 2.*pi*freq; +real c0 = 1.5; // reference (minimum) velocity +real lambda = (1./freq)*c0; +real h = lambda/nppwl; + +if (mpirank == 0) cout << "lambda = " << lambda << ", h = " << h << endl; + +// dimensions must be multiples of h +lengthx = h*floor(lengthx/h); +lengthy = h*floor(lengthy/h); +depth = h*floor(depth/h); + +if (mpirank == 0) cout << lengthx << " " << lengthy << " " << depth << endl; + +real Q = 100000; + +real[int]bounds = [0,lengthx,0,lengthy,-depth,0]; +Crustal crust("v.bin",bounds); // load the GO_3D_OBS crustal geomodel +func c = 1./((1./(crust(x,y,z)/1000))*(1+1i*0.5/Q)); +func mu = c^2; + +real[int] lengthpml(6); // length of the global PMLs +for (int i=0; i<6; i++) lengthpml[i] = npmlg[i]*lambda/nppwl; + +real nloc = nppwl/ffddmsplit*lengthx/lambda; + +int nplx = rint(nloc*(lengthx+lengthpml[0]+lengthpml[1])/lengthx); +int nply = rint(nloc*(lengthy+lengthpml[2]+lengthpml[3])/lengthx); +int npd = rint(nloc*(depth+lengthpml[4]+lengthpml[5])/lengthx); + +if (mpirank == 0) cout << "grid size " << nplx+1 << " x " << nply+1 << " x " << npd+1 << endl; + +//////////// *********** MESH PARTITIONING *********** //////////// +int p = mpisize; + +real nnx = pow(p * nplx^2 / nply / npd, 1./3.); +real nny = nnx * nply / nplx; +real nnz = nnx * npd / nplx; +nnx = ceil(nnx); nny = ceil(nny); nnz = ceil(nnz); + +int nx=0, ny=0, nz=0; + +/* try to find the best cuboid partitioning for this number of cores : */ +for (int ii=0; ii<4; ii++) +for (int jj=0; jj<4; jj++) +for (int kk=0; kk<4; kk++) { + int ni = nnx-ii, nj = nny-jj, nk = nnz-kk; + if (ni*nj*nk <= p && ni*nj*nk > nx*ny*nz) { + nx = ni; ny = nj; nz = nk; + } +} +p = nx*ny*nz; + +if (mpirank == 0) cout << "The domain will be decomposed in " << nx << " x " << ny << " x " << nz << " subdomains" << endl; +if (mpirank==0 && (p != mpisize)) + cout << "WARNING: the cuboid decomposition will only use " << p << " of the " << mpisize << " available cores" << endl; + +int zx = nx - (nplx%nx), zy = ny - (nply%ny), zz = nz - (npd%nz); +int px = ceil(1.*nplx/nx), py = ceil(1.*nply/ny), pz = ceil(1.*npd/nz); + +if (mpirank == 0) cout << "Subdomain size " << px+1 << " x " << py+1 << " x " << pz+1 << endl; + +int rank = mpirank; + +int boundzl = rank / ( nx * ny ) ; +int nr = rank - boundzl * nx * ny ; +int boundyl = nr / nx ; +int boundxl = nr % nx ; + +boundxl *= px; boundyl *= py; boundzl *= pz; + +int boundzu = (rank / ( nx * ny ) < nz - 1 ? boundzl + pz - 1 : npd-1); +int boundyu = (nr / nx < ny - 1 ? boundyl + py - 1 : nply - 1); +int boundxu = (nr % nx < nx - 1 ? boundxl + px - 1 : nplx - 1); + +boundxl = max(0,boundxl-3*ffddmoverlap); boundxu = min(nplx-1,boundxu+3*ffddmoverlap); +boundyl = max(0,boundyl-3*ffddmoverlap); boundyu = min(nply-1,boundyu+3*ffddmoverlap); +boundzl = max(0,boundzl-3*ffddmoverlap); boundzu = min(npd-1,boundzu+3*ffddmoverlap); + +int nbnx = boundxu-boundxl+1; +int nbny = boundyu-boundyl+1; +int nbnz = boundzu-boundzl+1; + +/* truncate global grid around the subdomain before partitioning to avoid defining the full grid */ +int[int] NN=[nbnx,nbny,nbnz]; +real [int,int] BB=[[(boundxl-npmlg[0])*h,(boundxu+1-npmlg[0]+0)*h],[(boundyl-npmlg[2])*h,(boundyu+1-npmlg[2]+0)*h],[-depth+(boundzl-npmlg[4])*h,-depth+(boundzu+1-npmlg[4]+0)*h]]; +int [int,int] LL=[[11+100*(boundxl!=0),12+100*(boundxu!=nplx-1)],[13+100*(boundyl!=0),14+100*(boundyu!=nply-1)],[15+100*(boundzl!=0),16+100*(boundzu!=npd-1)]]; + +mesh3 Th=Cube(NN,BB,LL); + +func int partcube(int ii, int jj, int kk) { + return min(kk / pz, int(nz-1))*nx*ny + min(jj / py, int(ny-1))*nx + min(ii / px, int(nx-1)); +} + +fespace Phg(Th,P0); +Phg partglob; + +/* define the regular partitioning as a P0 function on Th */ +partglob=partcube(floor((x+lengthpml[0])/(lengthx+lengthpml[0]+lengthpml[1])*nplx), + floor((y+lengthpml[2])/(lengthy+lengthpml[2]+lengthpml[3])*nply), + floor((z+depth+lengthpml[4])/(depth+lengthpml[4]+lengthpml[5])*npd)); + +/* user-defined custom partitioning for mesh prefix H */ +ffddmpartitioner = 0; +macro Hsimple(PhGlobal, part, comm) +part=partglob; +//EOM + +/* define sub-communicator if we are not using all cores */ +int[int] Iddm = (0:p-1); +mpiGroup grpddm(Iddm); +mpiComm commddm(mpiCommWorld,grpddm); + +ffddmnpart = p; +/* partition the domain into overlapping subdomains */ +ffddmbuildDmeshpartcubes(H,Th,commddm) + +/* clear memory */ +Th = cube(1,1,1); +partglob = 0; + +/* define the distributed nodal discretization space */ +macro def(u)u//EOM +macro init(u)u//EOM +ffddmbuildDfespace(H,H,complex,def,init,P1) + +//////////// *********** BUILD LOCAL MATRICES *********** //////////// + +macro HmyOperator(matName, meshName, VhName) +/* build local matrices A_i for the matrix-vector product */ +int[int] labs = labels(meshName); + +int[int] pmls(6); +pmls = -1; /* Dirichlet BC */ + +for (int i=0; i= 11 && labs[i] <= 16) + pmls[labs[i]-11] = npmlg[labs[i]-11]; /* global PML boundaries */ +matName = HelmholtzFD(meshName,omega,mu,npml=pmls); +//EOM + +macro HmyPrecond(matName, meshName, VhName) +/* build local matrices B_i for the preconditioner */ +int[int] labs = labels(meshName); + +int[int] pmls(6); +pmls = npmli; /* local PMLs */ + +for (int i=0; i= 11 && labs[i] <= 16) + pmls[labs[i]-11] = npmlg[labs[i]-11]; /* global PML boundaries */ +matName = HelmholtzFD(meshName,omega,mu,npml=pmls); +//EOM + +macro Hwithhpddm()1//EOM + +ffddmprecond = "oras"; +/* define operator (build A_i) */ +ffddmsetupOperator(H,H,null) +/* define preconditioner (build B_i) */ +ffddmsetupPrecond(H,null) + +//////////// *********** BUILD RIGHT-HAND SIDES *********** //////////// +//////////// *********** SOLVE THE LINEAR SYSTEMS *********** //////////// + +HVhi u, rhs; + +int irhs = 0; + +if (Hisincomm) +while (irhs < maxrhs) { + int mu = min(murhs, maxrhs-irhs); // number of treated RHSs for this block + + complex[int] brhs(HVhi.ndof*mu); // local RHSs + + /* assemble the mu RHSs */ + for (int i = 0; i < mu; i++) { + if (murhs > 1) { // read RHS position in the file + f >> zs; zs /= -1000; + f >> xs; xs /= 1000; + f >> ys; ys /= 1000; + } + irhs++; + + /* tag the source node closest to the RHS position */ + real disti, dist = 1e+30; + real idist = -1; + for (int i=0; i 1e-10) + idist = -1; + + rhs = 0; + if (idist != -1) rhs[][idist] = 1; + brhs(i*HVhi.ndof:(i+1)*HVhi.ndof-1) = rhs[]; + } + + complex[int] bu(HVhi.ndof*mu); // local solutions + bu = 0; // 0 initial guess + + /* solve the linear systems */ + bu = HfGMRES(bu, brhs, gmrestol, maxit, "right"); + + u[] = bu(0:HVhi.ndof-1); // save the first solution for export +} + +Hwritesummary + +/* export a solution to parallel vtu format */ +if (Hisincomm) { + load "PETSc-complex" + func pml = (x>=lengthx)+(x<=0)+(y>=lengthy)+(y<=0)+(z>=0)+(z<=-depth); + HThi = trunc(HThi,pml==0); // remove PML region + HVhi ur = real(u), ui = imag(u); + int[int] fforder = [1,1]; + savevtk("GO_3D_OBS.vtu", HThi, ur, ui, dataname = "u ui", order=fforder, communicator=commddm); + if (mpirank == 0) cout << "Solution saved: " << "GO_3D_OBS_"+p+".pvd" << endl; +} diff --git a/examples/ffddm/Helmholtz_geophysics_rhs_pos.txt b/examples/ffddm/Helmholtz_geophysics_rhs_pos.txt new file mode 100644 index 000000000..26b823fac --- /dev/null +++ b/examples/ffddm/Helmholtz_geophysics_rhs_pos.txt @@ -0,0 +1,130 @@ + 1590.00000 1000.00000 2000.00000 + 1590.00000 1000.00000 6000.00000 + 1590.00000 1000.00000 10000.0000 + 1390.00000 1000.00000 14000.0000 + 1290.00000 1000.00000 18000.0000 + 1690.00000 5000.00000 2000.00000 + 1690.00000 5000.00000 6000.00000 + 1490.00000 5000.00000 10000.0000 + 1190.00000 5000.00000 14000.0000 + 1190.00000 5000.00000 18000.0000 + 1790.00000 9000.00000 2000.00000 + 1590.00000 9000.00000 6000.00000 + 1290.00000 9000.00000 10000.0000 + 1090.00000 9000.00000 14000.0000 + 1090.00000 9000.00000 18000.0000 + 1590.00000 13000.0000 2000.00000 + 1390.00000 13000.0000 6000.00000 + 990.000000 13000.0000 10000.0000 + 890.000000 13000.0000 14000.0000 + 890.000000 13000.0000 18000.0000 + 1390.00000 17000.0000 2000.00000 + 1090.00000 17000.0000 6000.00000 + 790.000000 17000.0000 10000.0000 + 590.000000 17000.0000 14000.0000 + 690.000000 17000.0000 18000.0000 + 1290.00000 21000.0000 2000.00000 + 890.000000 21000.0000 6000.00000 + 590.000000 21000.0000 10000.0000 + 490.000000 21000.0000 14000.0000 + 390.000000 21000.0000 18000.0000 + 1290.00000 25000.0000 2000.00000 + 890.000000 25000.0000 6000.00000 + 590.000000 25000.0000 10000.0000 + 490.000000 25000.0000 14000.0000 + 490.000000 25000.0000 18000.0000 + 1490.00000 29000.0000 2000.00000 + 1190.00000 29000.0000 6000.00000 + 1090.00000 29000.0000 10000.0000 + 1090.00000 29000.0000 14000.0000 + 990.000000 29000.0000 18000.0000 + 1690.00000 33000.0000 2000.00000 + 1590.00000 33000.0000 6000.00000 + 1590.00000 33000.0000 10000.0000 + 1690.00000 33000.0000 14000.0000 + 1490.00000 33000.0000 18000.0000 + 1890.00000 37000.0000 2000.00000 + 1990.00000 37000.0000 6000.00000 + 2190.00000 37000.0000 10000.0000 + 2290.00000 37000.0000 14000.0000 + 1990.00000 37000.0000 18000.0000 + 1890.00000 41000.0000 2000.00000 + 2090.00000 41000.0000 6000.00000 + 2390.00000 41000.0000 10000.0000 + 2390.00000 41000.0000 14000.0000 + 1990.00000 41000.0000 18000.0000 + 1390.00000 45000.0000 2000.00000 + 1890.00000 45000.0000 6000.00000 + 2190.00000 45000.0000 10000.0000 + 1990.00000 45000.0000 14000.0000 + 1690.00000 45000.0000 18000.0000 + 890.000000 49000.0000 2000.00000 + 1290.00000 49000.0000 6000.00000 + 1390.00000 49000.0000 10000.0000 + 1190.00000 49000.0000 14000.0000 + 990.000000 49000.0000 18000.0000 + 1090.00000 53000.0000 2000.00000 + 1190.00000 53000.0000 6000.00000 + 1090.00000 53000.0000 10000.0000 + 890.000000 53000.0000 14000.0000 + 890.000000 53000.0000 18000.0000 + 1790.00000 57000.0000 2000.00000 + 1790.00000 57000.0000 6000.00000 + 1590.00000 57000.0000 10000.0000 + 1390.00000 57000.0000 14000.0000 + 1490.00000 57000.0000 18000.0000 + 1890.00000 61000.0000 2000.00000 + 1890.00000 61000.0000 6000.00000 + 2090.00000 61000.0000 10000.0000 + 2390.00000 61000.0000 14000.0000 + 2690.00000 61000.0000 18000.0000 + 1890.00000 65000.0000 2000.00000 + 2090.00000 65000.0000 6000.00000 + 2290.00000 65000.0000 10000.0000 + 2590.00000 65000.0000 14000.0000 + 2690.00000 65000.0000 18000.0000 + 2590.00000 69000.0000 2000.00000 + 2890.00000 69000.0000 6000.00000 + 3190.00000 69000.0000 10000.0000 + 3290.00000 69000.0000 14000.0000 + 3090.00000 69000.0000 18000.0000 + 3090.00000 73000.0000 2000.00000 + 3490.00000 73000.0000 6000.00000 + 3790.00000 73000.0000 10000.0000 + 3890.00000 73000.0000 14000.0000 + 3790.00000 73000.0000 18000.0000 + 3190.00000 77000.0000 2000.00000 + 3690.00000 77000.0000 6000.00000 + 3890.00000 77000.0000 10000.0000 + 3990.00000 77000.0000 14000.0000 + 3790.00000 77000.0000 18000.0000 + 3690.00000 81000.0000 2000.00000 + 4090.00000 81000.0000 6000.00000 + 4290.00000 81000.0000 10000.0000 + 4290.00000 81000.0000 14000.0000 + 3890.00000 81000.0000 18000.0000 + 3390.00000 85000.0000 2000.00000 + 3790.00000 85000.0000 6000.00000 + 3990.00000 85000.0000 10000.0000 + 3890.00000 85000.0000 14000.0000 + 3690.00000 85000.0000 18000.0000 + 3490.00000 89000.0000 2000.00000 + 3590.00000 89000.0000 6000.00000 + 3590.00000 89000.0000 10000.0000 + 3490.00000 89000.0000 14000.0000 + 3190.00000 89000.0000 18000.0000 + 4290.00000 93000.0000 2000.00000 + 4390.00000 93000.0000 6000.00000 + 4290.00000 93000.0000 10000.0000 + 4190.00000 93000.0000 14000.0000 + 3990.00000 93000.0000 18000.0000 + 5090.00000 97000.0000 2000.00000 + 5190.00000 97000.0000 6000.00000 + 5090.00000 97000.0000 10000.0000 + 4890.00000 97000.0000 14000.0000 + 4790.00000 97000.0000 18000.0000 + 5390.00000 101000.000 2000.00000 + 5690.00000 101000.000 6000.00000 + 5990.00000 101000.000 10000.0000 + 5890.00000 101000.000 14000.0000 + 5690.00000 101000.000 18000.0000 diff --git a/examples/ffddm/elasticity_saddlepoint.edp b/examples/ffddm/elasticity_saddlepoint.edp index 76ff908d1..ae856b931 100644 --- a/examples/ffddm/elasticity_saddlepoint.edp +++ b/examples/ffddm/elasticity_saddlepoint.edp @@ -6,6 +6,9 @@ method for Saddle Point problems. arXiv preprint available at https://arxiv.org/abs/1911.01858 */ +// the command line parameter '-Dmdim' sets the value of the macro 'mdim' in the script; +// '-Dmdim=2' or '-Dmdim=3' switches between the 2D and 3D test case + include "getARGV.idp" int global = getARGV("-global", 10); // discretization parameter int nlayers = getARGV("-nlayers", global); // number of alternating material layers in the y direction @@ -14,7 +17,7 @@ int nlayers = getARGV("-nlayers", global); // number of alternating material lay real nu1 = 0.4999; real nu2 = 0.35; real E1 = 1e+7; -real E2 = 2e+9; +real E2 = 200e+9; // heterogeneous material distribution: func fE = int(y*nlayers)%2 == 0 ? E1 : E2; @@ -42,13 +45,14 @@ fespace Ph0(meshName,P0); Ph0 E = fE, nu = fnu; func mu = E/(2*(1+nu)); func lambda = E*nu/((1+nu)*(1-2*nu)); - varf varfName([u, uB], [v, vB]) = int2d(meshName)(2.0 * mu * (epsilon(u)' * epsilon(v))) +on(4, u = 0, uB = 0) - -int2d(meshName)(100*vB); // + -int2d(meshName)(100*vB); + // EOM macro VarfB(varfName, meshName, PhName) -varf varfName([u, uB], [q]) = int2d(meshName)(div(u) * q); // +varf varfName([u, uB], [q]) = int2d(meshName)(div(u) * q); +// EOM macro VarfC(varfName, meshName, PhName) fespace Ph0(meshName,P0); @@ -56,7 +60,8 @@ Ph0 E = fE, nu = fnu; func mu = E/(2*(1+nu)); func lambda = E*nu/((1+nu)*(1-2*nu)); -varf varfName([p], [q]) = int2d(meshName)(1./lambda * p * q); // +varf varfName([p], [q]) = int2d(meshName)(1./lambda * p * q); +// EOM macro defA(i)[i, i#B] // EOM macro initA(i)[i, i] // EOM @@ -86,13 +91,14 @@ fespace Ph0(meshName,P0); Ph0 E = fE, nu = fnu; func mu = E/(2*(1+nu)); func lambda = E*nu/((1+nu)*(1-2*nu)); - varf varfName([u, uB, uC], [v, vB, vC]) = int3d(meshName)(2.0 * mu * (epsilon(u)' * epsilon(v))) +on(1, u = 0, uB = 0, uC = 0) - -int3d(meshName)(100*vB); // + -int3d(meshName)(100*vB); +// EOM macro VarfB(varfName, meshName, PhName) -varf varfName([u, uB, uC], [q]) = int3d(meshName)(div(u) * q); // +varf varfName([u, uB, uC], [q]) = int3d(meshName)(div(u) * q); +// EOM macro VarfC(varfName, meshName, PhName) fespace Ph0(meshName,P0); @@ -100,7 +106,8 @@ Ph0 E = fE, nu = fnu; func mu = E/(2*(1+nu)); func lambda = E*nu/((1+nu)*(1-2*nu)); -varf varfName([p], [q]) = int3d(meshName)(1./lambda * p * q); // +varf varfName([p], [q]) = int3d(meshName)(1./lambda * p * q); +// EOM macro defA(i)[i, i#B, i#C] // EOM macro initA(i)[i, i, i] // EOM @@ -109,12 +116,10 @@ macro defB(i)[i] // EOM macro initB(i)[i] // EOM ENDIFMACRO -real setuptime = mpiWtime(); - /* build mesh decomposition with minimal overlap size 1*2 (prefix M) and also the Augmented decomposition with overlap size 2*2 (prefix MAug) */ ffddmbuildDmeshAug(M,ThGlobal,mpiCommWorld) - + func Pk = [Pku,Pkp]; /* build Dfespace for A on distributed mesh M (prefix AFE) ; this also builds Dfespace tilde with larger overlap @@ -128,22 +133,32 @@ vsym=1; vtgvelim=1e+30; vtgv=1e+30; -ffddmsetupOperator(A,AFE,VarfA); // Operator A -ffddmsetupPrecond(A,null); // one level preconditioner for A -ffddmtau = getARGV("-ffddm_geneo_threshold_A", 0.3); +ffddmsetupOperator(A,AFE,VarfA); /* Operator A */ +ffddmsetupPrecond(A,null); /* one level preconditioner for A */ -ffddmgeneosetup(A,VarfA); // second level for A +ffddmtau = getARGV("-ffddm_geneo_threshold_A", 0.3); +ffddmgeneosetup(A,VarfA); /* second level for A */ Acorr == "ADEF1"; -ffddmsetupOperatorRect(Btilde,AFEAug,CFEAug,VarfB) // Operator B on tilde decomposition +ffddmsetupOperatorRect(Btilde,AFEAug,CFEAug,VarfB) /* Operator B on tilde decomposition */ + +ffddmsetupOperator(Ctilde,CFEAug,VarfC) /* Operator C on tilde decomposition */ -ffddmsetupOperator(Ctilde,CFEAug,VarfC) // Operator C on tilde decomposition +matrix Ctildei; +{ + VarfC(vC, MAugThi, null) + Ctildei = vC(CFEAugVhi,CFEAugVhi,sym=1); /* Ctilde_i from Remark 3.2 */ +} + +/* define and build all necessary operators for the application of N_S^-1 */ +ffddmtau = getARGV("-ffddm_geneo_threshold_S", 0.1); +ffddmSPsetup(SP,A,Btilde,Ctilde,Ctildei) AFEVhi defA(Fx); -ffddmbuildrhs(A,VarfA,Fx[]) // Build F_u +ffddmbuildrhs(A,VarfA,Fx[]) /* Build F_u */ -CFEAugVhi [Fp] = [0]; // Build F_p +CFEAugVhi [Fp] = [0]; /* Build F_p */ AFEVhi defA(Gx); @@ -151,252 +166,24 @@ Averbosity = 1; /* Solve A G_u = F_u with M_A^-1 as a preconditioner, step 1 of Algorithm 2 */ Gx[] = AfGMRES(Gx[], Fx[], gtol, 100, "right"); -/* build some of the matrices : */ -matrix Btildei, Ctildei, Si; - -real timea = mpiWtime(); -if (!Mexcluded) { - Btildei = BtildeaRd[mpiRank(Mcommddm)]*AFEAuginterp'; // Btilde_i of eq. (9) - - VarfC(vC, MAugThi, null) - Ctildei = vC(CFEAugVhi,CFEAugVhi,solver=CG,sym=1); // Ctilde_i from Remark 3.2 -} - -/* matrix-vector product with local Schur complement */ -func real[int] Simatvec(real[int] &l) { - real[int] t1 = Btildei'*l; - real[int] t2 = AaR[mpiRank(Mcommddm)]^-1*t1; - real[int] t3 = Btildei*t2; - real[int] t4 = Ctildei * l; - t3 += t4; - return t3; -} - -matrix localBlocki; - -if (!Mexcluded) { - matrix mC = -Ctildei; - localBlocki = [[AaR[mpiRank(Mcommddm)],0],[Btildei,mC]]; - set(localBlocki,solver=sparsesolver,sym=1,factorize=3,commworld=mpiCommSelf); -} - -/* inverse of local Schur complement through the solution of the augmented sparse local saddle point system */ -func real[int] Sisolve(real[int] &l) { - real[int] bi(AFEVhi.ndof+CFEAugVhi.ndof); - bi(AFEVhi.ndof:bi.n-1) = -l; - real[int] ui = localBlocki^-1*bi; - return ui(AFEVhi.ndof:bi.n-1); -} - -/* distributed matrix-vector product with B from AFEVhi to CFEAugVhi */ -func real[int] Bmatvec(real[int] &l) { - real[int] Dltilde(AFEAugVhi.ndof); - /* go from AFEVhi to AFEAugVhi: */ - if (!Mexcluded) { - real[int] Dl = AFEDk[mpiRank(Mcommddm)].*l; // multiplty by PoU - Dltilde = AFEAuginterp'*Dl; // extend - AFEAugupdate(Dltilde,false); // sum - } - real[int] res = BtildeA(Dltilde); - return res; -} - -/* distributed matrix-vector product with B^T from CFEAugVhi to AFEVhi */ -func real[int] BTmatvec(real[int] &l) { - real[int] BTtilde = BtildeAT(l); // B^T - real[int] res(AFEVhi.ndof); - if (!Mexcluded) res = AFEAuginterp*BTtilde; // restrict from AFEAugVhi to AFEVhi - return res; -} - /* Compute G_p = F_p - B G_u, step 2 of Algorithm 2 */ CFEAugVhi [Gp]; -Gp[] = Fp[] - Bmatvec(Gx[]); - -/* matrix-vector product with S_1 defined as custom operator for prefix S1tilde */ -macro S1tildemyA -func real[int] S1tildeA(real[int] &l) -{ - real[int] s(l.n); - s = 0; - - MAugtic(S1tildetmvi) - - if (!MAugexcluded){ - s = Simatvec(l); - CFEAugupdate(s,false); - CFEAugupdate(s,true); - } - MAugtoc(S1tildetmvi,"",S1tildetmv) - - return s; -} -// - -/* one-level preconditioner M_{S_1,1}^-1 defined as custom preconditioner for prefix S1tilde */ -macro S1tildemyPREC1 -func real[int] S1tildePREC1(real[int] &l) -{ - real[int] s(l.n); - s = 0; - - MAugtic(S1tildetpreci) - - if (!MAugexcluded){ - real[int] aux = l; - if(S1tildeprec == "soras") - aux = aux .* CFEAugDk[mpiRank(MAugcommddm)]; - - s = Sisolve(aux); - - if(S1tildeprec != "asm"){ - CFEAugupdate(s,true); - } - else{ - CFEAugupdate(s,false); - CFEAugupdate(s,true); - } - } - MAugtoc(S1tildetpreci,"",S1tildetprec) - - return s; -} -// - -/* operator (I + M_{S_1}^-1 S_0) for the solution of eq. (25) to apply N_S^-1 - defined as custom operator for prefix NStilde */ -macro NStildemyA -func real[int] NStildeA(real[int] &u) { - MAugtic(NStildetmvi) - real[int] res(u.n); - - /* recall that S_0 = B R_0^T (R_0 A R_0^T)^-1 R_0 B^T */ - - real[int] BTu = BTmatvec(u); /* B^T */ - - real[int] R0TA01R0BTu = AQ(BTu); /* Q = R_0^T (R_0 A R_0^T)^-1 R_0 */ - - /* extend from AFEVhi to AFEAugVhi : */ - real[int] El(AFEAugVhi.ndof); - if (!Mexcluded) { - real[int] Dl = AFEDk[mpiRank(Mcommddm)].*R0TA01R0BTu; /* multiplty by PoU */ - El = AFEAuginterp'*Dl; /* extend */ - AFEAugupdate(El,false); /* sum */ - } - - real[int] BR0TA01R0BTu = BtildeA(El); /* B */ - - real[int] MS11 = S1tildePREC(BR0TA01R0BTu); /* M_{S_1}^-1 */ - res = u + MS11; - MAugtoc(NStildetmvi,"",NStildetmv) - return res; -} -// - -/* matrix-vector product with Schur complement S = C + B A^-1 B^T for step 3 of Algorithm 2 - defined as custom operator for prefix Stilde */ -macro StildemyA -func real[int] StildeA(real[int] &l) -{ - MAugtic(Stildetmvi) - real[int] BTl(AFEVhi.ndof), s(AFEVhi.ndof), x0(AFEVhi.ndof); - - BTl = BTmatvec(l); /* B^T */ - - x0 = 0; - s = AfGMRES(x0, BTl, gtol, 100, "right"); /* A^-1 */ - - real[int] res = Bmatvec(s); /* B */ - - res += CtildeA(l); /* + C */ - - MAugtoc(Stildetmvi,"",Stildetmv) - return res; -} -// - -/* matrix-vector product with N_S^-1 (Algorithm 1, i.e. solve eq. (25)) - defined as custom preconditioner for prefix Stilde */ -macro StildemyPREC -func real[int] StildePREC(real[int] &G) { - MAugtic(Stildetpreci) - real[int] Gprime(G.n), res(G.n); - - /* solve (I + M_{S_1}^-1 S_0) P = M_{S_1}^-1 G */ - Gprime = S1tildePREC(G); - res = NStildefGMRES(res, Gprime, 1.e-2, 100, "right"); - - MAugtoc(Stildetpreci,"",Stildetprec) - return res; -} -// - -ffddmsetupinit(S1tilde,CFEAug); // define Operator for S_1 (S1tildeA with one-level preconditioner S1tildePREC1) -S1tildeprec = "soras"; - -ffddmsetupinit(NStilde,CFEAug); // define operator for N_S (NStildeA = I + M_{S_1}^-1 S_0, no preconditioner) -NStildeprec = "none"; -NStildeverbosity = 1; - -ffddmsetupinit(Stilde,CFEAug); // define Operator for S (StildeA = S := C + B A^-1 B^T with preconditioner StildePREC = N_S^-1) - -/* local contribution to lhs sum of eigenvalue problem (18) for Arpack ; - blocking forward-backward substitutions for A_i^{-1} for mu right-hand sides to accelerate computations, - as we will also have input vectors from neighboring subdomains */ -func real[int] Simatvecblock(real[int] &l, int mu) { - real[int] res(l.n); - real[int] buffi(AFEVhi.ndof * mu), buffo(AFEVhi.ndof * mu); - for (int i=0; i < mu; i++) - buffi(i*AFEVhi.ndof:(i+1)*AFEVhi.ndof-1) = Btildei'*l(i*CFEAugVhi.ndof:(i+1)*CFEAugVhi.ndof-1); - - buffo = AaR[mpiRank(Mcommddm)]^-1*buffi; - - for (int i=0; i < mu; i++) { - real[int] t1 = Btildei*buffo(i*AFEVhi.ndof:(i+1)*AFEVhi.ndof-1); - /* - real[int] t2 = CFEAugDk[mpiRank(Mcommddm)].*l(i*CFEAugVhi.ndof:(i+1)*CFEAugVhi.ndof-1); - real[int] t3 = CtildeaRd[mpiRank(Mcommddm)]*t2; - res(i*CFEAugVhi.ndof:(i+1)*CFEAugVhi.ndof-1) = t1 + t3; - */ - real[int] t2 = Ctildei*l(i*CFEAugVhi.ndof:(i+1)*CFEAugVhi.ndof-1); - res(i*CFEAugVhi.ndof:(i+1)*CFEAugVhi.ndof-1) = t1 + t2; - - } - return res; -} - -ffddmtau = getARGV("-ffddm_geneo_threshold_S", 0.1); - -/* build the second level of M_{S_1}^-1 (section 3.2.2) ; - Sisolve corresponds to the inverse of rhs of eigenvalue problem (18) for Arpack ; - Simatvecblock corresponds to the local Schur complement, i.e. the local contribution - to the S_1 sum -- and to the lhs sum of (18) */ -ffddmgeneofullsetup(S1tilde,Sisolve,Simatvecblock); - -S1tildecorr = "BNN"; - -mpiBarrier(mpiCommWorld); -if (mpirank == 0) cout << "total setup time = " << mpiWtime() - setuptime << endl; +Gp[] = Fp[] - SPBmatvec(Gx[]); /* Step 3 of Algorithm 2: solve (C + B A^-1 B^T) P = -G_p with N_S^-1 as a preconditioner */ Gp[] *= -1; CFEAugVhi [P]; P[] = 0; -P[] = StildefGMRES(P[], Gp[], gtol, 100, "right"); +P[] = SPfGMRES(P[], Gp[], gtol, 100, "right"); Awritesummary -S1tildewritesummary -NStildewritesummary -Stildewritesummary +SPwritesummary ffddmplot(CFEAug,P,"P"); // Step 4 of Algorithm 2: compute G_u = F_u - B^T P -real[int] tmp = BtildeAT(P[]); -Gx[] = AFEAuginterp*tmp; - -Gx[] = -Gx[] + Fx[]; +Gx[] = Fx[] - SPBTmatvec(P[]); // Step 5 of Algorithm 2: solve A U = G_u with M_A^-1 as a preconditioner AFEVhi defA(Ux); @@ -405,76 +192,7 @@ Ux[] = AfGMRES(Ux[], Gx[], gtol, 100, "right"); ffddmplot(CFEAug,UxB,"Uy"); -/******************* Block version (prefix 'Block') with preconditioner P eq. (28) *******************/ -macro Blockmyscalprod -func real Blockscalprod(real[int]& va, real[int]& vb) -{ - real resf = AFEscalprod(va(0:AFEVhi.ndof-1),vb(0:AFEVhi.ndof-1)); - real resb = CFEAugscalprod(va(AFEVhi.ndof:va.n-1),vb(AFEVhi.ndof:va.n-1)); - return resf+resb; -} -// - -ffddminitDfespacef(Block, MAug, real, def, init, P1, def, init, P1) - -macro BlockmyA -func real[int] BlockA(real[int] &u) -{ - real[int] res(u.n); - res(0:AFEVhi.ndof-1) = AA(u(0:AFEVhi.ndof-1)); - res(AFEVhi.ndof:u.n-1) = -CtildeA(u(AFEVhi.ndof:u.n-1)); - - real[int] r1 = BTmatvec(u(AFEVhi.ndof:u.n-1)); - - res(0:AFEVhi.ndof-1) += r1; - - real[int] r2 = Bmatvec(u(0:AFEVhi.ndof-1)); - - res(AFEVhi.ndof:u.n-1) += r2; - - return res; -} -// - -macro BlockmyPREC1 -func real[int] BlockPREC1(real[int] &u) -{ - real[int] res(u.n), resb(u.n); - - /*resb(0:AFEVhi.ndof-1) = AfGMRES(resb(0:AFEVhi.ndof-1), u(0:AFEVhi.ndof-1), 1e-2, 200, "right");*/ - resb(0:AFEVhi.ndof-1) = APREC(u(0:AFEVhi.ndof-1)); - - /*resb(AFEVhi.ndof:u.n-1) = -StildefGMRES(resb(AFEVhi.ndof:u.n-1) , u(AFEVhi.ndof:u.n-1), 1e-2, 100, "right");*/ - - resb(AFEVhi.ndof:u.n-1) = -StildePREC(u(AFEVhi.ndof:u.n-1)); - - real[int] r2 = Bmatvec(resb(0:AFEVhi.ndof-1)); - - real[int] s2(r2.n); - /*s2 = StildefGMRES(s2, r2, 1e-2, 100, "right");*/ - - s2 = StildePREC(r2); - - resb(AFEVhi.ndof:u.n-1) += s2; - - res(0:AFEVhi.ndof-1) = (resb(0:AFEVhi.ndof-1)); - res(AFEVhi.ndof:u.n-1) = (resb(AFEVhi.ndof:u.n-1)); - - real[int] r1 = BTmatvec(resb(AFEVhi.ndof:u.n-1)); - - real[int] s1(r1.n); - /*s1 = AfGMRES(s1, r1, 1e-2, 200, "right");*/ - s1 = APREC(r1); - - res(0:AFEVhi.ndof-1) -= s1; - - return res; -} -// - -ffddmsetupinit(Block,Block); -Blockprec = "ras"; - +IFMACRO(BLOCK) /* Block solve with preconditioner P of eq. (28) */ real[int] rhs(AFEVhi.ndof+CFEAugVhi.ndof); rhs(0:AFEVhi.ndof-1) = Fx[]; @@ -482,9 +200,9 @@ rhs(AFEVhi.ndof:rhs.n-1) = Fp[]; real[int] x0(rhs.n), u(rhs.n); -u = BlockfGMRES(x0, rhs, gtol, 100, "right"); +u = SPBlockfGMRES(x0, rhs, gtol, 100, "right"); -Blockwritesummary +SPBlockwritesummary real[int] Us = Ux[]; @@ -495,4 +213,4 @@ ffddmplot(CFEAug,UxB,"UxB block"); Ux[] -= Us; ffddmplot(CFEAug,UxB,"difference"); - +ENDIFMACRO \ No newline at end of file diff --git a/examples/hpddm/Makefile.am b/examples/hpddm/Makefile.am index db16d8d1b..b41a8a99c 100644 --- a/examples/hpddm/Makefile.am +++ b/examples/hpddm/Makefile.am @@ -25,7 +25,7 @@ TESTS_ENVIRONMENT = TEST_FFPP=$(TEST_FFPPMPI) FLAGS_FFPP="-np 4 -nw" LIST_CONDIT all-local: freefem++.pref -TESTS_MPI = withPartitioning.edp buildRecursive.edp createPartition.edp reconstructDmesh.edp redistributeDmesh.edp convect.edp +TESTS_MPI = withPartitioning.edp buildRecursive.edp createPartition.edp reconstructDmesh.edp redistributeDmesh_wo_PETSc.edp convect.edp TESTS_HPDDM = diffusion-substructuring-2d.edp \ diffusion-substructuring-withPartitioning-2d.edp \ @@ -76,17 +76,14 @@ TESTS_PETSC = bratu-2d-PETSc.edp \ stokes-block-2d-PETSc.edp \ MatLoad-PETSc.edp \ stokes-3d-PETSc.edp \ - stokes-fieldsplit-3d-PETSc.edp \ transpose-solve-PETSc.edp \ bratu-hpddm-2d-PETSc.edp \ vi-2d-PETSc.edp \ - orego-Tao-PETSc.edp \ + orego-TS-PETSc.edp \ heat-TS-2d-PETSc.edp \ heat-TS-RHS-2d-PETSc.edp \ advection-TS-2d-PETSc.edp \ - toy-Tao-PETSc.edp \ minimal-surface-Tao-2d-PETSc.edp \ - Schur-complement-PETSc.edp \ maxwell-2d-PETSc.edp \ maxwell-3d-PETSc.edp \ laplace-adapt-3d-PETSc.edp \ @@ -100,9 +97,14 @@ TESTS_PETSC = bratu-2d-PETSc.edp \ PtAP-2d-PETSc.edp \ restriction-2d-PETSc.edp \ function-PETSc.edp \ - bilaplace-2d-PETSc.edp + bilaplace-2d-PETSc.edp \ + redistributeDmesh_w_PETSc.edp \ + toy-Tao-PETSc.edp \ + stokes-fieldsplit-3d-PETSc.edp # diffusion-substructuring-2d-PETSc.edp <- broken, problem with BDDC +TESTS_PETSC_MUMPS = Schur-complement-PETSc.edp + TESTS_PETSC_PARMMG = distributed-parmmg.edp laplace-adapt-dist-3d-PETSc.edp TESTS_PETSC_SLEPC = laplace-2d-SLEPc.edp \ @@ -119,8 +121,9 @@ TESTS_PETSC_SLEPC = laplace-2d-SLEPc.edp \ TESTS_PETSCCOMPLEX = diffusion-2d-PETSc-complex.edp \ helmholtz-2d-PETSc-complex.edp \ - helmholtz-mg-2d-PETSc-complex.edp \ - maxwell-mg-3d-PETSc-complex.edp + helmholtz-mg-2d-PETSc-complex.edp + +TESTS_PETSCCOMPLEX_MUMPS = maxwell-mg-3d-PETSc-complex.edp TESTS_PETSCCOMPLEX_SLEPCCOMPLEX = laplace-2d-SLEPc-complex.edp \ navier-stokes-2d-SLEPc-complex.edp helmholtz-2d-SLEPc-complex.edp \ @@ -140,6 +143,9 @@ endif HPDDM if PETSC CONDITIONAL_PETSC = $(TESTS_PETSC) +if MUMPS +CONDITIONAL_PETSC_MUMPS = $(TESTS_PETSC_MUMPS) +endif if PARMMG CONDITIONAL_PETSC_PARMMG = $(TESTS_PETSC_PARMMG) endif PARMMG @@ -150,6 +156,9 @@ endif PETSC if PETSCCOMPLEX CONDITIONAL_PETSCCOMPLEX = $(TESTS_PETSCCOMPLEX) +if MUMPS +CONDITIONAL_PETSCCOMPLEX_MUMPS = $(TESTS_PETSCCOMPLEX_MUMPS) +endif if SLEPCCOMPLEX CONDITIONAL_PETSCCOMPLEX_SLEPCCOMPLEX = $(TESTS_PETSCCOMPLEX_SLEPCCOMPLEX) endif SLEPCCOMPLEX @@ -168,9 +177,11 @@ TESTS = $(TESTS_MPI) \ $(TESTS_HPDDM) \ $(TESTS_HPDDM_ARPACK) \ $(TESTS_PETSC) \ + $(TESTS_PETSC_MUMPS) \ $(TESTS_PETSC_PARMMG) \ $(TESTS_PETSC_SLEPC) \ $(TESTS_PETSCCOMPLEX) \ + $(TESTS_PETSCCOMPLEX_MUMPS) \ $(TESTS_PETSCCOMPLEX_SLEPCCOMPLEX) \ $(TESTS_PETSCCOMPLEX_BEMTOOL_BOOST_HTOOL) @@ -178,9 +189,11 @@ LIST_CONDITIONAL = $(CONDITIONAL_MPI) \ $(CONDITIONAL_HPDDM) \ $(CONDITIONAL_HPDDM_ARPACK) \ $(CONDITIONAL_PETSC) \ + $(CONDITIONAL_PETSC_MUMPS) \ $(CONDITIONAL_PETSC_PARMMG) \ $(CONDITIONAL_PETSC_SLEPC) \ $(CONDITIONAL_PETSCCOMPLEX) \ + $(CONDITIONAL_PETSCCOMPLEX_MUMPS) \ $(CONDITIONAL_PETSCCOMPLEX_SLEPCCOMPLEX) \ $(CONDITIONAL_PETSCCOMPLEX_BEMTOOL_BOOST_HTOOL) diff --git a/examples/hpddm/PtAP-2d-PETSc.edp b/examples/hpddm/PtAP-2d-PETSc.edp index 81d1b54ab..4253f3d22 100644 --- a/examples/hpddm/PtAP-2d-PETSc.edp +++ b/examples/hpddm/PtAP-2d-PETSc.edp @@ -2,7 +2,6 @@ // NBPROC 4 load "PETSc" -macro dimension()2// EOM include "macro_ddm.idp" mesh ThNew, Th = square(getARGV("-global", 20), getARGV("-global", 20)); diff --git a/examples/hpddm/README.md b/examples/hpddm/README.md index 48e605a12..e3690e06b 100644 --- a/examples/hpddm/README.md +++ b/examples/hpddm/README.md @@ -60,7 +60,7 @@ You can find the PETSc and SLEPc documentation [here](https://doc.freefem.org/do | [heat-TS-2d-PETSc.edp](https://github.com/FreeFem/FreeFem-sources/tree/develop/examples/hpddm/heat-TS-2d-PETSc.edp) |   | | [heat-TS-RHS-2d-PETSc.edp](https://github.com/FreeFem/FreeFem-sources/tree/develop/examples/hpddm/heat-TS-RHS-2d-PETSc.edp) |   | | [minimal-surface-Tao-2d-PETSc.edp](https://github.com/FreeFem/FreeFem-sources/tree/develop/examples/hpddm/minimal-surface-Tao-2d-PETSc.edp) | Minimal surface problem | -| [orego-Tao-PETSc.edp](https://github.com/FreeFem/FreeFem-sources/tree/develop/examples/hpddm/orego-Tao-PETSc.edp) |   | +| [orego-TS-PETSc.edp](https://github.com/FreeFem/FreeFem-sources/tree/develop/examples/hpddm/orego-TS-PETSc.edp) |   | | [toy-Tao-PETSc.edp](https://github.com/FreeFem/FreeFem-sources/tree/develop/examples/hpddm/toy-Tao-PETSc.edp) |   | ### Eigenvalue problems diff --git a/examples/hpddm/blasius-stability-1d-SLEPc-complex.edp b/examples/hpddm/blasius-stability-1d-SLEPc-complex.edp index e275507dd..7fcc6a59b 100644 --- a/examples/hpddm/blasius-stability-1d-SLEPc-complex.edp +++ b/examples/hpddm/blasius-stability-1d-SLEPc-complex.edp @@ -115,20 +115,20 @@ varf A0mat([u1, u2, p], [v1, v2, q]) = int1d(thL)( -1i*omega*u2*v2 + nu*(dx(u2)*dx(v2) + dy(u2)*dy(v2)) + dy(p)*v2 + dy(u2)*q) + on(1, u1 = 0., u2 = 0.) /* bot wall */ -+ on(2, u1 = 0., u2 = 0.); /* Free-strem */ ++ on(2, u1 = 0., u2 = 0.); /* Free-stream */ varf A1mat([u1, u2, p], [v1, v2, q]) = int1d(thL)( 1i*fG2*u1*v1 + 1i*p*v1 + 1i*fG2*u2*v2 + 1i*u1*q) + on(1, u1 = 0., u2 = 0.) /* bot wall */ -+ on(2, u1 = 0., u2 = 0.); /* Free-strem */ ++ on(2, u1 = 0., u2 = 0.); /* Free-stream */ varf A2mat([u1, u2, p], [v1, v2, q]) = int1d(thL)( nu*u1*v1 + nu*u2*v2) -+ on(1, u1 = 0., u2 = 0.) /* Free-strem */ -+ on(2, u1 = 0., u2 = 0.); /* Free-strem */ ++ on(1, u1 = 0., u2 = 0.) /* bot wall */ ++ on(2, u1 = 0., u2 = 0.); /* Free-stream */ Mat[int] Apep(3); macro def(u)[u, u#B, u#C]//EOM @@ -145,6 +145,7 @@ Apep[0] = A0mat(VhC,VhC,tgv=-1); VhC[int] def(eigenvecVec)(nEV); complex[int] eigvalVec(nEV); +real[int] errestVec(nEV); string PEPParamsbase = " -pep_basis monomial " + " -pep_general " + @@ -156,10 +157,69 @@ string PEPspar = PEPParamsbase + " -pep_target " + shift + " -pep_nev " + nEV + " -pep_ncv " + nKryl + " "; -int nEvalConv = PEPSolve(Apep, vectors = eigenvecVec, values = eigvalVec, sparams = PEPspar); +int nEvalConv = PEPSolve(Apep, vectors = eigenvecVec, values = eigvalVec, sparams = PEPspar, errorestimate = errestVec); + +if(mpirank==0){ + cout << "Same output manually" << endl; + cout << " PEP nconv=" << nEvalConv << " Values (Errors)"; + for(int i=0; i dA, dB; + +/* -1 factor for the companion matrix */ +Apep[0] *= -1; +Apep[1] *= -1; + +{ + matrix Id = eye(VhC.ndof); + Mat IMat(Apep[0], Id); + Mat dAux; + dAux = [[IMat, 0], + [0, Apep[2]]]; + MatConvert(dAux, dB); + dAux = [[0, IMat], + [Apep[0], Apep[1]]]; + MatConvert(dAux, dA); +} + +VhC[int] def(eigenvecCompVec)(nEV); +complex[int] eigvalCompVec(nEV); +real[int] errestCompVec(nEV); + +string EPSParamsbase = + " -eps_type krylovschur" + + " -st_type sinvert " + + " -st_pc_type lu " + + " -eps_monitor_all" + + " -eps_gen_non_hermitian "; + +string EPSpar = EPSParamsbase + " -eps_target " + shift + + " -eps_nev " + nEV + + " -eps_ncv " + nKryl + " "; + + +int nEvalCompConv = EPSSolve(dA, dB, vectors = eigenvecCompVec, values = eigvalCompVec, sparams = EPSpar, errorestimate = errestCompVec); + +if(mpirank==0){ + cout << "Same output manually" << endl; + cout << " EPS nconv=" << nEvalCompConv << " Values (Errors)"; + for(int i=0; i A; buildDmesh(Th3); createMat(Th3, A, P1); fespace Vh(Th3, P1); -Vh u; +Vh u; real err = 8.0e-3; int iMax = getARGV("-iMax", 1); @@ -33,10 +33,10 @@ int[int] rt(2); rt = [1,2]; for(int i = 0; i < iMax; ++i) { A = vPoisson(Vh, Vh, tgv = -2); - set(A, sparams = "-ksp_monitor -pc_type hypre"); - real[int] rhs = vPoisson(0, Vh, tgv = -1); + set(A, sparams = "-ksp_monitor -pc_type gamg"); + PetscScalar[int] rhs = vPoisson(0, Vh, tgv = -1); u[] = A^-1 * rhs; - real[int] met = mshmet(Th3, u, aniso = !isotropic, hmin = 1.0e-3, hmax = 1.0e-1, err = err); + real[int] met = mshmet(Th3, abs(u), aniso = !isotropic, hmin = 1.0e-3, hmax = 1.0e-1, err = err); mesh3 ThParMmg; int[int] n2o; int[int][int] communicators; @@ -62,15 +62,15 @@ for(int i = 0; i < iMax; ++i) { ThParMmg = parmmg3d(ThParMmg, metric = metParMmg, hausd = 0.01, requiredTriangle = rt, nodeCommunicators = communicators, niter = niter, verbose = verbose, neighbors = neighbors); reconstructDmesh(ThParMmg) int[int] fforder = [1]; - savevtk("laplace-adapt-dist-3d.vtu", Th3, u, bin = 1, order = fforder, append = i ? true : false); + savevtk("laplace-adapt-dist-3d.vtu", Th3, abs(u), bin = 1, order = fforder, append = i ? true : false); if(!noTransfer) { fespace VhAdapt(ThParMmg, P1); - VhAdapt uAdapt; + VhAdapt uAdapt; transfer(Th3, P1, u, ThParMmg, P1, uAdapt) - savevtk("laplace-adapt-dist-3d.vtu", ThParMmg, uAdapt, bin = 1, order = fforder, append = true); + savevtk("laplace-adapt-dist-3d.vtu", ThParMmg, abs(uAdapt), bin = 1, order = fforder, append = true); } copyDmesh(ThParMmg, Th3) - Mat Adapt; + Mat Adapt; createMat(Th3, Adapt, P1); A = Adapt; u = 0.0; diff --git a/examples/hpddm/laplace-spherical-harmonics-2d-SLEPc.edp b/examples/hpddm/laplace-spherical-harmonics-2d-SLEPc.edp index 6f4240760..2f77668f0 100644 --- a/examples/hpddm/laplace-spherical-harmonics-2d-SLEPc.edp +++ b/examples/hpddm/laplace-spherical-harmonics-2d-SLEPc.edp @@ -162,7 +162,6 @@ string ssparams = // Parameters for the distributed EigenValue solver " -st_type sinvert " + " -st_pc_type cholesky " + " -st_matstructure same " + - " -st_pc_factor_mat_solver_type mumps" + " -eps_view" + " -eps_gen_hermitian" // The problem is symmetric ; diff --git a/examples/hpddm/laplace-torus-2d-SLEPc.edp b/examples/hpddm/laplace-torus-2d-SLEPc.edp index 44ab91fb0..2720c830e 100644 --- a/examples/hpddm/laplace-torus-2d-SLEPc.edp +++ b/examples/hpddm/laplace-torus-2d-SLEPc.edp @@ -164,7 +164,6 @@ string ssparams = // Parameters for the distributed EigenValue solver " -st_type sinvert " + " -st_pc_type cholesky " + " -st_matstructure same " + - " -st_pc_factor_mat_solver_type mumps" + " -eps_view" + " -eps_gen_hermitian" // The problem is symmetric ; diff --git a/examples/hpddm/mf-2d-SLEPc.edp b/examples/hpddm/mf-2d-SLEPc.edp index c00fa2d4e..019424329 100644 --- a/examples/hpddm/mf-2d-SLEPc.edp +++ b/examples/hpddm/mf-2d-SLEPc.edp @@ -93,4 +93,10 @@ for (int idSV = 0; idSV < nsv; ++idSV) temp2 = valuesMF[idSV] * lvecMF(:,idSV); temp2 -= temp1; assert(temp2.linfty < 1.0e-4); + MatMult(MF, rvecMF(:,idSV), temp2); + ChangeNumbering(A, temp1, temp2, inverse = true, exchange = true); + temp2.resize(uMF[].n); + temp2 = MF * vMF[]; + temp2 -= temp1; + assert(temp2.linfty < 1.e-4); } diff --git a/examples/hpddm/orego-Tao-PETSc.edp b/examples/hpddm/orego-TS-PETSc.edp similarity index 100% rename from examples/hpddm/orego-Tao-PETSc.edp rename to examples/hpddm/orego-TS-PETSc.edp diff --git a/examples/hpddm/reconstructDmesh.edp b/examples/hpddm/reconstructDmesh.edp index 4351a505e..1a8650897 100644 --- a/examples/hpddm/reconstructDmesh.edp +++ b/examples/hpddm/reconstructDmesh.edp @@ -5,7 +5,6 @@ func Pk = P2; macro def(u)u// { - macro dimension()2// EOM include "macro_ddm.idp" mesh ThGlobal = square(getARGV("-global_2d", 40), getARGV("-global_2d", 40)); @@ -15,7 +14,7 @@ macro def(u)u// partitionerSeq(part[], ThGlobal, mpisize); } partitionerPar(part[], ThGlobal, mpiCommWorld, mpisize); - mesh Th = trunc(ThGlobal, abs(part - mpirank) < 1.0e-2, renum = 1); + mesh Th = trunc(ThGlobal, abs(part - mpirank) < 1.0e-2, renum = 1, label = -111112); reconstructDmesh(Th) fespace Wh(Th, Pk); Wh u; @@ -33,7 +32,7 @@ macro def(u)u// partitionerSeq(part[], ThGlobal, mpisize); } partitionerPar(part[], ThGlobal, mpiCommWorld, mpisize); - mesh3 Th = trunc(ThGlobal, abs(part - mpirank) < 1.0e-2, renum = 1); + mesh3 Th = trunc(ThGlobal, abs(part - mpirank) < 1.0e-2, renum = 1, label = -111112); reconstructDmesh(Th) fespace Wh(Th, Pk); Wh u; diff --git a/examples/hpddm/redistributeDmesh.edp b/examples/hpddm/redistributeDmesh.idp similarity index 95% rename from examples/hpddm/redistributeDmesh.edp rename to examples/hpddm/redistributeDmesh.idp index 66506e9fa..a88fec4f3 100644 --- a/examples/hpddm/redistributeDmesh.edp +++ b/examples/hpddm/redistributeDmesh.idp @@ -1,9 +1,10 @@ -// run with MPI: ff-mpirun -np 4 script.edp -// NBPROC 4 -// PARAM -sizeComm 2 -Dpartitioner=scotch - include "getARGV.idp" +IFMACRO(with,PETSc) +load "PETSc" +ENDIFMACRO +IFMACRO(!with) macro PetscScalar()real// +ENDIFMACRO int sizeComm = max(1, min(mpisize, getARGV("-sizeComm", mpisize))); int div = mpisize / sizeComm; @@ -14,7 +15,6 @@ func Pk = [P2, P2]; macro def(u)[u, u#B]// macro init(u)[u, u]// { - macro dimension()2// EOM // 2D or 3D include "macro_ddm.idp" // additional DDM functions mesh Th = square(getARGV("-global_2d", 20), getARGV("-global_2d", 20)); // global mesh buildDmesh(Th) diff --git a/examples/hpddm/redistributeDmesh_w_PETSc.edp b/examples/hpddm/redistributeDmesh_w_PETSc.edp new file mode 100644 index 000000000..36b8fd2d8 --- /dev/null +++ b/examples/hpddm/redistributeDmesh_w_PETSc.edp @@ -0,0 +1,8 @@ +// run with MPI: ff-mpirun -np 4 script.edp +// NBPROC 4 +// PARAM -sizeComm 2 -Dpartitioner=scotch -Dwith=PETSc + +IFMACRO(!with) +macro with()PETSc// +ENDIFMACRO +include "redistributeDmesh.idp" diff --git a/examples/hpddm/redistributeDmesh_wo_PETSc.edp b/examples/hpddm/redistributeDmesh_wo_PETSc.edp new file mode 100644 index 000000000..6e91c352e --- /dev/null +++ b/examples/hpddm/redistributeDmesh_wo_PETSc.edp @@ -0,0 +1,5 @@ +// run with MPI: ff-mpirun -np 4 script.edp +// NBPROC 4 +// PARAM -sizeComm 2 -Dpartitioner=scotch + +include "redistributeDmesh.idp" diff --git a/examples/hpddm/schrodinger-harmonic-oscillator-1d-SLEPc.edp b/examples/hpddm/schrodinger-harmonic-oscillator-1d-SLEPc.edp index a18dda13c..43913da1a 100644 --- a/examples/hpddm/schrodinger-harmonic-oscillator-1d-SLEPc.edp +++ b/examples/hpddm/schrodinger-harmonic-oscillator-1d-SLEPc.edp @@ -137,7 +137,6 @@ string ssparams = // Parameters for the distributed EigenValue solver " -eps_target "+ sigma + // Shift value " -st_type sinvert " + " -st_pc_type lu " + - " -st_pc_factor_mat_solver_type mumps" + " -eps_view" + " -eps_gen_hermitian" // The problem is symmetric ; diff --git a/examples/hpddm/schrodinger-harmonic-oscillator-2d-SLEPc.edp b/examples/hpddm/schrodinger-harmonic-oscillator-2d-SLEPc.edp index 177ea3b18..a829f6680 100644 --- a/examples/hpddm/schrodinger-harmonic-oscillator-2d-SLEPc.edp +++ b/examples/hpddm/schrodinger-harmonic-oscillator-2d-SLEPc.edp @@ -140,7 +140,6 @@ string ssparams = // Parameters for the distributed EigenValue solver " -eps_target "+ sigma + // Shift value " -st_type sinvert " + " -st_pc_type lu " + - " -st_pc_factor_mat_solver_type mumps" + " -eps_view" + " -eps_gen_hermitian" // The problem is symmetric ; diff --git a/examples/hpddm/schrodinger-square-well-1d-SLEPc.edp b/examples/hpddm/schrodinger-square-well-1d-SLEPc.edp index f5c8370de..05ae5bc0c 100644 --- a/examples/hpddm/schrodinger-square-well-1d-SLEPc.edp +++ b/examples/hpddm/schrodinger-square-well-1d-SLEPc.edp @@ -157,7 +157,6 @@ string ssparams = // Parameters for the distributed EigenValue solver " -eps_target "+ sigma + // Shift value " -st_type sinvert " + " -st_pc_type lu " + - " -st_pc_factor_mat_solver_type mumps" + " -eps_view" + " -eps_gen_hermitian" // The problem is symmetric ; diff --git a/examples/hpddm/stokes-2d-PETSc.edp b/examples/hpddm/stokes-2d-PETSc.edp index c904b8e16..c1613b12d 100644 --- a/examples/hpddm/stokes-2d-PETSc.edp +++ b/examples/hpddm/stokes-2d-PETSc.edp @@ -27,7 +27,7 @@ fespace Wh(Th, Pk); // local finite element space varf vPb([u, uB, p], [v, vB, q]) = int2d(Th)(grad(u)' * grad(v) + grad(uB)' * grad(vB) - div(u) * q - div(v) * p + 1e-10 * p * q) + on(1, 3, 5, u = 0, uB = 0) + on(2, u = y*(0.5-y), uB = 0); real[int] rhs = vPb(0, Wh); -set(A, sparams = "-pc_type lu -pc_factor_mat_solver_type mumps"); +set(A, sparams = "-pc_type lu"); Wh def(u); A = vPb(Wh, Wh); diff --git a/examples/hpddm/stokes-2d-SLEPc.edp b/examples/hpddm/stokes-2d-SLEPc.edp index c44e63c8a..850caf29f 100644 --- a/examples/hpddm/stokes-2d-SLEPc.edp +++ b/examples/hpddm/stokes-2d-SLEPc.edp @@ -42,8 +42,7 @@ M = vPbM(VhP, VhP); Mat B(A, M); Mat Z(A); { - matrix BLoc = vPbB(VhP, VhV); - B = BLoc; + B = vPbB(VhP, VhV); real[int] diag(VhV.ndof); matrix zeros = diag; Z = zeros; diff --git a/examples/hpddm/stokes-3d-PETSc.edp b/examples/hpddm/stokes-3d-PETSc.edp index ba57f873f..fd183826f 100644 --- a/examples/hpddm/stokes-3d-PETSc.edp +++ b/examples/hpddm/stokes-3d-PETSc.edp @@ -28,7 +28,7 @@ fespace Wh(Th, Pk); // local finite element space varf vPb([u, uB, uC, p], [v, vB, vC, q]) = int3d(Th)(grad(u)' * grad(v) + grad(uB)' * grad(vB) + grad(uC)' * grad(vC) - div(u) * q - div(v) * p + 1e-10 * p * q) + on(0, 1, 3, 5, u = 0, uB = 0, uC = 0) + on(2, u = 1000*y*(0.5-y)*z*(0.4-z), uB = 0, uC = 0); real[int] rhs = vPb(0, Wh, tgv = -1); -set(A, sparams = "-pc_type lu -pc_factor_mat_solver_type mumps"); +set(A, sparams = "-pc_type lu"); Wh def(u); A = vPb(Wh, Wh, tgv = -1); diff --git a/examples/hpddm/stokes-fieldsplit-3d-PETSc.edp b/examples/hpddm/stokes-fieldsplit-3d-PETSc.edp index 74bf62b48..93a280211 100644 --- a/examples/hpddm/stokes-fieldsplit-3d-PETSc.edp +++ b/examples/hpddm/stokes-fieldsplit-3d-PETSc.edp @@ -12,6 +12,12 @@ real Sqrt = sqrt(2.); macro div(u)(dx(u) + dy(u#B) + dz(u#C))// EOM func Pk = [P2, P2, P2, P1]; // finite element space +string solver; +if(!HasType("MATSOLVER", "mumps") && !HasType("MATSOLVER", "superlu")) + exit(0); +else + solver = (HasType("MATSOLVER", "mumps") ? "mumps" : "superlu"); + mesh3 Th; { mesh ThGlobal2d = square(getARGV("-global", 12), getARGV("-global", 12), [x, y]); // global mesh @@ -33,7 +39,7 @@ names[0] = "velocity"; names[1] = "pressure"; A = vPb(Wh, Wh, tgv = -1); -set(A, sparams = "-ksp_type fgmres -pc_type fieldsplit -pc_fieldsplit_type schur -pc_fieldsplit_schur_fact_type lower -pc_fieldsplit_detect_saddle_point -fieldsplit_velocity_sub_pc_type lu " + " -fieldsplit_pressure_sub_pc_type lu -fieldsplit_velocity_sub_pc_factor_mat_solver_type mumps " + " -fieldsplit_pressure_sub_pc_factor_mat_solver_type mumps -ksp_monitor -ksp_view " + " -fieldsplit_velocity_ksp_type gmres -fieldsplit_velocity_ksp_max_it 5 -fieldsplit_pressure_ksp_type gmres -fieldsplit_pressure_ksp_max_it 5 -ksp_rtol 1e-6", fields = u[], names = names); +set(A, sparams = "-ksp_type fgmres -pc_type fieldsplit -pc_fieldsplit_type schur -pc_fieldsplit_schur_fact_type lower -pc_fieldsplit_detect_saddle_point -fieldsplit_velocity_sub_pc_type lu " + " -fieldsplit_pressure_sub_pc_type lu -fieldsplit_velocity_sub_pc_factor_mat_solver_type " + solver + " -fieldsplit_pressure_sub_pc_factor_mat_solver_type " + solver + " -ksp_monitor -ksp_view " + " -fieldsplit_velocity_ksp_type gmres -fieldsplit_velocity_ksp_max_it 5 -fieldsplit_pressure_ksp_type gmres -fieldsplit_pressure_ksp_max_it 5 -ksp_rtol 1e-6", fields = u[], names = names); u[] = 0.0; u[] = A^-1 * rhs; macro def1(u)u// diff --git a/examples/hpddm/toy-Tao-PETSc.edp b/examples/hpddm/toy-Tao-PETSc.edp index ae0f8664a..9b86e5b8d 100644 --- a/examples/hpddm/toy-Tao-PETSc.edp +++ b/examples/hpddm/toy-Tao-PETSc.edp @@ -43,6 +43,11 @@ func int funcJE(real[int]& in) { JE = sp; return 0; } +string solver; +if(!HasType("MATSOLVER", "mumps") && !HasType("MATSOLVER", "superlu")) + exit(0); +else + solver = (HasType("MATSOLVER", "mumps") ? "mumps" : "superlu"); { func int funcH(real[int]& in) { real[int] diag(n); @@ -54,9 +59,9 @@ func int funcJE(real[int]& in) { for(int i = 0; i < 2; ++i) { real[int] x = [0, 0]; if(i == 0) - TaoSolve(H, J, DJ, x, xl = xl, xu = xu, sparams = "-tao_monitor -tao_type bqnls -pc_type lu -pc_factor_mat_solver_type mumps"); + TaoSolve(H, J, DJ, x, xl = xl, xu = xu, sparams = "-tao_monitor -tao_type bqnls -pc_type lu -pc_factor_mat_solver_type " + solver); else - TaoSolve(H, J, DJ, x, xl = xl, xu = xu, sparams = "-tao_monitor -tao_type bnls -pc_type lu -pc_factor_mat_solver_type mumps", HessianRoutine = funcH); + TaoSolve(H, J, DJ, x, xl = xl, xu = xu, sparams = "-tao_monitor -tao_type bnls -pc_type lu -pc_factor_mat_solver_type " + solver, HessianRoutine = funcH); cout << "J([" << x[0] << ", " << x[1] << "]) = " << J(x) << endl; } } @@ -70,7 +75,7 @@ func int funcJE(real[int]& in) { return 0; } real[int] x = [0, 0]; - TaoSolve(H, J, DJ, x, xl = xl, xu = xu, sparams = "-tao_monitor -tao_type ipm -pc_type lu -pc_factor_mat_solver_type mumps", HessianRoutine = funcH, EqualityConstraints = funcE, JacobianEquality = funcJE, JE = JE); + TaoSolve(H, J, DJ, x, xl = xl, xu = xu, sparams = "-tao_monitor -tao_type ipm -pc_type lu -pc_factor_mat_solver_type " + solver, HessianRoutine = funcH, EqualityConstraints = funcE, JacobianEquality = funcJE, JE = JE); cout << "J([" << x[0] << ", " << x[1] << "]) = " << J(x) << ", E(x) = " << funcE(x)[0] << " (= 0)" << endl; } { @@ -115,9 +120,9 @@ func int funcJE(real[int]& in) { return 0; } real[int] x = [0, 0]; - TaoSolve(H, J, DJ, x, xl = xl, xu = xu, sparams = "-tao_monitor -tao_type ipm -pc_type lu -pc_factor_mat_solver_type mumps", HessianRoutine = funcHnoE, InequalityConstraints = funcI, JacobianInequality = funcJI, JI = JI); + TaoSolve(H, J, DJ, x, xl = xl, xu = xu, sparams = "-tao_monitor -tao_type ipm -pc_type lu -pc_factor_mat_solver_type " + solver, HessianRoutine = funcHnoE, InequalityConstraints = funcI, JacobianInequality = funcJI, JI = JI); cout << "J([" << x[0] << ", " << x[1] << "]) = " << J(x) << ", I(x) = [" << funcI(x)[0] << ", " << funcI(x)[0] << "] (>= [0, 0])" << endl; x = [0, 0]; - TaoSolve(H, J, DJ, x, xl = xl, xu = xu, sparams = "-tao_monitor -tao_type ipm -pc_type lu -pc_factor_mat_solver_type mumps", HessianRoutine = funcH, EqualityConstraints = funcE, JacobianEquality = funcJE, JE = JE, InequalityConstraints = funcI, JacobianInequality = funcJI, JI = JI); + TaoSolve(H, J, DJ, x, xl = xl, xu = xu, sparams = "-tao_monitor -tao_type ipm -pc_type lu -pc_factor_mat_solver_type " + solver, HessianRoutine = funcH, EqualityConstraints = funcE, JacobianEquality = funcJE, JE = JE, InequalityConstraints = funcI, JacobianInequality = funcJI, JI = JI); cout << "J([" << x[0] << ", " << x[1] << "]) = " << J(x) << ", E(x) = " << funcE(x)[0] << " (= 0), I(x) = [" << funcI(x)[0] << ", " << funcI(x)[0] << "] (>= [0, 0])" << endl; } diff --git a/examples/plugin/Helmholtz_FD.edp b/examples/plugin/Helmholtz_FD.edp index bb1a8e065..f0454167b 100644 --- a/examples/plugin/Helmholtz_FD.edp +++ b/examples/plugin/Helmholtz_FD.edp @@ -78,10 +78,9 @@ fespace Uh(Th,P1); Uh rhs = 0; rhs[][idist] = -1./(h^3); -int[int] pmlsides(6), npmls(6); -pmlsides = 1; +int[int] npmls(6); npmls = npml; -matrix A = HelmholtzFD(Th,omega,mu,npml=npmls,pmlsides=pmlsides); +matrix A = HelmholtzFD(Th,omega,mu,npml=npmls); set(A,solver=sparsesolver); Uh u, uexact = exact*supp; diff --git a/examples/plugin/Makefile.am b/examples/plugin/Makefile.am index 1cddc2294..1429698a3 100644 --- a/examples/plugin/Makefile.am +++ b/examples/plugin/Makefile.am @@ -100,9 +100,10 @@ TESTS_OTHER = APk-AdaptEpsDeltaPk.edp \ testFEMorley.edp \ testp1dcnc.edp \ iovtk.edp \ - ConnectedComponents.edp + ConnectedComponents.edp \ + testFE-P3dc.edp cavityNewtowP3pnc.edp -TESTS_FFTW3 = dfft.edp +TESTS_FFTW3 = dfft.edp dfft-3d.edp TESTS_FORTRAN = ffnewuoa.edp diff --git a/examples/plugin/cavityNewtowP3pnc.edp b/examples/plugin/cavityNewtowP3pnc.edp new file mode 100644 index 000000000..c2fe6e470 --- /dev/null +++ b/examples/plugin/cavityNewtowP3pnc.edp @@ -0,0 +1,139 @@ +/* + * Incompressible Navier Stokes + * with Taylor-Hood Finite element + * Non linearity : Newton method + * continuation on Reynols Number + * Mesh adaptation +*/ +if (HaveUMFPACK) +{// just do with UMPACK fgmres do not converge !!! +load "Element_P3pnc" + +// Parameters +real reyini= 500; +real reymax = 1000; // ok < 125000 + +func BCu1 = 4*x*(1-x); +real epsr=1e-6; + +// Mesh + + +mesh Th = square(8, 8); +func PkX = P3pnc; +func PkM = P2dc; + +// Fespace +fespace Xh(Th, PkX); +Xh uu1, uu2; +Xh psi, phi; + +fespace Mh(Th, PkM); +fespace XXMh(Th, [PkX, PkX, PkM]); +XXMh [u1, u2, p]; +XXMh [v1, v2, q]; +XXMh [up1, up2, pp]; + +// Macro +macro div(u1, u2) (dx(u1) + dy(u2)) // +macro grad(u1, u2) [dx(u1), dy(u2)] // +macro ugrad(u1, u2, v) (u1*dx(v) + u2*dy(v)) // +macro Ugrad(u1, u2, v1, v2) [ugrad(u1, u2, v1), ugrad(u1, u2, v2)] // + +// Problem Stokes (with solve) +solve Stokes ([u1, u2, p], [v1, v2, q], solver=sparsesolver) + = int2d(Th,qforder=9)( + ( dx(u1)*dx(v1) + dy(u1)*dy(v1) + + dx(u2)*dx(v2) + dy(u2)*dy(v2) ) + - p * q * epsr + - p*div(v1, v2) - q*div(u1, u2) + ) + + on(3, u1=BCu1, u2=0) + + on(1, 2, 4, u1=0, u2=0); + +// Plot +uu1 = u1; +uu2 = u2; +plot(coef=0.2, cmm="[u1, u2] and p" ,p, [uu1, uu2], wait=1); + +// Problem stream-lines (with solve) +solve streamlines (psi, phi) + = int2d(Th,qforder=9)( + dx(psi)*dx(phi) + + dy(psi)*dy(phi) + ) + + int2d(Th,qforder=9)( + - phi*(dy(u1) - dx(u2)) + ) + + on(1, 2, 3, 4, psi=0); + +// Plot +plot(psi, wait=1); +real nu = 1.; + +// Variatonal form definition Navier-Stokes +int i = 0; + +varf vDNS ([u1, u2, p], [v1, v2, q]) + = int2d(Th,qforder=9)( + + nu * ( + dx(u1)*dx(v1) + dy(u1)*dy(v1) + + dx(u2)*dx(v2) + dy(u2)*dy(v2) + ) + - p * q * epsr + - p*div(v1, v2) - q*div(u1, u2) + + Ugrad(u1, u2, up1, up2)'*[v1, v2] + + Ugrad(up1, up2, u1, u2)'*[v1, v2] + ) + + on(3, u1=BCu1, u2=0) + + on(1, 2, 4, u1=0, u2=0); + ; + +varf vNS ([u1, u2, p], [v1, v2, q]) // DF(u)u - F(u) + = int2d(Th,qforder=9)( + Ugrad(up1, up2, up1, up2)'*[v1, v2] + ) + + on(3, u1=BCu1, u2=0) + + on(1, 2, 4, u1=0, u2=0); + ; + +for (real re = reyini ; re <= reymax; re *= 2) { + real lerr = 1; + nu = 1./re; + + if (re > 8000) lerr = 0.2; + if (re > 10000) lerr = 0.05; + for (int step = 0; step < 2; step++) { + // Mesh adaptation & interpolation + Th = adaptmesh(Th, [dx(u1), dx(u2),dy(u1), dy(u2)], p, err=lerr, nbvx=100000, abserror=0, cutoff=0.01); + [u1, u2, p] = [u1, u2, p]; + [up1, up2, pp] = [up1, up2, pp]; + + // Newton + for (i = 0; i <= 20; i++) { + // Update + up1[] = u1[]; + + // Solve + real[int] b = vNS(0, XXMh); // build right hand side + matrix Ans = vDNS(XXMh, XXMh); // build matrix + set(Ans, solver=sparsesolver); // set solver + u1[] = Ans^-1*b; // solve linear system + + // Error + b = u1[]-up1[]; + + cout << "iter = "<< i << ", err = " << b.l2 << ", rey = " << re << endl; + + // Convergence criteria + if (b.l2 < 1e-4) break; + } + } + + // Stream-lines + uu1 = u1; + uu2 = u2; + streamlines; + plot(coef=0.2, cmm="rey="+re+" [u1, u2] and p", psi, [uu1, uu2], wait=0, nbiso=20); +} +} diff --git a/examples/plugin/dfft-3d.edp b/examples/plugin/dfft-3d.edp new file mode 100644 index 000000000..5c149f55c --- /dev/null +++ b/examples/plugin/dfft-3d.edp @@ -0,0 +1,96 @@ +// Example of dynamic function load +// -------------------------------- +// $Id$ +// Discret Fast Fourier Transform +// ------------------------------- + load "dfft" + load "msh3" + { +int nx=32,ny=32,nz=32,N=nx*ny*nz; +// warning the fourier space is not exactly the unite square due to periodic condition +mesh3 Th=cube(nx-1,ny-1,nz-1,[(nx-1)*x/nx, (ny-1)*y/ny, (nz-1)*z/nz ]); +// warring the numbering is of the vertices (x,y) is +// given by $ i = round(x*nx) + nx* round(y*ny) + nx*ny* round(z*nz); +int nerr=0; +for(int v=0; v u; + // Lapacien en FFT \hfilll + // $ -\Delta u = f $ with full periodic condition \hfilll +func f = cos(3*2*pi*x)*cos(2*2*pi*y)*sin(2*pi*z); // +func ue = +(1./(square(2*pi)*14.))*cos(3*2*pi*x)*cos(2*2*pi*y)*sin(2*pi*z); // the exact solution +Vh ff = f; +Vh fhat; +fhat[] = dfft(ff[],ny,nz,-1); + +Vh wij; +// warning in fact we take mode between -nx/2, nx/2 and -ny/2,ny/2 +// thank to the operator ?: \label{?:} +wij = square(2.*pi)*( square((x<0.5?x*nx:(x-1)*nx)) + + square((y<0.5?y*ny:(y-1)*ny)) + + square((z<0.5?z*nz:(z-1)*nz)) ); + +real c2 = sqr(2*pi); +// New wait to set fourier function more simpile +mapkkk(wij[],P,ny,nz,c2*P.norm2); +wij[][0] = 1e-5; // to remove constante .. + +plot(wij,wait=1); +fhat[] = fhat[]./ wij[]; // +u[]=dfft(fhat[],ny,nz,1); +u[] /= complex(N); +Vh ur,w; +ur = real(u); // the solution +w = real(ue); // the exact solution +plot(ur,value=1 ,cmm=" ue ", wait=1); +w[] -= ur[]; // array sub +real err= abs(w[].max)+abs(w[].min) ; +cout << " err = " << err << endl; +assert( err < 1e-6); +} +// test in all dimention ... + { +int n1=32,n2=32; +mesh Th= square(n1-1,n2-1); +fespace Vh(Th,P1); +Vh u; +//verbosity=29; +R3 K; +mapkk(u[],K,n2,K.norm2); +//cout << u[] << endl; +plot(u,wait=1); + +} +{ load "msh3" +int n1=32,n2=32,n3=32; +mesh3 Th= cube(n1-1,n2-1,n3-1); +fespace Vh(Th,P1); +Vh u; +//verbosity=29; +R3 K; +mapkkk(u[],K,n2,n3,K.norm2); +//cout << u[] << endl; +plot(u,wait=1); + +} +{ +int n1=32; +meshL Th= segment(n1-1); +fespace Vh(Th,P1); +Vh u; +//verbosity=29; +R3 K; +mapk(u[],K,K.norm2); +//cout << u[] << endl; +plot(u,wait=1); + +} + diff --git a/examples/plugin/dfft.edp b/examples/plugin/dfft.edp index 85dfd2e42..e18c2eb72 100644 --- a/examples/plugin/dfft.edp +++ b/examples/plugin/dfft.edp @@ -41,7 +41,7 @@ Vh ff = f; Vh fhat; fhat[] = dfft(ff[],ny,-1); -Vh wij; +Vh wij,wijm; // warning in fact we take mode between -nx/2, nx/2 and -ny/2,ny/2 // thank to the operator ?: \label{?:} wij = square(2.*pi)*(square(( x<0.5?x*nx:(x-1)*nx)) + square((y<0.5?y*ny:(y-1)*ny))); @@ -61,7 +61,11 @@ assert( err < 1e-6); fftwplan p1=plandfft(u[],v[],ny,-1); fftwplan p2=plandfft(u[],v[],ny,1); -real ccc = square(2.*pi); -cout << " ny = " << ny << endl; -map(wij[],ny,ccc*(x*x+y*y)); -wij[][0] = 1e-5; +//mapkk(wijm[],ny,cccx*(x*x)+cccy*(y*y)); +mapkk(wijm[],P,ny,sqr(2*pi*x)+sqr(2*pi*y)); +wijm[][0] = 1e-5; +plot(wij,wait=1); +plot(wijm,wait=1); +wij[]-=wijm[]; +cout << " err = " << wij[].linfty << endl; +assert( wij[].linfty < 1e-8); diff --git a/examples/plugin/testFE-P3pnc.edp b/examples/plugin/testFE-P3pnc.edp new file mode 100644 index 000000000..ec7950942 --- /dev/null +++ b/examples/plugin/testFE-P3pnc.edp @@ -0,0 +1,172 @@ + +load "Element_P4dc" +load "Element_P4" +load "Element_P3pnc" +func real cc(real aa) {real a=aa; if(abs(a)<1e-10) a=0; return a;} +int[int] ne1=[1,2,0]; +int[int] ne2=[2,0,1]; + +// the ref triangle +int[int] ll=[2,0,0,1]; +mesh Th=square(1,1,flags=2,label=ll); + +Th = trunc(Th,x<0.5,label=0); + + +//Th = movemesh(Th,[x+0.1*y,y-0.2*x]); +//Th = movemesh(Th,[x*2,y*2]); + +mesh Thg = trunc(Th,1,split=2,label=-1); +plot(Th, wait=1); + +int it0=0; + +fespace Lh(Th,P1); +Lh[int] l(3); +l[0][][0]=1; +l[1][][1]=1; +l[2][][2]=1; + + +fespace Wh(Th,P4dc); +fespace Vh(Th,P3pnc); +Wh[int] mn(12); +int k=0; +real cc7 = 3*4*5*6*7; +func bk = (l[0] - l[1]) * (l[1] - l[2]) * (l[2] - l[0]); +func l0 =l[0]; +func l1 =l[1]; +func l2 =l[2]; + +mn[k++]= l0 * l0 * l0; +mn[k++]= l1 * l1 * l1; +mn[k++]= l2 * l2 * l2; //3 +mn[k++]= l0 * l0 * l1; +mn[k++]= l0 * l0 * l2; +mn[k++]= l1 * l1 * l0; +mn[k++]= l1 * l1 * l2; +mn[k++]= l2 * l2 * l0; +mn[k++]= l2 * l2 * l1; + //6 +mn[k++]= l0 * l1 * l2; //2 +mn[k++]= bk * l0; +mn[k++]= bk * l1 ; // P4 element + + +/* + l0 * l0 * l0, l1 * l1 * l1, l2 * l2 * l2, //3 + l0 * l0 * l1, l0 * l0 * l2, l1 * l1 * l0, l1 * l1 * l2, l2 * l2 * l0, l2 * l2 * l1, //6 + l0 * l1 * l2, //2 + bk * l0, bk * l1 // P4 element + +*/ +/* +for(int i=0; i<3;++i) +{ + int i1 = (i+1)%3, i2=(i+3)%3; + mn[k++]= l[i]; + mn[k++]= l[i1]*l[i2]; + mn[k++]= l[i]*l[i]*l[i]; + +} +mn[k++]= l[0]*l[1]*l[2]; +mn[k++]= l[0]*bk; +mn[k++]= l[1]*bk; +*/ +Vh u,v; +real[int,int] CC(12,12),C1(12,12); +for (int j=0;j " << i << " : " ; + u=0; + u[][i]=1; + for(int k=0; k<3;k++) + { + int i1= (k+1)%3, i2=(k+2)%3; + if ( i2 < i1) swap(i1,i2); + cout << " " << cc(int1d(Th,k,qforder=9)(u*l[i1]/lenEdge)) << " " << cc(int1d(Th,k,qforder=9)(u*l[i2]/lenEdge)) << " " << cc(int1d(Th,k,qforder=9)(u*l[i2]*l[i1]/lenEdge)) ; + } + cout << " " << cc(int2d(Th,qforder=9)( l[0]*u/area)) << " " << cc(int2d(Th,qforder=9)( l[1]*u/area)) <<" " << cc(int2d(Th,qforder=9)( l[2]*u/area)) << endl; + //plot(u,wait=1); + v=u; + for (int j=0;j 1e-6) + cout << i << " " << e << " " << e1 << " " << e2 << " :: " << dxu []. linfty << " " << dyu []. linfty << endl; + err+= ee; +} +cout << " err=" << err << endl; ; +assert( err < 1e-6); \ No newline at end of file diff --git a/examples/tutorial/Makefile.am b/examples/tutorial/Makefile.am index 23082a841..a3d7f9896 100644 --- a/examples/tutorial/Makefile.am +++ b/examples/tutorial/Makefile.am @@ -25,7 +25,14 @@ TESTS_ENVIRONMENT=TEST_FFPP=$(TEST_FFPP) FLAGS_FFPP=-nw all-local: all.edp regtests.edp freefem++.pref -TESTS=forall.edp adapt.edp adaptindicatorP1.edp adaptindicatorP2.edp algo.edp array.edp a_tutorial.edp beam.edp calculus.edp cavity.edp convect2.edp convect-apt.edp convect.edp dumptable.edp ex-vf.edp FE.edp fluidStructAdapt.edp fluidStruct.edp freeboundary.edp freeboundary-weak.edp LapDG2.edp Laplace.edp LaplaceP1bis.edp LaplaceP1.edp LaplaceP1P2h.edp LaplaceRT.edp mesh.edp movemesh.edp nolinear-elas.edp NSUzawaCahouetChabart.edp onde.edp periodic4.edp Periodic.edp plot.edp readmesh.edp region.edp saverestore.edp schwarz-gc.edp schwarz-no-overlap.edp schwarz-overlap.edp sparse-matrix.edp sparse-cmatrix.edp StokesUzawa.edp tablefunction.edp intlevelset.edp mesh-internal.edp minlenedge.edp AdjointSolve.edp +TESTS=forall.edp adapt.edp adaptindicatorP1.edp adaptindicatorP2.edp algo.edp array.edp a_tutorial.edp \ +beam.edp calculus.edp cavity.edp convect2.edp convect-apt.edp convect.edp dumptable.edp ex-vf.edp FE.edp \ +fluidStructAdapt.edp fluidStruct.edp freeboundary.edp freeboundary-weak.edp LapDG2.edp Laplace.edp \ +LaplaceP1bis.edp LaplaceP1.edp LaplaceP1P2h.edp LaplaceRT.edp mesh.edp movemesh.edp nolinear-elas.edp \ +NSUzawaCahouetChabart.edp onde.edp periodic4.edp Periodic.edp plot.edp readmesh.edp region.edp saverestore.edp \ +schwarz-gc.edp schwarz-no-overlap.edp schwarz-overlap.edp sparse-matrix.edp sparse-cmatrix.edp StokesUzawa.edp \ +tablefunction.edp intlevelset.edp mesh-internal.edp minlenedge.edp AdjointSolve.edp tgv-test.edp \ +nl-elas-neo-Hookean.edp EXTRA_DIST=*.edp aile.msh xyf all.edp regtests.edp regtests.m4 ref.edp diff --git a/examples/tutorial/calculus.edp b/examples/tutorial/calculus.edp index 0a2e34615..8deba4932 100644 --- a/examples/tutorial/calculus.edp +++ b/examples/tutorial/calculus.edp @@ -60,3 +60,31 @@ cout << "str = " << str << " == abc++abcddddd+2;\n"; string ss = "\z\a\b\f\\--\\"; cout << "\"" << ss << "\"" << endl; } + +// Add basic operation on R3 version 4.10.1 feb. 2022 +// to speed up compuatution +R3 A(1.,2.,3.); +R3 B(3.,1.,0.); +R3 AB(A,B); // bipoint affine construction .. +R3 C = A^B; // cross product .. +R3 AB1 = A.*B ; // product by componant by componant +R3 AB2 = A./B ; // div by componant by componant +R3 Q= A+3*B+C-B; +cout << "det= " << det(A,B,C) << " == " << (A^B)'*C << endl; +cout << Q.x << " " << Q.y << " "<< Q. z << endl; +Q.x =1; +P=Q;// Current pojnt +cout << P.x << " " << P.y << " "<< P. z << endl; +cout <<"P=" << P << " det " << det(A,B,C) << endl; +cout << "R3" << R3(1,3,6) << " R3(A,) =" << R3(A,B) << endl; +cout << C.l2 << " " << C.norm << " " << C.linfty << " " << C << " dot product: " << C'*C << endl; +real[int] E=A; // def array from R3* +real[int] F2=A+A; // def array from R3 +R3 F3=E; // def R3 from array +F3=E; // set R3 from array +F3+=E; +R3 O(0,0,0),E1(1,0,0),E2(0,1,0),E3(0,0,1); +cout << " solidangle " << solidangle(O,E1,E2,E3) << " == " << pi/2 << endl; +cout << A'*R3(1,1,1) << endl; +cout << R3(1,2,3).norm << " == " << sqrt(14.) << endl; + diff --git a/examples/tutorial/mesh.edp b/examples/tutorial/mesh.edp index 3e65671f4..2c8904488 100644 --- a/examples/tutorial/mesh.edp +++ b/examples/tutorial/mesh.edp @@ -216,7 +216,8 @@ plot(rh,ps="lshape.eps"); for (int i=0;i3.4-1 // --------- new stuff ----------------- - int k=0,l=1,e=1; + int k=0,l=1,e=1,v=1; Th.nbe ; // return the number of boundary element \hfilll + Th(v).P; // coordinate of vetices v in R3 :: 22 jan 2022 Th.be(k); // return the boundary element k $\in \{0,...,Th.nbe-1\}$ \hfilll Th.be(k)[l]; // return the vertices l $\in \{0,1\}$ of boundary element k \hfilll Th.be(k).Element ; // return the triangle contening the boundary element k \hfilll Th.be(k).whoinElement ; // return the egde number of triangle contening the boundary element k \hfilll + Th.be(k).N ; // return the Normal to be(k) version 4.10.1 Th[k].adj(e) ; // return adjacent triangle to k by edge e, and change the value of e to \hfilll + // the corresponding edge in the adjacent triangle Th[k] == Th[k].adj(e) ;// non adjacent triangle return the same Th[k] != Th[k].adj(e) ;// true adjacent triangle @@ -278,7 +282,7 @@ plot(rh,ps="lshape.eps"); Th.be; for (int k=0;k (sqrt(I3)-1)^2 ' = sqrt(I3)' (sqrt(I3)-1) = 0.5 I3' (1-1/sqrt(I3)) +// -1/sqrt(I3)' = 0.5 I3''/(sqrt(I3)*I3) +// the enarge ... +macro W(I) ( + C1*(I[0] - 4. - log(I[2]) ) + + D1 *sqr(1.-sqrt(I[2])) ) //EOM (J-1)^2 + +macro dW(I,dI) ( + C1* (dI[0] - dI[2]/I[2] ) + + 0.5*D1*dI[2]*(1.-1/sqrt(I[2]) ) + ) //EOM +// EOM +macro ddW(I,dI,ddI) ( + +C1/sqr(I[2])*ddI[2]*dI[2] + + 0.25*D1* dI[2]*ddI[2]/(sqrt(I[2])*I[2]) + ) //EOM + // EOM + +// ************************************************ +// THE (BIO)MECHANICAL PARAMETERS: Begin + +// Elastic coefficients + + +// Stress loads +real Pa = -3.e2; + + +// THE (BIO)MECHANICAL PARAMETERS: End +// ************************************************ + + +// ************************************************ +// THE COMPUTATIONAL PARAMETERS: Begin + +// The wound radius +real InnerRadius = 1.e0; + +// The outer (truncated) radius +real OuterRadius = 4.e0; + +// Tolerance (L^2) +real tol = 1.e-4; + +// Extension of the inner ellipse ((major axis) - (minor axis)) +real InnerEllipseExtension = 1.e0; + +int m = 100, n = 50; + +border InnerEdge(t = 0, 2.0*pi) {x = (1.0 + InnerEllipseExtension) * InnerRadius * cos(t); y = InnerRadius * sin(t); label = 1;} + +border OuterEdge(t = 0, 2.0*pi) {x = (1.0 + 0.0 * InnerEllipseExtension) * OuterRadius * cos(t); y = OuterRadius * sin(t); label = 2;} + +mesh Th = buildmesh(InnerEdge(-m) + OuterEdge(n)); +plot(Th,wait=1); +int bottom=1, right=2,upper=3,left=4; + +int Nnewton = 20; +real epsNewton = 1.e-10; + +fespace Wh(Th,[P2,P2]); + +// methode de Newton .. + + Wh [d1,d2]=[0,0/100]; // Ok CL sirichlet homogene . + Wh [w1,w2],[v1,v2]; + + cout << 0 << " Energie = " << int2d(Th)(W2d([d1,d2])) - int1d(Th,1)( Pa * ([d1,d2]'*[N.x,N.y]) ) << endl; + + for(int i=0;i= tol) -{ - loopcount ++; - - //////////////////////////////////////////////////////////// - - cout << "Loop " << loopcount << endl; - -// plot([u1n,u2n], wait=0, cmm="displacement:" ); - -/* - cout << "TESTING: Begin" << endl; - cout << "dFStress2PK11 = " << dFStress2PK11 (u1n, u2n, varu1, varu2) << endl; - cout << "TESTING: End" << endl; - - cout << "B11 = " << B11(u1n, u2n) << endl; - cout << "B12 = " << B12(u1n, u2n) << endl; - cout << "B21 = " << B21(u1n, u2n) << endl; - cout << "B22 = " << B22(u1n, u2n) << endl << endl; - - cout << "J = " << J(u1n, u2n) << endl << endl; - - StrK11 = StressK11(u1n, u2n); - StrK12 = StressK12(u1n, u2n); - StrK21 = StressK21(u1n, u2n); - StrK22 = StressK22(u1n, u2n); - - cout << "StressK11 = " << StrK11 << endl; - cout << "StressK12 = " << StrK12 << endl; - cout << "StressK21 = " << StrK21 << endl; - cout << "StressK22 = " << StrK22 << endl; -*/ - - neoHookeanInc; // compute [varu1,varu2] = (D^2 J(u1n))^{-1}(D J(u1n)) - -// cout << "This marker reached" << endl; - - - u1 = varu1; - u2 = varu2; - - w1[] = Mass*varu1[]; - - res = sqrt(w1[]' * varu1[]); // norme L^2 of [varu1, varu2] - -// cout << " u1 min =" <=0 set to tgv value on diagonal term of Dof with label 1 or 2 + +fespace Vh(Th,P1); +int symj = 0; +// for [j,symj:vsym] buggus never get sym matrix .... FH.. +for [i,tgvi:vtgv] +{ + verbosity=9; + matrix A= va(Vh,Vh,tgv=tgvi,sym=symj,solver="GMRES"); + real[int,int] F(Vh.ndof,Vh.ndof); // to copy sparse matrix in full matrix .. + F=0.; + for [i,j,aij:A] + F(i,j) = aij; + cout << " sym= " << symj << " tgv = " << tgvi << " matrix= " << F << "\n\n\n"; +} \ No newline at end of file diff --git a/idp/ElasticLaw2d.idp b/idp/ElasticLaw2d.idp new file mode 100644 index 000000000..6916aea32 --- /dev/null +++ b/idp/ElasticLaw2d.idp @@ -0,0 +1,88 @@ +// -------------------------------------------------------------------------- +// Definition of Kinematics Operators +// -------------------------------------------------------------------------- +// notation ...\hfilll +// +// all 2x2 symetric matrix [[a11,a12], [a21,a22] are see as an array \hfilll +// [a11,a22,a12] .. \hfilll +// the strain(d) = $ \varepsilon(d) = (\nabla d + {}^t(\nabla d)/2 $ matrix is \hfilll +// we always use the differential notation \hfilll +// so $F(y)$ is a fonction ; when $ dy \mapsto dF(y,dy)$ is the Frechet differentiel \hfilll +// add second Frechet differentiel is $ (dy,ddy) \mapsto ddF(y,dy,ddy)$ \hfilll + +// -------------------------------------------------------------------------- +// the vector displacement parameter d = [d1,d2] \hfilll +macro Strain2(d) +[ +dx(d[0]), +dy(d[1]), +dy(d[0])+dx(d[1]) +] //EOM + +// -------------------------------------------------------------------------- +// definition of C(d) = $ {}^t F F$ and 2 differentiel +// with , with $F = Id + \nabla d$ where $Id$ is the identity matrix +macro C2(d) +[ +1. + 2.*dx(d[0]) + dx(d[0])*dx(d[0]) + dx(d[1])*dx(d[1]) , +1. + 2.*dy(d[1]) + dy(d[0])*dy(d[0]) + dy(d[1])*dy(d[1]) , + dy(d[0]) + dx(d[1]) + dx(d[0])*dy(d[0]) + dx(d[1])*dy(d[1]) +] // +macro dC2(d,dd) +[ + 2.*dx((dd)[0]) + 2.*dx((dd)[0])*dx(d[0]) + 2.*dx((dd)[1])*dx(d[1]) , + 2.*dy((dd)[1]) + 2.*dy((dd)[0])*dy(d[0]) + 2.*dy((dd)[1])*dy(d[1]) , + dy((dd)[0]) + dx((dd)[1]) + dx((dd)[0])*dy(d[0]) + dx((dd)[1])*dy(d[1]) + + dx(d[0])*dy((dd)[0]) + dx(d[1])*dy((dd)[1]) +] // +macro ddC2(dd,ddd) +[ + 2.*dx((dd)[0])*dx((ddd)[0]) + 2.*dx((dd)[1])*dx((ddd)[1]) , + 2.*dy((dd)[0])*dy((ddd)[0]) + 2.*dy((dd)[1])*dy((ddd)[1]) , + dx((dd)[0])*dy((ddd)[0]) + dx((dd)[1])*dy((ddd)[1]) + + dx((ddd)[0])*dy((dd)[0]) + dx((ddd)[1])*dy((dd)[1]) +] // + +// -------------------------------------------------------------------------- +// definition of the 3 invariant I[0], I[1], I[2]in 2d +// so the value is an array size 3 . +// I2C (I (C) 2d ..) +// +// I[0] = trace(C) +1 +// I[1] = (trace(C)^2 - trace(C^2) )/2 +// I[2] = det(C) +// ************** BIZARRE FH *********************** + +macro I2C(C) +[ + C[0] + C[1] + 1., + C[0]*C[1] + C[1] + C[0] - C[2]*C[2], + C[0]*C[1] - C[2]*C[2] +] //EOM + +macro dI2C(C,dC) + [ + dC[0] + dC[1] , + dC[0]*C[1] + dC[1] + dC[0] - 2.*dC[2]*C[2] + C[0]*dC[1], + dC[0]*C[1] + C[0]*dC[1] - 2.*C[2]*dC[2] + ] // + +macro ddI2C(dC,ddC) +[ + 0.*dC[0]*ddC[0] , + dC[0]*ddC[1] - 2.*dC[2]*ddC[2] + ddC[0]*dC[1], + dC[0]*ddC[1] + ddC[0]*dC[1] - 2.*ddC[2]*dC[2] + ] // + + +macro I2d(d) I2C(C2(d)) // +macro dI2d(d,dd) dI2C( C2(d) , dC2(d,(dd)) ) // +macro ddI2d(d,dd,ddd) ( ddI2C( dC2(d,(dd)),dC2(d,(ddd)) ) + dI2C( C2(d) , ddC2((dd),(ddd)) ) ) // +macro W2d(d) W(I2d(d)) // +macro dW2d(d,dd) dW( I2d(d) , dI2d(d,(dd)) ) // +macro ddW2d(d,dd,ddd) +( ddW( I2d(d) , dI2d(d,(dd)) ,dI2d(d,(ddd)) ) + dW( I2d(d) , ddI2d(d,(dd),(ddd)) ) ) // + + + + \ No newline at end of file diff --git a/idp/MeshSurface.idp b/idp/MeshSurface.idp index 582173300..1e8b14b8c 100644 --- a/idp/MeshSurface.idp +++ b/idp/MeshSurface.idp @@ -19,6 +19,15 @@ load "mmg" L is the label the the sphere orient the global orientation of the surface 1 extern (-1 intern + func meshS Icosahedron (int orientation) + -- build a Icosahedron meshS with given orientation. + with a region number go from 1 to 20 corresponding to the 20 faces + + func meshS Sphere20(real R,int N,int orient); + -- build a sphere mesh form a Isocaedron with each traingle subdivide by N^2 + with a region number go from 1 to 20 corresponding to the 20 faces + orient the global orientation of the surface 1 extern (-1 intern + */ func meshS SurfaceHex(int[int] & N,real[int,int] &B ,int[int,int] & L,int orientation) { @@ -94,6 +103,106 @@ func meshS Sphere(real R,real h,int L,real Ox,real Oy,real Oz,int orientation) return Ellipsoide(R,R,R,h,L,Ox,Oy,Oz,orientation); } +func meshS Icosahedron (int orientation,int wplot) +{ + +//=================================================================================== +//Angles utiles +//=================================================================================== +real tan3pi10 = sqrt(25.+10.*sqrt(5.))/5.;//3pi/10 angle entre deux aretes du pentagone +real sin3pi10 = (sqrt(5)+1)/4;//3pi/10 angle entre deux aretes du pentagone +real cos3pi10 = sqrt(10-2*sqrt(5))/4;//3pi/10 angle entre deux aretes du pentagone + +real cosdiedre = sqrt(5)/3; //angle diedre de l'icosaedre -pi/2 +real sindiedre = 2./3; //angle diedre de l'icosaedre -pi/2 + +real cosico = tan3pi10/sqrt(3); //angle entre une face de la pyramide pentagonale par rapport à l'horizontale +real sinico = sqrt(1-square(cosico)); //angle entre une face de la pyramide pentagonale par rapport à l'horizontale + +real sin2pi5 = sqrt(10+2*sqrt(5))/4; //2pi/5 angle pour la rotation des aretes du pentagone +real cos2pi5 = (sqrt(5)-1)/4; //2pi/5 angle pour la rotation des aretes du pentagone + +real cosicod = cosdiedre*cosico+sindiedre*sinico;//angle diedre -pi/2 - ico +real sinicod = sindiedre*cosico-cosdiedre*sinico;//angle diedre -pi/2 - ico + + +real sinpi3 = sqrt(3)/2; //angle du triangle equilateral + +int n = 1; + +real sinpi5 = cos3pi10;//pi/5 angle de décalage entre deux demi icosaedre +real cospi5 = sin3pi10;//pi/5 angle de décalage entre deux demi icosaedre + +real tanpi10 = sqrt(25.-10.*sqrt(5.))/5.;//pi/10 +real h = 0.5*sqrt(3-square(tanpi10));//hauteur du prisme d'ordre 5; + +//================================================================================= +//Construction du triangle equilateral en 2D +//================================================================================= +border a(t=0,1){x=t; y=0; label =1;}; +border b(t=1,0.5){x=t; y=sqrt(3)*(1-t); label =2;}; +border c(t=0.5,0){x=t; y=sqrt(3)*(t); label =3;}; +mesh Triangle= buildmesh(a(n)+b(n)+c(n)); //traingle equilateral +if(wplot>2) plot (cmm="Triangle",Triangle,wait=1); + +func f = 1; + + +meshS Triangle3 = movemesh23(Triangle,transfo=[x,0,y]);//trianglesup +if(wplot>2) plot (cmm="Triangle3",Triangle3,wait=1); + +meshS TriangleS = change(fregion=1,movemeshS(Triangle3,transfo=[x,sinico*y+cosico*z,-cosico*y+sinico*z]));//rotation de -(pi - diedre) par rapport à l'axe des x pour former une face de la pyramide pentagonale +if(wplot>2) plot (cmm="TriangleS",TriangleS,wait=1); +//medit("face pyramide pentagonale",TriangleS); + +meshS TriangleI = change(fregion=2,movemeshS(TriangleS,transfo=[x,-cosdiedre*y+sindiedre*z,-sindiedre*y-cosdiedre*z],orientation=-1));//triangle inf rotation de l'angle diedre par rapport au triangle sup +if(wplot>2) plot (cmm="TriangleI",TriangleI,wait=1); + +meshS Triangles = TriangleI+TriangleS; + +if(wplot>1) plot (cmm="Triangles",Triangles,wait=1); +//medit("face pyramide pentagonale + face antiprisme d'ordre 5",Triangles); + +meshS T1 = change(movemeshS(Triangles,transfo=[x-0.5,y-sinpi3*cosico,z],orientation=1),fregion = region);//translation pour que la figure soit sur le bord du pentagone +meshS T2 = change(movemeshS(T1,transfo=[cos2pi5*x-sin2pi5*y,sin2pi5*x+cos2pi5*y,z],orientation=1),fregion = region+2);; +meshS T3 = change(movemeshS(T2,transfo=[cos2pi5*x-sin2pi5*y,sin2pi5*x+cos2pi5*y,z]),fregion = region+2);; +meshS T4 = change(movemeshS(T3,transfo=[cos2pi5*x-sin2pi5*y,sin2pi5*x+cos2pi5*y,z]),fregion = region+2);; +meshS T5 = change(movemeshS(T4,transfo=[cos2pi5*x-sin2pi5*y,sin2pi5*x+cos2pi5*y,z]),fregion = region+2);; + +meshS Tdemi= T1+T2+T3+T4+T5;//moitié de l'icosaedre +meshS Tdemi0 = movemeshS(Tdemi,transfo=[x,y,z+0.5*h]);//moitié supérieure +meshS Tdemi1 = movemeshS(Tdemi0,transfo=[x,y,-z]);//moitié inférieure +meshS Tdemi1rot = change(movemeshS(Tdemi1,transfo=[cospi5*x-sinpi5*y,sinpi5*x+cospi5*y,z],orientation=-1),fregion = region+10);//rotation de la moitié inférieure pour les emboiter +meshS Ticosaedre = Tdemi0+Tdemi1rot; +//Ticosaedre=trunc(Ticosaedre,1,split=5); +if(wplot) plot(Ticosaedre,wait=1); +//cout << regions(Ticosaedre) << endl; +return Ticosaedre; +} + +func meshS Icosahedron (int orientation) +{ + return Icosahedron(orientation,0); +} +func meshS Sphere20 (real R,int N,int orientation,int wplot) +{// Isocaedre regulier !!!! Thank G. Vergez .. +meshS Ticosaedre = Icosahedron(orientation,wplot); +Ticosaedre=trunc(Ticosaedre,1,split=N); +if(wplot) plot(cmm="Icosaedre",Ticosaedre,wait=1); + +//================================================================================= +//Construction de la sphere 3D +//================================================================================= +func metric =dist(x,y,z)/R; +meshS Th = movemeshS(Ticosaedre,transfo=[x/metric,y/metric,z/metric]); +if(wplot) plot (cmm="Th",Th,wait=1); +return Th; +} + +func meshS Sphere20 (real R,int N,int orientation) +{ + return Sphere20(R,N,orientation,0); +} /* test: load "tetgen" @@ -120,4 +229,5 @@ func meshS Sphere(real R,real h,int L,real Ox,real Oy,real Oz,int orientation) mesh3 Th = tetg(ThHS,switch="pqaAAYYQ",nbofregions=2,regionlist=domaine); medit("Cube-With-Ball",Th); } + */ \ No newline at end of file diff --git a/idp/ffddm.idp b/idp/ffddm.idp index 36bcd11fd..0f0fe03fe 100644 --- a/idp/ffddm.idp +++ b/idp/ffddm.idp @@ -194,7 +194,7 @@ real pr#ttotalelapsed = mpiWtime(); NewMacro pr#writesummary if (preffe#prmesh#isincomm) { - real[int] timings = [preffe#prmesh#tdecomp,pr#tfacto,pr#tbuildE,pr#tgmres,pr#tmv,pr#tprec,pr#tcs,pr#teigenv]; + real[int] timings = [preffe#prmesh#tdecomp,pr#tfacto,pr#tbuildE,pr#tgmres,pr#tmv,pr#tprec,pr#tcs,pr#teigenv,pr#tdirect]; real[int] timingsg(timings.n); timingsg = 0; mpiAllReduce(timings,timingsg,preffe#prmesh#mpicomm,mpiMAX); @@ -207,7 +207,7 @@ if (preffe#prmesh#isincomm) cout << "["+Stringification(pr)+"] timings - PREC : " << timingsg[5] << endl; cout << "["+Stringification(pr)+"] timings - COARSE SOLVE : " << timingsg[6] << endl; /*cout << "timings - scalprod : " << timingsg[7] << endl;*/ - cout << "["+Stringification(pr)+"] timings - total_sum : " << timingsg[3]+timingsg[0]+timingsg[1]+timingsg[2]+timingsg[7] << endl; + cout << "["+Stringification(pr)+"] timings - total_sum : " << timingsg[3]+timingsg[0]+timingsg[1]+timingsg[2]+timingsg[7]+timingsg[8] << endl; cout << "["+Stringification(pr)+"] timings - total elapsed wall time : " << mpiWtime()-pr#ttotalelapsed << endl; } pr#tgmres = 0; pr#tmv = 0; pr#tprec = 0; pr#tcs = 0; pr#tscalprod = 0; @@ -259,15 +259,16 @@ if (preffe#prmesh#inexactCSsplit == 1) ENDIFMACRO IFMACRO(pr#withpetsc) +pr#aRd[mpiRank(preffe#prmesh#commddm)].resize(preffe#Dk[mpiRank(preffe#prmesh#commddm)].n, preffe#Dk[mpiRank(preffe#prmesh#commddm)].n); IFMACRO(preffe#K,real) load "PETSc" -Mat pr#petscOP(pr#aRd[mpiRank(preffe#prmesh#commddm)], pr#intersectionhpddm, preffe#Dk[mpiRank(preffe#prmesh#commddm)], communicator = preffe#prmesh#commddm); +real[int] pr#petscDk = preffe#Dk[mpiRank(preffe#prmesh#commddm)]; ENDIFMACRO IFMACRO(preffe#K,complex) load "PETSc-complex" real[int] pr#petscDk = preffe#Dk[mpiRank(preffe#prmesh#commddm)].re; -Mat pr#petscOP(pr#aRd[mpiRank(preffe#prmesh#commddm)], pr#intersectionhpddm, pr#petscDk, scaled = false, communicator = preffe#prmesh#commddm); ENDIFMACRO +Mat pr#petscOP(pr#aRd[mpiRank(preffe#prmesh#commddm)], pr#intersectionhpddm, pr#petscDk, communicator = preffe#prmesh#commddm); ENDIFMACRO NewMacro pr#localmacrominoverlap() preffe#prmesh#mminoverlap EndMacro @@ -332,8 +333,8 @@ if (preffe#prmesh#isincomm) if ((!preffe#prmesh#excluded) && ((!bpara) || (i == mpiRank(preffe#prmesh#commddm)))) { preffe#prmesh#Thi = preffe#prmesh#aTh[i]; - - NewMacro localmacroaug preffe#prmesh#buildAug EndMacro + + NewMacro localmacroaug preffe#prmesh#buildAug EndMacro IFMACRO(localmacroaug,1) preffe#prmesh#AugThi = preffe#prmesh#AugaTh[i]; ENDIFMACRO @@ -394,13 +395,7 @@ if (preffe#prmesh#isincomm) ChangeOperator(pr#hpddmOP,pr#aRd[mpiRank(preffe#prmesh#commddm)]); ENDIFMACRO IFMACRO(pr#withpetsc) - IFMACRO(preffe#K,real) - Mat mat(pr#aRd[mpiRank(preffe#prmesh#commddm)], pr#intersectionhpddm, preffe#Dk[mpiRank(preffe#prmesh#commddm)], communicator = preffe#prmesh#commddm); - ENDIFMACRO - IFMACRO(preffe#K,complex) - real[int] pr#hpddmDk = preffe#Dk[mpiRank(preffe#prmesh#commddm)].re; - schwarz mat(pr#aRd[mpiRank(preffe#prmesh#commddm)], pr#intersectionhpddm, pr#hpddmDk, scaled = false, communicator = preffe#prmesh#commddm); - ENDIFMACRO + Mat mat(pr#aRd[mpiRank(preffe#prmesh#commddm)], pr#intersectionhpddm, pr#petscDk, communicator = preffe#prmesh#commddm); pr#petscOP = mat; ENDIFMACRO } @@ -410,6 +405,16 @@ if (preffe#prmesh#isincomm) Varf(vN,preffe#prmesh#Thi,preffe#Vhi) pr#matN = vN(preffe#Vhi,preffe2#Vhi,sym=vsym*(!pr#isrect),tgv=vtgv,solver=GMRES); ENDIFMACRO + IFMACRO(pr#myOperator) + pr#myOperator(pr#matN, preffe#prmesh#Thi, preffe#Vhi) + ENDIFMACRO + IFMACRO(pr#withhpddm) + ChangeOperator(pr#hpddmOP,pr#matN); + ENDIFMACRO + IFMACRO(pr#withpetsc) + Mat mat(pr#matN, pr#intersectionhpddm, pr#petscDk, communicator = preffe#prmesh#commddm); + pr#petscOP = mat; + ENDIFMACRO } } diff --git a/idp/ffddm_functions.idp b/idp/ffddm_functions.idp index 3ae84c032..35b711e76 100644 --- a/idp/ffddm_functions.idp +++ b/idp/ffddm_functions.idp @@ -578,9 +578,9 @@ func preffe#K[int] pr#fGMRES(preffe#K[int]& x0, preffe#K[int]& rhs, real eps, in set(pr#hpddmOP, sparams = "-hpddm_"+prefix+"schwarz_coarse_correction deflated", prefix=prefix); if (pr#prec == "oras" || pr#prec == "soras") - DDM(pr#hpddmOP,rhs,uni,O=pr#aR[mpiRank(preffe#prmesh#commddm)],timing=timings); + DDM(pr#hpddmOP,rhs,uni,O=pr#aR[mpiRank(preffe#prmesh#commddm)],communicator=preffe#prmesh#commddm,timing=timings); else - DDM(pr#hpddmOP,rhs,uni,timing=timings); + DDM(pr#hpddmOP,rhs,uni,communicator=preffe#prmesh#commddm,timing=timings); /* real[int] timingsg(timings.n); diff --git a/idp/ffddm_geneoCS_saddlepoint.idp b/idp/ffddm_geneoCS_saddlepoint.idp index a4f17984d..33d60a53b 100644 --- a/idp/ffddm_geneoCS_saddlepoint.idp +++ b/idp/ffddm_geneoCS_saddlepoint.idp @@ -170,3 +170,284 @@ ffddmbuildZTAZ(pr,pr,null) ENDIFMACRO } // EOM + +macro ffddmSPsetup(SP,prA,prBtilde,prCtilde,Ctildei) + +matrix SP#Btildei, SP#localBlocki; + +/* matrix-vector product with local Schur complement */ +func real[int] SP#Simatvec(real[int] &l) { + real[int] t1 = SP#Btildei'*l; + real[int] t2 = prA#aR[mpiRank(prA#prfe#prmesh#commddm)]^-1*t1; + real[int] t3 = SP#Btildei*t2; + real[int] t4 = Ctildei * l; + t3 += t4; + return t3; +} + +/* inverse of local Schur complement through the solution of the augmented sparse local saddle point system */ +func real[int] SP#Sisolve(real[int] &l) { + real[int] bi(prA#prfe#Vhi.ndof + prCtilde#prfe#Vhi.ndof); + bi(prA#prfe#Vhi.ndof:bi.n-1) = -l; + real[int] ui = SP#localBlocki^-1*bi; + return ui(prA#prfe#Vhi.ndof:bi.n-1); +} + +/* distributed matrix-vector product with B from prA#prfe#Vhi to prCtilde#prfe#Vhi */ +func real[int] SP#Bmatvec(real[int] &l) { + real[int] Dltilde(prA#prfe#AugVhi.ndof); + /* go from prA#prfe#Vhi to prA#prfe#AugVhi: */ + if (!prA#prfe#prmesh#excluded) { + real[int] Dl = prA#prfe#Dk[mpiRank(prA#prfe#prmesh#commddm)].*l; /* multiplty by PoU */ + Dltilde = prA#prfe#Auginterp'*Dl; /* extend */ + prA#prfe#Augupdate(Dltilde,false); /* sum */ + } + real[int] res = prBtilde#A(Dltilde); + return res; +} + +/* distributed matrix-vector product with B^T from prCtilde#prfe#Vhi to prA#prfe#Vhi */ +func real[int] SP#BTmatvec(real[int] &l) { + real[int] BTtilde = prBtilde#AT(l); /* B^T */ + real[int] res(prA#prfe#Vhi.ndof); + if (!prA#prfe#prmesh#excluded) res = prA#prfe#Auginterp*BTtilde; /* restrict from prA#prfe#AugVhi to prA#prfe#Vhi */ + return res; +} + +/* matrix-vector product with S_1 defined as custom operator for prefix S1tilde */ +NewMacro SP#S1tildemyA +func real[int] SP#S1tildeA(real[int] &l) +{ + real[int] s(l.n); + s = 0; + + prA#prfe#prmesh#Augtic(SP#S1tildetmvi) + + if (!prA#prfe#prmesh#Augexcluded){ + s = SP#Simatvec(l); + prCtilde#prfe#update(s,false); + prCtilde#prfe#update(s,true); + } + prA#prfe#prmesh#Augtoc(SP#S1tildetmvi,"",SP#S1tildetmv) + + return s; +} +EndMacro + +/* one-level preconditioner M_{S_1,1}^-1 defined as custom preconditioner for prefix S1tilde */ +NewMacro SP#S1tildemyPREC1 +func real[int] SP#S1tildePREC1(real[int] &l) +{ + real[int] s(l.n); + s = 0; + + prA#prfe#prmesh#Augtic(SP#S1tildetpreci) + + if (!prA#prfe#prmesh#Augexcluded){ + real[int] aux = l; + if(SP#S1tildeprec == "soras") + aux = aux .* prCtilde#prfe#Dk[mpiRank(prA#prfe#prmesh#Augcommddm)]; + + s = SP#Sisolve(aux); + + if(SP#S1tildeprec != "asm"){ + prCtilde#prfe#update(s,true); + } + else{ + prCtilde#prfe#update(s,false); + prCtilde#prfe#update(s,true); + } + } + prA#prfe#prmesh#Augtoc(SP#S1tildetpreci,"",SP#S1tildetprec) + + return s; +} +EndMacro + +/* operator (I + M_{S_1}^-1 S_0) for the solution of eq. (25) to apply N_S^-1 + defined as custom operator for prefix NStilde */ +NewMacro SP#NStildemyA +func real[int] SP#NStildeA(real[int] &u) { + prA#prfe#prmesh#Augtic(SP#NStildetmvi) + real[int] res(u.n); + + /* recall that S_0 = B R_0^T (R_0 A R_0^T)^-1 R_0 B^T */ + + real[int] BTu = SP#BTmatvec(u); /* B^T */ + + real[int] R0TA01R0BTu = prA#Q(BTu); /* Q = R_0^T (R_0 A R_0^T)^-1 R_0 */ + + /* extend from prA#prfe#Vhi to prA#prfe#AugVhi : */ + real[int] El(prA#prfe#AugVhi.ndof); + if (!prA#prfe#prmesh#excluded) { + real[int] Dl = prA#prfe#Dk[mpiRank(prA#prfe#prmesh#commddm)].*R0TA01R0BTu; /* multiplty by PoU */ + El = prA#prfe#Auginterp'*Dl; /* extend */ + prA#prfe#Augupdate(El,false); /* sum */ + } + + real[int] BR0TA01R0BTu = prBtilde#A(El); /* B */ + + real[int] MS11 = SP#S1tildePREC(BR0TA01R0BTu); /* M_{S_1}^-1 */ + res = u + MS11; + prA#prfe#prmesh#Augtoc(SP#NStildetmvi,"",SP#NStildetmv) + return res; +} +EndMacro + +/* matrix-vector product with Schur complement S = C + B A^-1 B^T for step 3 of Algorithm 2 + defined as custom operator for prefix SP */ +NewMacro SP#myA +func real[int] SP#A(real[int] &l) +{ + prA#prfe#prmesh#Augtic(SP#tmvi) + real[int] BTl(prA#prfe#Vhi.ndof), s(prA#prfe#Vhi.ndof), x0(prA#prfe#Vhi.ndof); + + BTl = SP#BTmatvec(l); /* B^T */ + + x0 = 0; + s = prA#fGMRES(x0, BTl, gtol, 100, "right"); /* A^-1 */ + + real[int] res = SP#Bmatvec(s); /* B */ + + res += prCtilde#A(l); /* + C */ + + prA#prfe#prmesh#Augtoc(SP#tmvi,"",SP#tmv) + return res; +} +EndMacro + +/* matrix-vector product with N_S^-1 (Algorithm 1, i.e. solve eq. (25)) + defined as custom preconditioner for prefix SP */ +NewMacro SP#myPREC +func real[int] SP#PREC(real[int] &G) { + prA#prfe#prmesh#Augtic(SP#tpreci) + real[int] Gprime(G.n), res(G.n); + + /* solve (I + M_{S_1}^-1 S_0) P = M_{S_1}^-1 G */ + Gprime = SP#S1tildePREC(G); + res = SP#NStildefGMRES(res, Gprime, 1.e-2, 100, "right"); + + prA#prfe#prmesh#Augtoc(SP#tpreci,"",SP#tprec) + return res; +} +EndMacro + +ffddmsetupinit(SP#S1tilde,prCtilde#prfe); /* define Operator for S_1 (S1tildeA with one-level preconditioner S1tildePREC1) */ +SP#S1tildeprec = "soras"; + +ffddmsetupinit(SP#NStilde,prCtilde#prfe); /* define operator for N_S (NStildeA = I + M_{S_1}^-1 S_0, no preconditioner) */ +SP#NStildeprec = "none"; +SP#NStildeverbosity = 1; + +ffddmsetupinit(SP,prCtilde#prfe); /* define Operator for S (SPA = S := C + B A^-1 B^T with preconditioner SPPREC = N_S^-1) */ + +/* build Btildei and localBlocki : */ +prA#prfe#prmesh#Augtic(SP#tfactoi) +if (!prA#prfe#prmesh#excluded) { + SP#Btildei = prBtilde#aRd[mpiRank(prA#prfe#prmesh#commddm)]*prA#prfe#Auginterp'; /* Btilde_i of eq. (9) */ + + matrix mC = -Ctildei; + SP#localBlocki = [[prA#aR[mpiRank(prA#prfe#prmesh#commddm)],0],[SP#Btildei,mC]]; + set(SP#localBlocki,solver=sparsesolver,sym=1,factorize=3,commworld=mpiCommSelf); +} +prA#prfe#prmesh#Augtoc(SP#tfactoi,"",SP#tfacto) + +/* local contribution to lhs sum of eigenvalue problem (18) for Arpack ; + blocking forward-backward substitutions for A_i^{-1} for mu right-hand sides to accelerate computations, + as we will also have input vectors from neighboring subdomains */ +func real[int] SP#Simatvecblock(real[int] &l, int mu) { + real[int] res(l.n); + real[int] buffi(prA#prfe#Vhi.ndof * mu), buffo(prA#prfe#Vhi.ndof * mu); + for (int i=0; i < mu; i++) + buffi(i*prA#prfe#Vhi.ndof:(i+1)*prA#prfe#Vhi.ndof-1) = SP#Btildei'*l(i*prCtilde#prfe#Vhi.ndof:(i+1)*prCtilde#prfe#Vhi.ndof-1); + + buffo = prA#aR[mpiRank(prA#prfe#prmesh#commddm)]^-1*buffi; + + for (int i=0; i < mu; i++) { + real[int] t1 = SP#Btildei*buffo(i*prA#prfe#Vhi.ndof:(i+1)*prA#prfe#Vhi.ndof-1); + /* + real[int] t2 = prCtilde#prfe#Dk[mpiRank(prA#prfe#prmesh#commddm)].*l(i*prCtilde#prfe#Vhi.ndof:(i+1)*prCtilde#prfe#Vhi.ndof-1); + real[int] t3 = CtildeaRd[mpiRank(prA#prfe#prmesh#commddm)]*t2; + res(i*prCtilde#prfe#Vhi.ndof:(i+1)*prCtilde#prfe#Vhi.ndof-1) = t1 + t3; + */ + real[int] t2 = Ctildei*l(i*prCtilde#prfe#Vhi.ndof:(i+1)*prCtilde#prfe#Vhi.ndof-1); + res(i*prCtilde#prfe#Vhi.ndof:(i+1)*prCtilde#prfe#Vhi.ndof-1) = t1 + t2; + + } + return res; +} + +/* build the second level of M_{S_1}^-1 (section 3.2.2) ; + Sisolve corresponds to the inverse of rhs of eigenvalue problem (18) for Arpack ; + Simatvecblock corresponds to the local Schur complement, i.e. the local contribution + to the S_1 sum -- and to the lhs sum of (18) */ +ffddmgeneofullsetup(SP#S1tilde,SP#Sisolve,SP#Simatvecblock); + +SP#S1tildecorr = "BNN"; + +/******************* Block version (prefix 'Block') with preconditioner P eq. (28) *******************/ +NewMacro SP#Blockmyscalprod +func real SP#Blockscalprod(real[int]& va, real[int]& vb) +{ + real resf = prA#prfe#scalprod(va(0:prA#prfe#Vhi.ndof-1),vb(0:prA#prfe#Vhi.ndof-1)); + real resb = prCtilde#prfe#scalprod(va(prA#prfe#Vhi.ndof:va.n-1),vb(prA#prfe#Vhi.ndof:va.n-1)); + return resf+resb; +} +EndMacro + +ffddminitDfespacef(SP#Block, prA#prfe#prmesh#Aug, real, def, init, P1, def, init, P1) + +NewMacro SP#BlockmyA +func real[int] SP#BlockA(real[int] &u) +{ + real[int] res(u.n); + res(0:prA#prfe#Vhi.ndof-1) = prA#A(u(0:prA#prfe#Vhi.ndof-1)); + res(prA#prfe#Vhi.ndof:u.n-1) = -prCtilde#A(u(prA#prfe#Vhi.ndof:u.n-1)); + + real[int] r1 = SP#BTmatvec(u(prA#prfe#Vhi.ndof:u.n-1)); + + res(0:prA#prfe#Vhi.ndof-1) += r1; + + real[int] r2 = SP#Bmatvec(u(0:prA#prfe#Vhi.ndof-1)); + + res(prA#prfe#Vhi.ndof:u.n-1) += r2; + + return res; +} +EndMacro + +NewMacro SP#BlockmyPREC1 +func real[int] SP#BlockPREC1(real[int] &u) +{ + real[int] res(u.n), resb(u.n); + + resb(0:prA#prfe#Vhi.ndof-1) = prA#PREC(u(0:prA#prfe#Vhi.ndof-1)); + + resb(prA#prfe#Vhi.ndof:u.n-1) = -SP#PREC(u(prA#prfe#Vhi.ndof:u.n-1)); + + real[int] r2 = SP#Bmatvec(resb(0:prA#prfe#Vhi.ndof-1)); + + real[int] s2(r2.n); + + s2 = SP#PREC(r2); + + resb(prA#prfe#Vhi.ndof:u.n-1) += s2; + + res(0:prA#prfe#Vhi.ndof-1) = (resb(0:prA#prfe#Vhi.ndof-1)); + res(prA#prfe#Vhi.ndof:u.n-1) = (resb(prA#prfe#Vhi.ndof:u.n-1)); + + real[int] r1 = SP#BTmatvec(resb(prA#prfe#Vhi.ndof:u.n-1)); + + real[int] s1(r1.n); + + s1 = prA#PREC(r1); + + res(0:prA#prfe#Vhi.ndof-1) -= s1; + + return res; +} +EndMacro + +ffddmsetupinit(SP#Block,SP#Block); +SP#Blockprec = "ras"; +// \ No newline at end of file diff --git a/idp/ffddm_parameters.idp b/idp/ffddm_parameters.idp index 096fd957f..efca9f7ed 100644 --- a/idp/ffddm_parameters.idp +++ b/idp/ffddm_parameters.idp @@ -25,6 +25,7 @@ int ffddmexclude = getARGV("-ffddm_master_exclude", 0); int ffddmpCS = getARGV("-ffddm_master_p", 1); int ffddminterfacelabel = 10; +int[int] ffddmcubelabels = [10,10,10,10,10,10]; /* int binexactCS = usedARGV("-inexactCS") > -1 ? 1 : 0; diff --git a/idp/ffddm_partitioning.idp b/idp/ffddm_partitioning.idp index 5ef38e095..64cc46a58 100644 --- a/idp/ffddm_partitioning.idp +++ b/idp/ffddm_partitioning.idp @@ -81,7 +81,18 @@ if (prmesh#isincomm) int[int] labs(6), labsi(6); labs = 0; + for (int ii=0; ii=lx)&&(x<=ux)&&(y>=ly)&&(y<=uy), new2old = n2o, label=9999); diff --git a/idp/macro_ddm.idp b/idp/macro_ddm.idp index 66c1e27e0..9ff3ff2eb 100644 --- a/idp/macro_ddm.idp +++ b/idp/macro_ddm.idp @@ -145,13 +145,9 @@ IFMACRO(!privateCreateMat) AddLayers(globalName, supp[], 2 * overlap, suppSmooth[]); } } - int[int] n2oNeighbor; + int[int] n2oGlobal, n2oNeighbor; IFMACRO(!privateDmesh#CartesianPartitioning) - globalName = trunc(globalName, suppSmooth > 0.001, label = 9999 -IFMACRO(privateDmesh#N2O) - , new2old = n2oNeighbor -ENDIFMACRO - ); + globalName = trunc(globalName, suppSmooth > 0.001, label = 9999, new2old = n2oGlobal); ENDIFMACRO real eps = globalName.measure; real[int] epsTab(intersection[0].n); @@ -195,7 +191,7 @@ ENDIFMACRO IFMACRO(!privateDmesh#CartesianPartitioning) { int[int] backup = privateDmesh#N2O; - int[int] new = n2oNeighbor(privateDmesh#N2O); + int[int] new = n2oGlobal(privateDmesh#N2O); privateDmesh#N2O.resize(new.n); privateDmesh#N2O = new; n2oNeighbor.resize(backup.n); @@ -239,11 +235,28 @@ ENDIFMACRO } } fespace VhLocalPrivate(meshName[level - 1], P1); - VhLocalPrivate[int] partitionIntersection(intersection[0].n); +IFMACRO(!privateDmesh#meshName) +NewMacro privateDmesh#meshName#intersectionDef()partitionIntersectionTab EndMacro + real[int][int] partitionIntersectionTab(1 + intersection[0].n); + privateDmesh#meshName#intersectionDef[0].resize(intersection[0].n); +ENDIFMACRO +IFMACRO(privateBuildDmesh) + privateDmesh#meshName#intersectionDef.resize(1 + intersection[0].n); + privateDmesh#meshName#intersectionDef[0].resize(intersection[0].n); +ENDIFMACRO VhLocalPrivate khi = max(2 * suppSmooth - 1.0, 0.0); - VhLocalPrivate sum = khi; + VhLocalPrivate sum; + sum[] = khi[]; VhGlobalPrivate phi; - part = part; + if(n2oGlobal.n == globalName.nt) { + real[int] restrictionPart(n2oGlobal.n); + restrictionPart = part[](n2oGlobal); + part = 0.0; + part[] = restrictionPart; + } + else + part = part; + n2oGlobal.resize(0); int numberIntersection = 0; { int[int] restriction = restrict(VhLocalPrivate, VhGlobalPrivate, n2oNeighbor); @@ -253,17 +266,20 @@ ENDIFMACRO PhGlobalPrivate suppPartition = abs(part - intersection[0][i]) < 0.1; AddLayers(globalName, suppPartition[], overlap, phi[]); if(min(eps, epsTab[i]) > 0.0) { - if(intN(globalName)(phi) / min(eps, epsTab[i]) > 1.0e-10) { - partitionIntersection[numberIntersection][] = phi[](restriction); + if(intN(globalName, qforder = 2)(phi) / min(eps, epsTab[i]) > 1.0e-10) { + privateDmesh#meshName#intersectionDef[1 + numberIntersection].resize(restriction.n); + privateDmesh#meshName#intersectionDef[1 + numberIntersection] = phi[](restriction); if(!trueRestrict) - sum[] += partitionIntersection[numberIntersection][]; + sum[] += privateDmesh#meshName#intersectionDef[1 + numberIntersection]; intersection[0][numberIntersection++] = intersection[0][i]; } } } } - if(numberIntersection != intersection[0].n) + if(numberIntersection != intersection[0].n) { intersection[0].resize(numberIntersection); + privateDmesh#meshName#intersectionDef.resize(1 + numberIntersection); + } intersection.resize(1 + level * numberIntersection); ENDIFMACRO IFMACRO(privateCreateMat) @@ -272,11 +288,7 @@ IFMACRO(privateCreateMat) intersection.resize(1 + level * numberIntersection); intersection[0].resize(numberIntersection); fespace VhLocalPrivate(meshName[level - 1], P1); - VhLocalPrivate[int] partitionIntersection(numberIntersection); - for(int i = 0; i < numberIntersection; ++i) { - intersection[0][i] = privateDmesh#meshName#intersectionDef[0][i]; - partitionIntersection[i][] = privateDmesh#meshName#intersectionDef[1 + i]; - } + for[i, v : privateDmesh#meshName#intersectionDef[0]] intersection[0][i] = v; IFMACRO(privateDmesh#N2O) IFMACRO(privateDmesh#Original) IFMACRO(privateDmesh#Restriction) @@ -291,19 +303,16 @@ ENDIFMACRO ENDIFMACRO ENDIFMACRO IFMACRO(privateBuildDmesh) - privateDmesh#meshName#intersectionDef.resize(1 + numberIntersection); privateDmesh#meshName#intersectionDef[0].resize(numberIntersection); - for(int i = 0; i < numberIntersection; ++i) { - privateDmesh#meshName#intersectionDef[0][i] = intersection[0][i]; - privateDmesh#meshName#intersectionDef[1 + i].resize(VhLocalPrivate.ndof); - privateDmesh#meshName#intersectionDef[1 + i] = partitionIntersection[i][]; - } + for[i, v : intersection[0]] privateDmesh#meshName#intersectionDef[0][i] = v; ENDIFMACRO meshN[int] meshIntersection(numberIntersection); for(int j = 0; j < (s == 1 ? 1 : level); ++j) { for(int i = 0; i < numberIntersection; ++i) { int[int] n2o; - meshIntersection[i] = trunc(meshName[j], partitionIntersection[i] > 1.0e-6, new2old = n2o, label = 9999); + VhLocalPrivate partitionIntersection; + partitionIntersection[] = privateDmesh#meshName#intersectionDef[1 + i]; + meshIntersection[i] = trunc(meshName[j], partitionIntersection > 1.0e-6, new2old = n2o, label = 9999); IFMACRO(privateDmesh#CartesianPartitioning) real[int] bb(2 * dimension); boundingbox(meshIntersection[i], bb); @@ -336,7 +345,6 @@ IFMACRO(!privateCreateMat) intersection[1 + i + j * numberIntersection].resize(intersection[1 + i].n); intersection[1 + i + j * numberIntersection] = intersection[1 + i]; } - partitionIntersection.resize(0); for(int i = 0; i < (trueRestrict ? level : level - 1); ++i) { fespace VhRefinedPrivate(meshName[i], P1); fespace PhRefinedPrivate(meshName[i], P0); @@ -366,7 +374,7 @@ IFMACRO(!privateCreateMat) khi[] = khiL[]; } if(!trueRestrict) - khi[] = khi[] ./= sum[]; + khi[] ./= sum[]; if(trueRestrict && mpiSize(comm) == size && removeZeros) { assert(level == 1); meshN ThIntersection; @@ -612,6 +620,9 @@ ENDIFMACRO IFMACRO(!ThName#UserPartitioning) IFMACRO(!ThName#Periodicity) IFMACRO(ThName#CartesianPartitioning) +IFMACRO(!dimension) +NewMacro dimension()2 EndMacro +ENDIFMACRO NewMacro privateDmesh#CartesianPartitioning() EndMacro ENDIFMACRO build(ThName, 1, intersection, privateDmesh#ThName#khi[0], P1, ThName#Comm); @@ -651,8 +662,10 @@ ENDIFMACRO mpiAllReduce(tmp, hmax, ThName#Comm, mpiMAX); } int between = 0; - for(int i = 0; i < mpiSize(ThName#Comm); ++i) { - if(i != mpiRank(ThName#Comm) && + int size = mpiSize(ThName#Comm); + int rank = mpiRank(ThName#Comm); + for(int i = 0; i < size; ++i) { + if(i != rank && IFMACRO(dimension,2) !(bbAll[1 + 4 * i] < bb[0] - hmax || bbAll[0 + 4 * i] > bb[1] + hmax @@ -695,68 +708,49 @@ ENDIFMACRO real timerReconstruction = mpiWtime(); varf vG(u, v) = on(labels(ThName), u = 1.0); fespace VhGammaPrivate(ThName, P1); - fespace PhGammaPrivate(ThName, P0); VhGammaPrivate gamma; gamma[] = vG(0, VhGammaPrivate, tgv = -1); - PhGammaPrivate gammaElt = gamma > 0.1; - meshN ThLocalInit = trunc(ThName, gammaElt > 0.1, label = -111112); - meshN ThLocalInitInterior = trunc(ThName, gammaElt < 0.1, label = -111112); + meshN[int] ThTab(neighborsName.n + 2); neighborsName.sort; int between = 0; + int rank = mpiRank(ThName#Comm); for(int i = 0; i < neighborsName.n; ++i) - if(neighborsName[i] > mpiRank(ThName#Comm)) { + if(neighborsName[i] > rank) { between = i; break; } if(neighborsName.n) - if(neighborsName[neighborsName.n - 1] < mpiRank(ThName#Comm)) + if(neighborsName[neighborsName.n - 1] < rank) between = neighborsName.n; - meshN[int] ThTab(neighborsName.n + 1); - ThTab[between] = ThLocalInit; mpiRequest[int] rqRecv(neighborsName.n); + for[i, v : neighborsName] + Irecv(processor(v, ThName#Comm, rqRecv[i]), ThTab[i + (i >= between)]); + ThTab[between] = trunc(ThName, gamma > 0.01, label = -111112); mpiRequest[int] rqSend(neighborsName.n); - for(int i = 0; i < neighborsName.n; ++i) - Isend(processor(neighborsName[i], ThName#Comm, rqSend[i]), ThLocalInit); - for(int i = 0; i < between; ++i) - Irecv(processor(neighborsName[i], ThName#Comm, rqRecv[i]), ThTab[i]); - for(int i = between; i < neighborsName.n; ++i) - Irecv(processor(neighborsName[i], ThName#Comm, rqRecv[i]), ThTab[i + 1]); + for[i, v : neighborsName] + Isend(processor(v, ThName#Comm, rqSend[i]), ThTab[between]); + ThTab[neighborsName.n + 1] = trunc(ThName, gamma < 0.01, label = -111112); mpiWaitAll(rqRecv); - meshN ThLocalNew = gluemesh(ThTab); - int m = 0; - for(int i = 0; i < between; ++i) - m += ThTab[i].nt; - ThTab[between] = trunc(ThLocalNew, nuTriangle >= m && nuTriangle < m + ThTab[between].nt, label = -111111); - mpiWaitAll(rqSend); - for(int i = 0; i < neighborsName.n; ++i) - Isend(processor(neighborsName[i], ThName#Comm, rqSend[i]), ThTab[between]); - for(int i = 0; i < between; ++i) - Irecv(processor(neighborsName[i], ThName#Comm, rqRecv[i]), ThTab[i]); - for(int i = between; i < neighborsName.n; ++i) - Irecv(processor(neighborsName[i], ThName#Comm, rqRecv[i]), ThTab[i + 1]); - mpiWaitAll(rqRecv); - ThTab.resize(neighborsName.n + 2); - ThTab[neighborsName.n + 1] = ThLocalInitInterior; - ThName = gluemesh(ThTab); IFMACRO(dimension,3) + ThName = gluemesh(ThTab); ThName = change(ThName, rmlfaces = -111112); ENDIFMACRO IFMACRO(dimension,2) - ThName = change(ThName, rmledges = -111112); + ThName = gluemesh(ThTab, labtodel = -111112); ENDIFMACRO part.resize(ThName.nt); - m = 0; + int m = 0; for(int i = 0; i < between; ++i) { part(m:m + ThTab[i].nt - 1) = neighborsName[i]; m += ThTab[i].nt; } - part(m:m + ThTab[between].nt - 1) = mpiRank(ThName#Comm); + part(m:m + ThTab[between].nt - 1) = rank; m += ThTab[between].nt; for(int i = between; i < neighborsName.n; ++i) { part(m:m + ThTab[i + 1].nt - 1) = neighborsName[i]; m += ThTab[i + 1].nt; } - part(part.n - ThLocalInitInterior.nt:ThName.nt - 1) = mpiRank(ThName#Comm); + part(m:ThName.nt - 1) = rank; mpiWaitAll(rqSend); if(verbosity > 0) { mpiBarrier(ThName#Comm); @@ -855,6 +849,9 @@ IFMACRO(!ThName#PkPart) ENDIFMACRO IFMACRO(ThName#CartesianPartitioning) NewMacro privateDmesh#CartesianPartitioning() EndMacro +IFMACRO(!dimension) + NewMacro dimension()2 EndMacro +ENDIFMACRO ENDIFMACRO partitionPrivate(ThTab, privateCreateMat, privateCreateMat, privateCreateMat, privateCreateMat, privateCreateMat, mpiRank(ThName#Comm), mpiSize(ThName#Comm), 1, 1, 1, privateCreateMat, DTab, PkName, intersection, ThName#Comm, -111111, ThName#PkPart, def, init, 1) } @@ -1596,6 +1593,7 @@ ENDIFMACRO IFMACRO(!meshN) NewMacro meshN()mesh EndMacro ENDIFMACRO +IFMACRO(!ThName#NestedIn#ThNew) real[int] bb(4 * dimension); { real[int] tmp(2 * dimension); @@ -1679,7 +1677,7 @@ ENDIFMACRO backupRegion = backup[]; int[int] newRegion(ThName.nt); int rank = mpiRank(ThName#Comm); - for[i, v : privateDmesh#ThName#khiDef[1]] newRegion[i] = abs(v - rank) < 1.0e-2 ? 1 : 0; + for[i, v : privateDmesh#ThName#khiDef[1]] newRegion[i] = abs(v - rank) < 1.0e-2; ThName = change(ThName, fregion = newRegion[nuTriangle]); } meshN[int] recvTh(rankRecv.n); @@ -1711,10 +1709,9 @@ ENDIFMACRO int[int] n2o; sendTh[i] = trunc(ThName, part > 1.0e-2, new2old = n2o); fespace VhRestrictionPrivate(sendTh[i], Pk); - int[int] map; - map = restrict(VhRestrictionPrivate, VhLocalOldPrivate, n2o); + int[int] map = restrict(VhRestrictionPrivate, VhLocalOldPrivate, n2o); exchangeU[rankRecv.n + i].resize(VhRestrictionPrivate.ndof); - for[j, w : map] exchangeU[rankRecv.n + i][j] = scaledU[][w]; + exchangeU[rankRecv.n + i] = scaledU[](map); Isend(processor(v, rqSendTh[i]), sendTh[i]); Isend(processor(v, rqSendU[i]), exchangeU[rankRecv.n + i]); } @@ -1761,7 +1758,7 @@ ENDIFMACRO [I, J, C] = R; fespace VhRestrictionPrivate(recvTh[index], Pk); int[int] restriction = restrict(VhRestrictionPrivate, VhExchangePrivate, J); - for[i, v : restriction] uExchange[][v] += exchangeU[index][i]; + uExchange[](restriction) += exchangeU[index]; } } } @@ -1777,6 +1774,22 @@ ENDIFMACRO ThName = change(ThName, fregion = backupRegion[nuTriangle]); mpiWaitAll(rqSendTh); mpiWaitAll(rqSendU); +ENDIFMACRO +IFMACRO(ThName#NestedIn#ThNew) +IFMACRO(!transfer#Q) + def(uANew) = def(uA); + Mat exchange; + createMat(ThNew, exchange, PkNew) + PetscScalar[int] tmp; + ChangeNumbering(exchange, uANew[], tmp); + ChangeNumbering(exchange, uANew[], tmp, inverse = true, exchange = true); +ENDIFMACRO +IFMACRO(transfer#Q) + matrix loc = interpolate(VhLocalNewPrivate, VhLocalOldPrivate); + matrix locPetscScalar = loc; + constructor(P, uANew, uA, locPetscScalar); +ENDIFMACRO +ENDIFMACRO } if(verbosity > 0) { mpiBarrier(ThName#Comm); @@ -1805,7 +1818,7 @@ macro createParMmgCommunicators(ThName, ThParMmgName, ThN2O, ThCommunicators) { IFMACRO(!privateDmesh#ThName) assert(0); ENDIFMACRO - Mat A; + Mat A; createMat(ThName, A, P1); real[int] D(ThName.nt); createPartition(ThName, D, P0); @@ -1831,6 +1844,9 @@ NewMacro ThName#Comm()mpiCommWorld EndMacro ENDIFMACRO IFMACRO(!ThGatherName#Comm) NewMacro ThGatherName#Comm()mpiCommWorld EndMacro +ENDIFMACRO +IFMACRO(!meshN) +NewMacro meshN()mesh EndMacro ENDIFMACRO if(verbosity > 0 && ThName#Comm) mpiBarrier(ThName#Comm); @@ -1880,6 +1896,9 @@ NewMacro ThName#Comm()mpiCommWorld EndMacro ENDIFMACRO IFMACRO(!ThScatterName#Comm) NewMacro ThScatterName#Comm()mpiCommWorld EndMacro +ENDIFMACRO +IFMACRO(!meshN) +NewMacro meshN()mesh EndMacro ENDIFMACRO if(verbosity > 0 && ThScatterName#Comm) mpiBarrier(ThScatterName#Comm); @@ -1938,10 +1957,26 @@ NewMacro ThName#Comm()mpiCommWorld EndMacro ENDIFMACRO IFMACRO(!ThGatherName#Comm) NewMacro ThGatherName#Comm()mpiCommWorld EndMacro +ENDIFMACRO +IFMACRO(!meshN) +NewMacro meshN()mesh EndMacro +ENDIFMACRO +IFMACRO(!intN) +NewMacro intN()int2d EndMacro ENDIFMACRO if(verbosity > 0 && ThName#Comm) mpiBarrier(ThName#Comm); real timerGather = mpiWtime(); +IFMACRO(with,PETSc) + PetscScalar[int] v(u[]); + { + Mat gather; + createMat(ThName, gather, Pk) + PetscScalar[int] trash; + ChangeNumbering(gather, v, trash); + ChangeNumbering(gather, v, trash, inverse = true, exchange = false); + } +ENDIFMACRO if(ThGatherName#Comm) { meshN[int] recvTh(mpiSize(comm) - 1); PetscScalar[int][int] recvU(mpiSize(comm) - 1); @@ -1956,11 +1991,17 @@ ENDIFMACRO Irecv(processor(index + 1, comm, rqRecvU[index]), recvU[index]); } fespace VhGlobalGatherPrivate(ThGatherName, Pk); +IFMACRO(!with) PetscScalar[int] visited(VhGlobalGatherPrivate.ndof); visited = 1.0; +ENDIFMACRO { fespace VhRestrictionPrivate(ThName, Pk); matrix R = interpolate(VhRestrictionPrivate, VhGlobalGatherPrivate); +IFMACRO(with,PETSc) + uNew[] += R' * v; +ENDIFMACRO +IFMACRO(!with) PetscScalar[int] buffer = R' * u[]; buffer .*= visited; PetscScalar[int] ones(VhRestrictionPrivate.ndof); @@ -1968,11 +2009,16 @@ ENDIFMACRO visited += R' * ones; for[j, v : visited] v = max(abs(v), 0.0); uNew[] += buffer; +ENDIFMACRO } for(int i = 0; i < mpiSize(comm) - 1; ++i) { int index = mpiWaitAny(rqRecvU); fespace VhRestrictionPrivate(recvTh[index], Pk); matrix R = interpolate(VhRestrictionPrivate, VhGlobalGatherPrivate); +IFMACRO(with,PETSc) + uNew[] += R' * recvU[index]; +ENDIFMACRO +IFMACRO(!with) PetscScalar[int] buffer = R' * recvU[index]; buffer .*= visited; PetscScalar[int] ones(VhRestrictionPrivate.ndof); @@ -1980,14 +2026,25 @@ ENDIFMACRO visited += R' * ones; for[j, v : visited] v = max(abs(v), 0.0); uNew[] += buffer; +ENDIFMACRO } +IFMACRO(with,PETSc) + Mat gather; + createMat(ThGatherName, gather, Pk) + exchange(gather, uNew[], scaled = false); +ENDIFMACRO } else { mpiRequest[int] rqSend(2); Isend(processor(0, comm, rqSend[0]), ThName); fespace VhLocalGatherPrivate(ThName, Pk); assert(u[].n == VhLocalGatherPrivate.ndof); +IFMACRO(with,PETSc) + Isend(processor(0, comm, rqSend[1]), v); +ENDIFMACRO +IFMACRO(!with) Isend(processor(0, comm, rqSend[1]), u[]); +ENDIFMACRO mpiWaitAll(rqSend); } if(verbosity > 0 && ThName#Comm) { @@ -2012,6 +2069,9 @@ NewMacro ThName#Comm()mpiCommWorld EndMacro ENDIFMACRO IFMACRO(!ThScatterName#Comm) NewMacro ThScatterName#Comm()mpiCommWorld EndMacro +ENDIFMACRO +IFMACRO(!meshN) +NewMacro meshN()mesh EndMacro ENDIFMACRO if(verbosity > 0 && ThScatterName#Comm) mpiBarrier(ThScatterName#Comm); diff --git a/plugin/mpi/PETSc-code.hpp b/plugin/mpi/PETSc-code.hpp index aabc7ca2c..d7606b44f 100644 --- a/plugin/mpi/PETSc-code.hpp +++ b/plugin/mpi/PETSc-code.hpp @@ -334,7 +334,8 @@ namespace PETSc { AssembleBC>(stack, Th, Uh, Vh, ds.sym, A.A, 0, 0, b->largs, ds.tgv); } changeOperatorSimple(&B, &A); - B._A->setMatrix(nullptr); + if(B._A) + B._A->setMatrix(nullptr); } #if defined(WITH_bemtool) && defined(WITH_htool) && defined(PETSC_HAVE_HTOOL) else { @@ -357,34 +358,30 @@ namespace PETSc { KN< typename std::conditional< std::is_same< HpddmType, Dmat >::value, double, long >::type >* ptD) { double timing = MPI_Wtime( ); long long global; - int size; - MPI_Comm_size(ptA->_A->getCommunicator(), &size); - if (ptD || size == 1) { - if (ptD) { - if(!ptA->_D) { - PetscReal* d = reinterpret_cast(ptD->operator double*()); - if(!std::is_same, PetscReal>::value) { - for(int i = 0; i < ptD->n; ++i) - d[i] = ptD->operator[](i); - } - ptA->_A->restriction(d); - if (!C) ptA->_A->initialize(d); - else { - ptA->_D = new KN(ptD->n); + if (ptD) { + if(!ptA->_D) { + PetscReal* d = reinterpret_cast(ptD->operator double*()); + if(!std::is_same, PetscReal>::value) { for(int i = 0; i < ptD->n; ++i) - ptA->_D->operator[](i) = d[i]; - ptA->_A->initialize(*ptA->_D); - } + d[i] = ptD->operator[](i); } + ptA->_A->restriction(d); + if (!C) ptA->_A->initialize(d); else { + ptA->_D = new KN(ptD->n); + for(int i = 0; i < ptD->n; ++i) + ptA->_D->operator[](i) = d[i]; ptA->_A->initialize(*ptA->_D); } } - ptA->_A->distributedNumbering(ptA->_num, ptA->_first, ptA->_last, global); - if (verbosity > 0 && mpirank == 0) - cout << " --- global numbering created (in " << MPI_Wtime( ) - timing << ")" << endl; - } else - global = PETSC_DECIDE; + else { + ptA->_A->initialize(*ptA->_D); + } + } + if (!C && !ptD) global = PETSC_DECIDE; + else ptA->_A->distributedNumbering(ptA->_num, ptA->_first, ptA->_last, global); + if (verbosity > 0 && mpirank == 0) + cout << " --- global numbering created (in " << MPI_Wtime( ) - timing << ")" << endl; timing = MPI_Wtime( ); PetscInt* ia = nullptr; PetscInt* ja = nullptr; @@ -398,15 +395,17 @@ namespace PETSc { bool sym = ptA->_A->getMatrix( )->_sym; if (ia) { if (sym) { - MatSetType(ptA->_petsc, MATMPISBAIJ); + MatSetType(ptA->_petsc, MATSBAIJ); + MatSeqSBAIJSetPreallocationCSR(ptA->_petsc, 1, ia, ja, c); MatMPISBAIJSetPreallocationCSR(ptA->_petsc, 1, ia, ja, c); } else { - MatSetType(ptA->_petsc, MATMPIAIJ); + MatSetType(ptA->_petsc, MATAIJ); + MatSeqAIJSetPreallocationCSR(ptA->_petsc, ia, ja, c); MatMPIAIJSetPreallocationCSR(ptA->_petsc, ia, ja, c); MatSetOption(ptA->_petsc, MAT_SYMMETRIC, symmetric); } } else { - MatSetType(ptA->_petsc, MATMPIAIJ); + MatSetType(ptA->_petsc, MATAIJ); MatSetUp(ptA->_petsc); } if (free) { @@ -486,7 +485,7 @@ namespace PETSc { MatCreateVecs(ptA->_petsc, &rglobal, NULL); Vec isVec; VecCreate(PETSC_COMM_SELF, &isVec); - VecSetType(isVec, VECMPI); + VecSetType(isVec, VECSTANDARD); VecSetSizes(isVec, PETSC_DECIDE, nr); VecScatterCreate(rglobal, from, isVec, to, &ptA->_scatter); VecDestroy(&isVec); @@ -748,10 +747,12 @@ namespace PETSc { PETSC_DECIDE, PETSC_DECIDE); } if (ptA->_A && ptA->_A->getMatrix( )->_sym) { - MatSetType(ptA->_petsc, MATMPISBAIJ); + MatSetType(ptA->_petsc, MATSBAIJ); + MatSeqSBAIJSetPreallocationCSR(ptA->_petsc, 1, ia, ja, c); MatMPISBAIJSetPreallocationCSR(ptA->_petsc, 1, ia, ja, c); } else { - MatSetType(ptA->_petsc, MATMPIAIJ); + MatSetType(ptA->_petsc, MATAIJ); + MatSeqAIJSetPreallocationCSR(ptA->_petsc, ia, ja, c); MatMPIAIJSetPreallocationCSR(ptA->_petsc, ia, ja, c); } } @@ -764,6 +765,7 @@ namespace PETSc { PetscInt m; MatGetLocalSize(ptA->_petsc, &m, NULL); PetscInt* ia = new PetscInt[m + 1]( ); + MatSeqAIJSetPreallocationCSR(ptA->_petsc, ia, NULL, NULL); MatMPIAIJSetPreallocationCSR(ptA->_petsc, ia, NULL, NULL); delete[] ia; } @@ -848,13 +850,17 @@ namespace PETSc { if (ptB->_petsc) { PetscBool assembled; MatAssembled(ptB->_petsc, &assembled); - if (assembled) MatConvert(ptB->_petsc, MATSAME, MAT_INITIAL_MATRIX, &ptA->_petsc); +#if PETSC_VERSION_GE(3, 17, 0) + MatDuplicate(ptB->_petsc, assembled ? MAT_COPY_VALUES : MAT_DO_NOT_COPY_VALUES, &ptA->_petsc); +#else + if (assembled) MatDuplicate(ptB->_petsc, MAT_COPY_VALUES, &ptA->_petsc); + else ffassert(0); +#endif MatDestroy(&ptB->_petsc); } - } else { + } else MatHeaderReplace(ptA->_petsc, &ptB->_petsc); - } - if (ptB->_ksp) KSPDestroy(&ptB->_ksp); + KSPDestroy(&ptB->_ksp); ptA->_A = ptB->_A; ptB->_A = nullptr; ptA->_num = ptB->_num; @@ -1015,6 +1021,12 @@ namespace PETSc { if(mat) return 1L; } + else if (o.compare("MATSOLVER") == 0) { + PetscBool foundtype; + MatSolverTypeGet(t.c_str(), MATAIJ, MAT_FACTOR_LU, &foundtype, NULL, NULL); + if(foundtype) + return 1L; + } } return 0L; } @@ -1205,14 +1217,20 @@ namespace PETSc { } bool clean = nargs[3] && GetAny< bool >((*nargs[3])(stack)); if (clean) ptSize->resize(0); - MatSetType(ptA->_petsc, bsr ? MATMPIBAIJ : MATMPIAIJ); + MatSetType(ptA->_petsc, bsr ? MATBAIJ : MATAIJ); mK->CSR( ); - if (bsr) + if (bsr) { + MatSeqBAIJSetPreallocationCSR(ptA->_petsc, bs, reinterpret_cast< PetscInt* >(mK->p), + reinterpret_cast< PetscInt* >(mK->j), mK->aij); MatMPIBAIJSetPreallocationCSR(ptA->_petsc, bs, reinterpret_cast< PetscInt* >(mK->p), reinterpret_cast< PetscInt* >(mK->j), mK->aij); - else + } + else { + MatSeqAIJSetPreallocationCSR(ptA->_petsc, reinterpret_cast< PetscInt* >(mK->p), + reinterpret_cast< PetscInt* >(mK->j), mK->aij); MatMPIAIJSetPreallocationCSR(ptA->_petsc, reinterpret_cast< PetscInt* >(mK->p), reinterpret_cast< PetscInt* >(mK->j), mK->aij); + } if (prune) { ffassert(0); } @@ -1366,7 +1384,8 @@ namespace PETSc { } ptK->resize(0); } - MatSetType(ptA->_petsc, MATMPIAIJ); + MatSetType(ptA->_petsc, MATAIJ); + MatSeqAIJSetPreallocationCSR(ptA->_petsc, ia, ja, c); MatMPIAIJSetPreallocationCSR(ptA->_petsc, ia, ja, c); MatSetOption( ptA->_petsc, MAT_SYMMETRIC, @@ -1399,7 +1418,7 @@ namespace PETSc { E_initCSR(const basicAC_F0& args, int d) : A(0), K(0), R(0), D(0), c(d) { args.SetNameParam(n_name_param, name_param, nargs); A = to< DistributedCSR< HpddmType >* >(args[0]); - if (c == 1 || c == 3) + if (c == 1 || c == 3 || c == 4) K = to< long >(args[1]); else K = to< Matrice_Creuse< HPDDM::upscaled_type >* >(args[1]); @@ -1409,6 +1428,8 @@ namespace PETSc { std::is_same< HpddmType, HpSchwarz< PetscScalar > >::value, double, long >::type >* >( args[3]); } + else if (c == 4) + R = to< long >(args[2]); } AnyType operator( )(Stack stack) const; @@ -1440,6 +1461,10 @@ namespace PETSc { : OneOperator(atype< DistributedCSR< HpddmType >* >( ), atype< DistributedCSR< HpddmType >* >( ), atype< long >( )), c(3) {} + initCSR(int, int, int, int) + : OneOperator(atype< DistributedCSR< HpddmType >* >( ), + atype< DistributedCSR< HpddmType >* >( ), atype< long >( ), atype< long >( )), + c(4) {} }; template< class HpddmType, bool C > basicAC_F0::name_and_type initCSR< HpddmType, C >::E_initCSR::name_param[] = { @@ -1469,38 +1494,57 @@ namespace PETSc { else dof = GetAny< long >((*K)(stack)); MPI_Comm* comm = nargs[0] ? (MPI_Comm*)GetAny< pcommworld >((*nargs[0])(stack)) : 0; - if(c == 2 || c == 3) { - static MPI_Comm self = MPI_COMM_SELF; - MPI_Comm& rval = self; - comm = &rval; - } - if (c == 2 && mA->n != mA->m) { + if ((c == 2 && mA->n != mA->m) || c == 4) { ptA->_first = 0; - ptA->_last = mA->n; ptA->_cfirst = 0; - ptA->_clast = mA->m; - MatCreate(*comm, &ptA->_petsc); - MatSetSizes(ptA->_petsc, mA->n, mA->m, PETSC_DECIDE, PETSC_DECIDE); - MatSetType(ptA->_petsc, MATMPIAIJ); - ff_HPDDM_MatrixCSR< PetscScalar > dA(mA); - ptA->_num = new PetscInt[mA->n + mA->m]; - ptA->_cnum = ptA->_num + mA->n; - std::iota(ptA->_num, ptA->_num + mA->n, 0); - std::iota(ptA->_cnum, ptA->_cnum + mA->m, 0); + if (c != 4) { + ptA->_last = mA->n; + ptA->_clast = mA->m; + } + else { + ptA->_last = dof; + ptA->_clast = GetAny< long >((*R)(stack)); + } + MatCreate(comm ? *comm : PETSC_COMM_WORLD, &ptA->_petsc); + MatSetSizes(ptA->_petsc, ptA->_last, ptA->_clast, PETSC_DECIDE, PETSC_DECIDE); + MatSetType(ptA->_petsc, MATAIJ); + MatSetUp(ptA->_petsc); + ptA->_num = new PetscInt[ptA->_last + ptA->_clast]; + ptA->_cnum = ptA->_num + ptA->_last; + PetscInt rbegin, cbegin; + MatGetOwnershipRange(ptA->_petsc, &rbegin, NULL); + MatGetOwnershipRangeColumn(ptA->_petsc, &cbegin, NULL); + std::iota(ptA->_num, ptA->_cnum, rbegin); + std::iota(ptA->_cnum, ptA->_cnum + ptA->_clast, cbegin); + ptA->_first += rbegin; + ptA->_last += rbegin; + ptA->_cfirst += cbegin; + ptA->_clast += cbegin; + if (c != 4) { + ff_HPDDM_MatrixCSR< PetscScalar > dA(mA); + if(cbegin) + for(int i = 0; i < dA._nnz; ++i) + dA._ja[i] += cbegin; #if defined(PETSC_USE_64BIT_INDICES) - PetscInt* ia = new PetscInt[dA._n + 1]; - std::copy_n(dA._ia, dA._n + 1, ia); - PetscInt* ja = new PetscInt[dA._nnz]; - std::copy_n(dA._ja, dA._nnz, ja); - PetscScalar* c = new PetscScalar[dA._nnz]; - std::copy_n(dA._a, dA._nnz, c); - MatMPIAIJSetPreallocationCSR(ptA->_petsc, ia, ja, c); - delete[] c; - delete[] ja; - delete[] ia; + PetscInt* ia = new PetscInt[dA._n + 1]; + std::copy_n(dA._ia, dA._n + 1, ia); + PetscInt* ja = new PetscInt[dA._nnz]; + std::copy_n(dA._ja, dA._nnz, ja); + PetscScalar* c = new PetscScalar[dA._nnz]; + std::copy_n(dA._a, dA._nnz, c); + MatSeqAIJSetPreallocationCSR(ptA->_petsc, ia, ja, c); + MatMPIAIJSetPreallocationCSR(ptA->_petsc, ia, ja, c); + delete[] c; + delete[] ja; + delete[] ia; #else - MatMPIAIJSetPreallocationCSR(ptA->_petsc, dA._ia, dA._ja, dA._a); + MatSeqAIJSetPreallocationCSR(ptA->_petsc, dA._ia, dA._ja, dA._a); + MatMPIAIJSetPreallocationCSR(ptA->_petsc, dA._ia, dA._ja, dA._a); #endif + if(cbegin) + for(int i = 0; i < dA._nnz; ++i) + dA._ja[i] -= cbegin; + } } else { ptA->_A = new HpddmType; @@ -1547,6 +1591,10 @@ namespace PETSc { comm, dL); delete dL; ptA->_num = new PetscInt[ptA->_A->getMatrix( )->_n]; + if (!C && (c == 2 || c == 3)) { + long long global; + ptA->_A->distributedNumbering(ptA->_num, ptA->_first, ptA->_last, global); + } initPETScStructure(ptA, bs, nargs[3] && GetAny< bool >((*nargs[3])(stack)) ? PETSC_TRUE : PETSC_FALSE, empty ? empty : ptD); delete empty; @@ -1679,10 +1727,9 @@ namespace PETSc { PetscScalar r = GetAny< PetscScalar >(e_ij); if (std::abs(r) > 1.0e-16) { Mat B; - MatCreate(PETSC_COMM_WORLD, &B); - MatSetSizes(B, PETSC_DECIDE, PETSC_DECIDE, 1, 1); - MatSetType(B, MATMPIDENSE); - MatMPIDenseSetPreallocation(B, PETSC_NULL); + MatCreateDense(PETSC_COMM_WORLD, PETSC_DECIDE, PETSC_DECIDE, 1, 1, NULL, &B); + MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY); + MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY); PetscScalar* array; MatDenseGetArray(B, &array); if (array) array[0] = r; @@ -1696,12 +1743,11 @@ namespace PETSc { } else if (t == 3 || t == 4) { KN< PetscScalar > x; Mat B; - MatCreate(PETSC_COMM_WORLD, &B); if (t == 3) x = GetAny< KN_< PetscScalar > >(e_ij); else x = GetAny< Transpose< KN_< PetscScalar > > >(e_ij); - MatSetSizes(B, x.n, PETSC_DECIDE, PETSC_DECIDE, 1); - MatSetType(B, MATMPIDENSE); - MatMPIDenseSetPreallocation(B, PETSC_NULL); + MatCreateDense(PETSC_COMM_WORLD, x.n, PETSC_DECIDE, PETSC_DECIDE, 1, NULL, &B); + MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY); + MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY); PetscScalar* array; MatDenseGetArray(B, &array); if (array) std::copy_n(static_cast< PetscScalar* >(x), x.n, array); @@ -1765,7 +1811,8 @@ namespace PETSc { } MatCreate(PETSC_COMM_WORLD, a + zeros[i] * M + zeros[i]); MatSetSizes(a[zeros[i] * M + zeros[i]], x, y, X, Y); - MatSetType(a[zeros[i] * M + zeros[i]], MATMPIAIJ); + MatSetType(a[zeros[i] * M + zeros[i]], MATAIJ); + MatSeqAIJSetPreallocation(a[zeros[i] * M + zeros[i]], 0, NULL); MatMPIAIJSetPreallocation(a[zeros[i] * M + zeros[i]], 0, NULL, 0, NULL); MatAssemblyBegin(a[zeros[i] * M + zeros[i]], MAT_FINAL_ASSEMBLY); MatAssemblyEnd(a[zeros[i] * M + zeros[i]], MAT_FINAL_ASSEMBLY); @@ -1800,7 +1847,7 @@ namespace PETSc { Expression A; Expression P; const int c; - static const int n_name_param = 19; + static const int n_name_param = 20; static basicAC_F0::name_and_type name_param[]; Expression nargs[n_name_param]; setOptions_Op(const basicAC_F0& args, int d) : A(0), P(0), c(d) { @@ -1852,7 +1899,8 @@ namespace PETSc { {"O", &typeid(Matrice_Creuse< HPDDM::upscaled_type >*)}, // 15 {"bs", &typeid(long)}, // 16 {"precon", &typeid(Polymorphic*)}, // 17 - {"setup", &typeid(bool)} // 18 + {"setup", &typeid(bool)}, // 18 + {"monitor", &typeid(Polymorphic*)} // 19 }; class ShellInjection; template< class Type > @@ -2062,6 +2110,12 @@ namespace PETSc { ierr = PetscFree(user);CHKERRQ(ierr); PetscFunctionReturn(0); } + template< class Type > + static PetscErrorCode MonitorDestroy(void** ctx) { + PetscFunctionBeginUser; + delete reinterpret_cast< typename LinearSolver< Type >::MonF_O* >(*ctx); + PetscFunctionReturn(0); + } struct WrapperSubKSP { IS is; KSP *ksp; @@ -2094,6 +2148,14 @@ namespace PETSc { template< class, class Container, char N = 'N' > static PetscErrorCode Op_User(Container, Vec, Vec); template< class Type > + PetscErrorCode Monitor(KSP ksp, PetscInt it, PetscReal rnorm, void* ctx) { + PetscFunctionBeginUser; + typename LinearSolver< Type >::MonF_O* mat = + reinterpret_cast< typename LinearSolver< Type >::MonF_O* >(ctx); + mat->apply(it, rnorm); + PetscFunctionReturn(0); + } + template< class Type > AnyType setOptions< Type >::setOptions_Op::operator( )(Stack stack) const { Type *ptA, *ptParent; KN< Dmat >* tabA; @@ -2169,9 +2231,7 @@ namespace PETSc { MatDestroy(&ptA->_petsc); MatPermute(A, wrapper->is, wrapper->is, &ptA->_petsc); if(convert) - MatConvert(ptA->_petsc, MATMPISBAIJ, MAT_INPLACE_MATRIX, &ptA->_petsc); - else - MatConvert(ptA->_petsc, MATMPIAIJ, MAT_INPLACE_MATRIX, &ptA->_petsc); + MatConvert(ptA->_petsc, MATSBAIJ, MAT_INPLACE_MATRIX, &ptA->_petsc); } } } @@ -2500,12 +2560,22 @@ namespace PETSc { if (std::is_same< Type, Dmat >::value && ptA->_petsc && nargs[17]) { PC pc; KSPGetPC(ksp, &pc); + PetscBool isType; + PetscObjectTypeCompare((PetscObject)pc, PCSHELL, &isType); + User< LinearSolver< Type > > userPC = nullptr; + if(isType) { + PCShellGetContext(pc, &userPC); + if(userPC) + delete userPC->op; + } + else { + PCSetType(pc, PCSHELL); + } + if(!userPC) + PetscNew(&userPC); const Polymorphic* op = dynamic_cast< const Polymorphic* >(nargs[17]); ffassert(op); const OneOperator* codeA = op->Find("(", ArrayOfaType(atype< KN< PetscScalar >* >( ), false)); - PCSetType(pc, PCSHELL); - User< LinearSolver< Type > > userPC = nullptr; - PetscNew(&userPC); PetscInt n; MatGetLocalSize(ptA->_petsc, &n, NULL); userPC->op = new typename LinearSolver< Type >::MatF_O(n, stack, codeA); @@ -2513,6 +2583,14 @@ namespace PETSc { PCShellSetApply(pc, Op_User< LinearSolver< Type >, PC >); PCShellSetDestroy(pc, PCShellDestroy< LinearSolver< Dmat > >); } + const Polymorphic* op = nargs[19] ? dynamic_cast< const Polymorphic* >(nargs[19]) : nullptr; + if (op) { + ffassert(op); + const OneOperator* codeM = op->Find( + "(", ArrayOfaType(atype< long >( ), atype< double >( ), false)); + typename LinearSolver< Type >::MonF_O* mon = new typename LinearSolver< Type >::MonF_O(stack, codeM); + KSPMonitorSet(ksp, Monitor< LinearSolver< Type > >, mon, MonitorDestroy< Type >); + } } } if(nargs[18] && GetAny< bool >((*nargs[18])(stack))) @@ -2762,6 +2840,7 @@ namespace PETSc { Type* ptA = GetAny< Type* >((*(E[j].first))(stack)); if (ptA && (ptA->_last - ptA->_first || (inverse && ptA->_num))) { PetscInt m; + ffassert(ptA->_petsc); MatGetLocalSize(ptA->_petsc, &m, NULL); Storage< PetscScalar >* ptIn = GetAny< Storage< PetscScalar >* >((*(E[j].second))(stack)); if (!inverse) ffassert(ptIn->N() == ptA->_A->getDof()); @@ -2853,45 +2932,22 @@ namespace PETSc { template< char P, class Type, class Storage, typename std::enable_if< std::is_same< Storage, KNM< PetscScalar > >::value >::type* = nullptr > long MatMatMult(Type* const& A, Storage* const& in, Storage* const& out) { if (A->_petsc) { - Mat C; - MatType type; - MatGetType(A->_petsc, &type); - PetscBool isType; - PetscStrcmp(type, MATMPIAIJ, &isType); - int size; - MPI_Comm_size(PetscObjectComm((PetscObject)A->_petsc), &size); - if (size == 1 && isType) - MatMPIAIJGetLocalMat(A->_petsc, MAT_INITIAL_MATRIX, &C); - else - C = A->_petsc; Mat x, y; PetscInt n, m, N, M; MatGetLocalSize(A->_petsc, &n, &m); MatGetSize(A->_petsc, &N, &M); - MatCreate(PetscObjectComm((PetscObject)A->_petsc), &x); - MatSetSizes(x, P == 'T' || P == 'H' ? n : m, PETSC_DECIDE, - P == 'T' || P == 'H' ? N : M, in->M( )); - MatSetType(x, MATDENSE); - { - int size; - MPI_Comm_size(PetscObjectComm((PetscObject)A->_petsc), &size); - if (size == 1) - MatSeqDenseSetPreallocation(x, &(in->operator( )(0, 0))); - else - MatMPIDenseSetPreallocation(x, &(in->operator( )(0, 0))); - } - MatAssemblyBegin(x, MAT_FINAL_ASSEMBLY); - MatAssemblyEnd(x, MAT_FINAL_ASSEMBLY); + MatCreateDense(PetscObjectComm((PetscObject)A->_petsc), P == 'T' || P == 'H' ? n : m, PETSC_DECIDE, + P == 'T' || P == 'H' ? N : M, in->M( ), &(in->operator( )(0, 0)), &x); if (P == 'T' || P == 'H') { ffassert(in->N( ) == n); out->resize(m, in->M( )); if (P == 'T') - MatTransposeMatMult(C, x, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &y); + MatTransposeMatMult(A->_petsc, x, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &y); else { Mat w; MatDuplicate(x, MAT_COPY_VALUES, &w); MatConjugate(w); - MatTransposeMatMult(C, w, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &y); + MatTransposeMatMult(A->_petsc, w, MAT_INITIAL_MATRIX, PETSC_DEFAULT, &y); MatDestroy(&w); MatConjugate(y); } @@ -2902,23 +2958,12 @@ namespace PETSc { } else { ffassert(in->N( ) == m); out->resize(n, in->M( )); - MatCreate(PetscObjectComm((PetscObject)A->_petsc), &y); - MatSetSizes(y, P == 'T' || P == 'H' ? m : n, PETSC_DECIDE, - P == 'T' || P == 'H' ? M : N, in->M( )); - MatSetType(y, MATDENSE); - int size; - MPI_Comm_size(PetscObjectComm((PetscObject)A->_petsc), &size); - if (size == 1) - MatSeqDenseSetPreallocation(y, &(out->operator( )(0, 0))); - else - MatMPIDenseSetPreallocation(y, &(out->operator( )(0, 0))); - MatAssemblyBegin(y, MAT_FINAL_ASSEMBLY); - MatAssemblyEnd(y, MAT_FINAL_ASSEMBLY); - MatMatMult(C, x, MAT_REUSE_MATRIX, PETSC_DEFAULT, &y); + MatCreateDense(PetscObjectComm((PetscObject)A->_petsc), P == 'T' || P == 'H' ? m : n, PETSC_DECIDE, + P == 'T' || P == 'H' ? M : N, in->M( ), &(out->operator( )(0, 0)), &y); + MatMatMult(A->_petsc, x, MAT_REUSE_MATRIX, PETSC_DEFAULT, &y); } MatDestroy(&y); MatDestroy(&x); - if (C != A->_petsc) MatDestroy(&C); } return 0L; } @@ -2979,7 +3024,7 @@ namespace PETSc { } } } - MatConvert(A, MATMPIAIJ, MAT_INITIAL_MATRIX, B); + MatConvert(A, MATAIJ, MAT_INITIAL_MATRIX, B); for (std::pair< std::pair< PetscInt, PetscInt >, Mat > p : b) { Mat C; if (std::is_same< PetscScalar, PetscReal >::value) @@ -3011,7 +3056,7 @@ namespace PETSc { } #endif if (!isType) { - MatConvert(A->_petsc, MATMPIAIJ, MAT_INITIAL_MATRIX, &B->_petsc); + MatConvert(A->_petsc, MATAIJ, MAT_INITIAL_MATRIX, &B->_petsc); } } } @@ -3098,6 +3143,34 @@ namespace PETSc { WhereStackOfPtr2Free(stack)->clean( ); } }; + class MonF_O { + public: + Stack stack; + mutable long s; + C_F0 c_s; + mutable double t; + C_F0 c_t; + Expression mat; + MonF_O(Stack stk, const OneOperator* op) + : stack(stk), s(0), c_s(CPValue(s)), t(0), c_t(CPValue(t)), + mat(op ? CastTo< long >(C_F0(op->code(basicAC_F0_wa({c_s, c_t})), (aType)*op)) : 0) { + } + ~MonF_O( ) { + delete mat; + Expression zzz = c_s; + delete zzz; + zzz = c_t; + delete zzz; + } + long apply(const long& ss, const double& tt) const { + s = ss; + t = tt; + ffassert(mat); + long ret = GetAny< long >((*mat)(stack)); + WhereStackOfPtr2Free(stack)->clean( ); + return ret; + } + }; const int c; class E_LinearSolver : public E_F0mps { public: @@ -3214,7 +3287,7 @@ namespace PETSc { PetscObjectTypeCompareAny((PetscObject)X->_petsc, &isDense, MATMPIDENSE, MATSEQDENSE, ""); Mat XD; if (!isDense) { - MatConvert(X->_petsc, MATMPIDENSE, MAT_INITIAL_MATRIX, &XD); + MatConvert(X->_petsc, MATDENSE, MAT_INITIAL_MATRIX, &XD); } else XD = X->_petsc; if (!Y->_petsc) MatDuplicate(XD, MAT_DO_NOT_COPY_VALUES, &Y->_petsc); KSPMatSolve(ptA->_ksp, XD, Y->_petsc); @@ -3301,19 +3374,6 @@ namespace PETSc { Mat B, C; MatCreateDense(PetscObjectComm((PetscObject)ptA->_ksp), in->N( ), PETSC_DECIDE, M, in->M(), &in->operator( )(0, 0), &B); MatCreateDense(PetscObjectComm((PetscObject)ptA->_ksp), out->N( ), PETSC_DECIDE, M, out->M(), &out->operator( )(0, 0), &C); - int size; - MPI_Comm_size(PetscObjectComm((PetscObject)ptA->_ksp), &size); - if(size == 1) { - MatType type; - MatGetType(ptA->_petsc, &type); - PetscStrcmp(type, MATMPIAIJ, &isType); - if(isType) { - Mat Ad, Ac; - MatMPIAIJGetSeqAIJ(ptA->_petsc, &Ad, NULL, NULL); - MatConvert(Ad, MATSAME, MAT_INITIAL_MATRIX, &Ac); - MatHeaderReplace(ptA->_petsc, &Ac); - } - } #if PETSC_VERSION_GE(3, 14, 0) KSPMatSolve(ptA->_ksp, B, C); #else @@ -3456,7 +3516,7 @@ namespace PETSc { MatCreate(PetscObjectComm((PetscObject)ptB->_petsc), &ptA->_petsc); if (bsB == bsC && bsB > 1) MatSetBlockSize(ptA->_petsc, bsB); MatSetSizes(ptA->_petsc, ptB->_last - ptB->_first, ptC->_last - ptC->_first, PETSC_DECIDE, PETSC_DECIDE); - MatSetType(ptA->_petsc, MATMPIAIJ); + MatSetType(ptA->_petsc, MATAIJ); if (c == 0 || c == 3) { PetscInt* ia = nullptr; PetscInt* ja = nullptr; @@ -3483,6 +3543,7 @@ namespace PETSc { } } else ia = new PetscInt[ptB->_last - ptB->_first + 1]( ); + MatSeqAIJSetPreallocationCSR(ptA->_petsc, ia, ja, a); MatMPIAIJSetPreallocationCSR(ptA->_petsc, ia, ja, a); if (free) { delete[] ia; @@ -4132,10 +4193,19 @@ namespace PETSc { user->r = new typename LinearSolver< Type >::MatF_O(in->n, stack, codeR); Tao tao; TaoCreate(PETSC_COMM_WORLD, &tao); +#if PETSC_VERSION_GE(3, 17, 0) + TaoSetObjective(tao, FormObjectiveRoutine< TaoSolver< Type > >, &user); + TaoSetGradient(tao, NULL, FormFunction< Tao, TaoSolver< Type > >, &user); +#else TaoSetObjectiveRoutine(tao, FormObjectiveRoutine< TaoSolver< Type > >, &user); TaoSetGradientRoutine(tao, FormFunction< Tao, TaoSolver< Type > >, &user); +#endif if (setXl || setXu) TaoSetVariableBounds(tao, xl, xu); +#if PETSC_VERSION_GE(3, 17, 0) + TaoSetSolution(tao, x); +#else TaoSetInitialVector(tao, x); +#endif PetscInt sizeE, sizeI; Vec ce = nullptr, ci = nullptr; const Polymorphic* op = nargs[5] ? dynamic_cast< const Polymorphic* >(nargs[5]) : nullptr; @@ -4186,25 +4256,45 @@ namespace PETSc { const OneOperator* codeH = op->Find( "(", ArrayOfaType(atype< Kn* >( ), atype< Kn* >( ), atype< Kn* >( ), false)); user->op = new NonlinearSolver< Type >::VecF_O(in->n, stack, codeH, 2, sizeI, sizeE); +#if PETSC_VERSION_GE(3, 17, 0) + TaoSetHessian(tao, ptA->_petsc, ptA->_petsc, + FormJacobianTao< TaoSolver< Type >, 5 >, &user); +#else TaoSetHessianRoutine(tao, ptA->_petsc, ptA->_petsc, FormJacobianTao< TaoSolver< Type >, 5 >, &user); +#endif } else if (user->icJ) { const OneOperator* codeH = op->Find("(", ArrayOfaType(atype< Kn* >( ), atype< Kn* >( ), false)); user->op = new NonlinearSolver< Type >::VecF_O(in->n, stack, codeH, 2, sizeI, -1); +#if PETSC_VERSION_GE(3, 17, 0) + TaoSetHessian(tao, ptA->_petsc, ptA->_petsc, + FormJacobianTao< TaoSolver< Type >, 3 >, &user); +#else TaoSetHessianRoutine(tao, ptA->_petsc, ptA->_petsc, FormJacobianTao< TaoSolver< Type >, 3 >, &user); +#endif } else if (user->ecJ) { const OneOperator* codeH = op->Find("(", ArrayOfaType(atype< Kn* >( ), atype< Kn* >( ), false)); user->op = new NonlinearSolver< Type >::VecF_O(in->n, stack, codeH, 2, -1, sizeE); +#if PETSC_VERSION_GE(3, 17, 0) + TaoSetHessian(tao, ptA->_petsc, ptA->_petsc, + FormJacobianTao< TaoSolver< Type >, 4 >, &user); +#else TaoSetHessianRoutine(tao, ptA->_petsc, ptA->_petsc, FormJacobianTao< TaoSolver< Type >, 4 >, &user); +#endif } else { const OneOperator* codeH = op->Find("(", ArrayOfaType(atype< Kn* >( ), false)); user->op = new NonlinearSolver< Type >::VecF_O(in->n, stack, codeH); +#if PETSC_VERSION_GE(3, 17, 0) + TaoSetHessian(tao, ptA->_petsc, ptA->_petsc, + FormJacobianTao< TaoSolver< Type >, 2 >, &user); +#else TaoSetHessianRoutine(tao, ptA->_petsc, ptA->_petsc, FormJacobianTao< TaoSolver< Type >, 2 >, &user); +#endif } } TaoSetFromOptions(tao); @@ -4379,7 +4469,7 @@ namespace PETSc { for(PetscInt j = 0; j < N; ++j) { if(mat[i][j]) { MatGetType(mat[i][j], &type); - PetscStrcmp(type, MATMPIDENSE, &isType); + PetscObjectTypeCompareAny((PetscObject)mat[i][j], &isType, MATMPIDENSE, MATSEQDENSE, ""); PetscInt n = 0, m = 0; if(!isType) { PetscStrcmp(type, MATTRANSPOSEMAT, &isType); @@ -4387,8 +4477,7 @@ namespace PETSc { Mat C; if (std::is_same< PetscScalar, PetscReal >::value) MatTransposeGetMat(mat[i][j], &C); else MatHermitianTransposeGetMat(mat[i][j], &C); - MatGetType(C, &type); - PetscStrcmp(type, MATMPIDENSE, &isType); + PetscObjectTypeCompareAny((PetscObject)C, &isType, MATMPIDENSE, MATSEQDENSE, ""); if(isType) MatGetSize(C, &m, &n); type = MATTRANSPOSEMAT; } @@ -4609,6 +4698,15 @@ namespace PETSc { ffassert((std::is_same>::value)); loopDistributedVec<0, N>(t->_petsc, t->_exchange, u, ptr); } else { + if(t->_A) + assert(u->n == t->_A->getDof() && out->n == t->_A->getDof()); + else if (t->_exchange) { + if (N == 'T') { + assert(u->n == t->_exchange[0]->getDof() && out->n == t->_exchange[1]->getDof()); + } else { + assert(u->n == t->_exchange[1]->getDof() && out->n == t->_exchange[0]->getDof()); + } + } for(int i = 0; i < u->n; ++i) p[i] = u->operator[](i); if (!t->_cnum || N == 'T') { @@ -4665,10 +4763,16 @@ namespace PETSc { return Ax; } static U init(U Ax, ProdPETSc< T, U, K, N > A) { - PetscInt n, m; - MatGetSize(A.t->_petsc, &n, &m); - ffassert(n == m); - Ax->init(A.u->n); + if (A.t->_A) + Ax->init(A.u->n); + else { + if (A.t->_exchange) { + if (N == 'T') + Ax->init(A.t->_exchange[1]->getDof()); + else + Ax->init(A.t->_exchange[0]->getDof()); + } + } return mv(Ax, A); } }; @@ -4844,7 +4948,11 @@ namespace PETSc { MPI_Comm comm = nargs[0] ? *static_cast< MPI_Comm* >(GetAny< pcommworld >((*nargs[0])(stack))) : PETSC_COMM_WORLD; int size; MPI_Comm_size(comm, &size); +#if PETSC_VERSION_GE(3, 17, 0) + DMPlexCreateFromFile(comm, pB->c_str(), NULL, PETSC_TRUE, &pA->_dm); +#else DMPlexCreateFromFile(comm, pB->c_str(), overlap > 0 || size == 1 ? PETSC_TRUE : PETSC_FALSE, &pA->_dm); +#endif if(prefix) DMSetOptionsPrefix(pA->_dm, prefix->c_str()); DMSetFromOptions(pA->_dm); @@ -5085,7 +5193,10 @@ namespace PETSc { PetscInt *closure = NULL; PetscInt closureSize, cl; DMPlexGetTransitiveClosure(p->_dm, c, PETSC_TRUE, &closureSize, &closure); - int iv[4], lab = 0; + int iv[4]; + PetscInt lab; + DMGetLabelValue(p->_dm, "Cell Sets", c, &lab); + if (lab == -1) lab = 0; int* ivv = iv; for (cl = 0; cl < 2 * closureSize; cl += 2) { PetscInt point = closure[cl], dof, off, d, p; @@ -5217,6 +5328,50 @@ namespace PETSc { return pA; } } + class buildSolution : public OneOperator { + public: + class buildSolution_Op : public E_F0mps { + public: + Expression A; + Expression B; + static const int n_name_param = 0; + static basicAC_F0::name_and_type name_param[]; + Expression nargs[n_name_param]; + buildSolution_Op(const basicAC_F0& args) : A(0), B(0) { + args.SetNameParam(n_name_param, name_param, nargs); + A = to(args[0]); + B = to>*>(args[1]); + } + + AnyType operator( )(Stack stack) const; + operator aType( ) const { return atype< long >( ); } + }; + E_F0* code(const basicAC_F0& args) const { return new buildSolution_Op(args); } + buildSolution( ) + : OneOperator(atype( ), atype( ), atype>*>( )) {} + }; + basicAC_F0::name_and_type buildSolution::buildSolution_Op::name_param[] = { }; + AnyType buildSolution::buildSolution_Op::operator( )(Stack stack) const { + Dmat* ptA = GetAny((*A)(stack)); + KN>* ptKN = GetAny>*>((*B)(stack)); + ffassert(ptA->_ksp); + Mat A; + KSPGetOperators(ptA->_ksp, &A, NULL); + PetscInt n, N; + MatGetLocalSize(A, &n, NULL); + MatGetSize(A, &N, NULL); + ptKN->resize(n); + Vec v; + PetscScalar* p = reinterpret_cast(ptKN->operator HPDDM::upscaled_type*()); + VecCreateMPIWithArray(PetscObjectComm((PetscObject)A), 1, n, N, p, &v); + KSPBuildSolution(ptA->_ksp, v, NULL); + if(!std::is_same, PetscReal>::value) { + for(int i = n - 1; i >= 0; --i) + ptKN->operator[](i) = p[i]; + } + VecDestroy(&v); + return 0L; + } } // namespace PETSc static void Init_PETSc( ) { @@ -5259,9 +5414,9 @@ static void Init_PETSc( ) { TheOperators->Add("<-", new PETSc::initCSR< HpSchwarz< PetscScalar > >(1)); TheOperators->Add("<-", new PETSc::initCSR< HpSchwarz< PetscScalar > >(1, 1)); TheOperators->Add("<-", new PETSc::initCSR< HpSchwarz< PetscScalar > >(1, 1, 1)); + TheOperators->Add("<-", new PETSc::initCSR< HpSchwarz< PetscScalar > >(1, 1, 1, 1)); Global.Add("constructor", "(", new PETSc::initCSR< HpSchwarz< PetscScalar >, true >); Global.Add("constructor", "(", new PETSc::initCSR< HpSchwarz< PetscScalar >, true >(1)); - Global.Add("constructor", "(", new PETSc::initCSR< HpSchwarz< PetscScalar >, true >(1, 1)); Global.Add("constructor", "(", new PETSc::initCSR< HpSchwarz< PetscScalar >, true >(1, 1, 1)); Global.Add("MatDestroy", "(", new OneOperator1< long, Dmat* >(PETSc::destroyCSR)); zzzfff->Add("PetscScalar", atype::value, double, Complex>::type*>()); @@ -5324,6 +5479,7 @@ static void Init_PETSc( ) { Global.Add("PetscLogStagePop", "(", new OneOperator0< long >(PETSc::stagePop)); Global.Add("PetscMemoryGetCurrentUsage", "(", new OneOperator0< double >(PETSc::memoryGetCurrentUsage)); Global.Add("HasType", "(", new OneOperator2_< long, string*, string* >(PETSc::hasType)); + Global.Add("KSPBuildSolution", "(", new PETSc::buildSolution()); Init_Common( ); Dcl_Type< PETSc::DMPlex* >(Initialize< PETSc::DMPlex >, DeleteDTOR< PETSc::DMPlex >); zzzfff->Add("DM", atype< PETSc::DMPlex* >( )); diff --git a/plugin/mpi/PETSc.hpp b/plugin/mpi/PETSc.hpp index 6f8a947b9..b352b4556 100644 --- a/plugin/mpi/PETSc.hpp +++ b/plugin/mpi/PETSc.hpp @@ -162,7 +162,8 @@ void setVectorSchur(Type* ptA, KN* const& mT, KN* const& pL) { if(!(*ptA->_vS)[k]) { MatCreate(ptA->_A->getCommunicator(), &(*ptA->_vS)[k]); MatSetSizes((*ptA->_vS)[k], end - start, end - start, global, global); - MatSetType((*ptA->_vS)[k], MATMPIAIJ); + MatSetType((*ptA->_vS)[k], MATAIJ); + MatSeqAIJSetPreallocationCSR((*ptA->_vS)[k], reinterpret_cast(ia), reinterpret_cast(ja), c); MatMPIAIJSetPreallocationCSR((*ptA->_vS)[k], reinterpret_cast(ia), reinterpret_cast(ja), c); MatSetOption((*ptA->_vS)[k], MAT_NO_OFF_PROC_ENTRIES, PETSC_TRUE); } @@ -173,7 +174,8 @@ void setVectorSchur(Type* ptA, KN* const& mT, KN* const& pL) { Mat S; MatCreate(PetscObjectComm((PetscObject)ptA->_ksp), &S); MatSetSizes(S, end - start, end - start, global, global); - MatSetType(S, MATMPIAIJ); + MatSetType(S, MATAIJ); + MatSeqAIJSetPreallocationCSR(S, reinterpret_cast(ia), reinterpret_cast(ja), c); MatMPIAIJSetPreallocationCSR(S, reinterpret_cast(ia), reinterpret_cast(ja), c); MatDestroy(&((*ptA->_vS)[k])); PetscInt nsplits; diff --git a/plugin/mpi/SLEPc-code.hpp b/plugin/mpi/SLEPc-code.hpp index 347f16d62..c64848929 100644 --- a/plugin/mpi/SLEPc-code.hpp +++ b/plugin/mpi/SLEPc-code.hpp @@ -105,7 +105,7 @@ class eigensolver : public OneOperator { Expression B; const OneOperator* codeA, *codeB; const int c; - static const int n_name_param = 10; + static const int n_name_param = 11; static basicAC_F0::name_and_type name_param[]; Expression nargs[n_name_param]; E_eigensolver(const basicAC_F0& args, int d) : A(0), B(0), codeA(0), codeB(0), c(d) { @@ -158,6 +158,7 @@ basicAC_F0::name_and_type eigensolver::E_eigensolver::name_param {!std::is_same::value ? "schurPreconditioner" : "rvectors", !std::is_same::value ? &typeid(KN>>*) : &typeid(FEbaseArrayKn*)}, {!std::is_same::value ? "schurList" : "rarray", !std::is_same::value ? &typeid(KN*) : &typeid(KNM*)}, {"deflation", &typeid(KNM*)}, + {"errorestimate", &typeid(KN*)}, }; template struct _n_User { @@ -274,12 +275,16 @@ AnyType eigensolver::E_eigensolver::operator()(Stack stack) cons else PEPSetOptionsPrefix(pep, GetAny((*nargs[1])(stack))->c_str()); } + KSP empty = NULL; if(std::is_same::value) { EPSSetFromOptions(eps); ST st; EPSGetST(eps, &st); - if(ptA->_ksp) + if(ptA->_ksp) { + STGetKSP(st, &empty); + PetscObjectReference((PetscObject)empty); STSetKSP(st, ptA->_ksp); + } else { KSP ksp; PC pc; @@ -389,6 +394,7 @@ AnyType eigensolver::E_eigensolver::operator()(Stack stack) cons PEPGetConverged(pep, &nconv); if(nconv > 0 && ((nargs[2] || nargs[3] || nargs[4]) || (std::is_same::value && (nargs[7] || nargs[8])))) { KN::value, K, PetscReal>::type>* eigenvalues = nargs[2] ? GetAny::value, K, PetscReal>::type>*>((*nargs[2])(stack)) : nullptr; + KN* errorestimate = nargs[10] ? GetAny*>((*nargs[10])(stack)) : nullptr; KNM* array = nargs[4] ? GetAny*>((*nargs[4])(stack)) : nullptr; FEbaseArrayKn* rvectors = std::is_same::value && nargs[7] ? GetAny*>((*nargs[7])(stack)) : nullptr; KNM* rarray = std::is_same::value && nargs[8] ? GetAny*>((*nargs[8])(stack)) : nullptr; @@ -398,6 +404,8 @@ AnyType eigensolver::E_eigensolver::operator()(Stack stack) cons eigenvectors->resize(nconv); if(rvectors && !isType) rvectors->resize(nconv); + if(errorestimate) + errorestimate->resize(nconv); if(array) array->resize(m, nconv); Vec xr, xi; @@ -412,14 +420,24 @@ AnyType eigensolver::E_eigensolver::operator()(Stack stack) cons for(PetscInt i = 0; i < nconv; ++i) { PetscScalar kr, ki = 0; PetscReal sigma; - if(std::is_same::value) + PetscReal errest; + if(std::is_same::value) { EPSGetEigenpair(eps, i, &kr, &ki, (eigenvectors || array) ? xr : NULL, (eigenvectors || array) && std::is_same::value && std::is_same>::value ? xi : NULL); + if(errorestimate) + EPSGetErrorEstimate(eps, i, &errest); + } else if(std::is_same::value) SVDGetSingularTriplet(svd, i, &sigma, xr, xi); - else if(std::is_same::value) + else if(std::is_same::value) { NEPGetEigenpair(nep, i, &kr, &ki, (eigenvectors || array) ? xr : NULL, (eigenvectors || array) && std::is_same::value && std::is_same>::value ? xi : NULL); - else + if(errorestimate) + NEPGetErrorEstimate(nep, i, &errest); + } + else { PEPGetEigenpair(pep, i, &kr, &ki, (eigenvectors || array) ? xr : NULL, (eigenvectors || array) && std::is_same::value && std::is_same>::value ? xi : NULL); + if(errorestimate) + PEPGetErrorEstimate(pep, i, &errest); + } if(eigenvectors || array || rvectors || rarray) { PetscScalar* tmpr; PetscScalar* tmpi; @@ -495,6 +513,8 @@ AnyType eigensolver::E_eigensolver::operator()(Stack stack) cons else eigenvalues->operator[](i) = sigma; } + if(errorestimate) + errorestimate->operator[](i) = errest; } if(eigenvectors || array || rvectors || rarray) { VecDestroy(&xr); @@ -506,8 +526,15 @@ AnyType eigensolver::E_eigensolver::operator()(Stack stack) cons delete user->mat; PetscFree(user); } - if(std::is_same::value) + if(std::is_same::value) { + if(empty) { + ST st; + EPSGetST(eps, &st); + STSetKSP(st, empty); + PetscObjectDereference((PetscObject)empty); + } EPSDestroy(&eps); + } else if(std::is_same::value) SVDDestroy(&svd); else if(std::is_same::value) diff --git a/plugin/mpi/SLEPc-complex.cpp b/plugin/mpi/SLEPc-complex.cpp index 10b31ca7a..fd040c9d2 100644 --- a/plugin/mpi/SLEPc-complex.cpp +++ b/plugin/mpi/SLEPc-complex.cpp @@ -1,4 +1,4 @@ -//ff-c++-LIBRARY-dep: cxx11 slepccomplex petsccomplex [mkl|blas] hpddm mpi +//ff-c++-LIBRARY-dep: cxx11 //ff-c++-cpp-dep: #include "ff++.hpp" diff --git a/plugin/mpi/SLEPc.cpp b/plugin/mpi/SLEPc.cpp index 76f60e6d3..ae22b41cf 100644 --- a/plugin/mpi/SLEPc.cpp +++ b/plugin/mpi/SLEPc.cpp @@ -1,4 +1,4 @@ -//ff-c++-LIBRARY-dep: cxx11 slepc petsc [mkl|blas] hpddm mpi +//ff-c++-LIBRARY-dep: cxx11 //ff-c++-cpp-dep: #include "ff++.hpp" diff --git a/plugin/mpi/bem.cpp b/plugin/mpi/bem.cpp index 3c06619b9..6f60deebb 100644 --- a/plugin/mpi/bem.cpp +++ b/plugin/mpi/bem.cpp @@ -587,7 +587,7 @@ AnyType SetCompressMat(Stack stack,Expression emat,Expression einter,int init) template void addHmat() { - Dcl_Type**>(Initialize*>, Delete*>); + // Dcl_Type**>(Initialize*>, Delete*>); Dcl_TypeandPtr*>(0,0,::InitializePtr*>,::DeletePtr*>); //atype**>()->Add("(","",new OneOperator2_**, string*>(get_infos)); @@ -1078,10 +1078,234 @@ EquationEnum whatEquationEnum(BemKernel *K,int i) { return equEnum; } +// Begin Array of HMatrix[int] +template< class A > +inline AnyType DestroyKNmat(Stack, const AnyType &x) { + KN< A > *a = GetAny< KN< A > * >(x); + for (int i = 0; i < a->N( ); i++) + if ((*a)[i]) delete (*a)[i]; + a->destroy( ); + return Nothing; +} + +template< class RR, class A, class B > +RR *get_elementp_(const A &a, const B &b) { + if (b < 0 || a->N( ) <= b) { + cerr << " Out of bound 0 <=" << b << " < " << a->N( ) << " array type = " << typeid(A).name( ) + << endl; + ExecError("Out of bound in operator []"); + } + return &((*a)[b]); +} + +template< class R > +R *set_initinit(R *const &a, const long &n) { + SHOWVERB(cout << " set_init " << typeid(R).name( ) << " " << n << endl); + a->init(n); + for (int i = 0; i < n; i++) (*a)[i] = 0; + return a; +} + +template +void ArrayofHmat() +{ + typedef HMatrixVirt< R > *Mat; + typedef Mat *PMat; + typedef KN< Mat > AMat; + + Dcl_Type< AMat * >(0, ::DestroyKNmat< Mat >); + // to declare HMatrix[int] + map_type_of_map[make_pair(atype< long >( ), atype< PMat >( )->right())] = atype< AMat * >( ); + atype< AMat * >( )->Add( + "[", "", + new OneOperator2_< PMat, AMat *, long >(get_elementp_< Mat, AMat *, long >)); + + TheOperators->Add("<-", new OneOperator2_< AMat*, AMat* , long >(&set_initinit)); + + + // resize mars 2006 v2.4-1 + Dcl_Type< Resize< AMat > >( ); + Add< AMat *>("resize", ".", + new OneOperator1< Resize< AMat >, AMat * >(to_Resize)); + Add< Resize< AMat > >( + "(", "", new OneOperator2_< AMat*, Resize< AMat >, long >(resizeandclean1)); + +} +// End Array of HMatrix[int] + +template +class OpHMatrixUser : public OneOperator +{ + public: + typedef typename v_fes1::pfes pfes1; + typedef typename v_fes2::pfes pfes2; + class Op : public E_F0info { + public: + Expression g, uh1, uh2; + static const int n_name_param = 8; + static basicAC_F0::name_and_type name_param[] ; + Expression nargs[n_name_param]; + long argl(int i,Stack stack,long a) const{ return nargs[i] ? GetAny( (*nargs[i])(stack) ): a;} + string* args(int i,Stack stack,string* a) const{ return nargs[i] ? GetAny( (*nargs[i])(stack) ): a;} + double arg(int i,Stack stack,double a) const{ return nargs[i] ? GetAny( (*nargs[i])(stack) ): a;} + pcommworld argc(int i,Stack stack,pcommworld a ) const{ return nargs[i] ? GetAny( (*nargs[i])(stack) ): a;} + Op(const basicAC_F0 & args, Expression bb, Expression cc, Expression dd) : g(bb),uh1(cc), uh2(dd) { + args.SetNameParam(n_name_param,name_param,nargs); + } + }; + + E_F0 * code(const basicAC_F0 & args) const { + return new Op(args,t[0]->CastTo(args[0]),t[1]->CastTo(args[1]),t[2]->CastTo(args[2])); + } + + OpHMatrixUser() : + OneOperator(atype::Op*>(),atype**>(),atype(),atype()) {} +}; + +template +basicAC_F0::name_and_type OpHMatrixUser::Op::name_param[]= { + { "eps", &typeid(double)}, + { "commworld", &typeid(pcommworld)}, + { "eta", &typeid(double)}, + { "minclustersize", &typeid(long)}, + { "maxblocksize", &typeid(long)}, + { "mintargetdepth", &typeid(long)}, + { "minsourcedepth", &typeid(long)}, + { "compressor", &typeid(string*)} +}; + +template +AnyType SetOpHMatrixUser(Stack stack,Expression emat, Expression eop) +{ + typedef typename v_fes1::pfes pfes1; + typedef typename v_fes2::pfes pfes2; + typedef typename v_fes1::FESpace FESpace1; + typedef typename v_fes2::FESpace FESpace2; + typedef typename FESpace1::Mesh SMesh; + typedef typename FESpace2::Mesh TMesh; + typedef typename SMesh::RdHat SRdHat; + typedef typename TMesh::RdHat TRdHat; + + typedef typename OpHMatrixUser::Op UOp; + const UOp * op(dynamic_cast(eop)); + pfes1 * pUh= GetAny((*op->uh1)(stack)); + FESpace1 * Uh = **pUh; + int NUh =Uh->N; + pfes2 * pVh= GetAny((*op->uh2)(stack)); + FESpace2 * Vh = **pVh; + int NVh =Vh->N; + ffassert(Vh); + ffassert(Uh); + + int n=Uh->NbOfDF; + int m=Vh->NbOfDF; + HMatrixVirt** Hmat =GetAny** >((*emat)(stack)); + + Data_Bem_Solver ds; + ds.factorize=0; + ds.initmat=true; + + ds.epsilon = op->arg(0,stack,ds.epsilon); + ds.commworld = op->argc(1,stack,ds.commworld); + ds.eta = op->arg(2,stack,ds.eta); + ds.minclustersize = op->argl(3,stack,ds.minclustersize); + ds.maxblocksize = op->argl(4,stack,ds.maxblocksize); + ds.mintargetdepth = op->argl(5,stack,ds.mintargetdepth); + ds.minsourcedepth = op->argl(6,stack,ds.minsourcedepth); + ds.compressor = *(op->args(7,stack,&ds.compressor)); + + const SMesh & ThU =Uh->Th; + const TMesh & ThV =Vh->Th; + bool samemesh = (void*)&Uh->Th == (void*)&Vh->Th; + + if(init) + *Hmat =0; + *Hmat =0; + if( *Hmat) + delete *Hmat; + + *Hmat =0; + + vector p1(3*n); + vector p2(3*m); + Fem2D::R3 pp; + bemtool::R3 p; + SRdHat pbs; + TRdHat pbt; + pbs[0] = 1./(SRdHat::d+1); + pbs[1] = 1./(SRdHat::d+1); + if (SRdHat::d == 2) pbs[2] = 1./(SRdHat::d+1); + pbt[0] = 1./(TRdHat::d+1); + pbt[1] = 1./(TRdHat::d+1); + if (TRdHat::d == 2) pbt[2] = 1./(TRdHat::d+1); + + int Snbv = Uh->TFE[0]->ndfonVertex; + int Snbe = Uh->TFE[0]->ndfonEdge; + int Snbt = Uh->TFE[0]->ndfonFace; + bool SP0 = SRdHat::d == 1 ? (Snbv == 0) && (Snbe == 1) && (Snbt == 0) : (Snbv == 0) && (Snbe == 0) && (Snbt == 1); + bool SP1 = (Snbv == 1) && (Snbe == 0) && (Snbt == 0); + + int Tnbv = Vh->TFE[0]->ndfonVertex; + int Tnbe = Vh->TFE[0]->ndfonEdge; + int Tnbt = Vh->TFE[0]->ndfonFace; + bool TP0 = TRdHat::d == 1 ? (Tnbv == 0) && (Tnbe == 1) && (Tnbt == 0) : (Tnbv == 0) && (Tnbe == 0) && (Tnbt == 1); + bool TP1 = (Tnbv == 1) && (Tnbe == 0) && (Tnbt == 0); + + for (int i=0; i** generator = GetAny**>((*op->g)(stack)); + + MPI_Comm comm = ds.commworld ? *(MPI_Comm*)ds.commworld : MPI_COMM_WORLD; + builHmat(Hmat,*generator,ds,p1,p2,comm); + + return Hmat; +} + +template +void AddHMatrixUser() { + typedef typename OpHMatrixUser< R, v_fes1, v_fes2 >::Op OpT; + Dcl_Type(); + Global.Add("Build","(", new OpHMatrixUser< R, v_fes1, v_fes2 >); + Add("<-","(", new OpHMatrixUser< R, v_fes1, v_fes2 >); + TheOperators->Add("<-", new OneOperator2_**,HMatrixVirt**,const OpT*,E_F_StackF0F0>(SetOpHMatrixUser)); + TheOperators->Add("=", new OneOperator2_**,HMatrixVirt**,const OpT*,E_F_StackF0F0>(SetOpHMatrixUser)); +} static void Init_Bem() { - + if(mpirank==0) cout << "\nInit_Bem\n"; + map_type[typeid(const BemFormBilinear *).name( )] = new TypeFormBEM; map_type[typeid(const BemKFormBilinear *).name( )] = new ForEachType< BemKFormBilinear >; @@ -1101,8 +1325,8 @@ static void Init_Bem() { typedef const BemPotential *pBemPotential; - Dcl_Type< fkernel * >( ); // a bem kernel - Dcl_Type< fpotential * >( ); // a bem potential + // Dcl_Type< fkernel * >( ); // a bem kernel + // Dcl_Type< fpotential * >( ); // a bem potential Dcl_Type< const OP_MakeBemKernelFunc::Op * >( ); Dcl_Type< const OP_MakeBemPotentialFunc::Op * >( ); @@ -1192,7 +1416,26 @@ static void Init_Bem() { Global.New("htoolMaxblocksize",CPValue(ff_htoolMaxblocksize)); Global.New("htoolMintargetdepth",CPValue(ff_htoolMintargetdepth)); Global.New("htoolMinsourcedepth",CPValue(ff_htoolMinsourcedepth)); - + ArrayofHmat(); + ArrayofHmat>(); + + // Build HMatrix from custom user generator + Dcl_TypeandPtr< VirtualGenerator* >(0, 0,::InitializePtr< VirtualGenerator* >, ::DeletePtr< VirtualGenerator*> ); + Dcl_TypeandPtr< VirtualGenerator>* >(0, 0,::InitializePtr< VirtualGenerator>* >, ::DeletePtr< VirtualGenerator>*> ); + zzzfff->Add("Generator", atype** >( )); + map_type_of_map[make_pair(atype**>(), atype())] = atype**>(); + map_type_of_map[make_pair(atype**>(), atype())] = atype >**>(); + + AddHMatrixUser(); + AddHMatrixUser(); + AddHMatrixUser(); + AddHMatrixUser,v_fesL, v_fesL>(); + AddHMatrixUser,v_fesS, v_fesS>(); + AddHMatrixUser,v_fes3, v_fes3>(); + AddHMatrixUser(); + AddHMatrixUser(); + AddHMatrixUser,v_fesL, v_fesS>(); + AddHMatrixUser,v_fesS, v_fes3>(); } LOADFUNC(Init_Bem) diff --git a/plugin/mpi/common_hpddm.hpp b/plugin/mpi/common_hpddm.hpp index b00c7265c..cd5b23e8a 100644 --- a/plugin/mpi/common_hpddm.hpp +++ b/plugin/mpi/common_hpddm.hpp @@ -431,8 +431,8 @@ void addArray() { map_type_of_map[make_pair(atype(), atype())] = atype*>(); } -void parallelIO(string*& name, MPI_Comm* const& comm, bool const& append) { - std::string base_filename(*name); +void parallelIO(string*& name, MPI_Comm* const& comm, bool const& append, int& T, int& size, std::string& base_filename) { + base_filename = *name; std::string::size_type p(base_filename.find_last_of('.')); std::string file_without_extension = base_filename.substr(0, p); std::string extension; @@ -446,14 +446,13 @@ void parallelIO(string*& name, MPI_Comm* const& comm, bool const& append) { else base_filename = file_without_extension.substr(p + 1, std::string::npos); int rank; - int size; MPI_Comm_rank(comm ? *comm : MPI_COMM_WORLD, &rank); MPI_Comm_size(comm ? *comm : MPI_COMM_WORLD, &size); std::ostringstream str[3]; str[2] << size; str[1] << std::setw(str[2].str().length()) << std::setfill('0') << rank; ofstream pvd; - int T = 0; + T = 0; if(append) { if(rank == 0) { ifstream input; @@ -473,26 +472,6 @@ void parallelIO(string*& name, MPI_Comm* const& comm, bool const& append) { } str[0] << std::setw(4) << std::setfill('0') << T; *name = file_without_extension + "_" + (size > 1 ? str[2].str() + "_" : "") + str[0].str() + (size > 1 ? "_" + str[1].str() : "") + "." + extension; - if(rank == 0) { - pvd.open(file_without_extension + (size > 1 ? "_" + str[2].str() : "") + ".pvd"); - pvd << "\n"; - pvd << "\n"; - pvd << " \n"; - for(int t = 0; t < T + 1; ++t) - for(int i = 0; i < size; ++i) { - pvd << " 1) pvd << str[2].str() + "_"; - pvd << std::setw(4) << std::setfill('0') << t; - if(size > 1) pvd << "_" << std::setw(str[2].str().length()) << std::setfill('0') << i; - pvd << "." << std::setw(0) << extension << "\"/>\n"; - } - pvd << " \n"; - pvd << "\n"; - } } long periodicity(Matrice_Creuse* const& R, KN< KN< long > >* const& interaction, KN< double >* const& D) { diff --git a/plugin/seq/Element_P3pnc.cpp b/plugin/seq/Element_P3pnc.cpp new file mode 100644 index 000000000..46a038861 --- /dev/null +++ b/plugin/seq/Element_P3pnc.cpp @@ -0,0 +1,292 @@ +/****************************************************************************/ +/* This file is part of FreeFEM. */ +/* */ +/* FreeFEM is free software: you can redistribute it and/or modify */ +/* it under the terms of the GNU Lesser General Public License as */ +/* published by the Free Software Foundation, either version 3 of */ +/* the License, or (at your option) any later version. */ +/* */ +/* FreeFEM is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU Lesser General Public License for more details. */ +/* */ +/* You should have received a copy of the GNU Lesser General Public License */ +/* along with FreeFEM. If not, see . */ +/****************************************************************************/ +// SUMMARY : ... +// LICENSE : LGPLv3 +// ORG : LJLL Universite Pierre et Marie Curie, Paris, FRANCE, CEA +// AUTHORS : BALAZI ATCHY NILLAMA Loïc et HECHT Frédéric +// E-MAIL : loic.balaziatchynillama@cea.fr et rederic.hecht@sorbonne-universite.fr + +/* clang-format off */ +//ff-c++-LIBRARY-dep: +//ff-c++-cpp-dep: +/* clang-format on */ +/* + the DoF are + 3 dof per edge e + int_(e) \lambda^e_0 v, int_(e) \lambda^e_1 v, int_(e) \lambda^e_0 \lambda^e_1 v + where \lambda^e_0 and \lambda^e_1 is the barycentric coordinate on oriented edge + 3 Dof on triangle K + int_(K) \lambda_0 v, int_(e) \lambda_1 v, int_(e) \lambda_2 + where \lambda_0 , \lambda_1, \lambda_2 is the barycentric coordinate on traingle K + + and the Pk polynomial space is : P3 + span( bk \lambda_0 , bk \lambda_1) + bk = (\lambda_0 - \lambda_1) * (\lambda_1 - \lambda_2) * (\lambda_2 - \lambda_0); + */ +#include "ff++.hpp" +#include "AddNewFE.h" + +// Attention probleme de numerotation des inconnues +// ------------------------------------------------- +// dans freefem, il y a un noeud par objets sommet, arete, element. +// et donc la numerotation des dl dans l'element depend +// de l'orientation des aretes +// +/// --------------------------------------------------------------- +namespace Fem2D { + static const QuadratureFormular1d &QFE = QF_GaussLegendre4; + static const GQuadratureFormular< R2 > &QFK = QuadratureFormular_T_5; + + class TypeOfFE_P3pnc : public TypeOfFE { + public: + static int Data[]; + + TypeOfFE_P3pnc( ) : TypeOfFE(12, 1, Data, 4, 1, 3 * 3 * QFE.n + 3 * QFK.n, 3 * QFE.n + QFK.n, 0) { + int p = 0, k = 0; + const R2 Ph[] = {R2(0, 0), R2(1, 0), R2(0, 1)}; + + for (int i = 0; i < 3; i++) { + R2 A = Ph[(i + 1) % 3], B = Ph[(i + 2) % 3]; + for (int j = 0; j < QFE.n; j++) { + R l0 = QFE[j].x, l1 = 1 - l0; + if(verbosity>4) cout << "k = " << k << " AND pij = " << pij_alpha.N( ) << endl; + pij_alpha[k++] = IPJ(3 * i, p, 0); + pij_alpha[k++] = IPJ(3 * i + 1, p, 0); + pij_alpha[k++] = IPJ(3 * i + 2, p, 0); + P_Pi_h[p++] = A * l0 + B * l1; + } + } + + for (int i = 0; i < QFK.n; i++) { + if(verbosity>4) cout << "k = " << k << " AND pij = " << pij_alpha.N( ) << endl; + pij_alpha[k++] = IPJ(9, p, 0); + pij_alpha[k++] = IPJ(10, p, 0); + pij_alpha[k++] = IPJ(11, p, 0); + P_Pi_h[p++] = QFK[i]; + } + if(verbosity>4) + { + cout << " QFE.n " << QFE.n << endl; + cout << " QFK.n " << QFK.n << endl; + cout << "k = " << k << " AND pij = " << pij_alpha.N( ) << endl; + cout << "p = " << p << " AND P_Pi_h = " << P_Pi_h.N( )<< endl; +} + ffassert(k == this->pij_alpha.N( )); + ffassert(p == this->P_Pi_h.N( )); + } + + void FB(const bool *whatd, const Mesh &Th, const Triangle &K, const RdHat &PHat, + RNMK_ &val) const; + void Pi_h_alpha(const baseFElement &K, KN_< double > &v) const; + }; + + // const QuadratureFormular1d & TypeOfFE_P2pnc::QFE=QF_GaussLegendre3; + // const GQuadratureFormular & TypeOfFE_P2pnc::QFK=QuadratureFormular_T_5; + + int TypeOfFE_P3pnc::Data[] = {3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, // the support number of the node of the df + 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, // the number of the df on the node + 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, // the node of the df + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // the df come from which FE (generaly 0) + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11, // which are de df on sub FE + 0, // for each compontant $j=0,N-1$ it give the sub FE associated + 0, 12}; + void TypeOfFE_P3pnc::Pi_h_alpha( + const baseFElement &K, KN_< double > &v) const { // compute the coef of interpolation ... + const Triangle &T(K.T); + int k = 0; + R oe[3] = {T.EdgeOrientation(0), T.EdgeOrientation(1), T.EdgeOrientation(2)}; + static int ddd = 10; + + ++ddd; + + for (int i = 0; i < 3; i++) { + for (int p = 0; p < QFE.n; ++p) { + double x = QFE[p].x; + R L0 = QFE[p].x , L1 = 1-QFE[p].x , L2 = L0*L1 ; + if (oe[i] < 0) { + swap(L0, L1); //depend on edge orientation //No need to swap L2 since symmetric + } + + if (ddd < 3) { + cout << p << " " << oe[i] << " " << L0 << " " << L1 << endl; + } + + R cc0 = L0 * QFE[p].a; + R cc1 = L1 * QFE[p].a; + R cc2 = L2 * QFE[p].a; + v[k++] = cc0; + v[k++] = cc1; + v[k++] = cc2; + } + } + + for (int p = 0; p < QFK.n; ++p) { + double w = QFK[p].a; + R l1 = QFK[p].x, l2 = QFK[p].y, l0 = 1 - l1 - l2; + v[k++] = l0 * w; + v[k++] = l1 * w; + v[k++] = l2 * w; + } + + ffassert(k == this->pij_alpha.N( )); + } + + void TypeOfFE_P3pnc::FB(const bool *whatd, const Mesh &TH, const Triangle &K, const RdHat &PHat, + RNMK_ &val) const { + R2 A(K[0]), B(K[1]), C(K[2]); + R l0 = 1 - PHat.x - PHat.y, l1 = PHat.x, l2 = PHat.y; + R bk = (l0 - l1) * (l1 - l2) * (l2 - l0); + R oe[3] = {K.EdgeOrientation(0), K.EdgeOrientation(1), K.EdgeOrientation(2)}; + R l12[] = { + l0 * l0 * l0, l1 * l1 * l1, l2 * l2 * l2, //3 + l0 * l0 * l1, l0 * l0 * l2, l1 * l1 * l0, l1 * l1 * l2, l2 * l2 * l0, l2 * l2 * l1, //6 + l0 * l1 * l2, //2 + bk * l0, bk * l1 // P4 element + }; // 12 monome + + /* + double C1[12][12] ={ + {-1.2, 6, 1.2, -8.4, 10.8, 10.8, -46.8, -10.8, 20.4, 12, 0, -84 }, + {-1.2, 1.2, 6, -73.2, 75.6, 73.2, -63.6, -73.2, 37.2, 12, -84, -84 }, + {1.2, -15.6, -15.6, 298.8, -205.2, -306, 349.2, 198, -154.8, -180, 252, 504 }, + {1.2, -1.2, 6, 73.2, -63.6, -73.2, 75.6, 37.2, -73.2, 12, 84, 84 }, + {6, -1.2, 1.2, 10.8, -46.8, -8.4, 10.8, 20.4, -10.8, 12 , 84, 0 }, + {-15.6, 1.2, -15.6, -306, 349.2, 298.8, -205.2, -154.8, 198, -180, -504, -252 }, + {6, 1.2, -1.2, -46.8, 10.8, 20.4, -10.8, -8.4, 10.8, 12, -84, 0 }, + {1.2, 6, -1.2, 20.4, -10.8, -46.8, 10.8, 10.8, -8.4, 12, 0, 84 }, + {-15.6, -15.6, 1.2, 97.2, -54, 97.2, -54, 46.8, 46.8, -180, 252, -252 }, + {-9.6, 4.8, 4.8, 189.6, 21.6, -192, 86.4, -24, -81.6, 60, 84, 168 }, + {4.8, -9.6, 4.8, -192, 86.4, 189.6, 21.6, -81.6, -24, 60, -168, -84 }, + {4.8, 4.8, -9.6, 2.4, -108, 2.4, -108, 105.6, 105.6, 60, 84, -84 }, + }; */ + + + double C1[12][12] ={ + { -1.2, -1.2, 1.2, 1.2, 6., -15.6, 6., 1.2, -15.6, -9.6, 4.8, 4.8 }, //dof 1 + { 6., 1.2, -15.6, -1.2, -1.2, 1.2, 1.2, 6., -15.6, 4.8, -9.6, 4.8 }, //dof 2 + { 1.2, 6., -15.6, 6., 1.2, -15.6, -1.2, -1.2, 1.2, 4.8 , 4.8, -9.6 }, //dof 3 + { -8.4, -73.2, 298.8, 73.2, 10.8, -306., -46.8, 20.4, 97.2, 189.6, -192., 2.4 }, //dof 4 + { 10.8, 75.6, -205.2, -63.6, -46.8, 349.2, 10.8, -10.8, -54., 21.6, 86.4, -108. }, //dof 5 + { 10.8, 73.2, -306., -73.2, -8.4, 298.8, 20.4, -46.8, 97.2, -192., 189.6, 2.4 }, //dof 6 + { -46.8, -63.6, 349.2, 75.6, 10.8, -205.2, -10.8, 10.8, -54., 86.4 , 21.6, -108. }, //dof 7 + { -10.8, -73.2, 198., 37.2, 20.4, -154.8, -8.4, 10.8, 46.8, -24. , -81.6, 105.6 }, //dof 8 + { 20.4, 37.2, -154.8, -73.2, -10.8, 198., 10.8, -8.4, 46.8, -81.6 , -24., 105.6 }, //dof 9 + { 12., 12., -180., 12., 12., -180., 12., 12., -180., 60. , 60., 60. }, //dof 10 + { 0., -84., 252., 84., 84., -504., -84., 0., 252., 84., -168., 84. }, //dof 11 + { -84., -84., 504., 84., 0., -252., -0., 84., -252., 168., -84., -84. }, //dof 12 + }; + + + // C1 = C^1 + // C(i,j) = dof(i,mom_j) + // dof(k,sum_j C1(j,i)*mom_j) = delta_ik + // sum_j C1(j,i)*dof(k,mom_j) = Id + // sum_j C_kj C1(j,i) = Id + // sum_j dof(k,mom_j) C1(j,i) = Id + // C_kj= dof(k,mom_j) + + // formule magic : + // sur un simplex en dim d , l_0, , .. l_d coord barycentric + // int_K (\Prod_i=0^d l_i^n_i) = |K| ( d! \Prod_i n_i! / (d+ sum_i n_i)!) + // n_i == 0 , + // n_i = delta_ik => int_K l_k = |K|/(d+1) + // int_K l_k l_j = |K|(1+delta_kj) /((d+1)((d+2)) + // + + if (val.N( ) < 12) { + throwassert(val.N( ) >= 12); + } + + throwassert(val.M( ) == 1); + + val = 0; + RN_ f0(val('.', 0, op_id)); + int p[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; //no need to swap 2, 5, 8 since symmetric + + + if (oe[0] < 0) { + swap(p[0], p[1]); + } + + if (oe[1] < 0) { + swap(p[3], p[4]); + } + + if (oe[2] < 0) { + swap(p[6], p[7]); + } + + //No need to swap elemet 2, 5 and 8 since they are symmetric = do not depends on edge orientation + + if (whatd[op_id]) { + for (int i = 0; i < 12; ++i) { + for (int j = 0; j < 12; ++j) { + f0[p[i]] += C1[j][i] * l12[j]; + } + } + } + + if (whatd[op_dx] || whatd[op_dy]) { + R2 D0 = K.H(0), D1 = K.H(1), D2 = K.H(2); + R2 Dbk = (l1 - l2) * (l2 - l0) * (D0 - D1) + + (l0 - l1) * (l2 - l0) * (D1 - D2) + + (l0 - l1) * (l1 - l2) * (D2 - D0); + R2 D12[] = { + D0 * (l0 * l0*3.), + D1 * (l1 * l1*3.), + D2 * (l2 * l2*3.), + D0 * (l0 * l1 *2.) + D1 * (l0 * l0), + D0 * (l0 * l2 *2.) + D2 * (l0 * l0), + D1 * (l1 * l0 *2.) + D0 * (l1 * l1), + D1 * (l1 * l2 *2.) + D2 * (l1 * l1), + D2 * (l2 * l0 *2.) + D0 * (l2 * l2), + D2 * (l2 * l1 *2.) + D1 * (l2 * l2), + D0 * (l1 * l2) + D1* (l0 * l2) + D2* (l0 * l1) , + Dbk*l0 + D0 *bk, Dbk*l1 + D1 *bk + }; + + if (whatd[op_dx]) { + RN_ f0x(val('.', 0, op_dx)); + + for (int i = 0; i < 12; ++i) { + for (int j = 0; j < 12; ++j) { + f0x[p[i]] += C1[j][i] * D12[j].x; + } + } + } + + if (whatd[op_dy]) { + RN_ f0y(val('.', 0, op_dy)); + + for (int i = 0; i < 12; ++i) { + for (int j = 0; j < 12; ++j) { + f0y[p[i]] += C1[j][i] * D12[j].y; + } + } + } + } + } +} // namespace Fem2D +static TypeOfFE_P3pnc VTypeOfFE_P3pnc; +static AddNewFE P1dcLagrange("P3pnc", &VTypeOfFE_P3pnc); + +static void finit( ) { + // link with FreeFem++ +} + +LOADFUNC(finit) + +// --- fin -- diff --git a/plugin/seq/Helmholtz_FD.cpp b/plugin/seq/Helmholtz_FD.cpp index 7343c80a0..d0b3d122e 100644 --- a/plugin/seq/Helmholtz_FD.cpp +++ b/plugin/seq/Helmholtz_FD.cpp @@ -357,18 +357,420 @@ double wtab[2752] = { 20.15 , 0.623136342 , 0.045090564 , 0.007242844 , 0.002425767 , 0.137593195 , 0.791602910 , 0.070803881 }; +double wtab2[3192] = { + 2.49999994E-03 , 0.578033745 , 3.99446450E-02 , 2.38903537E-02 , -1.30482316E-02 , 0.179515034 , 0.731100619 , 8.93843472E-02, + 3.50000011E-03 , 0.577869534 , 3.99689302E-02 , 2.39049532E-02 , -1.30678229E-02 , 0.179440185 , 0.731137991 , 8.94218087E-02, + 4.49999981E-03 , 0.577705383 , 3.99932154E-02 , 2.39195526E-02 , -1.30874133E-02 , 0.179365337 , 0.731175423 , 8.94592628E-02, + 5.49999997E-03 , 0.577541232 , 4.00174968E-02 , 2.39341483E-02 , -1.31069971E-02 , 0.179290488 , 0.731212795 , 8.94967243E-02, + 6.50000013E-03 , 0.577377021 , 4.00417708E-02 , 2.39487402E-02 , -1.31265689E-02 , 0.179215625 , 0.731250167 , 8.95342156E-02, + 7.49999983E-03 , 0.577212870 , 4.00660373E-02 , 2.39633210E-02 , -1.31461201E-02 , 0.179140732 , 0.731287539 , 8.95717517E-02, + 8.50000046E-03 , 0.577048659 , 4.00902927E-02 , 2.39778906E-02 , -1.31656425E-02 , 0.179065749 , 0.731324852 , 8.96094143E-02, + 9.49999969E-03 , 0.576884508 , 4.01145332E-02 , 2.39924453E-02 , -1.31851304E-02 , 0.178990647 , 0.731362045 , 8.96473005E-02, + 1.04999999E-02 , 0.576720297 , 4.01387550E-02 , 2.40069814E-02 , -1.32045783E-02 , 0.178915322 , 0.731399119 , 8.96855593E-02, + 1.15000000E-02 , 0.576556087 , 4.01629582E-02 , 2.40214970E-02 , -1.32239787E-02 , 0.178839639 , 0.731435955 , 8.97244066E-02, + 1.25000002E-02 , 0.576391935 , 4.01871353E-02 , 2.40359865E-02 , -1.32433213E-02 , 0.178763434 , 0.731472433 , 8.97641182E-02, + 1.35000004E-02 , 0.576227725 , 4.02112827E-02 , 2.40504444E-02 , -1.32625941E-02 , 0.178686514 , 0.731508434 , 8.98050219E-02, + 1.44999996E-02 , 0.576063514 , 4.02353965E-02 , 2.40648650E-02 , -1.32817822E-02 , 0.178608656 , 0.731543839 , 8.98475125E-02, + 1.54999997E-02 , 0.575899243 , 4.02594656E-02 , 2.40792390E-02 , -1.33008687E-02 , 0.178529590 , 0.731578410 , 8.98919925E-02, + 1.64999999E-02 , 0.575735033 , 4.02834900E-02 , 2.40935609E-02 , -1.33198369E-02 , 0.178449064 , 0.731612027 , 8.99389088E-02, + 1.75000001E-02 , 0.575570762 , 4.03074548E-02 , 2.41078213E-02 , -1.33386711E-02 , 0.178366825 , 0.731644511 , 8.99886861E-02, + 1.85000002E-02 , 0.575406551 , 4.03313600E-02 , 2.41220128E-02 , -1.33573553E-02 , 0.178282633 , 0.731675625 , 9.00417194E-02, + 1.95000004E-02 , 0.575242221 , 4.03551981E-02 , 2.41361316E-02 , -1.33758765E-02 , 0.178196281 , 0.731705368 , 9.00983587E-02, + 2.05000006E-02 , 0.575077951 , 4.03789654E-02 , 2.41501704E-02 , -1.33942226E-02 , 0.178107575 , 0.731733561 , 9.01588872E-02, + 2.15000007E-02 , 0.574913621 , 4.04026546E-02 , 2.41641272E-02 , -1.34123880E-02 , 0.178016424 , 0.731760025 , 9.02235359E-02, + 2.25000009E-02 , 0.574749291 , 4.04262692E-02 , 2.41780002E-02 , -1.34303654E-02 , 0.177922696 , 0.731784880 , 9.02924463E-02, + 2.34999992E-02 , 0.574584961 , 4.04497981E-02 , 2.41917893E-02 , -1.34481536E-02 , 0.177826360 , 0.731807947 , 9.03657228E-02, + 2.44999994E-02 , 0.574420631 , 4.04732488E-02 , 2.42054947E-02 , -1.34657528E-02 , 0.177727371 , 0.731829226 , 9.04433951E-02, + 2.54999995E-02 , 0.574256241 , 4.04966101E-02 , 2.42191181E-02 , -1.34831630E-02 , 0.177625760 , 0.731848776 , 9.05254781E-02, + 2.64999997E-02 , 0.574091792 , 4.05198894E-02 , 2.42326632E-02 , -1.35003878E-02 , 0.177521497 , 0.731866539 , 9.06119570E-02, + 2.74999999E-02 , 0.573927343 , 4.05430831E-02 , 2.42461301E-02 , -1.35174291E-02 , 0.177414611 , 0.731882572 , 9.07028094E-02, + 2.85000000E-02 , 0.573762894 , 4.05661911E-02 , 2.42595226E-02 , -1.35342898E-02 , 0.177305117 , 0.731896877 , 9.07979980E-02, + 2.95000002E-02 , 0.573598444 , 4.05892096E-02 , 2.42728423E-02 , -1.35509735E-02 , 0.177193031 , 0.731909454 , 9.08975154E-02, + 3.05000003E-02 , 0.573433876 , 4.06121388E-02 , 2.42860932E-02 , -1.35674803E-02 , 0.177078366 , 0.731920302 , 9.10013393E-02, + 3.15000005E-02 , 0.573269367 , 4.06349748E-02 , 2.42992751E-02 , -1.35838138E-02 , 0.176961109 , 0.731929421 , 9.11094695E-02, + 3.24999988E-02 , 0.573104799 , 4.06577215E-02 , 2.43123900E-02 , -1.35999750E-02 , 0.176841274 , 0.731936812 , 9.12219137E-02, + 3.35000008E-02 , 0.572940171 , 4.06803750E-02 , 2.43254397E-02 , -1.36159649E-02 , 0.176718846 , 0.731942475 , 9.13386792E-02, + 3.44999991E-02 , 0.572775543 , 4.07029316E-02 , 2.43384279E-02 , -1.36317844E-02 , 0.176593810 , 0.731946409 , 9.14597660E-02, + 3.55000012E-02 , 0.572610915 , 4.07253951E-02 , 2.43513510E-02 , -1.36474352E-02 , 0.176466182 , 0.731948614 , 9.15851891E-02, + 3.64999995E-02 , 0.572446167 , 4.07477617E-02 , 2.43642144E-02 , -1.36629166E-02 , 0.176335946 , 0.731949091 , 9.17149633E-02, + 3.75000015E-02 , 0.572281480 , 4.07700278E-02 , 2.43770182E-02 , -1.36782313E-02 , 0.176203087 , 0.731947839 , 9.18490961E-02, + 3.84999998E-02 , 0.572116673 , 4.07921970E-02 , 2.43897643E-02 , -1.36933802E-02 , 0.176067606 , 0.731944799 , 9.19876024E-02, + 3.95000018E-02 , 0.571951866 , 4.08142619E-02 , 2.44024526E-02 , -1.37083633E-02 , 0.175929502 , 0.731940031 , 9.21304747E-02, + 4.05000001E-02 , 0.571787059 , 4.08362262E-02 , 2.44150888E-02 , -1.37231825E-02 , 0.175788775 , 0.731933475 , 9.22777429E-02, + 4.14999984E-02 , 0.571622133 , 4.08580862E-02 , 2.44276691E-02 , -1.37378387E-02 , 0.175645396 , 0.731925189 , 9.24293920E-02, + 4.25000004E-02 , 0.571457267 , 4.08798419E-02 , 2.44401973E-02 , -1.37523329E-02 , 0.175499380 , 0.731915176 , 9.25854519E-02, + 4.34999987E-02 , 0.571292281 , 4.09014896E-02 , 2.44526770E-02 , -1.37666669E-02 , 0.175350726 , 0.731903374 , 9.27459151E-02, + 4.45000008E-02 , 0.571127295 , 4.09230292E-02 , 2.44651064E-02 , -1.37808416E-02 , 0.175199404 , 0.731889784 , 9.29107890E-02, + 4.54999991E-02 , 0.570962250 , 4.09444608E-02 , 2.44774893E-02 , -1.37948571E-02 , 0.175045431 , 0.731874466 , 9.30800810E-02, + 4.65000011E-02 , 0.570797145 , 4.09657806E-02 , 2.44898256E-02 , -1.38087161E-02 , 0.174888805 , 0.731857359 , 9.32538062E-02, + 4.74999994E-02 , 0.570631981 , 4.09869850E-02 , 2.45021190E-02 , -1.38224186E-02 , 0.174729496 , 0.731838524 , 9.34319720E-02, + 4.85000014E-02 , 0.570466816 , 4.10080776E-02 , 2.45143697E-02 , -1.38359666E-02 , 0.174567536 , 0.731817901 , 9.36145708E-02, + 4.94999997E-02 , 0.570301592 , 4.10290547E-02 , 2.45265793E-02 , -1.38493609E-02 , 0.174402878 , 0.731795490 , 9.38016176E-02, + 5.05000018E-02 , 0.570136309 , 4.10499126E-02 , 2.45387498E-02 , -1.38626024E-02 , 0.174235553 , 0.731771350 , 9.39931199E-02, + 5.15000001E-02 , 0.569971025 , 4.10706550E-02 , 2.45508850E-02 , -1.38756940E-02 , 0.174065530 , 0.731745422 , 9.41890776E-02, + 5.24999984E-02 , 0.569805622 , 4.10912707E-02 , 2.45629847E-02 , -1.38886357E-02 , 0.173892811 , 0.731717706 , 9.43894982E-02, + 5.35000004E-02 , 0.569640219 , 4.11117673E-02 , 2.45750509E-02 , -1.39014283E-02 , 0.173717394 , 0.731688201 , 9.45943892E-02, + 5.44999987E-02 , 0.569474757 , 4.11321409E-02 , 2.45870855E-02 , -1.39140757E-02 , 0.173539281 , 0.731656969 , 9.48037580E-02, + 5.55000007E-02 , 0.569309235 , 4.11523841E-02 , 2.45990921E-02 , -1.39265768E-02 , 0.173358455 , 0.731623948 , 9.50176045E-02, + 5.64999990E-02 , 0.569143653 , 4.11725007E-02 , 2.46110708E-02 , -1.39389345E-02 , 0.173174903 , 0.731589139 , 9.52359363E-02, + 5.75000010E-02 , 0.568978012 , 4.11924832E-02 , 2.46230271E-02 , -1.39511507E-02 , 0.172988623 , 0.731552601 , 9.54587534E-02, + 5.84999993E-02 , 0.568812311 , 4.12123352E-02 , 2.46349592E-02 , -1.39632262E-02 , 0.172799632 , 0.731514335 , 9.56860632E-02, + 5.95000014E-02 , 0.568646550 , 4.12320495E-02 , 2.46468727E-02 , -1.39751639E-02 , 0.172607884 , 0.731474280 , 9.59178656E-02, + 6.04999997E-02 , 0.568480730 , 4.12516259E-02 , 2.46587694E-02 , -1.39869656E-02 , 0.172413394 , 0.731432438 , 9.61541682E-02, + 6.15000017E-02 , 0.568314850 , 4.12710607E-02 , 2.46706530E-02 , -1.39986323E-02 , 0.172216147 , 0.731388867 , 9.63949710E-02, + 6.25000000E-02 , 0.568148911 , 4.12903503E-02 , 2.46825255E-02 , -1.40101677E-02 , 0.172016144 , 0.731343567 , 9.66402814E-02, + 6.35000020E-02 , 0.567982912 , 4.13094945E-02 , 2.46943906E-02 , -1.40215736E-02 , 0.171813369 , 0.731296539 , 9.68900993E-02, + 6.44999966E-02 , 0.567816854 , 4.13284861E-02 , 2.47062519E-02 , -1.40328519E-02 , 0.171607807 , 0.731247783 , 9.71444249E-02, + 6.54999986E-02 , 0.567650735 , 4.13473211E-02 , 2.47181114E-02 , -1.40440054E-02 , 0.171399474 , 0.731197238 , 9.74032655E-02, + 6.65000007E-02 , 0.567484558 , 4.13659997E-02 , 2.47299764E-02 , -1.40550369E-02 , 0.171188325 , 0.731145084 , 9.76666138E-02, + 6.75000027E-02 , 0.567318320 , 4.13845181E-02 , 2.47418471E-02 , -1.40659502E-02 , 0.170974374 , 0.731091142 , 9.79344845E-02, + 6.84999973E-02 , 0.567152023 , 4.14028689E-02 , 2.47537289E-02 , -1.40767479E-02 , 0.170757592 , 0.731035531 , 9.82068628E-02, + 6.94999993E-02 , 0.566985607 , 4.14210483E-02 , 2.47656275E-02 , -1.40874321E-02 , 0.170537993 , 0.730978251 , 9.84837636E-02, + 7.05000013E-02 , 0.566819191 , 4.14390527E-02 , 2.47775484E-02 , -1.40980082E-02 , 0.170315534 , 0.730919302 , 9.87651795E-02, + 7.15000033E-02 , 0.566652656 , 4.14568745E-02 , 2.47894935E-02 , -1.41084781E-02 , 0.170090228 , 0.730858624 , 9.90511179E-02, + 7.24999979E-02 , 0.566486061 , 4.14745137E-02 , 2.48014685E-02 , -1.41188465E-02 , 0.169862062 , 0.730796397 , 9.93415713E-02, + 7.34999999E-02 , 0.566319406 , 4.14919592E-02 , 2.48134807E-02 , -1.41291162E-02 , 0.169631004 , 0.730732441 , 9.96365473E-02, + 7.45000020E-02 , 0.566152692 , 4.15092111E-02 , 2.48255339E-02 , -1.41392928E-02 , 0.169397056 , 0.730666876 , 9.99360383E-02, + 7.54999965E-02 , 0.565985858 , 4.15262580E-02 , 2.48376355E-02 , -1.41493799E-02 , 0.169160202 , 0.730599761 , 0.100240052 , + 7.64999986E-02 , 0.565818965 , 4.15431000E-02 , 2.48497911E-02 , -1.41593814E-02 , 0.168920428 , 0.730530977 , 0.100548580 , + 7.75000006E-02 , 0.565652013 , 4.15597260E-02 , 2.48620044E-02 , -1.41693018E-02 , 0.168677703 , 0.730460644 , 0.100861631 , + 7.85000026E-02 , 0.565485001 , 4.15761322E-02 , 2.48742830E-02 , -1.41791450E-02 , 0.168432042 , 0.730388761 , 0.101179205 , + 7.94999972E-02 , 0.565317869 , 4.15923111E-02 , 2.48866342E-02 , -1.41889164E-02 , 0.168183401 , 0.730315328 , 0.101501293 , + 8.04999992E-02 , 0.565150678 , 4.16082591E-02 , 2.48990618E-02 , -1.41986208E-02 , 0.167931795 , 0.730240285 , 0.101827897 , + 8.15000013E-02 , 0.564983428 , 4.16239686E-02 , 2.49115750E-02 , -1.42082619E-02 , 0.167677179 , 0.730163813 , 0.102159023 , + 8.25000033E-02 , 0.564816058 , 4.16394323E-02 , 2.49241758E-02 , -1.42178452E-02 , 0.167419568 , 0.730085790 , 0.102494672 , + 8.34999979E-02 , 0.564648628 , 4.16546427E-02 , 2.49368753E-02 , -1.42273735E-02 , 0.167158917 , 0.730006218 , 0.102834836 , + 8.44999999E-02 , 0.564481139 , 4.16695997E-02 , 2.49496773E-02 , -1.42368525E-02 , 0.166895241 , 0.729925215 , 0.103179514 , + 8.55000019E-02 , 0.564313531 , 4.16842923E-02 , 2.49625854E-02 , -1.42462859E-02 , 0.166628510 , 0.729842782 , 0.103528716 , + 8.64999965E-02 , 0.564145863 , 4.16987166E-02 , 2.49756072E-02 , -1.42556773E-02 , 0.166358709 , 0.729758859 , 0.103882439 , + 8.74999985E-02 , 0.563978076 , 4.17128652E-02 , 2.49887481E-02 , -1.42650316E-02 , 0.166085824 , 0.729673505 , 0.104240686 , + 8.85000005E-02 , 0.563810229 , 4.17267382E-02 , 2.50020120E-02 , -1.42743504E-02 , 0.165809840 , 0.729586720 , 0.104603447 , + 8.95000026E-02 , 0.563642263 , 4.17403281E-02 , 2.50154026E-02 , -1.42836375E-02 , 0.165530771 , 0.729498506 , 0.104970731 , + 9.04999971E-02 , 0.563474238 , 4.17536348E-02 , 2.50289254E-02 , -1.42928958E-02 , 0.165248573 , 0.729408920 , 0.105342537 , + 9.14999992E-02 , 0.563306153 , 4.17666472E-02 , 2.50425823E-02 , -1.43021280E-02 , 0.164963245 , 0.729317904 , 0.105718873 , + 9.25000012E-02 , 0.563137949 , 4.17793691E-02 , 2.50563771E-02 , -1.43113350E-02 , 0.164674789 , 0.729225457 , 0.106099732 , + 9.35000032E-02 , 0.562969625 , 4.17917967E-02 , 2.50703096E-02 , -1.43205188E-02 , 0.164383188 , 0.729131699 , 0.106485114 , + 9.44999978E-02 , 0.562801242 , 4.18039300E-02 , 2.50843819E-02 , -1.43296793E-02 , 0.164088428 , 0.729036570 , 0.106875025 , + 9.54999998E-02 , 0.562632799 , 4.18157689E-02 , 2.50985958E-02 , -1.43388184E-02 , 0.163790509 , 0.728940010 , 0.107269473 , + 9.65000018E-02 , 0.562464178 , 4.18273099E-02 , 2.51129512E-02 , -1.43479342E-02 , 0.163489416 , 0.728842139 , 0.107668452 , + 9.74999964E-02 , 0.562295556 , 4.18385565E-02 , 2.51274444E-02 , -1.43570267E-02 , 0.163185149 , 0.728742898 , 0.108071961 , + 9.84999985E-02 , 0.562126756 , 4.18495089E-02 , 2.51420774E-02 , -1.43660940E-02 , 0.162877724 , 0.728642285 , 0.108480006 , + 9.95000005E-02 , 0.561957896 , 4.18601707E-02 , 2.51568444E-02 , -1.43751344E-02 , 0.162567109 , 0.728540301 , 0.108892590 , + 0.100500003 , 0.561788917 , 4.18705493E-02 , 2.51717456E-02 , -1.43841449E-02 , 0.162253320 , 0.728436947 , 0.109309711 , + 0.101499997 , 0.561619878 , 4.18806411E-02 , 2.51867734E-02 , -1.43931238E-02 , 0.161936343 , 0.728332281 , 0.109731369 , + 0.102499999 , 0.561450660 , 4.18904535E-02 , 2.52019260E-02 , -1.44020654E-02 , 0.161616191 , 0.728226244 , 0.110157572 , + 0.103500001 , 0.561281383 , 4.18999940E-02 , 2.52171978E-02 , -1.44109679E-02 , 0.161292851 , 0.728118837 , 0.110588312 , + 0.104500003 , 0.561111987 , 4.19092700E-02 , 2.52325814E-02 , -1.44198257E-02 , 0.160966352 , 0.728010058 , 0.111023597 , + 0.105499998 , 0.560942531 , 4.19182815E-02 , 2.52480730E-02 , -1.44286342E-02 , 0.160636663 , 0.727899909 , 0.111463428 , + 0.106500000 , 0.560772896 , 4.19270396E-02 , 2.52636634E-02 , -1.44373877E-02 , 0.160303816 , 0.727788389 , 0.111907795 , + 0.107500002 , 0.560603201 , 4.19355519E-02 , 2.52793469E-02 , -1.44460816E-02 , 0.159967795 , 0.727675498 , 0.112356707 , + 0.108499996 , 0.560433328 , 4.19438221E-02 , 2.52951160E-02 , -1.44547094E-02 , 0.159628630 , 0.727561235 , 0.112810157 , + 0.109499998 , 0.560263395 , 4.19518650E-02 , 2.53109634E-02 , -1.44632664E-02 , 0.159286290 , 0.727445543 , 0.113268152 , + 0.110500000 , 0.560093284 , 4.19596806E-02 , 2.53268816E-02 , -1.44717460E-02 , 0.158940807 , 0.727328479 , 0.113730676 , + 0.111500002 , 0.559923112 , 4.19672839E-02 , 2.53428612E-02 , -1.44801419E-02 , 0.158592194 , 0.727210045 , 0.114197746 , + 0.112499997 , 0.559752762 , 4.19746749E-02 , 2.53588986E-02 , -1.44884493E-02 , 0.158240438 , 0.727090240 , 0.114669345 , + 0.113499999 , 0.559582293 , 4.19818684E-02 , 2.53749806E-02 , -1.44966627E-02 , 0.157885551 , 0.726969004 , 0.115145475 , + 0.114500001 , 0.559411705 , 4.19888683E-02 , 2.53911037E-02 , -1.45047745E-02 , 0.157527551 , 0.726846337 , 0.115626127 , + 0.115500003 , 0.559240997 , 4.19956855E-02 , 2.54072603E-02 , -1.45127801E-02 , 0.157166421 , 0.726722240 , 0.116111316 , + 0.116499998 , 0.559070170 , 4.20023203E-02 , 2.54234429E-02 , -1.45206749E-02 , 0.156802192 , 0.726596773 , 0.116601013 , + 0.117500000 , 0.558899164 , 4.20087874E-02 , 2.54396442E-02 , -1.45284534E-02 , 0.156434864 , 0.726469874 , 0.117095232 , + 0.118500002 , 0.558728039 , 4.20150906E-02 , 2.54558586E-02 , -1.45361116E-02 , 0.156064436 , 0.726341605 , 0.117593966 , + 0.119499996 , 0.558556795 , 4.20212336E-02 , 2.54720822E-02 , -1.45436432E-02 , 0.155690923 , 0.726211846 , 0.118097201 , + 0.120499998 , 0.558385372 , 4.20272239E-02 , 2.54883058E-02 , -1.45510444E-02 , 0.155314341 , 0.726080716 , 0.118604943 , + 0.121500000 , 0.558213770 , 4.20330651E-02 , 2.55045276E-02 , -1.45583125E-02 , 0.154934675 , 0.725948155 , 0.119117178 , + 0.122500002 , 0.558042049 , 4.20387648E-02 , 2.55207419E-02 , -1.45654436E-02 , 0.154551938 , 0.725814164 , 0.119633906 , + 0.123499997 , 0.557870209 , 4.20443267E-02 , 2.55369432E-02 , -1.45724332E-02 , 0.154166147 , 0.725678742 , 0.120155126 , + 0.124499999 , 0.557698190 , 4.20497544E-02 , 2.55531278E-02 , -1.45792784E-02 , 0.153777301 , 0.725541890 , 0.120680816 , + 0.125499994 , 0.557525992 , 4.20550518E-02 , 2.55692918E-02 , -1.45859765E-02 , 0.153385401 , 0.725403607 , 0.121210985 , + 0.126499996 , 0.557353675 , 4.20602225E-02 , 2.55854335E-02 , -1.45925246E-02 , 0.152990445 , 0.725263953 , 0.121745616 , + 0.127499998 , 0.557181180 , 4.20652702E-02 , 2.56015491E-02 , -1.45989209E-02 , 0.152592465 , 0.725122809 , 0.122284710 , + 0.128500000 , 0.557008505 , 4.20701988E-02 , 2.56176349E-02 , -1.46051617E-02 , 0.152191460 , 0.724980295 , 0.122828253 , + 0.129500002 , 0.556835651 , 4.20750119E-02 , 2.56336872E-02 , -1.46112461E-02 , 0.151787415 , 0.724836349 , 0.123376250 , + 0.130500004 , 0.556662619 , 4.20797132E-02 , 2.56497059E-02 , -1.46171711E-02 , 0.151380345 , 0.724690974 , 0.123928681 , + 0.131500006 , 0.556489468 , 4.20842990E-02 , 2.56656855E-02 , -1.46229351E-02 , 0.150970280 , 0.724544168 , 0.124485545 , + 0.132499993 , 0.556316078 , 4.20887768E-02 , 2.56816279E-02 , -1.46285370E-02 , 0.150557190 , 0.724395990 , 0.125046834 , + 0.133499995 , 0.556142569 , 4.20931503E-02 , 2.56975275E-02 , -1.46339731E-02 , 0.150141105 , 0.724246383 , 0.125612542 , + 0.134499997 , 0.555968821 , 4.20974195E-02 , 2.57133823E-02 , -1.46392426E-02 , 0.149722025 , 0.724095345 , 0.126182646 , + 0.135499999 , 0.555794954 , 4.21015881E-02 , 2.57291906E-02 , -1.46443443E-02 , 0.149299949 , 0.723942876 , 0.126757160 , + 0.136500001 , 0.555620849 , 4.21056561E-02 , 2.57449523E-02 , -1.46492757E-02 , 0.148874894 , 0.723789036 , 0.127336055 , + 0.137500003 , 0.555446565 , 4.21096273E-02 , 2.57606637E-02 , -1.46540357E-02 , 0.148446858 , 0.723633826 , 0.127919346 , + 0.138500005 , 0.555272102 , 4.21135016E-02 , 2.57763229E-02 , -1.46586224E-02 , 0.148015857 , 0.723477125 , 0.128507003 , + 0.139500007 , 0.555097401 , 4.21172827E-02 , 2.57919300E-02 , -1.46630351E-02 , 0.147581875 , 0.723319113 , 0.129099011 , + 0.140499994 , 0.554922581 , 4.21209745E-02 , 2.58074813E-02 , -1.46672716E-02 , 0.147144958 , 0.723159671 , 0.129695386 , + 0.141499996 , 0.554747462 , 4.21245769E-02 , 2.58229747E-02 , -1.46713303E-02 , 0.146705076 , 0.722998798 , 0.130296111 , + 0.142499998 , 0.554572225 , 4.21280898E-02 , 2.58384105E-02 , -1.46752102E-02 , 0.146262258 , 0.722836554 , 0.130901158 , + 0.143500000 , 0.554396749 , 4.21315171E-02 , 2.58537866E-02 , -1.46789113E-02 , 0.145816505 , 0.722672939 , 0.131510541 , + 0.144500002 , 0.554221034 , 4.21348624E-02 , 2.58691013E-02 , -1.46824298E-02 , 0.145367816 , 0.722507954 , 0.132124230 , + 0.145500004 , 0.554045141 , 4.21381257E-02 , 2.58843526E-02 , -1.46857658E-02 , 0.144916207 , 0.722341537 , 0.132742241 , + 0.146500006 , 0.553869009 , 4.21413071E-02 , 2.58995406E-02 , -1.46889184E-02 , 0.144461691 , 0.722173810 , 0.133364528 , + 0.147499993 , 0.553692698 , 4.21444103E-02 , 2.59146634E-02 , -1.46918865E-02 , 0.144004270 , 0.722004652 , 0.133991092 , + 0.148499995 , 0.553516090 , 4.21474315E-02 , 2.59297192E-02 , -1.46946684E-02 , 0.143543944 , 0.721834123 , 0.134621933 , + 0.149499997 , 0.553339303 , 4.21503820E-02 , 2.59447079E-02 , -1.46972630E-02 , 0.143080726 , 0.721662223 , 0.135257050 , + 0.150500000 , 0.553162277 , 4.21532542E-02 , 2.59596296E-02 , -1.46996705E-02 , 0.142614633 , 0.721488953 , 0.135896400 , + 0.151500002 , 0.552985013 , 4.21560518E-02 , 2.59744786E-02 , -1.47018880E-02 , 0.142145663 , 0.721314371 , 0.136539981 , + 0.152500004 , 0.552807570 , 4.21587788E-02 , 2.59892587E-02 , -1.47039173E-02 , 0.141673833 , 0.721138358 , 0.137187794 , + 0.153500006 , 0.552629828 , 4.21614349E-02 , 2.60039680E-02 , -1.47057548E-02 , 0.141199127 , 0.720961034 , 0.137839824 , + 0.154499993 , 0.552451849 , 4.21640202E-02 , 2.60186046E-02 , -1.47074014E-02 , 0.140721589 , 0.720782340 , 0.138496056 , + 0.155499995 , 0.552273631 , 4.21665348E-02 , 2.60331687E-02 , -1.47088561E-02 , 0.140241206 , 0.720602334 , 0.139156476 , + 0.156499997 , 0.552095175 , 4.21689823E-02 , 2.60476582E-02 , -1.47101181E-02 , 0.139757991 , 0.720420957 , 0.139821067 , + 0.157499999 , 0.551916420 , 4.21713628E-02 , 2.60620750E-02 , -1.47111872E-02 , 0.139271945 , 0.720238209 , 0.140489817 , + 0.158500001 , 0.551737428 , 4.21736762E-02 , 2.60764156E-02 , -1.47120617E-02 , 0.138783082 , 0.720054209 , 0.141162723 , + 0.159500003 , 0.551558197 , 4.21759263E-02 , 2.60906816E-02 , -1.47127407E-02 , 0.138291419 , 0.719868779 , 0.141839772 , + 0.160500005 , 0.551378667 , 4.21781093E-02 , 2.61048712E-02 , -1.47132259E-02 , 0.137796968 , 0.719682097 , 0.142520949 , + 0.161500007 , 0.551198900 , 4.21802290E-02 , 2.61189863E-02 , -1.47135137E-02 , 0.137299716 , 0.719494045 , 0.143206224 , + 0.162499994 , 0.551018834 , 4.21822853E-02 , 2.61330232E-02 , -1.47136068E-02 , 0.136799678 , 0.719304740 , 0.143895596 , + 0.163499996 , 0.550838530 , 4.21842821E-02 , 2.61469819E-02 , -1.47135016E-02 , 0.136296883 , 0.719114065 , 0.144589067 , + 0.164499998 , 0.550657928 , 4.21862155E-02 , 2.61608642E-02 , -1.47131998E-02 , 0.135791332 , 0.718922079 , 0.145286590 , + 0.165500000 , 0.550477028 , 4.21880856E-02 , 2.61746701E-02 , -1.47127006E-02 , 0.135283023 , 0.718728781 , 0.145988181 , + 0.166500002 , 0.550295889 , 4.21898961E-02 , 2.61883959E-02 , -1.47120031E-02 , 0.134771973 , 0.718534231 , 0.146693811 , + 0.167500004 , 0.550114393 , 4.21916507E-02 , 2.62020454E-02 , -1.47111062E-02 , 0.134258181 , 0.718338370 , 0.147403464 , + 0.168500006 , 0.549932659 , 4.21933420E-02 , 2.62156148E-02 , -1.47100110E-02 , 0.133741677 , 0.718141198 , 0.148117140 , + 0.169499993 , 0.549750566 , 4.21949774E-02 , 2.62291078E-02 , -1.47087174E-02 , 0.133222461 , 0.717942715 , 0.148834810 , + 0.170499995 , 0.549568236 , 4.21965532E-02 , 2.62425207E-02 , -1.47072235E-02 , 0.132700548 , 0.717742980 , 0.149556458 , + 0.171499997 , 0.549385548 , 4.21980694E-02 , 2.62558535E-02 , -1.47055294E-02 , 0.132175937 , 0.717541993 , 0.150282085 , + 0.172499999 , 0.549202561 , 4.21995334E-02 , 2.62691099E-02 , -1.47036361E-02 , 0.131648645 , 0.717339694 , 0.151011661 , + 0.173500001 , 0.549019277 , 4.22009379E-02 , 2.62822863E-02 , -1.47015424E-02 , 0.131118685 , 0.717136145 , 0.151745170 , + 0.174500003 , 0.548835695 , 4.22022827E-02 , 2.62953825E-02 , -1.46992477E-02 , 0.130586058 , 0.716931343 , 0.152482614 , + 0.175500005 , 0.548651755 , 4.22035754E-02 , 2.63084024E-02 , -1.46967527E-02 , 0.130050778 , 0.716725290 , 0.153223962 , + 0.176499993 , 0.548467457 , 4.22048122E-02 , 2.63213422E-02 , -1.46940565E-02 , 0.129512861 , 0.716517925 , 0.153969198 , + 0.177499995 , 0.548282862 , 4.22059931E-02 , 2.63342019E-02 , -1.46911591E-02 , 0.128972322 , 0.716309369 , 0.154718310 , + 0.178499997 , 0.548097968 , 4.22071218E-02 , 2.63469853E-02 , -1.46880616E-02 , 0.128429160 , 0.716099560 , 0.155471295 , + 0.179499999 , 0.547912657 , 4.22081910E-02 , 2.63596885E-02 , -1.46847609E-02 , 0.127883375 , 0.715888500 , 0.156228110 , + 0.180500001 , 0.547727048 , 4.22092117E-02 , 2.63723135E-02 , -1.46812601E-02 , 0.127335012 , 0.715676248 , 0.156988755 , + 0.181500003 , 0.547541082 , 4.22101729E-02 , 2.63848603E-02 , -1.46775572E-02 , 0.126784056 , 0.715462744 , 0.157753214 , + 0.182500005 , 0.547354758 , 4.22110856E-02 , 2.63973288E-02 , -1.46736521E-02 , 0.126230523 , 0.715247989 , 0.158521473 , + 0.183500007 , 0.547168076 , 4.22119386E-02 , 2.64097210E-02 , -1.46695459E-02 , 0.125674441 , 0.715032041 , 0.159293503 , + 0.184499994 , 0.546981037 , 4.22127433E-02 , 2.64220331E-02 , -1.46652376E-02 , 0.125115797 , 0.714814901 , 0.160069302 , + 0.185499996 , 0.546793640 , 4.22134921E-02 , 2.64342688E-02 , -1.46607272E-02 , 0.124554612 , 0.714596570 , 0.160848841 , + 0.186499998 , 0.546605825 , 4.22141925E-02 , 2.64464281E-02 , -1.46560147E-02 , 0.123990893 , 0.714376986 , 0.161632121 , + 0.187500000 , 0.546417654 , 4.22148369E-02 , 2.64585093E-02 , -1.46511002E-02 , 0.123424664 , 0.714156270 , 0.162419096 , + 0.188500002 , 0.546229124 , 4.22154292E-02 , 2.64705140E-02 , -1.46459844E-02 , 0.122855924 , 0.713934302 , 0.163209766 , + 0.189500004 , 0.546040177 , 4.22159694E-02 , 2.64824443E-02 , -1.46406656E-02 , 0.122284696 , 0.713711202 , 0.164004117 , + 0.190500006 , 0.545850873 , 4.22164537E-02 , 2.64942963E-02 , -1.46351457E-02 , 0.121710978 , 0.713486910 , 0.164802134 , + 0.191499993 , 0.545661151 , 4.22168896E-02 , 2.65060738E-02 , -1.46294227E-02 , 0.121134795 , 0.713261425 , 0.165603787 , + 0.192499995 , 0.545471013 , 4.22172733E-02 , 2.65177749E-02 , -1.46234985E-02 , 0.120556153 , 0.713034809 , 0.166409060 , + 0.193499997 , 0.545280516 , 4.22176085E-02 , 2.65294015E-02 , -1.46173723E-02 , 0.119975068 , 0.712807000 , 0.167217940 , + 0.194499999 , 0.545089543 , 4.22178879E-02 , 2.65409537E-02 , -1.46110430E-02 , 0.119391546 , 0.712578058 , 0.168030411 , + 0.195500001 , 0.544898212 , 4.22181152E-02 , 2.65524331E-02 , -1.46045135E-02 , 0.118805602 , 0.712347925 , 0.168846458 , + 0.196500003 , 0.544706464 , 4.22182940E-02 , 2.65638363E-02 , -1.45977810E-02 , 0.118217252 , 0.712116718 , 0.169666052 , + 0.197500005 , 0.544514239 , 4.22184207E-02 , 2.65751686E-02 , -1.45908464E-02 , 0.117626503 , 0.711884320 , 0.170489177 , + 0.198500007 , 0.544321597 , 4.22184952E-02 , 2.65864264E-02 , -1.45837115E-02 , 0.117033370 , 0.711650848 , 0.171315819 , + 0.199499995 , 0.544128537 , 4.22185212E-02 , 2.65976116E-02 , -1.45763736E-02 , 0.116437860 , 0.711416185 , 0.172145948 , + 0.200499997 , 0.543935001 , 4.22184914E-02 , 2.66087260E-02 , -1.45688346E-02 , 0.115840003 , 0.711180449 , 0.172979563 , + 0.201499999 , 0.543741047 , 4.22184132E-02 , 2.66197678E-02 , -1.45610943E-02 , 0.115239792 , 0.710943580 , 0.173816636 , + 0.202500001 , 0.543546617 , 4.22182865E-02 , 2.66307388E-02 , -1.45531520E-02 , 0.114637248 , 0.710705578 , 0.174657151 , + 0.203500003 , 0.543351769 , 4.22181077E-02 , 2.66416389E-02 , -1.45450085E-02 , 0.114032388 , 0.710466564 , 0.175501078 , + 0.204500005 , 0.543156445 , 4.22178768E-02 , 2.66524702E-02 , -1.45366648E-02 , 0.113425218 , 0.710226357 , 0.176348418 , + 0.205500007 , 0.542960644 , 4.22175936E-02 , 2.66632307E-02 , -1.45281190E-02 , 0.112815753 , 0.709985137 , 0.177199125 , + 0.206499994 , 0.542764366 , 4.22172621E-02 , 2.66739223E-02 , -1.45193730E-02 , 0.112204015 , 0.709742785 , 0.178053215 , + 0.207499996 , 0.542567611 , 4.22168784E-02 , 2.66845450E-02 , -1.45104248E-02 , 0.111589998 , 0.709499359 , 0.178910628 , + 0.208499998 , 0.542370319 , 4.22164463E-02 , 2.66951006E-02 , -1.45012774E-02 , 0.110973738 , 0.709254861 , 0.179771379 , + 0.209500000 , 0.542172611 , 4.22159620E-02 , 2.67055873E-02 , -1.44919287E-02 , 0.110355228 , 0.709009349 , 0.180635437 , + 0.210500002 , 0.541974366 , 4.22154255E-02 , 2.67160088E-02 , -1.44823790E-02 , 0.109734498 , 0.708762705 , 0.181502774 , + 0.211500004 , 0.541775644 , 4.22148407E-02 , 2.67263632E-02 , -1.44726299E-02 , 0.109111555 , 0.708515048 , 0.182373375 , + 0.212500006 , 0.541576385 , 4.22142036E-02 , 2.67366506E-02 , -1.44626806E-02 , 0.108486407 , 0.708266377 , 0.183247223 , + 0.213499993 , 0.541376650 , 4.22135182E-02 , 2.67468747E-02 , -1.44525301E-02 , 0.107859075 , 0.708016634 , 0.184124291 , + 0.214499995 , 0.541176379 , 4.22127806E-02 , 2.67570335E-02 , -1.44421812E-02 , 0.107229568 , 0.707765877 , 0.185004577 , + 0.215499997 , 0.540975571 , 4.22119945E-02 , 2.67671291E-02 , -1.44316312E-02 , 0.106597908 , 0.707514048 , 0.185888037 , + 0.216499999 , 0.540774226 , 4.22111526E-02 , 2.67771594E-02 , -1.44208828E-02 , 0.105964102 , 0.707261264 , 0.186774656 , + 0.217500001 , 0.540572345 , 4.22102660E-02 , 2.67871283E-02 , -1.44099342E-02 , 0.105328165 , 0.707007408 , 0.187664434 , + 0.218500003 , 0.540369928 , 4.22093272E-02 , 2.67970338E-02 , -1.43987862E-02 , 0.104690112 , 0.706752539 , 0.188557327 , + 0.219500005 , 0.540166974 , 4.22083363E-02 , 2.68068779E-02 , -1.43874399E-02 , 0.104049951 , 0.706496716 , 0.189453319 , + 0.220500007 , 0.539963424 , 4.22072932E-02 , 2.68166624E-02 , -1.43758943E-02 , 0.103407711 , 0.706239879 , 0.190352395 , + 0.221499994 , 0.539759338 , 4.22062017E-02 , 2.68263854E-02 , -1.43641494E-02 , 0.102763392 , 0.705982089 , 0.191254541 , + 0.222499996 , 0.539554715 , 4.22050618E-02 , 2.68360488E-02 , -1.43522071E-02 , 0.102117017 , 0.705723286 , 0.192159727 , + 0.223499998 , 0.539349496 , 4.22038659E-02 , 2.68456545E-02 , -1.43400654E-02 , 0.101468593 , 0.705463469 , 0.193067923 , + 0.224500000 , 0.539143682 , 4.22026254E-02 , 2.68552005E-02 , -1.43277254E-02 , 0.100818135 , 0.705202758 , 0.193979114 , + 0.225500003 , 0.538937271 , 4.22013290E-02 , 2.68646888E-02 , -1.43151879E-02 , 0.100165673 , 0.704941034 , 0.194893301 , + 0.226500005 , 0.538730264 , 4.21999842E-02 , 2.68741194E-02 , -1.43024521E-02 , 9.95111987E-02 , 0.704678357 , 0.195810437 , + 0.227500007 , 0.538522661 , 4.21985872E-02 , 2.68834941E-02 , -1.42895188E-02 , 9.88547429E-02 , 0.704414785 , 0.196730494 , + 0.228499994 , 0.538314521 , 4.21971418E-02 , 2.68928129E-02 , -1.42763881E-02 , 9.81963128E-02 , 0.704150200 , 0.197653487 , + 0.229499996 , 0.538105667 , 4.21956442E-02 , 2.69020777E-02 , -1.42630599E-02 , 9.75359231E-02 , 0.703884721 , 0.198579356 , + 0.230499998 , 0.537896276 , 4.21940945E-02 , 2.69112866E-02 , -1.42495343E-02 , 9.68735963E-02 , 0.703618288 , 0.199508101 , + 0.231500000 , 0.537686229 , 4.21924964E-02 , 2.69204434E-02 , -1.42358113E-02 , 9.62093398E-02 , 0.703350961 , 0.200439692 , + 0.232500002 , 0.537475526 , 4.21908461E-02 , 2.69295461E-02 , -1.42218927E-02 , 9.55431685E-02 , 0.703082740 , 0.201374114 , + 0.233500004 , 0.537264168 , 4.21891436E-02 , 2.69385949E-02 , -1.42077766E-02 , 9.48751047E-02 , 0.702813566 , 0.202311352 , + 0.234500006 , 0.537052214 , 4.21873927E-02 , 2.69475952E-02 , -1.41934641E-02 , 9.42051560E-02 , 0.702543497 , 0.203251362 , + 0.235499993 , 0.536839604 , 4.21855897E-02 , 2.69565415E-02 , -1.41789550E-02 , 9.35333371E-02 , 0.702272534 , 0.204194129 , + 0.236499995 , 0.536626339 , 4.21837345E-02 , 2.69654393E-02 , -1.41642503E-02 , 9.28596705E-02 , 0.702000678 , 0.205139652 , + 0.237499997 , 0.536412358 , 4.21818309E-02 , 2.69742869E-02 , -1.41493501E-02 , 9.21841636E-02 , 0.701727986 , 0.206087872 , + 0.238499999 , 0.536197782 , 4.21798714E-02 , 2.69830860E-02 , -1.41342534E-02 , 9.15068388E-02 , 0.701454341 , 0.207038805 , + 0.239500001 , 0.535982430 , 4.21778634E-02 , 2.69918367E-02 , -1.41189611E-02 , 9.08277035E-02 , 0.701179922 , 0.207992405 , + 0.240500003 , 0.535766482 , 4.21758071E-02 , 2.70005409E-02 , -1.41034732E-02 , 9.01467726E-02 , 0.700904548 , 0.208948657 , + 0.241500005 , 0.535549819 , 4.21736948E-02 , 2.70091966E-02 , -1.40877906E-02 , 8.94640759E-02 , 0.700628400 , 0.209907547 , + 0.242500007 , 0.535332441 , 4.21715342E-02 , 2.70178076E-02 , -1.40719134E-02 , 8.87796134E-02 , 0.700351357 , 0.210869029 , + 0.243499994 , 0.535114348 , 4.21693213E-02 , 2.70263720E-02 , -1.40558407E-02 , 8.80934075E-02 , 0.700073481 , 0.211833104 , + 0.244499996 , 0.534895539 , 4.21670564E-02 , 2.70348936E-02 , -1.40395733E-02 , 8.74054730E-02 , 0.699794769 , 0.212799743 , + 0.245499998 , 0.534676015 , 4.21647392E-02 , 2.70433705E-02 , -1.40231112E-02 , 8.67158249E-02 , 0.699515283 , 0.213768914 , + 0.246500000 , 0.534455717 , 4.21623737E-02 , 2.70518046E-02 , -1.40064554E-02 , 8.60244855E-02 , 0.699234903 , 0.214740604 , + 0.247500002 , 0.534234762 , 4.21599559E-02 , 2.70601958E-02 , -1.39896050E-02 , 8.53314549E-02 , 0.698953748 , 0.215714797 , + 0.248500004 , 0.534013033 , 4.21574824E-02 , 2.70685460E-02 , -1.39725609E-02 , 8.46367627E-02 , 0.698671758 , 0.216691449 , + 0.249500006 , 0.533790529 , 4.21549603E-02 , 2.70768553E-02 , -1.39553221E-02 , 8.39404240E-02 , 0.698389053 , 0.217670560 , + 0.250499994 , 0.533567309 , 4.21523899E-02 , 2.70851254E-02 , -1.39378905E-02 , 8.32424462E-02 , 0.698105454 , 0.218652084 , + 0.251500010 , 0.533343315 , 4.21497636E-02 , 2.70933546E-02 , -1.39202652E-02 , 8.25428441E-02 , 0.697821140 , 0.219636023 , + 0.252499998 , 0.533118486 , 4.21470851E-02 , 2.71015447E-02 , -1.39024463E-02 , 8.18416476E-02 , 0.697536051 , 0.220622331 , + 0.253500015 , 0.532892942 , 4.21443544E-02 , 2.71096993E-02 , -1.38844345E-02 , 8.11388642E-02 , 0.697250128 , 0.221610993 , + 0.254500002 , 0.532666624 , 4.21415754E-02 , 2.71178149E-02 , -1.38662299E-02 , 8.04345086E-02 , 0.696963489 , 0.222601995 , + 0.255499989 , 0.532439470 , 4.21387404E-02 , 2.71258950E-02 , -1.38478316E-02 , 7.97285959E-02 , 0.696676075 , 0.223595306 , + 0.256500006 , 0.532211542 , 4.21358570E-02 , 2.71339398E-02 , -1.38292415E-02 , 7.90211484E-02 , 0.696387947 , 0.224590912 , + 0.257499993 , 0.531982780 , 4.21329178E-02 , 2.71419492E-02 , -1.38104586E-02 , 7.83121809E-02 , 0.696099043 , 0.225588784 , + 0.258500010 , 0.531753182 , 4.21299301E-02 , 2.71499250E-02 , -1.37914829E-02 , 7.76017085E-02 , 0.695809424 , 0.226588875 , + 0.259499997 , 0.531522810 , 4.21268865E-02 , 2.71578673E-02 , -1.37723153E-02 , 7.68897384E-02 , 0.695519030 , 0.227591202 , + 0.260500014 , 0.531291544 , 4.21237908E-02 , 2.71657761E-02 , -1.37529559E-02 , 7.61763006E-02 , 0.695227981 , 0.228595719 , + 0.261500001 , 0.531059504 , 4.21206467E-02 , 2.71736551E-02 , -1.37334038E-02 , 7.54614100E-02 , 0.694936216 , 0.229602396 , + 0.262499988 , 0.530826569 , 4.21174467E-02 , 2.71815024E-02 , -1.37136597E-02 , 7.47450739E-02 , 0.694643676 , 0.230611220 , + 0.263500005 , 0.530592799 , 4.21141945E-02 , 2.71893200E-02 , -1.36937248E-02 , 7.40273148E-02 , 0.694350481 , 0.231622174 , + 0.264499992 , 0.530358136 , 4.21108902E-02 , 2.71971077E-02 , -1.36735979E-02 , 7.33081475E-02 , 0.694056630 , 0.232635230 , + 0.265500009 , 0.530122638 , 4.21075337E-02 , 2.72048656E-02 , -1.36532793E-02 , 7.25875869E-02 , 0.693762064 , 0.233650357 , + 0.266499996 , 0.529886246 , 4.21041250E-02 , 2.72125974E-02 , -1.36327697E-02 , 7.18656555E-02 , 0.693466783 , 0.234667540 , + 0.267500013 , 0.529648960 , 4.21006605E-02 , 2.72203013E-02 , -1.36120692E-02 , 7.11423680E-02 , 0.693170905 , 0.235686749 , + 0.268500000 , 0.529410779 , 4.20971438E-02 , 2.72279792E-02 , -1.35911768E-02 , 7.04177320E-02 , 0.692874312 , 0.236707956 , + 0.269499987 , 0.529171705 , 4.20935750E-02 , 2.72356328E-02 , -1.35700945E-02 , 6.96917772E-02 , 0.692577064 , 0.237731144 , + 0.270500004 , 0.528931737 , 4.20899540E-02 , 2.72432603E-02 , -1.35488203E-02 , 6.89645112E-02 , 0.692279220 , 0.238756284 , + 0.271499991 , 0.528690815 , 4.20862809E-02 , 2.72508636E-02 , -1.35273561E-02 , 6.82359561E-02 , 0.691980660 , 0.239783362 , + 0.272500008 , 0.528448939 , 4.20825519E-02 , 2.72584446E-02 , -1.35057010E-02 , 6.75061271E-02 , 0.691681504 , 0.240812346 , + 0.273499995 , 0.528206170 , 4.20787707E-02 , 2.72660032E-02 , -1.34838549E-02 , 6.67750388E-02 , 0.691381752 , 0.241843224 , + 0.274500012 , 0.527962446 , 4.20749336E-02 , 2.72735413E-02 , -1.34618189E-02 , 6.60427138E-02 , 0.691081345 , 0.242875949 , + 0.275500000 , 0.527717769 , 4.20710482E-02 , 2.72810571E-02 , -1.34395920E-02 , 6.53091595E-02 , 0.690780342 , 0.243910506 , + 0.276499987 , 0.527472138 , 4.20671031E-02 , 2.72885542E-02 , -1.34171750E-02 , 6.45743981E-02 , 0.690478742 , 0.244946882 , + 0.277500004 , 0.527225554 , 4.20631096E-02 , 2.72960309E-02 , -1.33945681E-02 , 6.38384521E-02 , 0.690176487 , 0.245985046 , + 0.278499991 , 0.526977956 , 4.20590565E-02 , 2.73034889E-02 , -1.33717712E-02 , 6.31013289E-02 , 0.689873695 , 0.247024968 , + 0.279500008 , 0.526729345 , 4.20549549E-02 , 2.73109321E-02 , -1.33487834E-02 , 6.23630472E-02 , 0.689570308 , 0.248066634 , + 0.280499995 , 0.526479781 , 4.20507975E-02 , 2.73183566E-02 , -1.33256065E-02 , 6.16236292E-02 , 0.689266384 , 0.249110013 , + 0.281500012 , 0.526229262 , 4.20465842E-02 , 2.73257643E-02 , -1.33022396E-02 , 6.08830862E-02 , 0.688961864 , 0.250155061 , + 0.282499999 , 0.525977671 , 4.20423187E-02 , 2.73331590E-02 , -1.32786818E-02 , 6.01414405E-02 , 0.688656747 , 0.251201808 , + 0.283499986 , 0.525725067 , 4.20379974E-02 , 2.73405369E-02 , -1.32549349E-02 , 5.93987070E-02 , 0.688351154 , 0.252250165 , + 0.284500003 , 0.525471449 , 4.20336202E-02 , 2.73479037E-02 , -1.32309990E-02 , 5.86549044E-02 , 0.688044965 , 0.253300160 , + 0.285499990 , 0.525216758 , 4.20291908E-02 , 2.73552556E-02 , -1.32068722E-02 , 5.79100475E-02 , 0.687738240 , 0.254351735 , + 0.286500007 , 0.524961054 , 4.20247056E-02 , 2.73625981E-02 , -1.31825563E-02 , 5.71641549E-02 , 0.687430978 , 0.255404860 , + 0.287499994 , 0.524704278 , 4.20201644E-02 , 2.73699276E-02 , -1.31580504E-02 , 5.64172417E-02 , 0.687123239 , 0.256459534 , + 0.288500011 , 0.524446487 , 4.20155674E-02 , 2.73772478E-02 , -1.31333554E-02 , 5.56693263E-02 , 0.686814964 , 0.257515728 , + 0.289499998 , 0.524187565 , 4.20109183E-02 , 2.73845587E-02 , -1.31084705E-02 , 5.49204275E-02 , 0.686506152 , 0.258573413 , + 0.290499985 , 0.523927569 , 4.20062132E-02 , 2.73918603E-02 , -1.30833965E-02 , 5.41705601E-02 , 0.686196864 , 0.259632587 , + 0.291500002 , 0.523666501 , 4.20014523E-02 , 2.73991544E-02 , -1.30581316E-02 , 5.34197465E-02 , 0.685887098 , 0.260693163 , + 0.292499989 , 0.523404360 , 4.19966318E-02 , 2.74064410E-02 , -1.30326785E-02 , 5.26679978E-02 , 0.685576797 , 0.261755168 , + 0.293500006 , 0.523141086 , 4.19917591E-02 , 2.74137203E-02 , -1.30070355E-02 , 5.19153364E-02 , 0.685266078 , 0.262818575 , + 0.294499993 , 0.522876680 , 4.19868305E-02 , 2.74209958E-02 , -1.29812025E-02 , 5.11617772E-02 , 0.684954882 , 0.263883352 , + 0.295500010 , 0.522611141 , 4.19818461E-02 , 2.74282675E-02 , -1.29551804E-02 , 5.04073389E-02 , 0.684643209 , 0.264949441 , + 0.296499997 , 0.522344530 , 4.19768058E-02 , 2.74355337E-02 , -1.29289683E-02 , 4.96520363E-02 , 0.684331059 , 0.266016871 , + 0.297500014 , 0.522076726 , 4.19717059E-02 , 2.74427980E-02 , -1.29025662E-02 , 4.88958918E-02 , 0.684018493 , 0.267085582 , + 0.298500001 , 0.521807790 , 4.19665501E-02 , 2.74500586E-02 , -1.28759751E-02 , 4.81389202E-02 , 0.683705509 , 0.268155575 , + 0.299499989 , 0.521537662 , 4.19613384E-02 , 2.74573192E-02 , -1.28491949E-02 , 4.73811366E-02 , 0.683392048 , 0.269226789 , + 0.300500005 , 0.521266401 , 4.19560708E-02 , 2.74645798E-02 , -1.28222238E-02 , 4.66225632E-02 , 0.683078229 , 0.270299226 , + 0.301499993 , 0.520993948 , 4.19507436E-02 , 2.74718404E-02 , -1.27950637E-02 , 4.58632149E-02 , 0.682763934 , 0.271372855 , + 0.302500010 , 0.520720303 , 4.19453606E-02 , 2.74791010E-02 , -1.27677135E-02 , 4.51031104E-02 , 0.682449222 , 0.272447646 , + 0.303499997 , 0.520445526 , 4.19399180E-02 , 2.74863653E-02 , -1.27401734E-02 , 4.43422683E-02 , 0.682134151 , 0.273523569 , + 0.304500014 , 0.520169437 , 4.19344194E-02 , 2.74936315E-02 , -1.27124442E-02 , 4.35807072E-02 , 0.681818664 , 0.274600625 , + 0.305500001 , 0.519892216 , 4.19288613E-02 , 2.75009014E-02 , -1.26845241E-02 , 4.28184420E-02 , 0.681502819 , 0.275678754 , + 0.306499988 , 0.519613743 , 4.19232473E-02 , 2.75081750E-02 , -1.26564140E-02 , 4.20554914E-02 , 0.681186557 , 0.276757926 , + 0.307500005 , 0.519334018 , 4.19175737E-02 , 2.75154542E-02 , -1.26281139E-02 , 4.12918739E-02 , 0.680869937 , 0.277838171 , + 0.308499992 , 0.519053042 , 4.19118404E-02 , 2.75227409E-02 , -1.25996238E-02 , 4.05276045E-02 , 0.680553019 , 0.278919399 , + 0.309500009 , 0.518770874 , 4.19060476E-02 , 2.75300331E-02 , -1.25709428E-02 , 3.97627093E-02 , 0.680235684 , 0.280001611 , + 0.310499996 , 0.518487394 , 4.19001952E-02 , 2.75373347E-02 , -1.25420718E-02 , 3.89971957E-02 , 0.679917991 , 0.281084806 , + 0.311500013 , 0.518202662 , 4.18942869E-02 , 2.75446437E-02 , -1.25130098E-02 , 3.82310897E-02 , 0.679600000 , 0.282168925 , + 0.312500000 , 0.517916620 , 4.18883152E-02 , 2.75519621E-02 , -1.24837579E-02 , 3.74644063E-02 , 0.679281652 , 0.283253938 , + 0.313499987 , 0.517629325 , 4.18822877E-02 , 2.75592916E-02 , -1.24543151E-02 , 3.66971642E-02 , 0.678963006 , 0.284339845 , + 0.314500004 , 0.517340720 , 4.18761969E-02 , 2.75666323E-02 , -1.24246813E-02 , 3.59293781E-02 , 0.678644001 , 0.285426617 , + 0.315499991 , 0.517050743 , 4.18700427E-02 , 2.75739841E-02 , -1.23948557E-02 , 3.51610705E-02 , 0.678324699 , 0.286514223 , + 0.316500008 , 0.516759515 , 4.18638326E-02 , 2.75813490E-02 , -1.23648401E-02 , 3.43922600E-02 , 0.678005099 , 0.287602603 , + 0.317499995 , 0.516466975 , 4.18575592E-02 , 2.75887288E-02 , -1.23346327E-02 , 3.36229615E-02 , 0.677685261 , 0.288691789 , + 0.318500012 , 0.516173065 , 4.18512262E-02 , 2.75961217E-02 , -1.23042343E-02 , 3.28531936E-02 , 0.677365065 , 0.289781719 , + 0.319499999 , 0.515877783 , 4.18448299E-02 , 2.76035313E-02 , -1.22736441E-02 , 3.20829749E-02 , 0.677044630 , 0.290872365 , + 0.320499986 , 0.515581191 , 4.18383740E-02 , 2.76109558E-02 , -1.22428620E-02 , 3.13123241E-02 , 0.676723957 , 0.291963726 , + 0.321500003 , 0.515283227 , 4.18318547E-02 , 2.76183989E-02 , -1.22118872E-02 , 3.05412598E-02 , 0.676402986 , 0.293055773 , + 0.322499990 , 0.514983833 , 4.18252721E-02 , 2.76258588E-02 , -1.21807214E-02 , 2.97698006E-02 , 0.676081777 , 0.294148445 , + 0.323500007 , 0.514683127 , 4.18186262E-02 , 2.76333373E-02 , -1.21493628E-02 , 2.89979633E-02 , 0.675760269 , 0.295241743 , + 0.324499995 , 0.514380932 , 4.18119170E-02 , 2.76408363E-02 , -1.21178124E-02 , 2.82257665E-02 , 0.675438583 , 0.296335667 , + 0.325500011 , 0.514077425 , 4.18051481E-02 , 2.76483558E-02 , -1.20860683E-02 , 2.74532288E-02 , 0.675116658 , 0.297430128 , + 0.326499999 , 0.513772428 , 4.17983122E-02 , 2.76558958E-02 , -1.20541323E-02 , 2.66803708E-02 , 0.674794495 , 0.298525155 , + 0.327499986 , 0.513466060 , 4.17914130E-02 , 2.76634600E-02 , -1.20220026E-02 , 2.59072073E-02 , 0.674472094 , 0.299620688 , + 0.328500003 , 0.513158202 , 4.17844467E-02 , 2.76710447E-02 , -1.19896792E-02 , 2.51337588E-02 , 0.674149573 , 0.300716698 , + 0.329499990 , 0.512848914 , 4.17774208E-02 , 2.76786555E-02 , -1.19571630E-02 , 2.43600421E-02 , 0.673826754 , 0.301813185 , + 0.330500007 , 0.512538195 , 4.17703241E-02 , 2.76862904E-02 , -1.19244531E-02 , 2.35860776E-02 , 0.673503816 , 0.302910119 , + 0.331499994 , 0.512225986 , 4.17631678E-02 , 2.76939515E-02 , -1.18915485E-02 , 2.28118841E-02 , 0.673180640 , 0.304007441 , + 0.332500011 , 0.511912286 , 4.17559408E-02 , 2.77016386E-02 , -1.18584502E-02 , 2.20374782E-02 , 0.672857344 , 0.305105180 , + 0.333499998 , 0.511597157 , 4.17486504E-02 , 2.77093519E-02 , -1.18251573E-02 , 2.12628786E-02 , 0.672533870 , 0.306203276 , + 0.334500015 , 0.511280477 , 4.17412929E-02 , 2.77170949E-02 , -1.17916698E-02 , 2.04881039E-02 , 0.672210217 , 0.307301700 , + 0.335500002 , 0.510962248 , 4.17338684E-02 , 2.77248677E-02 , -1.17579866E-02 , 1.97131746E-02 , 0.671886384 , 0.308400422 , + 0.336499989 , 0.510642588 , 4.17263731E-02 , 2.77326703E-02 , -1.17241079E-02 , 1.89381093E-02 , 0.671562493 , 0.309499413 , + 0.337500006 , 0.510321379 , 4.17188145E-02 , 2.77405027E-02 , -1.16900345E-02 , 1.81629229E-02 , 0.671238422 , 0.310598671 , + 0.338499993 , 0.509998560 , 4.17111851E-02 , 2.77483687E-02 , -1.16557647E-02 , 1.73876379E-02 , 0.670914173 , 0.311698169 , + 0.339500010 , 0.509674251 , 4.17034887E-02 , 2.77562663E-02 , -1.16212983E-02 , 1.66122708E-02 , 0.670589864 , 0.312797844 , + 0.340499997 , 0.509348392 , 4.16957214E-02 , 2.77641974E-02 , -1.15866354E-02 , 1.58368424E-02 , 0.670265436 , 0.313897699 , + 0.341500014 , 0.509020925 , 4.16878872E-02 , 2.77721621E-02 , -1.15517760E-02 , 1.50613701E-02 , 0.669940948 , 0.314997703 , + 0.342500001 , 0.508691907 , 4.16799821E-02 , 2.77801640E-02 , -1.15167182E-02 , 1.42858727E-02 , 0.669616282 , 0.316097826 , + 0.343499988 , 0.508361280 , 4.16720062E-02 , 2.77882013E-02 , -1.14814639E-02 , 1.35103688E-02 , 0.669291556 , 0.317198038 , + 0.344500005 , 0.508029044 , 4.16639596E-02 , 2.77962759E-02 , -1.14460113E-02 , 1.27348779E-02 , 0.668966770 , 0.318298340 , + 0.345499992 , 0.507695198 , 4.16558385E-02 , 2.78043877E-02 , -1.14103612E-02 , 1.19594187E-02 , 0.668641925 , 0.319398671 , + 0.346500009 , 0.507359743 , 4.16476503E-02 , 2.78125387E-02 , -1.13745118E-02 , 1.11840088E-02 , 0.668317020 , 0.320499003 , + 0.347499996 , 0.507022619 , 4.16393876E-02 , 2.78207306E-02 , -1.13384631E-02 , 1.04086697E-02 , 0.667991996 , 0.321599305 , + 0.348500013 , 0.506683886 , 4.16310504E-02 , 2.78289616E-02 , -1.13022150E-02 , 9.63341817E-03 , 0.667666972 , 0.322699606 , + 0.349500000 , 0.506343424 , 4.16226424E-02 , 2.78372355E-02 , -1.12657677E-02 , 8.85827467E-03 , 0.667341948 , 0.323799819 , + 0.350499988 , 0.506001353 , 4.16141599E-02 , 2.78455522E-02 , -1.12291202E-02 , 8.08325689E-03 , 0.667016804 , 0.324899912 , + 0.351500005 , 0.505657613 , 4.16056067E-02 , 2.78539099E-02 , -1.11922715E-02 , 7.30838394E-03 , 0.666691720 , 0.325999916 , + 0.352499992 , 0.505312145 , 4.15969752E-02 , 2.78623141E-02 , -1.11552216E-02 , 6.53367583E-03 , 0.666366577 , 0.327099770 , + 0.353500009 , 0.504965007 , 4.15882654E-02 , 2.78707631E-02 , -1.11179706E-02 , 5.75915119E-03 , 0.666041434 , 0.328199416 , + 0.354499996 , 0.504616141 , 4.15794849E-02 , 2.78792568E-02 , -1.10805174E-02 , 4.98482911E-03 , 0.665716290 , 0.329298884 , + 0.355500013 , 0.504265547 , 4.15706262E-02 , 2.78877988E-02 , -1.10428622E-02 , 4.21072822E-03 , 0.665391147 , 0.330398113 , + 0.356500000 , 0.503913224 , 4.15616892E-02 , 2.78963875E-02 , -1.10050039E-02 , 3.43686831E-03 , 0.665066063 , 0.331497073 , + 0.357499987 , 0.503559172 , 4.15526740E-02 , 2.79050265E-02 , -1.09669426E-02 , 2.66326847E-03 , 0.664740980 , 0.332595766 , + 0.358500004 , 0.503203332 , 4.15435843E-02 , 2.79137138E-02 , -1.09286774E-02 , 1.88994757E-03 , 0.664415896 , 0.333694130 , + 0.359499991 , 0.502845764 , 4.15344127E-02 , 2.79224515E-02 , -1.08902073E-02 , 1.11692504E-03 , 0.664090931 , 0.334792167 , + 0.360500008 , 0.502486408 , 4.15251628E-02 , 2.79312432E-02 , -1.08515332E-02 , 3.44220141E-04 , 0.663765967 , 0.335889846 , + 0.361499995 , 0.502125204 , 4.15158309E-02 , 2.79400852E-02 , -1.08126532E-02 , -4.28147963E-04 , 0.663441062 , 0.336987108 , + 0.362500012 , 0.501762271 , 4.15064208E-02 , 2.79489812E-02 , -1.07735675E-02 , -1.20016001E-03 , 0.663116217 , 0.338083953 , + 0.363499999 , 0.501397491 , 4.14969288E-02 , 2.79579312E-02 , -1.07342759E-02 , -1.97179662E-03 , 0.662791431 , 0.339180350 , + 0.364499986 , 0.501030862 , 4.14873548E-02 , 2.79669352E-02 , -1.06947776E-02 , -2.74303835E-03 , 0.662466764 , 0.340276241 , + 0.365500003 , 0.500662386 , 4.14776988E-02 , 2.79759970E-02 , -1.06550716E-02 , -3.51386587E-03 , 0.662142217 , 0.341371655 , + 0.366499990 , 0.500292122 , 4.14679609E-02 , 2.79851165E-02 , -1.06151570E-02 , -4.28425986E-03 , 0.661817729 , 0.342466533 , + 0.367500007 , 0.499919951 , 4.14581373E-02 , 2.79942919E-02 , -1.05750347E-02 , -5.05420053E-03 , 0.661493361 , 0.343560845 , + 0.368499994 , 0.499545932 , 4.14482281E-02 , 2.80035269E-02 , -1.05347028E-02 , -5.82366902E-03 , 0.661169112 , 0.344654590 , + 0.369500011 , 0.499170005 , 4.14382331E-02 , 2.80128233E-02 , -1.04941614E-02 , -6.59264531E-03 , 0.660844982 , 0.345747679 , + 0.370499998 , 0.498792201 , 4.14281562E-02 , 2.80221794E-02 , -1.04534104E-02 , -7.36111077E-03 , 0.660520971 , 0.346840173 , + 0.371499985 , 0.498412490 , 4.14179899E-02 , 2.80315969E-02 , -1.04124472E-02 , -8.12904444E-03 , 0.660197079 , 0.347931951 , + 0.372500002 , 0.498030841 , 4.14077379E-02 , 2.80410778E-02 , -1.03712734E-02 , -8.89642816E-03 , 0.659873366 , 0.349023044 , + 0.373499990 , 0.497647285 , 4.13973965E-02 , 2.80506201E-02 , -1.03298873E-02 , -9.66324192E-03 , 0.659549832 , 0.350113422 , + 0.374500006 , 0.497261763 , 4.13869657E-02 , 2.80602295E-02 , -1.02882879E-02 , -1.04294661E-02 , 0.659226418 , 0.351203024 , + 0.375499994 , 0.496874303 , 4.13764454E-02 , 2.80699041E-02 , -1.02464762E-02 , -1.11950804E-02 , 0.658903241 , 0.352291852 , + 0.376500010 , 0.496484846 , 4.13658358E-02 , 2.80796438E-02 , -1.02044493E-02 , -1.19600659E-02 , 0.658580184 , 0.353379875 , + 0.377499998 , 0.496093452 , 4.13551331E-02 , 2.80894525E-02 , -1.01622082E-02 , -1.27244033E-02 , 0.658257365 , 0.354467064 , + 0.378500015 , 0.495700032 , 4.13443409E-02 , 2.80993283E-02 , -1.01197511E-02 , -1.34880729E-02 , 0.657934725 , 0.355553359 , + 0.379500002 , 0.495304614 , 4.13334519E-02 , 2.81092748E-02 , -1.00770779E-02 , -1.42510533E-02 , 0.657612264 , 0.356638789 , + 0.380499989 , 0.494907200 , 4.13224734E-02 , 2.81192902E-02 , -1.00341886E-02 , -1.50133269E-02 , 0.657290041 , 0.357723266 , + 0.381500006 , 0.494507730 , 4.13113981E-02 , 2.81293783E-02 , -9.99108143E-03 , -1.57748722E-02 , 0.656968057 , 0.358806819 , + 0.382499993 , 0.494106233 , 4.13002297E-02 , 2.81395372E-02 , -9.94775537E-03 , -1.65356714E-02 , 0.656646311 , 0.359889358 , + 0.383500010 , 0.493702680 , 4.12889645E-02 , 2.81497706E-02 , -9.90421139E-03 , -1.72957033E-02 , 0.656324804 , 0.360970914 , + 0.384499997 , 0.493297040 , 4.12776023E-02 , 2.81600766E-02 , -9.86044668E-03 , -1.80549473E-02 , 0.656003535 , 0.362051427 , + 0.385500014 , 0.492889345 , 4.12661396E-02 , 2.81704590E-02 , -9.81646124E-03 , -1.88133847E-02 , 0.655682504 , 0.363130897 , + 0.386500001 , 0.492479533 , 4.12545800E-02 , 2.81809177E-02 , -9.77225509E-03 , -1.95709951E-02 , 0.655361772 , 0.364209235 , + 0.387499988 , 0.492067635 , 4.12429236E-02 , 2.81914528E-02 , -9.72782727E-03 , -2.03277599E-02 , 0.655041277 , 0.365286469 , + 0.388500005 , 0.491653621 , 4.12311628E-02 , 2.82020662E-02 , -9.68317594E-03 , -2.10836567E-02 , 0.654721081 , 0.366362572 , + 0.389499992 , 0.491237491 , 4.12193015E-02 , 2.82127578E-02 , -9.63830110E-03 , -2.18386669E-02 , 0.654401183 , 0.367437482 , + 0.390500009 , 0.490819186 , 4.12073396E-02 , 2.82235313E-02 , -9.59320087E-03 , -2.25927718E-02 , 0.654081583 , 0.368511170 , + 0.391499996 , 0.490398765 , 4.11952734E-02 , 2.82343850E-02 , -9.54787619E-03 , -2.33459491E-02 , 0.653762281 , 0.369583637 , + 0.392500013 , 0.489976138 , 4.11831029E-02 , 2.82453205E-02 , -9.50232521E-03 , -2.40981784E-02 , 0.653443336 , 0.370654851 , + 0.393500000 , 0.489551336 , 4.11708243E-02 , 2.82563400E-02 , -9.45654698E-03 , -2.48494428E-02 , 0.653124690 , 0.371724755 , + 0.394499987 , 0.489124358 , 4.11584415E-02 , 2.82674432E-02 , -9.41054057E-03 , -2.55997181E-02 , 0.652806401 , 0.372793347 , + 0.395500004 , 0.488695145 , 4.11459506E-02 , 2.82786321E-02 , -9.36430506E-03 , -2.63489876E-02 , 0.652488410 , 0.373860598 , + 0.396499991 , 0.488263756 , 4.11333516E-02 , 2.82899048E-02 , -9.31784045E-03 , -2.70972289E-02 , 0.652170777 , 0.374926448 , + 0.397500008 , 0.487830102 , 4.11206447E-02 , 2.83012670E-02 , -9.27114487E-03 , -2.78444234E-02 , 0.651853502 , 0.375990897 , + 0.398499995 , 0.487394184 , 4.11078297E-02 , 2.83127148E-02 , -9.22421645E-03 , -2.85905469E-02 , 0.651536644 , 0.377053916 , + 0.399500012 , 0.486956030 , 4.10948917E-02 , 2.83242576E-02 , -9.17705987E-03 , -2.93355919E-02 , 0.651220083 , 0.378115475 , + 0.400000006 , 0.486532003 , 4.11139540E-02 , 2.83555184E-02 , -9.18524247E-03 , -3.00840233E-02 , 0.650901794 , 0.379182220 +}; + class HelmholtzFD_Op : public E_F0mps { public: Expression expTh; Expression expomega, expmu; - static const int n_name_param = 2; + static const int n_name_param = 1; static basicAC_F0::name_and_type name_param[]; Expression nargs[n_name_param]; HelmholtzFD_Op(const basicAC_F0 &args, Expression Th) : expTh(Th) { args.SetNameParam(n_name_param, name_param, nargs); expTh = to< const Mesh3 * >(args[0]); expomega = to< Complex >(args[1]); - expmu = to< double >(args[2]); + expmu = to< Complex >(args[2]); } long arg(int i, Stack stack, long a) const { return nargs[i] ? GetAny< long >((*nargs[i])(stack)) : a;} @@ -379,13 +781,12 @@ class HelmholtzFD_Op : public E_F0mps { }; basicAC_F0::name_and_type HelmholtzFD_Op::name_param[] = { - {"npml", &typeid(KN_)}, - {"pmlsides", &typeid(KN_)} + {"npml", &typeid(KN_)} }; class HelmholtzFD : public OneOperator { public: - HelmholtzFD() : OneOperator(atype< newpMatrice_Creuse< Complex > >( ), atype< const Mesh3 * >( ), atype< Complex >( ), atype< double >( )) {}; + HelmholtzFD() : OneOperator(atype< newpMatrice_Creuse< Complex > >( ), atype< const Mesh3 * >( ), atype< Complex >( ), atype< Complex >( )) {}; E_F0 *code(const basicAC_F0 &args) const { return new HelmholtzFD_Op(args, t[0]->CastTo(args[0])); } }; @@ -532,7 +933,13 @@ AnyType HelmholtzFD_Op::operator( )(Stack stack) const { //if (mpirank == 0) cout << n1 << " " << n2 << " " << n3 << " " << Th.nv << endl; - KN mu(n1*n2*n3); + KN defnpml(6,8); + KN npml(arg(0,stack,defnpml)); + + KN pmlsides(6,1); + for (int i=0; i<6; i++) pmlsides[i] = (npml[i] > 0L); + + KN> mu(n1*n2*n3); KN xx(n1*n2*n3), yy(n1*n2*n3), zz(n1*n2*n3); KN boundarynodesFD(n1*n2*n3,0L); @@ -543,8 +950,10 @@ AnyType HelmholtzFD_Op::operator( )(Stack stack) const { xx[cpt] = lx + i1*h; yy[cpt] = ly + i2*h; zz[cpt] = lz + i3*h; MeshPoint* mp(Fem2D::MeshPointStack(stack)); mp->set(xx[cpt], yy[cpt], zz[cpt]); - mu[cpt] = GetAny( (*expmu)(stack) ); - if ((i1 == 0) || (i1 == n1-1) || (i2 == 0) || (i2 == n2-1) || (i3 == 0) || (i3 == n3-1)) + mu[cpt] = GetAny>( (*expmu)(stack) ); + if ((i1 == 0 && !npml[0]) || (i1 == n1-1 && !npml[1]) + || (i2 == 0 && !npml[2]) || (i2 == n2-1 && !npml[3]) + || (i3 == 0 && !npml[4]) || (i3 == n3-1 && !npml[5])) boundarynodesFD[kkindex(i1,i2,i3,n1,n2,n3)] = 1; cpt++; } @@ -555,12 +964,6 @@ AnyType HelmholtzFD_Op::operator( )(Stack stack) const { dd[0].resize(n1+2); dd[1].resize(n2+2); dd[2].resize(n3+2); db[0].resize(n1+2); db[1].resize(n2+2); db[2].resize(n3+2); - KN defnpml(6,8); - KN npml(arg(0,stack,defnpml)); - - KN defsides(6,1); - KN pmlsides(arg(1,stack,defsides)); - subdamp(n1,npml[0],npml[1],90,h,omega.real(),dd[0],db[0],pmlsides[0]+2*pmlsides[1]); subdamp(n2,npml[2],npml[3],90,h,omega.real(),dd[1],db[1],pmlsides[2]+2*pmlsides[3]); subdamp(n3,npml[4],npml[5],90,h,omega.real(),dd[2],db[2],pmlsides[4]+2*pmlsides[5]); @@ -588,7 +991,7 @@ AnyType HelmholtzFD_Op::operator( )(Stack stack) const { {1,-1,1},{-1,1,-1}, {1,1,-1},{-1,-1,1}}; - double lambda, ppwl, pi = 3.14159265358979323846; + double lambda, ppwl1, pi = 3.14159265358979323846; for (long i3 = 0; i3 < n3; i3++) for (long i2 = 0; i2 < n2; i2++) for (long i1 = 0; i1 < n1; i1++) { @@ -597,18 +1000,69 @@ AnyType HelmholtzFD_Op::operator( )(Stack stack) const { l3 = i3; k = kkindex(i1,i2,i3,n1,n2,n3); - lambda = 2 * pi / omega.real() * sqrt(mu[k]); - ppwl = lambda/h; - - int ntab = max(0.,min(343.,(ppwl-3)/(20.15-3)*343 + 0.5)); - - c=wtab[8*ntab+1]; - d=wtab[8*ntab+2]; - e=wtab[8*ntab+3]; - f=wtab[8*ntab+4]; - w1=wtab[8*ntab+5]; - w2=wtab[8*ntab+6]; - w3=wtab[8*ntab+7]; + lambda = 2 * pi / omega.real() * sqrt(mu[k].real()); + //ppwl = lambda/h; + //int ntab = max(0.,min(343.,(ppwl-3)/(20.15-3)*343 + 0.5)); + + ppwl1 = h/lambda; + int ntab = 0; + while ((ppwl1 > wtab2[8*ntab]) && (ntab<398)) + ntab++; + if (ntab > 0) + if (abs(ppwl1-wtab2[8*ntab]) > abs(ppwl1-wtab2[8*(ntab-1)])) + ntab--; + + c=wtab2[8*ntab+1]; + d=wtab2[8*ntab+2]; + e=wtab2[8*ntab+3]; + f=wtab2[8*ntab+4]; + w1=wtab2[8*ntab+5]; + w2=wtab2[8*ntab+6]; + w3=wtab2[8*ntab+7]; + +/* + c=0; d=0; e=0; f=0; w1=0; w2=0; w3=0; + for (int j3=-1;j3<=1;j3++) + for (int j2=-1;j2<=1;j2++) + for (int j1=-1;j1<=1;j1++) { + long k3 = max(0L,min(n3-1,i3+j3)); + long k2 = max(0L,min(n2-1,i2+j2)); + long k1 = max(0L,min(n1-1,i1+j1)); + long kk = kkindex(k1,k2,k3,n1,n2,n3); + lambda = 2 * pi / omega.real() * sqrt(mu[kk]); + ppwl = lambda/h; + ntab = max(0.,min(343.,(ppwl-3)/(20.15-3)*343 + 0.5)); + c +=wtab[8*ntab+1]; + d +=wtab[8*ntab+2]; + e +=wtab[8*ntab+3]; + f +=wtab[8*ntab+4]; + w1+=wtab[8*ntab+5]; + w2+=wtab[8*ntab+6]; + w3+=wtab[8*ntab+7]; + } + c/=27; d/=27; e/=27; f/=27; w1/=27; w2/=27; w3/=27; +*/ + +/* + // G=4 + c=0.5915900; + d=4.9653493E-02; + e=5.1085097E-03; + f=6.1483691E-03; + w1=8.8075437E-02; + w2=0.8266806; + w3=8.5243940E-02; +*/ +/* + // G=4810 + c=0.4966390; + d=7.5123318E-02; + e=4.3846383E-03; + f=6.7614019E-07; + w1=5.0247996E-05; + w2=0.8900359; + w3=0.1099138; +*/ w2u=w2/3.; w3u=w3/4.; diff --git a/plugin/seq/Makefile.am b/plugin/seq/Makefile.am index 5678f4c96..0b4045e5d 100644 --- a/plugin/seq/Makefile.am +++ b/plugin/seq/Makefile.am @@ -50,7 +50,7 @@ LIST_COMPILE=myfunction.$(DYLIB_SUFFIX) BernardiRaugel.$(DYLIB_SUFFIX) \ Element_P2pnc.$(DYLIB_SUFFIX) SaveHB.$(DYLIB_SUFFIX) IncompleteCholesky.$(DYLIB_SUFFIX) \ Schur-Complement.$(DYLIB_SUFFIX) biofunc.$(DYLIB_SUFFIX) mat_edgeP1.$(DYLIB_SUFFIX) \ geophysics.$(DYLIB_SUFFIX) CircumCenter.$(DYLIB_SUFFIX) MatD-VFP0.$(DYLIB_SUFFIX) \ - meshtools.$(DYLIB_SUFFIX) Helmholtz_FD.$(DYLIB_SUFFIX) + meshtools.$(DYLIB_SUFFIX) Helmholtz_FD.$(DYLIB_SUFFIX) Element_P3pnc.$(DYLIB_SUFFIX) # FFCS - some libraries are skipped because the corresponding tool is deactivated. diff --git a/plugin/seq/dfft.cpp b/plugin/seq/dfft.cpp index 6c37437c9..63ccda6fb 100644 --- a/plugin/seq/dfft.cpp +++ b/plugin/seq/dfft.cpp @@ -33,84 +33,84 @@ template< class Complex > class DFFT_1d2dor3d { - public: - Complex *x; - int n, m, k; - int sign; - DFFT_1d2dor3d(KN< Complex > *xx, long signn, long nn = 1, long kk = 1) +public: + Complex *x; + int n, m, k; + int sign; + DFFT_1d2dor3d(KN< Complex > *xx, long signn, long nn = 1, long kk = 1) : x(*xx), n(nn), m(xx->N( ) / (nn * kk)), k(kk), sign(signn) { - cout << xx << " " << signn << " " << nn << " " << xx->N( ) << " n: " << n << " m:" << m - << " k: " << k << endl; - ffassert(n > 0 && (n * m * k == xx->N( ))); - } - - DFFT_1d2dor3d(KNM< Complex > *xx, long signn) : x(*xx), n(xx->M( )), m(xx->N( )), sign(signn) {} + cout << xx << " " << signn << " " << nn << " " << xx->N( ) << " n: " << n << " m:" << m + << " k: " << k << endl; + ffassert(n > 0 && (n * m * k == xx->N( ))); + } + + DFFT_1d2dor3d(KNM< Complex > *xx, long signn) : x(*xx), n(xx->M( )), m(xx->N( )), sign(signn) {} }; DFFT_1d2dor3d< Complex > dfft(KN< Complex > *const &x, const long &sign) { - return DFFT_1d2dor3d< Complex >(x, sign); + return DFFT_1d2dor3d< Complex >(x, sign); } DFFT_1d2dor3d< Complex > dfft(KN< Complex > *const &x, const long &nn, const long &sign) { - return DFFT_1d2dor3d< Complex >(x, sign, nn); + return DFFT_1d2dor3d< Complex >(x, sign, nn); } DFFT_1d2dor3d< Complex > dfft(KN< Complex > *const &x, const long &nn, const long &kk, const long &sign) { - return DFFT_1d2dor3d< Complex >(x, sign, nn, kk); + return DFFT_1d2dor3d< Complex >(x, sign, nn, kk); } DFFT_1d2dor3d< Complex > dfft(KNM< Complex > *const &x, const long &sign) { - return DFFT_1d2dor3d< Complex >(x, sign); + return DFFT_1d2dor3d< Complex >(x, sign); } bool ff_execute(fftw_plan *p) { - if (*p) { - fftw_execute(*p); - } - - return 0; + if (*p) { + fftw_execute(*p); + } + + return 0; } bool ff_delete(fftw_plan *p) { - if (*p) { - fftw_destroy_plan(*p); - } - - *p = 0; - return 0; + if (*p) { + fftw_destroy_plan(*p); + } + + *p = 0; + return 0; } KN< Complex > *dfft_eq(KN< Complex > *const &x, const DFFT_1d2dor3d< Complex > &d) { - ffassert(x->N( ) == d.n * d.m * d.k); - Complex *px = *x; - fftw_plan p; - if (d.k == 1) { - if (d.n > 1) { - p = fftw_plan_dft_2d(d.n, d.m, reinterpret_cast< fftw_complex * >(d.x), - reinterpret_cast< fftw_complex * >(px), d.sign, FFTW_ESTIMATE); + ffassert(x->N( ) == d.n * d.m * d.k); + Complex *px = *x; + fftw_plan p; + if (d.k == 1) { + if (d.n > 1) { + p = fftw_plan_dft_2d(d.n, d.m, reinterpret_cast< fftw_complex * >(d.x), + reinterpret_cast< fftw_complex * >(px), d.sign, FFTW_ESTIMATE); + } else { + p = fftw_plan_dft_1d(d.m, reinterpret_cast< fftw_complex * >(d.x), + reinterpret_cast< fftw_complex * >(px), d.sign, FFTW_ESTIMATE); + } } else { - p = fftw_plan_dft_1d(d.m, reinterpret_cast< fftw_complex * >(d.x), - reinterpret_cast< fftw_complex * >(px), d.sign, FFTW_ESTIMATE); + if (d.n > 1) { + p = fftw_plan_dft_3d(d.n, d.m, d.k, reinterpret_cast< fftw_complex * >(d.x), + reinterpret_cast< fftw_complex * >(px), d.sign, FFTW_ESTIMATE); + } else { + p = fftw_plan_dft_2d(d.m, d.k, reinterpret_cast< fftw_complex * >(d.x), + reinterpret_cast< fftw_complex * >(px), d.sign, FFTW_ESTIMATE); + } } - } else { - if (d.n > 1) { - p = fftw_plan_dft_3d(d.n, d.m, d.k, reinterpret_cast< fftw_complex * >(d.x), - reinterpret_cast< fftw_complex * >(px), d.sign, FFTW_ESTIMATE); - } else { - p = fftw_plan_dft_2d(d.m, d.k, reinterpret_cast< fftw_complex * >(d.x), - reinterpret_cast< fftw_complex * >(px), d.sign, FFTW_ESTIMATE); - } - } - - fftw_execute(p); - fftw_destroy_plan(p); - return x; + + fftw_execute(p); + fftw_destroy_plan(p); + return x; } KN< double > *dfft_eq(KN< double > *const &x, const DFFT_1d2dor3d< double > &d) { - ffassert(0); - return x; + ffassert(0); + return x; } /* class Init { public: @@ -123,167 +123,188 @@ struct fftw_plan_s {}; template<> inline AnyType DeletePtr< fftw_plan * >(Stack, const AnyType &x) { - fftw_plan *a = PGetAny< fftw_plan >(x); - - if (*a) { - fftw_destroy_plan(*a); - } - - *a = 0; - return Nothing; + fftw_plan *a = PGetAny< fftw_plan >(x); + + if (*a) { + fftw_destroy_plan(*a); + } + + *a = 0; + return Nothing; }; fftw_plan *plan__eq(fftw_plan *a, fftw_plan b) { - if (*a) { - fftw_destroy_plan(*a); - } - - *a = b; - return a; + if (*a) { + fftw_destroy_plan(*a); + } + + *a = b; + return a; } fftw_plan *plan_set(fftw_plan *a, fftw_plan b) { - *a = b; - return a; + *a = b; + return a; } fftw_plan plan_dfft(KN< Complex > *const &x, KN< Complex > *const &y, const long &sign) { - return fftw_plan_dft_1d(x->N( ), reinterpret_cast< fftw_complex * >(&x[0]), - reinterpret_cast< fftw_complex * >(&y[0]), sign, FFTW_ESTIMATE); + return fftw_plan_dft_1d(x->N( ), reinterpret_cast< fftw_complex * >(&x[0]), + reinterpret_cast< fftw_complex * >(&y[0]), sign, FFTW_ESTIMATE); } fftw_plan plan_dfft(KNM< Complex > *const &x, KNM< Complex > *const &y, const long &sign) { - long m = x->N( ), n = x->M( ); - - fftw_plan_dft_2d(n, m, reinterpret_cast< fftw_complex * >(&x[0]), - reinterpret_cast< fftw_complex * >(&y[0]), sign, FFTW_ESTIMATE); - return 0; + long m = x->N( ), n = x->M( ); + + fftw_plan_dft_2d(n, m, reinterpret_cast< fftw_complex * >(&x[0]), + reinterpret_cast< fftw_complex * >(&y[0]), sign, FFTW_ESTIMATE); + return 0; } fftw_plan plan_dfft(KN< Complex > *const &x, KN< Complex > *const &y, const long &n, const long &sign) { - long nn = n, mm = y->N( ) / nn; - - ffassert(mm * nn == y->N( ) && x->N( ) == y->N( )); - - return fftw_plan_dft_2d(nn, mm, reinterpret_cast< fftw_complex * >(&x[0]), - reinterpret_cast< fftw_complex * >(&y[0]), sign, FFTW_ESTIMATE); + long nn = n, mm = y->N( ) / nn; + + ffassert(mm * nn == y->N( ) && x->N( ) == y->N( )); + + return fftw_plan_dft_2d(nn, mm, reinterpret_cast< fftw_complex * >(&x[0]), + reinterpret_cast< fftw_complex * >(&y[0]), sign, FFTW_ESTIMATE); } fftw_plan plan_dfft(KN< Complex > *const &x, KN< Complex > *const &y, const long &n, const long &k, const long &sign) { - int nn = n, mm = y->N( ) / (k * n), kk = k; - - ffassert(y->N( ) == nn * mm * kk); - if (nn > 1) { - return fftw_plan_dft_3d(nn, mm, kk, reinterpret_cast< fftw_complex * >(&x[0]), - reinterpret_cast< fftw_complex * >(&y[0]), sign, FFTW_ESTIMATE); - } else { - return fftw_plan_dft_2d(nn, mm, reinterpret_cast< fftw_complex * >(&x[0]), - reinterpret_cast< fftw_complex * >(&y[0]), sign, FFTW_ESTIMATE); - } + int nn = n, mm = y->N( ) / (k * n), kk = k; + + ffassert(y->N( ) == nn * mm * kk); + if (nn > 1) { + return fftw_plan_dft_3d(nn, mm, kk, reinterpret_cast< fftw_complex * >(&x[0]), + reinterpret_cast< fftw_complex * >(&y[0]), sign, FFTW_ESTIMATE); + } else { + return fftw_plan_dft_2d(nn, mm, reinterpret_cast< fftw_complex * >(&x[0]), + reinterpret_cast< fftw_complex * >(&y[0]), sign, FFTW_ESTIMATE); + } } - +template class Mapkk : public E_F0mps { - public: - typedef Complex R; - typedef KN_< R > Result; - ; - static basicAC_F0::name_and_type *name_param; - static const int n_name_param = 0; - Expression expv, expm, exp; - Expression nargs[n_name_param]; - - Mapkk(const basicAC_F0 &args) : expv(0), expm(0), exp(0) { - args.SetNameParam(n_name_param, name_param, nargs); - expv = to< KN< R > * >(args[0]); // a the expression to get the mesh - expm = to< long >(args[1]); - exp = to< R >(args[2]); // a the expression to get the mesh - } - - ~Mapkk( ) {} - - static ArrayOfaType typeargs( ) { - return ArrayOfaType(atype< KN< R > * >( ), atype< long >( ), atype< R >( )); - } - - static E_F0 *f(const basicAC_F0 &args) { return new Mapkk(args); } - - AnyType operator( )(Stack s) const; +public: + typedef Complex R; + typedef KN_< R > Result; + ; + static basicAC_F0::name_and_type *name_param; + static const int n_name_param = 0; + Expression expv, expK, expm, expk, exp; + Expression nargs[n_name_param]; + + Mapkk(const basicAC_F0 &args) : expv(0),expK(0), expm(0), expk(0), exp(0) { + args.SetNameParam(n_name_param, name_param, nargs); + expv = to< KN< R > * >(args[0]); // a the expression to get the mesh + expK = to< R3 * >(args[1]); // a the expression to get the K fourier variable + if(NP>2)expm = to< long >(args[2]);// 2d ... + if(NP==4) + expk = to< long >(args[3]); + exp = to< R >(args[NP]); // a the expression to get the mesh + } + + ~Mapkk( ) {} + + static ArrayOfaType typeargs( ) { + if(NP==2) + return ArrayOfaType(atype< KN< R > * >( ), atype< R3* >( ), atype< R >( )); + else if(NP==3) + return ArrayOfaType(atype< KN< R > * >( ), atype< R3* >( ), atype< long >( ), atype< R >( )); + else if(NP==4) + return ArrayOfaType(atype< KN< R > * >( ), atype< R3* >( ), atype< long >( ),atype< long >( ), atype< R >( )); + else ffassert(0); // + } + + static E_F0 *f(const basicAC_F0 &args) { return new Mapkk(args); } + + AnyType operator( )(Stack s) const; }; - -basicAC_F0::name_and_type *Mapkk::name_param = 0; -AnyType Mapkk::operator( )(Stack s) const { - // correct July 2015 ... not tested before.. - MeshPoint *mp(MeshPointStack(s)), mps = *mp; - - KN< R > *pv = GetAny< KN< R > * >((*expv)(s)); - KN< R > v(*pv); - - long nn = v.N( ); - long m = GetAny< long >((*expm)(s)); - if (verbosity > 10) { - cout << " map: expm " << expm << " m = " << m << endl; - } - - long n = nn / m; - double ki = 1. / n; - double kj = 1. / m; - double ki0 = 0., kj0 = 0; - if (verbosity > 10) { - cout << " map: " << n << " " << m << " " << nn << " == " << n * m << endl; - } - - ffassert(m * n == nn); - long n2 = (n + 1) / 2, m2 = (m + 1) / 2; - - for (long j = 0, kk = 0; j < m; ++j) { - for (long k = 0, i = 0; i < n; ++i) { - R2 P(i * ki + ki0, j * kj + kj0); - mp->set(P.x, P.y); - v[kk++] = GetAny< R >((*exp)(s)); +template +basicAC_F0::name_and_type *Mapkk::name_param = 0; +template +AnyType Mapkk::operator( )(Stack s) const { + // correct July 2015 ... not tested before.. + MeshPoint *mp(MeshPointStack(s)), mps = *mp; + + KN< R > *pv = GetAny< KN< R > * >((*expv)(s)); + KN< R > & v(*pv); + R3 * pK = GetAny< R3 * >((*expK)(s)); + long nn = v.N( ); + long n2 = expm ?GetAny< long >((*expm)(s)):1; + long n3 = expk ? GetAny< long >((*expk)(s)): 1; + if (verbosity > 9) { + cout << " map: expm " << expm << " n2 = " << n2 << " n3 =" << n3 << " size array:" << nn << endl; } - } - - *mp = mps; - return 0L; + long n23 =n2*n3; + long n1 = nn / n23; + double k1 = 1. / n1; + double k2 = 1. / n2; + double k3 = 1. / n3; + + double k10 = 0., k20 = 0, k30 = 0;; + if (verbosity > 9) { + cout << " map: " << n1 << " " << n2 << " " << n3 << " " << nn << " == " << n1 * n2 * n3 << endl; + } + + ffassert(n1 * n2 * n3 == nn); + long n12 = (n1 + 1) / 2, n22 = (n2 + 1) / 2, n32 = (n3 + 1) / 2; + int kkk =0; + for (long i3 = 0; i3 < n3; ++i3) + for (long i2 = 0 ; i2 < n2; ++i2) + for (long i1 = 0; i1 < n1; ++i1,++kkk) + { + int ii1 = i1%n12 - (i1/n12)*n12; + int ii2 = i2%n22 - (i2/n22)*n22; + int ii3 = i3%n32 - (i3/n32)*n32; + R3 P(ii1,ii2, ii3); + *pK = P; // set value of K to P. + v[kkk] = GetAny< R >((*exp)(s)); + if(verbosity>19) cout << "map" << kkk << " " <( ); - Dcl_Type< DFFT_R >( ); - - Dcl_Type< fftw_plan * >(::InitializePtr< fftw_plan * >, ::DeletePtr< fftw_plan * >); - Dcl_Type< fftw_plan >( ); - zzzfff->Add("fftwplan", atype< fftw_plan * >( )); - - TheOperators->Add("=", new OneOperator2< fftw_plan *, fftw_plan *, fftw_plan >(plan__eq)); - TheOperators->Add("<-", new OneOperator2< fftw_plan *, fftw_plan *, fftw_plan >(plan_set)); - - Global.Add("plandfft", "(", - new OneOperator3_< fftw_plan, KN< Complex > *, KN< Complex > *, long >(plan_dfft)); - Global.Add( - "plandfft", "(", - new OneOperator4_< fftw_plan, KN< Complex > *, KN< Complex > *, long, long >(plan_dfft)); - Global.Add( - "plandfft", "(", - new OneOperator5_< fftw_plan, KN< Complex > *, KN< Complex > *, long, long, long >(plan_dfft)); - Global.Add("plandfft", "(", - new OneOperator3_< fftw_plan, KNM< Complex > *, KNM< Complex > *, long >(plan_dfft)); - - Global.Add("execute", "(", new OneOperator1< bool, fftw_plan * >(ff_execute)); - Global.Add("delete", "(", new OneOperator1< bool, fftw_plan * >(ff_delete)); - - Global.Add("dfft", "(", new OneOperator2_< DFFT_C, KN< Complex > *, long >(dfft)); - Global.Add("dfft", "(", new OneOperator3_< DFFT_C, KN< Complex > *, long, long >(dfft)); - Global.Add("dfft", "(", new OneOperator4_< DFFT_C, KN< Complex > *, long, long, long >(dfft)); - Global.Add("dfft", "(", new OneOperator2_< DFFT_C, KNM< Complex > *, long >(dfft)); - Global.Add("map", "(", new OneOperatorCode< Mapkk >( )); - TheOperators->Add("=", new OneOperator2_< KN< Complex > *, KN< Complex > *, DFFT_C >(dfft_eq)); + typedef DFFT_1d2dor3d< Complex > DFFT_C; + typedef DFFT_1d2dor3d< double > DFFT_R; + if(mpirank==0) + cout << " load: init dfft " << endl; + Dcl_Type< DFFT_C >( ); + Dcl_Type< DFFT_R >( ); + + Dcl_Type< fftw_plan * >(::InitializePtr< fftw_plan * >, ::DeletePtr< fftw_plan * >); + Dcl_Type< fftw_plan >( ); + zzzfff->Add("fftwplan", atype< fftw_plan * >( )); + + TheOperators->Add("=", new OneOperator2< fftw_plan *, fftw_plan *, fftw_plan >(plan__eq)); + TheOperators->Add("<-", new OneOperator2< fftw_plan *, fftw_plan *, fftw_plan >(plan_set)); + + Global.Add("plandfft", "(", + new OneOperator3_< fftw_plan, KN< Complex > *, KN< Complex > *, long >(plan_dfft)); + Global.Add( + "plandfft", "(", + new OneOperator4_< fftw_plan, KN< Complex > *, KN< Complex > *, long, long >(plan_dfft)); + Global.Add( + "plandfft", "(", + new OneOperator5_< fftw_plan, KN< Complex > *, KN< Complex > *, long, long, long >(plan_dfft)); + Global.Add("plandfft", "(", + new OneOperator3_< fftw_plan, KNM< Complex > *, KNM< Complex > *, long >(plan_dfft)); + + Global.Add("execute", "(", new OneOperator1< bool, fftw_plan * >(ff_execute)); + Global.Add("delete", "(", new OneOperator1< bool, fftw_plan * >(ff_delete)); + + Global.Add("dfft", "(", new OneOperator2_< DFFT_C, KN< Complex > *, long >(dfft)); + Global.Add("dfft", "(", new OneOperator3_< DFFT_C, KN< Complex > *, long, long >(dfft)); + Global.Add("dfft", "(", new OneOperator4_< DFFT_C, KN< Complex > *, long, long, long >(dfft)); + Global.Add("dfft", "(", new OneOperator2_< DFFT_C, KNM< Complex > *, long >(dfft)); + Global.Add("mapk", "(", new OneOperatorCode< Mapkk<2> >( )); + Global.Add("mapkk", "(", new OneOperatorCode< Mapkk<3> >( )); + Global.Add("mapkkk", "(", new OneOperatorCode< Mapkk<4> >( )); + TheOperators->Add("=", new OneOperator2_< KN< Complex > *, KN< Complex > *, DFFT_C >(dfft_eq)); } LOADFUNC(Load_Init) diff --git a/plugin/seq/ff-get-dep.in b/plugin/seq/ff-get-dep.in index 7b2d4e7d0..6acf4ae65 100755 --- a/plugin/seq/ff-get-dep.in +++ b/plugin/seq/ff-get-dep.in @@ -9,7 +9,7 @@ case "$1" in ;; -dcpp) shift - awk -F: '/^[\/]+ff-c[+][+]-cpp-dep:/ { printf("%s",$2); exit 0;}' $@ + awk -F: '/^[\/]+ff-c[+][+]-cpp-dep:/ { if( $2 ~ /[ \n\r]*/) printf("%s",$2); exit 0;}' $@ exit 0; ;; -ff) diff --git a/plugin/seq/geophysics.cpp b/plugin/seq/geophysics.cpp index 2808d72a6..6f6910fd4 100644 --- a/plugin/seq/geophysics.cpp +++ b/plugin/seq/geophysics.cpp @@ -166,6 +166,98 @@ double Overthrust3d_eval(Overthrust3d *const &a, const double &xi, const double return (*a->tab)(ix, iy, iz); } +class Crustal3d { + public: + string *file; + KNMK< float > *tab; + + int mo_file_nx, mo_file_ny, mo_file_nz; + double mo_file_xend, mo_file_xstart; + double mo_file_yend, mo_file_ystart; + double mo_file_zend, mo_file_zstart; + double mo_file_dx, mo_file_dy, mo_file_dz; + + void init( ) { + file = 0; + tab = 0; + } + void destroy( ) { + delete file; + delete tab; + } +}; + +Crustal3d *init_Crustal3d(Crustal3d *const &a, string *const &s, KN *const& bounds) { + if (verbosity) cout << "Reading Crustal Model file " << *s << endl; + a->file = new string(*s); + + ifstream f((*a->file).c_str( ), ios::in | ios::binary); + if (!f.is_open( )) { + cerr << "Error opening " << (*a->file).c_str( ) << ": file does not exist." << endl; + ffassert(f.is_open( )); + } + + double h = 0.1; + + KN& bnds = *bounds; + + int ixl = max(0,min(1020,(int)floor(bnds[0]/h-1))); + int ixu = max(0,min(1020,(int)ceil(bnds[1]/h+1))); + int iyl = max(0,min(200,(int)floor(bnds[2]/h-1))); + int iyu = max(0,min(200,(int)ceil(bnds[3]/h+1))); + int izl = max(0,min(283,(int)floor((28.3+bnds[4])/h-1))); + int izu = max(0,min(283,(int)ceil((28.3+bnds[5])/h+1))); + + int nx = ixu-ixl+1; + int ny = iyu-iyl+1; + int nz = izu-izl+1; + + int sz = nx*ny*nz; + a->mo_file_nx = nx; + a->mo_file_xstart = ixl*h; + a->mo_file_xend = ixu*h; + a->mo_file_dx = (a->mo_file_xend - a->mo_file_xstart)/(a->mo_file_nx-1); + a->mo_file_ny = ny; + a->mo_file_ystart = iyl*h; + a->mo_file_yend = iyu*h; + a->mo_file_dy = (a->mo_file_yend - a->mo_file_ystart)/(a->mo_file_ny-1); + a->mo_file_nz = nz; + a->mo_file_zstart = -28.3+izl*h; + a->mo_file_zend = -28.3+izu*h; + a->mo_file_dz = (a->mo_file_zend - a->mo_file_zstart)/(a->mo_file_nz-1); + + int ix, iy, iz; + + a->tab = new KNMK< float >(nx,ny,nz); + + float *buff = new float[nz]; + + for (iy = 0; iy < a->mo_file_ny; iy++) + for (ix = 0; ix < a->mo_file_nx; ix++) { + f.seekg((284L * 1021L * (long)(iy+iyl) + 284L * (long)(ix+ixl) + (long)(284 -1 -izu)) * (long)sizeof(float)); + f.read((char *)buff, nz * sizeof(float)); + for (iz = 0; iz < a->mo_file_nz; iz++) + (*a->tab)(ix, iy, nz -1 -iz) = buff[iz]; + } + + delete[] buff; + + f.close( ); + return a; +} + +double Crustal3d_eval(Crustal3d *const &a, const double &xi, const double &yi, + const double &zi) { + int ix = (a->mo_file_nx-1) * (xi - a->mo_file_xstart + a->mo_file_dx/2) / (a->mo_file_xend - a->mo_file_xstart); + int iy = (a->mo_file_ny-1) * (yi - a->mo_file_ystart + a->mo_file_dy/2) / (a->mo_file_yend - a->mo_file_ystart); + int iz = (a->mo_file_nz-1) * (zi - a->mo_file_zstart + a->mo_file_dz/2) / (a->mo_file_zend - a->mo_file_zstart); + ix = max(0, min(ix, a->mo_file_nx - 1)); + iy = max(0, min(iy, a->mo_file_ny - 1)); + iz = max(0, min(iz, a->mo_file_nz - 1)); + + return (*a->tab)(ix, iy, iz); +} + static void Load_Init( ) { if (verbosity && mpirank == 0) cout << " load: geophysics " << endl; @@ -189,5 +281,13 @@ static void Load_Init( ) { atype< Overthrust3d * >( )->Add( "(", "", new OneOperator4_< double, Overthrust3d *, double, double, double >(Overthrust3d_eval)); + + Dcl_Type< Crustal3d * >(InitP< Crustal3d >, Destroy< Crustal3d >); + zzzfff->Add("Crustal", atype< Crustal3d * >( )); + TheOperators->Add( + "<-", new OneOperator3_< Crustal3d *, Crustal3d *, string *, KN * >(&init_Crustal3d)); + atype< Crustal3d * >( )->Add( + "(", "", + new OneOperator4_< double, Crustal3d *, double, double, double >(Crustal3d_eval)); } LOADFUNC(Load_Init) diff --git a/plugin/seq/iovtk.cpp b/plugin/seq/iovtk.cpp index b9eba559c..f1f7fbbe2 100644 --- a/plugin/seq/iovtk.cpp +++ b/plugin/seq/iovtk.cpp @@ -324,6 +324,99 @@ void VTU_PIECE(FILE *fp, const int &nv, const int &nc) { fprintf(fp, "\n", nv, nc); } +//---------------------------------------------------------------------------------// +// A function to output a .pvtu file for ParaView usage when PETSc or HPDDM is used +//---------------------------------------------------------------------------------// +void PvtuWriter(string*& pffname, const int size, const int time, const string base_filename, const string CellDataArrayForPvtu, const string PointDataArrayForPvtu) { + std::ostringstream marker; + marker << std::setw(to_string(size).length()) << std::setfill('0') << "0"; + std::string zero; + if (size > 1) + zero = "_" + marker.str() + ".vtu"; + else + zero = ".vtu"; + std::string full_filename(*pffname); + std::size_t found = full_filename.find(zero); + if (found != std::string::npos) { + std::string file_without_extension; + if (size > 1) + file_without_extension = full_filename.substr(0, found - 6 - string(to_string(size)).length()); + else + file_without_extension = full_filename.substr(0, found - 5); + std::string T = std::string(4 - string(to_string(time)).length(), '0') + to_string(time); + ofstream pvtu; + pvtu.open(file_without_extension + (size > 1 ? "_" + to_string(size) : "") + "_" + T + ".pvtu"); + pvtu << "\n" + "\n" + " \n" + " \n" + "" + PointDataArrayForPvtu + "" + " \n" + " \n" + " \n" + "" + CellDataArrayForPvtu + "" + " \n" + " \n" + " \n" + " \n"; + for (int i = 0; i < size; ++i) { + pvtu << " 1) + pvtu << to_string(size) + "_"; + pvtu << std::setw(4) << std::setfill('0') << time; + if (size > 1) + pvtu << "_" << std::setw(to_string(size).length()) << std::setfill('0') << i; + pvtu << ".vtu\"/>\n"; + } + pvtu << " \n" + "\n"; + } +} + +//--------------------------------------------------------------------------------// +// A function to output a .pvd file for ParaView usage when PETSc or HPDDM is used +//--------------------------------------------------------------------------------// +void PvdWriter(string*& pffname, const int size, const int time, const string base_filename, const string CellDataArrayForPvtu, const string PointDataArrayForPvtu) { + std::ostringstream marker; + marker << std::setw(to_string(size).length()) << std::setfill('0') << "0"; + std::string zero; + if (size > 1) + zero = "_" + marker.str() + ".vtu"; + else + zero = ".vtu"; + std::string full_filename(*pffname); + std::size_t found = full_filename.find(zero); + if (found != std::string::npos) { + std::string file_without_extension; + if (size > 1) + file_without_extension = full_filename.substr(0, found - 6 - string(to_string(size)).length()); + else + file_without_extension = full_filename.substr(0, found - 5); + ofstream pvd; + pvd.open(file_without_extension + (size > 1 ? "_" + to_string(size) : "") + ".pvd"); + pvd << "\n" + "\n" + " \n"; + for (int t = 0; t < time + 1; ++t) { + pvd << " 1) + pvd << to_string(size) + "_"; + pvd << std::setw(4) << std::setfill('0') << t; + pvd << ".pvtu\"/>\n"; + } + pvd << " \n" + "\n"; + } +} + void VTU_DATA_ARRAY(FILE *fp, const string &type, const string &name, bool binary) { fprintf(fp, "\n"); - fprintf(fp, "\n", Th.nv, nc); + fprintf(fp, "\n", Th.nv, nc); fprintf(fp, "\n"); fprintf(fp, "\n"); - fprintf(fp, "\n", Th.nv, nc); + fprintf(fp, "\n", Th.nv, nc); fprintf(fp, "\n"); fprintf(fp, "\n"); fprintf(fp, "\n"); - fprintf(fp, "\n", Th.nv, nc); + fprintf(fp, "\n", Th.nv, nc); fprintf(fp, "\n"); fprintf(fp, "((*nargs[6])(stack)); } #ifdef COMMON_HPDDM_PARALLEL_IO + int time, size; + string base_filename; + std::string CellDataArrayForPvtu = ""; + std::string PointDataArrayForPvtu = ""; parallelIO(pffname, nargs[7] ? (MPI_Comm *)GetAny< pcommworld >((*nargs[7])(stack)) : 0, - nargs[8] && GetAny< bool >((*nargs[8])(stack))); + nargs[8] && GetAny< bool >((*nargs[8])(stack)), time, size, base_filename); #endif int datasize = floatmesh ? sizeof(float) : sizeof(double); @@ -2946,9 +3043,15 @@ AnyType VTK_WriteMesh_Op::operator( )(Stack stack) const { for (int ii = 0; ii < nbofsol; ii++) { if (order[ii] == 0) { if (datasize == sizeof(float)) { +#ifdef COMMON_HPDDM_PARALLEL_IO + CellDataArrayForPvtu = CellDataArrayForPvtu + " \n"; +#endif VTU_DATA_ARRAY(fp, "Float32", nameofuser[ii], l[ii].nbfloat, binary); l[ii].writesolutionP0_float(fp, Th, stack, surface, binary, swap, 1); } else if (datasize == sizeof(double)) { +#ifdef COMMON_HPDDM_PARALLEL_IO + CellDataArrayForPvtu = CellDataArrayForPvtu + " \n"; +#endif VTU_DATA_ARRAY(fp, "Float64", nameofuser[ii], l[ii].nbfloat, binary); l[ii].writesolutionP0_double(fp, Th, stack, surface, binary, swap, 1); } @@ -2965,9 +3068,15 @@ AnyType VTK_WriteMesh_Op::operator( )(Stack stack) const { for (int ii = 0; ii < nbofsol; ii++) { if (order[ii] == 1) { if (datasize == sizeof(float)) { +#ifdef COMMON_HPDDM_PARALLEL_IO + PointDataArrayForPvtu = PointDataArrayForPvtu + " \n"; +#endif VTU_DATA_ARRAY(fp, "Float32", nameofuser[ii], l[ii].nbfloat, binary); l[ii].writesolutionP1_float(fp, Th, stack, binary, swap, 1); } else if (datasize == sizeof(double)) { +#ifdef COMMON_HPDDM_PARALLEL_IO + PointDataArrayForPvtu = PointDataArrayForPvtu + " \n"; +#endif VTU_DATA_ARRAY(fp, "Float64", nameofuser[ii], l[ii].nbfloat, binary); l[ii].writesolutionP1_double(fp, Th, stack, binary, swap, 1); } @@ -2982,6 +3091,10 @@ AnyType VTK_WriteMesh_Op::operator( )(Stack stack) const { fprintf(fp, "\n"); fprintf(fp, "\n"); fprintf(fp, "\n"); +#ifdef COMMON_HPDDM_PARALLEL_IO + PvtuWriter(pffname, size, time, base_filename, CellDataArrayForPvtu, PointDataArrayForPvtu); + PvdWriter(pffname, size, time, base_filename, CellDataArrayForPvtu, PointDataArrayForPvtu); +#endif } else { cout << " iovtk extension file is not correct (" << VTK_FILE << " != 1 or 2 ) " << endl; ExecError(" iovtk : extension file"); @@ -4144,7 +4257,7 @@ class VTK_WriteMesh3_Op : public E_F0mps { int ddim = 3; int stsize = 6; int sca = 0, vec = 0, ten = 0; - string scas("scalaire"); + string scas("scalar"); string vecs("vector"); string tens("tensor"); @@ -4182,7 +4295,7 @@ class VTK_WriteMesh3_Op : public E_F0mps { // cout << "taille" << a0->size() << endl; if (a0->size( ) != ddim && a0->size( ) != stsize) { CompileError( - "savesol in 3D: vector solution is 3 composant, tensor solution is 6 composant"); + "savesol in 3D: vector solution is 3 components, tensor solution is 6 components"); } if (a0->size( ) == ddim) { @@ -4647,8 +4760,12 @@ AnyType VTK_WriteMesh3_Op::operator( )(Stack stack) const { swap = GetAny< bool >((*nargs[6])(stack)); } #ifdef COMMON_HPDDM_PARALLEL_IO + int time, size; + std::string base_filename; + std::string CellDataArrayForPvtu = ""; + std::string PointDataArrayForPvtu = ""; parallelIO(pffname, nargs[7] ? (MPI_Comm *)GetAny< pcommworld >((*nargs[7])(stack)) : 0, - nargs[8] && GetAny< bool >((*nargs[8])(stack))); + nargs[8] && GetAny< bool >((*nargs[8])(stack)), time, size, base_filename); #endif int datasize = floatmesh ? sizeof(float) : sizeof(double); @@ -4825,10 +4942,16 @@ AnyType VTK_WriteMesh3_Op::operator( )(Stack stack) const { for (int ii = 0; ii < nbofsol; ii++) { if (order[ii] == 0) { if (datasize == sizeof(float)) { +#ifdef COMMON_HPDDM_PARALLEL_IO + CellDataArrayForPvtu = CellDataArrayForPvtu + " \n"; +#endif VTU_DATA_ARRAY(fp, "Float32", nameofuser[ii], l[ii].nbfloat, binary); l[ii].writesolutionP0_float(fp, Th, stack, surface, binary, swap, 1); } else if (datasize == sizeof(double)) { VTU_DATA_ARRAY(fp, "Float64", nameofuser[ii], l[ii].nbfloat, binary); +#ifdef COMMON_HPDDM_PARALLEL_IO + CellDataArrayForPvtu = CellDataArrayForPvtu + " \n"; +#endif l[ii].writesolutionP0_double(fp, Th, stack, surface, binary, swap, 1); } @@ -4844,9 +4967,15 @@ AnyType VTK_WriteMesh3_Op::operator( )(Stack stack) const { for (int ii = 0; ii < nbofsol; ii++) { if (order[ii] == 1) { if (datasize == sizeof(float)) { +#ifdef COMMON_HPDDM_PARALLEL_IO + PointDataArrayForPvtu = PointDataArrayForPvtu + " \n"; +#endif VTU_DATA_ARRAY(fp, "Float32", nameofuser[ii], l[ii].nbfloat, binary); l[ii].writesolutionP1_float(fp, Th, stack, binary, swap, 1); } else if (datasize == sizeof(double)) { +#ifdef COMMON_HPDDM_PARALLEL_IO + PointDataArrayForPvtu = PointDataArrayForPvtu + " \n"; +#endif VTU_DATA_ARRAY(fp, "Float64", nameofuser[ii], l[ii].nbfloat, binary); l[ii].writesolutionP1_double(fp, Th, stack, binary, swap, 1); } @@ -4860,6 +4989,10 @@ AnyType VTK_WriteMesh3_Op::operator( )(Stack stack) const { ENDTYPE_VTU(fp, "Piece"); ENDTYPE_VTU(fp, "UnstructuredGrid"); ENDTYPE_VTU(fp, "VTKFile"); +#ifdef COMMON_HPDDM_PARALLEL_IO + PvtuWriter(pffname, size, time, base_filename, CellDataArrayForPvtu, PointDataArrayForPvtu); + PvdWriter(pffname, size, time, base_filename, CellDataArrayForPvtu, PointDataArrayForPvtu); +#endif } else { cout << "extension file of VTK is not correct" << endl; exit(1); @@ -5442,7 +5575,7 @@ class VTK_WriteMeshT_Op : public E_F0mps { int ddim = 3; int stsize = 3; int sca = 0, vec = 0, ten = 0; - string scas("scalaire"); + string scas("scalar"); string vecs("vector"); string tens("tensor"); @@ -5477,7 +5610,7 @@ class VTK_WriteMeshT_Op : public E_F0mps { // cout << "taille" << a0->size() << endl; if (a0->size( ) != ddim && a0->size( ) != stsize) { CompileError( - "savesol in 3D: vector solution is 3 composant, tensor solution is 3 composant"); + "savesol in 3D: vector solution is 3 components, tensor solution is 3 components"); } if (a0->size( ) == ddim) { @@ -6720,7 +6853,7 @@ void saveTecplot(const string &file, const Mesh &Th) { * $1 */ #ifndef COMMON_HPDDM_PARALLEL_IO -static void Load_Init( ) { // le constructeur qui ajoute la fonction "splitmesh3" a freefem++ +static void Load_Init( ) { typedef Mesh *pmesh; typedef Mesh3 *pmesh3; typedef MeshS *pmeshS; diff --git a/plugin/seq/msh3.cpp b/plugin/seq/msh3.cpp index 3ecd2aaa2..3d6ccc062 100644 --- a/plugin/seq/msh3.cpp +++ b/plugin/seq/msh3.cpp @@ -52,12 +52,35 @@ using namespace std; // rajout global #include #include +#include +#include #include #include "msh3.hpp" // [[file:msh3.hpp]] #include "splitsimplex.hpp" // [[file:../src/femlib/splitsimplex.hpp]] #include "renumb.hpp" #include +namespace std +{ + template + struct hash > + { + typedef array argument_type; + typedef size_t result_type; + + result_type operator()(const argument_type& a) const + { + hash hasher; + result_type h = 0; + for (result_type i = 0; i < N; ++i) + { + h = h * 31 + hasher(a[i]); + } + return h; + } + }; +} + using namespace Fem2D; int ChangeLab(const map< int, int > &m, int lab); @@ -2640,10 +2663,8 @@ AnyType SetMesh_Op< MMesh >::operator( )(Stack stack) const { int fk, ke = Th.BoundaryElement(i, fk); int fkk, kke = Th.ElementAdj(ke, fkk = fk); bool onborder = (kke == ke) || (kke < 0); - const T &KE(Th[ke]); - TRdHat B = KE.PBord(fk, PtHat2); int iv[B::nv]; for (int j = 0; j < k; j++) iv[j] = Th.operator( )(K[j]); if(rV) { @@ -2653,10 +2674,12 @@ AnyType SetMesh_Op< MMesh >::operator( )(Stack stack) const { int l0, l1 = ChangeLab(mapBref, l0 = K.lab); if (flab) { + const T &KE(Th[ke]); + TRdHat B = KE.PBord(fk, PtHat2); R3 NN = KE.N(fk); double mes = NN.norme( ); NN /= mes; - mp->set(Th, KE(B), B, KE, K.lab, NN, fk); // problem + mp->set(Th, KE(B), B, KE, K.lab, NN, fk); // ok after version 4.10 l1 = GetAny< long >((*flab)(stack)); lmn = min(lmn, bb->lab); lmx = max(lmx, bb->lab); @@ -4286,7 +4309,7 @@ class cubeMesh_Op : public E_F0mps { }; basicAC_F0::name_and_type cubeMesh_Op::name_param[] = { - {"region", &typeid(long)}, {"label", &typeid(KN_< long >)}, {"flags", &typeid(long)}}; + {"region", &typeid(long)}, {"label", &typeid(KN_< long >)}, {"flags", &typeid(long)} }; class cubeMesh : public OneOperator { public: @@ -4321,8 +4344,7 @@ AnyType cubeMesh_Op::operator( )(Stack stack) const { MeshPoint *mp(MeshPointStack(stack)), mps = *mp; long flags = arg(2, stack, 0L); - ; - + double cpu0 = ((double) clock())/CLOCKS_PER_SEC; KN< long > label2; long ll3[] = {1, 2, 3, 4, 5, 6}; KN_< long > l3_(ll3, 6); @@ -4331,6 +4353,7 @@ AnyType cubeMesh_Op::operator( )(Stack stack) const { long region = arg(0, stack, 0L); Mesh *pTh = Carre_(n1, n2, 0, 0, stack, flags, label2, 0L); // WARNING no clean of teh stack in this case (durdur) + double cpu1 = ((double) clock())/CLOCKS_PER_SEC; ffassert(pTh && nlayer > 0); Mesh &Th = *pTh; int nbv = Th.nv; // nombre de sommet @@ -4436,6 +4459,7 @@ AnyType cubeMesh_Op::operator( )(Stack stack) const { exit(1); } } + double cpu2 = ((double) clock())/CLOCKS_PER_SEC; // cas maillage volumique + surfacique Mesh3 *Th3 = build_layer(Th, nlayer, ni, zmin, zmax, maptet, maptrimil, maptrizmax, maptrizmin, @@ -4444,6 +4468,7 @@ AnyType cubeMesh_Op::operator( )(Stack stack) const { // l'on veut pas creer � l'int�rieure delete pTh; + double cpu3 = ((double) clock())/CLOCKS_PER_SEC, cpu4=cpu3; if (xx && yy && zz) { // Mesh3 *Th3= build_layer(Th, nlayer, ni, zmin, zmax); @@ -4473,18 +4498,25 @@ AnyType cubeMesh_Op::operator( )(Stack stack) const { recollement_border = 0; point_confondus_ok = 1; } - + Mesh3 *T_Th3 = Transfo_Mesh3(precis_mesh, *Th3, txx, tyy, tzz, border_only, recollement_elem, recollement_border, point_confondus_ok, 1); + delete Th3; Th3 = T_Th3; } - + cpu4 = ((double) clock())/CLOCKS_PER_SEC; Th3->BuildGTree( ); // A decommenter if (verbosity > 10) { cout << " Cube %%% " << Th3 << endl; } - + double cpu5 = ((double) clock())/CLOCKS_PER_SEC; + if(verbosity>1) + { + cout<< " Cube timers 2d" << cpu1-cpu0 << " ?? "<< cpu2-cpu1 << endl << + " buildlayer: " << cpu3-cpu2 + << " Transfo " << cpu4-cpu3 << " Gtree " << cpu5-cpu4 << " " << endl; + } Add2StackOfPtr2FreeRC(stack, Th3); *mp = mps; return Th3; @@ -7088,11 +7120,12 @@ AnyType ExtractMeshLfromMesh_Op::operator( )(Stack stack) const { } -bool AddLayers(Mesh3 const *const &pTh, KN< double > *const &psupp, long const &nlayer, +template +bool AddLayers(MT const *const &pTh, KN< double > *const &psupp, long const &nlayer, KN< double > *const &pphi) { ffassert(pTh && psupp && pphi); - const int nve = Mesh3::Element::nv; - const Mesh3 &Th = *pTh; + const int nve = MT::Element::nv; + const MT &Th = *pTh; const int nt = Th.nt; const int nv = Th.nv; @@ -7110,126 +7143,36 @@ bool AddLayers(Mesh3 const *const &pTh, KN< double > *const &psupp, long const & u = 0.; for (int k = 0; k < nt; ++k) { - for (int i = 0; i < nve; ++i) { - u[Th(k, i)] += s[k]; - } + if(s[k] > 0.0) + for (int i = 0; i < nve; ++i) + u[Th(k, i)] = 1.0; } - for (int v = 0; v < nv; ++v) { - u[v] = u[v] > 0.; - } - - // cout << " u " << u << endl; - phi += u; s = 0.; for (int k = 0; k < nt; ++k) { for (int i = 0; i < nve; ++i) { - s[k] += u[Th(k, i)]; + if(u[Th(k,i)] > 0.0) + s[k] = 1.0; } } - for (int k = 0; k < nt; ++k) { - s[k] = s[k] > 0.; - } - supp += s; // cout << " s " << s << endl; } // cout << " phi " << phi << endl; - phi *= (1. / nlayer); + if (nlayer > 1) phi *= (1. / nlayer); // supp =s; return true; } - -bool AddLayers(MeshS const *const &pTh, KN< double > *const &psupp, long const &nlayer, - KN< double > *const &pphi) { - ffassert(pTh && psupp && pphi); - const int nve = MeshS::Element::nv; - const MeshS &Th = *pTh; - const int nt = Th.nt; - const int nv = Th.nv; - - KN< double > &supp(*psupp); - KN< double > u(nv), s(nt); - KN< double > &phi(*pphi); - ffassert(supp.N( ) == nt); // P0 - ffassert(phi.N( ) == nv); // P1 - s = supp; - phi = 0.; - - for (int step = 0; step < nlayer; ++step) { - u = 0.; - - for (int k = 0; k < nt; ++k) - for (int i = 0; i < nve; ++i) u[Th(k, i)] += s[k]; - - for (int v = 0; v < nv; ++v) u[v] = u[v] > 0.; - - phi += u; - s = 0.; - - for (int k = 0; k < nt; ++k) - for (int i = 0; i < nve; ++i) s[k] += u[Th(k, i)]; - - for (int k = 0; k < nt; ++k) s[k] = s[k] > 0.; - - supp += s; - } - - phi *= (1. / nlayer); - return true; -} - - -bool AddLayers(MeshL const *const &pTh, KN< double > *const &psupp, long const &nlayer, - KN< double > *const &pphi) { - ffassert(pTh && psupp && pphi); - const int nve = MeshL::Element::nv; - const MeshL &Th = *pTh; - const int nt = Th.nt; - const int nv = Th.nv; - - KN< double > &supp(*psupp); - KN< double > u(nv), s(nt); - KN< double > &phi(*pphi); - ffassert(supp.N( ) == nt); // P0 - ffassert(phi.N( ) == nv); // P1 - s = supp; - phi = 0.; - - for (int step = 0; step < nlayer; ++step) { - u = 0.; - - for (int k = 0; k < nt; ++k) - for (int i = 0; i < nve; ++i) u[Th(k, i)] += s[k]; - - for (int v = 0; v < nv; ++v) u[v] = u[v] > 0.; - - phi += u; - s = 0.; - - for (int k = 0; k < nt; ++k) - for (int i = 0; i < nve; ++i) - s[k] += u[Th(k, i)]; - - for (int k = 0; k < nt; ++k) - s[k] = s[k] > 0.; - - supp += s; - } - - phi *= (1. / nlayer); - return true; -} -Mesh3 *GluMesh3tab(KN< pmesh3 > *const &tab, long const &lab_delete) { +Mesh3 *GluMesh3tab(KN< pmesh3 > *const &tab, long const &lab_delete, bool const &legacy) { int flagsurfaceall = 0; // variables for mesh3 (volume) int nbt = 0; @@ -7269,11 +7212,12 @@ Mesh3 *GluMesh3tab(KN< pmesh3 > *const &tab, long const &lab_delete) { } } - for (int k = 0; k < Th3.nbe; k++) { - for (int e = 0; e < 3; e++) { - hmin = min(hmin, Th3.be(k).lenEdge(e)); // calcul de .lenEdge pour un Mesh3 + if (legacy) + for (int k = 0; k < Th3.nbe; k++) { + for (int e = 0; e < 3; e++) { + hmin = min(hmin, Th3.be(k).lenEdge(e)); // calcul de .lenEdge pour un Mesh3 + } } - } for (int ii = 0; ii < Th3.nv; ii++) { R3 P(Th3.vertices[ii].x, Th3.vertices[ii].y, Th3.vertices[ii].z); @@ -7286,117 +7230,172 @@ Mesh3 *GluMesh3tab(KN< pmesh3 > *const &tab, long const &lab_delete) { cout << " - hmin =" << hmin << " , Bounding Box: " << Pn << " " << Px << endl; } - // probleme memoire Vertex3 *v = new Vertex3[nbvx]; - Tet *t; - if (nbt != 0) { - t = new Tet[nbt]; - } - - Tet *tt = t; + Tet *t = new Tet[nbt]; Triangle3 *b = new Triangle3[nbex]; Triangle3 *bb = b; ffassert(hmin > Norme2(Pn - Px) / 1e9); double hseuil = hmin / 10.; - - // int *NumSom= new int[nbvx]; - - // VERSION morice - if (verbosity > 4) { - cout << " creation of : BuildGTree" << endl; - } - EF23::GTree< Vertex3 > *gtree = new EF23::GTree< Vertex3 >(v, Pn, Px, 0); - nbv = 0; - for (int i = 0; i < tab->n; i++) { - const Mesh3 &Th3(*tab->operator[](i)); - if (verbosity > 4) { - cout << " loop over mesh for create new mesh " << endl; - } + if (legacy) { + // probleme memoire + for (int i = 0; i < tab->n; i++) { + const Mesh3 &Th3(*tab->operator[](i)); - if (verbosity > 1) { - cout << " -- GluMesh3D + " << Th3.nv << " " << Th3.nt << " " << Th3.nbe << endl; - } + if (verbosity > 4) { + cout << " loop over mesh for create new mesh " << endl; + } - for (int ii = 0; ii < Th3.nv; ii++) { - const Vertex3 &vi(Th3.vertices[ii]); - Vertex3 *pvi = gtree->ToClose(vi, hseuil); + if (verbosity > 1) { + cout << " -- GluMesh3D + " << Th3.nv << " " << Th3.nt << " " << Th3.nbe << endl; + } - if (!pvi) { - v[nbv].x = vi.x; - v[nbv].y = vi.y; - v[nbv].z = vi.z; - v[nbv].lab = vi.lab; - gtree->Add(v[nbv]); - nbv++; + for (int ii = 0; ii < Th3.nv; ii++) { + const Vertex3 &vi(Th3.vertices[ii]); + Vertex3 *pvi = gtree->ToClose(vi, hseuil); + + if (!pvi) { + v[nbv].x = vi.x; + v[nbv].y = vi.y; + v[nbv].z = vi.z; + v[nbv].lab = vi.lab; + gtree->Add(v[nbv]); + nbv++; + } } - } - for (int k = 0; k < Th3.nt; k++) { - const Tet &K(Th3.elements[k]); - int iv[Tet::nea]; - for (int iea = 0; iea < Tet::nea; iea++) iv[iea] = gtree->ToClose(K[iea], hseuil) - v; + for (int k = 0; k < Th3.nt; k++) { + const Tet &K(Th3.elements[k]); + int iv[Tet::nea]; + for (int iea = 0; iea < Tet::nea; iea++) iv[iea] = gtree->ToClose(K[iea], hseuil) - v; - (tt++)->set(v, iv, K.lab); + (t++)->set(v, iv, K.lab); + } } - } - if (verbosity > 4) { - cout << " creation of : BuildGTree for border elements" << endl; - } + if (verbosity > 4) { + cout << " creation of : BuildGTree for border elements" << endl; + } - Vertex3 *becog = new Vertex3[nbex]; + Vertex3 *becog = new Vertex3[nbex]; - EF23::GTree< Vertex3 > *gtree_be = new EF23::GTree< Vertex3 >(becog, Pn, Px, 0); - double hseuil_border = hseuil / 3; + EF23::GTree< Vertex3 > *gtree_be = new EF23::GTree< Vertex3 >(becog, Pn, Px, 0); + double hseuil_border = hseuil / 3; - for (int i = 0; i < tab->n; i++) { - const Mesh3 &Th3(*tab->operator[](i)); - R2 PtHat(1. / 3., 1. / 3.); - for (int k = 0; k < Th3.nbe; k++) { - const Triangle3 &K(Th3.be(k)); - if ((K.lab != lab_delete)) { - int iv[3]; - for (int ii = 0; ii < 3; ii++) iv[ii] = Th3.operator( )(K[ii]); + for (int i = 0; i < tab->n; i++) { + const Mesh3 &Th3(*tab->operator[](i)); + R2 PtHat(1. / 3., 1. / 3.); + for (int k = 0; k < Th3.nbe; k++) { + const Triangle3 &K(Th3.be(k)); + if ((K.lab != lab_delete)) { + int iv[3]; + for (int ii = 0; ii < 3; ii++) iv[ii] = Th3.operator( )(K[ii]); - const Vertex3 &vi(K(PtHat)); - Vertex3 *pvi = gtree_be->ToClose(vi, hseuil_border); - if (!pvi) { - becog[nbe].x = vi.x; - becog[nbe].y = vi.y; - becog[nbe].z = vi.z; - becog[nbe].lab = vi.lab; - gtree_be->Add(becog[nbe++]); + const Vertex3 &vi(K(PtHat)); + Vertex3 *pvi = gtree_be->ToClose(vi, hseuil_border); + if (!pvi) { + becog[nbe].x = vi.x; + becog[nbe].y = vi.y; + becog[nbe].z = vi.z; + becog[nbe].lab = vi.lab; + gtree_be->Add(becog[nbe++]); - int igluv[3]; - for (int i = 0; i < 3; i++) igluv[i] = gtree->ToClose(K[i], hseuil) - v; + int igluv[3]; + for (int i = 0; i < 3; i++) igluv[i] = gtree->ToClose(K[i], hseuil) - v; - (bb++)->set(v, igluv, K.lab); + (bb++)->set(v, igluv, K.lab); + } } } } - } - delete gtree; - delete gtree_be; - delete[] becog; + delete gtree; + delete gtree_be; + delete[] becog; - if (verbosity > 4) { - cout << " nbv=" << nbv << endl; - cout << " nbvx=" << nbvx << endl; - cout << " nbt=" << nbt << endl; - cout << " nbe=" << nbe << endl; - cout << " nbex=" << nbex << endl; - } + if (verbosity > 4) { + cout << " nbv=" << nbv << endl; + cout << " nbvx=" << nbvx << endl; + cout << " nbt=" << nbt << endl; + cout << " nbe=" << nbe << endl; + cout << " nbex=" << nbex << endl; + } - if (verbosity > 1) { - cout << " Nb of glu3D point " << nbvx - nbv; - cout << " Nb of glu3D Boundary faces " << nbex - nbe << endl; + if (verbosity > 1) { + cout << " Nb of glu3D point " << nbvx - nbv; + cout << " Nb of glu3D Boundary faces " << nbex - nbe << endl; + } } - + else { + int** idx; + idx = new int*[tab->n + 1]; + *idx = new int[nbvx]; + std::fill_n(*idx, nbvx, -1); + nbvx = 0; + for (int i = 0; i < tab->n; i++) { + const Mesh3& Th3(*tab->operator[](i)); + idx[i+1] = idx[i] + Th3.nv; + for (int k = 0; k < Th3.nbe; k++) { + const Triangle3& K(Th3.be(k)); + for (int p = 0; p < 3; p++) { + const int iv = Th3.operator()(K[p]); + const Vertex3 &vi(Th3.vertices[iv]); + Vertex3 *pvi = gtree->ToClose(vi, hseuil); + if (!pvi) { + v[nbv].x = vi.x; + v[nbv].y = vi.y; + v[nbv].z = vi.z; + v[nbv].lab = vi.lab; + gtree->Add(v[nbv]); + idx[i][iv] = nbv++; + } else idx[i][iv] = pvi - v; + } + } + } + std::unordered_set> boundary; + boundary.reserve(nbex); + for (int i = 0; i < tab->n; i++) { + const Mesh3& Th3(*tab->operator[](i)); + for (int j = 0; j < Th3.nv; j++) { + if (idx[i][j] == -1) { + const Vertex3 &vi(Th3.vertices[j]); + v[nbv].x = vi.x; + v[nbv].y = vi.y; + v[nbv].z = vi.z; + v[nbv].lab = vi.lab; + gtree->Add(v[nbv]); + idx[i][j] = nbv++; + } + } + for (int k = 0; k < Th3.nt; k++) { + const Tet& K(Th3.elements[k]); + int iv[4]; + for (int iea = 0; iea < 4; iea++) iv[iea] = idx[i][Th3.operator()(K[iea])]; + (t++)->set(v, iv, K.lab); + } + for (int k = 0; k < Th3.nbe; k++) { + const Triangle3& K(Th3.be(k)); + if (K.lab != lab_delete) { + int iv[3]; + for (int p = 0; p < 3; p++) iv[p] = idx[i][Th3.operator()(K[p])]; + std::array sort; + std::copy_n(iv, 3, sort.begin()); + std::sort(sort.begin(), sort.end()); + if(boundary.find(sort) == boundary.end()) { + (bb++)->set(v, iv, K.lab); + boundary.insert(sort); + } + } + } + } + nbe = bb - b; + delete[] *idx; + delete[] idx; + } + t -= nbt; Mesh3 *mpq = new Mesh3(nbv, nbt, nbe, v, t, b); mpq->BuildGTree( ); @@ -7410,12 +7409,15 @@ struct Op_GluMesh3tab : public OneOperator { class Op : public E_F0mps { public: static basicAC_F0::name_and_type name_param[]; - static const int n_name_param = 1; + static const int n_name_param = 2; Expression nargs[n_name_param]; Expression getmeshtab; long arg(int i, Stack stack, long a) const { return nargs[i] ? GetAny< long >((*nargs[i])(stack)) : a; } + bool arg(int i, Stack stack, bool a) const { + return nargs[i] ? GetAny< bool >((*nargs[i])(stack)) : a; + } Op(const basicAC_F0 &args, Expression t) : getmeshtab(t) { args.SetNameParam(n_name_param, name_param, nargs); @@ -7463,11 +7465,13 @@ struct Op_GluMeshTtab : public OneOperator { basicAC_F0::name_and_type Op_GluMesh3tab::Op::name_param[Op_GluMesh3tab::Op::n_name_param] = { - {"labtodel", &typeid(long)}}; + {"labtodel", &typeid(long)}, + {"legacy", &typeid(bool)}}; AnyType Op_GluMesh3tab::Op::operator( )(Stack stack) const { KN< const Mesh3 * > *tab = GetAny< KN< const Mesh3 * > * >((*getmeshtab)(stack)); long labtodel = arg(0, stack, LONG_MIN); - Mesh3 *Tht = GluMesh3tab(tab, labtodel); + bool legacy = arg(1, stack, false); + Mesh3 *Tht = GluMesh3tab(tab, labtodel, legacy); Add2StackOfPtr2FreeRC(stack, Tht); return Tht; @@ -7859,6 +7863,8 @@ Mesh3 *BuildCube(long nx, long ny, long nz, long region, long *label, long kind, int debug = verbosity / 10; int codesb[64], kcode[20]; int kstable = 0; + double cpu0 = ((double) clock())/CLOCKS_PER_SEC; + if (debug) { cout << " Enter: BuildCube: " << kind << endl; } @@ -8017,6 +8023,7 @@ Mesh3 *BuildCube(long nx, long ny, long nz, long region, long *label, long kind, } } } + double cpu1 = ((double) clock())/CLOCKS_PER_SEC; Tet *tff = new Tet[nt]; Triangle3 *bff = new Triangle3[nbe]; @@ -8095,8 +8102,14 @@ Mesh3 *BuildCube(long nx, long ny, long nz, long region, long *label, long kind, if (debug) { cout << " Out: BuildCube" << endl; } + double cpu2 = ((double) clock())/CLOCKS_PER_SEC; - return new Mesh3(nv, nt, nbe, vff, tff, bff); + Mesh3 * Th3= new Mesh3(nv, nt, nbe, vff, tff, bff); + double cpu3 = ((double) clock())/CLOCKS_PER_SEC; + if(verbosity>1) + cout << " cube timers "<< cpu1-cpu0 << " " < *, long, KN< double > * >(AddLayers)); + new OneOperator4_< bool, const Mesh3 *, KN< double > *, long, KN< double > * >(AddLayers)); Global.Add("bcube", "(", new cubeMesh); Global.Add("bcube", "(", new cubeMesh(1)); @@ -9568,8 +9581,8 @@ static void Load_Init( ) { Global.Add("showborder", "(", new OneOperator1< long, const MeshS * >(ShowBorder)); Global.Add("getborder", "(", new OneOperator2< long, const MeshS *, KN< long > * >(GetBorder)); - Global.Add("AddLayers", "(", new OneOperator4_< bool, const MeshS *, KN< double > *, long, KN< double > * >(AddLayers)); - Global.Add("AddLayers", "(", new OneOperator4_< bool, const MeshL *, KN< double > *, long, KN< double > * >(AddLayers)); + Global.Add("AddLayers", "(", new OneOperator4_< bool, const MeshS *, KN< double > *, long, KN< double > * >(AddLayers)); + Global.Add("AddLayers", "(", new OneOperator4_< bool, const MeshL *, KN< double > *, long, KN< double > * >(AddLayers)); Global.Add("square3", "(", new Square); Global.Add("square3", "(", new Square(1)); diff --git a/plugin/seq/shell.cpp b/plugin/seq/shell.cpp index 86da40090..5c2ff4cf0 100644 --- a/plugin/seq/shell.cpp +++ b/plugin/seq/shell.cpp @@ -211,12 +211,12 @@ string dirname(const string *ppath) { } } - if (i == 0) { + if (i == -1) { return "."; - } else if (i == 1) { + } else if (i == 0) { return "/"; } else { - return path.substr(0, i - 1); + return path.substr(0, i); } } diff --git a/readme/COPYING b/readme/COPYING new file mode 100644 index 000000000..de52d6377 --- /dev/null +++ b/readme/COPYING @@ -0,0 +1,28 @@ +// +// SUMMARY: FreeFem++ +// RELEASE: 2 +// USAGE : +// AUTHOR: F. Hecht, O. Pironneau +// ORG : Université Pierre et Marie Curie, Paris, France +// E-MAIL : Hecht@ann.jussieu.fr +// +// ORIG-DATE: November 2001 +/* + + This file is part of Freefem++ + + Freefem++ is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + Freefem++ is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with Freefem++; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ \ No newline at end of file diff --git a/readme/README_COMPILATION.md b/readme/README_COMPILATION.md index b8610042e..e61abbb00 100644 --- a/readme/README_COMPILATION.md +++ b/readme/README_COMPILATION.md @@ -3,18 +3,18 @@ - + - + - + # Compilation of FreeFem++ and bamg (mesh generator) under Unix, MacOs X or MinGW (Windows) diff --git a/readme/README_GIT.md b/readme/README_GIT.md index e5b3c5635..1071aa0a3 100644 --- a/readme/README_GIT.md +++ b/readme/README_GIT.md @@ -3,18 +3,18 @@ - + - + - + diff --git a/readme/README_MAC.md b/readme/README_MAC.md index c00ad1f02..846007fa7 100644 --- a/readme/README_MAC.md +++ b/readme/README_MAC.md @@ -3,23 +3,98 @@ - + - + - + # How to compile FreeFem++ on MacOSX -_october 2015_ +## Feb 2022 + +The Version 4.10 is compiled Under Monteray (Apple M1: arm64e) and on (Apple : x86 ) + +### for Apple M1 (arm64e) + +Add with home brew +1) install brew see +[install Homebrew]{https://brew.sh/index_fr} + + +2) install this brew package to compile FreeFEM++ + +```bash +brew install \ +aom gettext jpeg libx11 pango \ +autoconf giflib jpeg-xl libxau pcre \ +automake glib libavif libxcb pixman \ +bdw-gc gmp libcerf libxdmcp pkg-config \ +bison gnuplot libevent libxext python@3.9 \ +brotli gnutls libffi libxrender qt@5 \ +ca-certificates gobject-introspection libidn2 lua readline \ +cairo graphite2 libmpc lzo sqlite \ +emacs gsl libnghttp2 m4 szip \ +flex guile libpng make unbound \ +fontconfig harfbuzz libpthread-stubs mpdecimal webp \ +freetype hdf5 libtasn1 mpfr wget \ +fribidi icu4c libtiff nettle xorgproto \ +gcc imath libtool openexr xz \ +gd isl libunistring openssl@1.1 zip \ +gdbm jansson libvmaf p11-kit zstd +``` + +3) download the sources of FreeFEM++ with git + + ```bash + git clone git@github.com:FreeFem/FreeFem-sources.git ff++ + ``` +or the develop version + + ```bash + git clone -b develop git@github.com:FreeFem/FreeFem-sources.git ff++ + ``` +4) Compile FreeFem++ without petsc and MPI + + ```bash + cd ff++ + autoreconf -i + ./configure --enable-summary --enable-download_arpack --prefix=/Applications/FreeFem++.app/Contents/ff-4.10/ --enable-download --enable-optim --enable-m64 F77=gfortran FC=gfortran CXXFLAGS=-Wno-undefined-var-template --enable-maintainer-mode + make + sudo make install + ``` + +4) Compile FreeFem++ with PETSc and MPI + +```bash + cd ff++ + autoreconf -i + ./configure --enable-summary --enable-download_arpack --prefix=/Applications/FreeFem++.app/Contents/ff-4.10/ --enable-download --enable-optim --enable-m64 F77=gfortran FC=gfortran CXXFLAGS=-Wno-undefined-var-template --enable-maintainer-mode + cd 3rdparty/ff-petsc + make +``` + follow the output +```bash + cd - + ./reconfigure + make -j 20 + # check your version ... + make -j 20 check + # to install in /Applications/FreeFem++.app/Contents/ff-4.10/ + sudo make install -j 20 + +``` + + +## _october 2015_ (oldies) The version 3.41 is compiled Under Yosemite (10.10.5), xcode 7.0.1 + previous install of latex and with other brew install diff --git a/readme/README_WINDOWS.md b/readme/README_WINDOWS.md index 01c175a42..844dbe045 100644 --- a/readme/README_WINDOWS.md +++ b/readme/README_WINDOWS.md @@ -3,18 +3,18 @@ - + - + - + # How to compile FreeFem++ on Microsoft Windows diff --git a/readme/README_XCODE.md b/readme/README_XCODE.md index a536bfdf2..3a497fae1 100644 --- a/readme/README_XCODE.md +++ b/readme/README_XCODE.md @@ -3,18 +3,18 @@ - + - + - + # The MacOS version can be built with Xcode diff --git a/src/bin-win32/launchff++.cpp b/src/bin-win32/launchff++.cpp index 64a5543e2..3bd528f66 100644 --- a/src/bin-win32/launchff++.cpp +++ b/src/bin-win32/launchff++.cpp @@ -20,6 +20,10 @@ // AUTHORS : Frederic Hecht // E-MAIL : frederic.hecht@sorbonne-universite.fr +#define NOMINMAX 1 +#define byte win_byte_override +#include + #include #include #include @@ -28,7 +32,6 @@ #include #include using namespace std; -#include const char C = '"'; diff --git a/src/femlib/GenericMesh.hpp b/src/femlib/GenericMesh.hpp index 52fc6fbeb..26b27912f 100644 --- a/src/femlib/GenericMesh.hpp +++ b/src/femlib/GenericMesh.hpp @@ -275,8 +275,9 @@ class GenericVertex : public Rn,public Label template<> inline R3 ExtNormal<1>( GenericVertex *const v[2],int const f[1]) { R3 Nn; - if(f[0]==0) Nn=R3(*v[1],*v[0])-R3(*v[0]); - else if(f[0]==1) Nn=R3(*v[0],*v[1])+R3(*v[1]); + if(f[0]==0) Nn=R3(*v[1],*v[0]);//-R3(*v[0]); + else if(f[0]==1) Nn=R3(*v[0],*v[1]);//+R3(*v[1]); + if (verbosity>99) cout << "\n( ExtNormal<1> " << Nn << " v0 " << *v[0] << " v1 " << *v[1]<< " 0/1: " << f[0] << ")" << endl; return Nn; } // Clever the orientation in case of only 1 vertex april 2019 (Hard to find !!!!! FH and PHT) diff --git a/src/femlib/HashMatrix.cpp b/src/femlib/HashMatrix.cpp index b32e4b2f2..2b452ecb2 100644 --- a/src/femlib/HashMatrix.cpp +++ b/src/femlib/HashMatrix.cpp @@ -1214,7 +1214,7 @@ void HashMatrix::SetBC(char *wbc,double ttgv) else operator()(ii,ii)=ttgv; } - if(std::abs(ttgv+2.0) < 1.0e-10 || std::abs(ttgv+20.0) < 1.0e-10) // remove also columm tgv == -2 ..... + if( std::abs(ttgv+2.0) < 1.0e-10 || std::abs(ttgv+20.0) < 1.0e-10) // remove also columm tgv == -2 ..... { CSC(); for(I jj=0; jj< this->n; ++jj) diff --git a/src/femlib/HashTable.hpp b/src/femlib/HashTable.hpp index 18a16f6fa..c489ae69f 100644 --- a/src/femlib/HashTable.hpp +++ b/src/femlib/HashTable.hpp @@ -56,7 +56,8 @@ struct SortArray { { return v[0] == t.v[0] && v[1] == t.v[1] ;} bool operator<(const SortArray & t) const { return v[0] != t.v[0] ? v[0] < t.v[0] : v[1] < t.v[1] ;} - size_t hash() const {return (size_t) v[0] + rotl(v[1],2) ;} + //size_t hash() const {return (size_t) v[0] + rotl(v[1],2) ;} + size_t hash() const {return (size_t) v[0] + 257LU*(size_t) v[0] ;} }; @@ -85,7 +86,8 @@ struct SortArray { bool operator<(const SortArray & t) const { return v[0] != t.v[0] ? v[0] < t.v[0] : ( v[1] != t.v[1] ? v[1] < t.v[1] : v[2] < t.v[2] );} - size_t hash() const {return (size_t) v[0] + rotl(v[1],2) * rotl(v[2],4) ;} + //size_t hash() const {return (size_t) v[0] + rotl(v[1],2) * rotl(v[2],4) ;} + size_t hash() const {return (size_t) v[0] + 257LU*(size_t) v[1] + 49993LU*(size_t) v[2] ;} // size_t hash() const {return (size_t) v[0];} }; @@ -125,7 +127,8 @@ struct SortArray { ( v[1] != t.v[1] ? v[1] < t.v[1] : ( v[2] != t.v[2] ? v[2] < t.v[2]: v[3] < t.v[3] ));} - size_t hash() const {return (size_t) v[0] + rotl(v[1],2) + rotl(v[2],4) + rotl(v[3],6);} +// size_t hash() const {return (size_t) v[0] + rotl(v[1],2) + rotl(v[2],4) + rotl(v[3],6);} + size_t hash() const {return (size_t) v[0] + 257LU*(size_t) v[1] + 66067LU*(size_t) v[2] +16974611LU*(size_t) v[3] ;} }; diff --git a/src/femlib/Mesh3dn.cpp b/src/femlib/Mesh3dn.cpp index be543b431..50489d936 100644 --- a/src/femlib/Mesh3dn.cpp +++ b/src/femlib/Mesh3dn.cpp @@ -1417,7 +1417,8 @@ namespace Fem2D vertices = vv; elements = tt; borderelements = bb; - + double cpu0 = ((double) clock())/CLOCKS_PER_SEC; + // check the input mesh file format if(verbosity && nv==0) { cerr << " WARNING! The mesh file doesn't contain any vertex" << endl; @@ -1463,16 +1464,24 @@ namespace Fem2D } // Add FH to be consitant we all constructor ... July 09 BuildBound(); + double cpu1 = ((double) clock())/CLOCKS_PER_SEC; + double cpu2=cpu1,cpu3=cpu1,cpu4=cpu1,cpu5=cpu1; if(nt && nbe) { BuildAdj(); + cpu2 = ((double) clock())/CLOCKS_PER_SEC; Buildbnormalv(); + cpu3 = ((double) clock())/CLOCKS_PER_SEC; BuildjElementConteningVertex(); + cpu4 = ((double) clock())/CLOCKS_PER_SEC; BuildGTree(); + cpu5 = ((double) clock())/CLOCKS_PER_SEC; } // end add if(verbosity>1) cout << " -- End of read: mesure = " << mes << " border mesure " << mesb << endl; - + if(verbosity>3) + cout << " timers Mesh3 :"<< cpu1-cpu0 << " "<< cpu2-cpu1 + << " " << cpu3-cpu2 << " " << cpu4-cpu3 << " " << cpu5-cpu4 <=0.); } diff --git a/src/femlib/Mesh3dn.hpp b/src/femlib/Mesh3dn.hpp index 25c76cedf..78d3c90fe 100644 --- a/src/femlib/Mesh3dn.hpp +++ b/src/femlib/Mesh3dn.hpp @@ -115,13 +115,13 @@ class Tet: public GenericElement { R3 AC(at(nvface[i][0]),at(nvface[i][2])); return AB^AC/(6.*this->mesure());} // heigth - R3 n(int i) const + R3 n(int i) const { ASSERTION(i>=0 && i <4); int nvface[4][3]= {{3,2,1}, {0,2,3},{ 3,1,0},{ 0,1,2}}; R3 AB(at(nvface[i][0]),at(nvface[i][1])); R3 AC(at(nvface[i][0]),at(nvface[i][2])); R3 N=AB^AC; - return N/N.norme();} // exterior normal + return N/-N.norme();} // exterior normal void Gradlambda(R3 * GradL) const { diff --git a/src/femlib/MeshLn.hpp b/src/femlib/MeshLn.hpp index f14eff0c1..91052611d 100755 --- a/src/femlib/MeshLn.hpp +++ b/src/femlib/MeshLn.hpp @@ -144,6 +144,11 @@ namespace Fem2D { R3 N = V; return N/N.norme(); } + R3 n(int i) const// Add jan 2022 FH + { + R3 Tg = TangenteUnitaire(); + if( i==0) Tg = -Tg; + return Tg;} // exterior normal }; diff --git a/src/femlib/MeshSn.hpp b/src/femlib/MeshSn.hpp index bf2d33555..e8d7e7f5b 100755 --- a/src/femlib/MeshSn.hpp +++ b/src/femlib/MeshSn.hpp @@ -96,7 +96,12 @@ typedef GenericVertex Vertex3; for(int i=0 ; i<3 ; i++) GradL[i]= (Edge(i)^Normal) / N; } - + R3 n(int i) const // add Jan 2022 + { + R3 Normal = Edge(2)^Edge(1); + R3 Gi= (Edge(i)^Normal);// interior normal + return Gi/-Gi.norme();} // exterior normal unitary + R3 NormalT() const { ASSERTION(i>=0 && i <3); return R3( Edge(2)^Edge(1) ); diff --git a/src/femlib/P012_3dCurve.cpp b/src/femlib/P012_3dCurve.cpp index cfb1987c1..78616598a 100644 --- a/src/femlib/P012_3dCurve.cpp +++ b/src/femlib/P012_3dCurve.cpp @@ -242,11 +242,112 @@ assert(k==3); } if( whatd & Fop_D2) - ffassert(0); // to DO FH. sorry - } + { + + //cout << " D2 " << endl; + if (whatd & Fop_dxx){ + RN_ f0xx(val('.',0,op_dxx)); + + int k=0; + for(int i=0;i modul == 2*le*area R3 N=K.N(e)*a; for (int c=0;c<3;c++,i++) M.coef[i]=N[c]; @@ -310,12 +310,17 @@ R la=1-PHat.sum(),lb=PHat.x,lc=PHat.y; R3 D[3]; K.Gradlambda(D); + // x = A la + B * lb + C lc + // x = AB lb + AC lc //loc basis R3 AB(A,B),AC(A,C),BA(B,A),BC(B,C),CA(C,A),CB(C,B); + ffassert( abs((AB,D[1]) + (AC,D[2]) -2. ) < 1e-6) ; // verif ... + R divxyz_tK =2.*K.mesure(); R c[3]; - c[0] = 1./(((AB,D[1]) + (AC,D[2])) *K.mesure()) ; c[0]*= K.EdgeOrientation(0) ; - c[1] = 1./(((BA,D[0]) + (BC,D[2])) *K.mesure()) ; c[1]*= K.EdgeOrientation(1); - c[2] = 1./(((CA,D[0]) + (CB,D[1])) *K.mesure()) ; c[2]*= K.EdgeOrientation(2); + + c[0] = K.EdgeOrientation(0)/divxyz_tK ; + c[1] = K.EdgeOrientation(1)/divxyz_tK ; + c[2] = K.EdgeOrientation(2)/divxyz_tK ; R3 f[3]; f[0] = AB*(lb*c[0]) + AC*(lc*c[0]); @@ -439,6 +444,124 @@ ffassert(0); } + class TypeOfFE_RT0ortho_surf : public GTypeOfFE { + public: + typedef MeshS Mesh; + typedef MeshS::Element Element; + typedef GFElement FElement; + static int dfon[]; + static const int d=Mesh::Rd::d; + + TypeOfFE_RT0ortho_surf(); + void FB(const What_d whatd,const Mesh & Th,const Element & K,const RdHat &PHat, RNMK_ & val) const; + void set(const Mesh & Th,const Element & K,InterpolationMatrix & M,int ocoef,int odf,int *nump) const; + } ; + + int TypeOfFE_RT0ortho_surf::dfon[]={0,1,0,0}; // dofs per vertice, edge, face, volume + + + TypeOfFE_RT0ortho_surf::TypeOfFE_RT0ortho_surf(): GTypeOfFE(dfon,d,1,3*3,3,false,true) { + + R2 Pt[]={ R2(0.5,0.5), R2(0.0,0.5), R2(0.5,0.0) }; + + for (int i=0;i<3;++i) + this->PtInterpolation[i]=Pt[i]; + int i=0; + for (int e=0;e<3;e++) //loop on edge + for (int c=0;c<3;c++,i++) { + this->pInterpolation[i]=e; + this->cInterpolation[i]=c; + this->dofInterpolation[i]=e; + this->coefInterpolation[i]=0.; + } + + } + + + + + void TypeOfFE_RT0ortho_surf::set(const Mesh & Th,const Element & K,InterpolationMatrix & M ,int ocoef,int odf,int *nump) const + { + + int i=ocoef; + for (int e=0;e<3;e++) { + R3 Ee=K.Edge(e)*K.EdgeOrientation(e) ; + for (int c=0;c<3;c++,i++) + M.coef[i]=Ee[c]; + } + } + + + void TypeOfFE_RT0ortho_surf::FB(const What_d whatd,const Mesh & Th,const MeshS::Element & K,const RdHat &PHat, RNMK_ & val) const + { + assert(val.N()>=Element::ne); + assert(val.M()==3 ); + val=0; + + R3 A(K[0]),B(K[1]),C(K[2]); + R l0=1-PHat.sum(),l1=PHat.x,l2=PHat.y; + R3 D[3]; + K.Gradlambda(D); + + R3 AB(A,B),AC(A,C),BA(B,A),BC(B,C),CA(C,A),CB(C,B); + R divxyz_tK =((AB,D[1]) + (AC,D[2]))*K.mesure(); + R c[3]; + + c[0] = K.EdgeOrientation(0) ; + c[1] = K.EdgeOrientation(1) ; + c[2] = K.EdgeOrientation(2) ; + + R3 f[3]; + f[0] = (D[1]*l2 - D[2]*l1)*c[0];// 1 2 + f[1] = (D[0]*l2 - D[2]*l0)*c[1]; // 2 0 + f[2] = (D[0]*l1 - D[1]*l0)*c[2]; // 0 1 + + + if (whatd & Fop_D0) + for(int i=0;i<3;i++){ + val(i,0,op_id) = f[i].x; + val(i,1,op_id) = f[i].y; + val(i,2,op_id) = f[i].z; + } + + if (whatd & Fop_D1) { + if (whatd & Fop_dx){ + R3 fx[3]; + fx[0] = (D[1]*D[2].x - D[2]*D[1].x)*c[0];// 1 2 + fx[1] = (D[0]*D[2].x - D[2]*D[0].x)*c[1]; // 2 0 + fx[2] = (D[0]*D[1].x - D[1]*D[0].x)*c[2]; // 0 1 + for(int i=0;i<3;i++){ + val(i,0,op_dx) = fx[i].x; + val(i,1,op_dx) = fx[i].y; + val(i,2,op_dx) = fx[i].z; + } + } + if (whatd & Fop_dy) { + R3 fy[3]; + fy[0] = (D[1]*D[2].y - D[2]*D[1].y)*c[0];// 1 2 + fy[1] = (D[0]*D[2].y - D[2]*D[0].y)*c[1]; // 2 0 + fy[2] = (D[0]*D[1].y - D[1]*D[0].y)*c[2]; // 0 1 + for(int i=0;i<3;i++){ + val(i,0,op_dy) = fy[i].x; + val(i,1,op_dy) = fy[i].y; + val(i,2,op_dy) = fy[i].z; + } + } + if (whatd & Fop_dz) { + R3 fz[3]; + fz[0] = (D[1]*D[2].z - D[2]*D[1].z)*c[0];// 1 2 + fz[1] = (D[0]*D[2].z - D[2]*D[0].z)*c[1]; // 2 0 + fz[2] = (D[0]*D[1].z - D[1]*D[0].z)*c[2]; // 0 1 + for(int i=0;i<3;i++){ + val(i,0,op_dz) = fz[i].x; + val(i,1,op_dz) = fz[i].y; + val(i,2,op_dz) = fz[i].z; + } + } + } + + } + class TypeOfFE_P2bLagrange_surf : public TypeOfFE_Lagrange { public: @@ -544,6 +667,8 @@ GTypeOfFE & P2Lagrange_surf(P2_surf); static TypeOfFE_RT0_surf RT0_surf; GTypeOfFE & RT0surf(RT0_surf); + static TypeOfFE_RT0ortho_surf RT0ortho_surf; + GTypeOfFE & RT0orthosurf(RT0ortho_surf); static TypeOfFE_P1bLagrange_surf P1b_surf; GTypeOfFE & P1bLagrange_surf(P1b_surf); static TypeOfFE_P2bLagrange_surf P2b_surf; diff --git a/src/femlib/R3.hpp b/src/femlib/R3.hpp index c8bcf5592..313761788 100644 --- a/src/femlib/R3.hpp +++ b/src/femlib/R3.hpp @@ -127,6 +127,8 @@ class R3 { R2 p2() const { return R2(x,y);} }; +inline R3 DotStar(const R3 &A,const R3 &B){return R3(A.x*B.x,A.y*B.y,A.y*B.y);} +inline R3 DotDiv(const R3 &A,const R3 &B){return R3(A.x/B.x,A.y/B.y,A.y/B.y);} inline R3 Minc(const R3 & A,const R3 &B){ return R3(min(A.x,B.x),min(A.y,B.y),min(A.z,B.z));} inline R3 Maxc(const R3 & A,const R3 &B){ return R3(max(A.x,B.x),max(A.y,B.y),max(A.z,B.z));} diff --git a/src/femlib/VirtualSolverSparseSuite.hpp b/src/femlib/VirtualSolverSparseSuite.hpp index 069c57c02..56ed04c5f 100644 --- a/src/femlib/VirtualSolverSparseSuite.hpp +++ b/src/femlib/VirtualSolverSparseSuite.hpp @@ -39,7 +39,74 @@ extern "C" { #include "VirtualSolver.hpp" #include +inline void CheckUmfpackStatus(int status) +{ + if(verbosity>4) cout << " CheckUmfpackStatus "<< status << endl; + if( status==0) return; + else if( status>0)// warning .. + { + if(verbosity) + switch (status) { + case 1: + cout << status<< " UMFPACK WARNING singular matrix " < class VirtualSolverUMFPACK: public VirtualSolver { public: @@ -104,7 +171,7 @@ class VirtualSolverUMFPACK : public VirtualSolver { { status= umfpack_di_solve (TS, Ap, Ai, Ax, x+oo, b+oo, Numeric,Control,Info) ; - if(status) cout << " Error umfpack_di_solve status " << status << endl; + CheckUmfpackStatus(status); if(verbosity>3) (void) umfpack_di_report_info(Control,Info); } @@ -123,14 +190,14 @@ class VirtualSolverUMFPACK : public VirtualSolver { A->CSC(Ap,Ai,Ax); if(Symbolic) umfpack_di_free_symbolic (&Symbolic) ; status = umfpack_di_symbolic (A->n, A->m, Ap, Ai, Ax, &Symbolic,Control,Info) ; - if(status) cout << " Error umpfack umfpack_di_symbolic status " << status << endl; + CheckUmfpackStatus(status); } void fac_numeric(){ if(Numeric) umfpack_di_free_numeric (&Numeric) ; if(verb>2 || verbosity> 9) cout << "fac_numeric UMFPACK R: nnz U " << " nnz= " << A->nnz << endl; status = umfpack_di_numeric (Ap, Ai, Ax, Symbolic, &Numeric, Control,Info) ; - if(status) cout << " Error umpfack umfpack_di_numeric status " << status << endl; + CheckUmfpackStatus(status); } ~VirtualSolverUMFPACK() @@ -186,7 +253,7 @@ class VirtualSolverUMFPACK > : public VirtualSolver > : public VirtualSolver2 || verbosity> 9) cout << "fac_symbolic UMFPACK C: nnz= " << A->nnz << endl; if(Symbolic) umfpack_zi_free_symbolic (&Symbolic) ; status = umfpack_zi_symbolic (A->n, A->m, Ap, Ai, Ax,Az, &Symbolic, 0, 0) ; - if(status) cout << " Error umpfack umfpack_zi_symbolic status " << status << endl; + CheckUmfpackStatus(status); } void fac_numeric(){ if(Numeric) umfpack_zi_free_numeric (&Numeric) ; if(verb>2 || verbosity> 9) cout << "fac_numeric UMFPACK C: nnz= " << A->nnz << endl; status = umfpack_zi_numeric (Ap, Ai, Ax,Az, Symbolic, &Numeric, 0, 0) ; - if(status) cout << " Error umpfack umfpack_zi_numeric status " << status << endl; + CheckUmfpackStatus(status); } ~VirtualSolverUMFPACK() @@ -221,7 +288,19 @@ class VirtualSolverUMFPACK > : public VirtualSolver class VirtualSolverCHOLMOD: public VirtualSolver { public: @@ -285,6 +364,7 @@ class VirtualSolverCHOLMOD : public VirtualSolver { { cholmod_start (&c) ; + c.error_handler = &handler_ff_cholmod ; //CHOLMOD_FUNCTION_DEFAULTS (&c) ; AA.nrow=n; AA.ncol=n; @@ -391,6 +471,7 @@ class VirtualSolverCHOLMOD > : public VirtualSolver : public VirtualSolver< Su for(int k=0,oo=0; kn) { status= umfpack_dl_solve (ts, Ap, Ai, Ax, x+oo, b+oo, Numeric,Control,Info) ; - if(status) cout << " Error umfpack_di_solve status " << status << endl; + CheckUmfpackStatus(status); + // if(status) cout << " Error umfpack_di_solve status " << status << endl; if(verbosity>3) (void) umfpack_di_report_info(Control,Info); } @@ -510,14 +592,16 @@ class VirtualSolverUMFPACK< SuiteSparse_long,double> : public VirtualSolver< Su if(Symbolic) umfpack_di_free_symbolic (&Symbolic) ; status = umfpack_dl_symbolic (A->n, A->m, Ap, Ai, Ax, &Symbolic,Control,Info) ; - if(status) cout << " Error umpfack umfpack_di_symbolic status " << status << endl; + CheckUmfpackStatus(status); + //if(status) cout << " Error umpfack umfpack_di_symbolic status " << status << endl; } void fac_numeric(){ if(Numeric) umfpack_dl_free_numeric (&Numeric) ; if(verb>2 || verbosity> 9) cout << " fac_numeric UMFPACK double/long " << endl; status = umfpack_dl_numeric (Ap, Ai, Ax, Symbolic, &Numeric, Control,Info) ; - if(status) cout << " Error umpfack umfpack_di_numeric status " << status << endl; + CheckUmfpackStatus(status); + //if(status) cout << " Error umpfack umfpack_di_numeric status " << status << endl; } ~VirtualSolverUMFPACK() { @@ -571,7 +655,8 @@ class VirtualSolverUMFPACK > : public Vir { double * xx = (double *) (void*) x+oo, *bb = (double *) (void*) b+oo, *zx=0;; status= umfpack_zl_solve (UMFPACK_A, Ap, Ai, Ax,Az, xx,zx, bb, zx , Numeric, 0, 0) ; - if(status) cout << " Error umfpack_di_solve status " << status << endl; + CheckUmfpackStatus(status); + //if(status) cout << " Error umfpack_di_solve status " << status << endl; } } @@ -591,14 +676,15 @@ class VirtualSolverUMFPACK > : public Vir if(Symbolic) umfpack_zl_free_symbolic (&Symbolic) ; status = umfpack_zl_symbolic (A->n, A->m, Ap, Ai, Ax,Az, &Symbolic, 0, 0) ; - if(status) cout << " Error umpfack umfpack_zl_symbolic status " << status << endl; + CheckUmfpackStatus(status); + //if(status) cout << " Error umpfack umfpack_zl_symbolic status " << status << endl; } void fac_numeric(){ if(Numeric) umfpack_zl_free_numeric (&Numeric) ; if(verb>2 || verbosity> 9) cout << " fac_numeric UMFPACK C/long " << endl; status = umfpack_zl_numeric (Ap, Ai, Ax,Az, Symbolic, &Numeric, 0, 0) ; - if(status) cout << " Error umpfack umfpack_zl_numeric status " << status << endl; + CheckUmfpackStatus(status);//if(status) cout << " Error umpfack umfpack_zl_numeric status " << status << endl; } ~VirtualSolverUMFPACK() @@ -648,6 +734,7 @@ class VirtualSolverCHOLMOD< SuiteSparse_long,double> : public VirtualSolver< Su { cholmod_start (&c) ; + c.error_handler = &handler_ff_cholmod ; //CHOLMOD_FUNCTION_DEFAULTS (&c) ; AA.nrow=n; AA.ncol=n; @@ -750,6 +837,7 @@ class VirtualSolverCHOLMOD< SuiteSparse_long,std::complex > : public Vi :HA(&HAA),n(HAA.n),L(0),A(&AA),Ai(0),Ap(0),Ax(0),Ywork(0),Ework(0),cs(0),cn(0),verb(ds.verb) { cholmod_start (&c) ; + c.error_handler = &handler_ff_cholmod ; // CHOLMOD_FUNCTION_DEFAULTS (&c) ; AA.nrow=n; AA.ncol=n; diff --git a/src/femlib/fem.cpp b/src/femlib/fem.cpp index 71f557302..dd5cf238c 100644 --- a/src/femlib/fem.cpp +++ b/src/femlib/fem.cpp @@ -1813,10 +1813,16 @@ Mesh::Mesh(const Mesh & Th,int * split,bool WithMortar,int label) nv =0; quadtree = new FQuadTree(this,Pmin,Pmax,nv); // build empty the quadtree long iseuil =(long) (quadtree->coef*seuil); - if(verbosity>5) - cout << " seuil = " << seuil << " hmin = " << hm << " iseuil/ quadtree: " << iseuil << endl; + long iseuilhm = (long) (quadtree->coef*hm*0.8); + if( iseuilhm ==0) + { + cerr << " The generatated 2d mesh is to fine : hmin = " << hm << " to to small < "<< 1./quadtree->coef << endl; + ffassert(0); + } + if(verbosity>5 || ! iseuil ) + cout << " seuil = " << seuil << " hmin = " << hm << " iseuil/ quadtree: " << iseuil << " coef quadtree " << quadtree->coef << endl; - ffassert(iseuil); // zero => too smal + // ffassert(iseuil); // zero => too smal { // to keep the order of old vertices to have no problem in // interpolation on sub grid of RT finite element for example (Feb. 2016 F. Hecht) KN setofv(Th.nv,false); @@ -1975,8 +1981,7 @@ Mesh::Mesh(const Mesh & Th,int * split,bool WithMortar,int label) R2 B=vertices[vt[1]]; R2 C=vertices[vt[2]]; R a = (( B-A)^(C-A))*0.5; - if( a<0) nwarm++; - if( nwarm<10 && verbosity>9) cout << " warning: bad oriantiation in trunc " << kt << " " << a << endl ; + if(a <0 && nwarm++ <10 && verbosity>9) cout << " warning: bad oriantiation in trunc " << kt << " " << a << endl ; if (a>0) triangles[kt].set(vertices,vt[0],vt[1],vt[2],T.lab); else diff --git a/src/fflib/AFunction.cpp b/src/fflib/AFunction.cpp index d59fe4c56..c149f9a5a 100644 --- a/src/fflib/AFunction.cpp +++ b/src/fflib/AFunction.cpp @@ -334,8 +334,8 @@ aType TypeArray(aType b,aType a) { // type of b[a] aType r=map_type_of_map[make_pair(a->right(),b->right())]; if (!r) { - cerr << "Sorry is not possible to make a map "<< *b->right() << " [" << *a->right() << "]" << endl; - cerr << " list: " << endl; + cerr << "\nSorry is not possible to make a map "<< *b->right() << " [" << *a->right() << "]" << endl; + cerr << "in map_type_of_map , list: " << endl; Map_type_of_map::const_iterator i; for(i=map_type_of_map.begin();i!=map_type_of_map.end();i++) cerr << "\t " << *i->first.second << " [" << *i->first.first << "]" << "=" << *i->second << endl; @@ -1566,7 +1566,10 @@ void Init_map_type() Global.Add("exp","(",new OneOperator1(exp)); Global.Add("log","(",new OneOperator1(log)); Global.Add("log10","(",new OneOperator1(log10)); - Global.Add("pow","(",new OneOperator2(pow)); +// Global.Add("pow","(",new OneOperator2(pow)); + Global.Add("pow","(",new OneBinaryOperator >); + Global.Add("pow","(",new OneBinaryOperator >); + // Global.Add("pow","(",new OneOperator2(pow)); Global.Add("max","(",new OneOperator2_(Max )); Global.Add("min","(",new OneOperator2_(Min )); diff --git a/src/fflib/AFunction.hpp b/src/fflib/AFunction.hpp index 45005ea95..58e8b4b3e 100644 --- a/src/fflib/AFunction.hpp +++ b/src/fflib/AFunction.hpp @@ -2238,9 +2238,11 @@ class OneOperator2 : public OneOperator { E_F0 * code(const basicAC_F0 & args) const { return new CODE(f,t0->CastTo(args[0]),t1->CastTo(args[1]));} - OneOperator2(func ff): + OneOperator2(func ff,int ppref=0): OneOperator(map_type[typeid(R).name()],map_type[typeid(A).name()],map_type[typeid(B).name()]), - t0( map_type[typeid(A).name()] ),t1(map_type[typeid(B).name()] ), f(ff) {} + t0( map_type[typeid(A).name()] ),t1(map_type[typeid(B).name()] ), f(ff) { + pref=ppref; + } OneOperator2(func ff,aType tt0,aType tt1): OneOperator(map_type[typeid(R).name()],tt0,tt1), @@ -2979,16 +2981,26 @@ inline C_F0 & operator+=(C_F0 & a,C_F0 &b) return a; } */ - +template +void CheckDclTypeEmpty() { + if(map_type.find(typeid(T).name())!=map_type.end()) + cout << " Erreur fftype dcl twist "<< typeid(T).name() << endl; + } + template void Dcl_TypeandPtr_ (Function1 i,Function1 d,Function1 pi,Function1 pd,Function1 OnReturn=0,Function1 pOnReturn=0) { - map_type[typeid(T).name()] = new ForEachType(i,d,OnReturn); + CheckDclTypeEmpty(); + CheckDclTypeEmpty(); + map_type[typeid(T).name()] = new ForEachType(i,d,OnReturn); map_type[typeid(PT).name()] = new ForEachTypePtr(pi,pd,pOnReturn); } template void Dcl_TypeandPtr (Function1 i,Function1 d,Function1 pi,Function1 pd,Function1 OnReturn=0,Function1 pOnReturn=0) { + CheckDclTypeEmpty(); + CheckDclTypeEmpty(); + map_type[typeid(T).name()] = new ForEachType(i,d,OnReturn); map_type[typeid(T*).name()] = new ForEachTypePtr(pi,pd,pOnReturn); } @@ -2997,21 +3009,27 @@ map_type[typeid(T*).name()] = new ForEachTypePtr(pi,pd,pOnReturn); template void Dcl_TypeandPtr (Function1 pi,Function1 pd) { - map_type[typeid(T).name()] = new ForEachType(); + CheckDclTypeEmpty(); + CheckDclTypeEmpty(); + map_type[typeid(T).name()] = new ForEachType(); map_type[typeid(T*).name()] = new ForEachTypePtr(pi,pd); } template void Dcl_TypeandPtr (Function1 pd) { - map_type[typeid(T).name()] = new ForEachType(); + CheckDclTypeEmpty(); + CheckDclTypeEmpty(); + map_type[typeid(T).name()] = new ForEachType(); map_type[typeid(T*).name()] = new ForEachTypePtr(pd); } template void Dcl_TypeandPtr () { - map_type[typeid(T).name()] = new ForEachType(); + CheckDclTypeEmpty(); + CheckDclTypeEmpty(); + map_type[typeid(T).name()] = new ForEachType(); map_type[typeid(T*).name()] = new ForEachTypePtr(); } @@ -3021,6 +3039,8 @@ template if (sizeof(T) >sizeof(AnyData)) { cerr << " the type " << typeid(T).name() << " is too large " << sizeof(AnyData) << endl; throwassert(sizeof(T) <=sizeof(AnyData));} + CheckDclTypeEmpty(); + return map_type[typeid(T).name()] = new ForEachType(iv,id,Onreturn); } diff --git a/src/fflib/Operator.hpp b/src/fflib/Operator.hpp index ea00846b2..bce9b87f1 100644 --- a/src/fflib/Operator.hpp +++ b/src/fflib/Operator.hpp @@ -54,19 +54,41 @@ template struct Op2_sub: public binary_function { static R f(const A & a,const B & b) { return ((R)a - (R)b);} }; -template -struct Op2_mul: public binary_function { - static R f(const A & a,const B & b) { +template +struct Op2_DotDiv: public binary_function { + static R f(const A & a,const B & b) { return DotDiv((R)a, (R)b);} }; + +template +struct Op2_DotStar: public binary_function { + static R f(const A & a,const B & b) { return DotStar((R)a, (R)b);} }; + + +template +struct Op2_mul: public binary_function { + static R f(const A & a,const B & b) { // cout << a << " * " << b <<" => " << ((R)a * (R)b) << endl; return ((R)a * (R)b);} }; +template +struct Op2_mull: public binary_function { + static R f(const A & a,const B & b) { + // cout << a << " * " << b <<" => " << ((R)a * (R)b) << endl; + return (a * b);} }; -template -struct Op2_div: public binary_function { +template +struct Op2_div: public binary_function { static R f(const A & a,const B & b) { - if (b == B()) + if (b == B()) {cerr << a << "/" << b << " : " << typeid(A).name() << " " << typeid(B).name() << " " << typeid(R).name() << endl;ExecError(" Div by 0");} - return ((R)a / (R)b);} }; + return ((R)a / (R)b);} }; + +template +struct Op2_divv: public binary_function { + static R f(const A & a,const B & b) { + if (b == B()) + {cerr << a << "/" << b << " : " << typeid(A).name() << " " << typeid(B).name() + << " " << typeid(R).name() << endl;ExecError(" Div by 0");} + return (a / b);} }; template struct Op2_pipe: public binary_function { @@ -326,14 +348,14 @@ struct set_eq_sub: public binary_function { static A* f(A* const & a,const A & b) { *a -= b; return a;} }; -template -struct set_eq_mul: public binary_function { - static A* f(A* const & a,const A & b) { *a *= b; return a;} +template +struct set_eq_mul: public binary_function { + static A* f(A* const & a,const B & b) { *a *= b; return a;} }; -template -struct set_eq_div: public binary_function { - static A* f(A* const & a,const A & b) { *a /= b; return a;} +template +struct set_eq_div: public binary_function { + static A* f(A* const & a,const B & b) { *a /= b; return a;} }; diff --git a/src/fflib/array_real.cpp b/src/fflib/array_real.cpp index bb73ada86..caf6b27fa 100644 --- a/src/fflib/array_real.cpp +++ b/src/fflib/array_real.cpp @@ -34,6 +34,8 @@ void initArrayDCLdouble() { if(abs(p.v[i]) < eps) p.v[i]=0; return p.v;}// //template A Build(B b) { return A(b); } + + void initArrayOperatordouble() { Dcl_Type< KN_rmeps > (); ArrayOperator(); @@ -83,5 +85,7 @@ void initArrayOperatordouble() { Global.Add("Unique", "(", new Unique); Global.Add("Unique", "(", new Unique); + + // ArrayDCL(); } diff --git a/src/fflib/array_tlp.hpp b/src/fflib/array_tlp.hpp index 2858e4a3a..794befbf4 100644 --- a/src/fflib/array_tlp.hpp +++ b/src/fflib/array_tlp.hpp @@ -56,7 +56,9 @@ #include #include "array_resize.hpp" #include "HeapSort.hpp" - +namespace Fem2D { +#include "R3.hpp" +} template struct affectation: binary_function { @@ -1363,6 +1365,7 @@ KNM * set_Eye(KNM *pA,const Eye eye) return pA; } extern aType aaaa_knlp; + template void ArrayOperator() { @@ -1474,6 +1477,9 @@ void ArrayOperator() TheOperators->Add("<-", + // new OneOperator2_ *,KN *,R3>(&set_initR3), + // new OneOperator2_ *,KN *,R3*>(&set_initR3), + new OneOperator2_ *,KN *,Z>(&set_init), new InitArrayfromArray*,true> // new OneOperator2_ *,KN *,KN >(&set_init), diff --git a/src/fflib/glumesh2D.cpp b/src/fflib/glumesh2D.cpp index fc309cf06..d0b9d52df 100644 --- a/src/fflib/glumesh2D.cpp +++ b/src/fflib/glumesh2D.cpp @@ -286,8 +286,17 @@ AnyType SetMesh_Op::operator()(Stack stack) const ffassert( nrt.N() %2 ==0); map mape,mapt; int z00 = false; + int err=0; for(int i=0;i #include "fem.hpp" @@ -81,6 +82,7 @@ namespace Fem2D { extern GTypeOfFE< MeshS > &P1bLagrange_surf; extern GTypeOfFE< MeshS > &P2bLagrange_surf; extern GTypeOfFE< MeshS > &RT0surf; + extern GTypeOfFE< MeshS > &RT0orthosurf; // add 22 march 2021 FH. extern GTypeOfFE< Mesh3 > &G_P1dc_3d; extern GTypeOfFE< Mesh3 > &G_P2dc_3d; @@ -1272,7 +1274,9 @@ AnyType TypeOfFESto2(Stack, const AnyType &b) { if (i != TEF2dtoS.end( )) tS = i->second; if (tS == 0) { - cerr << " sorry no cast to this surface finite element " << endl; + cerr << " sorry no cast to this surface finite element " << t2 << endl; + // for( map< TypeOfFE *, TypeOfFES * >::const_iterator i=TEF2dtoS.begin(); i != TEF2dtoS.end(); ++i ) + // { cout << i->first << " -> " << i->second <( );// + aType t_tfe2 = atype< TypeOfFE2 * >( ); + const int d = Mesh::Rd::d; const int dHat = Mesh::RdHat::d; const int dHatfe = TypeOfFE::RdHat::d; @@ -1330,7 +1338,15 @@ struct OpMake_pfes : public OneOperator, public OpMake_pfes_np { AnyType r = (*eppfes)(s); const TypeOfFE **tef = new const TypeOfFE *[atef.size( )]; for (int i = 0; i < atef.size( ); i++) - if (tedim[i] == dHat && d==dfe) + { + // verif type atef[i] coorection mars 2022 .. + aType ttfe =atef[i].left(); + ffassert( ttfe == t_tfe || t_tfe2) ; + if(verbosity>9) cout << "OpMake_pfes_np :: " << i << " " << (tedim[i] == dHat && d==dfe) << " " << tedim[i] + << dHat << d << dfe + << " " << typeid(TypeOfFE).name() << endl; + + if (ttfe == t_tfe) // good type no converstion tef[i] = GetAny< TypeOfFE * >(atef[i].eval(s)); else if (tedim[i] == 2 && d==3 && dHat == 3) tef[i] = GetAny< TypeOfFE * >(TypeOfFE3to2(s, atef[i].eval(s))); @@ -1340,6 +1356,7 @@ struct OpMake_pfes : public OneOperator, public OpMake_pfes_np { tef[i] = GetAny< TypeOfFE * >(TypeOfFELto2(s, atef[i].eval(s))); else ffassert(0); + } pfes *ppfes = GetAny< pfes * >(r); bool same = true; @@ -4804,7 +4821,7 @@ AnyType Plot::operator( )(Stack s) const { for (int i = 1; i < k; i++) rlineto(x[i], y[i]); } else { static int kerr=0; - if (verbosity && kerr++< 10) + if (verbosity && kerr++< 5 && mpirank==0) cout << " Plot:: Sorry no ps version for this type of plot " << l[i].what << endl; } thfill = false; @@ -5412,6 +5429,8 @@ lgVertex get_vertex(pmesh *const &a, long const &n) { return lgVertex(*a, n); } lgVertex get_element(lgElement const &a, long const &n) { return a[n]; } lgVertex get_belement(lgBoundaryEdge const &a, long const &n) { return a[n]; } +R3 getP(lgVertex const &a) { return R3(*a.v); } + R getx(lgVertex const &a) { return a.x( ); } R gety(lgVertex const &a) { return a.y( ); } @@ -5505,7 +5524,11 @@ T *resizeandclean2(const Resize< T > &t, const long &n) { // resizeandclean1 } return t.v; } - +/*R3 *init_R3(double x,double y,double z) +{ + + return (R3 *) &any; +}*/ template< class PMat > AnyType ClearReturn(Stack stack, const AnyType &a) { // a ne faire que pour les variables local au return... @@ -5528,7 +5551,7 @@ void DclTypeMatrix( ) { Dcl_Type< newpMatrice_Creuse< R > >( ); // to def new Matrice_Creuse Dcl_Type< Matrice_Creuse_Transpose< R > >( ); // matrice^t (A') - Dcl_Type< Matrice_Creuse_Transpose< R > >( ); // matrice^t (A') + Dcl_Type< Matrice_Creuse_inv< R > >( ); // matrice^-1 A^{-1} Dcl_Type< Matrice_Creuse_inv_trans< R > >( ); // matrice^-1 A'^{-1} Dcl_Type< typename RNM_VirtualMatrix< R >::plusAx >( ); // A*x (A'*x) @@ -5546,6 +5569,8 @@ void DclTypeMatrix( ) { typedef KN< Mat > AMat; Dcl_Type< AMat * >(0, ::DestroyKNmat< Mat >); + // TheOperators->Add("<-", new OneOperator3< R3 *, double>(init_R3); + // init array TheOperators->Add("<-", new OneOperator2_< AMat *, AMat *, long >(&set_initmat)); // A[i] @@ -5686,7 +5711,34 @@ template< class A > } OneOperator_trans_Ptr_o_R(ptr pp) : OneOperator(atype< Result * >( ), atype< Transpose >( )), p(pp) {} }; - +template +struct OppR3dot: public binary_function { + static R f(const A & a,const B & b) { + B pu = a; + return (*pu,*b);} }; + +template +struct OppqR3dot: public binary_function { + static R f(const A & a,const B & b) { + B* pu = a; + return (*pu,b);} }; + +template +struct OpR3dot: public binary_function { + static R f(const A & a,const B & b) { + B pu = a; + return (pu,b);} }; + +R3 CrossProduct(const R3 & A,const R3 & B){ return A^B;} +R Det(const R3 & A,const R3 & B,const R3 & C){ return det(A,B,C);} +R3* initR3(R3 *const & p,const R& a,const R& b,const R &c){*p = R3(a,b,c); return p;} +R3* initR3(R3 *const & p,const R3& a,const R3& b){*p = R3(a,b); return p;} + +R3 toR3(const R& a,const R& b,const R &c){return R3(a,b,c);} +R3 toR3(const R3& a,const R3& b){return R3(a,b);} + +R3 NElement(lgBoundaryEdge const & a) { return R3(a.NBoundaryElement()); }// add Jan 2022 + void init_lgfem( ) { if (verbosity && (mpirank == 0)) cout << "lg_fem "; #ifdef HAVE_CADNA @@ -5695,12 +5747,12 @@ void init_lgfem( ) { #endif Dcl_Type< MeshPoint * >( ); - Dcl_Type< R3 * >(::Initialize< R3 >); - Dcl_Type< R2 * >(::Initialize< R2 >); - Dcl_Type< Transpose >(); + Dcl_TypeandPtr< R3 >(0,0,::InitializeDef,0); + Dcl_TypeandPtr< R2 >(0,0,::InitializeDef,0); + Dcl_Type< Transpose >(); + Dcl_Type< Transpose >(); - map_type[typeid(R3 *).name( )] = new ForEachType< R3 * >(Initialize< R3 >); - Dcl_TypeandPtr< pmesh >(0, 0, ::InitializePtr< pmesh >, ::DestroyPtr< pmesh >, + Dcl_TypeandPtr< pmesh >(0, 0, ::InitializePtr< pmesh >, ::DestroyPtr< pmesh >, AddIncrement< pmesh >, NotReturnOfthisType); Dcl_TypeandPtr< pmesh3 >(0, 0, ::InitializePtr< pmesh3 >, ::DestroyPtr< pmesh3 >, AddIncrement< pmesh3 >, NotReturnOfthisType); @@ -5737,7 +5789,7 @@ void init_lgfem( ) { Dcl_TypeandPtr< pferbasearray >( ); // il faut le 2 pour pourvoir initialiser Dcl_Type< pfer >( ); Dcl_Type< pferarray >( ); - Dcl_Type< pferarray >( ); + // Dcl_Type< pferarray >( ); // pour des Func FE complex // FH v 1.43 Dcl_TypeandPtr< pfecbase >( ); // il faut le 2 pour pourvoir initialiser @@ -5849,8 +5901,17 @@ void init_lgfem( ) { Dcl_Type< const QuadratureFormular * >( ); Dcl_Type< const QuadratureFormular1d * >( ); Dcl_Type< const GQuadratureFormular< R3 > * >( ); - TheOperators->Add("\'", new OneOperator1,R3* >(&Build,R3* >)); - TheOperators->Add("*",new opDotR3(atype(),atype< R3* >() ) ); // "N" a faire mais dur + TheOperators->Add("\'", new OneOperator1,R3* >(&Build,R3* >,2)); + TheOperators->Add("\'", new OneOperator1,R3>(&Build,R3>,1)); + //TheOperators->Add("*",new opDotR3(atype(),atype< R3* >() ) ); + TheOperators->Add("*",new opDotR3(atype(),atype< R3 >() ) ); // + // "N" a faire mais dur + // R3dot + //TheOperators->Add("*",new OneBinaryOperator< OppR3dot, R3* >> () ); // "N" a faire mais dur + TheOperators->Add("*",new OneBinaryOperator< OpR3dot, R3>> () ); // "N" a faire mais dur + + TheOperators->Add("*",new OneBinaryOperator< OppqR3dot, R3 >> () ); // "N" a faire mais dur TheOperators->Add("*",new OneBinaryOperator< OpR3dot, R3>> () ); // "N" a faire mais dur + TheOperators->Add("*",new opDotR3(atype< Transpose >(),atype() ) ); // "N" a faire mais dur Global.New("qf1pT", CConstant< const QuadratureFormular * >(&QuadratureFormular_T_1)); @@ -5881,7 +5942,7 @@ void init_lgfem( ) { Global.New("NoUseOfWait", CConstant< bool * >(&NoWait)); Global.New("NoGraphicWindow", CConstant< bool * >(&NoGraphicWindow)); - Dcl_Type< MeshPoint * >( ); + //Dcl_Type< MeshPoint * >( ); Dcl_Type< finconnue * >( ); Dcl_Type< ftest * >( ); @@ -6009,7 +6070,7 @@ void init_lgfem( ) { new OpMake_pfes< pfes3, Mesh3, TypeOfFE3, pfes3_tefk >, new OpMake_pfes< pfesS, MeshS, TypeOfFES, pfesS_tefk >, // add for 3D surface FEspace new OpMake_pfes< pfesL, MeshL, TypeOfFEL, pfesL_tefk >); - TheOperators->Add("=", new OneOperator2< R3 *, R3 *, R3 * >(&set_eqp)); + TheOperators->Add("=", new OneOperator2< R3 *, R3 *, R3 * >(&set_eqp,2)); Add< MeshPoint * >("P", ".", new OneOperator_Ptr_o_R< R3, MeshPoint >(&MeshPoint::P)); Add< MeshPoint * >("N", ".", new OneOperator_Ptr_o_R< R3, MeshPoint >(&MeshPoint::N)); @@ -6024,6 +6085,48 @@ void init_lgfem( ) { Add< R2 * >("y", ".", new OneOperator_Ptr_o_R< R, R2 >(&R2::y)); Add< R3 * >("[", "", new OneOperator2< double, R3 *, long >(get_R3)); +// ADD dec 2021 to R3 computation ... + map_type[typeid(R3).name()]->AddCast( + new E_F1_funcT(UnRef)); + TheOperators->Add("<-",new OneOperator4_(initR3)); + TheOperators->Add("<-",new OneOperator3_(initR3)); + + TheOperators->Add("=", + new OneBinaryOperator ,OneBinaryOperatorMIWO >, + new OneBinaryOperator ,OneBinaryOperatorMIWO >); + TheOperators->Add("<-", + new OneOperator2_(&set_copyp), + new OneOperator2_(&set_copyp)); // + TheOperators->Add("^", new OneOperator2_(CrossProduct)); + Global.Add("det", "(",new OneOperator3_(Det)); + TheOperators->Add("+", new OneBinaryOperator >); + TheOperators->Add(".*", new OneBinaryOperator >); + TheOperators->Add("./", new OneBinaryOperator >); + TheOperators->Add("-", new OneBinaryOperator >); + TheOperators->Add("*", new OneBinaryOperator >); + TheOperators->Add("/", new OneBinaryOperator >); + TheOperators->Add("*", new OneBinaryOperator >); + TheOperators->Add("+=", new OneBinaryOperator,OneBinaryOperatorMIWO >); + TheOperators->Add("-=", new OneBinaryOperator,OneBinaryOperatorMIWO >); + TheOperators->Add("*=", new OneBinaryOperator,OneBinaryOperatorMIWO >); + TheOperators->Add("/=", new OneBinaryOperator,OneBinaryOperatorMIWO >); + TheOperators->Add("<<", new OneBinaryOperator >); + Add("<--","(",new OneOperator3_(toR3)); + Add("<--","(",new OneOperator2_(toR3)); + Add("norm",".",new OneOperator1_(Norme2)); + Add("norm2",".",new OneOperator1_(Norme2_2)); + Add("l2",".",new OneOperator1_(Norme2)); + Add("linfty",".",new OneOperator1_(Norme_infty)); + Add("norm",".",new OneOperator1_(Norme2)); + Add("norm2",".",new OneOperator1_(Norme2_2)); + Add("l2",".",new OneOperator1_(Norme2)); + Add("linfty",".",new OneOperator1_(Norme_infty)); + Add("<--","(",new OneOperator3_(toR3)); + Add("<--","(",new OneOperator2_(toR3)); + + + +// end add Add< pmesh >("[", "", new OneOperator2_< lgElement, pmesh, long >(get_element)); Add< pmesh * >("be", ".", new OneOperator1_< lgBoundaryEdge::BE, pmesh * >(Build)); @@ -6031,6 +6134,9 @@ void init_lgfem( ) { Add< lgBoundaryEdge::BE >( "(", "", new OneOperator2_< lgBoundaryEdge, lgBoundaryEdge::BE, long >(get_belement)); Add< lgElement::Adj >("(", "", new OneOperator2_< lgElement, lgElement::Adj, long * >(get_adj)); + + Add("N",".",new OneOperator1_(NElement)); + TheOperators->Add("==", new OneBinaryOperator< Op2_eq< lgElement, lgElement > >); TheOperators->Add("!=", new OneBinaryOperator< Op2_ne< lgElement, lgElement > >); TheOperators->Add("<", new OneBinaryOperator< Op2_lt< lgElement, lgElement > >); @@ -6043,6 +6149,7 @@ void init_lgfem( ) { Add< lgElement >("[", "", new OneOperator2_< lgVertex, lgElement, long >(get_element)); Add< lgBoundaryEdge >("[", "", new OneOperator2_< lgVertex, lgBoundaryEdge, long >(get_belement)); + Add< lgVertex >("P", ".", new OneOperator1_< R3, lgVertex >(getP));// Jan 2022 FH Add< lgVertex >("x", ".", new OneOperator1_< R, lgVertex >(getx)); Add< lgVertex >("y", ".", new OneOperator1_< R, lgVertex >(gety)); Add< lgVertex >("label", ".", new OneOperator1_< long, lgVertex >(getlab)); @@ -6052,6 +6159,7 @@ void init_lgfem( ) { Add< lgElement >("mesure", ".", new OneOperator1_< double, lgElement >(getarea)); Add< lgElement >("measure", ".", new OneOperator1_< double, lgElement >(getarea)); Add< lgBoundaryEdge >("length", ".", new OneOperator1_< double, lgBoundaryEdge >(getlength)); + Add< lgBoundaryEdge >("measure", ".", new OneOperator1_< double, lgBoundaryEdge >(getlength)); Add< lgBoundaryEdge >("label", ".", new OneOperator1_< long, lgBoundaryEdge >(getlab)); Add< lgBoundaryEdge >("Element", ".", new OneOperator1_< lgElement, lgBoundaryEdge >(getElement)); Add< lgBoundaryEdge >("whoinElement", ".", new OneOperator1_< long, lgBoundaryEdge >(EdgeElement)); @@ -6474,7 +6582,7 @@ void init_lgfem( ) { TheOperators->Add("<-", new OneOperator2_< pfes *, pfes *, pfes >(&set_copy_incr)); - TheOperators->Add("<<", new OneBinaryOperator< PrintPnd< R3 * > >, + TheOperators->Add("<<" ,// new OneBinaryOperator< PrintPnd< R3 * > >, new OneBinaryOperator< PrintPnd< Matrice_Creuse< R > * > >, new OneBinaryOperator< PrintPnd< Matrice_Creuse< Complex > * > > @@ -6712,6 +6820,8 @@ void init_lgfem( ) { AddNewFEL("P0VF3dcL", &G_P0VFdc_L); // end add .. + Global.New("Edge0S",CConstantTFES(&RT0orthosurf)); + Global.New("RT0orthoS",CConstantTFES(&RT0orthosurf)); Global.New("RT0S",CConstantTFES(&RT0surf)); Global.New("P2S", CConstantTFES(&DataFE< MeshS >::P2)); Global.New("P1S", CConstantTFES(&DataFE< MeshS >::P1)); diff --git a/src/fflib/lgfem.hpp b/src/fflib/lgfem.hpp index 8d1e0cbfe..3321efca4 100644 --- a/src/fflib/lgfem.hpp +++ b/src/fflib/lgfem.hpp @@ -219,6 +219,10 @@ namespace { (*pTh).BoundaryElement((*pTh)(k), ee); return ee; } + R2 NBoundaryElement() const {Check() ;int ee; + int kk=(*pTh).BoundaryElement((*pTh)(k),ee); + return (*pTh)[kk].n(ee);} + }; } // namespace diff --git a/src/fflib/lgmat.cpp b/src/fflib/lgmat.cpp index 8ab90deae..2d280f11a 100644 --- a/src/fflib/lgmat.cpp +++ b/src/fflib/lgmat.cpp @@ -3086,6 +3086,7 @@ Matrice_Creuse* set_H_Eye(Matrice_Creuse *pA,const Eye eye) if( init) pA->init(); pA->resize(n,m); HashMatrix * pH= pA->pHM(); + ffassert(pH); pH->clear(); pH->resize(n,m,nn); @@ -3093,6 +3094,26 @@ Matrice_Creuse* set_H_Eye(Matrice_Creuse *pA,const Eye eye) (*pH)(i,i)=1.; return pA; } +template long Set_BC(Matrice_Creuse * const & pA,KN_ const & bc,double const & tgv) +{ + long nbc=0; + if( pA ==0 && pA->A) return nbc; + MatriceCreuse A = pA->A; + HashMatrix * pH= pA->pHM(); + ffassert(pH); + int n = bc.N(); + KN cbc(n); + for(int i=0; i< n;++i ) + if (bc[i]) + ++nbc,cbc[i] = char(1); + else + cbc[i]=char(0); + pH->SetBC(cbc,tgv); + return nbc; +} +template long Set_BC(Matrice_Creuse * const & pA,KN_ const & bc) +{ return Set_BC(pA,bc,ff_tgv); +} template void AddSparseMat() { @@ -3214,6 +3235,8 @@ TheOperators->Add("+", TheOperators->Add("=", new OneOperator2,TheCoefMat,R>(set_mat_coef) ); Global.Add("set","(",new SetMatrix); + Global.Add("setBC","(",new OneOperator3_ *,KN_,double>(Set_BC)); + Global.Add("setBC","(",new OneOperator2_ *,KN_>(Set_BC)); Add *>("linfty",".",new OneOperator1 *>(get_norme_linfty)); Add *>("l2",".",new OneOperator1 *>(get_norme_l2)); Add *>("l1",".",new OneOperator1 *>(get_norme_l1)); diff --git a/src/fflib/lgmesh.cpp b/src/fflib/lgmesh.cpp index 3da1caac7..e5d681631 100644 --- a/src/fflib/lgmesh.cpp +++ b/src/fflib/lgmesh.cpp @@ -464,7 +464,7 @@ AnyType classBuildMesh::operator()(Stack stack) const { const TP * borders = GetAny((*getborders)(stack)); long nbvx = arg(0,stack,0L); int defrb = is_same::value ; - bool requireborder= arg(3,stack,arg(defrb,stack,false)); + bool requireborder= arg(3,stack,arg(1,stack,false));// correct 23 nov. 2021 FH KNM * p=0; p=arg(2,stack,p); double alea = arg(4,stack,0.); bool SplitEdgeWith2Boundary=arg(5,stack,false); @@ -796,8 +796,9 @@ AnyType Adaptation::operator()(Stack stack) const const Mesh * Thh = GetAny((*getmesh)(stack)); ffassert(Thh); Triangles * oTh =0; + KN ndfv(Thh->nv); + for(int i=0; i ndfv(Thh->nv); KN ndfe(Thh->neb); int nbdfv=0,nbdfe=0; BuildPeriodic2(nbcperiodic,periodic,*Thh,stack,nbdfv,ndfv,nbdfe,ndfe); @@ -924,6 +925,30 @@ AnyType Adaptation::operator()(Stack stack) const Th.SmoothMetric(raison); Th.MaxSubDivision(maxsubdiv); Th.BoundAnisotropy(anisomax); + if(nbcperiodic && 0 ) // in test + // to be sure that the metric is ok with periotic BC + { // bof Bof ... + if(verbosity>1) cout << " inforce de periodic BC on Metric" << endl; + KN m(3*ndfv.N()), c(ndfv.N()); + c=0.; + m=0.; + for ( iv=0;iv * const & psupp, long const supp += s; } - phi *= (1./nlayer); + if (nlayer > 1) phi *= (1./nlayer); return true; } @@ -1792,6 +1817,40 @@ double dist(Stack stack,pmesh3 const &pTh) return 0.; }*/ template +R3 Projection(Stack stack,Mesh * const &pTh,long *pnu,R3 *phat,bool *poutside) +{ // version 3d sep 2021 + R3 UnSet(doublenotset,doublenotset,doublenotset); + typedef typename Mesh::RdHat RdHat; + typedef typename Mesh::Rd Rd; + typedef typename Mesh::Element Element; + + if(pTh == 0) return UnSet; + RdHat PHat; + bool outside; + + MeshPoint & mp = *MeshPointStack(stack); + + if((const void *) pTh == (const void *) mp.Th) return UnSet; + Rd P(&mp.P.x); + const Element * K=pTh->Find(P,PHat,outside); + if(phat) *phat=PHat; + if(pnu ) *pnu = (*pTh)(K); + if(poutside ) *poutside = outside; + // if (!outside) + // return P; + // else + { + Rd Pb = (*K)(PHat); + return Pb; + } + return UnSet; +} +template +R3 Projection(Stack stack,Mesh * const &pTh) +{ + return Projection(stack,pTh,0,0,0); +} +template double dist(Stack stack,Mesh * const &pTh) { // version 3d sep 2021 typedef typename Mesh::RdHat RdHat; @@ -1868,7 +1927,44 @@ long savegnuplot(pmesh pTh,string* pgp) return 0; } extern void init_glumesh2D(); +static basicAC_F0::name_and_type OneOperator1s_np_name_param[3] = { + {"nu", &typeid(long*)}, + {"Phat", &typeid(R3 *)}, + {"outside", &typeid(bool *)} +}; + +template + class E_F_F0s_np :public E { public: + typedef R (*func)(Stack stack,const A0&, long *nu,R3 *Phat,bool * poutside ) ; + func f; + Expression a,b,c,d; + E_F_F0s_np(func ff,Expression aa,Expression bb,Expression cc,Expression dd) : f(ff),a(aa),b(bb),c(cc),d(dd) {} + AnyType operator()(Stack s) const + { long *nu=0; + R3 *Phat=0; + bool *poutside=0; + if( b) nu=GetAny( (*b)(s) ); + if( c) Phat=GetAny( (*c)(s) ); + if( d) poutside=GetAny( (*d)(s) ); + return SetAny(f(s,GetAny( (*a)(s) ),nu,Phat,poutside));} + + operator aType () const { return atype();} + +}; + +template > +class OneOperator1s_np : public OneOperator { + typedef R (*func)(Stack stack, const A &,long *,R3 *,bool *) ; + func f; + public: + E_F0 * code(const basicAC_F0 & args) const + { Expression nargs[]={0,0,0}; + args.SetNameParam(3, OneOperator1s_np_name_param, nargs); + return new CODE(f,t[0]->CastTo(args[0]),nargs[0],nargs[1],nargs[2]);} + OneOperator1s_np(func ff): + OneOperator(map_type[typeid(R).name()],map_type[typeid(A).name()]),f(ff){} +}; void init_lgmesh() { if(verbosity&&(mpirank==0) ) cout <<"lg_mesh "; bamg::MeshIstreamErrorHandler = MeshErrorIO; @@ -1917,7 +2013,12 @@ void init_lgmesh() { Global.Add("dist", "(", new OneOperator1s_ >(dist));// sep 2021 FH function distance to mesh Global.Add("dist", "(", new OneOperator1s_ >(dist));// sep 2021 FH function distance to mesh Global.Add("signeddist", "(", new OneOperator1s_ >(signeddist));// sep 2021 FH function distance to mesh - Global.Add("signeddist", "(", new OneOperator1s_ >(signeddist));// sep 2021 FH function distance to mesh + Global.Add("signeddist", "(", new OneOperator1s_ >(signeddist));// sep 2021 FH function distance to mesh + Global.Add("projection", "(", new OneOperator1s_np >(Projection));// jan 2022 FH function Projection to mesh + Global.Add("projection", "(", new OneOperator1s_np >(Projection));// jan 2022 FH function Projection to mesh + + Global.Add("projection", "(", new OneOperator1s_np >(Projection));// Jan 2022 FH function distance to mesh + Global.Add("projection", "(", new OneOperator1s_np >(Projection)); // Jan 2022 FH FH function Projection to mesh Global.Add("dist", "(", new OneOperator1s_ >(dist));// sep 2021 FH function distance to mesh Global.Add("dist", "(", new OneOperator1s_ >(dist)); // oct 2017 FH FH function distance to mesh diff --git a/src/fflib/lgmesh3.cpp b/src/fflib/lgmesh3.cpp index 472e402c5..800535cf3 100644 --- a/src/fflib/lgmesh3.cpp +++ b/src/fflib/lgmesh3.cpp @@ -450,7 +450,8 @@ class GlgBoundaryElement { public: typedef typename Mesh::Element Element; typedef typename Mesh::BorderElement BorderElement; - + typedef typename Mesh::Rd Rd; + struct BE { const Mesh * p; BE(const Mesh *pp) : p(pp) {} @@ -472,11 +473,15 @@ class GlgBoundaryElement { public: operator int() const { Check(); return (* pTh)(k);} GlgVertex operator [](const long & i) const { Check(); return GlgVertex(pTh,&(*k)[i]);} long lab() const {Check() ; return k ? k->lab : 0;} + double mes() const {Check() ; return k ? k->mesure() : 0;} double length() const {Check() ; return k->length() ;} long n() const { return k ? BorderElement::nv : 0 ;} GlgElement element() const {Check() ;int ee; return GlgElement(pTh,(*pTh).BoundaryElement((*pTh)(k),ee));} long nuBoundaryElement() const {Check() ;int ee; (*pTh).BoundaryElement((*pTh)(k),ee);return ee;} - + Rd NBoundaryElement() const {Check() ;int ee; + int kk=(*pTh).BoundaryElement((*pTh)(k),ee); + return (*pTh)[kk].n(ee);} + }; @@ -499,13 +504,120 @@ GlgElement getElement(GlgBoundaryElement const & a) long NuElement(GlgBoundaryElement const & a) { return a.nuBoundaryElement(); } +template +R3 NElement(GlgBoundaryElement const & a) +{ return a.NBoundaryElement(); } +template +R3 getP(GlgVertex const & a){ return R3(*a.v);} R getx(GlgVertex const & a){ return a.x();} R gety(GlgVertex const & a){ return a.y();} R getz(GlgVertex const & a){ return a.z();} +R getx(R3 const & a){ return a.x;} +R gety(R3 const & a){ return a.y;} +R getz(R3 const & a){ return a.z;} long getlab(GlgVertex const & a){ return a.lab();} long getlab(GlgElement const & a){ return a.lab();} long getlab(GlgBoundaryElement const & a){ return a.lab();} R getmes(GlgElement const & a){ return a.mes();} +R getmesb(GlgBoundaryElement const & a){ return a.mes();} +R Volume(const R3 & O,const R3 & AA,const R3 & BB,const R3 & CC ) +{ + R3 A(O,AA),B(O,BB),C(O,CC); + return det(A,B,C)/6.; +} + +R Volume(const R3 & O, GlgBoundaryElement const & gbe) +{ + gbe.Check(); // verif .. + const Mesh3::BorderElement & be = * gbe.k; + return Volume(O,be[0],be[1],be[2]);} + +R Volume(const R3 & O, GlgElement const & gbe) +{ + gbe.Check(); // verif .. + const MeshS::Element & be = * gbe.k; + return Volume(O,be[0],be[1],be[2]);} +R Volume(const R3 & O, GlgElement const & gbe,const long & nf) +{ + gbe.Check(); // verif .. + ffassert(nf>=0 && nf < 4); + const Mesh3::Element & be = * gbe.k; + static int nvface[4][3]= {{3,2,1}, {0,2,3},{ 3,1,0},{ 0,1,2}}; + int i0=nvface[nf][0]; + int i1=nvface[nf][1]; + int i2=nvface[nf][2]; + return Volume(O,be[i0],be[i1],be[i2]);} + +R SolidAngle(const R3 & O,const R3 & AA,const R3 & BB,const R3 & CC ) +{ + R3 A(O,AA),B(O,BB),C(O,CC); + R a=A.norme(),b=B.norme(),c=C.norme(); + R ref = max(max(a,b),max(c,1e-20)); + R epsA = 1e-10; + R eps = ref*ref*ref*epsA;//???? + R abc =abs(det(A,B,C)); + R ab = (A,B), ac=(A,C), bc = (B,C); + R abc1 = a*b*c; + R q = (abc1+ab*c+ac*b+bc*a); + R theta =0; + + if( abs(q)>eps || abc > eps )// OK + { theta=atan2(abc,q);// y = abc , x = q + + // x > 0 => -pi/2 , pi/2 + if( theta<0) { + + if(verbosity) cout << " Bug ??? SolidAngle ::: " << abc << " " << q << " => " << theta << " == " << atan(abc/q) << endl; + theta+= 2*Pi; + } + theta*=2; + } + else // sur le bord et dans le plan + { + R p = (a+b+c)/2; + R area = sqrt(p*(p-a)*(p-b)*(p-c)); // Formule de Heron + R epsp = eps*p; + if(area < epsp) + theta = 0; // bof bof + else if( a< epsp ) + theta=acos((B,C)/(b*c)); + else if (b < epsp) + theta=acos((A,C)/(a*c)); + else if (c < epsp) + theta=acos((A,B)/(a*b)); + else + theta = Pi; + } + if(verbosity>99) cout << a << " " << b << " " << c << " theta "<< theta << " " << (abs(q)>eps || abc > eps) << " q= " << q << " abc=" << abc << " eps " << eps << endl; + ffassert(theta>=0); + return theta; +} +R SolidAngle(const R3 & O, GlgBoundaryElement const & gbe) +{ + gbe.Check(); // verif .. + const Mesh3 &Th= *gbe.pTh; + const Mesh3::BorderElement & be = * gbe.k; + return SolidAngle(O,be[0],be[1],be[2]);} + + R SolidAngle(const R3 & O, GlgElement const & gbe) +{ + gbe.Check(); // verif .. + const MeshS &Th= *gbe.pTh; + const MeshS::Element & be = * gbe.k; + + return SolidAngle(O,be[0],be[1],be[2]);} + +R SolidAngle(const R3 & O, GlgElement const & gbe,const long & nf) +{ + gbe.Check(); // verif .. + ffassert(nf>=0 && nf < 4); + const Mesh3::Element & be = * gbe.k; + static int nvface[4][3]= {{3,2,1}, {0,2,3},{ 3,1,0},{ 0,1,2}}; + int i0=nvface[nf][0]; + int i1=nvface[nf][1]; + int i2=nvface[nf][2]; + + return SolidAngle(O,be[i0],be[i1],be[i2]);} double pmesh_mes(pmesh3 * p) { ffassert(p) ; return *p ? (**p).mes : 0.0;} double pmesh_mesb(pmesh3 * p) { ffassert(p) ; return *p ? (**p).mesb : 0.0;} @@ -554,6 +666,7 @@ pmeshL pmeshS_gamma(Stack stack, pmeshS * const & p) long pmesh_nadjnomanifold(pmesh3 * p) { ffassert(p) ; return *p ? ((**p).meshS)->nadjnomanifold : 0;} long pmesh_nadjnomanifold(pmeshS * p) { ffassert(p) ; return *p ? (**p).nadjnomanifold : 0;} +long pmesh_nadjnomanifold(pmeshL * p) { ffassert(p) ; return *p ? (**p).nadjnomanifold : 0;} // Tools for 3D surface mesh @@ -582,6 +695,7 @@ long getlab(GlgVertex const & a){ return a.lab();} long getlab(GlgElement const & a){ return a.lab();} long getlab(GlgBoundaryElement const & a){ return a.lab();} R getmes(GlgElement const & a){ return a.mes();} +R getmesb(GlgBoundaryElement const & a){ return a.mes();} double pmesh_mes(pmeshS * p) { ffassert(p) ; return *p ? (**p).mes : 0.0;} double pmesh_mesb(pmeshS * p) { ffassert(p) ; return *p ? (**p).mesb : 0.0;} @@ -660,6 +774,8 @@ long getlab(GlgVertex const & a){ return a.lab();} long getlab(GlgElement const & a){ return a.lab();} long getlab(GlgBoundaryElement const & a){ return a.lab();} R getmes(GlgElement const & a){ return a.mes();} +R getmesb(GlgBoundaryElement const & a){ return a.mes();} + double pmesh_mes(pmeshL * p) { ffassert(p) ; return *p ? (**p).mes : 0.0;} double pmesh_mesb(pmeshL * p) { ffassert(p) ; return *p ? (**p).mesb : 0.0;} @@ -2634,6 +2750,104 @@ class Op4_pfeK : public quad_function< pair< FEbase< K, v_fesL > *, int >, R, R, }; }; */ +template +void init_lgmesh1() +{ + typedef const Mesh3 * pmesh3; + // 3D volume + Dcl_Type >(); + Dcl_Type >( ); + Dcl_Type::Adj>( ); + + Dcl_Type::BE >( ); + Dcl_Type >( ); + + atype()->AddCast( + new E_F1_funcT >(Cast >), + new E_F1_funcT >(Cast >), + new E_F1_funcT >(Cast >) + + ); + + Add("[","",new OneOperator2_,pmesh3,long>(get_element)); + Add("[","",new OneOperator2_,pmesh3*,long>(get_element)); + Add("(","",new OneOperator2_,pmesh3,long>(get_vertex)); + Add("(","",new OneOperator2_,pmesh3*,long>(get_vertex)); + // second case of Th(x,y,z) ???? FH attention deja fait dans Op4_Mesh32mp now remove + Add("(", "", new OneQuadOperator< Op3_MeshDmp,typename Op3_MeshDmp::Op >); + + Add("be",".",new OneOperator1_::BE,pmesh3*>(Build)); + Add >("adj",".",new OneOperator1_::Adj,GlgElement >(Build)); + Add::BE>("(","",new OneOperator2_,typename GlgBoundaryElement::BE,long>(get_element)); + Add::Adj>("(","",new OneOperator2_,typename GlgElement::Adj,long*>(get_adj)); + TheOperators->Add("==", new OneBinaryOperator,GlgElement > >); + TheOperators->Add("!=", new OneBinaryOperator,GlgElement > >); + TheOperators->Add("<", new OneBinaryOperator,GlgElement > >); + TheOperators->Add("<=", new OneBinaryOperator,GlgElement > >); + + Add >("label",".",new OneOperator1_ >(getlab)); + Add >("measure",".",new OneOperator1_ >(getmesb)); + Add >("Element",".",new OneOperator1_ ,GlgBoundaryElement >(getElement)); + Add >("whoinElement",".",new OneOperator1_ >(NuElement)); + Add >("N",".",new OneOperator1_ >(NElement)); + + + Add >("[","",new OneOperator2_ ,GlgElement ,long>(get_element)); + Add >("[","",new OneOperator2_,GlgBoundaryElement,long>(get_element)); + + Add >("P",".",new OneOperator1_ >(getP)); + + Add >("x",".",new OneOperator1_ >(getx)); + Add >("y",".",new OneOperator1_ >(gety)); + Add >("z",".",new OneOperator1_ >(getz)); + + Add >("label",".",new OneOperator1_ >(getlab)); + Add >("label",".",new OneOperator1_ >(getlab)); + Add >("region",".",new OneOperator1_ >(getlab)); + Add >("mesure",".",new OneOperator1_ >(getmes)); + Add >("measure",".",new OneOperator1_ >(getmes)); + Add("mesure",".",new OneOperator1(pmesh_mes)); + Add("measure",".",new OneOperator1(pmesh_mes)); + Add("bordermesure",".",new OneOperator1(pmesh_mesb)); + Add("bordermeasure",".",new OneOperator1(pmesh_mesb)); + Add("nt",".",new OneOperator1(pmesh_nt)); + Add("nv",".",new OneOperator1(pmesh_nv)); + Add("nbe",".",new OneOperator1(pmesh_nbe)); + Add("hmax",".",new OneOperator1(pmesh_hmax)); + Add("hmin",".",new OneOperator1(pmesh_hmin)); + + Add("nbnomanifold",".",new OneOperator1(pmesh_nadjnomanifold)); + +} +//using Fem2D::R3; +KN * set_initR3( KN *a, R3 b){ + SHOWVERB( cout << " set_init array R3" << " " << &b << endl); + a->init(3); (*a)[0]=b.x;(*a)[1]=b.y;(*a)[2]=b.z; return a;} + +/* KN * set_initR3( KN *a, R3 * b){ + SHOWVERB( cout << " set_init array R3" << " " << &b << endl); + a->init(3); (*a)[0]=b->x;(*a)[1]=b->y;(*a)[2]=b->z; return a;} +*/ + +KN_ copy_R3( KN_ a, R3 b){ + SHOWVERB( cout << " set_init array R3" << " " << &b << endl); + ffassert(a.N()==3); (a)[0]=b.x;(a)[1]=b.y;(a)[2]=b.z; return a;} +/*KN_ copy_R3( KN_ a, R3 *b){ + SHOWVERB( cout << " set_init array R3" << " " << &b << endl); + ffassert(a.N()==3); (a)[0]=b->x;(a)[1]=b->y;(a)[2]=b->z; return a;} +*/ + + +AnyType Array2R3(Stack,const AnyType &b) { + KN_ a = GetAny> (b); + ffassert(a.N()>=3); + R3 P((double*)a); + return SetAny(P);} +AnyType pArray2R3(Stack,const AnyType &b) { + KN_ a = *GetAny*> (b); + ffassert(a.N()>=3); + R3 P((double*)a); + return SetAny(P);} void init_lgmesh3() { if(verbosity&&(mpirank==0)) cout <<"lg_mesh3 "; @@ -2709,185 +2923,28 @@ void init_lgmesh3() { Global.Add("buildmeshL","(",new OneOperator1s_(BuildMeshCurve3)); - - // 3D volume - Dcl_Type >(); - Dcl_Type >( ); - Dcl_Type::Adj>( ); - - Dcl_Type::BE >( ); - Dcl_Type >( ); - - atype()->AddCast( - new E_F1_funcT >(Cast >), - new E_F1_funcT >(Cast >), - new E_F1_funcT >(Cast >) - - ); - - Add("[","",new OneOperator2_,pmesh3,long>(get_element)); - Add("[","",new OneOperator2_,pmesh3*,long>(get_element)); - Add("(","",new OneOperator2_,pmesh3,long>(get_vertex)); - Add("(","",new OneOperator2_,pmesh3*,long>(get_vertex)); -// second case of Th(x,y,z) ???? FH attention deja fait dans Op4_Mesh32mp now remove - Add("(", "", new OneQuadOperator< Op3_MeshDmp, Op3_MeshDmp::Op >); - - Add("be",".",new OneOperator1_::BE,pmesh3*>(Build)); - Add >("adj",".",new OneOperator1_::Adj,GlgElement >(Build)); - Add::BE>("(","",new OneOperator2_,GlgBoundaryElement::BE,long>(get_element)); - Add::Adj>("(","",new OneOperator2_,GlgElement::Adj,long*>(get_adj)); - TheOperators->Add("==", new OneBinaryOperator,GlgElement > >); - TheOperators->Add("!=", new OneBinaryOperator,GlgElement > >); - TheOperators->Add("<", new OneBinaryOperator,GlgElement > >); - TheOperators->Add("<=", new OneBinaryOperator,GlgElement > >); - - Add >("label",".",new OneOperator1_ >(getlab)); - Add >("Element",".",new OneOperator1_ ,GlgBoundaryElement >(getElement)); - Add >("whoinElement",".",new OneOperator1_ >(NuElement)); + Add("x",".",new OneOperator1_(getx)); + Add("y",".",new OneOperator1_(gety)); + Add("z",".",new OneOperator1_(getz)); + init_lgmesh1(); + init_lgmesh1(); + init_lgmesh1(); - Add >("[","",new OneOperator2_ ,GlgElement ,long>(get_element)); - Add >("[","",new OneOperator2_,GlgBoundaryElement,long>(get_element)); - - Add >("x",".",new OneOperator1_ >(getx)); - Add >("y",".",new OneOperator1_ >(gety)); - Add >("z",".",new OneOperator1_ >(getz)); - Add >("label",".",new OneOperator1_ >(getlab)); - Add >("label",".",new OneOperator1_ >(getlab)); - Add >("region",".",new OneOperator1_ >(getlab)); - Add >("mesure",".",new OneOperator1_ >(getmes)); - Add >("measure",".",new OneOperator1_ >(getmes)); - Add("mesure",".",new OneOperator1(pmesh_mes)); - Add("measure",".",new OneOperator1(pmesh_mes)); - Add("bordermesure",".",new OneOperator1(pmesh_mesb)); - Add("bordermeasure",".",new OneOperator1(pmesh_mesb)); - Add("nt",".",new OneOperator1(pmesh_nt)); - Add("nv",".",new OneOperator1(pmesh_nv)); - Add("nbe",".",new OneOperator1(pmesh_nbe)); - Add("hmax",".",new OneOperator1(pmesh_hmax)); - Add("hmin",".",new OneOperator1(pmesh_hmin)); - - Add("Gamma",".",new OneOperator1s_(pmesh3_gamma)); - Add("nbnomanifold",".",new OneOperator1(pmesh_nadjnomanifold)); - - Add("Gamma",".",new OneOperator1s_(pmeshS_gamma)); - - //3D surface - Dcl_Type >(); - Dcl_Type >( ); - Dcl_Type::Adj>( ); - - Dcl_Type::BE >( ); - Dcl_Type >( ); - - atype()->AddCast( - new E_F1_funcT >(Cast >), - new E_F1_funcT >(Cast >), - new E_F1_funcT >(Cast >) - ); - - Add("[","",new OneOperator2_,pmeshS,long>(get_element)); - Add("[","",new OneOperator2_,pmeshS*,long>(get_element)); - Add("(","",new OneOperator2_,pmeshS,long>(get_vertex)); - Add("(","",new OneOperator2_,pmeshS*,long>(get_vertex)); - Add("(", "", new OneQuadOperator< Op3_MeshDmp, Op3_MeshDmp::Op >); - - Add("be",".",new OneOperator1_::BE,pmeshS*>(Build)); - Add >("adj",".",new OneOperator1_::Adj,GlgElement >(Build)); - Add::BE>("(","",new OneOperator2_,GlgBoundaryElement::BE,long>(get_element)); - Add::Adj>("(","",new OneOperator2_,GlgElement::Adj,long*>(get_adj)); - TheOperators->Add("==", new OneBinaryOperator,GlgElement > >); - TheOperators->Add("!=", new OneBinaryOperator,GlgElement > >); - TheOperators->Add("<", new OneBinaryOperator,GlgElement > >); - TheOperators->Add("<=", new OneBinaryOperator,GlgElement > >); - - Add >("label",".",new OneOperator1_ >(getlab)); - Add >("Element",".",new OneOperator1_ ,GlgBoundaryElement >(getElement)); - Add >("whoinElement",".",new OneOperator1_ >(NuElement)); - - Add >("[","",new OneOperator2_ ,GlgElement ,long>(get_element)); - Add >("[","",new OneOperator2_,GlgBoundaryElement,long>(get_element)); - - Add >("x",".",new OneOperator1_ >(getx)); - Add >("y",".",new OneOperator1_ >(gety)); - Add >("z",".",new OneOperator1_ >(getz)); - Add >("label",".",new OneOperator1_ >(getlab)); - Add >("label",".",new OneOperator1_ >(getlab)); - Add >("region",".",new OneOperator1_ >(getlab)); - Add >("mesure",".",new OneOperator1_ >(getmes)); - Add >("measure",".",new OneOperator1_ >(getmes)); - Add("mesure",".",new OneOperator1(pmesh_mes)); - Add("measure",".",new OneOperator1(pmesh_mes)); - Add("bordermesure",".",new OneOperator1(pmesh_mesb)); - Add("bordermeasure",".",new OneOperator1(pmesh_mesb)); - Add("nt",".",new OneOperator1(pmesh_nt)); - Add("nv",".",new OneOperator1(pmesh_nv)); - Add("nbe",".",new OneOperator1(pmesh_nbe)); - Add("hmax",".",new OneOperator1(pmesh_hmax)); - Add("hmin",".",new OneOperator1(pmesh_hmin)); - Add("nbnomanifold",".",new OneOperator1(pmesh_nadjnomanifold)); - - - //3D line - Dcl_Type >(); - Dcl_Type >( ); - Dcl_Type::Adj>( ); - - Dcl_Type::BE >( ); - Dcl_Type >( ); - - atype()->AddCast( - new E_F1_funcT >(Cast >), - new E_F1_funcT >(Cast >), - new E_F1_funcT >(Cast >) - ); - - Add("[","",new OneOperator2_,pmeshL,long>(get_element)); - Add("[","",new OneOperator2_,pmeshL*,long>(get_element)); - Add("(","",new OneOperator2_,pmeshL,long>(get_vertex)); - Add("(","",new OneOperator2_,pmeshL*,long>(get_vertex)); - Add("(", "", new OneQuadOperator< Op3_MeshDmp, Op3_MeshDmp::Op >); - - Add("be",".",new OneOperator1_::BE,pmeshL*>(Build)); - Add >("adj",".",new OneOperator1_::Adj,GlgElement >(Build)); - Add::BE>("(","",new OneOperator2_,GlgBoundaryElement::BE,long>(get_element)); - Add::Adj>("(","",new OneOperator2_,GlgElement::Adj,long*>(get_adj)); - - TheOperators->Add("==", new OneBinaryOperator,GlgElement > >); - TheOperators->Add("!=", new OneBinaryOperator,GlgElement > >); - TheOperators->Add("<", new OneBinaryOperator,GlgElement > >); - TheOperators->Add("<=", new OneBinaryOperator,GlgElement > >); - - Add >("label",".",new OneOperator1_ >(getlab)); - Add >("Element",".",new OneOperator1_ ,GlgBoundaryElement >(getElement)); - Add >("whoinElement",".",new OneOperator1_ >(NuElement)); - Add >("[","",new OneOperator2_ ,GlgElement ,long>(get_element)); - Add >("[","",new OneOperator2_,GlgBoundaryElement,long>(get_element)); - - Add >("x",".",new OneOperator1_ >(getx)); - Add >("y",".",new OneOperator1_ >(gety)); - Add >("z",".",new OneOperator1_ >(getz)); - Add >("label",".",new OneOperator1_ >(getlab)); - Add >("label",".",new OneOperator1_ >(getlab)); - Add >("region",".",new OneOperator1_ >(getlab)); - Add >("mesure",".",new OneOperator1_ >(getmes)); - Add >("measure",".",new OneOperator1_ >(getmes)); - - Add("mesure",".",new OneOperator1(pmesh_mes)); - Add("measure",".",new OneOperator1(pmesh_mes)); - Add("bordermesure",".",new OneOperator1(pmesh_mesb)); - Add("bordermeasure",".",new OneOperator1(pmesh_mesb)); - Add("nt",".",new OneOperator1(pmesh_nt)); - Add("nv",".",new OneOperator1(pmesh_nv)); - Add("nbe",".",new OneOperator1(pmesh_nbe)); - Add("hmax",".",new OneOperator1(pmesh_hmax)); - Add("hmin",".",new OneOperator1(pmesh_hmin)); - //Add("nbnomanifold",".",new OneOperator1(pmesh_nadjnomanifold)); + Add("Gamma",".",new OneOperator1s_(pmesh3_gamma)); + Add("Gamma",".",new OneOperator1s_(pmeshS_gamma)); - - - - + Global.Add("solidangle","(",new OneOperator4_(SolidAngle)); + Global.Add("solidangle","(",new OneOperator2_ >(SolidAngle)); + Global.Add("solidangle","(",new OneOperator2_ >(SolidAngle)); + Global.Add("solidangle","(",new OneOperator3_,long >(SolidAngle)); + // Volume with a Capital because volume is the set in integral + Global.Add("Volume","(",new OneOperator4_(Volume)); + Global.Add("Volume","(",new OneOperator2_ >(Volume)); + Global.Add("Volume","(",new OneOperator2_ >(Volume)); + Global.Add("Volume","(",new OneOperator3_,long >(Volume)); + + //GlgElement // 3D volume @@ -2967,7 +3024,15 @@ TheOperators->Add("=", Add< pfLr >("(", "", new OneQuadOperator< Op4_pfeK< R,v_fesL >, Op4_pfeK< R,v_fesL >::Op >); Add< pfLc >("(", "", new OneQuadOperator< Op4_pfeK< Complex, v_fesL>, Op4_pfeK< Complex,v_fesL >::Op >); */ - + + TheOperators->Add("<-", + new OneOperator2 *,KN *,R3>(set_initR3) +// , new OneOperator2 *,KN *,R3*>(set_initR3) + ); +TheOperators->Add("=", + new OneOperator2 ,KN_ ,R3>(copy_R3) + // , new OneOperator2 ,KN_ ,R3*>(copy_R3) + ); map_type[typeid(double).name()]->AddCast( new E_F1_funcT(pf3r2R) ); @@ -3192,7 +3257,11 @@ Add("Th",".",new OneOperator1(pVhL_Th));//ADD JUIN 2021 F Global.Add("regions","(",new OneOperator1s_,pmesh3>(listofregion)); Global.Add("regions","(",new OneOperator1s_,pmesh>(listofregion)); - + atype()->AddCast( + new E_F1_funcT >(Array2R3) + // new E_F1_funcT* >(pArray2R3) + // new E_F1_funcT >(Cast > + ); } //#include "InitFunct.hpp" diff --git a/src/fflib/problem.cpp b/src/fflib/problem.cpp index 3d14aacd9..b701f5288 100755 --- a/src/fflib/problem.cpp +++ b/src/fflib/problem.cpp @@ -2760,13 +2760,14 @@ template } } else // int on edge ie - //{ - ffassert(0); - /*R2 PA,PB; + { + // ffassert(0); + R2 PA,PB; PA=TriangleHat[VerticesOfTriangularEdge[ie][0]]; PB=TriangleHat[VerticesOfTriangularEdge[ie][1]]; R3 E=T.Edge(ie); double le = sqrt((E,E)); + for (npi=0;npi } } }} - }*/ + } *MeshPointStack(stack) = mp; diff --git a/src/fflib/strversionnumber.m4 b/src/fflib/strversionnumber.m4 index 2acd5cc25..91393a719 100644 --- a/src/fflib/strversionnumber.m4 +++ b/src/fflib/strversionnumber.m4 @@ -3,6 +3,9 @@ #include using namespace std; +#define xstrg(s) strg(s) +#define strg(s) #s + double VersionNumber() { return VersionFreeFem; } @@ -10,7 +13,7 @@ double VersionNumber() { string StrVersionNumber() { ostringstream version; version.precision(8); - version << VersionNumber() + version << xstrg(VersionFreeFem) << " (VersionFreeFemDate - git GitVersion)"; return version.str(); }