diff --git a/.gitattributes b/.gitattributes index 6bc316a77..9d1380127 100644 --- a/.gitattributes +++ b/.gitattributes @@ -14,7 +14,7 @@ # ignore files from MSC.Marc in language statistics install/MarcMentat/** linguist-vendored src/Marc/include/* linguist-vendored -install/MarcMentat/apply_DAMASK_modifications.py linguist-vendored=false +install/MarcMentat/MSC_modifications.py linguist-vendored=false # ignore reference files for tests in language statistics python/tests/reference/** linguist-vendored diff --git a/.github/workflows/Fortran.yml b/.github/workflows/Fortran.yml index e9175bd53..4229b097a 100644 --- a/.github/workflows/Fortran.yml +++ b/.github/workflows/Fortran.yml @@ -2,7 +2,7 @@ name: Grid and Mesh Solver on: [push] env: - PETSC_VERSION: '3.17.1' + PETSC_VERSION: '3.18.2' HOMEBREW_NO_ANALYTICS: 'ON' # Make Homebrew installation a little quicker HOMEBREW_NO_AUTO_UPDATE: 'ON' HOMEBREW_NO_BOTTLE_SOURCE_FALLBACK: 'ON' @@ -11,24 +11,23 @@ env: jobs: - gcc: + gcc_ubuntu: - runs-on: ${{ matrix.os }} + runs-on: ubuntu-22.04 strategy: matrix: - os: [ubuntu-latest, macos-latest] - gcc_v: [9, 10, 11] # Version of GCC compilers + gcc_v: [9, 10, 11, 12] + fail-fast: false env: GCC_V: ${{ matrix.gcc_v }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - - name: GCC - Install (Linux) - if: contains( matrix.os, 'ubuntu') + - name: GCC - Install run: | sudo add-apt-repository ppa:ubuntu-toolchain-r/test sudo apt-get update @@ -38,15 +37,9 @@ jobs: --slave /usr/bin/g++ g++ /usr/bin/g++-${GCC_V} \ --slave /usr/bin/gcov gcov /usr/bin/gcov-${GCC_V} - - name: GCC - Install (macOS) - if: contains( matrix.os, 'macos') - run: | - brew install gcc@${GCC_V} || brew upgrade gcc@${GCC_V} || true - brew link gcc@${GCC_V} - - name: PETSc - Cache download id: petsc-download - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: download key: petsc-${{ env.PETSC_VERSION }}.tar.gz @@ -63,28 +56,19 @@ jobs: export PETSC_ARCH=gcc${GCC_V} printenv >> $GITHUB_ENV - - name: PETSc - Cache installation + - name: PETSc - Cache Installation id: petsc-install - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: petsc-${{ env.PETSC_VERSION }} - key: petsc-${{ env.PETSC_VERSION }}-${{ matrix.os }}-gcc${{ matrix.gcc_v }}-${{ hashFiles('**/petscversion.h') }} + key: petsc-${{ env.PETSC_VERSION }}-gcc${{ matrix.gcc_v }}-${{ hashFiles('**/petscversion.h') }} - - name: PETSc - Install (Linux) - if: contains( matrix.os, 'ubuntu') + - name: PETSc - Installation run: | cd petsc-${PETSC_VERSION} ./configure --with-fc=gfortran --with-cc=gcc --with-cxx=g++ \ - --download-mpich --download-fftw --download-hdf5 --download-hdf5-fortran-bindings=1 --download-zlib \ - --with-mpi-f90module-visibility=0 - make all - - - name: PETSc - Install (macOS) - if: contains( matrix.os, 'macos') - run: | - cd petsc-${PETSC_VERSION} - ./configure --with-fc=gfortran-${GCC_V} --with-cc=gcc-${GCC_V} --with-cxx=g++-${GCC_V} \ - --download-openmpi --download-fftw --download-hdf5 --download-hdf5-fortran-bindings=1 --download-zlib + --download-openmpi --download-fftw --download-hdf5 --download-hdf5-fortran-bindings=1 --download-zlib \ + --with-mpi-f90module-visibility=1 make all - name: DAMASK - Compile @@ -100,19 +84,21 @@ jobs: run: | ./bin/DAMASK_grid -l tensionX.yaml -g 20grains16x16x16.vti -w examples/grid + intel: - runs-on: [ubuntu-latest] + runs-on: [ubuntu-22.04] strategy: matrix: intel_v: [classic, llvm] # Variant of Intel compilers + fail-fast: false env: INTEL_V: ${{ matrix.intel_v }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Intel - Install run: | @@ -130,7 +116,7 @@ jobs: - name: PETSc - Cache download id: petsc-download - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: download key: petsc-${{ env.PETSC_VERSION }}.tar.gz @@ -143,13 +129,15 @@ jobs: - name: PETSc - Prepare run: | tar -xf download/petsc-${PETSC_VERSION}.tar.gz -C . + sed -i "1718s/if not os.path.isfile(os.path.join(self.packageDir,'configure')):/if True:/g" \ + ./petsc-${PETSC_VERSION}/config/BuildSystem/config/package.py export PETSC_DIR=${PWD}/petsc-${PETSC_VERSION} export PETSC_ARCH=intel-${INTEL_V} printenv >> $GITHUB_ENV - name: PETSc - Cache installation id: petsc-install - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: petsc-${{ env.PETSC_VERSION }} key: petsc-${{ env.PETSC_VERSION }}-intel-${{ matrix.intel_v }}-${{ hashFiles('**/petscversion.h') }} @@ -158,7 +146,10 @@ jobs: if: contains( matrix.intel_v, 'classic') run: | cd petsc-${PETSC_VERSION} - ./configure --with-fc=mpiifort --with-cc=mpiicc --with-cxx=mpiicpc \ + ./configure \ + --with-fc='mpiifort -fc=ifort -diag-disable=10441' \ + --with-cc='mpiicc -cc=icc -diag-disable=10441' \ + --with-cxx='mpiicpc -cxx=icpc -diag-disable=10441' \ --download-fftw --download-hdf5 --download-hdf5-fortran-bindings=1 --download-zlib make all @@ -166,7 +157,10 @@ jobs: if: contains( matrix.intel_v, 'llvm') run: | cd petsc-${PETSC_VERSION} - ./configure --with-fc=mpiifort --with-cc="mpiicc -cc=icx" --with-cxx="mpiicpc -cxx=icpx" \ + ./configure \ + --with-fc='mpiifort -fc=ifx' \ + --with-cc='mpiicc -cc=icx' \ + --with-cxx='mpiicpc -cxx=icpx' \ --download-fftw --download-hdf5 --download-hdf5-fortran-bindings=1 --download-zlib make all diff --git a/.github/workflows/Python.yml b/.github/workflows/Python.yml index 2f2a5d111..c630670a1 100644 --- a/.github/workflows/Python.yml +++ b/.github/workflows/Python.yml @@ -9,22 +9,22 @@ jobs: strategy: matrix: - python-version: ['3.8', '3.9'] #, '3.10'] + python-version: ['3.8', '3.9', '3.10'] os: [ubuntu-latest, macos-latest, windows-latest] fail-fast: false steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - name: Install dependencies run: | python -m pip install --upgrade pip - pip install pytest pandas scipy h5py vtk matplotlib pyyaml + pip install pytest pandas scipy h5py vtk matplotlib pyyaml build - name: Strip git hash (Unix) if: runner.os != 'Windows' @@ -39,6 +39,13 @@ jobs: $VERSION,$_ = $VERSION -Split '-g',2,"simplematch" $VERSION | Out-File VERSION + - name: Build and Install + run: | + cd python + python -m build + python -m pip install dist/*.whl + python -c 'import damask;print(damask.__version__)' + - name: Install and run unit tests (Unix) if: runner.os != 'Windows' run: | @@ -56,7 +63,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install pytest run: | diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index faaf66564..8583c09c8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -47,9 +47,9 @@ variables: PETSC_INTELLLVM: "Libraries/PETSc/3.16.3/oneAPI-2022.0.1-IntelMPI-2021.5.0" PETSC_INTEL: "Libraries/PETSc/3.16.5/Intel-2022.0.1-IntelMPI-2021.5.0" # ++++++++++++ MSC Marc +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - MSC: "FEM/MSC/2022.1" + MSC: "FEM/MSC/2022.4" IntelMarc: "Compiler/Intel/19.1.2 Libraries/IMKL/2020" - HDF5Marc: "HDF5/1.12.1/Intel-19.1.2" + HDF5Marc: "HDF5/1.12.2/Intel-19.1.2" ################################################################################################### @@ -63,12 +63,19 @@ create_testroot: ################################################################################################### +setuptools: + stage: python + script: + - sed -i 's/-[[:digit:]]*-.*//' VERSION + - cd python + - python3 -m build --wheel --no-isolation + pytest: stage: python script: - cd python - - pytest --basetemp ${TESTROOT}/python -v --cov --cov-report=term - - coverage report --fail-under=90 + - pytest --basetemp ${TESTROOT}/python -v --cov + - coverage report --fail-under=90 --show-missing mypy: stage: python diff --git a/CMakeLists.txt b/CMakeLists.txt index 6827d31b8..9950b629a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,7 @@ endif() project(Prerequisites LANGUAGES) set(ENV{PKG_CONFIG_PATH} "$ENV{PETSC_DIR}/$ENV{PETSC_ARCH}/lib/pkgconfig:$ENV{PKG_CONFIG_PATH}") pkg_check_modules(PETSC_MIN REQUIRED PETSc>=3.12.0 QUIET) #CMake does not support version range -pkg_check_modules(PETSC REQUIRED PETSc<3.18.0) +pkg_check_modules(PETSC REQUIRED PETSc<3.19.0) pkg_get_variable(CMAKE_Fortran_COMPILER PETSc fcompiler) pkg_get_variable(CMAKE_C_COMPILER PETSc ccompiler) @@ -90,14 +90,21 @@ endif() list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) -if (CMAKE_Fortran_COMPILER_ID STREQUAL "Intel") - include(Compiler-Intel) -elseif(CMAKE_Fortran_COMPILER_ID STREQUAL "GNU") +if (CMAKE_Fortran_COMPILER_ID STREQUAL "GNU") include(Compiler-GNU) + set(Fortran_COMPILER_VERSION_MIN 9.1) +elseif(CMAKE_Fortran_COMPILER_ID STREQUAL "Intel") + include(Compiler-Intel) + set(Fortran_COMPILER_VERSION_MIN 19) elseif(CMAKE_Fortran_COMPILER_ID STREQUAL "IntelLLVM") include(Compiler-IntelLLVM) + set(Fortran_COMPILER_VERSION_MIN 19) else() - message(FATAL_ERROR "Compiler type(CMAKE_Fortran_COMPILER_ID) not recognized") + message(FATAL_ERROR "Compiler '${CMAKE_Fortran_COMPILER_ID}' not supported") +endif() + +if(CMAKE_Fortran_COMPILER_VERSION VERSION_LESS Fortran_COMPILER_VERSION_MIN) + message(FATAL_ERROR "Version '${CMAKE_Fortran_COMPILER_VERSION}' of '${CMAKE_Fortran_COMPILER_ID}' is not supported") endif() file(STRINGS "$ENV{PETSC_DIR}/$ENV{PETSC_ARCH}/lib/petsc/conf/petscvariables" PETSC_EXTERNAL_LIB REGEX "PETSC_EXTERNAL_LIB_BASIC = .*$?") diff --git a/LICENSE b/LICENSE index 11b05b50f..cd1f3810b 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright 2011-2022 Max-Planck-Institut für Eisenforschung GmbH +Copyright 2011-2023 Max-Planck-Institut für Eisenforschung GmbH DAMASK is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as diff --git a/PRIVATE b/PRIVATE index a8bd47ad5..547bfe56d 160000 --- a/PRIVATE +++ b/PRIVATE @@ -1 +1 @@ -Subproject commit a8bd47ad55125b477e6c03277ee38ce3998a66ca +Subproject commit 547bfe56d67cba358a7bb9582f2f7c0e344befd8 diff --git a/VERSION b/VERSION index cd1791ee2..1020479c8 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.0.0-alpha6-552-g938e8bd70 +3.0.0-alpha7-307-g6ee31e2ab diff --git a/cmake/Compiler-Intel.cmake b/cmake/Compiler-Intel.cmake index 4125aa8ef..69aee45ae 100644 --- a/cmake/Compiler-Intel.cmake +++ b/cmake/Compiler-Intel.cmake @@ -29,8 +29,8 @@ set (LINKER_FLAGS "${LINKER_FLAGS} -shared-intel") set (COMPILE_FLAGS "${COMPILE_FLAGS} -fpp") # preprocessor -set (COMPILE_FLAGS "${COMPILE_FLAGS} -ftz") -# flush underflow to zero, automatically set if -O[1,2,3] +set (COMPILE_FLAGS "${COMPILE_FLAGS} -no-ftz") +# disable flush underflow to zero, will be set if -O[1,2,3] set (COMPILE_FLAGS "${COMPILE_FLAGS} -diag-disable") # disables warnings ... @@ -95,8 +95,8 @@ set (DEBUG_FLAGS "${DEBUG_FLAGS},uninit") # ... for uninitialized variables. set (DEBUG_FLAGS "${DEBUG_FLAGS} -ftrapuv") # ... initializes stack local variables to an unusual value to aid error detection -set (DEBUG_FLAGS "${DEBUG_FLAGS} -fpe-all=0") -# ... capture all floating-point exceptions, sets -ftz automatically +set (DEBUG_FLAGS "${DEBUG_FLAGS} -fpe-all=0 -ftz") +# ... capture all floating-point exceptions, need to overwrite -no-ftz # disable due to compiler bug https://community.intel.com/t5/Intel-Fortran-Compiler/false-positive-stand-f18-and-IEEE-SELECTED-REAL-KIND/m-p/1227336 #set (DEBUG_FLAGS "${DEBUG_FLAGS} -warn") diff --git a/cmake/Compiler-IntelLLVM.cmake b/cmake/Compiler-IntelLLVM.cmake index bd0f07ee8..c6e6208b6 100644 --- a/cmake/Compiler-IntelLLVM.cmake +++ b/cmake/Compiler-IntelLLVM.cmake @@ -14,8 +14,8 @@ if (OPTIMIZATION STREQUAL "OFF" OR OPTIMIZATION STREQUAL "DEBUG") elseif (OPTIMIZATION STREQUAL "DEFENSIVE") set (OPTIMIZATION_FLAGS "-O2") elseif (OPTIMIZATION STREQUAL "AGGRESSIVE") - set (OPTIMIZATION_FLAGS "-ipo -O3 -fp-model fast=2 -xHost") - # -fast = -ipo, -O3, -no-prec-div, -static, -fp-model fast=2, and -xHost" + #set (OPTIMIZATION_FLAGS "-ipo -O3 -fp-model fast=2 -xHost") # ifx 2022.0 has problems with YAML types and IPO + set (OPTIMIZATION_FLAGS "-O3 -fp-model fast=2 -xHost") endif () # -assume std_mod_proc_name (included in -standard-semantics) causes problems if other modules @@ -29,8 +29,8 @@ set (LINKER_FLAGS "${LINKER_FLAGS} -shared-intel") set (COMPILE_FLAGS "${COMPILE_FLAGS} -fpp") # preprocessor -set (COMPILE_FLAGS "${COMPILE_FLAGS} -ftz") -# flush underflow to zero, automatically set if -O[1,2,3] +set (COMPILE_FLAGS "${COMPILE_FLAGS} -no-ftz") +# disable flush underflow to zero, will be set if -O[1,2,3] set (COMPILE_FLAGS "${COMPILE_FLAGS} -diag-disable") # disables warnings ... @@ -95,8 +95,8 @@ set (DEBUG_FLAGS "${DEBUG_FLAGS},uninit") # ... for uninitialized variables. set (DEBUG_FLAGS "${DEBUG_FLAGS} -ftrapuv") # ... initializes stack local variables to an unusual value to aid error detection -set (DEBUG_FLAGS "${DEBUG_FLAGS} -fpe-all=0") -# ... capture all floating-point exceptions, sets -ftz automatically +set (DEBUG_FLAGS "${DEBUG_FLAGS} -fpe-all=0 -ftz") +# ... capture all floating-point exceptions, need to overwrite -no-ftz # disable due to compiler bug https://community.intel.com/t5/Intel-Fortran-Compiler/false-positive-stand-f18-and-IEEE-SELECTED-REAL-KIND/m-p/1227336 #set (DEBUG_FLAGS "${DEBUG_FLAGS} -warn") diff --git a/examples/config/Phase_Dislotwin_TWIP-Steel-FeMnC.yaml b/examples/config/Phase_Dislotwin_TWIP-Steel-FeMnC.yaml deleted file mode 100644 index 864a8d2bd..000000000 --- a/examples/config/Phase_Dislotwin_TWIP-Steel-FeMnC.yaml +++ /dev/null @@ -1,62 +0,0 @@ -type: dislotwin -output: [rho_mob, rho_dip, gamma_sl, Lambda_sl, tau_pass, f_tw, Lambda_tw, f_tr] - -# Slip -N_sl: [12] -b_sl: [2.56e-10] -Q_sl: [3.5e-19] -p_sl: [0.325] -q_sl: [1.55] -B: [0.001] -i_sl: [30.0] - -rho_mob_0: [1.0e+12] -rho_dip_0: [1.0] - -v_0: [1.0e+4] -tau_0: [3.5e+8] -D_a: 1.0 # minimum dipole distance / b -Q_cl: 4.5e-19 # Activation energy for climb / J - -h_sl-sl: [0.122, 0.122, 0.625, 0.07, 0.137, 0.137, 0.122] # Interaction coefficients (Kubin et al. 2008) -h_tw-sl: [0.0] # ToDo: values not known - -# Twin -N_tw: [12] -b_tw: [1.40e-10] -L_tw: 1.8e-7 -i_tw: 10.0 -t_tw: [5.0e-8] -p_tw: [3.0] # A - -h_tw-tw: [0.0, 1.0] # ToDo: values not known -h_sl-tw: [0.0, 1.0, 1.0] # ToDo: values not known - -# Transformation -N_tr: [12] -b_tr: [1.40e-10] -L_tr: 1.8e-7 -i_tr: 3.0 -t_tr: [1.0e-7] -p_tr: [3.0] # B -V_mol: 7.09e-6 -Delta_G: 1.33343932e+02 -Delta_G,T: 2.56640412 -Delta_G,T^2: 1.49524179e-03 - -h_tr-tr: [1.0, 1.0] # guessing -h_sl-tr: [0.0, 1.0, 1.0] # guessing - -# Twin & Transformation -T_ref: 298.15 -Gamma_sf: 2.89394017e-02 -Gamma_sf,T: 1.22823814e-04 -Gamma_sf,T^2: 1.47322968e-07 -x_c: 1.0e-9 -V_cs: 1.67e-29 - -a_cF: 3.62e-10 -c/a_hP: 1.633 - -# Slip & Twin & Transformation -D: 2.0e-5 diff --git a/examples/config/numerics.yaml b/examples/config/numerics.yaml index 4363b97cc..e2759ab92 100644 --- a/examples/config/numerics.yaml +++ b/examples/config/numerics.yaml @@ -80,4 +80,4 @@ commercialFEM: generic: random_seed: 0 # fixed seeding for pseudo-random number generator, Default 0: use random seed. - residualStiffness: 1.0e-6 # non-zero residual damage. + phi_min: 1.0e-6 # non-zero residual damage. diff --git a/examples/config/phase/mechanical/eigen/thermalexpansion_AISI304.yaml b/examples/config/phase/mechanical/eigen/thermalexpansion_AISI304.yaml index bc0db5c5e..b266113ab 100644 --- a/examples/config/phase/mechanical/eigen/thermalexpansion_AISI304.yaml +++ b/examples/config/phase/mechanical/eigen/thermalexpansion_AISI304.yaml @@ -4,10 +4,11 @@ references: - R.H. Bogaard et al., Thermochimica Acta 218:373-393, 1993, https://doi.org/10.1016/0040-6031(93)80437-F, - fit to Fig. 6 (T_min=100K, T_max=1400K) + fit to Fig. 6 (T_min=100K, T_max=1200K) -A_11: 2.068e-08 -A_11,T: 1.579e-09 -A_11,T^2: 3.449e-13 +Alpha_11: 14.9e-6 +Alpha_11,T: 1.838e-08 +Alpha_11,T^2: -2.028e-11 +Alpha_11,T^3: 9.173e-15 T_ref: 293.15 diff --git a/examples/config/phase/mechanical/eigen/thermalexpansion_Al.yaml b/examples/config/phase/mechanical/eigen/thermalexpansion_Al.yaml index 495680b4e..7f323f710 100644 --- a/examples/config/phase/mechanical/eigen/thermalexpansion_Al.yaml +++ b/examples/config/phase/mechanical/eigen/thermalexpansion_Al.yaml @@ -4,4 +4,4 @@ references: - https://en.wikipedia.org/wiki/Thermal_expansion, 293.15K -A_11: 23.1e-6 +Alpha_11: 23.1e-6 diff --git a/examples/config/phase/mechanical/eigen/thermalexpansion_Au.yaml b/examples/config/phase/mechanical/eigen/thermalexpansion_Au.yaml index a14ac6b0f..b0ff0360d 100644 --- a/examples/config/phase/mechanical/eigen/thermalexpansion_Au.yaml +++ b/examples/config/phase/mechanical/eigen/thermalexpansion_Au.yaml @@ -4,4 +4,4 @@ references: - https://en.wikipedia.org/wiki/Thermal_expansion, 293.15K -A_11: 14.e-6 +Alpha_11: 14.e-6 diff --git a/examples/config/phase/mechanical/eigen/thermalexpansion_C35E.yaml b/examples/config/phase/mechanical/eigen/thermalexpansion_C35E.yaml index 08e9d6894..90dd0e6da 100644 --- a/examples/config/phase/mechanical/eigen/thermalexpansion_C35E.yaml +++ b/examples/config/phase/mechanical/eigen/thermalexpansion_C35E.yaml @@ -4,8 +4,8 @@ references: - https://commons.wikimedia.org/wiki/File:Coefficient_dilatation_lineique_aciers.svg, fit to image description (Scilab code) -A_11: 12.70371e-6 -A_11,T: 7.54e-9 -A_11,T^2: -1.0e-11 +Alpha_11: 10.2e-6 +Alpha_11,T: 1.260e-08 +Alpha_11,T^2: -1.000e-11 -T_ref: 273.0 +T_ref: 293.15 diff --git a/examples/config/phase/mechanical/eigen/thermalexpansion_Cu.yaml b/examples/config/phase/mechanical/eigen/thermalexpansion_Cu.yaml index a0a35c955..74418c55c 100644 --- a/examples/config/phase/mechanical/eigen/thermalexpansion_Cu.yaml +++ b/examples/config/phase/mechanical/eigen/thermalexpansion_Cu.yaml @@ -4,4 +4,4 @@ references: - https://en.wikipedia.org/wiki/Thermal_expansion, 293.15K -A_11: 17.e-6 +Alpha_11: 17.e-6 diff --git a/examples/config/phase/mechanical/eigen/thermalexpansion_Fe.yaml b/examples/config/phase/mechanical/eigen/thermalexpansion_Fe.yaml index da8ead4c1..6b64ca1a2 100644 --- a/examples/config/phase/mechanical/eigen/thermalexpansion_Fe.yaml +++ b/examples/config/phase/mechanical/eigen/thermalexpansion_Fe.yaml @@ -4,4 +4,4 @@ references: - https://en.wikipedia.org/wiki/Thermal_expansion, 293.15K -A_11: 11.8e-6 +Alpha_11: 11.8e-6 diff --git a/examples/config/phase/mechanical/eigen/thermalexpansion_SiC-alpha.yaml b/examples/config/phase/mechanical/eigen/thermalexpansion_SiC-alpha.yaml new file mode 100644 index 000000000..52bb982d5 --- /dev/null +++ b/examples/config/phase/mechanical/eigen/thermalexpansion_SiC-alpha.yaml @@ -0,0 +1,16 @@ +type: thermalexpansion + +references: + - Z. Li and R.C. Bradt, + Journal of the American Ceramic Society 69(12):863-866, 1986, + https://doi.org/10.1111/j.1151-2916.1986.tb07385.x + +Alpha_11: 3.27e-6 +Alpha_11,T: 3.25e-9 +Alpha_11,T^2: -1.36e-12 + +Alpha_33: 3.18e-6 +Alpha_33,T: 2.48e-9 +Alpha_33,T^2: -8.51e-13 + +T_ref: 273.15 diff --git a/examples/config/phase/mechanical/eigen/thermalexpansion_SiC-beta.yaml b/examples/config/phase/mechanical/eigen/thermalexpansion_SiC-beta.yaml new file mode 100644 index 000000000..6c521472a --- /dev/null +++ b/examples/config/phase/mechanical/eigen/thermalexpansion_SiC-beta.yaml @@ -0,0 +1,12 @@ +type: thermalexpansion + +references: + - Z. Li and R.C. Bradt, + Journal of Materials Science 21:4366-4368, 1986, + https://doi.org/10.1007/BF01106557 + +Alpha_11: 3.19e-6 +Alpha_11,T: 3.60e-9 +Alpha_11,T^2: -1.68e-12 + +T_ref: 273.15 diff --git a/examples/config/phase/mechanical/eigen/thermalexpansion_Sn-beta.yaml b/examples/config/phase/mechanical/eigen/thermalexpansion_Sn-beta.yaml index f77f79bba..9f7ecb6a9 100644 --- a/examples/config/phase/mechanical/eigen/thermalexpansion_Sn-beta.yaml +++ b/examples/config/phase/mechanical/eigen/thermalexpansion_Sn-beta.yaml @@ -6,12 +6,12 @@ references: https://doi.org/10.1107/S0365110X62000742, fit to Tab. 2 (T_min=30ºC, T_max=210ºC) -A_11: 1.639e-05 -A_11,T: 1.799e-08 -A_11,T^2: 1.734e-10 +Alpha_11: 16.4e-6 +Alpha_11,T: 1.799e-08 +Alpha_11,T^2: 1.734e-10 -A_33: 3.263e-05 -A_33,T: 1.387e-08 -A_33,T^2: 5.794e-10 +Alpha_33: 32.6e-6 +Alpha_33,T: 1.387e-08 +Alpha_33,T^2: 5.794e-10 T_ref: 293.15 diff --git a/examples/config/phase/mechanical/eigen/thermalexpansion_W.yaml b/examples/config/phase/mechanical/eigen/thermalexpansion_W.yaml index cb29ab270..ca4d2566b 100644 --- a/examples/config/phase/mechanical/eigen/thermalexpansion_W.yaml +++ b/examples/config/phase/mechanical/eigen/thermalexpansion_W.yaml @@ -4,4 +4,4 @@ references: - https://en.wikipedia.org/wiki/Thermal_expansion, 293.15K -A_11: 4.5e-6 +Alpha_11: 4.5e-6 diff --git a/examples/config/phase/mechanical/eigen/thermalexpansion_X20Cr13.yaml b/examples/config/phase/mechanical/eigen/thermalexpansion_X20Cr13.yaml index 1b8f1545b..c0e9d1676 100644 --- a/examples/config/phase/mechanical/eigen/thermalexpansion_X20Cr13.yaml +++ b/examples/config/phase/mechanical/eigen/thermalexpansion_X20Cr13.yaml @@ -2,9 +2,9 @@ type: thermalexpansion references: - https://commons.wikimedia.org/wiki/File:Coefficient_dilatation_lineique_aciers.svg, - fit to image description (Scilab code) + fit to Scilab code for generating the image (T_min=100ºC, T_max=400ºC) -A_11: 11.365e-6 -A_11,T: 5.0e-9 +Alpha_11: 10.1e-6 +Alpha_11,T: 5.000e-09 -T_ref: 273.0 +T_ref: 293.15 diff --git a/examples/config/phase/mechanical/elastic/Hooke_Ag.yaml b/examples/config/phase/mechanical/elastic/Hooke_Ag.yaml index 3b136a5c2..8d15c88b4 100644 --- a/examples/config/phase/mechanical/elastic/Hooke_Ag.yaml +++ b/examples/config/phase/mechanical/elastic/Hooke_Ag.yaml @@ -3,21 +3,23 @@ type: Hooke references: - J.R. Neighbours and G.A. Alers, Physical Review 111:707-712, 1958, - https://doi.org/10.1103/PhysRev.111.707 + https://doi.org/10.1103/PhysRev.111.707, + fit to Tab. I (T_min=100K, T_max=300K) - Y.A. Chang and L. Himmel, Journal of Applied Physics 37:3567-3572, 1966, - https://doi.org/10.1063/1.1708903 + https://doi.org/10.1063/1.1708903, + fit to Tab. II (T_min=300K, T_max=800K) -C_11: 122.9e+9 -C_11,T: -313.5e+5 -C_11,T^2: -107.3e+2 +C_11: 124.1e+9 +C_11,T: -3.148e+7 +C_11,T^2: -6.594e+3 -C_12: 91.55e+9 -C_12,T: -164.1e+5 -C_12,T^2: -681.6e+1 +C_12: 93.7e+9 +C_12,T: -1.657e+7 +C_12,T^2: -4.220e+3 -C_44: 42.63e+9 -C_44,T: -180.5e+5 -C_44,T^2: -353.8e+1 +C_44: 46.4e+9 +C_44,T: -1.775e+7 +C_44,T^2: -1.973e+3 -T_ref: 300 +T_ref: 293.15 diff --git a/examples/config/phase/mechanical/elastic/Hooke_Al.yaml b/examples/config/phase/mechanical/elastic/Hooke_Al.yaml index 3550449a3..5ef2a41b2 100644 --- a/examples/config/phase/mechanical/elastic/Hooke_Al.yaml +++ b/examples/config/phase/mechanical/elastic/Hooke_Al.yaml @@ -6,20 +6,20 @@ references: https://doi.org/10.1063/1.1713309, fit to Tab. I (T_min=100K, T_max=300K) - D. Gerlich and E.S. Fisher, - Journal of Physics and Chemistry of Solids 30:1197-1205, 1969 + Journal of Physics and Chemistry of Solids 30:1197-1205, 1969, https://doi.org/10.1016/0022-3697(69)90377-1, fit to Tab. 2 (T_min=293K, T_max=900K) C_11: 106.9e+9 -C_11,T: -3.685e+7 -C_11,T^2: -1.016e+4 +C_11,T: -3.691e+7 +C_11,T^2: -9.790e+3 -C_12: 60.55e+9 -C_12,T: -8.307e+6 -C_12,T^2: -4.353e+3 +C_12: 60.5e+9 +C_12,T: -8.412e+6 +C_12,T^2: -3.972e+3 -C_44: 28.37e+9 -C_44,T: -1.418e+7 -C_44,T^2: -3.253e+3 +C_44: 28.4e+9 +C_44,T: -1.413e+7 +C_44,T^2: -3.408e+3 T_ref: 293.15 diff --git a/examples/config/phase/mechanical/elastic/Hooke_Au.yaml b/examples/config/phase/mechanical/elastic/Hooke_Au.yaml index 47afd262b..efea8b742 100644 --- a/examples/config/phase/mechanical/elastic/Hooke_Au.yaml +++ b/examples/config/phase/mechanical/elastic/Hooke_Au.yaml @@ -1,11 +1,25 @@ type: Hooke references: - - J.P. Hirth and J. Lothe, - Theory of Dislocations, 1982, - John Wiley & Sons, - page 837 + - J.R. Neighbours and G.A. Alers, + Physical Review 111:707-712, 1958, + https://doi.org/10.1103/PhysRev.111.707, + fit to Tab. II (T_min=100K, T_max=300K) + - Y.A. Chang and L. Himmel, + Journal of Applied Physics 37:3567-3572, 1966, + https://doi.org/10.1063/1.1708903, + fit to Tab. III (T_min=300K, T_max=800K) -C_11: 186.e+9 -C_12: 157.e+9 -C_44: 42.e+9 +C_11: 192.7e+9 +C_11,T: -3.472e+7 +C_11,T^2: 1.102e+3 + +C_12: 163.2e+9 +C_12,T: -2.607e+7 +C_12,T^2: 2.397e+3 + +C_44: 42.2e+9 +C_44,T: -1.172e+7 +C_44,T^2: -3.078e+3 + +T_ref: 293.15 diff --git a/examples/config/phase/mechanical/elastic/Hooke_Cu.yaml b/examples/config/phase/mechanical/elastic/Hooke_Cu.yaml index d21324084..506cd8239 100644 --- a/examples/config/phase/mechanical/elastic/Hooke_Cu.yaml +++ b/examples/config/phase/mechanical/elastic/Hooke_Cu.yaml @@ -1,21 +1,25 @@ type: Hooke references: - - W.C. Overton, Jr. and J. Gaffney, + - W.C. Overton Jr. and J. Gaffney, Physical Review 98(4):969-977, 1955, https://doi.org/10.1103/PhysRev.98.969, fit to Tab. I (T_min=100K, T_max=300K) + - Y.A. Chang and L. Himmel, + Journal of Applied Physics 37:3567-3572, 1966, + https://doi.org/10.1063/1.1708903, + fit to Tab. II (T_min=300K, T_max=800K) -C_11: 168.6e+9 -C_11,T: -3.779e+7 -C_11,T^2: -2.536e+4 +C_11: 168.9e+9 +C_11,T: -3.332e+7 +C_11,T^2: -1.074e+4 -C_12: 121.5e+9 -C_12,T: -1.632e+7 -C_12,T^2: -1.116e+4 +C_12: 121.8e+9 +C_12,T: -1.402e+7 +C_12,T^2: -9.003e+3 -C_44: 75.59e+9 -C_44,T: -2.912e+7 -C_44,T^2: -1.669e+4 +C_44: 75.8e+9 +C_44,T: -2.555e+7 +C_44,T^2: -2.188e+3 T_ref: 293.15 diff --git a/examples/config/phase/mechanical/elastic/Hooke_Fe.yaml b/examples/config/phase/mechanical/elastic/Hooke_Fe.yaml index 198a2b4d3..e307e94d3 100644 --- a/examples/config/phase/mechanical/elastic/Hooke_Fe.yaml +++ b/examples/config/phase/mechanical/elastic/Hooke_Fe.yaml @@ -6,16 +6,16 @@ references: https://doi.org/10.1063/1.1661710 fit to Tab. II (T_min=25ºC, T_max=880ºC) -C_11: 232.1e+9 -C_11,T: -4.678e+7 -C_11,T^2: -5.762e+4 +C_11: 232.2e+9 +C_11,T: -4.683e+7 +C_11,T^2: -5.988e+4 -C_12: 135.9e+9 -C_12,T: -1.695e+7 -C_12,T^2: 1.555e+3 +C_12: 136.4e+9 +C_12,T: -1.970e+7 +C_12,T^2: 3.760e+3 C_44: 117.0e+9 -C_44,T: -2.047e+7 -C_44,T^2: -2.814e+2 +C_44,T: -2.015e+7 +C_44,T^2: -7.485e+2 T_ref: 293.15 diff --git a/examples/config/phase/mechanical/elastic/Hooke_IN625.yaml b/examples/config/phase/mechanical/elastic/Hooke_IN625.yaml index 1411de6f4..fefd0389b 100644 --- a/examples/config/phase/mechanical/elastic/Hooke_IN625.yaml +++ b/examples/config/phase/mechanical/elastic/Hooke_IN625.yaml @@ -4,18 +4,15 @@ references: - Wang et al., Materials Science and Engineering:A 674:406-412, 2016, https://doi.org/10.1016/j.msea.2016.08.010, - fitted to Tab. 2 (last 3 rows) + fit to Tab. 2 (last 3 rows) -C_11: 243.3e+9 -C_11,T: -6.380e+5 -C_11,T^2: -8.362e+4 +C_11: 243.9e+9 +C_11,T: -5.410e+7 -C_12: 156.7e+9 -C_12,T: 2.091e+7 -C_12,T^2: -4.675e+4 +C_12: 157.0e+9 +C_12,T: -9.352e+6 -C_44: 117.8e+9 -C_44,T: -3.800e+7 -C_44,T^2: 1.587e+4 +C_44: 117.9e+9 +C_44,T: -2.798e+7 T_ref: 293.15 diff --git a/examples/config/phase/mechanical/elastic/Hooke_Mg.yaml b/examples/config/phase/mechanical/elastic/Hooke_Mg.yaml index 06a6cfb62..752ddf0e4 100644 --- a/examples/config/phase/mechanical/elastic/Hooke_Mg.yaml +++ b/examples/config/phase/mechanical/elastic/Hooke_Mg.yaml @@ -6,23 +6,23 @@ references: https://doi.org/10.1103/PhysRev.107.972, fit to Tab. I (T_min=100K, T_max=300K) -C_11: 59.50e+9 +C_11: 59.5e+9 C_11,T: -1.930e+7 C_11,T^2: -1.215e+4 -C_33: 61.72e+9 -C_33,T: -2.175e+7 -C_33,T^2: -5.624e+3 - -C_44: 16.46e+9 -C_44,T: -1.006e+7 -C_44,T^2: -7.692e+3 - -C_12: 25.62e+9 +C_12: 25.6e+9 C_12,T: -2.216e+6 C_12,T^2: -4.138e+3 -C_13: 21.46e+9 +C_44: 16.5e+9 +C_44,T: -1.006e+7 +C_44,T^2: -7.692e+3 + +C_33: 61.7e+9 +C_33,T: -2.175e+7 +C_33,T^2: -5.624e+3 + +C_13: 21.5e+9 C_13,T: -1.921e+6 C_13,T^2: -4.283e+3 diff --git a/examples/config/phase/mechanical/elastic/Hooke_Ni.yaml b/examples/config/phase/mechanical/elastic/Hooke_Ni.yaml index bf63ae047..28ad60f49 100644 --- a/examples/config/phase/mechanical/elastic/Hooke_Ni.yaml +++ b/examples/config/phase/mechanical/elastic/Hooke_Ni.yaml @@ -7,15 +7,15 @@ references: fit to Tab. 2 (T_min=100K, T_max=700K) C_11: 251.0e+9 -C_11,T: -4.998e+7 -C_11,T^2: -2.952e+4 +C_11,T: -4.967e+7 +C_11,T^2: -3.327e+4 C_12: 150.0e+9 -C_12,T: -4.269e+6 -C_12,T^2: -6.429e+3 +C_12,T: -3.714e+6 +C_12,T^2: -7.414e+3 C_44: 123.7e+9 -C_44,T: -3.618e+7 -C_44,T^2: -7.024e+3 +C_44,T: -3.621e+7 +C_44,T^2: -8.017e+3 T_ref: 293.15 diff --git a/examples/config/phase/mechanical/elastic/Hooke_Sn-beta.yaml b/examples/config/phase/mechanical/elastic/Hooke_Sn-beta.yaml index a208c3aec..a55d85c76 100644 --- a/examples/config/phase/mechanical/elastic/Hooke_Sn-beta.yaml +++ b/examples/config/phase/mechanical/elastic/Hooke_Sn-beta.yaml @@ -4,29 +4,24 @@ references: - J.A. Rayne and B.S. Chandrasekhar, Physical Review 120(5):1658-1663, 1960, https://doi.org/10.1103/PhysRev.120.1658, - fit to Fig. 2 (T_min=100K, T_max=300K) and Tab. IV (C_13, T_min=77K, T_max=300K) + fit to Tab. IV (T_min=77K, T_max=300K) -C_11: 72.90e+9 -C_11,T: -4.399e+7 -C_11,T^2: -2.645e+4 +C_11: 72.6e+9 +C_11,T: -4.135e+7 -C_12: 59.27e+9 -C_12,T: 1.058e+7 -C_12,T^2: 1.002e+4 +C_12: 59.4e+9 +C_12,T: 6.726e+6 -C_13: 35.80e+9 +C_44: 22.2e+9 +C_44,T: -1.870e+7 + +C_33: 88.8e+9 +C_33,T: -5.381e+7 + +C_13: 35.8e+9 C_13,T: -2.870e+6 -C_33: 88.78e+9 -C_33,T: -5.250e+7 -C_33,T^2: 3.546e+3 - -C_44: 22.26e+9 -C_44,T: -1.982e+7 -C_44,T^2: -8.711e+3 - -C_66: 24.18e+9 -C_66,T: -1.806e+7 -C_66,T^2: -4.112e+3 +C_66: 24.1e+9 +C_66,T: -1.709e+7 T_ref: 293.15 diff --git a/examples/config/phase/mechanical/elastic/Hooke_Ta.yaml b/examples/config/phase/mechanical/elastic/Hooke_Ta.yaml new file mode 100644 index 000000000..354d66919 --- /dev/null +++ b/examples/config/phase/mechanical/elastic/Hooke_Ta.yaml @@ -0,0 +1,21 @@ +type: Hooke + +references: + - F.H. Featherston and J.R. Neighbours, + Physical Review 130(4):1324-1333, 1963, + https://doi.org/10.1103/PhysRev.130.1324, + fit to Tab. II (T_min=100K, T_max=300K) + +C_11: 523.6e+9 +C_11,T: -7.704e+7 +C_11,T^2: -1.562e+5 + +C_12: 204.6e+9 +C_12,T: -2.485e+7 +C_12,T^2: -1.182e+5 + +C_44: 160.7e+9 +C_44,T: -1.028e+7 +C_44,T^2: 1.291e+4 + +T_ref: 293.15 diff --git a/examples/config/phase/mechanical/elastic/Hooke_Ti.yaml b/examples/config/phase/mechanical/elastic/Hooke_Ti.yaml index 983452cd9..428723c95 100644 --- a/examples/config/phase/mechanical/elastic/Hooke_Ti.yaml +++ b/examples/config/phase/mechanical/elastic/Hooke_Ti.yaml @@ -4,30 +4,26 @@ references: - E.S. Fisher and C.J. Renken, Physical Review 135(2A):A482-A494, 1964, https://doi.org/10.1103/PhysRev.135.A482, - fit to Tab. IV (T_min=150K, T_max=250K) - - H. Ogi et al., - Acta Materialia 52(7):2075-2080, 2004, - https://doi.org/10.1016/j.actamat.2004.01.002, - fit to Fig. 3 (T_min=300K, T_max=900K) + fit to Tab. IV (T_min=77K, T_max=923K) -C_11: 162.6e+9 -C_11,T: -6.150e+7 -C_11,T^2: -5.557e+2 +C_11: 162.5e+9 +C_11,T: -5.915e+7 +C_11,T^2: 1.156e+4 -C_33: 183.3e+9 -C_33,T: -1.655e+07 -C_33,T^2: -1.022e+04 +C_12: 91.8e+9 +C_12,T: 2.192e+7 +C_12,T^2: -1.621e+4 -C_44: 45.80e+9 -C_44,T: -2.936e+07 -C_44,T^2: 7.120e+02 +C_44: 46.8e+9 +C_44,T: -1.857e+7 +C_44,T^2: -3.745e+3 -C_12: 89.97e+9 -C_12,T: 2.776e+6 -C_12,T^2: -2.389e+4 +C_33: 180.6e+9 +C_33,T: -4.110e+7 +C_33,T^2: 7.330e+3 -C_13: 69.53e+9 -C_13,T: 1.057e+7 -C_13,T^2: -2.966e+3 +C_13: 68.9e+9 +C_13,T: 2.965e+6 +C_13,T^2: -5.767e+3 T_ref: 293.15 diff --git a/examples/config/phase/mechanical/elastic/Hooke_W.yaml b/examples/config/phase/mechanical/elastic/Hooke_W.yaml index bb333d6af..2272316d3 100644 --- a/examples/config/phase/mechanical/elastic/Hooke_W.yaml +++ b/examples/config/phase/mechanical/elastic/Hooke_W.yaml @@ -1,20 +1,18 @@ type: Hooke references: - - F.H. Featherston and J.R. Nieghbours, - Physical Review 130(4):1324-1333, + - F.H. Featherston and J.R. Neighbours, + Physical Review 130(4):1324-1333, 1963, https://doi.org/10.1103/PhysRev.130.1324, fit to Tab. III (T_min=100K, T_max=300K) -C_11: 523.6e+9 -C_11,T: -7.607e+7 -C_11,T^2: -1.551e+5 +C_11: 524.3e+9 +C_11,T: -4.794e+07 C_12: 205.1e+9 -C_12,T: -2.843e+6 +C_12,T: -2.836e+06 -C_44: 160.8e+9 -C_44,T: -1.057e+7 -C_44,T^2: 9.933e+3 +C_44: 160.7e+9 +C_44,T: -1.269e+07 T_ref: 293.15 diff --git a/examples/config/phase/mechanical/plastic/dislotungsten_W.yaml b/examples/config/phase/mechanical/plastic/dislotungsten_W.yaml index a1332acc9..7c7a04c58 100644 --- a/examples/config/phase/mechanical/plastic/dislotungsten_W.yaml +++ b/examples/config/phase/mechanical/plastic/dislotungsten_W.yaml @@ -26,7 +26,7 @@ h_sl-sl: [0.009, 0.72, 0.009, 0.05, 0.05, 0.06, 0.09] w: [2.992e-09] # 11b # values in Cereceda et al. are high, using parameters from Gröger et al. -a_nonSchmid: [0.0, 0.56, 0.75] # Table 2 +a_nonSchmid: [0.0, 0.56, 0.75] # Tab. 2 # (almost) no annhilation, adjustment needed for simulations beyond the yield point i_sl: [1] # c, eq. (25) diff --git a/examples/config/phase/mechanical/plastic/dislotwin_IF-steel.yaml b/examples/config/phase/mechanical/plastic/dislotwin_IF-steel.yaml index 62801414f..5b5d3cbc2 100644 --- a/examples/config/phase/mechanical/plastic/dislotwin_IF-steel.yaml +++ b/examples/config/phase/mechanical/plastic/dislotwin_IF-steel.yaml @@ -13,7 +13,7 @@ output: [rho_dip, rho_mob] N_sl: [12, 12] b_sl: [2.49e-10, 2.49e-10] -rho_mob_0: [2.81e12, 2.8e+12] +rho_mob_0: [2.81e+12, 2.8e+12] rho_dip_0: [1.0, 1.0] # not given v_0: [1.4e+3, 1.4e+3] Q_sl: [1.57e-19, 1.57e-19] # Delta_F diff --git a/examples/config/phase/mechanical/plastic/dislotwin_TWIP-TRIP.yaml b/examples/config/phase/mechanical/plastic/dislotwin_TWIP-TRIP.yaml new file mode 100644 index 000000000..3e6087140 --- /dev/null +++ b/examples/config/phase/mechanical/plastic/dislotwin_TWIP-TRIP.yaml @@ -0,0 +1,72 @@ +type: dislotwin + +references: + - S.L. Wong et al., + Acta Materialia 118:140-151, 2016, + https://doi.org/10.1016/j.actamat.2016.07.032 + - K. Sedighiani et al., + Mechanics of Materials, 164:104117, 2022, + https://doi.org/10.1016/j.mechmat.2021.104117 + - L. Kubin et al., + Acta Materialia 56:6040-6049, + https://doi.org/10.1016/j.actamat.2008.08.012 + +output: [rho_mob, rho_dip, gamma_sl, Lambda_sl, tau_pass, f_tw, Lambda_tw, f_tr] + +# Glide +N_sl: [12] +b_sl: [2.56e-10] # a/sqrt(2) +Q_sl: [3.5e-19] +p_sl: [0.325] +q_sl: [1.55] +B: [0.001] +i_sl: [30.0] +v_0: [1.4e+3] +tau_0: [5.5e+8] # adjusted +D_a: 2.0 +Q_cl: 3.0e-19 + +rho_mob_0: [5.0e+10] +rho_dip_0: [5.0e+10] + +h_sl-sl: [0.122, 0.122, 0.625, 0.07, 0.137, 0.137, 0.122] + +# Twin +N_tw: [12] +b_tw: [1.47e-10] # a_cF/sqrt(6) +L_tw: 1.91e-7 # 1300 *b_tw +i_tw: 10.0 +t_tw: [5.0e-8] +p_tw: [7] # A, adjusted + +h_tw-tw: [1.0, 1.0] +h_sl-tw: [1.0, 1.0, 1.0] + +# Transformation +N_tr: [12] +b_tr: [1.47e-10] # a_cF/sqrt(6) +L_tr: 2.21e-7 # 1500 *b_tr +i_tr: 10.0 # adjusted +t_tr: [1.0e-7] +p_tr: [4] # B, adjusted +V_mol: 7.09e-6 +c/a_hP: 1.633 + +Delta_G: 1.2055e+2 +Delta_G,T: 2.5515 +Delta_G,T^2: 1.4952e-3 + +h_tr-tr: [1.0, 1.0] +h_sl-tr: [1.5, 1.5, 1.5] + +# Twin & Transformation +T_ref: 293.15 +Gamma_sf: 2.833e-2 +Gamma_sf,T: 1.214e-4 +Gamma_sf,T^2: 1.473e-7 + +x_c: 1.0e-9 +V_cs: 1.67e-29 + +# Slip & Twin & Transformation +D: 5.0e-5 diff --git a/examples/config/phase/mechanical/plastic/nonlocal_Al.yaml b/examples/config/phase/mechanical/plastic/nonlocal_Al.yaml index 451ce53db..0687b8b8d 100644 --- a/examples/config/phase/mechanical/plastic/nonlocal_Al.yaml +++ b/examples/config/phase/mechanical/plastic/nonlocal_Al.yaml @@ -40,7 +40,7 @@ nu_a: 50.e+9 B: 1.e-2 f_ed: 1.0 # k_3 -h_sl-sl: [0, 0, 0.625, 0.07, 0.137, 0.137, 0.122] # Table 3.4 +h_sl-sl: [0, 0, 0.625, 0.07, 0.137, 0.137, 0.122] # Tab. 3.4 chi_GB: 0.0 # full blocking at GB chi_surface: 1.0 # no blocking at surface diff --git a/examples/config/phase/mechanical/plastic/nonlocal_Ni.yaml b/examples/config/phase/mechanical/plastic/nonlocal_Ni.yaml index 68cf48f3c..5fbf8f9bc 100644 --- a/examples/config/phase/mechanical/plastic/nonlocal_Ni.yaml +++ b/examples/config/phase/mechanical/plastic/nonlocal_Ni.yaml @@ -40,7 +40,7 @@ nu_a: 50.e+9 B: 1.e-3 f_ed: 0.01 # k_3 -h_sl-sl: [0, 0, 0.625, 0.07, 0.137, 0.137, 0.122] # Table 3.4 +h_sl-sl: [0, 0, 0.625, 0.07, 0.137, 0.137, 0.122] # Tab. 3.4 chi_GB: 0.0 # full blocking at GB chi_surface: 1.0 # no blocking at surface diff --git a/examples/config/phase/thermal/Al.yaml b/examples/config/phase/thermal/Al.yaml index 1276f9a3f..b00dceebd 100644 --- a/examples/config/phase/thermal/Al.yaml +++ b/examples/config/phase/thermal/Al.yaml @@ -7,9 +7,11 @@ references: output: [T] -K_11: 2.380e+2 -K_11,T: 2.068e-3 -K_11,T^2: -7.765e-5 +K_11: 2.374e+2 +K_11,T: 8.952e-3 +K_11,T^2: 2.650e-5 +K_11,T^3: -5.687e-7 +K_11,T^4: 6.407e-10 T_ref: 293.15 diff --git a/examples/config/phase/thermal/Cu.yaml b/examples/config/phase/thermal/Cu.yaml index 3875dc8ef..09bd6d664 100644 --- a/examples/config/phase/thermal/Cu.yaml +++ b/examples/config/phase/thermal/Cu.yaml @@ -2,14 +2,16 @@ references: - J.G. Hust and A.B. Lankford, Thermal Conductivity of Aluminum, Copper, Iron, and Tungsten from 1K to the Melting Point, US Department of Commerce, Boulder, Colorado, 1984, - fit to Tab. 2.4.1 (RRR=1000, T_min=200K, T_max=1000K) + fit to Tab. 2.4.1 (RRR=300, T_min=150K, T_max=1000K) - https://www.mit.edu/~6.777/matprops/copper.htm output: [T] -K_11: 4.039e+2 -K_11,T: -8.119e-2 -K_11,T^2: 1.454e-5 +K_11: 4.005e+2 +K_11,T: -1.075e-1 +K_11,T^2: 3.293e-4 +K_11,T^3: -7.533e-7 +K_11,T^4: 5.223e-10 T_ref: 293.15 diff --git a/examples/config/phase/thermal/Fe.yaml b/examples/config/phase/thermal/Fe.yaml index b569683f0..74e586d32 100644 --- a/examples/config/phase/thermal/Fe.yaml +++ b/examples/config/phase/thermal/Fe.yaml @@ -2,14 +2,15 @@ references: - J.G. Hust and A.B. Lankford, Thermal Conductivity of Aluminum, Copper, Iron, and Tungsten from 1K to the Melting Point, US Department of Commerce, Boulder, Colorado, 1984, - fit to Tab. 4.4.1 (RRR=300, T_min=200K, T_max=1000K) + fit to Tab. 4.4.1 (RRR=300, T_min=150K, T_max=1000K) - https://www.engineeringtoolbox.com/specific-heat-metals-d_152.html output: [T] -K_11: 8.055e+1 -K_11,T: -1.051e-1 -K_11,T^2: 5.464e-5 +K_11: 8.034e+1 +K_11,T: -1.216e-1 +K_11,T^2: 1.327e-4 +K_11,T^3: -7.993e-8 T_ref: 293.15 diff --git a/examples/config/phase/thermal/Ni.yaml b/examples/config/phase/thermal/Ni.yaml index 6544c197b..df501f30c 100644 --- a/examples/config/phase/thermal/Ni.yaml +++ b/examples/config/phase/thermal/Ni.yaml @@ -2,14 +2,16 @@ references: - Y.S. Touloukian et al., TPRC Data Series Volume 1. Thermal conductivity - metallic elements and alloys, IFI/Plenum, 1970, - fit to Tab. 35R (T_min=150K, T_max=500K) + fit to Tab. 35R (T_min=80K, T_max=500K) - https://www.engineeringtoolbox.com/specific-heat-metals-d_152.html output: [T] -K_11: 9.132e+1 -K_11,T: -1.525e-1 -K_11,T^2: 3.053e-4 +K_11: 9.311e+1 +K_11,T: -8.719e-2 +K_11,T^2: -3.793e-4 +K_11,T^3: -4.003e-6 +K_11,T^4: 2.676e-8 T_ref: 293.15 diff --git a/examples/config/phase/thermal/Sn-beta.yaml b/examples/config/phase/thermal/Sn-beta.yaml index 99f2c3cee..5f22f4ece 100644 --- a/examples/config/phase/thermal/Sn-beta.yaml +++ b/examples/config/phase/thermal/Sn-beta.yaml @@ -2,18 +2,22 @@ references: - Y.S. Touloukian et al., TPRC Data Series Volume 1. Thermal conductivity - metallic elements and alloys, IFI/Plenum, 1970, - fit to Tab. 61R (T_min=100K, T_max=400K) + fit to Tab. 61R (T_min=80K, T_max=500K) - https://www.engineeringtoolbox.com/specific-heat-metals-d_152.html output: [T] -K_11: 7.414e+1 -K_11,T: -6.465e-2 -K_11,T^2: 2.066e-4 +K_11: 7.495e+1 +K_11,T: -5.646e-2 +K_11,T^2: 1.420e-5 +K_11,T^3: -5.390e-7 +K_11,T^4: 4.012e-9 -K_33: 5.147e+1 -K_33,T: -4.506e-2 -K_33,T^2: 1.435e-4 +K_33: 5.204e+1 +K_33,T: -3.940e-2 +K_33,T^2: 7.037e-6 +K_33,T^3: -3.738e-7 +K_33,T^4: 2.873e-9 T_ref: 293.15 diff --git a/examples/config/phase/thermal/W.yaml b/examples/config/phase/thermal/W.yaml index 5a9cb475f..81326321c 100644 --- a/examples/config/phase/thermal/W.yaml +++ b/examples/config/phase/thermal/W.yaml @@ -2,14 +2,16 @@ references: - J.G. Hust and A.B. Lankford, Thermal Conductivity of Aluminum, Copper, Iron, and Tungsten from 1K to the Melting Point, US Department of Commerce, Boulder, Colorado, 1984, - fit to Tab. 5.4.1 (RRR=300, T_min=200K, T_max=1000K) + fit to Tab. 5.4.1 (RRR=300, T_min=100K, T_max=2000K) - https://www.mit.edu/~6.777/matprops/tungsten.htm output: [T] -K_11: 1.758e+2 -K_11,T: -1.605e-1 -K_11,T^2: 1.160e-4 +K_11: 1.750e+2 +K_11,T: -1.809e-1 +K_11,T^2: 2.257e-4 +K_11,T^3: -1.395e-7 +K_11,T^4: 3.192e-11 T_ref: 293.15 diff --git a/examples/config/phase/thermal/source/externalheat_ramp-and-hold.yaml b/examples/config/phase/thermal/source/externalheat_ramp-and-hold.yaml index 3567f55cf..e6cc8f509 100644 --- a/examples/config/phase/thermal/source/externalheat_ramp-and-hold.yaml +++ b/examples/config/phase/thermal/source/externalheat_ramp-and-hold.yaml @@ -1,4 +1,4 @@ type: externalheat -f_T: [1, 1, 0, 0] -t_n: [0, 500, 500.001, 1000] +f: [1, 1, 0, 0] +t: [0, 500, 500.001, 1000] diff --git a/install/MarcMentat/2020/Marc_tools/include_linux64.patch b/install/MarcMentat/2020/Marc_tools/include_linux64.patch index 043b887f0..193a308f2 100644 --- a/install/MarcMentat/2020/Marc_tools/include_linux64.patch +++ b/install/MarcMentat/2020/Marc_tools/include_linux64.patch @@ -46,7 +46,7 @@ + +# determine DAMASK version +if test -n "$DAMASK_USER"; then -+ DAMASKROOT=`dirname $DAMASK_USER`/.. ++ DAMASKROOT=`dirname $DAMASK_USER`/../.. + read DAMASKVERSION < $DAMASKROOT/VERSION + DAMASKVERSION="'"$DAMASKVERSION"'" +else diff --git a/install/MarcMentat/2020/Marc_tools/run_damask_hmp.patch b/install/MarcMentat/2020/Marc_tools/run_damask_hmp.patch index 0d1be0c8a..f5224265f 100644 --- a/install/MarcMentat/2020/Marc_tools/run_damask_hmp.patch +++ b/install/MarcMentat/2020/Marc_tools/run_damask_hmp.patch @@ -251,7 +251,7 @@ - usersub=$usersubname - fi - -+ userobj=$usermoext.o ++ userobj=$usernoext.o fi cat > $jid.runmarcscript << END4 if test "$user" diff --git a/install/MarcMentat/2020/Marc_tools/run_damask_lmp.patch b/install/MarcMentat/2020/Marc_tools/run_damask_lmp.patch index 0960673de..6e1aa8f01 100644 --- a/install/MarcMentat/2020/Marc_tools/run_damask_lmp.patch +++ b/install/MarcMentat/2020/Marc_tools/run_damask_lmp.patch @@ -251,7 +251,7 @@ - usersub=$usersubname - fi - -+ userobj=$usermoext.o ++ userobj=$usernoext.o fi cat > $jid.runmarcscript << END4 if test "$user" diff --git a/install/MarcMentat/2020/Marc_tools/run_damask_mp.patch b/install/MarcMentat/2020/Marc_tools/run_damask_mp.patch index f8ef8bfb0..12eb57510 100644 --- a/install/MarcMentat/2020/Marc_tools/run_damask_mp.patch +++ b/install/MarcMentat/2020/Marc_tools/run_damask_mp.patch @@ -251,7 +251,7 @@ - usersub=$usersubname - fi - -+ userobj=$usermoext.o ++ userobj=$usernoext.o fi cat > $jid.runmarcscript << END4 if test "$user" diff --git a/install/MarcMentat/2020/Mentat_menus/job_run.ms.patch b/install/MarcMentat/2020/Mentat_menus/job_run.ms.patch index e011e93e3..7c0942335 100644 --- a/install/MarcMentat/2020/Mentat_menus/job_run.ms.patch +++ b/install/MarcMentat/2020/Mentat_menus/job_run.ms.patch @@ -66,7 +66,7 @@ + label { + position -32 +6 + size 12 6 -+ text "O2 / OpenMP" ++ text "O3 / OpenMP" + border_width 1 + border_color black + } diff --git a/install/MarcMentat/2021.2/Marc_tools/include_linux64.patch b/install/MarcMentat/2021.2/Marc_tools/include_linux64.patch index e8dede2ea..a8cb9248a 100644 --- a/install/MarcMentat/2021.2/Marc_tools/include_linux64.patch +++ b/install/MarcMentat/2021.2/Marc_tools/include_linux64.patch @@ -46,7 +46,7 @@ + +# determine DAMASK version +if test -n "$DAMASK_USER"; then -+ DAMASKROOT=`dirname $DAMASK_USER`/.. ++ DAMASKROOT=`dirname $DAMASK_USER`/../.. + read DAMASKVERSION < $DAMASKROOT/VERSION + DAMASKVERSION="'"$DAMASKVERSION"'" +else diff --git a/install/MarcMentat/2021.2/Marc_tools/run_damask_hmp.patch b/install/MarcMentat/2021.2/Marc_tools/run_damask_hmp.patch index 8842a1fda..cd1d7547c 100644 --- a/install/MarcMentat/2021.2/Marc_tools/run_damask_hmp.patch +++ b/install/MarcMentat/2021.2/Marc_tools/run_damask_hmp.patch @@ -284,7 +284,7 @@ - usersub=$usersubname - fi - -+ userobj=$usermoext.o ++ userobj=$usernoext.o fi cat > $jid.runmarcscript << END4 if test "$user" diff --git a/install/MarcMentat/2021.2/Marc_tools/run_damask_lmp.patch b/install/MarcMentat/2021.2/Marc_tools/run_damask_lmp.patch index 02642e7b4..84839e7be 100644 --- a/install/MarcMentat/2021.2/Marc_tools/run_damask_lmp.patch +++ b/install/MarcMentat/2021.2/Marc_tools/run_damask_lmp.patch @@ -284,7 +284,7 @@ - usersub=$usersubname - fi - -+ userobj=$usermoext.o ++ userobj=$usernoext.o fi cat > $jid.runmarcscript << END4 if test "$user" diff --git a/install/MarcMentat/2021.2/Marc_tools/run_damask_mp.patch b/install/MarcMentat/2021.2/Marc_tools/run_damask_mp.patch index c22bcb5c7..e1c40b632 100644 --- a/install/MarcMentat/2021.2/Marc_tools/run_damask_mp.patch +++ b/install/MarcMentat/2021.2/Marc_tools/run_damask_mp.patch @@ -284,7 +284,7 @@ - usersub=$usersubname - fi - -+ userobj=$usermoext.o ++ userobj=$usernoext.o fi cat > $jid.runmarcscript << END4 if test "$user" diff --git a/install/MarcMentat/2021.2/Mentat_menus/job_run.ms.patch b/install/MarcMentat/2021.2/Mentat_menus/job_run.ms.patch index 55f64ecf5..b2bcc08ec 100644 --- a/install/MarcMentat/2021.2/Mentat_menus/job_run.ms.patch +++ b/install/MarcMentat/2021.2/Mentat_menus/job_run.ms.patch @@ -65,7 +65,7 @@ + label { + position -32 +6 + size 12 6 -+ text "O2 / OpenMP" ++ text "O3 / OpenMP" + border_width 1 + border_color black + } diff --git a/install/MarcMentat/2021.3.1/Marc_tools/include_linux64.patch b/install/MarcMentat/2021.3.1/Marc_tools/include_linux64.patch index a90c60aa6..9087d75a3 100644 --- a/install/MarcMentat/2021.3.1/Marc_tools/include_linux64.patch +++ b/install/MarcMentat/2021.3.1/Marc_tools/include_linux64.patch @@ -50,7 +50,7 @@ +# determine DAMASK version +if test -n "$DAMASK_USER"; then -+ DAMASKROOT=`dirname $DAMASK_USER`/.. ++ DAMASKROOT=`dirname $DAMASK_USER`/../.. + read DAMASKVERSION < $DAMASKROOT/VERSION + DAMASKVERSION="'"$DAMASKVERSION"'" +else diff --git a/install/MarcMentat/2021.3.1/Marc_tools/run_damask_hmp.patch b/install/MarcMentat/2021.3.1/Marc_tools/run_damask_hmp.patch index bdec42401..f670c1b71 100644 --- a/install/MarcMentat/2021.3.1/Marc_tools/run_damask_hmp.patch +++ b/install/MarcMentat/2021.3.1/Marc_tools/run_damask_hmp.patch @@ -283,7 +283,7 @@ - usersub=$usersubname - fi - -+ userobj=$usermoext.o ++ userobj=$usernoext.o fi cat > $jid.runmarcscript << END4 if test "$user" diff --git a/install/MarcMentat/2021.3.1/Marc_tools/run_damask_lmp.patch b/install/MarcMentat/2021.3.1/Marc_tools/run_damask_lmp.patch index 3872981dd..3f71a6f87 100644 --- a/install/MarcMentat/2021.3.1/Marc_tools/run_damask_lmp.patch +++ b/install/MarcMentat/2021.3.1/Marc_tools/run_damask_lmp.patch @@ -283,7 +283,7 @@ - usersub=$usersubname - fi - -+ userobj=$usermoext.o ++ userobj=$usernoext.o fi cat > $jid.runmarcscript << END4 if test "$user" diff --git a/install/MarcMentat/2021.3.1/Marc_tools/run_damask_mp.patch b/install/MarcMentat/2021.3.1/Marc_tools/run_damask_mp.patch index 00f8d6e8c..bdece2b7e 100644 --- a/install/MarcMentat/2021.3.1/Marc_tools/run_damask_mp.patch +++ b/install/MarcMentat/2021.3.1/Marc_tools/run_damask_mp.patch @@ -301,7 +301,7 @@ - usersub=$usersubname - fi - -+ userobj=$usermoext.o ++ userobj=$usernoext.o fi cat > $jid.runmarcscript << END4 if test "$user" diff --git a/install/MarcMentat/2021.3.1/Mentat_menus/job_run.ms.patch b/install/MarcMentat/2021.3.1/Mentat_menus/job_run.ms.patch index 6299ca83b..fa25218ca 100644 --- a/install/MarcMentat/2021.3.1/Mentat_menus/job_run.ms.patch +++ b/install/MarcMentat/2021.3.1/Mentat_menus/job_run.ms.patch @@ -67,7 +67,7 @@ + label { + position -32 +6 + size 12 6 -+ text "O2 / OpenMP" ++ text "O3 / OpenMP" + border_width 1 + border_color black + } diff --git a/install/MarcMentat/2022.1/Marc_tools/comp_damask_hmp.patch b/install/MarcMentat/2022.1/Marc_tools/comp_damask_hmp.patch index 8dda8e1ce..886ebf008 100644 --- a/install/MarcMentat/2022.1/Marc_tools/comp_damask_hmp.patch +++ b/install/MarcMentat/2022.1/Marc_tools/comp_damask_hmp.patch @@ -32,7 +32,7 @@ $LOAD ${program} $DIR/lib/main.o\ -@@ -33,9 +42,13 @@ echo "program: $program" +@@ -33,9 +42,13 @@ $TKLIBS \ $MRCLIBS \ $METISLIBS \ @@ -46,4 +46,4 @@ /bin/rm $userobj + /bin/rm $DIRJOB/*.mod + /bin/rm $DIRJOB/*.smod -+ /bin/rm $DIRJOB/*_genmod.f90 ++ /bin/rm $DIRJOB/*_genmod.f90 diff --git a/install/MarcMentat/2022.1/Marc_tools/comp_damask_lmp.patch b/install/MarcMentat/2022.1/Marc_tools/comp_damask_lmp.patch index 6ea9c098f..191cb1a53 100644 --- a/install/MarcMentat/2022.1/Marc_tools/comp_damask_lmp.patch +++ b/install/MarcMentat/2022.1/Marc_tools/comp_damask_lmp.patch @@ -32,7 +32,7 @@ $LOAD ${program} $DIR/lib/main.o\ -@@ -33,9 +42,13 @@ echo "program: $program" +@@ -33,9 +42,13 @@ $TKLIBS \ $MRCLIBS \ $METISLIBS \ @@ -46,4 +46,4 @@ /bin/rm $userobj + /bin/rm $DIRJOB/*.mod + /bin/rm $DIRJOB/*.smod -+ /bin/rm $DIRJOB/*_genmod.f90 ++ /bin/rm $DIRJOB/*_genmod.f90 diff --git a/install/MarcMentat/2022.1/Marc_tools/comp_damask_mp.patch b/install/MarcMentat/2022.1/Marc_tools/comp_damask_mp.patch index 3316227d6..7c9cf7ba7 100644 --- a/install/MarcMentat/2022.1/Marc_tools/comp_damask_mp.patch +++ b/install/MarcMentat/2022.1/Marc_tools/comp_damask_mp.patch @@ -32,7 +32,7 @@ $LOAD ${program} $DIR/lib/main.o\ -@@ -33,9 +42,13 @@ echo "program: $program" +@@ -33,9 +42,13 @@ $TKLIBS \ $MRCLIBS \ $METISLIBS \ @@ -46,4 +46,4 @@ /bin/rm $userobj + /bin/rm $DIRJOB/*.mod + /bin/rm $DIRJOB/*.smod -+ /bin/rm $DIRJOB/*_genmod.f90 ++ /bin/rm $DIRJOB/*_genmod.f90 diff --git a/install/MarcMentat/2022.1/Marc_tools/include_linux64.patch b/install/MarcMentat/2022.1/Marc_tools/include_linux64.patch index d11e84f1a..c0d5aa10e 100644 --- a/install/MarcMentat/2022.1/Marc_tools/include_linux64.patch +++ b/install/MarcMentat/2022.1/Marc_tools/include_linux64.patch @@ -1,6 +1,6 @@ --- +++ -@@ -166,6 +166,11 @@ if test -n "$MSCCOSIM_HOME"; then +@@ -166,6 +166,15 @@ MARC_COSIM_LIB="$MSCCOSIM_HOME/Cosim$MSCCOSIM_VERSION/Dcosim$MSCCOSIM_VERSION/lib" fi @@ -16,17 +16,7 @@ # AEM if test "$MARCDLLOUTDIR" = ""; then DLLOUTDIR="$MARC_LIB" -@@ -477,8 +486,8 @@ if test "$MARC_INTEGER_SIZE" = "i4" ; then - I8DEFINES= - I8CDEFINES= - else -- I8FFLAGS="-i8" -+ I8FFLAGS="-i8 -integer-size 64" - I8DEFINES="-DI64" - I8CDEFINES="-U_DOUBLE -D_SINGLE" - fi - -@@ -594,7 +605,7 @@ then +@@ -594,7 +603,7 @@ PROFILE=" $PROFILE -pg" fi @@ -35,7 +25,7 @@ if test "$MTHREAD" = "OPENMP" then FORT_OPT=" $FORT_OPT -qopenmp" -@@ -607,7 +616,7 @@ else +@@ -607,7 +616,7 @@ FORT_OPT=" $FORT_OPT -save -zero" fi if test "$MARCHDF_HDF" = "HDF"; then @@ -44,13 +34,13 @@ fi FORTLOW="$FCOMP $FORT_OPT $PROFILE -O0 $I8FFLAGS -I$MARC_SOURCE/common \ -@@ -621,6 +630,29 @@ FORTNA="$FCOMP $FORT_OPT -fno-alias -O3 $I8FFLAGS -I$MARC_SOURCE/common \ +@@ -621,6 +630,29 @@ # for compiling free form f90 files. high opt, integer(4) FORTF90="$FCOMP -c -O3" - + +# determine DAMASK version +if test -n "$DAMASK_USER"; then -+ DAMASKROOT=`dirname $DAMASK_USER`/.. ++ DAMASKROOT=`dirname $DAMASK_USER`/../.. + read DAMASKVERSION < $DAMASKROOT/VERSION + DAMASKVERSION="'"$DAMASKVERSION"'" +else @@ -74,30 +64,12 @@ if test "$MARCDEBUG" = "ON" then FORTLOW="$FCOMP $FORT_OPT $PROFILE $I8FFLAGS -I$MARC_SOURCE/common \ -@@ -778,7 +806,7 @@ SECLIBS="-L$MARC_LIB -llapi" - +@@ -778,7 +810,7 @@ + SOLVERLIBS="${BCSSOLVERLIBS} ${VKISOLVERLIBS} ${CASISOLVERLIBS} ${MF2SOLVERLIBS} \ -L$MARC_MKL \ - $MARC_LIB/blas_src.a ${ACSI_LIB}/ACSI_MarcLib.a $KDTREE2_LIB/libkdtree2.a $MARC_LIB/libtetmeshinterface.a $MARC_LIB/libcaefatigueinterface.a -L$MARC_LIB -lmkl_blacs_intelmpi_ilp64 -lmkl_scalapack_ilp64 -lmkl_intel_ilp64 -lmkl_intel_thread -lmkl_core -liomp5 -ltetmesh -lmeshgems -lmg-tetra -lmeshgems_stubs $HDF_LIBS $SOLVER2LIBS" + $MARC_LIB/blas_src.a ${ACSI_LIB}/ACSI_MarcLib.a $KDTREE2_LIB/libkdtree2.a $MARC_LIB/libtetmeshinterface.a $MARC_LIB/libcaefatigueinterface.a -L$MARC_LIB -lmkl_blacs_intelmpi_ilp64 -lmkl_scalapack_ilp64 -lmkl_intel_ilp64 -lmkl_intel_thread -lmkl_core -liomp5 -ltetmesh -lmeshgems -lmg-tetra -lmeshgems_stubs $HDF5_LIB $SOLVER2LIBS" - + SOLVERLIBS_DLL=${SOLVERLIBS} if test "$AEM_DLL" -eq 1 -@@ -802,7 +830,7 @@ then - OPENSSL=NONE - fi - --SYSLIBS=" $OPENMP -lpthread -shared-intel -cxxlib $MARC_RPC_LIB" -+SYSLIBS=" $OPENMP -lpthread -cxxlib $MARC_RPC_LIB" - - # Uncomment the following lines to turn on the trace and comment out the next 4 lines - # if test $MPITYPE = intelmpi -@@ -812,7 +840,7 @@ SYSLIBS=" $OPENMP -lpthread -shared-intel -cxxlib $MARC_RPC_LIB" - # fi - if test $MPITYPE = intelmpi - then -- SYSLIBS="-L${MPI_ROOT}/lib/release -lmpi -L${MPI_ROOT}/lib -lmpifort -lrt $OPENMP -threads -lpthread -shared-intel -cxxlib $MARC_RPC_LIB" -+ SYSLIBS="-L${MPI_ROOT}/lib/release -lmpi -L${MPI_ROOT}/lib -lmpifort -lrt $OPENMP -threads -lpthread -cxxlib $MARC_RPC_LIB" - fi - - if test "$ZLIB" = "ZLIB"; then diff --git a/install/MarcMentat/2022.1/Marc_tools/run_damask_hmp.patch b/install/MarcMentat/2022.1/Marc_tools/run_damask_hmp.patch index e3a364e00..4a1356876 100644 --- a/install/MarcMentat/2022.1/Marc_tools/run_damask_hmp.patch +++ b/install/MarcMentat/2022.1/Marc_tools/run_damask_hmp.patch @@ -1,6 +1,6 @@ --- +++ -@@ -302,7 +302,23 @@ fi +@@ -302,7 +302,23 @@ . "$DIR/getarch" @@ -24,7 +24,7 @@ # # -@@ -405,7 +421,7 @@ sid= +@@ -405,7 +421,7 @@ did= vid= user= @@ -33,16 +33,7 @@ objs= qid=background cpu= -@@ -573,7 +589,7 @@ do - justlist=yes - ;; - -fe* | -FE*) -- feature=$value -+ feature=$value - - ;; - -pr* | -PR*) -@@ -676,50 +692,19 @@ do +@@ -676,50 +692,19 @@ esac ;; -u* | -U*) @@ -99,39 +90,7 @@ ;; -obj | -OBJ) objs="$value" -@@ -739,19 +724,19 @@ do - ;; - esac - ;; -- -dl | -DL) -- case $value in -- y* | Y*) -- deletelog=yes -- ;; -- n* | N*) -- deletelog=no -- ;; -- *) -- ;; -- esac -+ -dl | -DL) -+ case $value in -+ y* | Y*) -+ deletelog=yes -+ ;; -+ n* | N*) -+ deletelog=no -+ ;; -+ *) -+ ;; -+ esac - -- ;; -+ ;; - -at | -AT) - att=$value - ;; -@@ -1207,12 +1192,12 @@ post file $DIRPID/$pid.t16 or $DIRPID/$pid.t19 or $DIRPID/$pid.h5 not accessible +@@ -1207,12 +1192,12 @@ fi fi fi @@ -147,16 +106,7 @@ fi fi if test "$objs" -@@ -1386,7 +1371,7 @@ else - else - error="$error - job id required" -- fi -+fi - fi - - case $qid in -@@ -1531,7 +1516,7 @@ Program name : $prog +@@ -1531,7 +1516,7 @@ Marc shared lib : $progdll Version type : $mode Job ID : $DIRJID/$jid$extra_job_info @@ -165,7 +115,7 @@ User objects/libs : $objs Restart file job ID : $rid Substructure file ID : $sid -@@ -1564,7 +1549,7 @@ Program name : $prog +@@ -1564,7 +1549,7 @@ Marc shared lib : $progdll Version type : $mode Job ID : $DIRJID/$jid$extra_job_info @@ -174,7 +124,7 @@ User objects/libs : $objs Restart file job ID : $rid Substructure file ID : $sid -@@ -1687,7 +1672,7 @@ Program name ($prog)? $ECHOTXT" +@@ -1687,7 +1672,7 @@ ;; esac fi @@ -183,7 +133,7 @@ read value if test "$value" then -@@ -1696,50 +1681,19 @@ Program name ($prog)? $ECHOTXT" +@@ -1696,50 +1681,19 @@ user= ;; *) @@ -209,16 +159,13 @@ - fi + user=$value case $user in -- \/*) -- ;; -- *) -+ \/*) -+ ;; -+ *) + \/*) + ;; + *) user=`pwd`/$user - usersubname=`pwd`/$usersubname -- ;; -- esac + ;; + esac - if test ! -f $usersubname - then - if test -f $usersubname.f @@ -235,8 +182,6 @@ - usersubname=$usersubname.F90 - fi - fi -+ ;; -+ esac + usernoext=$user + usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` + usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` @@ -245,7 +190,7 @@ ;; esac fi -@@ -2274,11 +2228,12 @@ fi +@@ -2274,11 +2228,12 @@ # # user subroutine used # @@ -260,7 +205,7 @@ case $program in \/* | \.\/*) bd= -@@ -2391,7 +2346,7 @@ fi +@@ -2391,7 +2346,7 @@ fi if test "$user" then @@ -269,7 +214,7 @@ usersub=1 fi export execpath -@@ -3274,44 +3229,27 @@ then +@@ -3274,44 +3229,27 @@ echo if test "$user" then @@ -283,7 +228,7 @@ - usersub=$usersubname - fi - -+ userobj=$usermoext.o ++ userobj=$usernoext.o fi cat > $jid.runmarcscript << END4 if test "$user" @@ -319,21 +264,15 @@ fi -@@ -3331,10 +3269,11 @@ then +@@ -3331,6 +3269,7 @@ $TKLIBS \ $MRCLIBS \ $METISLIBS \ -- $SFLIB \ + $DAMASK \ -+ $SFLIB \ + $SFLIB \ $OPENSSL_LIB \ $SYSLIBS \ -- $SECLIBS || \ -+ $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - exit 1 -@@ -3344,6 +3283,9 @@ else +@@ -3344,6 +3283,9 @@ prgsav=yes fi /bin/rm $userobj 2>/dev/null @@ -343,7 +282,7 @@ # # run marc -@@ -3390,7 +3332,7 @@ if test $dllrun -eq 0; then +@@ -3390,7 +3332,7 @@ fi else if test $cpdll = yes; then @@ -352,7 +291,7 @@ /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null fi if test $rmdll = yes -@@ -3556,7 +3498,7 @@ then +@@ -3556,7 +3498,7 @@ # first copy over the user sub if local directories if test ${dirstatus[$counter]} = "local" then @@ -361,7 +300,7 @@ fi # do the compilation on the other machine if test ${dirstatus[$counter]} = "shared" -@@ -3569,21 +3511,21 @@ then +@@ -3569,21 +3511,21 @@ remoteuser=$DIR1/`$BASENAME $user` $RSH $i /bin/rm $remoteprog 2> /dev/null echo @@ -386,7 +325,7 @@ fi fi fi -@@ -3593,39 +3535,27 @@ then +@@ -3593,39 +3535,27 @@ if test "$userhost" then echo @@ -432,21 +371,15 @@ fi # if test $user -@@ -3645,10 +3575,11 @@ then +@@ -3645,6 +3575,7 @@ $TKLIBS \ $MRCLIBS \ $METISLIBS \ -- $SFLIB \ + $DAMASK \ -+ $SFLIB \ + $SFLIB \ $OPENSSL_LIB \ $SYSLIBS \ -- $SECLIBS || \ -+ $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - echo " $PRODUCT Exit number 3" -@@ -3686,6 +3617,9 @@ else # if test $link +@@ -3686,6 +3617,9 @@ prgsav=yes fi # if test $link /bin/rm $userobj 2>/dev/null @@ -456,69 +389,7 @@ # # run marc -@@ -3744,42 +3678,42 @@ then - counter=0 - if test -f "$host_filt" - then -- for i in `$AWK -v n=$numfield '{print $n}' $host_filt` -- do -- ibase=${i%%.*} -- if test $ibase != $thishost -+ for i in `$AWK -v n=$numfield '{print $n}' $host_filt` -+ do -+ ibase=${i%%.*} -+ if test $ibase != $thishost -+ then -+ counter=$((counter+1)) -+ DIR1=$DIRJOB -+ line=`grep -v '^#' $userhost | grep "^$ibase "` -+ workdir=`echo $line | $AWK '{print $3}'` -+ if test -n "$workdir" - then -- counter=$((counter+1)) -- DIR1=$DIRJOB -- line=`grep -v '^#' $userhost | grep "^$ibase "` -- workdir=`echo $line | $AWK '{print $3}'` -- if test -n "$workdir" -- then -- DIR1=$workdir -- fi -- # if an incompatible host uses shared directory, -- # then the root machine deletes the executable -- if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" -- then -- hname=_$ibase -- /bin/rm ${execname}$hname -- fi -- # if local directory used, the remote machine -- # deletes the executable -- if test ${dirstatus[$counter]} = "local" -- then -- $RSH $i /bin/rm $DIR1/${execname} 2>/dev/null -- fi -+ DIR1=$workdir - fi -- done -- fi -+ # if an incompatible host uses shared directory, -+ # then the root machine deletes the executable -+ if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" -+ then -+ hname=_$ibase -+ /bin/rm ${execname}$hname -+ fi -+ # if local directory used, the remote machine -+ # deletes the executable -+ if test ${dirstatus[$counter]} = "local" -+ then -+ $RSH $i /bin/rm $DIR1/${execname} 2>/dev/null -+ fi -+ fi -+ done - fi - fi - fi -+fi +@@ -3779,7 +3713,7 @@ else #dllrun >0 if test $cpdll = yes; then @@ -527,7 +398,7 @@ /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null fi if test $rmdll = yes;then -@@ -3904,7 +3838,7 @@ then +@@ -3904,7 +3838,7 @@ # first copy over the user sub if local directories if test ${dirstatus[$counter]} = "local" then @@ -536,7 +407,7 @@ fi # do the compilation on the other machine if test ${dirstatus[$counter]} = "shared" -@@ -3917,20 +3851,20 @@ then +@@ -3917,20 +3851,20 @@ remoteuser=$DIR1/`$BASENAME $user` $RSH $i /bin/rm $remoteprog 2> /dev/null echo @@ -560,7 +431,7 @@ fi fi fi -@@ -3940,37 +3874,25 @@ then +@@ -3940,37 +3874,25 @@ if test "$userhost" then echo @@ -604,7 +475,7 @@ fi # if test $user -@@ -3990,10 +3912,11 @@ then +@@ -3990,6 +3912,7 @@ $TKLIBS \ $MRCLIBS \ $METISLIBS \ @@ -612,12 +483,7 @@ $SFLIB \ $OPENSSL_LIB \ $SYSLIBS \ -- $SECLIBS || \ -+ $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - exit 1 -@@ -4030,7 +3953,9 @@ else # if test $link +@@ -4030,7 +3953,9 @@ prgsav=yes fi # if test $link /bin/rm $userobj 2>/dev/null @@ -628,78 +494,7 @@ # done if no job id given if test -z "$jid" then -@@ -4070,7 +3995,7 @@ if test $ddm_arc -gt 0; then - RUN_JOB="$BINDIR/exeddm $RUN_JOB -ddm $ddm_arc " - fi - --$RUN_JOB -+ $RUN_JOB - - if test $nprocd -gt 1 - then -@@ -4114,42 +4039,42 @@ then - counter=0 - if test -f "$host_filt" - then -- for i in `$AWK -v n=$numfield '{print $n}' $host_filt` -- do -- ibase=${i%%.*} -- if test $ibase != $thishost -+ for i in `$AWK -v n=$numfield '{print $n}' $host_filt` -+ do -+ ibase=${i%%.*} -+ if test $ibase != $thishost -+ then -+ counter=$((counter+1)) -+ DIR1=$DIRJOB -+ line=`grep -v '^#' $userhost | grep "^$ibase "` -+ workdir=`echo $line | $AWK '{print $3}'` -+ if test -n "$workdir" - then -- counter=$((counter+1)) -- DIR1=$DIRJOB -- line=`grep -v '^#' $userhost | grep "^$ibase "` -- workdir=`echo $line | $AWK '{print $3}'` -- if test -n "$workdir" -- then -- DIR1=$workdir -- fi -- # if an incompatible host uses shared directory, -- # then the root machine deletes the executable -- if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" -- then -- hname=_$ibase -- /bin/rm ${execname}$hname -- fi -- # if local directory used, the remote machine -- # deletes the executable -- if test ${dirstatus[$counter]} = "local" -- then -- $RSH $i /bin/rm $DIR1/${execname} 2>/dev/null -- fi -+ DIR1=$workdir - fi -- done -- fi -+ # if an incompatible host uses shared directory, -+ # then the root machine deletes the executable -+ if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" -+ then -+ hname=_$ibase -+ /bin/rm ${execname}$hname -+ fi -+ # if local directory used, the remote machine -+ # deletes the executable -+ if test ${dirstatus[$counter]} = "local" -+ then -+ $RSH $i /bin/rm $DIR1/${execname} 2>/dev/null -+ fi -+ fi -+ done - fi - fi - fi -+fi +@@ -4149,7 +4074,7 @@ else #dllrun >0 if test $cpdll = yes; then diff --git a/install/MarcMentat/2022.1/Marc_tools/run_damask_lmp.patch b/install/MarcMentat/2022.1/Marc_tools/run_damask_lmp.patch index a5989bfca..86265457b 100644 --- a/install/MarcMentat/2022.1/Marc_tools/run_damask_lmp.patch +++ b/install/MarcMentat/2022.1/Marc_tools/run_damask_lmp.patch @@ -1,6 +1,6 @@ --- +++ -@@ -302,7 +302,23 @@ fi +@@ -302,7 +302,23 @@ . "$DIR/getarch" @@ -24,7 +24,7 @@ # # -@@ -405,7 +421,7 @@ sid= +@@ -405,7 +421,7 @@ did= vid= user= @@ -33,16 +33,7 @@ objs= qid=background cpu= -@@ -573,7 +589,7 @@ do - justlist=yes - ;; - -fe* | -FE*) -- feature=$value -+ feature=$value - - ;; - -pr* | -PR*) -@@ -676,50 +692,19 @@ do +@@ -676,50 +692,19 @@ esac ;; -u* | -U*) @@ -99,39 +90,7 @@ ;; -obj | -OBJ) objs="$value" -@@ -739,19 +724,19 @@ do - ;; - esac - ;; -- -dl | -DL) -- case $value in -- y* | Y*) -- deletelog=yes -- ;; -- n* | N*) -- deletelog=no -- ;; -- *) -- ;; -- esac -+ -dl | -DL) -+ case $value in -+ y* | Y*) -+ deletelog=yes -+ ;; -+ n* | N*) -+ deletelog=no -+ ;; -+ *) -+ ;; -+ esac - -- ;; -+ ;; - -at | -AT) - att=$value - ;; -@@ -1207,12 +1192,12 @@ post file $DIRPID/$pid.t16 or $DIRPID/$pid.t19 or $DIRPID/$pid.h5 not accessible +@@ -1207,12 +1192,12 @@ fi fi fi @@ -147,16 +106,7 @@ fi fi if test "$objs" -@@ -1386,7 +1371,7 @@ else - else - error="$error - job id required" -- fi -+fi - fi - - case $qid in -@@ -1531,7 +1516,7 @@ Program name : $prog +@@ -1531,7 +1516,7 @@ Marc shared lib : $progdll Version type : $mode Job ID : $DIRJID/$jid$extra_job_info @@ -165,7 +115,7 @@ User objects/libs : $objs Restart file job ID : $rid Substructure file ID : $sid -@@ -1564,7 +1549,7 @@ Program name : $prog +@@ -1564,7 +1549,7 @@ Marc shared lib : $progdll Version type : $mode Job ID : $DIRJID/$jid$extra_job_info @@ -174,7 +124,7 @@ User objects/libs : $objs Restart file job ID : $rid Substructure file ID : $sid -@@ -1687,7 +1672,7 @@ Program name ($prog)? $ECHOTXT" +@@ -1687,7 +1672,7 @@ ;; esac fi @@ -183,7 +133,7 @@ read value if test "$value" then -@@ -1696,50 +1681,19 @@ Program name ($prog)? $ECHOTXT" +@@ -1696,50 +1681,19 @@ user= ;; *) @@ -209,16 +159,13 @@ - fi + user=$value case $user in -- \/*) -- ;; -- *) -+ \/*) -+ ;; -+ *) + \/*) + ;; + *) user=`pwd`/$user - usersubname=`pwd`/$usersubname -- ;; -- esac + ;; + esac - if test ! -f $usersubname - then - if test -f $usersubname.f @@ -235,8 +182,6 @@ - usersubname=$usersubname.F90 - fi - fi -+ ;; -+ esac + usernoext=$user + usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` + usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` @@ -245,7 +190,7 @@ ;; esac fi -@@ -2274,11 +2228,12 @@ fi +@@ -2274,11 +2228,12 @@ # # user subroutine used # @@ -260,7 +205,7 @@ case $program in \/* | \.\/*) bd= -@@ -2391,7 +2346,7 @@ fi +@@ -2391,7 +2346,7 @@ fi if test "$user" then @@ -269,7 +214,7 @@ usersub=1 fi export execpath -@@ -3274,44 +3229,27 @@ then +@@ -3274,44 +3229,27 @@ echo if test "$user" then @@ -283,7 +228,7 @@ - usersub=$usersubname - fi - -+ userobj=$usermoext.o ++ userobj=$usernoext.o fi cat > $jid.runmarcscript << END4 if test "$user" @@ -319,21 +264,15 @@ fi -@@ -3331,10 +3269,11 @@ then +@@ -3331,6 +3269,7 @@ $TKLIBS \ $MRCLIBS \ $METISLIBS \ -- $SFLIB \ + $DAMASK \ -+ $SFLIB \ + $SFLIB \ $OPENSSL_LIB \ $SYSLIBS \ -- $SECLIBS || \ -+ $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - exit 1 -@@ -3344,6 +3283,9 @@ else +@@ -3344,6 +3283,9 @@ prgsav=yes fi /bin/rm $userobj 2>/dev/null @@ -343,7 +282,7 @@ # # run marc -@@ -3390,7 +3332,7 @@ if test $dllrun -eq 0; then +@@ -3390,7 +3332,7 @@ fi else if test $cpdll = yes; then @@ -352,7 +291,7 @@ /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null fi if test $rmdll = yes -@@ -3556,7 +3498,7 @@ then +@@ -3556,7 +3498,7 @@ # first copy over the user sub if local directories if test ${dirstatus[$counter]} = "local" then @@ -361,7 +300,7 @@ fi # do the compilation on the other machine if test ${dirstatus[$counter]} = "shared" -@@ -3569,21 +3511,21 @@ then +@@ -3569,21 +3511,21 @@ remoteuser=$DIR1/`$BASENAME $user` $RSH $i /bin/rm $remoteprog 2> /dev/null echo @@ -386,7 +325,7 @@ fi fi fi -@@ -3593,39 +3535,27 @@ then +@@ -3593,39 +3535,27 @@ if test "$userhost" then echo @@ -432,21 +371,15 @@ fi # if test $user -@@ -3645,10 +3575,11 @@ then +@@ -3645,6 +3575,7 @@ $TKLIBS \ $MRCLIBS \ $METISLIBS \ -- $SFLIB \ + $DAMASK \ -+ $SFLIB \ + $SFLIB \ $OPENSSL_LIB \ $SYSLIBS \ -- $SECLIBS || \ -+ $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - echo " $PRODUCT Exit number 3" -@@ -3686,6 +3617,9 @@ else # if test $link +@@ -3686,6 +3617,9 @@ prgsav=yes fi # if test $link /bin/rm $userobj 2>/dev/null @@ -456,69 +389,7 @@ # # run marc -@@ -3744,42 +3678,42 @@ then - counter=0 - if test -f "$host_filt" - then -- for i in `$AWK -v n=$numfield '{print $n}' $host_filt` -- do -- ibase=${i%%.*} -- if test $ibase != $thishost -+ for i in `$AWK -v n=$numfield '{print $n}' $host_filt` -+ do -+ ibase=${i%%.*} -+ if test $ibase != $thishost -+ then -+ counter=$((counter+1)) -+ DIR1=$DIRJOB -+ line=`grep -v '^#' $userhost | grep "^$ibase "` -+ workdir=`echo $line | $AWK '{print $3}'` -+ if test -n "$workdir" - then -- counter=$((counter+1)) -- DIR1=$DIRJOB -- line=`grep -v '^#' $userhost | grep "^$ibase "` -- workdir=`echo $line | $AWK '{print $3}'` -- if test -n "$workdir" -- then -- DIR1=$workdir -- fi -- # if an incompatible host uses shared directory, -- # then the root machine deletes the executable -- if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" -- then -- hname=_$ibase -- /bin/rm ${execname}$hname -- fi -- # if local directory used, the remote machine -- # deletes the executable -- if test ${dirstatus[$counter]} = "local" -- then -- $RSH $i /bin/rm $DIR1/${execname} 2>/dev/null -- fi -+ DIR1=$workdir - fi -- done -- fi -+ # if an incompatible host uses shared directory, -+ # then the root machine deletes the executable -+ if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" -+ then -+ hname=_$ibase -+ /bin/rm ${execname}$hname -+ fi -+ # if local directory used, the remote machine -+ # deletes the executable -+ if test ${dirstatus[$counter]} = "local" -+ then -+ $RSH $i /bin/rm $DIR1/${execname} 2>/dev/null -+ fi -+ fi -+ done - fi - fi - fi -+fi +@@ -3779,7 +3713,7 @@ else #dllrun >0 if test $cpdll = yes; then @@ -527,7 +398,7 @@ /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null fi if test $rmdll = yes;then -@@ -3904,7 +3838,7 @@ then +@@ -3904,7 +3838,7 @@ # first copy over the user sub if local directories if test ${dirstatus[$counter]} = "local" then @@ -536,7 +407,7 @@ fi # do the compilation on the other machine if test ${dirstatus[$counter]} = "shared" -@@ -3917,20 +3851,20 @@ then +@@ -3917,20 +3851,20 @@ remoteuser=$DIR1/`$BASENAME $user` $RSH $i /bin/rm $remoteprog 2> /dev/null echo @@ -560,7 +431,7 @@ fi fi fi -@@ -3940,37 +3874,25 @@ then +@@ -3940,37 +3874,25 @@ if test "$userhost" then echo @@ -604,7 +475,7 @@ fi # if test $user -@@ -3990,10 +3912,11 @@ then +@@ -3990,6 +3912,7 @@ $TKLIBS \ $MRCLIBS \ $METISLIBS \ @@ -612,12 +483,7 @@ $SFLIB \ $OPENSSL_LIB \ $SYSLIBS \ -- $SECLIBS || \ -+ $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - exit 1 -@@ -4030,7 +3953,9 @@ else # if test $link +@@ -4030,7 +3953,9 @@ prgsav=yes fi # if test $link /bin/rm $userobj 2>/dev/null @@ -628,78 +494,7 @@ # done if no job id given if test -z "$jid" then -@@ -4070,7 +3995,7 @@ if test $ddm_arc -gt 0; then - RUN_JOB="$BINDIR/exeddm $RUN_JOB -ddm $ddm_arc " - fi - --$RUN_JOB -+ $RUN_JOB - - if test $nprocd -gt 1 - then -@@ -4114,42 +4039,42 @@ then - counter=0 - if test -f "$host_filt" - then -- for i in `$AWK -v n=$numfield '{print $n}' $host_filt` -- do -- ibase=${i%%.*} -- if test $ibase != $thishost -+ for i in `$AWK -v n=$numfield '{print $n}' $host_filt` -+ do -+ ibase=${i%%.*} -+ if test $ibase != $thishost -+ then -+ counter=$((counter+1)) -+ DIR1=$DIRJOB -+ line=`grep -v '^#' $userhost | grep "^$ibase "` -+ workdir=`echo $line | $AWK '{print $3}'` -+ if test -n "$workdir" - then -- counter=$((counter+1)) -- DIR1=$DIRJOB -- line=`grep -v '^#' $userhost | grep "^$ibase "` -- workdir=`echo $line | $AWK '{print $3}'` -- if test -n "$workdir" -- then -- DIR1=$workdir -- fi -- # if an incompatible host uses shared directory, -- # then the root machine deletes the executable -- if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" -- then -- hname=_$ibase -- /bin/rm ${execname}$hname -- fi -- # if local directory used, the remote machine -- # deletes the executable -- if test ${dirstatus[$counter]} = "local" -- then -- $RSH $i /bin/rm $DIR1/${execname} 2>/dev/null -- fi -+ DIR1=$workdir - fi -- done -- fi -+ # if an incompatible host uses shared directory, -+ # then the root machine deletes the executable -+ if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" -+ then -+ hname=_$ibase -+ /bin/rm ${execname}$hname -+ fi -+ # if local directory used, the remote machine -+ # deletes the executable -+ if test ${dirstatus[$counter]} = "local" -+ then -+ $RSH $i /bin/rm $DIR1/${execname} 2>/dev/null -+ fi -+ fi -+ done - fi - fi - fi -+fi +@@ -4149,7 +4074,7 @@ else #dllrun >0 if test $cpdll = yes; then diff --git a/install/MarcMentat/2022.1/Marc_tools/run_damask_mp.patch b/install/MarcMentat/2022.1/Marc_tools/run_damask_mp.patch index 924af6fbd..4a1356876 100644 --- a/install/MarcMentat/2022.1/Marc_tools/run_damask_mp.patch +++ b/install/MarcMentat/2022.1/Marc_tools/run_damask_mp.patch @@ -1,8 +1,6 @@ -diff --git "a/C:\\Users\\f.roters\\Documents\\Forschung\\FEM\\Kristallplastizit\303\244t\\Programme\\Userroutinen\\Marc\\Marc_mods\\2022.1\\Marc_tools\\run_marc.original" "b/C:\\Users\\f.roters\\Documents\\Forschung\\FEM\\Kristallplastizit\303\244t\\Programme\\Userroutinen\\Marc\\Marc_mods\\2022.1\\Marc_tools\\run_damask_mp" -index 88a3027..85beabe 100644 ---- "a/C:\\Users\\f.roters\\Documents\\Forschung\\FEM\\Kristallplastizit\303\244t\\Programme\\Userroutinen\\Marc\\Marc_mods\\2022.1\\Marc_tools\\run_marc.original" -+++ "b/C:\\Users\\f.roters\\Documents\\Forschung\\FEM\\Kristallplastizit\303\244t\\Programme\\Userroutinen\\Marc\\Marc_mods\\2022.1\\Marc_tools\\run_damask_mp" -@@ -302,7 +302,23 @@ fi +--- ++++ +@@ -302,7 +302,23 @@ . "$DIR/getarch" @@ -26,7 +24,7 @@ index 88a3027..85beabe 100644 # # -@@ -405,7 +421,7 @@ sid= +@@ -405,7 +421,7 @@ did= vid= user= @@ -35,16 +33,7 @@ index 88a3027..85beabe 100644 objs= qid=background cpu= -@@ -573,7 +589,7 @@ do - justlist=yes - ;; - -fe* | -FE*) -- feature=$value -+ feature=$value - - ;; - -pr* | -PR*) -@@ -676,50 +692,19 @@ do +@@ -676,50 +692,19 @@ esac ;; -u* | -U*) @@ -101,39 +90,7 @@ index 88a3027..85beabe 100644 ;; -obj | -OBJ) objs="$value" -@@ -739,19 +724,19 @@ do - ;; - esac - ;; -- -dl | -DL) -- case $value in -- y* | Y*) -- deletelog=yes -- ;; -- n* | N*) -- deletelog=no -- ;; -- *) -- ;; -- esac -+ -dl | -DL) -+ case $value in -+ y* | Y*) -+ deletelog=yes -+ ;; -+ n* | N*) -+ deletelog=no -+ ;; -+ *) -+ ;; -+ esac - -- ;; -+ ;; - -at | -AT) - att=$value - ;; -@@ -1207,12 +1192,12 @@ post file $DIRPID/$pid.t16 or $DIRPID/$pid.t19 or $DIRPID/$pid.h5 not accessible +@@ -1207,12 +1192,12 @@ fi fi fi @@ -149,16 +106,7 @@ index 88a3027..85beabe 100644 fi fi if test "$objs" -@@ -1386,7 +1371,7 @@ else - else - error="$error - job id required" -- fi -+fi - fi - - case $qid in -@@ -1531,7 +1516,7 @@ Program name : $prog +@@ -1531,7 +1516,7 @@ Marc shared lib : $progdll Version type : $mode Job ID : $DIRJID/$jid$extra_job_info @@ -167,16 +115,7 @@ index 88a3027..85beabe 100644 User objects/libs : $objs Restart file job ID : $rid Substructure file ID : $sid -@@ -1548,8 +1533,6 @@ GPGPU option : $gpuids - Host file name : $host" > $jid.log - if test "$iprintsimufact" = true ; then - echo "DDM with ARC Mapper : $ddm_arc" >> $jid.log -- echo "Mapper directory : $MESHERDIR" >> $jid.log -- echo "Meshing directory : $MESHERDIR" >> $jid.log - fi - echo \ - "Message passing type : $itree -@@ -1564,7 +1547,7 @@ Program name : $prog +@@ -1564,7 +1549,7 @@ Marc shared lib : $progdll Version type : $mode Job ID : $DIRJID/$jid$extra_job_info @@ -185,16 +124,7 @@ index 88a3027..85beabe 100644 User objects/libs : $objs Restart file job ID : $rid Substructure file ID : $sid -@@ -1579,6 +1562,8 @@ Solver processes : $nsolverprint - Solver threads : $ntsprint" - if test "$iprintsimufact" = true ; then - echo "DDM with ARC Mapper : $ddm_arc" -+ echo "Mapper directory : $MESHERDIR" >> $jid.log -+ echo "Meshing directory : $MESHERDIR" >> $jid.log - fi - echo \ - "GPGPU option : $gpuids -@@ -1687,7 +1672,7 @@ Program name ($prog)? $ECHOTXT" +@@ -1687,7 +1672,7 @@ ;; esac fi @@ -203,7 +133,7 @@ index 88a3027..85beabe 100644 read value if test "$value" then -@@ -1696,50 +1681,19 @@ Program name ($prog)? $ECHOTXT" +@@ -1696,50 +1681,19 @@ user= ;; *) @@ -229,16 +159,13 @@ index 88a3027..85beabe 100644 - fi + user=$value case $user in -- \/*) -- ;; -- *) -+ \/*) -+ ;; -+ *) + \/*) + ;; + *) user=`pwd`/$user - usersubname=`pwd`/$usersubname -- ;; -- esac + ;; + esac - if test ! -f $usersubname - then - if test -f $usersubname.f @@ -255,8 +182,6 @@ index 88a3027..85beabe 100644 - usersubname=$usersubname.F90 - fi - fi -+ ;; -+ esac + usernoext=$user + usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` + usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` @@ -265,7 +190,7 @@ index 88a3027..85beabe 100644 ;; esac fi -@@ -2274,11 +2228,12 @@ fi +@@ -2274,11 +2228,12 @@ # # user subroutine used # @@ -280,7 +205,7 @@ index 88a3027..85beabe 100644 case $program in \/* | \.\/*) bd= -@@ -2391,7 +2346,7 @@ fi +@@ -2391,7 +2346,7 @@ fi if test "$user" then @@ -289,7 +214,7 @@ index 88a3027..85beabe 100644 usersub=1 fi export execpath -@@ -3274,44 +3229,27 @@ then +@@ -3274,44 +3229,27 @@ echo if test "$user" then @@ -303,7 +228,7 @@ index 88a3027..85beabe 100644 - usersub=$usersubname - fi - -+ userobj=$usermoext.o ++ userobj=$usernoext.o fi cat > $jid.runmarcscript << END4 if test "$user" @@ -315,7 +240,7 @@ index 88a3027..85beabe 100644 if test $MACHINENAME = "CRAY" then - $FORTRAN $usersub || \ -+ $DFORTRANMP $user || \ ++ $DFORTHIGHMP $user || \ { - echo "$0: compile failed for $user.f" + echo "$0: compile failed for $user" @@ -324,7 +249,7 @@ index 88a3027..85beabe 100644 /bin/rm $program 2>/dev/null else - $FORTRAN $usersub -o $userobj || \ -+ $DFORTRANMP $user -o $userobj || \ ++ $DFORTHIGHMP $user -o $userobj || \ { - echo "$0: compile failed for $user.f" + echo "$0: compile failed for $user" @@ -339,21 +264,15 @@ index 88a3027..85beabe 100644 fi -@@ -3331,10 +3269,11 @@ then +@@ -3331,6 +3269,7 @@ $TKLIBS \ $MRCLIBS \ $METISLIBS \ -- $SFLIB \ + $DAMASK \ -+ $SFLIB \ + $SFLIB \ $OPENSSL_LIB \ $SYSLIBS \ -- $SECLIBS || \ -+ $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - exit 1 -@@ -3344,6 +3283,9 @@ else +@@ -3344,6 +3283,9 @@ prgsav=yes fi /bin/rm $userobj 2>/dev/null @@ -363,7 +282,7 @@ index 88a3027..85beabe 100644 # # run marc -@@ -3390,7 +3332,7 @@ if test $dllrun -eq 0; then +@@ -3390,7 +3332,7 @@ fi else if test $cpdll = yes; then @@ -372,7 +291,7 @@ index 88a3027..85beabe 100644 /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null fi if test $rmdll = yes -@@ -3556,7 +3498,7 @@ then +@@ -3556,7 +3498,7 @@ # first copy over the user sub if local directories if test ${dirstatus[$counter]} = "local" then @@ -381,12 +300,12 @@ index 88a3027..85beabe 100644 fi # do the compilation on the other machine if test ${dirstatus[$counter]} = "shared" -@@ -3569,21 +3511,21 @@ then +@@ -3569,21 +3511,21 @@ remoteuser=$DIR1/`$BASENAME $user` $RSH $i /bin/rm $remoteprog 2> /dev/null echo - $RSH $i $DIR2/tools/comp_user $DIR2 $DIR1 $remoteuser $remoteprog -+ $RSH $i $DIR2/tools/comp_damask_mp $DIR2 $DIR1 $remoteuser $remoteprog ++ $RSH $i $DIR2/tools/comp_damask_hmp $DIR2 $DIR1 $remoteuser $remoteprog # check if successful, the new executable should be there line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` if test "$line" @@ -406,7 +325,7 @@ index 88a3027..85beabe 100644 fi fi fi -@@ -3593,39 +3535,27 @@ then +@@ -3593,39 +3535,27 @@ if test "$userhost" then echo @@ -426,7 +345,7 @@ index 88a3027..85beabe 100644 if test $MACHINENAME = "CRAY" then - $FORTRAN $usersub || \ -+ $DFORTRANMP $user || \ ++ $DFORTHIGHMP $user || \ { - echo "$0: compile failed for $user.f" + echo "$0: compile failed for $user" @@ -436,7 +355,7 @@ index 88a3027..85beabe 100644 /bin/rm $program 2>/dev/null else - $FORTRAN $usersub -o $userobj || \ -+ $DFORTRANMP $user -o $userobj || \ ++ $DFORTHIGHMP $user -o $userobj || \ { - echo "$0: compile failed for $user.f" + echo "$0: compile failed for $user" @@ -452,21 +371,15 @@ index 88a3027..85beabe 100644 fi # if test $user -@@ -3645,10 +3575,11 @@ then +@@ -3645,6 +3575,7 @@ $TKLIBS \ $MRCLIBS \ $METISLIBS \ -- $SFLIB \ + $DAMASK \ -+ $SFLIB \ + $SFLIB \ $OPENSSL_LIB \ $SYSLIBS \ -- $SECLIBS || \ -+ $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - echo " $PRODUCT Exit number 3" -@@ -3686,6 +3617,9 @@ else # if test $link +@@ -3686,6 +3617,9 @@ prgsav=yes fi # if test $link /bin/rm $userobj 2>/dev/null @@ -476,69 +389,7 @@ index 88a3027..85beabe 100644 # # run marc -@@ -3744,42 +3678,42 @@ then - counter=0 - if test -f "$host_filt" - then -- for i in `$AWK -v n=$numfield '{print $n}' $host_filt` -- do -- ibase=${i%%.*} -- if test $ibase != $thishost -+ for i in `$AWK -v n=$numfield '{print $n}' $host_filt` -+ do -+ ibase=${i%%.*} -+ if test $ibase != $thishost -+ then -+ counter=$((counter+1)) -+ DIR1=$DIRJOB -+ line=`grep -v '^#' $userhost | grep "^$ibase "` -+ workdir=`echo $line | $AWK '{print $3}'` -+ if test -n "$workdir" - then -- counter=$((counter+1)) -- DIR1=$DIRJOB -- line=`grep -v '^#' $userhost | grep "^$ibase "` -- workdir=`echo $line | $AWK '{print $3}'` -- if test -n "$workdir" -- then -- DIR1=$workdir -- fi -- # if an incompatible host uses shared directory, -- # then the root machine deletes the executable -- if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" -- then -- hname=_$ibase -- /bin/rm ${execname}$hname -- fi -- # if local directory used, the remote machine -- # deletes the executable -- if test ${dirstatus[$counter]} = "local" -- then -- $RSH $i /bin/rm $DIR1/${execname} 2>/dev/null -- fi -+ DIR1=$workdir - fi -- done -- fi -+ # if an incompatible host uses shared directory, -+ # then the root machine deletes the executable -+ if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" -+ then -+ hname=_$ibase -+ /bin/rm ${execname}$hname -+ fi -+ # if local directory used, the remote machine -+ # deletes the executable -+ if test ${dirstatus[$counter]} = "local" -+ then -+ $RSH $i /bin/rm $DIR1/${execname} 2>/dev/null -+ fi -+ fi -+ done - fi - fi - fi -+fi +@@ -3779,7 +3713,7 @@ else #dllrun >0 if test $cpdll = yes; then @@ -547,7 +398,7 @@ index 88a3027..85beabe 100644 /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null fi if test $rmdll = yes;then -@@ -3904,7 +3838,7 @@ then +@@ -3904,7 +3838,7 @@ # first copy over the user sub if local directories if test ${dirstatus[$counter]} = "local" then @@ -556,12 +407,12 @@ index 88a3027..85beabe 100644 fi # do the compilation on the other machine if test ${dirstatus[$counter]} = "shared" -@@ -3917,20 +3851,20 @@ then +@@ -3917,20 +3851,20 @@ remoteuser=$DIR1/`$BASENAME $user` $RSH $i /bin/rm $remoteprog 2> /dev/null echo - $RSH $i $DIR2/tools/comp_user $DIR2 $DIR1 $remoteuser $remoteprog -+ $RSH $i $DIR2/tools/comp_damask_mp $DIR2 $DIR1 $remoteuser $remoteprog ++ $RSH $i $DIR2/tools/comp_damask_hmp $DIR2 $DIR1 $remoteuser $remoteprog # check if successful, the new executable should be there line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` if test "$line" @@ -580,7 +431,7 @@ index 88a3027..85beabe 100644 fi fi fi -@@ -3940,37 +3874,25 @@ then +@@ -3940,37 +3874,25 @@ if test "$userhost" then echo @@ -600,7 +451,7 @@ index 88a3027..85beabe 100644 if test $MACHINENAME = "CRAY" then - $FORTRAN $usersub || \ -+ $DFORTRANMP $user || \ ++ $DFORTHIGHMP $user || \ { - echo "$0: compile failed for $user.f" + echo "$0: compile failed for $user" @@ -609,7 +460,7 @@ index 88a3027..85beabe 100644 /bin/rm $program 2>/dev/null else - $FORTRAN $usersub -o $userobj || \ -+ $DFORTRANMP $user -o $userobj || \ ++ $DFORTHIGHMP $user -o $userobj || \ { - echo "$0: compile failed for $user.f" + echo "$0: compile failed for $user" @@ -624,7 +475,7 @@ index 88a3027..85beabe 100644 fi # if test $user -@@ -3990,10 +3912,11 @@ then +@@ -3990,6 +3912,7 @@ $TKLIBS \ $MRCLIBS \ $METISLIBS \ @@ -632,12 +483,7 @@ index 88a3027..85beabe 100644 $SFLIB \ $OPENSSL_LIB \ $SYSLIBS \ -- $SECLIBS || \ -+ $SECLIBS || \ - { - echo "$0: link failed for ${user:+$userobj }$objs" - exit 1 -@@ -4030,7 +3953,9 @@ else # if test $link +@@ -4030,7 +3953,9 @@ prgsav=yes fi # if test $link /bin/rm $userobj 2>/dev/null @@ -648,78 +494,7 @@ index 88a3027..85beabe 100644 # done if no job id given if test -z "$jid" then -@@ -4070,7 +3995,7 @@ if test $ddm_arc -gt 0; then - RUN_JOB="$BINDIR/exeddm $RUN_JOB -ddm $ddm_arc " - fi - --$RUN_JOB -+ $RUN_JOB - - if test $nprocd -gt 1 - then -@@ -4114,42 +4039,42 @@ then - counter=0 - if test -f "$host_filt" - then -- for i in `$AWK -v n=$numfield '{print $n}' $host_filt` -- do -- ibase=${i%%.*} -- if test $ibase != $thishost -+ for i in `$AWK -v n=$numfield '{print $n}' $host_filt` -+ do -+ ibase=${i%%.*} -+ if test $ibase != $thishost -+ then -+ counter=$((counter+1)) -+ DIR1=$DIRJOB -+ line=`grep -v '^#' $userhost | grep "^$ibase "` -+ workdir=`echo $line | $AWK '{print $3}'` -+ if test -n "$workdir" - then -- counter=$((counter+1)) -- DIR1=$DIRJOB -- line=`grep -v '^#' $userhost | grep "^$ibase "` -- workdir=`echo $line | $AWK '{print $3}'` -- if test -n "$workdir" -- then -- DIR1=$workdir -- fi -- # if an incompatible host uses shared directory, -- # then the root machine deletes the executable -- if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" -- then -- hname=_$ibase -- /bin/rm ${execname}$hname -- fi -- # if local directory used, the remote machine -- # deletes the executable -- if test ${dirstatus[$counter]} = "local" -- then -- $RSH $i /bin/rm $DIR1/${execname} 2>/dev/null -- fi -+ DIR1=$workdir - fi -- done -- fi -+ # if an incompatible host uses shared directory, -+ # then the root machine deletes the executable -+ if test ${dirstatus[$counter]} = "shared" -a ${compstatus[$counter]} = "no" -+ then -+ hname=_$ibase -+ /bin/rm ${execname}$hname -+ fi -+ # if local directory used, the remote machine -+ # deletes the executable -+ if test ${dirstatus[$counter]} = "local" -+ then -+ $RSH $i /bin/rm $DIR1/${execname} 2>/dev/null -+ fi -+ fi -+ done - fi - fi - fi -+fi +@@ -4149,7 +4074,7 @@ else #dllrun >0 if test $cpdll = yes; then diff --git a/install/MarcMentat/2022.1/Mentat_bin/submit4.patch b/install/MarcMentat/2022.1/Mentat_bin/submit4.patch index 3f1371fdb..98c51e76d 100644 --- a/install/MarcMentat/2022.1/Mentat_bin/submit4.patch +++ b/install/MarcMentat/2022.1/Mentat_bin/submit4.patch @@ -1,6 +1,6 @@ --- +++ -@@ -63,10 +64,10 @@ doe_nparallel=$6 +@@ -63,10 +63,10 @@ if [ "$slv" != "" -a "$slv" != "marc" -a "$slv" != "datfit" ]; then slv="-iam sfm" fi @@ -13,7 +13,7 @@ slv="-iam datfit" fi -@@ -91,6 +92,7 @@ if [ "$srcfile" != "" -a "$srcfile" != "-" ]; then +@@ -91,6 +91,7 @@ srcfile="-u $srcfile -save y" ;; runsaved) @@ -21,7 +21,7 @@ srcfile="-prog $srcfile" ;; esac -@@ -189,12 +191,12 @@ unset PYTHONHOME +@@ -189,12 +190,12 @@ unset PYTHONPATH if [ "$doe_first" = "-" ]; then # submit of regular Marc job diff --git a/install/MarcMentat/2022.1/Mentat_bin/submit5.patch b/install/MarcMentat/2022.1/Mentat_bin/submit5.patch index 9614d8c69..ab32b1058 100644 --- a/install/MarcMentat/2022.1/Mentat_bin/submit5.patch +++ b/install/MarcMentat/2022.1/Mentat_bin/submit5.patch @@ -1,6 +1,6 @@ --- +++ -@@ -63,10 +64,10 @@ doe_nparallel=$6 +@@ -63,10 +63,10 @@ if [ "$slv" != "" -a "$slv" != "marc" -a "$slv" != "datfit" ]; then slv="-iam sfm" fi @@ -13,7 +13,7 @@ slv="-iam datfit" fi -@@ -91,6 +92,7 @@ if [ "$srcfile" != "" -a "$srcfile" != "-" ]; then +@@ -91,6 +91,7 @@ srcfile="-u $srcfile -save y" ;; runsaved) @@ -21,7 +21,7 @@ srcfile="-prog $srcfile" ;; esac -@@ -189,12 +191,12 @@ unset PYTHONHOME +@@ -189,12 +190,12 @@ unset PYTHONPATH if [ "$doe_first" = "-" ]; then # submit of regular Marc job diff --git a/install/MarcMentat/2022.1/Mentat_bin/submit6.patch b/install/MarcMentat/2022.1/Mentat_bin/submit6.patch index a3ed16135..d5ea3cfde 100644 --- a/install/MarcMentat/2022.1/Mentat_bin/submit6.patch +++ b/install/MarcMentat/2022.1/Mentat_bin/submit6.patch @@ -1,6 +1,6 @@ --- +++ -@@ -63,10 +64,10 @@ doe_nparallel=$6 +@@ -63,10 +63,10 @@ if [ "$slv" != "" -a "$slv" != "marc" -a "$slv" != "datfit" ]; then slv="-iam sfm" fi @@ -13,7 +13,7 @@ slv="-iam datfit" fi -@@ -91,6 +92,7 @@ if [ "$srcfile" != "" -a "$srcfile" != "-" ]; then +@@ -91,6 +91,7 @@ srcfile="-u $srcfile -save y" ;; runsaved) @@ -21,7 +21,7 @@ srcfile="-prog $srcfile" ;; esac -@@ -189,12 +191,12 @@ unset PYTHONHOME +@@ -189,12 +190,12 @@ unset PYTHONPATH if [ "$doe_first" = "-" ]; then # submit of regular Marc job diff --git a/install/MarcMentat/2022.1/Mentat_menus/job_run.ms.patch b/install/MarcMentat/2022.1/Mentat_menus/job_run.ms.patch index 6cbcf895c..979f8856a 100644 --- a/install/MarcMentat/2022.1/Mentat_menus/job_run.ms.patch +++ b/install/MarcMentat/2022.1/Mentat_menus/job_run.ms.patch @@ -1,6 +1,6 @@ --- +++ -@@ -261,11 +261,18 @@ popmenu job_run_popmenu { +@@ -261,12 +261,19 @@ } button { position +25 = @@ -10,21 +10,21 @@ help "job_run#Job Submission And Control" popmenu job_submit_adv_pm } -+ button { + button { + position +18 = + size 7 4 + text "DAMASK" + help "damask_run#Job Submission And Control" + popmenu damask + } - button { ++ button { position 0 +4 size 12 4 -@@ -1189,6 +1196,135 @@ popmenu job_submit_adv_pm { - } + text "UPDATE" +@@ -1190,6 +1197,135 @@ -+#-------------------------------------------------------------------------------------------------- + #-------------------------------------------------------------------------------------------------- +popmenu damask { + +#ifdef QT_MENTAT @@ -67,7 +67,7 @@ + label { + position -32 +6 + size 12 6 -+ text "O2 / OpenMP" ++ text "O3 / OpenMP" + border_width 1 + border_color black + } @@ -153,6 +153,7 @@ + mode permanent +} + - #-------------------------------------------------------------------------------------------------- ++#-------------------------------------------------------------------------------------------------- popmenu job_exit_msg_pm { + text "EXIT MESSAGE" diff --git a/install/MarcMentat/2022.2/Marc_tools/comp_damask_hmp.patch b/install/MarcMentat/2022.2/Marc_tools/comp_damask_hmp.patch new file mode 100644 index 000000000..886ebf008 --- /dev/null +++ b/install/MarcMentat/2022.2/Marc_tools/comp_damask_hmp.patch @@ -0,0 +1,49 @@ +--- ++++ +@@ -6,18 +6,27 @@ + DIR=$1 + user=$3 + program=$4 ++usernoext=$user ++usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` ++usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` ++usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` ++usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` ++ ++# add BLAS options for linking ++ BLAS="%BLAS%" ++ + . $DIR/tools/include + DIRJOB=$2 + cd $DIRJOB +-echo "Compiling and linking user subroutine $user.f on host `hostname`" ++echo "Compiling and linking user subroutine $user on host `hostname`" + echo "program: $program" +- $FORTRAN $user.f || \ ++ $DFORTHIGHMP $user || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null +- userobj=$user.o ++ userobj=$usernoext.o + + + $LOAD ${program} $DIR/lib/main.o\ +@@ -33,9 +42,13 @@ + $TKLIBS \ + $MRCLIBS \ + $METISLIBS \ ++ $BLAS \ + $SYSLIBS || \ + { +- echo "$0: link failed for $user.o on host `hostname`" ++ echo "$0: link failed for $usernoext.o on host `hostname`" + exit 1 + } + /bin/rm $userobj ++ /bin/rm $DIRJOB/*.mod ++ /bin/rm $DIRJOB/*.smod ++ /bin/rm $DIRJOB/*_genmod.f90 diff --git a/install/MarcMentat/2022.2/Marc_tools/comp_damask_lmp.patch b/install/MarcMentat/2022.2/Marc_tools/comp_damask_lmp.patch new file mode 100644 index 000000000..191cb1a53 --- /dev/null +++ b/install/MarcMentat/2022.2/Marc_tools/comp_damask_lmp.patch @@ -0,0 +1,49 @@ +--- ++++ +@@ -6,18 +6,27 @@ + DIR=$1 + user=$3 + program=$4 ++usernoext=$user ++usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` ++usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` ++usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` ++usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` ++ ++# add BLAS options for linking ++ BLAS="%BLAS%" ++ + . $DIR/tools/include + DIRJOB=$2 + cd $DIRJOB +-echo "Compiling and linking user subroutine $user.f on host `hostname`" ++echo "Compiling and linking user subroutine $user on host `hostname`" + echo "program: $program" +- $FORTRAN $user.f || \ ++ $DFORTRANLOWMP $user || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null +- userobj=$user.o ++ userobj=$usernoext.o + + + $LOAD ${program} $DIR/lib/main.o\ +@@ -33,9 +42,13 @@ + $TKLIBS \ + $MRCLIBS \ + $METISLIBS \ ++ $BLAS \ + $SYSLIBS || \ + { +- echo "$0: link failed for $user.o on host `hostname`" ++ echo "$0: link failed for $usernoext.o on host `hostname`" + exit 1 + } + /bin/rm $userobj ++ /bin/rm $DIRJOB/*.mod ++ /bin/rm $DIRJOB/*.smod ++ /bin/rm $DIRJOB/*_genmod.f90 diff --git a/install/MarcMentat/2022.2/Marc_tools/comp_damask_mp.patch b/install/MarcMentat/2022.2/Marc_tools/comp_damask_mp.patch new file mode 100644 index 000000000..7c9cf7ba7 --- /dev/null +++ b/install/MarcMentat/2022.2/Marc_tools/comp_damask_mp.patch @@ -0,0 +1,49 @@ +--- ++++ +@@ -6,18 +6,27 @@ + DIR=$1 + user=$3 + program=$4 ++usernoext=$user ++usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` ++usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` ++usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` ++usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` ++ ++# add BLAS options for linking ++ BLAS="%BLAS%" ++ + . $DIR/tools/include + DIRJOB=$2 + cd $DIRJOB +-echo "Compiling and linking user subroutine $user.f on host `hostname`" ++echo "Compiling and linking user subroutine $user on host `hostname`" + echo "program: $program" +- $FORTRAN $user.f || \ ++ $DFORTRANMP $user || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null +- userobj=$user.o ++ userobj=$usernoext.o + + + $LOAD ${program} $DIR/lib/main.o\ +@@ -33,9 +42,13 @@ + $TKLIBS \ + $MRCLIBS \ + $METISLIBS \ ++ $BLAS \ + $SYSLIBS || \ + { +- echo "$0: link failed for $user.o on host `hostname`" ++ echo "$0: link failed for $usernoext.o on host `hostname`" + exit 1 + } + /bin/rm $userobj ++ /bin/rm $DIRJOB/*.mod ++ /bin/rm $DIRJOB/*.smod ++ /bin/rm $DIRJOB/*_genmod.f90 diff --git a/install/MarcMentat/2022.2/Marc_tools/include_linux64.patch b/install/MarcMentat/2022.2/Marc_tools/include_linux64.patch new file mode 100644 index 000000000..27219e75e --- /dev/null +++ b/install/MarcMentat/2022.2/Marc_tools/include_linux64.patch @@ -0,0 +1,75 @@ +--- ++++ +@@ -166,6 +166,15 @@ + MARC_COSIM_LIB="$MSCCOSIM_HOME/CoSim$MSCCOSIM_VERSION/Dcosim$MSCCOSIM_VERSION/lib" + fi + ++# DAMASK uses the HDF5 compiler wrapper around the Intel compiler ++H5FC=$(h5fc -shlib -show) ++if [[ "$H5FC" == *"$dir is"* ]]; then ++ H5FC=$(echo $(echo "$H5FC" | tail -n1) | sed -e "s/\-shlib/-fPIC -qopenmp/g") ++ H5FC=${H5FC%-lmpifort*} ++fi ++HDF5_LIB=${H5FC//*ifort/} ++FCOMP="$H5FC" ++ + # AEM + if test "$MARCDLLOUTDIR" = ""; then + DLLOUTDIR="$MARC_LIB" +@@ -594,7 +603,7 @@ + PROFILE=" $PROFILE -pg" + fi + +-FORT_OPT="-c -assume byterecl -safe_cray_ptr -mp1 -WB -fp-model source" ++FORT_OPT="-c -implicitnone -stand f18 -standard-semantics -assume nostd_mod_proc_name -safe_cray_ptr -mp1 -WB -fp-model source" + if test "$MTHREAD" = "OPENMP" + then + FORT_OPT=" $FORT_OPT -qopenmp" +@@ -607,7 +616,7 @@ + FORT_OPT=" $FORT_OPT -save -zero" + fi + if test "$MARCHDF_HDF" = "HDF"; then +- FORT_OPT="$FORT_OPT -DMARCHDF_HDF=$MARCHDF_HDF $HDF_INCLUDE" ++ FORT_OPT="$FORT_OPT -DMARCHDF=$MARCHDF_HDF" + fi + + FORTLOW="$FCOMP $FORT_OPT $PROFILE -O0 $I8FFLAGS -I$MARC_SOURCE/common \ +@@ -621,6 +630,29 @@ + # for compiling free form f90 files. high opt, integer(4) + FORTF90="$FCOMP -c -O3" + ++# determine DAMASK version ++if test -n "$DAMASK_USER"; then ++ DAMASKROOT=`dirname $DAMASK_USER`/../.. ++ read DAMASKVERSION < $DAMASKROOT/VERSION ++ DAMASKVERSION="'"$DAMASKVERSION"'" ++else ++ DAMASKVERSION="'N/A'" ++fi ++ ++# DAMASK compiler calls ++DFORTLOWMP="$FCOMP -c -O0 -qno-offload -implicitnone -stand f18 -standard-semantics -assume nostd_mod_proc_name -safe_cray_ptr $PROFILE -zero -mp1 -WB $I8FFLAGS -I$MARC_SOURCE/common \ ++ -fpp -ftz -diag-disable 5268 -warn declarations -warn general -warn usage -warn interfaces -warn ignore_loc -warn alignments -DMARC4DAMASK=2022.2 -DDAMASKVERSION=$DAMASKVERSION \ ++ -qopenmp -qopenmp-threadprivate=compat\ ++ $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD -I$MARC_MOD" ++DFORTRANMP="$FCOMP -c -O1 -qno-offload -implicitnone -stand f18 -standard-semantics -assume nostd_mod_proc_name -safe_cray_ptr $PROFILE -zero -mp1 -WB $I8FFLAGS -I$MARC_SOURCE/common \ ++ -fpp -ftz -diag-disable 5268 -warn declarations -warn general -warn usage -warn interfaces -warn ignore_loc -warn alignments -DMARC4DAMASK=2022.2 -DDAMASKVERSION=$DAMASKVERSION \ ++ -qopenmp -qopenmp-threadprivate=compat\ ++ $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD -I$MARC_MOD" ++DFORTHIGHMP="$FCOMP -c -O3 -qno-offload -implicitnone -stand f18 -standard-semantics -assume nostd_mod_proc_name -safe_cray_ptr $PROFILE -zero -mp1 -WB $I8FFLAGS -I$MARC_SOURCE/common \ ++ -fpp -ftz -diag-disable 5268 -warn declarations -warn general -warn usage -warn interfaces -warn ignore_loc -warn alignments -DMARC4DAMASK=2022.2 -DDAMASKVERSION=$DAMASKVERSION \ ++ -qopenmp -qopenmp-threadprivate=compat\ ++ $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD -I$MARC_MOD" ++ + if test "$MARCDEBUG" = "ON" + then + FORTLOW="$FCOMP $FORT_OPT $PROFILE $I8FFLAGS -I$MARC_SOURCE/common \ +@@ -778,7 +810,7 @@ + + SOLVERLIBS="${BCSSOLVERLIBS} ${VKISOLVERLIBS} ${CASISOLVERLIBS} ${MF2SOLVERLIBS} \ + -L$MARC_MKL \ +- $MARC_LIB/blas_src.a ${ACSI_LIB}/ACSI_MarcLib.a $KDTREE2_LIB/libkdtree2.a $MARC_LIB/libtetmeshinterface.a $MARC_LIB/libcaefatigueinterface.a -L$MARC_LIB -lmkl_blacs_intelmpi_ilp64 -lmkl_scalapack_ilp64 -lmkl_intel_ilp64 -lmkl_intel_thread -lmkl_core -liomp5 -ltetmesh -lmeshgems -lmg-tetra -lmeshgems_stubs $HDF_LIBS $SOLVER2LIBS" ++ $MARC_LIB/blas_src.a ${ACSI_LIB}/ACSI_MarcLib.a $KDTREE2_LIB/libkdtree2.a $MARC_LIB/libtetmeshinterface.a $MARC_LIB/libcaefatigueinterface.a -L$MARC_LIB -lmkl_blacs_intelmpi_ilp64 -lmkl_scalapack_ilp64 -lmkl_intel_ilp64 -lmkl_intel_thread -lmkl_core -liomp5 -ltetmesh -lmeshgems -lmg-tetra -lmeshgems_stubs $HDF5_LIB $SOLVER2LIBS" + + SOLVERLIBS_DLL=${SOLVERLIBS} + if test "$AEM_DLL" -eq 1 diff --git a/install/MarcMentat/2022.2/Marc_tools/run_damask_hmp.patch b/install/MarcMentat/2022.2/Marc_tools/run_damask_hmp.patch new file mode 100644 index 000000000..a63591c4b --- /dev/null +++ b/install/MarcMentat/2022.2/Marc_tools/run_damask_hmp.patch @@ -0,0 +1,517 @@ +--- ++++ +@@ -136,6 +136,11 @@ + # is created. For job running in the background, the log # + # file is always created. Default is "yes" # + ############################################################################## ++# remove all Mentat paths from LD_LIBRARY_PATH ++LD_LIBRARY_PATH=:$LD_LIBRARY_PATH: ++LD_LIBRARY_PATH=${LD_LIBRARY_PATH//+([!(:)])mentat2022.2+([!(:)])/:} ++LD_LIBRARY_PATH=${LD_LIBRARY_PATH//+([(:)])/:} ++LD_LIBRARY_PATH=${LD_LIBRARY_PATH#:}; LD_LIBRARY_PATH=${LD_LIBRARY_PATH%:} + # set DIR to the directory in which this script is + REALCOM="`/bin/ls -l $0 |awk '{ print $NF; }'`" + DIR=`dirname $REALCOM` +@@ -302,7 +307,23 @@ + + . "$DIR/getarch" + ++ ++# getting user subroutine file name ++found=0 ++for i in "$@"; do ++ if test $found = 1; then ++ DAMASK_USER=$i ++ found=0 ++ fi ++ case $i in ++ -u* | -U*) ++ found=1 ++ ;; ++ esac ++done ++# sourcing include_linux64 (needs DAMASK_USER to be set) + . $MARC_INCLUDE ++ + # + + # +@@ -405,7 +426,7 @@ + did= + vid= + user= +-usersubname= ++usernoext= + objs= + qid=background + cpu= +@@ -676,50 +697,19 @@ + esac + ;; + -u* | -U*) +- user=`dirname $value`/`$BASENAME $value .f` +- usersubname=$user +- basefile=`$BASENAME $value` +- if test ${basefile##*.} = f +- then +- user=`dirname $value`/`$BASENAME $value .f` +- usersubname=$user.f +- elif test ${basefile##*.} = F +- then +- user=`dirname $value`/`$BASENAME $value .F` +- usersubname=$user.F +- elif test ${basefile##*.} = f90 +- then +- user=`dirname $value`/`$BASENAME $value .f90` +- usersubname=$user.f90 +- elif test ${basefile##*.} = F90 +- then +- user=`dirname $value`/`$BASENAME $value .F90` +- usersubname=$user.F90 +- fi ++ user=$value + case $user in + \/*) + ;; + *) + user=`pwd`/$user +- usersubname=`pwd`/$usersubname + ;; + esac +- if test ! -f $usersubname +- then +- if test -f $usersubname.f +- then +- usersubname=$usersubname.f +- elif test -f $usersubname.F +- then +- usersubname=$usersubname.F +- elif test -f $usersubname.f90 +- then +- usersubname=$usersubname.f90 +- elif test -f $usersubname.F90 +- then +- usersubname=$usersubname.F90 +- fi +- fi ++ usernoext=$user ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` + ;; + -obj | -OBJ) + objs="$value" +@@ -1207,12 +1197,12 @@ + fi + fi + fi +- if test "$usersubname" ++ if test "$user" + then +- if test ! -f $usersubname ++ if test ! -f $user + then + error="$error +-user subroutine file $usersubname not accessible" ++user subroutine file $user not accessible" + fi + fi + if test "$objs" +@@ -1531,7 +1521,7 @@ + Marc shared lib : $progdll + Version type : $mode + Job ID : $DIRJID/$jid$extra_job_info +-User subroutine name : $usersubname ++User subroutine name : $user + User objects/libs : $objs + Restart file job ID : $rid + Substructure file ID : $sid +@@ -1564,7 +1554,7 @@ + Marc shared lib : $progdll + Version type : $mode + Job ID : $DIRJID/$jid$extra_job_info +-User subroutine name : $usersubname ++User subroutine name : $user + User objects/libs : $objs + Restart file job ID : $rid + Substructure file ID : $sid +@@ -1687,7 +1677,7 @@ + ;; + esac + fi +- $ECHO "User subroutine name ($usersubname)? $ECHOTXT" ++ $ECHO "User subroutine name ($user)? $ECHOTXT" + read value + if test "$value" + then +@@ -1696,50 +1686,19 @@ + user= + ;; + *) +- user=`dirname $value`/`$BASENAME $value .f` +- usersubname=$user +- basefile=`$BASENAME $value` +- if test ${basefile##*.} = f +- then +- user=`dirname $value`/`$BASENAME $value .f` +- usersubname=$user.f +- elif test ${basefile##*.} = F +- then +- user=`dirname $value`/`$BASENAME $value .F` +- usersubname=$user.F +- elif test ${basefile##*.} = f90 +- then +- user=`dirname $value`/`$BASENAME $value .f90` +- usersubname=$user.f90 +- elif test ${basefile##*.} = F90 +- then +- user=`dirname $value`/`$BASENAME $value .F90` +- usersubname=$user.F90 +- fi ++ user=$value + case $user in + \/*) + ;; + *) + user=`pwd`/$user +- usersubname=`pwd`/$usersubname + ;; + esac +- if test ! -f $usersubname +- then +- if test -f $usersubname.f +- then +- usersubname=$usersubname.f +- elif test -f $usersubname.F +- then +- usersubname=$usersubname.F +- elif test -f $usersubname.f90 +- then +- usersubname=$usersubname.f90 +- elif test -f $usersubname.F90 +- then +- usersubname=$usersubname.F90 +- fi +- fi ++ usernoext=$user ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` + ;; + esac + fi +@@ -2274,11 +2233,12 @@ + # + # user subroutine used + # ++# add DAMASK options for linking ++ DAMASK="-lstdc++" + + if test "$user" + then +-# program=$user.marc +- program=$DIRJOB/`$BASENAME $user .f`.marc ++ program=$usernoext.marc + case $program in + \/* | \.\/*) + bd= +@@ -2391,7 +2351,7 @@ + fi + if test "$user" + then +- execpath=$DIRJOB/`$BASENAME $user .f`.marc ++ execpath=$usernoext.marc + usersub=1 + fi + export execpath +@@ -3274,44 +3234,27 @@ + echo + if test "$user" + then +- userobj=$DIRJOB/`$BASENAME $user .f`.o +- basefile=`$BASENAME $usersubname` +- if test ${basefile##*.} = f +- then +- usersub=$DIRJOB/`$BASENAME $user .f`.F +- ln -sf "$user.f" "$usersub" +- else +- usersub=$usersubname +- fi +- ++ userobj=$usernoext.o + fi + cat > $jid.runmarcscript << END4 + if test "$user" + then +- if test ${basefile##*.} = f +- then +- ln -sf "$user.f" "$usersub" +- fi + if test $MACHINENAME = "CRAY" + then +- $FORTRAN $usersub || \ ++ $DFORTHIGHMP $user || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null + else +- $FORTRAN $usersub -o $userobj || \ ++ $DFORTHIGHMP $user -o $userobj || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null + fi +- if test ${basefile##*.} = f +- then +- /bin/rm -f "$usersub" +- fi + fi + + +@@ -3331,6 +3274,7 @@ + $TKLIBS \ + $MRCLIBS \ + $METISLIBS \ ++ $DAMASK \ + $SFLIB \ + $OPENSSL_LIB \ + $SYSLIBS \ +@@ -3344,6 +3288,9 @@ + prgsav=yes + fi + /bin/rm $userobj 2>/dev/null ++/bin/rm $DIRJOB/*.mod 2>/dev/null ++/bin/rm $DIRJOB/*.smod 2>/dev/null ++/bin/rm $DIRJOB/*_genmod.f90 2>/dev/null + + # + # run marc +@@ -3390,7 +3337,7 @@ + fi + else + if test $cpdll = yes; then +- filename=`basename $usersubname .f` ++ filename=$usernoext + /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null + fi + if test $rmdll = yes +@@ -3556,7 +3503,7 @@ + # first copy over the user sub if local directories + if test ${dirstatus[$counter]} = "local" + then +- $RCP $user.f $i:$DIR1/ ++ $RCP $user $i:$DIR1/ + fi + # do the compilation on the other machine + if test ${dirstatus[$counter]} = "shared" +@@ -3569,21 +3516,21 @@ + remoteuser=$DIR1/`$BASENAME $user` + $RSH $i /bin/rm $remoteprog 2> /dev/null + echo +- $RSH $i $DIR2/tools/comp_user $DIR2 $DIR1 $remoteuser $remoteprog ++ $RSH $i $DIR2/tools/comp_damask_hmp $DIR2 $DIR1 $remoteuser $remoteprog + # check if successful, the new executable should be there + line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` + if test "$line" + then + echo compilation and linking successful on host $i + else +- echo "$0: compile failed for $user.f on host $i" ++ echo "$0: compile failed for $user on host $i" + echo " $PRODUCT Exit number 3" + exit 1 + fi + # remove the user subroutine on remote machine + if test ${dirstatus[$counter]} = "local" + then +- $RSH $i /bin/rm $remoteuser.f 2> /dev/null ++ $RSH $i /bin/rm $remoteuser 2> /dev/null + fi + fi + fi +@@ -3593,39 +3540,27 @@ + if test "$userhost" + then + echo +- echo "Compiling and linking user subroutine $user.f on host `hostname`" +- fi +- userobj=$DIRJOB/`$BASENAME $user .f`.o +- basefile=`$BASENAME $usersubname` +- if test ${basefile##*.} = f +- then +- usersub=$DIRJOB/`$BASENAME $user .f`.F +- ln -sf "$user.f" "$usersub" +- else +- usersub=$usersubname ++ echo "Compiling and linking user subroutine $user on host `hostname`" + fi ++ userobj=$usernoext.o + if test $MACHINENAME = "CRAY" + then +- $FORTRAN $usersub || \ ++ $DFORTHIGHMP $user || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + echo " $PRODUCT Exit number 3" + exit 1 + } + /bin/rm $program 2>/dev/null + else +- $FORTRAN $usersub -o $userobj || \ ++ $DFORTHIGHMP $user -o $userobj || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + echo " $PRODUCT Exit number 3" + exit 1 + } + /bin/rm $program 2>/dev/null + fi +- if test ${basefile##*.} = f +- then +- /bin/rm -f "$usersub" +- fi + fi # if test $user + + +@@ -3645,6 +3580,7 @@ + $TKLIBS \ + $MRCLIBS \ + $METISLIBS \ ++ $DAMASK \ + $SFLIB \ + $OPENSSL_LIB \ + $SYSLIBS \ +@@ -3686,6 +3622,9 @@ + prgsav=yes + fi # if test $link + /bin/rm $userobj 2>/dev/null ++/bin/rm $DIRJOB/*.mod 2>/dev/null ++/bin/rm $DIRJOB/*.smod 2>/dev/null ++/bin/rm $DIRJOB/*_genmod.f90 2>/dev/null + + # + # run marc +@@ -3779,7 +3718,7 @@ + else + #dllrun >0 + if test $cpdll = yes; then +- filename=`basename $usersubname .f` ++ filename=$usernoext + /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null + fi + if test $rmdll = yes;then +@@ -3904,7 +3843,7 @@ + # first copy over the user sub if local directories + if test ${dirstatus[$counter]} = "local" + then +- $RCP $user.f $i:$DIR1/ ++ $RCP $user $i:$DIR1/ + fi + # do the compilation on the other machine + if test ${dirstatus[$counter]} = "shared" +@@ -3917,20 +3856,20 @@ + remoteuser=$DIR1/`$BASENAME $user` + $RSH $i /bin/rm $remoteprog 2> /dev/null + echo +- $RSH $i $DIR2/tools/comp_user $DIR2 $DIR1 $remoteuser $remoteprog ++ $RSH $i $DIR2/tools/comp_damask_hmp $DIR2 $DIR1 $remoteuser $remoteprog + # check if successful, the new executable should be there + line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` + if test "$line" + then + echo compilation and linking successful on host $i + else +- echo "$0: compile failed for $user.f on host $i" ++ echo "$0: compile failed for $user on host $i" + exit 1 + fi + # remove the user subroutine on remote machine + if test ${dirstatus[$counter]} = "local" + then +- $RSH $i /bin/rm $remoteuser.f 2> /dev/null ++ $RSH $i /bin/rm $remoteuser 2> /dev/null + fi + fi + fi +@@ -3940,37 +3879,25 @@ + if test "$userhost" + then + echo +- echo "Compiling and linking user subroutine $user.f on host `hostname`" +- fi +- userobj=$DIRJOB/`$BASENAME $user .f`.o +- basefile=`$BASENAME $usersubname` +- if test ${basefile##*.} = f +- then +- usersub=$DIRJOB/`$BASENAME $user .f`.F +- ln -sf "$user.f" "$usersub" +- else +- usersub=$usersubname ++ echo "Compiling and linking user subroutine $user on host `hostname`" + fi ++ userobj=$usernoext.o + if test $MACHINENAME = "CRAY" + then +- $FORTRAN $usersub || \ ++ $DFORTHIGHMP $user || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null + else +- $FORTRAN $usersub -o $userobj || \ ++ $DFORTHIGHMP $user -o $userobj || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null + fi +- if test ${basefile##*.} = f +- then +- /bin/rm -f "$usersub" +- fi + fi # if test $user + + +@@ -3990,6 +3917,7 @@ + $TKLIBS \ + $MRCLIBS \ + $METISLIBS \ ++ $DAMASK \ + $SFLIB \ + $OPENSSL_LIB \ + $SYSLIBS \ +@@ -4030,7 +3958,9 @@ + prgsav=yes + fi # if test $link + /bin/rm $userobj 2>/dev/null +- ++/bin/rm $DIRJOB/*.mod 2>/dev/null ++/bin/rm $DIRJOB/*.smod 2>/dev/null ++/bin/rm $DIRJOB/*_genmod.f90 2>/dev/null + # done if no job id given + if test -z "$jid" + then +@@ -4149,7 +4079,7 @@ + else + #dllrun >0 + if test $cpdll = yes; then +- filename=`basename $usersubname .f` ++ filename=$usernoext + /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null + fi + if test $rmdll = yes;then diff --git a/install/MarcMentat/2022.2/Marc_tools/run_damask_lmp.patch b/install/MarcMentat/2022.2/Marc_tools/run_damask_lmp.patch new file mode 100644 index 000000000..4371ece0c --- /dev/null +++ b/install/MarcMentat/2022.2/Marc_tools/run_damask_lmp.patch @@ -0,0 +1,517 @@ +--- ++++ +@@ -136,6 +136,11 @@ + # is created. For job running in the background, the log # + # file is always created. Default is "yes" # + ############################################################################## ++# remove all Mentat paths from LD_LIBRARY_PATH ++LD_LIBRARY_PATH=:$LD_LIBRARY_PATH: ++LD_LIBRARY_PATH=${LD_LIBRARY_PATH//+([!(:)])mentat2022.2+([!(:)])/:} ++LD_LIBRARY_PATH=${LD_LIBRARY_PATH//+([(:)])/:} ++LD_LIBRARY_PATH=${LD_LIBRARY_PATH#:}; LD_LIBRARY_PATH=${LD_LIBRARY_PATH%:} + # set DIR to the directory in which this script is + REALCOM="`/bin/ls -l $0 |awk '{ print $NF; }'`" + DIR=`dirname $REALCOM` +@@ -302,7 +307,23 @@ + + . "$DIR/getarch" + ++ ++# getting user subroutine file name ++found=0 ++for i in "$@"; do ++ if test $found = 1; then ++ DAMASK_USER=$i ++ found=0 ++ fi ++ case $i in ++ -u* | -U*) ++ found=1 ++ ;; ++ esac ++done ++# sourcing include_linux64 (needs DAMASK_USER to be set) + . $MARC_INCLUDE ++ + # + + # +@@ -405,7 +426,7 @@ + did= + vid= + user= +-usersubname= ++usernoext= + objs= + qid=background + cpu= +@@ -676,50 +697,19 @@ + esac + ;; + -u* | -U*) +- user=`dirname $value`/`$BASENAME $value .f` +- usersubname=$user +- basefile=`$BASENAME $value` +- if test ${basefile##*.} = f +- then +- user=`dirname $value`/`$BASENAME $value .f` +- usersubname=$user.f +- elif test ${basefile##*.} = F +- then +- user=`dirname $value`/`$BASENAME $value .F` +- usersubname=$user.F +- elif test ${basefile##*.} = f90 +- then +- user=`dirname $value`/`$BASENAME $value .f90` +- usersubname=$user.f90 +- elif test ${basefile##*.} = F90 +- then +- user=`dirname $value`/`$BASENAME $value .F90` +- usersubname=$user.F90 +- fi ++ user=$value + case $user in + \/*) + ;; + *) + user=`pwd`/$user +- usersubname=`pwd`/$usersubname + ;; + esac +- if test ! -f $usersubname +- then +- if test -f $usersubname.f +- then +- usersubname=$usersubname.f +- elif test -f $usersubname.F +- then +- usersubname=$usersubname.F +- elif test -f $usersubname.f90 +- then +- usersubname=$usersubname.f90 +- elif test -f $usersubname.F90 +- then +- usersubname=$usersubname.F90 +- fi +- fi ++ usernoext=$user ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` + ;; + -obj | -OBJ) + objs="$value" +@@ -1207,12 +1197,12 @@ + fi + fi + fi +- if test "$usersubname" ++ if test "$user" + then +- if test ! -f $usersubname ++ if test ! -f $user + then + error="$error +-user subroutine file $usersubname not accessible" ++user subroutine file $user not accessible" + fi + fi + if test "$objs" +@@ -1531,7 +1521,7 @@ + Marc shared lib : $progdll + Version type : $mode + Job ID : $DIRJID/$jid$extra_job_info +-User subroutine name : $usersubname ++User subroutine name : $user + User objects/libs : $objs + Restart file job ID : $rid + Substructure file ID : $sid +@@ -1564,7 +1554,7 @@ + Marc shared lib : $progdll + Version type : $mode + Job ID : $DIRJID/$jid$extra_job_info +-User subroutine name : $usersubname ++User subroutine name : $user + User objects/libs : $objs + Restart file job ID : $rid + Substructure file ID : $sid +@@ -1687,7 +1677,7 @@ + ;; + esac + fi +- $ECHO "User subroutine name ($usersubname)? $ECHOTXT" ++ $ECHO "User subroutine name ($user)? $ECHOTXT" + read value + if test "$value" + then +@@ -1696,50 +1686,19 @@ + user= + ;; + *) +- user=`dirname $value`/`$BASENAME $value .f` +- usersubname=$user +- basefile=`$BASENAME $value` +- if test ${basefile##*.} = f +- then +- user=`dirname $value`/`$BASENAME $value .f` +- usersubname=$user.f +- elif test ${basefile##*.} = F +- then +- user=`dirname $value`/`$BASENAME $value .F` +- usersubname=$user.F +- elif test ${basefile##*.} = f90 +- then +- user=`dirname $value`/`$BASENAME $value .f90` +- usersubname=$user.f90 +- elif test ${basefile##*.} = F90 +- then +- user=`dirname $value`/`$BASENAME $value .F90` +- usersubname=$user.F90 +- fi ++ user=$value + case $user in + \/*) + ;; + *) + user=`pwd`/$user +- usersubname=`pwd`/$usersubname + ;; + esac +- if test ! -f $usersubname +- then +- if test -f $usersubname.f +- then +- usersubname=$usersubname.f +- elif test -f $usersubname.F +- then +- usersubname=$usersubname.F +- elif test -f $usersubname.f90 +- then +- usersubname=$usersubname.f90 +- elif test -f $usersubname.F90 +- then +- usersubname=$usersubname.F90 +- fi +- fi ++ usernoext=$user ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` + ;; + esac + fi +@@ -2274,11 +2233,12 @@ + # + # user subroutine used + # ++# add DAMASK options for linking ++ DAMASK="-lstdc++" + + if test "$user" + then +-# program=$user.marc +- program=$DIRJOB/`$BASENAME $user .f`.marc ++ program=$usernoext.marc + case $program in + \/* | \.\/*) + bd= +@@ -2391,7 +2351,7 @@ + fi + if test "$user" + then +- execpath=$DIRJOB/`$BASENAME $user .f`.marc ++ execpath=$usernoext.marc + usersub=1 + fi + export execpath +@@ -3274,44 +3234,27 @@ + echo + if test "$user" + then +- userobj=$DIRJOB/`$BASENAME $user .f`.o +- basefile=`$BASENAME $usersubname` +- if test ${basefile##*.} = f +- then +- usersub=$DIRJOB/`$BASENAME $user .f`.F +- ln -sf "$user.f" "$usersub" +- else +- usersub=$usersubname +- fi +- ++ userobj=$usernoext.o + fi + cat > $jid.runmarcscript << END4 + if test "$user" + then +- if test ${basefile##*.} = f +- then +- ln -sf "$user.f" "$usersub" +- fi + if test $MACHINENAME = "CRAY" + then +- $FORTRAN $usersub || \ ++ $DFORTLOWMP $user || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null + else +- $FORTRAN $usersub -o $userobj || \ ++ $DFORTLOWMP $user -o $userobj || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null + fi +- if test ${basefile##*.} = f +- then +- /bin/rm -f "$usersub" +- fi + fi + + +@@ -3331,6 +3274,7 @@ + $TKLIBS \ + $MRCLIBS \ + $METISLIBS \ ++ $DAMASK \ + $SFLIB \ + $OPENSSL_LIB \ + $SYSLIBS \ +@@ -3344,6 +3288,9 @@ + prgsav=yes + fi + /bin/rm $userobj 2>/dev/null ++/bin/rm $DIRJOB/*.mod 2>/dev/null ++/bin/rm $DIRJOB/*.smod 2>/dev/null ++/bin/rm $DIRJOB/*_genmod.f90 2>/dev/null + + # + # run marc +@@ -3390,7 +3337,7 @@ + fi + else + if test $cpdll = yes; then +- filename=`basename $usersubname .f` ++ filename=$usernoext + /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null + fi + if test $rmdll = yes +@@ -3556,7 +3503,7 @@ + # first copy over the user sub if local directories + if test ${dirstatus[$counter]} = "local" + then +- $RCP $user.f $i:$DIR1/ ++ $RCP $user $i:$DIR1/ + fi + # do the compilation on the other machine + if test ${dirstatus[$counter]} = "shared" +@@ -3569,21 +3516,21 @@ + remoteuser=$DIR1/`$BASENAME $user` + $RSH $i /bin/rm $remoteprog 2> /dev/null + echo +- $RSH $i $DIR2/tools/comp_user $DIR2 $DIR1 $remoteuser $remoteprog ++ $RSH $i $DIR2/tools/comp_damask_lmp $DIR2 $DIR1 $remoteuser $remoteprog + # check if successful, the new executable should be there + line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` + if test "$line" + then + echo compilation and linking successful on host $i + else +- echo "$0: compile failed for $user.f on host $i" ++ echo "$0: compile failed for $user on host $i" + echo " $PRODUCT Exit number 3" + exit 1 + fi + # remove the user subroutine on remote machine + if test ${dirstatus[$counter]} = "local" + then +- $RSH $i /bin/rm $remoteuser.f 2> /dev/null ++ $RSH $i /bin/rm $remoteuser 2> /dev/null + fi + fi + fi +@@ -3593,39 +3540,27 @@ + if test "$userhost" + then + echo +- echo "Compiling and linking user subroutine $user.f on host `hostname`" +- fi +- userobj=$DIRJOB/`$BASENAME $user .f`.o +- basefile=`$BASENAME $usersubname` +- if test ${basefile##*.} = f +- then +- usersub=$DIRJOB/`$BASENAME $user .f`.F +- ln -sf "$user.f" "$usersub" +- else +- usersub=$usersubname ++ echo "Compiling and linking user subroutine $user on host `hostname`" + fi ++ userobj=$usernoext.o + if test $MACHINENAME = "CRAY" + then +- $FORTRAN $usersub || \ ++ $DFORTLOWMP $user || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + echo " $PRODUCT Exit number 3" + exit 1 + } + /bin/rm $program 2>/dev/null + else +- $FORTRAN $usersub -o $userobj || \ ++ $DFORTLOWMP $user -o $userobj || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + echo " $PRODUCT Exit number 3" + exit 1 + } + /bin/rm $program 2>/dev/null + fi +- if test ${basefile##*.} = f +- then +- /bin/rm -f "$usersub" +- fi + fi # if test $user + + +@@ -3645,6 +3580,7 @@ + $TKLIBS \ + $MRCLIBS \ + $METISLIBS \ ++ $DAMASK \ + $SFLIB \ + $OPENSSL_LIB \ + $SYSLIBS \ +@@ -3686,6 +3622,9 @@ + prgsav=yes + fi # if test $link + /bin/rm $userobj 2>/dev/null ++/bin/rm $DIRJOB/*.mod 2>/dev/null ++/bin/rm $DIRJOB/*.smod 2>/dev/null ++/bin/rm $DIRJOB/*_genmod.f90 2>/dev/null + + # + # run marc +@@ -3779,7 +3718,7 @@ + else + #dllrun >0 + if test $cpdll = yes; then +- filename=`basename $usersubname .f` ++ filename=$usernoext + /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null + fi + if test $rmdll = yes;then +@@ -3904,7 +3843,7 @@ + # first copy over the user sub if local directories + if test ${dirstatus[$counter]} = "local" + then +- $RCP $user.f $i:$DIR1/ ++ $RCP $user $i:$DIR1/ + fi + # do the compilation on the other machine + if test ${dirstatus[$counter]} = "shared" +@@ -3917,20 +3856,20 @@ + remoteuser=$DIR1/`$BASENAME $user` + $RSH $i /bin/rm $remoteprog 2> /dev/null + echo +- $RSH $i $DIR2/tools/comp_user $DIR2 $DIR1 $remoteuser $remoteprog ++ $RSH $i $DIR2/tools/comp_damask_lmp $DIR2 $DIR1 $remoteuser $remoteprog + # check if successful, the new executable should be there + line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` + if test "$line" + then + echo compilation and linking successful on host $i + else +- echo "$0: compile failed for $user.f on host $i" ++ echo "$0: compile failed for $user on host $i" + exit 1 + fi + # remove the user subroutine on remote machine + if test ${dirstatus[$counter]} = "local" + then +- $RSH $i /bin/rm $remoteuser.f 2> /dev/null ++ $RSH $i /bin/rm $remoteuser 2> /dev/null + fi + fi + fi +@@ -3940,37 +3879,25 @@ + if test "$userhost" + then + echo +- echo "Compiling and linking user subroutine $user.f on host `hostname`" +- fi +- userobj=$DIRJOB/`$BASENAME $user .f`.o +- basefile=`$BASENAME $usersubname` +- if test ${basefile##*.} = f +- then +- usersub=$DIRJOB/`$BASENAME $user .f`.F +- ln -sf "$user.f" "$usersub" +- else +- usersub=$usersubname ++ echo "Compiling and linking user subroutine $user on host `hostname`" + fi ++ userobj=$usernoext.o + if test $MACHINENAME = "CRAY" + then +- $FORTRAN $usersub || \ ++ $DFORTLOWMP $user || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null + else +- $FORTRAN $usersub -o $userobj || \ ++ $DFORTLOWMP $user -o $userobj || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null + fi +- if test ${basefile##*.} = f +- then +- /bin/rm -f "$usersub" +- fi + fi # if test $user + + +@@ -3990,6 +3917,7 @@ + $TKLIBS \ + $MRCLIBS \ + $METISLIBS \ ++ $DAMASK \ + $SFLIB \ + $OPENSSL_LIB \ + $SYSLIBS \ +@@ -4030,7 +3958,9 @@ + prgsav=yes + fi # if test $link + /bin/rm $userobj 2>/dev/null +- ++/bin/rm $DIRJOB/*.mod 2>/dev/null ++/bin/rm $DIRJOB/*.smod 2>/dev/null ++/bin/rm $DIRJOB/*_genmod.f90 2>/dev/null + # done if no job id given + if test -z "$jid" + then +@@ -4149,7 +4079,7 @@ + else + #dllrun >0 + if test $cpdll = yes; then +- filename=`basename $usersubname .f` ++ filename=$usernoext + /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null + fi + if test $rmdll = yes;then diff --git a/install/MarcMentat/2022.2/Marc_tools/run_damask_mp.patch b/install/MarcMentat/2022.2/Marc_tools/run_damask_mp.patch new file mode 100644 index 000000000..11f9f00f4 --- /dev/null +++ b/install/MarcMentat/2022.2/Marc_tools/run_damask_mp.patch @@ -0,0 +1,517 @@ +--- ++++ +@@ -136,6 +136,11 @@ + # is created. For job running in the background, the log # + # file is always created. Default is "yes" # + ############################################################################## ++# remove all Mentat paths from LD_LIBRARY_PATH ++LD_LIBRARY_PATH=:$LD_LIBRARY_PATH: ++LD_LIBRARY_PATH=${LD_LIBRARY_PATH//+([!(:)])mentat2022.2+([!(:)])/:} ++LD_LIBRARY_PATH=${LD_LIBRARY_PATH//+([(:)])/:} ++LD_LIBRARY_PATH=${LD_LIBRARY_PATH#:}; LD_LIBRARY_PATH=${LD_LIBRARY_PATH%:} + # set DIR to the directory in which this script is + REALCOM="`/bin/ls -l $0 |awk '{ print $NF; }'`" + DIR=`dirname $REALCOM` +@@ -302,7 +307,23 @@ + + . "$DIR/getarch" + ++ ++# getting user subroutine file name ++found=0 ++for i in "$@"; do ++ if test $found = 1; then ++ DAMASK_USER=$i ++ found=0 ++ fi ++ case $i in ++ -u* | -U*) ++ found=1 ++ ;; ++ esac ++done ++# sourcing include_linux64 (needs DAMASK_USER to be set) + . $MARC_INCLUDE ++ + # + + # +@@ -405,7 +426,7 @@ + did= + vid= + user= +-usersubname= ++usernoext= + objs= + qid=background + cpu= +@@ -676,50 +697,19 @@ + esac + ;; + -u* | -U*) +- user=`dirname $value`/`$BASENAME $value .f` +- usersubname=$user +- basefile=`$BASENAME $value` +- if test ${basefile##*.} = f +- then +- user=`dirname $value`/`$BASENAME $value .f` +- usersubname=$user.f +- elif test ${basefile##*.} = F +- then +- user=`dirname $value`/`$BASENAME $value .F` +- usersubname=$user.F +- elif test ${basefile##*.} = f90 +- then +- user=`dirname $value`/`$BASENAME $value .f90` +- usersubname=$user.f90 +- elif test ${basefile##*.} = F90 +- then +- user=`dirname $value`/`$BASENAME $value .F90` +- usersubname=$user.F90 +- fi ++ user=$value + case $user in + \/*) + ;; + *) + user=`pwd`/$user +- usersubname=`pwd`/$usersubname + ;; + esac +- if test ! -f $usersubname +- then +- if test -f $usersubname.f +- then +- usersubname=$usersubname.f +- elif test -f $usersubname.F +- then +- usersubname=$usersubname.F +- elif test -f $usersubname.f90 +- then +- usersubname=$usersubname.f90 +- elif test -f $usersubname.F90 +- then +- usersubname=$usersubname.F90 +- fi +- fi ++ usernoext=$user ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` + ;; + -obj | -OBJ) + objs="$value" +@@ -1207,12 +1197,12 @@ + fi + fi + fi +- if test "$usersubname" ++ if test "$user" + then +- if test ! -f $usersubname ++ if test ! -f $user + then + error="$error +-user subroutine file $usersubname not accessible" ++user subroutine file $user not accessible" + fi + fi + if test "$objs" +@@ -1531,7 +1521,7 @@ + Marc shared lib : $progdll + Version type : $mode + Job ID : $DIRJID/$jid$extra_job_info +-User subroutine name : $usersubname ++User subroutine name : $user + User objects/libs : $objs + Restart file job ID : $rid + Substructure file ID : $sid +@@ -1564,7 +1554,7 @@ + Marc shared lib : $progdll + Version type : $mode + Job ID : $DIRJID/$jid$extra_job_info +-User subroutine name : $usersubname ++User subroutine name : $user + User objects/libs : $objs + Restart file job ID : $rid + Substructure file ID : $sid +@@ -1687,7 +1677,7 @@ + ;; + esac + fi +- $ECHO "User subroutine name ($usersubname)? $ECHOTXT" ++ $ECHO "User subroutine name ($user)? $ECHOTXT" + read value + if test "$value" + then +@@ -1696,50 +1686,19 @@ + user= + ;; + *) +- user=`dirname $value`/`$BASENAME $value .f` +- usersubname=$user +- basefile=`$BASENAME $value` +- if test ${basefile##*.} = f +- then +- user=`dirname $value`/`$BASENAME $value .f` +- usersubname=$user.f +- elif test ${basefile##*.} = F +- then +- user=`dirname $value`/`$BASENAME $value .F` +- usersubname=$user.F +- elif test ${basefile##*.} = f90 +- then +- user=`dirname $value`/`$BASENAME $value .f90` +- usersubname=$user.f90 +- elif test ${basefile##*.} = F90 +- then +- user=`dirname $value`/`$BASENAME $value .F90` +- usersubname=$user.F90 +- fi ++ user=$value + case $user in + \/*) + ;; + *) + user=`pwd`/$user +- usersubname=`pwd`/$usersubname + ;; + esac +- if test ! -f $usersubname +- then +- if test -f $usersubname.f +- then +- usersubname=$usersubname.f +- elif test -f $usersubname.F +- then +- usersubname=$usersubname.F +- elif test -f $usersubname.f90 +- then +- usersubname=$usersubname.f90 +- elif test -f $usersubname.F90 +- then +- usersubname=$usersubname.F90 +- fi +- fi ++ usernoext=$user ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` + ;; + esac + fi +@@ -2274,11 +2233,12 @@ + # + # user subroutine used + # ++# add DAMASK options for linking ++ DAMASK="-lstdc++" + + if test "$user" + then +-# program=$user.marc +- program=$DIRJOB/`$BASENAME $user .f`.marc ++ program=$usernoext.marc + case $program in + \/* | \.\/*) + bd= +@@ -2391,7 +2351,7 @@ + fi + if test "$user" + then +- execpath=$DIRJOB/`$BASENAME $user .f`.marc ++ execpath=$usernoext.marc + usersub=1 + fi + export execpath +@@ -3274,44 +3234,27 @@ + echo + if test "$user" + then +- userobj=$DIRJOB/`$BASENAME $user .f`.o +- basefile=`$BASENAME $usersubname` +- if test ${basefile##*.} = f +- then +- usersub=$DIRJOB/`$BASENAME $user .f`.F +- ln -sf "$user.f" "$usersub" +- else +- usersub=$usersubname +- fi +- ++ userobj=$usernoext.o + fi + cat > $jid.runmarcscript << END4 + if test "$user" + then +- if test ${basefile##*.} = f +- then +- ln -sf "$user.f" "$usersub" +- fi + if test $MACHINENAME = "CRAY" + then +- $FORTRAN $usersub || \ ++ $DFORTRANMP $user || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null + else +- $FORTRAN $usersub -o $userobj || \ ++ $DFORTRANMP $user -o $userobj || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null + fi +- if test ${basefile##*.} = f +- then +- /bin/rm -f "$usersub" +- fi + fi + + +@@ -3331,6 +3274,7 @@ + $TKLIBS \ + $MRCLIBS \ + $METISLIBS \ ++ $DAMASK \ + $SFLIB \ + $OPENSSL_LIB \ + $SYSLIBS \ +@@ -3344,6 +3288,9 @@ + prgsav=yes + fi + /bin/rm $userobj 2>/dev/null ++/bin/rm $DIRJOB/*.mod 2>/dev/null ++/bin/rm $DIRJOB/*.smod 2>/dev/null ++/bin/rm $DIRJOB/*_genmod.f90 2>/dev/null + + # + # run marc +@@ -3390,7 +3337,7 @@ + fi + else + if test $cpdll = yes; then +- filename=`basename $usersubname .f` ++ filename=$usernoext + /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null + fi + if test $rmdll = yes +@@ -3556,7 +3503,7 @@ + # first copy over the user sub if local directories + if test ${dirstatus[$counter]} = "local" + then +- $RCP $user.f $i:$DIR1/ ++ $RCP $user $i:$DIR1/ + fi + # do the compilation on the other machine + if test ${dirstatus[$counter]} = "shared" +@@ -3569,21 +3516,21 @@ + remoteuser=$DIR1/`$BASENAME $user` + $RSH $i /bin/rm $remoteprog 2> /dev/null + echo +- $RSH $i $DIR2/tools/comp_user $DIR2 $DIR1 $remoteuser $remoteprog ++ $RSH $i $DIR2/tools/comp_damask_mp $DIR2 $DIR1 $remoteuser $remoteprog + # check if successful, the new executable should be there + line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` + if test "$line" + then + echo compilation and linking successful on host $i + else +- echo "$0: compile failed for $user.f on host $i" ++ echo "$0: compile failed for $user on host $i" + echo " $PRODUCT Exit number 3" + exit 1 + fi + # remove the user subroutine on remote machine + if test ${dirstatus[$counter]} = "local" + then +- $RSH $i /bin/rm $remoteuser.f 2> /dev/null ++ $RSH $i /bin/rm $remoteuser 2> /dev/null + fi + fi + fi +@@ -3593,39 +3540,27 @@ + if test "$userhost" + then + echo +- echo "Compiling and linking user subroutine $user.f on host `hostname`" +- fi +- userobj=$DIRJOB/`$BASENAME $user .f`.o +- basefile=`$BASENAME $usersubname` +- if test ${basefile##*.} = f +- then +- usersub=$DIRJOB/`$BASENAME $user .f`.F +- ln -sf "$user.f" "$usersub" +- else +- usersub=$usersubname ++ echo "Compiling and linking user subroutine $user on host `hostname`" + fi ++ userobj=$usernoext.o + if test $MACHINENAME = "CRAY" + then +- $FORTRAN $usersub || \ ++ $DFORTRANMP $user || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + echo " $PRODUCT Exit number 3" + exit 1 + } + /bin/rm $program 2>/dev/null + else +- $FORTRAN $usersub -o $userobj || \ ++ $DFORTRANMP $user -o $userobj || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + echo " $PRODUCT Exit number 3" + exit 1 + } + /bin/rm $program 2>/dev/null + fi +- if test ${basefile##*.} = f +- then +- /bin/rm -f "$usersub" +- fi + fi # if test $user + + +@@ -3645,6 +3580,7 @@ + $TKLIBS \ + $MRCLIBS \ + $METISLIBS \ ++ $DAMASK \ + $SFLIB \ + $OPENSSL_LIB \ + $SYSLIBS \ +@@ -3686,6 +3622,9 @@ + prgsav=yes + fi # if test $link + /bin/rm $userobj 2>/dev/null ++/bin/rm $DIRJOB/*.mod 2>/dev/null ++/bin/rm $DIRJOB/*.smod 2>/dev/null ++/bin/rm $DIRJOB/*_genmod.f90 2>/dev/null + + # + # run marc +@@ -3779,7 +3718,7 @@ + else + #dllrun >0 + if test $cpdll = yes; then +- filename=`basename $usersubname .f` ++ filename=$usernoext + /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null + fi + if test $rmdll = yes;then +@@ -3904,7 +3843,7 @@ + # first copy over the user sub if local directories + if test ${dirstatus[$counter]} = "local" + then +- $RCP $user.f $i:$DIR1/ ++ $RCP $user $i:$DIR1/ + fi + # do the compilation on the other machine + if test ${dirstatus[$counter]} = "shared" +@@ -3917,20 +3856,20 @@ + remoteuser=$DIR1/`$BASENAME $user` + $RSH $i /bin/rm $remoteprog 2> /dev/null + echo +- $RSH $i $DIR2/tools/comp_user $DIR2 $DIR1 $remoteuser $remoteprog ++ $RSH $i $DIR2/tools/comp_damask_mp $DIR2 $DIR1 $remoteuser $remoteprog + # check if successful, the new executable should be there + line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` + if test "$line" + then + echo compilation and linking successful on host $i + else +- echo "$0: compile failed for $user.f on host $i" ++ echo "$0: compile failed for $user on host $i" + exit 1 + fi + # remove the user subroutine on remote machine + if test ${dirstatus[$counter]} = "local" + then +- $RSH $i /bin/rm $remoteuser.f 2> /dev/null ++ $RSH $i /bin/rm $remoteuser 2> /dev/null + fi + fi + fi +@@ -3940,37 +3879,25 @@ + if test "$userhost" + then + echo +- echo "Compiling and linking user subroutine $user.f on host `hostname`" +- fi +- userobj=$DIRJOB/`$BASENAME $user .f`.o +- basefile=`$BASENAME $usersubname` +- if test ${basefile##*.} = f +- then +- usersub=$DIRJOB/`$BASENAME $user .f`.F +- ln -sf "$user.f" "$usersub" +- else +- usersub=$usersubname ++ echo "Compiling and linking user subroutine $user on host `hostname`" + fi ++ userobj=$usernoext.o + if test $MACHINENAME = "CRAY" + then +- $FORTRAN $usersub || \ ++ $DFORTRANMP $user || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null + else +- $FORTRAN $usersub -o $userobj || \ ++ $DFORTRANMP $user -o $userobj || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null + fi +- if test ${basefile##*.} = f +- then +- /bin/rm -f "$usersub" +- fi + fi # if test $user + + +@@ -3990,6 +3917,7 @@ + $TKLIBS \ + $MRCLIBS \ + $METISLIBS \ ++ $DAMASK \ + $SFLIB \ + $OPENSSL_LIB \ + $SYSLIBS \ +@@ -4030,7 +3958,9 @@ + prgsav=yes + fi # if test $link + /bin/rm $userobj 2>/dev/null +- ++/bin/rm $DIRJOB/*.mod 2>/dev/null ++/bin/rm $DIRJOB/*.smod 2>/dev/null ++/bin/rm $DIRJOB/*_genmod.f90 2>/dev/null + # done if no job id given + if test -z "$jid" + then +@@ -4149,7 +4079,7 @@ + else + #dllrun >0 + if test $cpdll = yes; then +- filename=`basename $usersubname .f` ++ filename=$usernoext + /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null + fi + if test $rmdll = yes;then diff --git a/install/MarcMentat/2022.2/Mentat_bin/edit_window.patch b/install/MarcMentat/2022.2/Mentat_bin/edit_window.patch new file mode 100644 index 000000000..915af9bf6 --- /dev/null +++ b/install/MarcMentat/2022.2/Mentat_bin/edit_window.patch @@ -0,0 +1,24 @@ +--- ++++ +@@ -1,18 +1,5 @@ + #!/bin/sh +-# This script opens a window running an editor. The default window is an +-# xterm, and the default editor is vi. These may be customized. ++# This script opens a window running an editor. ++# The command to invoke the editor is specified during DAMASK installation + +-dir= +-for d in /usr/bin /usr/bin/X11; do +- if test -x "$d/xterm"; then +- dir="$d" +- break +- fi +-done +- +-if test -z "$dir"; then +- echo "$0: Could not find xterm" +- exit 1 +-fi +- +-"$dir/xterm" -T "vi $*" -n "vi $*" -e vi $* ++%EDITOR% $* diff --git a/install/MarcMentat/2022.2/Mentat_bin/kill4.patch b/install/MarcMentat/2022.2/Mentat_bin/kill4.patch new file mode 100644 index 000000000..e69de29bb diff --git a/install/MarcMentat/2022.2/Mentat_bin/kill5.patch b/install/MarcMentat/2022.2/Mentat_bin/kill5.patch new file mode 100644 index 000000000..e69de29bb diff --git a/install/MarcMentat/2022.2/Mentat_bin/kill6.patch b/install/MarcMentat/2022.2/Mentat_bin/kill6.patch new file mode 100644 index 000000000..e69de29bb diff --git a/install/MarcMentat/2022.2/Mentat_bin/submit4.patch b/install/MarcMentat/2022.2/Mentat_bin/submit4.patch new file mode 100644 index 000000000..98c51e76d --- /dev/null +++ b/install/MarcMentat/2022.2/Mentat_bin/submit4.patch @@ -0,0 +1,38 @@ +--- ++++ +@@ -63,10 +63,10 @@ + if [ "$slv" != "" -a "$slv" != "marc" -a "$slv" != "datfit" ]; then + slv="-iam sfm" + fi +-if [ "$slv" == "marc" ]; then ++if [ "$slv" = "marc" ]; then + slv="" + fi +-if [ "$slv" == "datfit" ]; then ++if [ "$slv" = "datfit" ]; then + slv="-iam datfit" + fi + +@@ -91,6 +91,7 @@ + srcfile="-u $srcfile -save y" + ;; + runsaved) ++ srcfile=${srcfile%.*}".marc" + srcfile="-prog $srcfile" + ;; + esac +@@ -189,12 +190,12 @@ + unset PYTHONPATH + + if [ "$doe_first" = "-" ]; then # submit of regular Marc job +- "${DIR}/tools/run_marc" $slv -j $job -v n -b y $nprocds $nprocd \ ++ "${DIR}/tools/run_damask_hmp" $slv -j $job -v n -b y $nprocds $nprocd \ + $srcfile $restart $postfile $viewfactorsfile $hostfile \ + $compat $copy_datfile $copy_postfile $scr_dir $dcoup \ + $assem_recov_nthread $nthread $nsolver $mode $gpu > /dev/null 2>&1 + else # submit of a DoE Marc job +- "${DIR}/tools/run_marc" $slv -j $job -v n -b n $nprocds $nprocd \ ++ "${DIR}/tools/run_damask_hmp" $slv -j $job -v n -b n $nprocds $nprocd \ + $srcfile $restart $postfile $viewfactorsfile $hostfile \ + $compat $copy_datfile $copy_postfile $scr_dir $dcoup \ + $assem_recov_nthread $nthread $nsolver $mode $gpu diff --git a/install/MarcMentat/2022.2/Mentat_bin/submit5.patch b/install/MarcMentat/2022.2/Mentat_bin/submit5.patch new file mode 100644 index 000000000..ab32b1058 --- /dev/null +++ b/install/MarcMentat/2022.2/Mentat_bin/submit5.patch @@ -0,0 +1,38 @@ +--- ++++ +@@ -63,10 +63,10 @@ + if [ "$slv" != "" -a "$slv" != "marc" -a "$slv" != "datfit" ]; then + slv="-iam sfm" + fi +-if [ "$slv" == "marc" ]; then ++if [ "$slv" = "marc" ]; then + slv="" + fi +-if [ "$slv" == "datfit" ]; then ++if [ "$slv" = "datfit" ]; then + slv="-iam datfit" + fi + +@@ -91,6 +91,7 @@ + srcfile="-u $srcfile -save y" + ;; + runsaved) ++ srcfile=${srcfile%.*}".marc" + srcfile="-prog $srcfile" + ;; + esac +@@ -189,12 +190,12 @@ + unset PYTHONPATH + + if [ "$doe_first" = "-" ]; then # submit of regular Marc job +- "${DIR}/tools/run_marc" $slv -j $job -v n -b y $nprocds $nprocd \ ++ "${DIR}/tools/run_damask_mp" $slv -j $job -v n -b y $nprocds $nprocd \ + $srcfile $restart $postfile $viewfactorsfile $hostfile \ + $compat $copy_datfile $copy_postfile $scr_dir $dcoup \ + $assem_recov_nthread $nthread $nsolver $mode $gpu > /dev/null 2>&1 + else # submit of a DoE Marc job +- "${DIR}/tools/run_marc" $slv -j $job -v n -b n $nprocds $nprocd \ ++ "${DIR}/tools/run_damask_mp" $slv -j $job -v n -b n $nprocds $nprocd \ + $srcfile $restart $postfile $viewfactorsfile $hostfile \ + $compat $copy_datfile $copy_postfile $scr_dir $dcoup \ + $assem_recov_nthread $nthread $nsolver $mode $gpu diff --git a/install/MarcMentat/2022.2/Mentat_bin/submit6.patch b/install/MarcMentat/2022.2/Mentat_bin/submit6.patch new file mode 100644 index 000000000..d5ea3cfde --- /dev/null +++ b/install/MarcMentat/2022.2/Mentat_bin/submit6.patch @@ -0,0 +1,38 @@ +--- ++++ +@@ -63,10 +63,10 @@ + if [ "$slv" != "" -a "$slv" != "marc" -a "$slv" != "datfit" ]; then + slv="-iam sfm" + fi +-if [ "$slv" == "marc" ]; then ++if [ "$slv" = "marc" ]; then + slv="" + fi +-if [ "$slv" == "datfit" ]; then ++if [ "$slv" = "datfit" ]; then + slv="-iam datfit" + fi + +@@ -91,6 +91,7 @@ + srcfile="-u $srcfile -save y" + ;; + runsaved) ++ srcfile=${srcfile%.*}".marc" + srcfile="-prog $srcfile" + ;; + esac +@@ -189,12 +190,12 @@ + unset PYTHONPATH + + if [ "$doe_first" = "-" ]; then # submit of regular Marc job +- "${DIR}/tools/run_marc" $slv -j $job -v n -b y $nprocds $nprocd \ ++ "${DIR}/tools/run_damask_lmp" $slv -j $job -v n -b y $nprocds $nprocd \ + $srcfile $restart $postfile $viewfactorsfile $hostfile \ + $compat $copy_datfile $copy_postfile $scr_dir $dcoup \ + $assem_recov_nthread $nthread $nsolver $mode $gpu > /dev/null 2>&1 + else # submit of a DoE Marc job +- "${DIR}/tools/run_marc" $slv -j $job -v n -b n $nprocds $nprocd \ ++ "${DIR}/tools/run_damask_lmp" $slv -j $job -v n -b n $nprocds $nprocd \ + $srcfile $restart $postfile $viewfactorsfile $hostfile \ + $compat $copy_datfile $copy_postfile $scr_dir $dcoup \ + $assem_recov_nthread $nthread $nsolver $mode $gpu diff --git a/install/MarcMentat/2022.2/Mentat_menus/job_run.ms.patch b/install/MarcMentat/2022.2/Mentat_menus/job_run.ms.patch new file mode 100644 index 000000000..3368a6360 --- /dev/null +++ b/install/MarcMentat/2022.2/Mentat_menus/job_run.ms.patch @@ -0,0 +1,158 @@ +--- ++++ +@@ -261,11 +261,18 @@ + } + button { + position +25 = +- size 25 4 ++ size 18 4 + text "ADVANCED JOB SUBMISSION" + help "job_run#Job Submission And Control" + popmenu job_submit_adv_pm + } ++ button { ++ position +18 = ++ size 7 4 ++ text "DAMASK" ++ help "damask_run#Job Submission And Control" ++ popmenu damask ++ } + button { + position 0 +4 + size 16 4 +@@ -1202,6 +1209,135 @@ + } + + ++#-------------------------------------------------------------------------------------------------- ++popmenu damask { ++ ++#ifdef QT_MENTAT ++ text "DAMASK.MPIE.DE" ++#endif ++ ++ group { ++#ifndef QT_MENTAT ++ label { ++ position 0 0 ++ size 50 4 ++ text "DAMASK.MPIE.DE" ++ } ++#endif ++ ++ label { ++ position 1 6 ++ size 13 6 ++ text "Optimzation" ++ border_width 1 ++ border_color black ++ } ++ ++ label { ++ position +13 = ++ size 20 6 ++ text "write Input" ++ border_width 1 ++ border_color black ++ } ++ ++ label { ++ position +18 = ++ size 30 6 ++ text "do not write Inp." ++ border_width 1 ++ border_color black ++ } ++ ++ label { ++ position -32 +6 ++ size 12 6 ++ text "O3 / OpenMP" ++ border_width 1 ++ border_color black ++ } ++ ++ popdown { ++ position +12 = ++ size 20 6 ++ text "Submit" ++ command "*submit_job 4 *monitor_job" ++ } ++ ++ popdown { ++ position +20 = ++ size 20 6 ++ text "Execute" ++ command "*execute_job 4 *monitor_job" ++ } ++ ++ label { ++ position -32 +6 ++ size 12 6 ++ text "O1 / OpenMP" ++ border_width 1 ++ border_color black ++ } ++ ++ popdown { ++ position +12 = ++ size 20 6 ++ text "Submit" ++ command "*submit_job 5 *monitor_job" ++ } ++ ++ popdown { ++ position +20 = ++ size 20 6 ++ text "Execute" ++ command "*execute_job 5 *monitor_job" ++ } ++ ++ label { ++ position -32 +6 ++ size 12 6 ++ text "O0 / OpenMP" ++ border_width 1 ++ border_color black ++ } ++ ++ popdown { ++ position +12 = ++ size 20 6 ++ text "Submit" ++ command "*submit_job 6 *monitor_job" ++ } ++ ++ popdown { ++ position +20 = ++ size 20 6 ++ text "Execute" ++ command "*execute_job 6 *monitor_job" ++ } ++ ++ popdown { ++ position 19 +8 ++ size 12 8 ++ text "CANCEL" ++ } ++} ++ ++ window { ++ parent mentat ++ origin 38 8 ++#ifdef DCOM ++ size 50 100 ++#else ++ size 50 94 ++#endif ++ background_color body ++ border_width 1 ++ border_color border ++ buffering single ++ } ++ mode permanent ++} ++ + #-------------------------------------------------------------------------------------------------- + popmenu job_exit_msg_pm { + diff --git a/install/MarcMentat/2022.3/Marc_tools/comp_damask_hmp.patch b/install/MarcMentat/2022.3/Marc_tools/comp_damask_hmp.patch new file mode 100644 index 000000000..886ebf008 --- /dev/null +++ b/install/MarcMentat/2022.3/Marc_tools/comp_damask_hmp.patch @@ -0,0 +1,49 @@ +--- ++++ +@@ -6,18 +6,27 @@ + DIR=$1 + user=$3 + program=$4 ++usernoext=$user ++usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` ++usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` ++usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` ++usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` ++ ++# add BLAS options for linking ++ BLAS="%BLAS%" ++ + . $DIR/tools/include + DIRJOB=$2 + cd $DIRJOB +-echo "Compiling and linking user subroutine $user.f on host `hostname`" ++echo "Compiling and linking user subroutine $user on host `hostname`" + echo "program: $program" +- $FORTRAN $user.f || \ ++ $DFORTHIGHMP $user || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null +- userobj=$user.o ++ userobj=$usernoext.o + + + $LOAD ${program} $DIR/lib/main.o\ +@@ -33,9 +42,13 @@ + $TKLIBS \ + $MRCLIBS \ + $METISLIBS \ ++ $BLAS \ + $SYSLIBS || \ + { +- echo "$0: link failed for $user.o on host `hostname`" ++ echo "$0: link failed for $usernoext.o on host `hostname`" + exit 1 + } + /bin/rm $userobj ++ /bin/rm $DIRJOB/*.mod ++ /bin/rm $DIRJOB/*.smod ++ /bin/rm $DIRJOB/*_genmod.f90 diff --git a/install/MarcMentat/2022.3/Marc_tools/comp_damask_lmp.patch b/install/MarcMentat/2022.3/Marc_tools/comp_damask_lmp.patch new file mode 100644 index 000000000..191cb1a53 --- /dev/null +++ b/install/MarcMentat/2022.3/Marc_tools/comp_damask_lmp.patch @@ -0,0 +1,49 @@ +--- ++++ +@@ -6,18 +6,27 @@ + DIR=$1 + user=$3 + program=$4 ++usernoext=$user ++usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` ++usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` ++usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` ++usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` ++ ++# add BLAS options for linking ++ BLAS="%BLAS%" ++ + . $DIR/tools/include + DIRJOB=$2 + cd $DIRJOB +-echo "Compiling and linking user subroutine $user.f on host `hostname`" ++echo "Compiling and linking user subroutine $user on host `hostname`" + echo "program: $program" +- $FORTRAN $user.f || \ ++ $DFORTRANLOWMP $user || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null +- userobj=$user.o ++ userobj=$usernoext.o + + + $LOAD ${program} $DIR/lib/main.o\ +@@ -33,9 +42,13 @@ + $TKLIBS \ + $MRCLIBS \ + $METISLIBS \ ++ $BLAS \ + $SYSLIBS || \ + { +- echo "$0: link failed for $user.o on host `hostname`" ++ echo "$0: link failed for $usernoext.o on host `hostname`" + exit 1 + } + /bin/rm $userobj ++ /bin/rm $DIRJOB/*.mod ++ /bin/rm $DIRJOB/*.smod ++ /bin/rm $DIRJOB/*_genmod.f90 diff --git a/install/MarcMentat/2022.3/Marc_tools/comp_damask_mp.patch b/install/MarcMentat/2022.3/Marc_tools/comp_damask_mp.patch new file mode 100644 index 000000000..7c9cf7ba7 --- /dev/null +++ b/install/MarcMentat/2022.3/Marc_tools/comp_damask_mp.patch @@ -0,0 +1,49 @@ +--- ++++ +@@ -6,18 +6,27 @@ + DIR=$1 + user=$3 + program=$4 ++usernoext=$user ++usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` ++usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` ++usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` ++usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` ++ ++# add BLAS options for linking ++ BLAS="%BLAS%" ++ + . $DIR/tools/include + DIRJOB=$2 + cd $DIRJOB +-echo "Compiling and linking user subroutine $user.f on host `hostname`" ++echo "Compiling and linking user subroutine $user on host `hostname`" + echo "program: $program" +- $FORTRAN $user.f || \ ++ $DFORTRANMP $user || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null +- userobj=$user.o ++ userobj=$usernoext.o + + + $LOAD ${program} $DIR/lib/main.o\ +@@ -33,9 +42,13 @@ + $TKLIBS \ + $MRCLIBS \ + $METISLIBS \ ++ $BLAS \ + $SYSLIBS || \ + { +- echo "$0: link failed for $user.o on host `hostname`" ++ echo "$0: link failed for $usernoext.o on host `hostname`" + exit 1 + } + /bin/rm $userobj ++ /bin/rm $DIRJOB/*.mod ++ /bin/rm $DIRJOB/*.smod ++ /bin/rm $DIRJOB/*_genmod.f90 diff --git a/install/MarcMentat/2022.3/Marc_tools/include_linux64.patch b/install/MarcMentat/2022.3/Marc_tools/include_linux64.patch new file mode 100644 index 000000000..a5eff26b1 --- /dev/null +++ b/install/MarcMentat/2022.3/Marc_tools/include_linux64.patch @@ -0,0 +1,75 @@ +--- ++++ +@@ -166,6 +166,15 @@ + MARC_COSIM_LIB="$MSCCOSIM_HOME/CoSim$MSCCOSIM_VERSION/Dcosim$MSCCOSIM_VERSION/lib" + fi + ++# DAMASK uses the HDF5 compiler wrapper around the Intel compiler ++H5FC=$(h5fc -shlib -show) ++if [[ "$H5FC" == *"$dir is"* ]]; then ++ H5FC=$(echo $(echo "$H5FC" | tail -n1) | sed -e "s/\-shlib/-fPIC -qopenmp/g") ++ H5FC=${H5FC%-lmpifort*} ++fi ++HDF5_LIB=${H5FC//*ifort/} ++FCOMP="$H5FC" ++ + # AEM + if test "$MARCDLLOUTDIR" = ""; then + DLLOUTDIR="$MARC_LIB" +@@ -594,7 +603,7 @@ + PROFILE=" $PROFILE -pg" + fi + +-FORT_OPT="-c -assume byterecl -safe_cray_ptr -mp1 -WB -fp-model source" ++FORT_OPT="-c -implicitnone -stand f18 -standard-semantics -assume nostd_mod_proc_name -safe_cray_ptr -mp1 -WB -fp-model source" + if test "$MTHREAD" = "OPENMP" + then + FORT_OPT=" $FORT_OPT -qopenmp" +@@ -607,7 +616,7 @@ + FORT_OPT=" $FORT_OPT -save -zero" + fi + if test "$MARCHDF_HDF" = "HDF"; then +- FORT_OPT="$FORT_OPT -DMARCHDF_HDF=$MARCHDF_HDF $HDF_INCLUDE" ++ FORT_OPT="$FORT_OPT -DMARCHDF=$MARCHDF_HDF" + fi + + FORTLOW="$FCOMP $FORT_OPT $PROFILE -O0 $I8FFLAGS -I$MARC_SOURCE/common \ +@@ -621,6 +630,29 @@ + # for compiling free form f90 files. high opt, integer(4) + FORTF90="$FCOMP -c -O3" + ++# determine DAMASK version ++if test -n "$DAMASK_USER"; then ++ DAMASKROOT=`dirname $DAMASK_USER`/../.. ++ read DAMASKVERSION < $DAMASKROOT/VERSION ++ DAMASKVERSION="'"$DAMASKVERSION"'" ++else ++ DAMASKVERSION="'N/A'" ++fi ++ ++# DAMASK compiler calls ++DFORTLOWMP="$FCOMP -c -O0 -qno-offload -implicitnone -stand f18 -standard-semantics -assume nostd_mod_proc_name -safe_cray_ptr $PROFILE -zero -mp1 -WB $I8FFLAGS -I$MARC_SOURCE/common \ ++ -fpp -ftz -diag-disable 5268 -warn declarations -warn general -warn usage -warn interfaces -warn ignore_loc -warn alignments -DMARC4DAMASK=2022.3 -DDAMASKVERSION=$DAMASKVERSION \ ++ -qopenmp -qopenmp-threadprivate=compat\ ++ $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD -I$MARC_MOD" ++DFORTRANMP="$FCOMP -c -O1 -qno-offload -implicitnone -stand f18 -standard-semantics -assume nostd_mod_proc_name -safe_cray_ptr $PROFILE -zero -mp1 -WB $I8FFLAGS -I$MARC_SOURCE/common \ ++ -fpp -ftz -diag-disable 5268 -warn declarations -warn general -warn usage -warn interfaces -warn ignore_loc -warn alignments -DMARC4DAMASK=2022.3 -DDAMASKVERSION=$DAMASKVERSION \ ++ -qopenmp -qopenmp-threadprivate=compat\ ++ $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD -I$MARC_MOD" ++DFORTHIGHMP="$FCOMP -c -O3 -qno-offload -implicitnone -stand f18 -standard-semantics -assume nostd_mod_proc_name -safe_cray_ptr $PROFILE -zero -mp1 -WB $I8FFLAGS -I$MARC_SOURCE/common \ ++ -fpp -ftz -diag-disable 5268 -warn declarations -warn general -warn usage -warn interfaces -warn ignore_loc -warn alignments -DMARC4DAMASK=2022.3 -DDAMASKVERSION=$DAMASKVERSION \ ++ -qopenmp -qopenmp-threadprivate=compat\ ++ $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD -I$MARC_MOD" ++ + if test "$MARCDEBUG" = "ON" + then + FORTLOW="$FCOMP $FORT_OPT $PROFILE $I8FFLAGS -I$MARC_SOURCE/common \ +@@ -778,7 +810,7 @@ + + SOLVERLIBS="${BCSSOLVERLIBS} ${VKISOLVERLIBS} ${CASISOLVERLIBS} ${MF2SOLVERLIBS} \ + -L$MARC_MKL \ +- $MARC_LIB/blas_src.a ${ACSI_LIB}/ACSI_MarcLib.a $KDTREE2_LIB/libkdtree2.a $MARC_LIB/libtetmeshinterface.a $MARC_LIB/libcaefatigueinterface.a -L$MARC_LIB -lmkl_blacs_intelmpi_ilp64 -lmkl_scalapack_ilp64 -lmkl_intel_ilp64 -lmkl_intel_thread -lmkl_core -liomp5 -ltetmesh -lmeshgems -lmg-tetra -lmeshgems_stubs $HDF_LIBS $SOLVER2LIBS" ++ $MARC_LIB/blas_src.a ${ACSI_LIB}/ACSI_MarcLib.a $KDTREE2_LIB/libkdtree2.a $MARC_LIB/libtetmeshinterface.a $MARC_LIB/libcaefatigueinterface.a -L$MARC_LIB -lmkl_blacs_intelmpi_ilp64 -lmkl_scalapack_ilp64 -lmkl_intel_ilp64 -lmkl_intel_thread -lmkl_core -liomp5 -ltetmesh -lmeshgems -lmg-tetra -lmeshgems_stubs $HDF5_LIB $SOLVER2LIBS" + + SOLVERLIBS_DLL=${SOLVERLIBS} + if test "$AEM_DLL" -eq 1 diff --git a/install/MarcMentat/2022.3/Marc_tools/run_damask_hmp.patch b/install/MarcMentat/2022.3/Marc_tools/run_damask_hmp.patch new file mode 100644 index 000000000..a885dd04b --- /dev/null +++ b/install/MarcMentat/2022.3/Marc_tools/run_damask_hmp.patch @@ -0,0 +1,517 @@ +--- ++++ +@@ -136,6 +136,11 @@ + # is created. For job running in the background, the log # + # file is always created. Default is "yes" # + ############################################################################## ++# remove all Mentat paths from LD_LIBRARY_PATH ++LD_LIBRARY_PATH=:$LD_LIBRARY_PATH: ++LD_LIBRARY_PATH=${LD_LIBRARY_PATH//+([!(:)])mentat2022.3+([!(:)])/:} ++LD_LIBRARY_PATH=${LD_LIBRARY_PATH//+([(:)])/:} ++LD_LIBRARY_PATH=${LD_LIBRARY_PATH#:}; LD_LIBRARY_PATH=${LD_LIBRARY_PATH%:} + # set DIR to the directory in which this script is + REALCOM="`/bin/ls -l $0 |awk '{ print $NF; }'`" + DIR=`dirname $REALCOM` +@@ -302,7 +307,23 @@ + + . "$DIR/getarch" + ++ ++# getting user subroutine file name ++found=0 ++for i in "$@"; do ++ if test $found = 1; then ++ DAMASK_USER=$i ++ found=0 ++ fi ++ case $i in ++ -u* | -U*) ++ found=1 ++ ;; ++ esac ++done ++# sourcing include_linux64 (needs DAMASK_USER to be set) + . $MARC_INCLUDE ++ + # + + # +@@ -405,7 +426,7 @@ + did= + vid= + user= +-usersubname= ++usernoext= + objs= + qid=background + cpu= +@@ -676,50 +697,19 @@ + esac + ;; + -u* | -U*) +- user=`dirname $value`/`$BASENAME $value .f` +- usersubname=$user +- basefile=`$BASENAME $value` +- if test ${basefile##*.} = f +- then +- user=`dirname $value`/`$BASENAME $value .f` +- usersubname=$user.f +- elif test ${basefile##*.} = F +- then +- user=`dirname $value`/`$BASENAME $value .F` +- usersubname=$user.F +- elif test ${basefile##*.} = f90 +- then +- user=`dirname $value`/`$BASENAME $value .f90` +- usersubname=$user.f90 +- elif test ${basefile##*.} = F90 +- then +- user=`dirname $value`/`$BASENAME $value .F90` +- usersubname=$user.F90 +- fi ++ user=$value + case $user in + \/*) + ;; + *) + user=`pwd`/$user +- usersubname=`pwd`/$usersubname + ;; + esac +- if test ! -f $usersubname +- then +- if test -f $usersubname.f +- then +- usersubname=$usersubname.f +- elif test -f $usersubname.F +- then +- usersubname=$usersubname.F +- elif test -f $usersubname.f90 +- then +- usersubname=$usersubname.f90 +- elif test -f $usersubname.F90 +- then +- usersubname=$usersubname.F90 +- fi +- fi ++ usernoext=$user ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` + ;; + -obj | -OBJ) + objs="$value" +@@ -1207,12 +1197,12 @@ + fi + fi + fi +- if test "$usersubname" ++ if test "$user" + then +- if test ! -f $usersubname ++ if test ! -f $user + then + error="$error +-user subroutine file $usersubname not accessible" ++user subroutine file $user not accessible" + fi + fi + if test "$objs" +@@ -1531,7 +1521,7 @@ + Marc shared lib : $progdll + Version type : $mode + Job ID : $DIRJID/$jid$extra_job_info +-User subroutine name : $usersubname ++User subroutine name : $user + User objects/libs : $objs + Restart file job ID : $rid + Substructure file ID : $sid +@@ -1564,7 +1554,7 @@ + Marc shared lib : $progdll + Version type : $mode + Job ID : $DIRJID/$jid$extra_job_info +-User subroutine name : $usersubname ++User subroutine name : $user + User objects/libs : $objs + Restart file job ID : $rid + Substructure file ID : $sid +@@ -1687,7 +1677,7 @@ + ;; + esac + fi +- $ECHO "User subroutine name ($usersubname)? $ECHOTXT" ++ $ECHO "User subroutine name ($user)? $ECHOTXT" + read value + if test "$value" + then +@@ -1696,50 +1686,19 @@ + user= + ;; + *) +- user=`dirname $value`/`$BASENAME $value .f` +- usersubname=$user +- basefile=`$BASENAME $value` +- if test ${basefile##*.} = f +- then +- user=`dirname $value`/`$BASENAME $value .f` +- usersubname=$user.f +- elif test ${basefile##*.} = F +- then +- user=`dirname $value`/`$BASENAME $value .F` +- usersubname=$user.F +- elif test ${basefile##*.} = f90 +- then +- user=`dirname $value`/`$BASENAME $value .f90` +- usersubname=$user.f90 +- elif test ${basefile##*.} = F90 +- then +- user=`dirname $value`/`$BASENAME $value .F90` +- usersubname=$user.F90 +- fi ++ user=$value + case $user in + \/*) + ;; + *) + user=`pwd`/$user +- usersubname=`pwd`/$usersubname + ;; + esac +- if test ! -f $usersubname +- then +- if test -f $usersubname.f +- then +- usersubname=$usersubname.f +- elif test -f $usersubname.F +- then +- usersubname=$usersubname.F +- elif test -f $usersubname.f90 +- then +- usersubname=$usersubname.f90 +- elif test -f $usersubname.F90 +- then +- usersubname=$usersubname.F90 +- fi +- fi ++ usernoext=$user ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` + ;; + esac + fi +@@ -2274,11 +2233,12 @@ + # + # user subroutine used + # ++# add DAMASK options for linking ++ DAMASK="-lstdc++" + + if test "$user" + then +-# program=$user.marc +- program=$DIRJOB/`$BASENAME $user .f`.marc ++ program=$usernoext.marc + case $program in + \/* | \.\/*) + bd= +@@ -2391,7 +2351,7 @@ + fi + if test "$user" + then +- execpath=$DIRJOB/`$BASENAME $user .f`.marc ++ execpath=$usernoext.marc + usersub=1 + fi + export execpath +@@ -3274,44 +3234,27 @@ + echo + if test "$user" + then +- userobj=$DIRJOB/`$BASENAME $user .f`.o +- basefile=`$BASENAME $usersubname` +- if test ${basefile##*.} = f +- then +- usersub=$DIRJOB/`$BASENAME $user .f`.F +- ln -sf "$user.f" "$usersub" +- else +- usersub=$usersubname +- fi +- ++ userobj=$usernoext.o + fi + cat > $jid.runmarcscript << END4 + if test "$user" + then +- if test ${basefile##*.} = f +- then +- ln -sf "$user.f" "$usersub" +- fi + if test $MACHINENAME = "CRAY" + then +- $FORTRAN $usersub || \ ++ $DFORTHIGHMP $user || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null + else +- $FORTRAN $usersub -o $userobj || \ ++ $DFORTHIGHMP $user -o $userobj || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null + fi +- if test ${basefile##*.} = f +- then +- /bin/rm -f "$usersub" +- fi + fi + + +@@ -3331,6 +3274,7 @@ + $TKLIBS \ + $MRCLIBS \ + $METISLIBS \ ++ $DAMASK \ + $SFLIB \ + $OPENSSL_LIB \ + $SYSLIBS \ +@@ -3344,6 +3288,9 @@ + prgsav=yes + fi + /bin/rm $userobj 2>/dev/null ++/bin/rm $DIRJOB/*.mod 2>/dev/null ++/bin/rm $DIRJOB/*.smod 2>/dev/null ++/bin/rm $DIRJOB/*_genmod.f90 2>/dev/null + + # + # run marc +@@ -3390,7 +3337,7 @@ + fi + else + if test $cpdll = yes; then +- filename=`basename $usersubname .f` ++ filename=$usernoext + /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null + fi + if test $rmdll = yes +@@ -3556,7 +3503,7 @@ + # first copy over the user sub if local directories + if test ${dirstatus[$counter]} = "local" + then +- $RCP $user.f $i:$DIR1/ ++ $RCP $user $i:$DIR1/ + fi + # do the compilation on the other machine + if test ${dirstatus[$counter]} = "shared" +@@ -3569,21 +3516,21 @@ + remoteuser=$DIR1/`$BASENAME $user` + $RSH $i /bin/rm $remoteprog 2> /dev/null + echo +- $RSH $i $DIR2/tools/comp_user $DIR2 $DIR1 $remoteuser $remoteprog ++ $RSH $i $DIR2/tools/comp_damask_hmp $DIR2 $DIR1 $remoteuser $remoteprog + # check if successful, the new executable should be there + line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` + if test "$line" + then + echo compilation and linking successful on host $i + else +- echo "$0: compile failed for $user.f on host $i" ++ echo "$0: compile failed for $user on host $i" + echo " $PRODUCT Exit number 3" + exit 1 + fi + # remove the user subroutine on remote machine + if test ${dirstatus[$counter]} = "local" + then +- $RSH $i /bin/rm $remoteuser.f 2> /dev/null ++ $RSH $i /bin/rm $remoteuser 2> /dev/null + fi + fi + fi +@@ -3593,39 +3540,27 @@ + if test "$userhost" + then + echo +- echo "Compiling and linking user subroutine $user.f on host `hostname`" +- fi +- userobj=$DIRJOB/`$BASENAME $user .f`.o +- basefile=`$BASENAME $usersubname` +- if test ${basefile##*.} = f +- then +- usersub=$DIRJOB/`$BASENAME $user .f`.F +- ln -sf "$user.f" "$usersub" +- else +- usersub=$usersubname ++ echo "Compiling and linking user subroutine $user on host `hostname`" + fi ++ userobj=$usernoext.o + if test $MACHINENAME = "CRAY" + then +- $FORTRAN $usersub || \ ++ $DFORTHIGHMP $user || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + echo " $PRODUCT Exit number 3" + exit 1 + } + /bin/rm $program 2>/dev/null + else +- $FORTRAN $usersub -o $userobj || \ ++ $DFORTHIGHMP $user -o $userobj || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + echo " $PRODUCT Exit number 3" + exit 1 + } + /bin/rm $program 2>/dev/null + fi +- if test ${basefile##*.} = f +- then +- /bin/rm -f "$usersub" +- fi + fi # if test $user + + +@@ -3645,6 +3580,7 @@ + $TKLIBS \ + $MRCLIBS \ + $METISLIBS \ ++ $DAMASK \ + $SFLIB \ + $OPENSSL_LIB \ + $SYSLIBS \ +@@ -3686,6 +3622,9 @@ + prgsav=yes + fi # if test $link + /bin/rm $userobj 2>/dev/null ++/bin/rm $DIRJOB/*.mod 2>/dev/null ++/bin/rm $DIRJOB/*.smod 2>/dev/null ++/bin/rm $DIRJOB/*_genmod.f90 2>/dev/null + + # + # run marc +@@ -3779,7 +3718,7 @@ + else + #dllrun >0 + if test $cpdll = yes; then +- filename=`basename $usersubname .f` ++ filename=$usernoext + /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null + fi + if test $rmdll = yes;then +@@ -3904,7 +3843,7 @@ + # first copy over the user sub if local directories + if test ${dirstatus[$counter]} = "local" + then +- $RCP $user.f $i:$DIR1/ ++ $RCP $user $i:$DIR1/ + fi + # do the compilation on the other machine + if test ${dirstatus[$counter]} = "shared" +@@ -3917,20 +3856,20 @@ + remoteuser=$DIR1/`$BASENAME $user` + $RSH $i /bin/rm $remoteprog 2> /dev/null + echo +- $RSH $i $DIR2/tools/comp_user $DIR2 $DIR1 $remoteuser $remoteprog ++ $RSH $i $DIR2/tools/comp_damask_hmp $DIR2 $DIR1 $remoteuser $remoteprog + # check if successful, the new executable should be there + line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` + if test "$line" + then + echo compilation and linking successful on host $i + else +- echo "$0: compile failed for $user.f on host $i" ++ echo "$0: compile failed for $user on host $i" + exit 1 + fi + # remove the user subroutine on remote machine + if test ${dirstatus[$counter]} = "local" + then +- $RSH $i /bin/rm $remoteuser.f 2> /dev/null ++ $RSH $i /bin/rm $remoteuser 2> /dev/null + fi + fi + fi +@@ -3940,37 +3879,25 @@ + if test "$userhost" + then + echo +- echo "Compiling and linking user subroutine $user.f on host `hostname`" +- fi +- userobj=$DIRJOB/`$BASENAME $user .f`.o +- basefile=`$BASENAME $usersubname` +- if test ${basefile##*.} = f +- then +- usersub=$DIRJOB/`$BASENAME $user .f`.F +- ln -sf "$user.f" "$usersub" +- else +- usersub=$usersubname ++ echo "Compiling and linking user subroutine $user on host `hostname`" + fi ++ userobj=$usernoext.o + if test $MACHINENAME = "CRAY" + then +- $FORTRAN $usersub || \ ++ $DFORTHIGHMP $user || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null + else +- $FORTRAN $usersub -o $userobj || \ ++ $DFORTHIGHMP $user -o $userobj || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null + fi +- if test ${basefile##*.} = f +- then +- /bin/rm -f "$usersub" +- fi + fi # if test $user + + +@@ -3990,6 +3917,7 @@ + $TKLIBS \ + $MRCLIBS \ + $METISLIBS \ ++ $DAMASK \ + $SFLIB \ + $OPENSSL_LIB \ + $SYSLIBS \ +@@ -4030,7 +3958,9 @@ + prgsav=yes + fi # if test $link + /bin/rm $userobj 2>/dev/null +- ++/bin/rm $DIRJOB/*.mod 2>/dev/null ++/bin/rm $DIRJOB/*.smod 2>/dev/null ++/bin/rm $DIRJOB/*_genmod.f90 2>/dev/null + # done if no job id given + if test -z "$jid" + then +@@ -4149,7 +4079,7 @@ + else + #dllrun >0 + if test $cpdll = yes; then +- filename=`basename $usersubname .f` ++ filename=$usernoext + /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null + fi + if test $rmdll = yes;then diff --git a/install/MarcMentat/2022.3/Marc_tools/run_damask_lmp.patch b/install/MarcMentat/2022.3/Marc_tools/run_damask_lmp.patch new file mode 100644 index 000000000..096e3204d --- /dev/null +++ b/install/MarcMentat/2022.3/Marc_tools/run_damask_lmp.patch @@ -0,0 +1,517 @@ +--- ++++ +@@ -136,6 +136,11 @@ + # is created. For job running in the background, the log # + # file is always created. Default is "yes" # + ############################################################################## ++# remove all Mentat paths from LD_LIBRARY_PATH ++LD_LIBRARY_PATH=:$LD_LIBRARY_PATH: ++LD_LIBRARY_PATH=${LD_LIBRARY_PATH//+([!(:)])mentat2022.3+([!(:)])/:} ++LD_LIBRARY_PATH=${LD_LIBRARY_PATH//+([(:)])/:} ++LD_LIBRARY_PATH=${LD_LIBRARY_PATH#:}; LD_LIBRARY_PATH=${LD_LIBRARY_PATH%:} + # set DIR to the directory in which this script is + REALCOM="`/bin/ls -l $0 |awk '{ print $NF; }'`" + DIR=`dirname $REALCOM` +@@ -302,7 +307,23 @@ + + . "$DIR/getarch" + ++ ++# getting user subroutine file name ++found=0 ++for i in "$@"; do ++ if test $found = 1; then ++ DAMASK_USER=$i ++ found=0 ++ fi ++ case $i in ++ -u* | -U*) ++ found=1 ++ ;; ++ esac ++done ++# sourcing include_linux64 (needs DAMASK_USER to be set) + . $MARC_INCLUDE ++ + # + + # +@@ -405,7 +426,7 @@ + did= + vid= + user= +-usersubname= ++usernoext= + objs= + qid=background + cpu= +@@ -676,50 +697,19 @@ + esac + ;; + -u* | -U*) +- user=`dirname $value`/`$BASENAME $value .f` +- usersubname=$user +- basefile=`$BASENAME $value` +- if test ${basefile##*.} = f +- then +- user=`dirname $value`/`$BASENAME $value .f` +- usersubname=$user.f +- elif test ${basefile##*.} = F +- then +- user=`dirname $value`/`$BASENAME $value .F` +- usersubname=$user.F +- elif test ${basefile##*.} = f90 +- then +- user=`dirname $value`/`$BASENAME $value .f90` +- usersubname=$user.f90 +- elif test ${basefile##*.} = F90 +- then +- user=`dirname $value`/`$BASENAME $value .F90` +- usersubname=$user.F90 +- fi ++ user=$value + case $user in + \/*) + ;; + *) + user=`pwd`/$user +- usersubname=`pwd`/$usersubname + ;; + esac +- if test ! -f $usersubname +- then +- if test -f $usersubname.f +- then +- usersubname=$usersubname.f +- elif test -f $usersubname.F +- then +- usersubname=$usersubname.F +- elif test -f $usersubname.f90 +- then +- usersubname=$usersubname.f90 +- elif test -f $usersubname.F90 +- then +- usersubname=$usersubname.F90 +- fi +- fi ++ usernoext=$user ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` + ;; + -obj | -OBJ) + objs="$value" +@@ -1207,12 +1197,12 @@ + fi + fi + fi +- if test "$usersubname" ++ if test "$user" + then +- if test ! -f $usersubname ++ if test ! -f $user + then + error="$error +-user subroutine file $usersubname not accessible" ++user subroutine file $user not accessible" + fi + fi + if test "$objs" +@@ -1531,7 +1521,7 @@ + Marc shared lib : $progdll + Version type : $mode + Job ID : $DIRJID/$jid$extra_job_info +-User subroutine name : $usersubname ++User subroutine name : $user + User objects/libs : $objs + Restart file job ID : $rid + Substructure file ID : $sid +@@ -1564,7 +1554,7 @@ + Marc shared lib : $progdll + Version type : $mode + Job ID : $DIRJID/$jid$extra_job_info +-User subroutine name : $usersubname ++User subroutine name : $user + User objects/libs : $objs + Restart file job ID : $rid + Substructure file ID : $sid +@@ -1687,7 +1677,7 @@ + ;; + esac + fi +- $ECHO "User subroutine name ($usersubname)? $ECHOTXT" ++ $ECHO "User subroutine name ($user)? $ECHOTXT" + read value + if test "$value" + then +@@ -1696,50 +1686,19 @@ + user= + ;; + *) +- user=`dirname $value`/`$BASENAME $value .f` +- usersubname=$user +- basefile=`$BASENAME $value` +- if test ${basefile##*.} = f +- then +- user=`dirname $value`/`$BASENAME $value .f` +- usersubname=$user.f +- elif test ${basefile##*.} = F +- then +- user=`dirname $value`/`$BASENAME $value .F` +- usersubname=$user.F +- elif test ${basefile##*.} = f90 +- then +- user=`dirname $value`/`$BASENAME $value .f90` +- usersubname=$user.f90 +- elif test ${basefile##*.} = F90 +- then +- user=`dirname $value`/`$BASENAME $value .F90` +- usersubname=$user.F90 +- fi ++ user=$value + case $user in + \/*) + ;; + *) + user=`pwd`/$user +- usersubname=`pwd`/$usersubname + ;; + esac +- if test ! -f $usersubname +- then +- if test -f $usersubname.f +- then +- usersubname=$usersubname.f +- elif test -f $usersubname.F +- then +- usersubname=$usersubname.F +- elif test -f $usersubname.f90 +- then +- usersubname=$usersubname.f90 +- elif test -f $usersubname.F90 +- then +- usersubname=$usersubname.F90 +- fi +- fi ++ usernoext=$user ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` + ;; + esac + fi +@@ -2274,11 +2233,12 @@ + # + # user subroutine used + # ++# add DAMASK options for linking ++ DAMASK="-lstdc++" + + if test "$user" + then +-# program=$user.marc +- program=$DIRJOB/`$BASENAME $user .f`.marc ++ program=$usernoext.marc + case $program in + \/* | \.\/*) + bd= +@@ -2391,7 +2351,7 @@ + fi + if test "$user" + then +- execpath=$DIRJOB/`$BASENAME $user .f`.marc ++ execpath=$usernoext.marc + usersub=1 + fi + export execpath +@@ -3274,44 +3234,27 @@ + echo + if test "$user" + then +- userobj=$DIRJOB/`$BASENAME $user .f`.o +- basefile=`$BASENAME $usersubname` +- if test ${basefile##*.} = f +- then +- usersub=$DIRJOB/`$BASENAME $user .f`.F +- ln -sf "$user.f" "$usersub" +- else +- usersub=$usersubname +- fi +- ++ userobj=$usernoext.o + fi + cat > $jid.runmarcscript << END4 + if test "$user" + then +- if test ${basefile##*.} = f +- then +- ln -sf "$user.f" "$usersub" +- fi + if test $MACHINENAME = "CRAY" + then +- $FORTRAN $usersub || \ ++ $DFORTLOWMP $user || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null + else +- $FORTRAN $usersub -o $userobj || \ ++ $DFORTLOWMP $user -o $userobj || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null + fi +- if test ${basefile##*.} = f +- then +- /bin/rm -f "$usersub" +- fi + fi + + +@@ -3331,6 +3274,7 @@ + $TKLIBS \ + $MRCLIBS \ + $METISLIBS \ ++ $DAMASK \ + $SFLIB \ + $OPENSSL_LIB \ + $SYSLIBS \ +@@ -3344,6 +3288,9 @@ + prgsav=yes + fi + /bin/rm $userobj 2>/dev/null ++/bin/rm $DIRJOB/*.mod 2>/dev/null ++/bin/rm $DIRJOB/*.smod 2>/dev/null ++/bin/rm $DIRJOB/*_genmod.f90 2>/dev/null + + # + # run marc +@@ -3390,7 +3337,7 @@ + fi + else + if test $cpdll = yes; then +- filename=`basename $usersubname .f` ++ filename=$usernoext + /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null + fi + if test $rmdll = yes +@@ -3556,7 +3503,7 @@ + # first copy over the user sub if local directories + if test ${dirstatus[$counter]} = "local" + then +- $RCP $user.f $i:$DIR1/ ++ $RCP $user $i:$DIR1/ + fi + # do the compilation on the other machine + if test ${dirstatus[$counter]} = "shared" +@@ -3569,21 +3516,21 @@ + remoteuser=$DIR1/`$BASENAME $user` + $RSH $i /bin/rm $remoteprog 2> /dev/null + echo +- $RSH $i $DIR2/tools/comp_user $DIR2 $DIR1 $remoteuser $remoteprog ++ $RSH $i $DIR2/tools/comp_damask_lmp $DIR2 $DIR1 $remoteuser $remoteprog + # check if successful, the new executable should be there + line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` + if test "$line" + then + echo compilation and linking successful on host $i + else +- echo "$0: compile failed for $user.f on host $i" ++ echo "$0: compile failed for $user on host $i" + echo " $PRODUCT Exit number 3" + exit 1 + fi + # remove the user subroutine on remote machine + if test ${dirstatus[$counter]} = "local" + then +- $RSH $i /bin/rm $remoteuser.f 2> /dev/null ++ $RSH $i /bin/rm $remoteuser 2> /dev/null + fi + fi + fi +@@ -3593,39 +3540,27 @@ + if test "$userhost" + then + echo +- echo "Compiling and linking user subroutine $user.f on host `hostname`" +- fi +- userobj=$DIRJOB/`$BASENAME $user .f`.o +- basefile=`$BASENAME $usersubname` +- if test ${basefile##*.} = f +- then +- usersub=$DIRJOB/`$BASENAME $user .f`.F +- ln -sf "$user.f" "$usersub" +- else +- usersub=$usersubname ++ echo "Compiling and linking user subroutine $user on host `hostname`" + fi ++ userobj=$usernoext.o + if test $MACHINENAME = "CRAY" + then +- $FORTRAN $usersub || \ ++ $DFORTLOWMP $user || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + echo " $PRODUCT Exit number 3" + exit 1 + } + /bin/rm $program 2>/dev/null + else +- $FORTRAN $usersub -o $userobj || \ ++ $DFORTLOWMP $user -o $userobj || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + echo " $PRODUCT Exit number 3" + exit 1 + } + /bin/rm $program 2>/dev/null + fi +- if test ${basefile##*.} = f +- then +- /bin/rm -f "$usersub" +- fi + fi # if test $user + + +@@ -3645,6 +3580,7 @@ + $TKLIBS \ + $MRCLIBS \ + $METISLIBS \ ++ $DAMASK \ + $SFLIB \ + $OPENSSL_LIB \ + $SYSLIBS \ +@@ -3686,6 +3622,9 @@ + prgsav=yes + fi # if test $link + /bin/rm $userobj 2>/dev/null ++/bin/rm $DIRJOB/*.mod 2>/dev/null ++/bin/rm $DIRJOB/*.smod 2>/dev/null ++/bin/rm $DIRJOB/*_genmod.f90 2>/dev/null + + # + # run marc +@@ -3779,7 +3718,7 @@ + else + #dllrun >0 + if test $cpdll = yes; then +- filename=`basename $usersubname .f` ++ filename=$usernoext + /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null + fi + if test $rmdll = yes;then +@@ -3904,7 +3843,7 @@ + # first copy over the user sub if local directories + if test ${dirstatus[$counter]} = "local" + then +- $RCP $user.f $i:$DIR1/ ++ $RCP $user $i:$DIR1/ + fi + # do the compilation on the other machine + if test ${dirstatus[$counter]} = "shared" +@@ -3917,20 +3856,20 @@ + remoteuser=$DIR1/`$BASENAME $user` + $RSH $i /bin/rm $remoteprog 2> /dev/null + echo +- $RSH $i $DIR2/tools/comp_user $DIR2 $DIR1 $remoteuser $remoteprog ++ $RSH $i $DIR2/tools/comp_damask_lmp $DIR2 $DIR1 $remoteuser $remoteprog + # check if successful, the new executable should be there + line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` + if test "$line" + then + echo compilation and linking successful on host $i + else +- echo "$0: compile failed for $user.f on host $i" ++ echo "$0: compile failed for $user on host $i" + exit 1 + fi + # remove the user subroutine on remote machine + if test ${dirstatus[$counter]} = "local" + then +- $RSH $i /bin/rm $remoteuser.f 2> /dev/null ++ $RSH $i /bin/rm $remoteuser 2> /dev/null + fi + fi + fi +@@ -3940,37 +3879,25 @@ + if test "$userhost" + then + echo +- echo "Compiling and linking user subroutine $user.f on host `hostname`" +- fi +- userobj=$DIRJOB/`$BASENAME $user .f`.o +- basefile=`$BASENAME $usersubname` +- if test ${basefile##*.} = f +- then +- usersub=$DIRJOB/`$BASENAME $user .f`.F +- ln -sf "$user.f" "$usersub" +- else +- usersub=$usersubname ++ echo "Compiling and linking user subroutine $user on host `hostname`" + fi ++ userobj=$usernoext.o + if test $MACHINENAME = "CRAY" + then +- $FORTRAN $usersub || \ ++ $DFORTLOWMP $user || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null + else +- $FORTRAN $usersub -o $userobj || \ ++ $DFORTLOWMP $user -o $userobj || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null + fi +- if test ${basefile##*.} = f +- then +- /bin/rm -f "$usersub" +- fi + fi # if test $user + + +@@ -3990,6 +3917,7 @@ + $TKLIBS \ + $MRCLIBS \ + $METISLIBS \ ++ $DAMASK \ + $SFLIB \ + $OPENSSL_LIB \ + $SYSLIBS \ +@@ -4030,7 +3958,9 @@ + prgsav=yes + fi # if test $link + /bin/rm $userobj 2>/dev/null +- ++/bin/rm $DIRJOB/*.mod 2>/dev/null ++/bin/rm $DIRJOB/*.smod 2>/dev/null ++/bin/rm $DIRJOB/*_genmod.f90 2>/dev/null + # done if no job id given + if test -z "$jid" + then +@@ -4149,7 +4079,7 @@ + else + #dllrun >0 + if test $cpdll = yes; then +- filename=`basename $usersubname .f` ++ filename=$usernoext + /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null + fi + if test $rmdll = yes;then diff --git a/install/MarcMentat/2022.3/Marc_tools/run_damask_mp.patch b/install/MarcMentat/2022.3/Marc_tools/run_damask_mp.patch new file mode 100644 index 000000000..f73bc5299 --- /dev/null +++ b/install/MarcMentat/2022.3/Marc_tools/run_damask_mp.patch @@ -0,0 +1,517 @@ +--- ++++ +@@ -136,6 +136,11 @@ + # is created. For job running in the background, the log # + # file is always created. Default is "yes" # + ############################################################################## ++# remove all Mentat paths from LD_LIBRARY_PATH ++LD_LIBRARY_PATH=:$LD_LIBRARY_PATH: ++LD_LIBRARY_PATH=${LD_LIBRARY_PATH//+([!(:)])mentat2022.3+([!(:)])/:} ++LD_LIBRARY_PATH=${LD_LIBRARY_PATH//+([(:)])/:} ++LD_LIBRARY_PATH=${LD_LIBRARY_PATH#:}; LD_LIBRARY_PATH=${LD_LIBRARY_PATH%:} + # set DIR to the directory in which this script is + REALCOM="`/bin/ls -l $0 |awk '{ print $NF; }'`" + DIR=`dirname $REALCOM` +@@ -302,7 +307,23 @@ + + . "$DIR/getarch" + ++ ++# getting user subroutine file name ++found=0 ++for i in "$@"; do ++ if test $found = 1; then ++ DAMASK_USER=$i ++ found=0 ++ fi ++ case $i in ++ -u* | -U*) ++ found=1 ++ ;; ++ esac ++done ++# sourcing include_linux64 (needs DAMASK_USER to be set) + . $MARC_INCLUDE ++ + # + + # +@@ -405,7 +426,7 @@ + did= + vid= + user= +-usersubname= ++usernoext= + objs= + qid=background + cpu= +@@ -676,50 +697,19 @@ + esac + ;; + -u* | -U*) +- user=`dirname $value`/`$BASENAME $value .f` +- usersubname=$user +- basefile=`$BASENAME $value` +- if test ${basefile##*.} = f +- then +- user=`dirname $value`/`$BASENAME $value .f` +- usersubname=$user.f +- elif test ${basefile##*.} = F +- then +- user=`dirname $value`/`$BASENAME $value .F` +- usersubname=$user.F +- elif test ${basefile##*.} = f90 +- then +- user=`dirname $value`/`$BASENAME $value .f90` +- usersubname=$user.f90 +- elif test ${basefile##*.} = F90 +- then +- user=`dirname $value`/`$BASENAME $value .F90` +- usersubname=$user.F90 +- fi ++ user=$value + case $user in + \/*) + ;; + *) + user=`pwd`/$user +- usersubname=`pwd`/$usersubname + ;; + esac +- if test ! -f $usersubname +- then +- if test -f $usersubname.f +- then +- usersubname=$usersubname.f +- elif test -f $usersubname.F +- then +- usersubname=$usersubname.F +- elif test -f $usersubname.f90 +- then +- usersubname=$usersubname.f90 +- elif test -f $usersubname.F90 +- then +- usersubname=$usersubname.F90 +- fi +- fi ++ usernoext=$user ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` + ;; + -obj | -OBJ) + objs="$value" +@@ -1207,12 +1197,12 @@ + fi + fi + fi +- if test "$usersubname" ++ if test "$user" + then +- if test ! -f $usersubname ++ if test ! -f $user + then + error="$error +-user subroutine file $usersubname not accessible" ++user subroutine file $user not accessible" + fi + fi + if test "$objs" +@@ -1531,7 +1521,7 @@ + Marc shared lib : $progdll + Version type : $mode + Job ID : $DIRJID/$jid$extra_job_info +-User subroutine name : $usersubname ++User subroutine name : $user + User objects/libs : $objs + Restart file job ID : $rid + Substructure file ID : $sid +@@ -1564,7 +1554,7 @@ + Marc shared lib : $progdll + Version type : $mode + Job ID : $DIRJID/$jid$extra_job_info +-User subroutine name : $usersubname ++User subroutine name : $user + User objects/libs : $objs + Restart file job ID : $rid + Substructure file ID : $sid +@@ -1687,7 +1677,7 @@ + ;; + esac + fi +- $ECHO "User subroutine name ($usersubname)? $ECHOTXT" ++ $ECHO "User subroutine name ($user)? $ECHOTXT" + read value + if test "$value" + then +@@ -1696,50 +1686,19 @@ + user= + ;; + *) +- user=`dirname $value`/`$BASENAME $value .f` +- usersubname=$user +- basefile=`$BASENAME $value` +- if test ${basefile##*.} = f +- then +- user=`dirname $value`/`$BASENAME $value .f` +- usersubname=$user.f +- elif test ${basefile##*.} = F +- then +- user=`dirname $value`/`$BASENAME $value .F` +- usersubname=$user.F +- elif test ${basefile##*.} = f90 +- then +- user=`dirname $value`/`$BASENAME $value .f90` +- usersubname=$user.f90 +- elif test ${basefile##*.} = F90 +- then +- user=`dirname $value`/`$BASENAME $value .F90` +- usersubname=$user.F90 +- fi ++ user=$value + case $user in + \/*) + ;; + *) + user=`pwd`/$user +- usersubname=`pwd`/$usersubname + ;; + esac +- if test ! -f $usersubname +- then +- if test -f $usersubname.f +- then +- usersubname=$usersubname.f +- elif test -f $usersubname.F +- then +- usersubname=$usersubname.F +- elif test -f $usersubname.f90 +- then +- usersubname=$usersubname.f90 +- elif test -f $usersubname.F90 +- then +- usersubname=$usersubname.F90 +- fi +- fi ++ usernoext=$user ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` + ;; + esac + fi +@@ -2274,11 +2233,12 @@ + # + # user subroutine used + # ++# add DAMASK options for linking ++ DAMASK="-lstdc++" + + if test "$user" + then +-# program=$user.marc +- program=$DIRJOB/`$BASENAME $user .f`.marc ++ program=$usernoext.marc + case $program in + \/* | \.\/*) + bd= +@@ -2391,7 +2351,7 @@ + fi + if test "$user" + then +- execpath=$DIRJOB/`$BASENAME $user .f`.marc ++ execpath=$usernoext.marc + usersub=1 + fi + export execpath +@@ -3274,44 +3234,27 @@ + echo + if test "$user" + then +- userobj=$DIRJOB/`$BASENAME $user .f`.o +- basefile=`$BASENAME $usersubname` +- if test ${basefile##*.} = f +- then +- usersub=$DIRJOB/`$BASENAME $user .f`.F +- ln -sf "$user.f" "$usersub" +- else +- usersub=$usersubname +- fi +- ++ userobj=$usernoext.o + fi + cat > $jid.runmarcscript << END4 + if test "$user" + then +- if test ${basefile##*.} = f +- then +- ln -sf "$user.f" "$usersub" +- fi + if test $MACHINENAME = "CRAY" + then +- $FORTRAN $usersub || \ ++ $DFORTRANMP $user || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null + else +- $FORTRAN $usersub -o $userobj || \ ++ $DFORTRANMP $user -o $userobj || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null + fi +- if test ${basefile##*.} = f +- then +- /bin/rm -f "$usersub" +- fi + fi + + +@@ -3331,6 +3274,7 @@ + $TKLIBS \ + $MRCLIBS \ + $METISLIBS \ ++ $DAMASK \ + $SFLIB \ + $OPENSSL_LIB \ + $SYSLIBS \ +@@ -3344,6 +3288,9 @@ + prgsav=yes + fi + /bin/rm $userobj 2>/dev/null ++/bin/rm $DIRJOB/*.mod 2>/dev/null ++/bin/rm $DIRJOB/*.smod 2>/dev/null ++/bin/rm $DIRJOB/*_genmod.f90 2>/dev/null + + # + # run marc +@@ -3390,7 +3337,7 @@ + fi + else + if test $cpdll = yes; then +- filename=`basename $usersubname .f` ++ filename=$usernoext + /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null + fi + if test $rmdll = yes +@@ -3556,7 +3503,7 @@ + # first copy over the user sub if local directories + if test ${dirstatus[$counter]} = "local" + then +- $RCP $user.f $i:$DIR1/ ++ $RCP $user $i:$DIR1/ + fi + # do the compilation on the other machine + if test ${dirstatus[$counter]} = "shared" +@@ -3569,21 +3516,21 @@ + remoteuser=$DIR1/`$BASENAME $user` + $RSH $i /bin/rm $remoteprog 2> /dev/null + echo +- $RSH $i $DIR2/tools/comp_user $DIR2 $DIR1 $remoteuser $remoteprog ++ $RSH $i $DIR2/tools/comp_damask_mp $DIR2 $DIR1 $remoteuser $remoteprog + # check if successful, the new executable should be there + line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` + if test "$line" + then + echo compilation and linking successful on host $i + else +- echo "$0: compile failed for $user.f on host $i" ++ echo "$0: compile failed for $user on host $i" + echo " $PRODUCT Exit number 3" + exit 1 + fi + # remove the user subroutine on remote machine + if test ${dirstatus[$counter]} = "local" + then +- $RSH $i /bin/rm $remoteuser.f 2> /dev/null ++ $RSH $i /bin/rm $remoteuser 2> /dev/null + fi + fi + fi +@@ -3593,39 +3540,27 @@ + if test "$userhost" + then + echo +- echo "Compiling and linking user subroutine $user.f on host `hostname`" +- fi +- userobj=$DIRJOB/`$BASENAME $user .f`.o +- basefile=`$BASENAME $usersubname` +- if test ${basefile##*.} = f +- then +- usersub=$DIRJOB/`$BASENAME $user .f`.F +- ln -sf "$user.f" "$usersub" +- else +- usersub=$usersubname ++ echo "Compiling and linking user subroutine $user on host `hostname`" + fi ++ userobj=$usernoext.o + if test $MACHINENAME = "CRAY" + then +- $FORTRAN $usersub || \ ++ $DFORTRANMP $user || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + echo " $PRODUCT Exit number 3" + exit 1 + } + /bin/rm $program 2>/dev/null + else +- $FORTRAN $usersub -o $userobj || \ ++ $DFORTRANMP $user -o $userobj || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + echo " $PRODUCT Exit number 3" + exit 1 + } + /bin/rm $program 2>/dev/null + fi +- if test ${basefile##*.} = f +- then +- /bin/rm -f "$usersub" +- fi + fi # if test $user + + +@@ -3645,6 +3580,7 @@ + $TKLIBS \ + $MRCLIBS \ + $METISLIBS \ ++ $DAMASK \ + $SFLIB \ + $OPENSSL_LIB \ + $SYSLIBS \ +@@ -3686,6 +3622,9 @@ + prgsav=yes + fi # if test $link + /bin/rm $userobj 2>/dev/null ++/bin/rm $DIRJOB/*.mod 2>/dev/null ++/bin/rm $DIRJOB/*.smod 2>/dev/null ++/bin/rm $DIRJOB/*_genmod.f90 2>/dev/null + + # + # run marc +@@ -3779,7 +3718,7 @@ + else + #dllrun >0 + if test $cpdll = yes; then +- filename=`basename $usersubname .f` ++ filename=$usernoext + /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null + fi + if test $rmdll = yes;then +@@ -3904,7 +3843,7 @@ + # first copy over the user sub if local directories + if test ${dirstatus[$counter]} = "local" + then +- $RCP $user.f $i:$DIR1/ ++ $RCP $user $i:$DIR1/ + fi + # do the compilation on the other machine + if test ${dirstatus[$counter]} = "shared" +@@ -3917,20 +3856,20 @@ + remoteuser=$DIR1/`$BASENAME $user` + $RSH $i /bin/rm $remoteprog 2> /dev/null + echo +- $RSH $i $DIR2/tools/comp_user $DIR2 $DIR1 $remoteuser $remoteprog ++ $RSH $i $DIR2/tools/comp_damask_mp $DIR2 $DIR1 $remoteuser $remoteprog + # check if successful, the new executable should be there + line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` + if test "$line" + then + echo compilation and linking successful on host $i + else +- echo "$0: compile failed for $user.f on host $i" ++ echo "$0: compile failed for $user on host $i" + exit 1 + fi + # remove the user subroutine on remote machine + if test ${dirstatus[$counter]} = "local" + then +- $RSH $i /bin/rm $remoteuser.f 2> /dev/null ++ $RSH $i /bin/rm $remoteuser 2> /dev/null + fi + fi + fi +@@ -3940,37 +3879,25 @@ + if test "$userhost" + then + echo +- echo "Compiling and linking user subroutine $user.f on host `hostname`" +- fi +- userobj=$DIRJOB/`$BASENAME $user .f`.o +- basefile=`$BASENAME $usersubname` +- if test ${basefile##*.} = f +- then +- usersub=$DIRJOB/`$BASENAME $user .f`.F +- ln -sf "$user.f" "$usersub" +- else +- usersub=$usersubname ++ echo "Compiling and linking user subroutine $user on host `hostname`" + fi ++ userobj=$usernoext.o + if test $MACHINENAME = "CRAY" + then +- $FORTRAN $usersub || \ ++ $DFORTRANMP $user || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null + else +- $FORTRAN $usersub -o $userobj || \ ++ $DFORTRANMP $user -o $userobj || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null + fi +- if test ${basefile##*.} = f +- then +- /bin/rm -f "$usersub" +- fi + fi # if test $user + + +@@ -3990,6 +3917,7 @@ + $TKLIBS \ + $MRCLIBS \ + $METISLIBS \ ++ $DAMASK \ + $SFLIB \ + $OPENSSL_LIB \ + $SYSLIBS \ +@@ -4030,7 +3958,9 @@ + prgsav=yes + fi # if test $link + /bin/rm $userobj 2>/dev/null +- ++/bin/rm $DIRJOB/*.mod 2>/dev/null ++/bin/rm $DIRJOB/*.smod 2>/dev/null ++/bin/rm $DIRJOB/*_genmod.f90 2>/dev/null + # done if no job id given + if test -z "$jid" + then +@@ -4149,7 +4079,7 @@ + else + #dllrun >0 + if test $cpdll = yes; then +- filename=`basename $usersubname .f` ++ filename=$usernoext + /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null + fi + if test $rmdll = yes;then diff --git a/install/MarcMentat/2022.3/Mentat_bin/edit_window.patch b/install/MarcMentat/2022.3/Mentat_bin/edit_window.patch new file mode 100644 index 000000000..915af9bf6 --- /dev/null +++ b/install/MarcMentat/2022.3/Mentat_bin/edit_window.patch @@ -0,0 +1,24 @@ +--- ++++ +@@ -1,18 +1,5 @@ + #!/bin/sh +-# This script opens a window running an editor. The default window is an +-# xterm, and the default editor is vi. These may be customized. ++# This script opens a window running an editor. ++# The command to invoke the editor is specified during DAMASK installation + +-dir= +-for d in /usr/bin /usr/bin/X11; do +- if test -x "$d/xterm"; then +- dir="$d" +- break +- fi +-done +- +-if test -z "$dir"; then +- echo "$0: Could not find xterm" +- exit 1 +-fi +- +-"$dir/xterm" -T "vi $*" -n "vi $*" -e vi $* ++%EDITOR% $* diff --git a/install/MarcMentat/2022.3/Mentat_bin/kill4.patch b/install/MarcMentat/2022.3/Mentat_bin/kill4.patch new file mode 100644 index 000000000..e69de29bb diff --git a/install/MarcMentat/2022.3/Mentat_bin/kill5.patch b/install/MarcMentat/2022.3/Mentat_bin/kill5.patch new file mode 100644 index 000000000..e69de29bb diff --git a/install/MarcMentat/2022.3/Mentat_bin/kill6.patch b/install/MarcMentat/2022.3/Mentat_bin/kill6.patch new file mode 100644 index 000000000..e69de29bb diff --git a/install/MarcMentat/2022.3/Mentat_bin/submit4.patch b/install/MarcMentat/2022.3/Mentat_bin/submit4.patch new file mode 100644 index 000000000..98c51e76d --- /dev/null +++ b/install/MarcMentat/2022.3/Mentat_bin/submit4.patch @@ -0,0 +1,38 @@ +--- ++++ +@@ -63,10 +63,10 @@ + if [ "$slv" != "" -a "$slv" != "marc" -a "$slv" != "datfit" ]; then + slv="-iam sfm" + fi +-if [ "$slv" == "marc" ]; then ++if [ "$slv" = "marc" ]; then + slv="" + fi +-if [ "$slv" == "datfit" ]; then ++if [ "$slv" = "datfit" ]; then + slv="-iam datfit" + fi + +@@ -91,6 +91,7 @@ + srcfile="-u $srcfile -save y" + ;; + runsaved) ++ srcfile=${srcfile%.*}".marc" + srcfile="-prog $srcfile" + ;; + esac +@@ -189,12 +190,12 @@ + unset PYTHONPATH + + if [ "$doe_first" = "-" ]; then # submit of regular Marc job +- "${DIR}/tools/run_marc" $slv -j $job -v n -b y $nprocds $nprocd \ ++ "${DIR}/tools/run_damask_hmp" $slv -j $job -v n -b y $nprocds $nprocd \ + $srcfile $restart $postfile $viewfactorsfile $hostfile \ + $compat $copy_datfile $copy_postfile $scr_dir $dcoup \ + $assem_recov_nthread $nthread $nsolver $mode $gpu > /dev/null 2>&1 + else # submit of a DoE Marc job +- "${DIR}/tools/run_marc" $slv -j $job -v n -b n $nprocds $nprocd \ ++ "${DIR}/tools/run_damask_hmp" $slv -j $job -v n -b n $nprocds $nprocd \ + $srcfile $restart $postfile $viewfactorsfile $hostfile \ + $compat $copy_datfile $copy_postfile $scr_dir $dcoup \ + $assem_recov_nthread $nthread $nsolver $mode $gpu diff --git a/install/MarcMentat/2022.3/Mentat_bin/submit5.patch b/install/MarcMentat/2022.3/Mentat_bin/submit5.patch new file mode 100644 index 000000000..ab32b1058 --- /dev/null +++ b/install/MarcMentat/2022.3/Mentat_bin/submit5.patch @@ -0,0 +1,38 @@ +--- ++++ +@@ -63,10 +63,10 @@ + if [ "$slv" != "" -a "$slv" != "marc" -a "$slv" != "datfit" ]; then + slv="-iam sfm" + fi +-if [ "$slv" == "marc" ]; then ++if [ "$slv" = "marc" ]; then + slv="" + fi +-if [ "$slv" == "datfit" ]; then ++if [ "$slv" = "datfit" ]; then + slv="-iam datfit" + fi + +@@ -91,6 +91,7 @@ + srcfile="-u $srcfile -save y" + ;; + runsaved) ++ srcfile=${srcfile%.*}".marc" + srcfile="-prog $srcfile" + ;; + esac +@@ -189,12 +190,12 @@ + unset PYTHONPATH + + if [ "$doe_first" = "-" ]; then # submit of regular Marc job +- "${DIR}/tools/run_marc" $slv -j $job -v n -b y $nprocds $nprocd \ ++ "${DIR}/tools/run_damask_mp" $slv -j $job -v n -b y $nprocds $nprocd \ + $srcfile $restart $postfile $viewfactorsfile $hostfile \ + $compat $copy_datfile $copy_postfile $scr_dir $dcoup \ + $assem_recov_nthread $nthread $nsolver $mode $gpu > /dev/null 2>&1 + else # submit of a DoE Marc job +- "${DIR}/tools/run_marc" $slv -j $job -v n -b n $nprocds $nprocd \ ++ "${DIR}/tools/run_damask_mp" $slv -j $job -v n -b n $nprocds $nprocd \ + $srcfile $restart $postfile $viewfactorsfile $hostfile \ + $compat $copy_datfile $copy_postfile $scr_dir $dcoup \ + $assem_recov_nthread $nthread $nsolver $mode $gpu diff --git a/install/MarcMentat/2022.3/Mentat_bin/submit6.patch b/install/MarcMentat/2022.3/Mentat_bin/submit6.patch new file mode 100644 index 000000000..d5ea3cfde --- /dev/null +++ b/install/MarcMentat/2022.3/Mentat_bin/submit6.patch @@ -0,0 +1,38 @@ +--- ++++ +@@ -63,10 +63,10 @@ + if [ "$slv" != "" -a "$slv" != "marc" -a "$slv" != "datfit" ]; then + slv="-iam sfm" + fi +-if [ "$slv" == "marc" ]; then ++if [ "$slv" = "marc" ]; then + slv="" + fi +-if [ "$slv" == "datfit" ]; then ++if [ "$slv" = "datfit" ]; then + slv="-iam datfit" + fi + +@@ -91,6 +91,7 @@ + srcfile="-u $srcfile -save y" + ;; + runsaved) ++ srcfile=${srcfile%.*}".marc" + srcfile="-prog $srcfile" + ;; + esac +@@ -189,12 +190,12 @@ + unset PYTHONPATH + + if [ "$doe_first" = "-" ]; then # submit of regular Marc job +- "${DIR}/tools/run_marc" $slv -j $job -v n -b y $nprocds $nprocd \ ++ "${DIR}/tools/run_damask_lmp" $slv -j $job -v n -b y $nprocds $nprocd \ + $srcfile $restart $postfile $viewfactorsfile $hostfile \ + $compat $copy_datfile $copy_postfile $scr_dir $dcoup \ + $assem_recov_nthread $nthread $nsolver $mode $gpu > /dev/null 2>&1 + else # submit of a DoE Marc job +- "${DIR}/tools/run_marc" $slv -j $job -v n -b n $nprocds $nprocd \ ++ "${DIR}/tools/run_damask_lmp" $slv -j $job -v n -b n $nprocds $nprocd \ + $srcfile $restart $postfile $viewfactorsfile $hostfile \ + $compat $copy_datfile $copy_postfile $scr_dir $dcoup \ + $assem_recov_nthread $nthread $nsolver $mode $gpu diff --git a/install/MarcMentat/2022.3/Mentat_menus/job_run.ms.patch b/install/MarcMentat/2022.3/Mentat_menus/job_run.ms.patch new file mode 100644 index 000000000..e9223b1e4 --- /dev/null +++ b/install/MarcMentat/2022.3/Mentat_menus/job_run.ms.patch @@ -0,0 +1,158 @@ +--- ++++ +@@ -261,11 +261,18 @@ + } + button { + position +25 = +- size 25 4 ++ size 18 4 + text "ADVANCED JOB SUBMISSION" + help "job_run#Job Submission And Control" + popmenu job_submit_adv_pm + } ++ button { ++ position +18 = ++ size 7 4 ++ text "DAMASK" ++ help "damask_run#Job Submission And Control" ++ popmenu damask ++ } + button { + position 0 +4 + size 16 4 +@@ -1207,6 +1214,135 @@ + } + + ++#-------------------------------------------------------------------------------------------------- ++popmenu damask { ++ ++#ifdef QT_MENTAT ++ text "DAMASK.MPIE.DE" ++#endif ++ ++ group { ++#ifndef QT_MENTAT ++ label { ++ position 0 0 ++ size 50 4 ++ text "DAMASK.MPIE.DE" ++ } ++#endif ++ ++ label { ++ position 1 6 ++ size 13 6 ++ text "Optimzation" ++ border_width 1 ++ border_color black ++ } ++ ++ label { ++ position +13 = ++ size 20 6 ++ text "write Input" ++ border_width 1 ++ border_color black ++ } ++ ++ label { ++ position +18 = ++ size 30 6 ++ text "do not write Inp." ++ border_width 1 ++ border_color black ++ } ++ ++ label { ++ position -32 +6 ++ size 12 6 ++ text "O3 / OpenMP" ++ border_width 1 ++ border_color black ++ } ++ ++ popdown { ++ position +12 = ++ size 20 6 ++ text "Submit" ++ command "*submit_job 4 *monitor_job" ++ } ++ ++ popdown { ++ position +20 = ++ size 20 6 ++ text "Execute" ++ command "*execute_job 4 *monitor_job" ++ } ++ ++ label { ++ position -32 +6 ++ size 12 6 ++ text "O1 / OpenMP" ++ border_width 1 ++ border_color black ++ } ++ ++ popdown { ++ position +12 = ++ size 20 6 ++ text "Submit" ++ command "*submit_job 5 *monitor_job" ++ } ++ ++ popdown { ++ position +20 = ++ size 20 6 ++ text "Execute" ++ command "*execute_job 5 *monitor_job" ++ } ++ ++ label { ++ position -32 +6 ++ size 12 6 ++ text "O0 / OpenMP" ++ border_width 1 ++ border_color black ++ } ++ ++ popdown { ++ position +12 = ++ size 20 6 ++ text "Submit" ++ command "*submit_job 6 *monitor_job" ++ } ++ ++ popdown { ++ position +20 = ++ size 20 6 ++ text "Execute" ++ command "*execute_job 6 *monitor_job" ++ } ++ ++ popdown { ++ position 19 +8 ++ size 12 8 ++ text "CANCEL" ++ } ++} ++ ++ window { ++ parent mentat ++ origin 38 8 ++#ifdef DCOM ++ size 50 100 ++#else ++ size 50 94 ++#endif ++ background_color body ++ border_width 1 ++ border_color border ++ buffering single ++ } ++ mode permanent ++} ++ + #-------------------------------------------------------------------------------------------------- + popmenu job_exit_msg_pm { + diff --git a/install/MarcMentat/2022.4/Marc_tools/comp_damask_hmp.patch b/install/MarcMentat/2022.4/Marc_tools/comp_damask_hmp.patch new file mode 100644 index 000000000..886ebf008 --- /dev/null +++ b/install/MarcMentat/2022.4/Marc_tools/comp_damask_hmp.patch @@ -0,0 +1,49 @@ +--- ++++ +@@ -6,18 +6,27 @@ + DIR=$1 + user=$3 + program=$4 ++usernoext=$user ++usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` ++usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` ++usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` ++usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` ++ ++# add BLAS options for linking ++ BLAS="%BLAS%" ++ + . $DIR/tools/include + DIRJOB=$2 + cd $DIRJOB +-echo "Compiling and linking user subroutine $user.f on host `hostname`" ++echo "Compiling and linking user subroutine $user on host `hostname`" + echo "program: $program" +- $FORTRAN $user.f || \ ++ $DFORTHIGHMP $user || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null +- userobj=$user.o ++ userobj=$usernoext.o + + + $LOAD ${program} $DIR/lib/main.o\ +@@ -33,9 +42,13 @@ + $TKLIBS \ + $MRCLIBS \ + $METISLIBS \ ++ $BLAS \ + $SYSLIBS || \ + { +- echo "$0: link failed for $user.o on host `hostname`" ++ echo "$0: link failed for $usernoext.o on host `hostname`" + exit 1 + } + /bin/rm $userobj ++ /bin/rm $DIRJOB/*.mod ++ /bin/rm $DIRJOB/*.smod ++ /bin/rm $DIRJOB/*_genmod.f90 diff --git a/install/MarcMentat/2022.4/Marc_tools/comp_damask_lmp.patch b/install/MarcMentat/2022.4/Marc_tools/comp_damask_lmp.patch new file mode 100644 index 000000000..191cb1a53 --- /dev/null +++ b/install/MarcMentat/2022.4/Marc_tools/comp_damask_lmp.patch @@ -0,0 +1,49 @@ +--- ++++ +@@ -6,18 +6,27 @@ + DIR=$1 + user=$3 + program=$4 ++usernoext=$user ++usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` ++usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` ++usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` ++usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` ++ ++# add BLAS options for linking ++ BLAS="%BLAS%" ++ + . $DIR/tools/include + DIRJOB=$2 + cd $DIRJOB +-echo "Compiling and linking user subroutine $user.f on host `hostname`" ++echo "Compiling and linking user subroutine $user on host `hostname`" + echo "program: $program" +- $FORTRAN $user.f || \ ++ $DFORTRANLOWMP $user || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null +- userobj=$user.o ++ userobj=$usernoext.o + + + $LOAD ${program} $DIR/lib/main.o\ +@@ -33,9 +42,13 @@ + $TKLIBS \ + $MRCLIBS \ + $METISLIBS \ ++ $BLAS \ + $SYSLIBS || \ + { +- echo "$0: link failed for $user.o on host `hostname`" ++ echo "$0: link failed for $usernoext.o on host `hostname`" + exit 1 + } + /bin/rm $userobj ++ /bin/rm $DIRJOB/*.mod ++ /bin/rm $DIRJOB/*.smod ++ /bin/rm $DIRJOB/*_genmod.f90 diff --git a/install/MarcMentat/2022.4/Marc_tools/comp_damask_mp.patch b/install/MarcMentat/2022.4/Marc_tools/comp_damask_mp.patch new file mode 100644 index 000000000..7c9cf7ba7 --- /dev/null +++ b/install/MarcMentat/2022.4/Marc_tools/comp_damask_mp.patch @@ -0,0 +1,49 @@ +--- ++++ +@@ -6,18 +6,27 @@ + DIR=$1 + user=$3 + program=$4 ++usernoext=$user ++usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` ++usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` ++usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` ++usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` ++ ++# add BLAS options for linking ++ BLAS="%BLAS%" ++ + . $DIR/tools/include + DIRJOB=$2 + cd $DIRJOB +-echo "Compiling and linking user subroutine $user.f on host `hostname`" ++echo "Compiling and linking user subroutine $user on host `hostname`" + echo "program: $program" +- $FORTRAN $user.f || \ ++ $DFORTRANMP $user || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null +- userobj=$user.o ++ userobj=$usernoext.o + + + $LOAD ${program} $DIR/lib/main.o\ +@@ -33,9 +42,13 @@ + $TKLIBS \ + $MRCLIBS \ + $METISLIBS \ ++ $BLAS \ + $SYSLIBS || \ + { +- echo "$0: link failed for $user.o on host `hostname`" ++ echo "$0: link failed for $usernoext.o on host `hostname`" + exit 1 + } + /bin/rm $userobj ++ /bin/rm $DIRJOB/*.mod ++ /bin/rm $DIRJOB/*.smod ++ /bin/rm $DIRJOB/*_genmod.f90 diff --git a/install/MarcMentat/2022.4/Marc_tools/include_linux64.patch b/install/MarcMentat/2022.4/Marc_tools/include_linux64.patch new file mode 100644 index 000000000..429ba64c4 --- /dev/null +++ b/install/MarcMentat/2022.4/Marc_tools/include_linux64.patch @@ -0,0 +1,75 @@ +--- ++++ +@@ -166,6 +166,15 @@ + MARC_COSIM_LIB="$MSCCOSIM_HOME/CoSim$MSCCOSIM_VERSION/Dcosim$MSCCOSIM_VERSION/lib" + fi + ++# DAMASK uses the HDF5 compiler wrapper around the Intel compiler ++H5FC=$(h5fc -shlib -show) ++if [[ "$H5FC" == *"$dir is"* ]]; then ++ H5FC=$(echo $(echo "$H5FC" | tail -n1) | sed -e "s/\-shlib/-fPIC -qopenmp/g") ++ H5FC=${H5FC%-lmpifort*} ++fi ++HDF5_LIB=${H5FC//*ifort/} ++FCOMP="$H5FC" ++ + # AEM + if test "$MARCDLLOUTDIR" = ""; then + DLLOUTDIR="$MARC_LIB" +@@ -594,7 +603,7 @@ + PROFILE=" $PROFILE -pg" + fi + +-FORT_OPT="-c -assume byterecl -safe_cray_ptr -mp1 -WB -fp-model source" ++FORT_OPT="-c -implicitnone -stand f18 -standard-semantics -assume nostd_mod_proc_name -safe_cray_ptr -mp1 -WB -fp-model source" + if test "$MTHREAD" = "OPENMP" + then + FORT_OPT=" $FORT_OPT -qopenmp" +@@ -607,7 +616,7 @@ + FORT_OPT=" $FORT_OPT -save -zero" + fi + if test "$MARCHDF_HDF" = "HDF"; then +- FORT_OPT="$FORT_OPT -DMARCHDF_HDF=$MARCHDF_HDF $HDF_INCLUDE" ++ FORT_OPT="$FORT_OPT -DMARCHDF=$MARCHDF_HDF" + fi + + FORTLOW="$FCOMP $FORT_OPT $PROFILE -O0 $I8FFLAGS -I$MARC_SOURCE/common \ +@@ -621,6 +630,29 @@ + # for compiling free form f90 files. high opt, integer(4) + FORTF90="$FCOMP -c -O3" + ++# determine DAMASK version ++if test -n "$DAMASK_USER"; then ++ DAMASKROOT=`dirname $DAMASK_USER`/../.. ++ read DAMASKVERSION < $DAMASKROOT/VERSION ++ DAMASKVERSION="'"$DAMASKVERSION"'" ++else ++ DAMASKVERSION="'N/A'" ++fi ++ ++# DAMASK compiler calls ++DFORTLOWMP="$FCOMP -c -O0 -qno-offload -implicitnone -stand f18 -standard-semantics -assume nostd_mod_proc_name -safe_cray_ptr $PROFILE -zero -mp1 -WB $I8FFLAGS -I$MARC_SOURCE/common \ ++ -fpp -ftz -diag-disable 5268 -warn declarations -warn general -warn usage -warn interfaces -warn ignore_loc -warn alignments -DMARC4DAMASK=2022.4 -DDAMASKVERSION=$DAMASKVERSION \ ++ -qopenmp -qopenmp-threadprivate=compat\ ++ $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD -I$MARC_MOD" ++DFORTRANMP="$FCOMP -c -O1 -qno-offload -implicitnone -stand f18 -standard-semantics -assume nostd_mod_proc_name -safe_cray_ptr $PROFILE -zero -mp1 -WB $I8FFLAGS -I$MARC_SOURCE/common \ ++ -fpp -ftz -diag-disable 5268 -warn declarations -warn general -warn usage -warn interfaces -warn ignore_loc -warn alignments -DMARC4DAMASK=2022.4 -DDAMASKVERSION=$DAMASKVERSION \ ++ -qopenmp -qopenmp-threadprivate=compat\ ++ $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD -I$MARC_MOD" ++DFORTHIGHMP="$FCOMP -c -O3 -qno-offload -implicitnone -stand f18 -standard-semantics -assume nostd_mod_proc_name -safe_cray_ptr $PROFILE -zero -mp1 -WB $I8FFLAGS -I$MARC_SOURCE/common \ ++ -fpp -ftz -diag-disable 5268 -warn declarations -warn general -warn usage -warn interfaces -warn ignore_loc -warn alignments -DMARC4DAMASK=2022.4 -DDAMASKVERSION=$DAMASKVERSION \ ++ -qopenmp -qopenmp-threadprivate=compat\ ++ $MUMPS_INCLUDE $I8DEFINES -DLinux -DLINUX -DLinux_intel $FDEFINES $DDM $SOLVERFLAGS -I$KDTREE2_MOD -I$MARC_MOD" ++ + if test "$MARCDEBUG" = "ON" + then + FORTLOW="$FCOMP $FORT_OPT $PROFILE $I8FFLAGS -I$MARC_SOURCE/common \ +@@ -778,7 +810,7 @@ + + SOLVERLIBS="${BCSSOLVERLIBS} ${VKISOLVERLIBS} ${CASISOLVERLIBS} ${MF2SOLVERLIBS} \ + -L$MARC_MKL \ +- $MARC_LIB/blas_src.a ${ACSI_LIB}/ACSI_MarcLib.a $KDTREE2_LIB/libkdtree2.a $MARC_LIB/libtetmeshinterface.a $MARC_LIB/libcaefatigueinterface.a -L$MARC_LIB -lmkl_blacs_intelmpi_ilp64 -lmkl_scalapack_ilp64 -lmkl_intel_ilp64 -lmkl_intel_thread -lmkl_core -liomp5 -ltetmesh -lmeshgems -lmg-tetra -lmeshgems_stubs -lmg-hybrid -lmg-cadsurf -lmg-hexa $HDF_LIBS $SOLVER2LIBS" ++ $MARC_LIB/blas_src.a ${ACSI_LIB}/ACSI_MarcLib.a $KDTREE2_LIB/libkdtree2.a $MARC_LIB/libtetmeshinterface.a $MARC_LIB/libcaefatigueinterface.a -L$MARC_LIB -lmkl_blacs_intelmpi_ilp64 -lmkl_scalapack_ilp64 -lmkl_intel_ilp64 -lmkl_intel_thread -lmkl_core -liomp5 -ltetmesh -lmeshgems -lmg-tetra -lmeshgems_stubs -lmg-hybrid -lmg-cadsurf -lmg-hexa $HDF5_LIB $SOLVER2LIBS" + + SOLVERLIBS_DLL=${SOLVERLIBS} + if test "$AEM_DLL" -eq 1 diff --git a/install/MarcMentat/2022.4/Marc_tools/run_damask_hmp.patch b/install/MarcMentat/2022.4/Marc_tools/run_damask_hmp.patch new file mode 100644 index 000000000..fa55c6be1 --- /dev/null +++ b/install/MarcMentat/2022.4/Marc_tools/run_damask_hmp.patch @@ -0,0 +1,517 @@ +--- ++++ +@@ -136,6 +136,11 @@ + # is created. For job running in the background, the log # + # file is always created. Default is "yes" # + ############################################################################## ++# remove all Mentat paths from LD_LIBRARY_PATH ++LD_LIBRARY_PATH=:$LD_LIBRARY_PATH: ++LD_LIBRARY_PATH=${LD_LIBRARY_PATH//+([!(:)])mentat2022.4+([!(:)])/:} ++LD_LIBRARY_PATH=${LD_LIBRARY_PATH//+([(:)])/:} ++LD_LIBRARY_PATH=${LD_LIBRARY_PATH#:}; LD_LIBRARY_PATH=${LD_LIBRARY_PATH%:} + # set DIR to the directory in which this script is + REALCOM="`/bin/ls -l $0 |awk '{ print $NF; }'`" + DIR=`dirname $REALCOM` +@@ -302,7 +307,23 @@ + + . "$DIR/getarch" + ++ ++# getting user subroutine file name ++found=0 ++for i in "$@"; do ++ if test $found = 1; then ++ DAMASK_USER=$i ++ found=0 ++ fi ++ case $i in ++ -u* | -U*) ++ found=1 ++ ;; ++ esac ++done ++# sourcing include_linux64 (needs DAMASK_USER to be set) + . $MARC_INCLUDE ++ + # + + # +@@ -405,7 +426,7 @@ + did= + vid= + user= +-usersubname= ++usernoext= + objs= + qid=background + cpu= +@@ -676,50 +697,19 @@ + esac + ;; + -u* | -U*) +- user=`dirname $value`/`$BASENAME $value .f` +- usersubname=$user +- basefile=`$BASENAME $value` +- if test ${basefile##*.} = f +- then +- user=`dirname $value`/`$BASENAME $value .f` +- usersubname=$user.f +- elif test ${basefile##*.} = F +- then +- user=`dirname $value`/`$BASENAME $value .F` +- usersubname=$user.F +- elif test ${basefile##*.} = f90 +- then +- user=`dirname $value`/`$BASENAME $value .f90` +- usersubname=$user.f90 +- elif test ${basefile##*.} = F90 +- then +- user=`dirname $value`/`$BASENAME $value .F90` +- usersubname=$user.F90 +- fi ++ user=$value + case $user in + \/*) + ;; + *) + user=`pwd`/$user +- usersubname=`pwd`/$usersubname + ;; + esac +- if test ! -f $usersubname +- then +- if test -f $usersubname.f +- then +- usersubname=$usersubname.f +- elif test -f $usersubname.F +- then +- usersubname=$usersubname.F +- elif test -f $usersubname.f90 +- then +- usersubname=$usersubname.f90 +- elif test -f $usersubname.F90 +- then +- usersubname=$usersubname.F90 +- fi +- fi ++ usernoext=$user ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` + ;; + -obj | -OBJ) + objs="$value" +@@ -1207,12 +1197,12 @@ + fi + fi + fi +- if test "$usersubname" ++ if test "$user" + then +- if test ! -f $usersubname ++ if test ! -f $user + then + error="$error +-user subroutine file $usersubname not accessible" ++user subroutine file $user not accessible" + fi + fi + if test "$objs" +@@ -1531,7 +1521,7 @@ + Marc shared lib : $progdll + Version type : $mode + Job ID : $DIRJID/$jid$extra_job_info +-User subroutine name : $usersubname ++User subroutine name : $user + User objects/libs : $objs + Restart file job ID : $rid + Substructure file ID : $sid +@@ -1564,7 +1554,7 @@ + Marc shared lib : $progdll + Version type : $mode + Job ID : $DIRJID/$jid$extra_job_info +-User subroutine name : $usersubname ++User subroutine name : $user + User objects/libs : $objs + Restart file job ID : $rid + Substructure file ID : $sid +@@ -1687,7 +1677,7 @@ + ;; + esac + fi +- $ECHO "User subroutine name ($usersubname)? $ECHOTXT" ++ $ECHO "User subroutine name ($user)? $ECHOTXT" + read value + if test "$value" + then +@@ -1696,50 +1686,19 @@ + user= + ;; + *) +- user=`dirname $value`/`$BASENAME $value .f` +- usersubname=$user +- basefile=`$BASENAME $value` +- if test ${basefile##*.} = f +- then +- user=`dirname $value`/`$BASENAME $value .f` +- usersubname=$user.f +- elif test ${basefile##*.} = F +- then +- user=`dirname $value`/`$BASENAME $value .F` +- usersubname=$user.F +- elif test ${basefile##*.} = f90 +- then +- user=`dirname $value`/`$BASENAME $value .f90` +- usersubname=$user.f90 +- elif test ${basefile##*.} = F90 +- then +- user=`dirname $value`/`$BASENAME $value .F90` +- usersubname=$user.F90 +- fi ++ user=$value + case $user in + \/*) + ;; + *) + user=`pwd`/$user +- usersubname=`pwd`/$usersubname + ;; + esac +- if test ! -f $usersubname +- then +- if test -f $usersubname.f +- then +- usersubname=$usersubname.f +- elif test -f $usersubname.F +- then +- usersubname=$usersubname.F +- elif test -f $usersubname.f90 +- then +- usersubname=$usersubname.f90 +- elif test -f $usersubname.F90 +- then +- usersubname=$usersubname.F90 +- fi +- fi ++ usernoext=$user ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` + ;; + esac + fi +@@ -2274,11 +2233,12 @@ + # + # user subroutine used + # ++# add DAMASK options for linking ++ DAMASK="-lstdc++" + + if test "$user" + then +-# program=$user.marc +- program=$DIRJOB/`$BASENAME $user .f`.marc ++ program=$usernoext.marc + case $program in + \/* | \.\/*) + bd= +@@ -2391,7 +2351,7 @@ + fi + if test "$user" + then +- execpath=$DIRJOB/`$BASENAME $user .f`.marc ++ execpath=$usernoext.marc + usersub=1 + fi + export execpath +@@ -3274,44 +3234,27 @@ + echo + if test "$user" + then +- userobj=$DIRJOB/`$BASENAME $user .f`.o +- basefile=`$BASENAME $usersubname` +- if test ${basefile##*.} = f +- then +- usersub=$DIRJOB/`$BASENAME $user .f`.F +- ln -sf "$user.f" "$usersub" +- else +- usersub=$usersubname +- fi +- ++ userobj=$usernoext.o + fi + cat > $jid.runmarcscript << END4 + if test "$user" + then +- if test ${basefile##*.} = f +- then +- ln -sf "$user.f" "$usersub" +- fi + if test $MACHINENAME = "CRAY" + then +- $FORTRAN $usersub || \ ++ $DFORTHIGHMP $user || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null + else +- $FORTRAN $usersub -o $userobj || \ ++ $DFORTHIGHMP $user -o $userobj || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null + fi +- if test ${basefile##*.} = f +- then +- /bin/rm -f "$usersub" +- fi + fi + + +@@ -3331,6 +3274,7 @@ + $TKLIBS \ + $MRCLIBS \ + $METISLIBS \ ++ $DAMASK \ + $SFLIB \ + $OPENSSL_LIB \ + $SYSLIBS \ +@@ -3344,6 +3288,9 @@ + prgsav=yes + fi + /bin/rm $userobj 2>/dev/null ++/bin/rm $DIRJOB/*.mod 2>/dev/null ++/bin/rm $DIRJOB/*.smod 2>/dev/null ++/bin/rm $DIRJOB/*_genmod.f90 2>/dev/null + + # + # run marc +@@ -3390,7 +3337,7 @@ + fi + else + if test $cpdll = yes; then +- filename=`basename $usersubname .f` ++ filename=$usernoext + /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null + fi + if test $rmdll = yes +@@ -3556,7 +3503,7 @@ + # first copy over the user sub if local directories + if test ${dirstatus[$counter]} = "local" + then +- $RCP $user.f $i:$DIR1/ ++ $RCP $user $i:$DIR1/ + fi + # do the compilation on the other machine + if test ${dirstatus[$counter]} = "shared" +@@ -3569,21 +3516,21 @@ + remoteuser=$DIR1/`$BASENAME $user` + $RSH $i /bin/rm $remoteprog 2> /dev/null + echo +- $RSH $i $DIR2/tools/comp_user $DIR2 $DIR1 $remoteuser $remoteprog ++ $RSH $i $DIR2/tools/comp_damask_hmp $DIR2 $DIR1 $remoteuser $remoteprog + # check if successful, the new executable should be there + line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` + if test "$line" + then + echo compilation and linking successful on host $i + else +- echo "$0: compile failed for $user.f on host $i" ++ echo "$0: compile failed for $user on host $i" + echo " $PRODUCT Exit number 3" + exit 1 + fi + # remove the user subroutine on remote machine + if test ${dirstatus[$counter]} = "local" + then +- $RSH $i /bin/rm $remoteuser.f 2> /dev/null ++ $RSH $i /bin/rm $remoteuser 2> /dev/null + fi + fi + fi +@@ -3593,39 +3540,27 @@ + if test "$userhost" + then + echo +- echo "Compiling and linking user subroutine $user.f on host `hostname`" +- fi +- userobj=$DIRJOB/`$BASENAME $user .f`.o +- basefile=`$BASENAME $usersubname` +- if test ${basefile##*.} = f +- then +- usersub=$DIRJOB/`$BASENAME $user .f`.F +- ln -sf "$user.f" "$usersub" +- else +- usersub=$usersubname ++ echo "Compiling and linking user subroutine $user on host `hostname`" + fi ++ userobj=$usernoext.o + if test $MACHINENAME = "CRAY" + then +- $FORTRAN $usersub || \ ++ $DFORTHIGHMP $user || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + echo " $PRODUCT Exit number 3" + exit 1 + } + /bin/rm $program 2>/dev/null + else +- $FORTRAN $usersub -o $userobj || \ ++ $DFORTHIGHMP $user -o $userobj || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + echo " $PRODUCT Exit number 3" + exit 1 + } + /bin/rm $program 2>/dev/null + fi +- if test ${basefile##*.} = f +- then +- /bin/rm -f "$usersub" +- fi + fi # if test $user + + +@@ -3645,6 +3580,7 @@ + $TKLIBS \ + $MRCLIBS \ + $METISLIBS \ ++ $DAMASK \ + $SFLIB \ + $OPENSSL_LIB \ + $SYSLIBS \ +@@ -3686,6 +3622,9 @@ + prgsav=yes + fi # if test $link + /bin/rm $userobj 2>/dev/null ++/bin/rm $DIRJOB/*.mod 2>/dev/null ++/bin/rm $DIRJOB/*.smod 2>/dev/null ++/bin/rm $DIRJOB/*_genmod.f90 2>/dev/null + + # + # run marc +@@ -3779,7 +3718,7 @@ + else + #dllrun >0 + if test $cpdll = yes; then +- filename=`basename $usersubname .f` ++ filename=$usernoext + /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null + fi + if test $rmdll = yes;then +@@ -3904,7 +3843,7 @@ + # first copy over the user sub if local directories + if test ${dirstatus[$counter]} = "local" + then +- $RCP $user.f $i:$DIR1/ ++ $RCP $user $i:$DIR1/ + fi + # do the compilation on the other machine + if test ${dirstatus[$counter]} = "shared" +@@ -3917,20 +3856,20 @@ + remoteuser=$DIR1/`$BASENAME $user` + $RSH $i /bin/rm $remoteprog 2> /dev/null + echo +- $RSH $i $DIR2/tools/comp_user $DIR2 $DIR1 $remoteuser $remoteprog ++ $RSH $i $DIR2/tools/comp_damask_hmp $DIR2 $DIR1 $remoteuser $remoteprog + # check if successful, the new executable should be there + line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` + if test "$line" + then + echo compilation and linking successful on host $i + else +- echo "$0: compile failed for $user.f on host $i" ++ echo "$0: compile failed for $user on host $i" + exit 1 + fi + # remove the user subroutine on remote machine + if test ${dirstatus[$counter]} = "local" + then +- $RSH $i /bin/rm $remoteuser.f 2> /dev/null ++ $RSH $i /bin/rm $remoteuser 2> /dev/null + fi + fi + fi +@@ -3940,37 +3879,25 @@ + if test "$userhost" + then + echo +- echo "Compiling and linking user subroutine $user.f on host `hostname`" +- fi +- userobj=$DIRJOB/`$BASENAME $user .f`.o +- basefile=`$BASENAME $usersubname` +- if test ${basefile##*.} = f +- then +- usersub=$DIRJOB/`$BASENAME $user .f`.F +- ln -sf "$user.f" "$usersub" +- else +- usersub=$usersubname ++ echo "Compiling and linking user subroutine $user on host `hostname`" + fi ++ userobj=$usernoext.o + if test $MACHINENAME = "CRAY" + then +- $FORTRAN $usersub || \ ++ $DFORTHIGHMP $user || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null + else +- $FORTRAN $usersub -o $userobj || \ ++ $DFORTHIGHMP $user -o $userobj || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null + fi +- if test ${basefile##*.} = f +- then +- /bin/rm -f "$usersub" +- fi + fi # if test $user + + +@@ -3990,6 +3917,7 @@ + $TKLIBS \ + $MRCLIBS \ + $METISLIBS \ ++ $DAMASK \ + $SFLIB \ + $OPENSSL_LIB \ + $SYSLIBS \ +@@ -4030,7 +3958,9 @@ + prgsav=yes + fi # if test $link + /bin/rm $userobj 2>/dev/null +- ++/bin/rm $DIRJOB/*.mod 2>/dev/null ++/bin/rm $DIRJOB/*.smod 2>/dev/null ++/bin/rm $DIRJOB/*_genmod.f90 2>/dev/null + # done if no job id given + if test -z "$jid" + then +@@ -4149,7 +4079,7 @@ + else + #dllrun >0 + if test $cpdll = yes; then +- filename=`basename $usersubname .f` ++ filename=$usernoext + /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null + fi + if test $rmdll = yes;then diff --git a/install/MarcMentat/2022.4/Marc_tools/run_damask_lmp.patch b/install/MarcMentat/2022.4/Marc_tools/run_damask_lmp.patch new file mode 100644 index 000000000..ae2dec9ab --- /dev/null +++ b/install/MarcMentat/2022.4/Marc_tools/run_damask_lmp.patch @@ -0,0 +1,517 @@ +--- ++++ +@@ -136,6 +136,11 @@ + # is created. For job running in the background, the log # + # file is always created. Default is "yes" # + ############################################################################## ++# remove all Mentat paths from LD_LIBRARY_PATH ++LD_LIBRARY_PATH=:$LD_LIBRARY_PATH: ++LD_LIBRARY_PATH=${LD_LIBRARY_PATH//+([!(:)])mentat2022.4+([!(:)])/:} ++LD_LIBRARY_PATH=${LD_LIBRARY_PATH//+([(:)])/:} ++LD_LIBRARY_PATH=${LD_LIBRARY_PATH#:}; LD_LIBRARY_PATH=${LD_LIBRARY_PATH%:} + # set DIR to the directory in which this script is + REALCOM="`/bin/ls -l $0 |awk '{ print $NF; }'`" + DIR=`dirname $REALCOM` +@@ -302,7 +307,23 @@ + + . "$DIR/getarch" + ++ ++# getting user subroutine file name ++found=0 ++for i in "$@"; do ++ if test $found = 1; then ++ DAMASK_USER=$i ++ found=0 ++ fi ++ case $i in ++ -u* | -U*) ++ found=1 ++ ;; ++ esac ++done ++# sourcing include_linux64 (needs DAMASK_USER to be set) + . $MARC_INCLUDE ++ + # + + # +@@ -405,7 +426,7 @@ + did= + vid= + user= +-usersubname= ++usernoext= + objs= + qid=background + cpu= +@@ -676,50 +697,19 @@ + esac + ;; + -u* | -U*) +- user=`dirname $value`/`$BASENAME $value .f` +- usersubname=$user +- basefile=`$BASENAME $value` +- if test ${basefile##*.} = f +- then +- user=`dirname $value`/`$BASENAME $value .f` +- usersubname=$user.f +- elif test ${basefile##*.} = F +- then +- user=`dirname $value`/`$BASENAME $value .F` +- usersubname=$user.F +- elif test ${basefile##*.} = f90 +- then +- user=`dirname $value`/`$BASENAME $value .f90` +- usersubname=$user.f90 +- elif test ${basefile##*.} = F90 +- then +- user=`dirname $value`/`$BASENAME $value .F90` +- usersubname=$user.F90 +- fi ++ user=$value + case $user in + \/*) + ;; + *) + user=`pwd`/$user +- usersubname=`pwd`/$usersubname + ;; + esac +- if test ! -f $usersubname +- then +- if test -f $usersubname.f +- then +- usersubname=$usersubname.f +- elif test -f $usersubname.F +- then +- usersubname=$usersubname.F +- elif test -f $usersubname.f90 +- then +- usersubname=$usersubname.f90 +- elif test -f $usersubname.F90 +- then +- usersubname=$usersubname.F90 +- fi +- fi ++ usernoext=$user ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` + ;; + -obj | -OBJ) + objs="$value" +@@ -1207,12 +1197,12 @@ + fi + fi + fi +- if test "$usersubname" ++ if test "$user" + then +- if test ! -f $usersubname ++ if test ! -f $user + then + error="$error +-user subroutine file $usersubname not accessible" ++user subroutine file $user not accessible" + fi + fi + if test "$objs" +@@ -1531,7 +1521,7 @@ + Marc shared lib : $progdll + Version type : $mode + Job ID : $DIRJID/$jid$extra_job_info +-User subroutine name : $usersubname ++User subroutine name : $user + User objects/libs : $objs + Restart file job ID : $rid + Substructure file ID : $sid +@@ -1564,7 +1554,7 @@ + Marc shared lib : $progdll + Version type : $mode + Job ID : $DIRJID/$jid$extra_job_info +-User subroutine name : $usersubname ++User subroutine name : $user + User objects/libs : $objs + Restart file job ID : $rid + Substructure file ID : $sid +@@ -1687,7 +1677,7 @@ + ;; + esac + fi +- $ECHO "User subroutine name ($usersubname)? $ECHOTXT" ++ $ECHO "User subroutine name ($user)? $ECHOTXT" + read value + if test "$value" + then +@@ -1696,50 +1686,19 @@ + user= + ;; + *) +- user=`dirname $value`/`$BASENAME $value .f` +- usersubname=$user +- basefile=`$BASENAME $value` +- if test ${basefile##*.} = f +- then +- user=`dirname $value`/`$BASENAME $value .f` +- usersubname=$user.f +- elif test ${basefile##*.} = F +- then +- user=`dirname $value`/`$BASENAME $value .F` +- usersubname=$user.F +- elif test ${basefile##*.} = f90 +- then +- user=`dirname $value`/`$BASENAME $value .f90` +- usersubname=$user.f90 +- elif test ${basefile##*.} = F90 +- then +- user=`dirname $value`/`$BASENAME $value .F90` +- usersubname=$user.F90 +- fi ++ user=$value + case $user in + \/*) + ;; + *) + user=`pwd`/$user +- usersubname=`pwd`/$usersubname + ;; + esac +- if test ! -f $usersubname +- then +- if test -f $usersubname.f +- then +- usersubname=$usersubname.f +- elif test -f $usersubname.F +- then +- usersubname=$usersubname.F +- elif test -f $usersubname.f90 +- then +- usersubname=$usersubname.f90 +- elif test -f $usersubname.F90 +- then +- usersubname=$usersubname.F90 +- fi +- fi ++ usernoext=$user ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` + ;; + esac + fi +@@ -2274,11 +2233,12 @@ + # + # user subroutine used + # ++# add DAMASK options for linking ++ DAMASK="-lstdc++" + + if test "$user" + then +-# program=$user.marc +- program=$DIRJOB/`$BASENAME $user .f`.marc ++ program=$usernoext.marc + case $program in + \/* | \.\/*) + bd= +@@ -2391,7 +2351,7 @@ + fi + if test "$user" + then +- execpath=$DIRJOB/`$BASENAME $user .f`.marc ++ execpath=$usernoext.marc + usersub=1 + fi + export execpath +@@ -3274,44 +3234,27 @@ + echo + if test "$user" + then +- userobj=$DIRJOB/`$BASENAME $user .f`.o +- basefile=`$BASENAME $usersubname` +- if test ${basefile##*.} = f +- then +- usersub=$DIRJOB/`$BASENAME $user .f`.F +- ln -sf "$user.f" "$usersub" +- else +- usersub=$usersubname +- fi +- ++ userobj=$usernoext.o + fi + cat > $jid.runmarcscript << END4 + if test "$user" + then +- if test ${basefile##*.} = f +- then +- ln -sf "$user.f" "$usersub" +- fi + if test $MACHINENAME = "CRAY" + then +- $FORTRAN $usersub || \ ++ $DFORTLOWMP $user || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null + else +- $FORTRAN $usersub -o $userobj || \ ++ $DFORTLOWMP $user -o $userobj || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null + fi +- if test ${basefile##*.} = f +- then +- /bin/rm -f "$usersub" +- fi + fi + + +@@ -3331,6 +3274,7 @@ + $TKLIBS \ + $MRCLIBS \ + $METISLIBS \ ++ $DAMASK \ + $SFLIB \ + $OPENSSL_LIB \ + $SYSLIBS \ +@@ -3344,6 +3288,9 @@ + prgsav=yes + fi + /bin/rm $userobj 2>/dev/null ++/bin/rm $DIRJOB/*.mod 2>/dev/null ++/bin/rm $DIRJOB/*.smod 2>/dev/null ++/bin/rm $DIRJOB/*_genmod.f90 2>/dev/null + + # + # run marc +@@ -3390,7 +3337,7 @@ + fi + else + if test $cpdll = yes; then +- filename=`basename $usersubname .f` ++ filename=$usernoext + /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null + fi + if test $rmdll = yes +@@ -3556,7 +3503,7 @@ + # first copy over the user sub if local directories + if test ${dirstatus[$counter]} = "local" + then +- $RCP $user.f $i:$DIR1/ ++ $RCP $user $i:$DIR1/ + fi + # do the compilation on the other machine + if test ${dirstatus[$counter]} = "shared" +@@ -3569,21 +3516,21 @@ + remoteuser=$DIR1/`$BASENAME $user` + $RSH $i /bin/rm $remoteprog 2> /dev/null + echo +- $RSH $i $DIR2/tools/comp_user $DIR2 $DIR1 $remoteuser $remoteprog ++ $RSH $i $DIR2/tools/comp_damask_lmp $DIR2 $DIR1 $remoteuser $remoteprog + # check if successful, the new executable should be there + line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` + if test "$line" + then + echo compilation and linking successful on host $i + else +- echo "$0: compile failed for $user.f on host $i" ++ echo "$0: compile failed for $user on host $i" + echo " $PRODUCT Exit number 3" + exit 1 + fi + # remove the user subroutine on remote machine + if test ${dirstatus[$counter]} = "local" + then +- $RSH $i /bin/rm $remoteuser.f 2> /dev/null ++ $RSH $i /bin/rm $remoteuser 2> /dev/null + fi + fi + fi +@@ -3593,39 +3540,27 @@ + if test "$userhost" + then + echo +- echo "Compiling and linking user subroutine $user.f on host `hostname`" +- fi +- userobj=$DIRJOB/`$BASENAME $user .f`.o +- basefile=`$BASENAME $usersubname` +- if test ${basefile##*.} = f +- then +- usersub=$DIRJOB/`$BASENAME $user .f`.F +- ln -sf "$user.f" "$usersub" +- else +- usersub=$usersubname ++ echo "Compiling and linking user subroutine $user on host `hostname`" + fi ++ userobj=$usernoext.o + if test $MACHINENAME = "CRAY" + then +- $FORTRAN $usersub || \ ++ $DFORTLOWMP $user || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + echo " $PRODUCT Exit number 3" + exit 1 + } + /bin/rm $program 2>/dev/null + else +- $FORTRAN $usersub -o $userobj || \ ++ $DFORTLOWMP $user -o $userobj || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + echo " $PRODUCT Exit number 3" + exit 1 + } + /bin/rm $program 2>/dev/null + fi +- if test ${basefile##*.} = f +- then +- /bin/rm -f "$usersub" +- fi + fi # if test $user + + +@@ -3645,6 +3580,7 @@ + $TKLIBS \ + $MRCLIBS \ + $METISLIBS \ ++ $DAMASK \ + $SFLIB \ + $OPENSSL_LIB \ + $SYSLIBS \ +@@ -3686,6 +3622,9 @@ + prgsav=yes + fi # if test $link + /bin/rm $userobj 2>/dev/null ++/bin/rm $DIRJOB/*.mod 2>/dev/null ++/bin/rm $DIRJOB/*.smod 2>/dev/null ++/bin/rm $DIRJOB/*_genmod.f90 2>/dev/null + + # + # run marc +@@ -3779,7 +3718,7 @@ + else + #dllrun >0 + if test $cpdll = yes; then +- filename=`basename $usersubname .f` ++ filename=$usernoext + /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null + fi + if test $rmdll = yes;then +@@ -3904,7 +3843,7 @@ + # first copy over the user sub if local directories + if test ${dirstatus[$counter]} = "local" + then +- $RCP $user.f $i:$DIR1/ ++ $RCP $user $i:$DIR1/ + fi + # do the compilation on the other machine + if test ${dirstatus[$counter]} = "shared" +@@ -3917,20 +3856,20 @@ + remoteuser=$DIR1/`$BASENAME $user` + $RSH $i /bin/rm $remoteprog 2> /dev/null + echo +- $RSH $i $DIR2/tools/comp_user $DIR2 $DIR1 $remoteuser $remoteprog ++ $RSH $i $DIR2/tools/comp_damask_lmp $DIR2 $DIR1 $remoteuser $remoteprog + # check if successful, the new executable should be there + line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` + if test "$line" + then + echo compilation and linking successful on host $i + else +- echo "$0: compile failed for $user.f on host $i" ++ echo "$0: compile failed for $user on host $i" + exit 1 + fi + # remove the user subroutine on remote machine + if test ${dirstatus[$counter]} = "local" + then +- $RSH $i /bin/rm $remoteuser.f 2> /dev/null ++ $RSH $i /bin/rm $remoteuser 2> /dev/null + fi + fi + fi +@@ -3940,37 +3879,25 @@ + if test "$userhost" + then + echo +- echo "Compiling and linking user subroutine $user.f on host `hostname`" +- fi +- userobj=$DIRJOB/`$BASENAME $user .f`.o +- basefile=`$BASENAME $usersubname` +- if test ${basefile##*.} = f +- then +- usersub=$DIRJOB/`$BASENAME $user .f`.F +- ln -sf "$user.f" "$usersub" +- else +- usersub=$usersubname ++ echo "Compiling and linking user subroutine $user on host `hostname`" + fi ++ userobj=$usernoext.o + if test $MACHINENAME = "CRAY" + then +- $FORTRAN $usersub || \ ++ $DFORTLOWMP $user || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null + else +- $FORTRAN $usersub -o $userobj || \ ++ $DFORTLOWMP $user -o $userobj || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null + fi +- if test ${basefile##*.} = f +- then +- /bin/rm -f "$usersub" +- fi + fi # if test $user + + +@@ -3990,6 +3917,7 @@ + $TKLIBS \ + $MRCLIBS \ + $METISLIBS \ ++ $DAMASK \ + $SFLIB \ + $OPENSSL_LIB \ + $SYSLIBS \ +@@ -4030,7 +3958,9 @@ + prgsav=yes + fi # if test $link + /bin/rm $userobj 2>/dev/null +- ++/bin/rm $DIRJOB/*.mod 2>/dev/null ++/bin/rm $DIRJOB/*.smod 2>/dev/null ++/bin/rm $DIRJOB/*_genmod.f90 2>/dev/null + # done if no job id given + if test -z "$jid" + then +@@ -4149,7 +4079,7 @@ + else + #dllrun >0 + if test $cpdll = yes; then +- filename=`basename $usersubname .f` ++ filename=$usernoext + /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null + fi + if test $rmdll = yes;then diff --git a/install/MarcMentat/2022.4/Marc_tools/run_damask_mp.patch b/install/MarcMentat/2022.4/Marc_tools/run_damask_mp.patch new file mode 100644 index 000000000..982bdd603 --- /dev/null +++ b/install/MarcMentat/2022.4/Marc_tools/run_damask_mp.patch @@ -0,0 +1,517 @@ +--- ++++ +@@ -136,6 +136,11 @@ + # is created. For job running in the background, the log # + # file is always created. Default is "yes" # + ############################################################################## ++# remove all Mentat paths from LD_LIBRARY_PATH ++LD_LIBRARY_PATH=:$LD_LIBRARY_PATH: ++LD_LIBRARY_PATH=${LD_LIBRARY_PATH//+([!(:)])mentat2022.4+([!(:)])/:} ++LD_LIBRARY_PATH=${LD_LIBRARY_PATH//+([(:)])/:} ++LD_LIBRARY_PATH=${LD_LIBRARY_PATH#:}; LD_LIBRARY_PATH=${LD_LIBRARY_PATH%:} + # set DIR to the directory in which this script is + REALCOM="`/bin/ls -l $0 |awk '{ print $NF; }'`" + DIR=`dirname $REALCOM` +@@ -302,7 +307,23 @@ + + . "$DIR/getarch" + ++ ++# getting user subroutine file name ++found=0 ++for i in "$@"; do ++ if test $found = 1; then ++ DAMASK_USER=$i ++ found=0 ++ fi ++ case $i in ++ -u* | -U*) ++ found=1 ++ ;; ++ esac ++done ++# sourcing include_linux64 (needs DAMASK_USER to be set) + . $MARC_INCLUDE ++ + # + + # +@@ -405,7 +426,7 @@ + did= + vid= + user= +-usersubname= ++usernoext= + objs= + qid=background + cpu= +@@ -676,50 +697,19 @@ + esac + ;; + -u* | -U*) +- user=`dirname $value`/`$BASENAME $value .f` +- usersubname=$user +- basefile=`$BASENAME $value` +- if test ${basefile##*.} = f +- then +- user=`dirname $value`/`$BASENAME $value .f` +- usersubname=$user.f +- elif test ${basefile##*.} = F +- then +- user=`dirname $value`/`$BASENAME $value .F` +- usersubname=$user.F +- elif test ${basefile##*.} = f90 +- then +- user=`dirname $value`/`$BASENAME $value .f90` +- usersubname=$user.f90 +- elif test ${basefile##*.} = F90 +- then +- user=`dirname $value`/`$BASENAME $value .F90` +- usersubname=$user.F90 +- fi ++ user=$value + case $user in + \/*) + ;; + *) + user=`pwd`/$user +- usersubname=`pwd`/$usersubname + ;; + esac +- if test ! -f $usersubname +- then +- if test -f $usersubname.f +- then +- usersubname=$usersubname.f +- elif test -f $usersubname.F +- then +- usersubname=$usersubname.F +- elif test -f $usersubname.f90 +- then +- usersubname=$usersubname.f90 +- elif test -f $usersubname.F90 +- then +- usersubname=$usersubname.F90 +- fi +- fi ++ usernoext=$user ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` + ;; + -obj | -OBJ) + objs="$value" +@@ -1207,12 +1197,12 @@ + fi + fi + fi +- if test "$usersubname" ++ if test "$user" + then +- if test ! -f $usersubname ++ if test ! -f $user + then + error="$error +-user subroutine file $usersubname not accessible" ++user subroutine file $user not accessible" + fi + fi + if test "$objs" +@@ -1531,7 +1521,7 @@ + Marc shared lib : $progdll + Version type : $mode + Job ID : $DIRJID/$jid$extra_job_info +-User subroutine name : $usersubname ++User subroutine name : $user + User objects/libs : $objs + Restart file job ID : $rid + Substructure file ID : $sid +@@ -1564,7 +1554,7 @@ + Marc shared lib : $progdll + Version type : $mode + Job ID : $DIRJID/$jid$extra_job_info +-User subroutine name : $usersubname ++User subroutine name : $user + User objects/libs : $objs + Restart file job ID : $rid + Substructure file ID : $sid +@@ -1687,7 +1677,7 @@ + ;; + esac + fi +- $ECHO "User subroutine name ($usersubname)? $ECHOTXT" ++ $ECHO "User subroutine name ($user)? $ECHOTXT" + read value + if test "$value" + then +@@ -1696,50 +1686,19 @@ + user= + ;; + *) +- user=`dirname $value`/`$BASENAME $value .f` +- usersubname=$user +- basefile=`$BASENAME $value` +- if test ${basefile##*.} = f +- then +- user=`dirname $value`/`$BASENAME $value .f` +- usersubname=$user.f +- elif test ${basefile##*.} = F +- then +- user=`dirname $value`/`$BASENAME $value .F` +- usersubname=$user.F +- elif test ${basefile##*.} = f90 +- then +- user=`dirname $value`/`$BASENAME $value .f90` +- usersubname=$user.f90 +- elif test ${basefile##*.} = F90 +- then +- user=`dirname $value`/`$BASENAME $value .F90` +- usersubname=$user.F90 +- fi ++ user=$value + case $user in + \/*) + ;; + *) + user=`pwd`/$user +- usersubname=`pwd`/$usersubname + ;; + esac +- if test ! -f $usersubname +- then +- if test -f $usersubname.f +- then +- usersubname=$usersubname.f +- elif test -f $usersubname.F +- then +- usersubname=$usersubname.F +- elif test -f $usersubname.f90 +- then +- usersubname=$usersubname.f90 +- elif test -f $usersubname.F90 +- then +- usersubname=$usersubname.F90 +- fi +- fi ++ usernoext=$user ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .F` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .for` ++ usernoext=`dirname $usernoext`/`$BASENAME $usernoext .f90` + ;; + esac + fi +@@ -2274,11 +2233,12 @@ + # + # user subroutine used + # ++# add DAMASK options for linking ++ DAMASK="-lstdc++" + + if test "$user" + then +-# program=$user.marc +- program=$DIRJOB/`$BASENAME $user .f`.marc ++ program=$usernoext.marc + case $program in + \/* | \.\/*) + bd= +@@ -2391,7 +2351,7 @@ + fi + if test "$user" + then +- execpath=$DIRJOB/`$BASENAME $user .f`.marc ++ execpath=$usernoext.marc + usersub=1 + fi + export execpath +@@ -3274,44 +3234,27 @@ + echo + if test "$user" + then +- userobj=$DIRJOB/`$BASENAME $user .f`.o +- basefile=`$BASENAME $usersubname` +- if test ${basefile##*.} = f +- then +- usersub=$DIRJOB/`$BASENAME $user .f`.F +- ln -sf "$user.f" "$usersub" +- else +- usersub=$usersubname +- fi +- ++ userobj=$usernoext.o + fi + cat > $jid.runmarcscript << END4 + if test "$user" + then +- if test ${basefile##*.} = f +- then +- ln -sf "$user.f" "$usersub" +- fi + if test $MACHINENAME = "CRAY" + then +- $FORTRAN $usersub || \ ++ $DFORTRANMP $user || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null + else +- $FORTRAN $usersub -o $userobj || \ ++ $DFORTRANMP $user -o $userobj || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null + fi +- if test ${basefile##*.} = f +- then +- /bin/rm -f "$usersub" +- fi + fi + + +@@ -3331,6 +3274,7 @@ + $TKLIBS \ + $MRCLIBS \ + $METISLIBS \ ++ $DAMASK \ + $SFLIB \ + $OPENSSL_LIB \ + $SYSLIBS \ +@@ -3344,6 +3288,9 @@ + prgsav=yes + fi + /bin/rm $userobj 2>/dev/null ++/bin/rm $DIRJOB/*.mod 2>/dev/null ++/bin/rm $DIRJOB/*.smod 2>/dev/null ++/bin/rm $DIRJOB/*_genmod.f90 2>/dev/null + + # + # run marc +@@ -3390,7 +3337,7 @@ + fi + else + if test $cpdll = yes; then +- filename=`basename $usersubname .f` ++ filename=$usernoext + /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null + fi + if test $rmdll = yes +@@ -3556,7 +3503,7 @@ + # first copy over the user sub if local directories + if test ${dirstatus[$counter]} = "local" + then +- $RCP $user.f $i:$DIR1/ ++ $RCP $user $i:$DIR1/ + fi + # do the compilation on the other machine + if test ${dirstatus[$counter]} = "shared" +@@ -3569,21 +3516,21 @@ + remoteuser=$DIR1/`$BASENAME $user` + $RSH $i /bin/rm $remoteprog 2> /dev/null + echo +- $RSH $i $DIR2/tools/comp_user $DIR2 $DIR1 $remoteuser $remoteprog ++ $RSH $i $DIR2/tools/comp_damask_mp $DIR2 $DIR1 $remoteuser $remoteprog + # check if successful, the new executable should be there + line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` + if test "$line" + then + echo compilation and linking successful on host $i + else +- echo "$0: compile failed for $user.f on host $i" ++ echo "$0: compile failed for $user on host $i" + echo " $PRODUCT Exit number 3" + exit 1 + fi + # remove the user subroutine on remote machine + if test ${dirstatus[$counter]} = "local" + then +- $RSH $i /bin/rm $remoteuser.f 2> /dev/null ++ $RSH $i /bin/rm $remoteuser 2> /dev/null + fi + fi + fi +@@ -3593,39 +3540,27 @@ + if test "$userhost" + then + echo +- echo "Compiling and linking user subroutine $user.f on host `hostname`" +- fi +- userobj=$DIRJOB/`$BASENAME $user .f`.o +- basefile=`$BASENAME $usersubname` +- if test ${basefile##*.} = f +- then +- usersub=$DIRJOB/`$BASENAME $user .f`.F +- ln -sf "$user.f" "$usersub" +- else +- usersub=$usersubname ++ echo "Compiling and linking user subroutine $user on host `hostname`" + fi ++ userobj=$usernoext.o + if test $MACHINENAME = "CRAY" + then +- $FORTRAN $usersub || \ ++ $DFORTRANMP $user || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + echo " $PRODUCT Exit number 3" + exit 1 + } + /bin/rm $program 2>/dev/null + else +- $FORTRAN $usersub -o $userobj || \ ++ $DFORTRANMP $user -o $userobj || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + echo " $PRODUCT Exit number 3" + exit 1 + } + /bin/rm $program 2>/dev/null + fi +- if test ${basefile##*.} = f +- then +- /bin/rm -f "$usersub" +- fi + fi # if test $user + + +@@ -3645,6 +3580,7 @@ + $TKLIBS \ + $MRCLIBS \ + $METISLIBS \ ++ $DAMASK \ + $SFLIB \ + $OPENSSL_LIB \ + $SYSLIBS \ +@@ -3686,6 +3622,9 @@ + prgsav=yes + fi # if test $link + /bin/rm $userobj 2>/dev/null ++/bin/rm $DIRJOB/*.mod 2>/dev/null ++/bin/rm $DIRJOB/*.smod 2>/dev/null ++/bin/rm $DIRJOB/*_genmod.f90 2>/dev/null + + # + # run marc +@@ -3779,7 +3718,7 @@ + else + #dllrun >0 + if test $cpdll = yes; then +- filename=`basename $usersubname .f` ++ filename=$usernoext + /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null + fi + if test $rmdll = yes;then +@@ -3904,7 +3843,7 @@ + # first copy over the user sub if local directories + if test ${dirstatus[$counter]} = "local" + then +- $RCP $user.f $i:$DIR1/ ++ $RCP $user $i:$DIR1/ + fi + # do the compilation on the other machine + if test ${dirstatus[$counter]} = "shared" +@@ -3917,20 +3856,20 @@ + remoteuser=$DIR1/`$BASENAME $user` + $RSH $i /bin/rm $remoteprog 2> /dev/null + echo +- $RSH $i $DIR2/tools/comp_user $DIR2 $DIR1 $remoteuser $remoteprog ++ $RSH $i $DIR2/tools/comp_damask_mp $DIR2 $DIR1 $remoteuser $remoteprog + # check if successful, the new executable should be there + line=`$RSH $i /bin/ls $remoteprog 2> /dev/null` + if test "$line" + then + echo compilation and linking successful on host $i + else +- echo "$0: compile failed for $user.f on host $i" ++ echo "$0: compile failed for $user on host $i" + exit 1 + fi + # remove the user subroutine on remote machine + if test ${dirstatus[$counter]} = "local" + then +- $RSH $i /bin/rm $remoteuser.f 2> /dev/null ++ $RSH $i /bin/rm $remoteuser 2> /dev/null + fi + fi + fi +@@ -3940,37 +3879,25 @@ + if test "$userhost" + then + echo +- echo "Compiling and linking user subroutine $user.f on host `hostname`" +- fi +- userobj=$DIRJOB/`$BASENAME $user .f`.o +- basefile=`$BASENAME $usersubname` +- if test ${basefile##*.} = f +- then +- usersub=$DIRJOB/`$BASENAME $user .f`.F +- ln -sf "$user.f" "$usersub" +- else +- usersub=$usersubname ++ echo "Compiling and linking user subroutine $user on host `hostname`" + fi ++ userobj=$usernoext.o + if test $MACHINENAME = "CRAY" + then +- $FORTRAN $usersub || \ ++ $DFORTRANMP $user || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null + else +- $FORTRAN $usersub -o $userobj || \ ++ $DFORTRANMP $user -o $userobj || \ + { +- echo "$0: compile failed for $user.f" ++ echo "$0: compile failed for $user" + exit 1 + } + /bin/rm $program 2>/dev/null + fi +- if test ${basefile##*.} = f +- then +- /bin/rm -f "$usersub" +- fi + fi # if test $user + + +@@ -3990,6 +3917,7 @@ + $TKLIBS \ + $MRCLIBS \ + $METISLIBS \ ++ $DAMASK \ + $SFLIB \ + $OPENSSL_LIB \ + $SYSLIBS \ +@@ -4030,7 +3958,9 @@ + prgsav=yes + fi # if test $link + /bin/rm $userobj 2>/dev/null +- ++/bin/rm $DIRJOB/*.mod 2>/dev/null ++/bin/rm $DIRJOB/*.smod 2>/dev/null ++/bin/rm $DIRJOB/*_genmod.f90 2>/dev/null + # done if no job id given + if test -z "$jid" + then +@@ -4149,7 +4079,7 @@ + else + #dllrun >0 + if test $cpdll = yes; then +- filename=`basename $usersubname .f` ++ filename=$usernoext + /bin/cp $DIRJOB/$marcdll $DIRJOB/${filename}_$marcdll 2>/dev/null + fi + if test $rmdll = yes;then diff --git a/install/MarcMentat/2022.4/Mentat_bin/edit_window.patch b/install/MarcMentat/2022.4/Mentat_bin/edit_window.patch new file mode 100644 index 000000000..915af9bf6 --- /dev/null +++ b/install/MarcMentat/2022.4/Mentat_bin/edit_window.patch @@ -0,0 +1,24 @@ +--- ++++ +@@ -1,18 +1,5 @@ + #!/bin/sh +-# This script opens a window running an editor. The default window is an +-# xterm, and the default editor is vi. These may be customized. ++# This script opens a window running an editor. ++# The command to invoke the editor is specified during DAMASK installation + +-dir= +-for d in /usr/bin /usr/bin/X11; do +- if test -x "$d/xterm"; then +- dir="$d" +- break +- fi +-done +- +-if test -z "$dir"; then +- echo "$0: Could not find xterm" +- exit 1 +-fi +- +-"$dir/xterm" -T "vi $*" -n "vi $*" -e vi $* ++%EDITOR% $* diff --git a/install/MarcMentat/2022.4/Mentat_bin/kill4.patch b/install/MarcMentat/2022.4/Mentat_bin/kill4.patch new file mode 100644 index 000000000..e69de29bb diff --git a/install/MarcMentat/2022.4/Mentat_bin/kill5.patch b/install/MarcMentat/2022.4/Mentat_bin/kill5.patch new file mode 100644 index 000000000..e69de29bb diff --git a/install/MarcMentat/2022.4/Mentat_bin/kill6.patch b/install/MarcMentat/2022.4/Mentat_bin/kill6.patch new file mode 100644 index 000000000..e69de29bb diff --git a/install/MarcMentat/2022.4/Mentat_bin/submit4.patch b/install/MarcMentat/2022.4/Mentat_bin/submit4.patch new file mode 100644 index 000000000..98c51e76d --- /dev/null +++ b/install/MarcMentat/2022.4/Mentat_bin/submit4.patch @@ -0,0 +1,38 @@ +--- ++++ +@@ -63,10 +63,10 @@ + if [ "$slv" != "" -a "$slv" != "marc" -a "$slv" != "datfit" ]; then + slv="-iam sfm" + fi +-if [ "$slv" == "marc" ]; then ++if [ "$slv" = "marc" ]; then + slv="" + fi +-if [ "$slv" == "datfit" ]; then ++if [ "$slv" = "datfit" ]; then + slv="-iam datfit" + fi + +@@ -91,6 +91,7 @@ + srcfile="-u $srcfile -save y" + ;; + runsaved) ++ srcfile=${srcfile%.*}".marc" + srcfile="-prog $srcfile" + ;; + esac +@@ -189,12 +190,12 @@ + unset PYTHONPATH + + if [ "$doe_first" = "-" ]; then # submit of regular Marc job +- "${DIR}/tools/run_marc" $slv -j $job -v n -b y $nprocds $nprocd \ ++ "${DIR}/tools/run_damask_hmp" $slv -j $job -v n -b y $nprocds $nprocd \ + $srcfile $restart $postfile $viewfactorsfile $hostfile \ + $compat $copy_datfile $copy_postfile $scr_dir $dcoup \ + $assem_recov_nthread $nthread $nsolver $mode $gpu > /dev/null 2>&1 + else # submit of a DoE Marc job +- "${DIR}/tools/run_marc" $slv -j $job -v n -b n $nprocds $nprocd \ ++ "${DIR}/tools/run_damask_hmp" $slv -j $job -v n -b n $nprocds $nprocd \ + $srcfile $restart $postfile $viewfactorsfile $hostfile \ + $compat $copy_datfile $copy_postfile $scr_dir $dcoup \ + $assem_recov_nthread $nthread $nsolver $mode $gpu diff --git a/install/MarcMentat/2022.4/Mentat_bin/submit5.patch b/install/MarcMentat/2022.4/Mentat_bin/submit5.patch new file mode 100644 index 000000000..ab32b1058 --- /dev/null +++ b/install/MarcMentat/2022.4/Mentat_bin/submit5.patch @@ -0,0 +1,38 @@ +--- ++++ +@@ -63,10 +63,10 @@ + if [ "$slv" != "" -a "$slv" != "marc" -a "$slv" != "datfit" ]; then + slv="-iam sfm" + fi +-if [ "$slv" == "marc" ]; then ++if [ "$slv" = "marc" ]; then + slv="" + fi +-if [ "$slv" == "datfit" ]; then ++if [ "$slv" = "datfit" ]; then + slv="-iam datfit" + fi + +@@ -91,6 +91,7 @@ + srcfile="-u $srcfile -save y" + ;; + runsaved) ++ srcfile=${srcfile%.*}".marc" + srcfile="-prog $srcfile" + ;; + esac +@@ -189,12 +190,12 @@ + unset PYTHONPATH + + if [ "$doe_first" = "-" ]; then # submit of regular Marc job +- "${DIR}/tools/run_marc" $slv -j $job -v n -b y $nprocds $nprocd \ ++ "${DIR}/tools/run_damask_mp" $slv -j $job -v n -b y $nprocds $nprocd \ + $srcfile $restart $postfile $viewfactorsfile $hostfile \ + $compat $copy_datfile $copy_postfile $scr_dir $dcoup \ + $assem_recov_nthread $nthread $nsolver $mode $gpu > /dev/null 2>&1 + else # submit of a DoE Marc job +- "${DIR}/tools/run_marc" $slv -j $job -v n -b n $nprocds $nprocd \ ++ "${DIR}/tools/run_damask_mp" $slv -j $job -v n -b n $nprocds $nprocd \ + $srcfile $restart $postfile $viewfactorsfile $hostfile \ + $compat $copy_datfile $copy_postfile $scr_dir $dcoup \ + $assem_recov_nthread $nthread $nsolver $mode $gpu diff --git a/install/MarcMentat/2022.4/Mentat_bin/submit6.patch b/install/MarcMentat/2022.4/Mentat_bin/submit6.patch new file mode 100644 index 000000000..d5ea3cfde --- /dev/null +++ b/install/MarcMentat/2022.4/Mentat_bin/submit6.patch @@ -0,0 +1,38 @@ +--- ++++ +@@ -63,10 +63,10 @@ + if [ "$slv" != "" -a "$slv" != "marc" -a "$slv" != "datfit" ]; then + slv="-iam sfm" + fi +-if [ "$slv" == "marc" ]; then ++if [ "$slv" = "marc" ]; then + slv="" + fi +-if [ "$slv" == "datfit" ]; then ++if [ "$slv" = "datfit" ]; then + slv="-iam datfit" + fi + +@@ -91,6 +91,7 @@ + srcfile="-u $srcfile -save y" + ;; + runsaved) ++ srcfile=${srcfile%.*}".marc" + srcfile="-prog $srcfile" + ;; + esac +@@ -189,12 +190,12 @@ + unset PYTHONPATH + + if [ "$doe_first" = "-" ]; then # submit of regular Marc job +- "${DIR}/tools/run_marc" $slv -j $job -v n -b y $nprocds $nprocd \ ++ "${DIR}/tools/run_damask_lmp" $slv -j $job -v n -b y $nprocds $nprocd \ + $srcfile $restart $postfile $viewfactorsfile $hostfile \ + $compat $copy_datfile $copy_postfile $scr_dir $dcoup \ + $assem_recov_nthread $nthread $nsolver $mode $gpu > /dev/null 2>&1 + else # submit of a DoE Marc job +- "${DIR}/tools/run_marc" $slv -j $job -v n -b n $nprocds $nprocd \ ++ "${DIR}/tools/run_damask_lmp" $slv -j $job -v n -b n $nprocds $nprocd \ + $srcfile $restart $postfile $viewfactorsfile $hostfile \ + $compat $copy_datfile $copy_postfile $scr_dir $dcoup \ + $assem_recov_nthread $nthread $nsolver $mode $gpu diff --git a/install/MarcMentat/2022.4/Mentat_menus/job_run.ms.patch b/install/MarcMentat/2022.4/Mentat_menus/job_run.ms.patch new file mode 100644 index 000000000..9296e96d8 --- /dev/null +++ b/install/MarcMentat/2022.4/Mentat_menus/job_run.ms.patch @@ -0,0 +1,158 @@ +--- ++++ +@@ -261,11 +261,18 @@ + } + button { + position +25 = +- size 25 4 ++ size 18 4 + text "ADVANCED JOB SUBMISSION" + help "job_run#Job Submission And Control" + popmenu job_submit_adv_pm + } ++ button { ++ position +18 = ++ size 7 4 ++ text "DAMASK" ++ help "damask_run#Job Submission And Control" ++ popmenu damask ++ } + button { + position 0 +4 + size 16 4 +@@ -1211,6 +1218,135 @@ + } + + ++#-------------------------------------------------------------------------------------------------- ++popmenu damask { ++ ++#ifdef QT_MENTAT ++ text "DAMASK.MPIE.DE" ++#endif ++ ++ group { ++#ifndef QT_MENTAT ++ label { ++ position 0 0 ++ size 50 4 ++ text "DAMASK.MPIE.DE" ++ } ++#endif ++ ++ label { ++ position 1 6 ++ size 13 6 ++ text "Optimzation" ++ border_width 1 ++ border_color black ++ } ++ ++ label { ++ position +13 = ++ size 20 6 ++ text "write Input" ++ border_width 1 ++ border_color black ++ } ++ ++ label { ++ position +18 = ++ size 30 6 ++ text "do not write Inp." ++ border_width 1 ++ border_color black ++ } ++ ++ label { ++ position -32 +6 ++ size 12 6 ++ text "O3 / OpenMP" ++ border_width 1 ++ border_color black ++ } ++ ++ popdown { ++ position +12 = ++ size 20 6 ++ text "Submit" ++ command "*submit_job 4 *monitor_job" ++ } ++ ++ popdown { ++ position +20 = ++ size 20 6 ++ text "Execute" ++ command "*execute_job 4 *monitor_job" ++ } ++ ++ label { ++ position -32 +6 ++ size 12 6 ++ text "O1 / OpenMP" ++ border_width 1 ++ border_color black ++ } ++ ++ popdown { ++ position +12 = ++ size 20 6 ++ text "Submit" ++ command "*submit_job 5 *monitor_job" ++ } ++ ++ popdown { ++ position +20 = ++ size 20 6 ++ text "Execute" ++ command "*execute_job 5 *monitor_job" ++ } ++ ++ label { ++ position -32 +6 ++ size 12 6 ++ text "O0 / OpenMP" ++ border_width 1 ++ border_color black ++ } ++ ++ popdown { ++ position +12 = ++ size 20 6 ++ text "Submit" ++ command "*submit_job 6 *monitor_job" ++ } ++ ++ popdown { ++ position +20 = ++ size 20 6 ++ text "Execute" ++ command "*execute_job 6 *monitor_job" ++ } ++ ++ popdown { ++ position 19 +8 ++ size 12 8 ++ text "CANCEL" ++ } ++} ++ ++ window { ++ parent mentat ++ origin 38 8 ++#ifdef DCOM ++ size 50 100 ++#else ++ size 50 94 ++#endif ++ background_color body ++ border_width 1 ++ border_color border ++ buffering single ++ } ++ mode permanent ++} ++ + #-------------------------------------------------------------------------------------------------- + popmenu job_exit_msg_pm { + diff --git a/install/MarcMentat/apply_DAMASK_modifications.py b/install/MarcMentat/MSC_modifications.py similarity index 50% rename from install/MarcMentat/apply_DAMASK_modifications.py rename to install/MarcMentat/MSC_modifications.py index 353df955e..689d49b2a 100755 --- a/install/MarcMentat/apply_DAMASK_modifications.py +++ b/install/MarcMentat/MSC_modifications.py @@ -9,9 +9,12 @@ from pathlib import Path import subprocess import shlex -sys.path.append(str(Path(__file__).parents[2]/'python/damask')) +sys.path.append(str(Path(__file__).resolve().parents[2]/'python/damask')) import solver +APPLY = 'install' +RESTORE = 'uninstall' + def copy_and_patch(patch,orig,editor): try: shutil.copyfile(orig,orig.parent/patch.stem) @@ -25,9 +28,11 @@ def copy_and_patch(patch,orig,editor): parser = argparse.ArgumentParser( - description='Apply DAMASK modification to MSC Marc/Mentat', + description=f'{APPLY.capitalize()} or {RESTORE} DAMASK modifications to MSC Marc/Mentat', formatter_class=argparse.ArgumentDefaultsHelpFormatter) +parser.add_argument('command', metavar='command', nargs='?', default=APPLY, choices=[APPLY,RESTORE], + help=f'Mode of operation {[APPLY,RESTORE]}') parser.add_argument('--editor', dest='editor', metavar='string', default='vi', help='Name of the editor (executable) used by Marc Mentat') parser.add_argument('--marc-root', dest='marc_root', metavar='string', @@ -40,10 +45,10 @@ parser.add_argument('--damask-root', dest='damask_root', metavar = 'string', default=solver._marc._damask_root, help='DAMASK root directory') - args = parser.parse_args() -marc_root = Path(args.marc_root).expanduser() -damask_root = Path(args.damask_root).expanduser() + +damask_root = Path(args.damask_root).expanduser() +marc_root = Path(args.marc_root).expanduser() marc_version = args.marc_version matches = {'Marc_tools': [['comp_user','comp_damask_*mp'], @@ -54,22 +59,40 @@ matches = {'Marc_tools': [['comp_user','comp_damask_*mp'], ['kill1','kill?']], 'Mentat_menus':[['job_run.ms','job_run.ms']]} -for cmd in ['patch','xvfb-run']: +for cmd in ['xvfb-run','patch'] if args.command == APPLY else ['xvfb-run'] if args.command == RESTORE else []: try: - subprocess.run(shlex.split(f'{cmd} --help')) + subprocess.run([cmd,'--help'], capture_output=True) except FileNotFoundError: print(f'"{cmd}" not found, please install') sys.exit() +if args.command == APPLY: + print('patching files...') -print('patching files...') + for directory in glob.glob(str(damask_root/'install/MarcMentat'/marc_version/'*')): + for orig, mods in matches[Path(directory).name]: + product,subfolder = (marc_root/directory).name.split('_') + orig = marc_root/f'{product.lower()}{marc_version}/{subfolder}/{orig}' + for patch in glob.glob(f'{directory}/{mods}.patch'): + copy_and_patch(Path(patch),orig,args.editor) -for directory in glob.glob(str(damask_root/'install/MarcMentat'/marc_version/'*')): - for orig, mods in matches[Path(directory).name]: - product,subfolder = (marc_root/Path(directory)).name.split('_') - orig = marc_root/f'{product.lower()}{marc_version}/{subfolder}/{orig}' - for patch in glob.glob(f'{directory}/{mods}.patch'): - copy_and_patch(Path(patch),orig,args.editor) +elif args.command == RESTORE: + print('deleting modified files...') + + for file in (glob.glob(str(marc_root/f'marc{marc_version}/tools/*_damask*')) + + glob.glob(str(marc_root/f'mentat{marc_version}/bin/kill[4-6]')) + + glob.glob(str(marc_root/f'mentat{marc_version}/bin/submit[4-6]*'))): + os.remove(file) + + print('restoring original files...') + + for file in (glob.glob(str(marc_root/f'marc{marc_version}/tools/include_linux64.orig')) + + glob.glob(str(marc_root/f'mentat{marc_version}/bin/edit_window.orig')) + + glob.glob(str(marc_root/f'mentat{marc_version}/menus/job_run.ms.orig'))): + shutil.copyfile(file,Path(file).with_suffix('')) + os.remove(file) +else: + print('skipping file modifications...') print('compiling Mentat menu binaries...') @@ -79,8 +102,10 @@ subprocess.run(shlex.split(f'xvfb-run -a {executable} -compile {menu_file}')) print('setting file access rights...') -for file in (glob.glob(str(marc_root/f'marc{marc_version}/tools/*_damask*')) + - glob.glob(str(marc_root/f'mentat{marc_version}/bin/edit_window')) + - glob.glob(str(marc_root/f'mentat{marc_version}/bin/kill[4-6]')) + - glob.glob(str(marc_root/f'mentat{marc_version}/bin/submit[4-6]'))): +for file in ( + (glob.glob(str(marc_root/f'marc{marc_version}/tools/*_damask*')) + + glob.glob(str(marc_root/f'mentat{marc_version}/bin/kill[4-6]')) + + glob.glob(str(marc_root/f'mentat{marc_version}/bin/submit[4-6]')) if args.command == APPLY else []) + + glob.glob(str(marc_root/f'mentat{marc_version}/bin/edit_window')) + ): os.chmod(file , 0o755) diff --git a/install/MarcMentat/installation.txt b/install/MarcMentat/installation.txt index 2ef682d65..e51af8932 100644 --- a/install/MarcMentat/installation.txt +++ b/install/MarcMentat/installation.txt @@ -1,7 +1,12 @@ -Install DAMASK modifications to use DAMASK_marc -This is for the Linux64 version of Marc/Mentat +Install or uninstall DAMASK modifications to MSC Marc/Mentat. +This is for the Linux64 version of Marc/Mentat. -Refer to http://damask.mpie.de for complete installation instructions. +usage: MSC_modifications.py [-h] [--editor string] [--marc-root string] [--marc-version string] [--damask-root string] + [command] + +where command is either 'install' or 'uninstall' + +Refer to https://damask.mpie.de/installation/source_code.html#msc-marc for complete installation instructions. Usually you will need to be root for this to work! @@ -9,6 +14,6 @@ See Marc and Mentat Release Guide for List of Build and Supported Platforms. The Intel Fortran compiler needs to be installed. -1) Install Marc, Mentat and Documentation as usual +1) Install Marc, Mentat, and Documentation as usual. Run the test example including subroutines to confirm that the installation of both Marc/Mentat and the Intel Fortran Compiler is ok. -2) Run the apply_DAMASK_modifications.py script from this directory. +2) Run the MSC_modifications.py script from this directory. diff --git a/processing/mentat_pbcOnBoxMesh.py b/processing/mentat_pbcOnBoxMesh.py new file mode 100755 index 000000000..3eedacb7d --- /dev/null +++ b/processing/mentat_pbcOnBoxMesh.py @@ -0,0 +1,262 @@ +#!/usr/bin/env python3 + +import sys +import os +import re +import time +import tempfile +from optparse import OptionParser + +import numpy as np + +import damask + +script_name = os.path.splitext(os.path.basename(__file__))[0] +script_id = ' '.join([script_name,damask.version]) + +# Convert .mfd file into a usable format +# Broken into labeled sections (eg. nodes, links, etc) +# Each section has a list of labeled elements with formatted numerical data +def parseMFD(dat): + formatted = [] + section = 0 + formatted.append({'label': 'header', 'uid': -1, 'els': []}) + # in between =beg= and =end= part of file + in_block = False + for line in dat: + if in_block: # currently in a section + # lines that start with a space are numerical data + if line[0] == ' ': + formatted[section]['els'].append([]) + + # grab numbers + nums = re.split(r'\s+', line.strip()) + + for num in nums: + # floating point has format ' -x.xxxxxxxxxxxxe+yy' + # scientific notation is used for float + if (len(num) >= 4) and (num[-4] == 'e'): + formatted[section]['els'][-1].append(float(num)) + else: # integer + formatted[section]['els'][-1].append(int(num)) + else: # not numerical data, so it is a label for an element or section end + if line[0] == '=' and re.search(r'=end=$', line) is not None: # End of section, avoiding regex if possible + in_block = False + else: + formatted[section]['els'].append([]) + formatted[section]['els'][-1] = line + + else: # Not in a section, we are looking for a =beg= now + search = re.search(r'=beg=\s+(\d+)\s\((.*?)\)', line) + if search is not None: # found start of a new section + section += 1 + in_block = True + formatted.append({'label': search.group(2), 'uid': int(search.group(1)), 'els': []}) + else: # No =beg= found, probably in the header + # Either header or somthing we didn't plan for - just save the line so it isn't lost + if formatted[section]['uid'] > 0: + section += 1 + formatted.append({'label': '', 'uid': -2, 'els': []}) # make dummy section to store unrecognized data + formatted[section]['els'].append(line) + + return formatted + +def asMFD(mfd_data): + result = '' + for section in mfd_data: + if section['uid'] > 0: + result += '=beg={0:5d} ({1})\n'.format(section['uid'], section['label']) + for el in section['els']: + if type(el) == str: + result += el + elif type(el) == list: + for num in el: + if type(num) == int: + result += '{:20d}'.format(num) + elif type(num) == float: + result += '{:20.12e}'.format(num) + else: + print(f'WARNING: encountered unknown type: {type(el)}') + result += '\n' + else: + print(f'WARNING: encountered unknown type: {type(el)}') + if section['uid'] > 0: + result += '=end=\n' + return result.strip() + + +def add_servoLinks(mfd_data,active=[True,True,True]): # directions on which to add PBC + base = ['x','y','z'] + box = {'min': np.zeros(3,dtype='d'), + 'max': np.zeros(3,dtype='d'), + 'delta': np.zeros(3,dtype='d'), + } + + mfd_dict = {} + for i in range(len(mfd_data)): + mfd_dict[mfd_data[i]['label']] = i + + NodeCoords = np.array(mfd_data[mfd_dict['nodes']]['els'][1::4])[:,1:4] + Nnodes = NodeCoords.shape[0] + + box['min'] = NodeCoords.min(axis=0) # find the bounding box + box['max'] = NodeCoords.max(axis=0) + box['delta'] = box['max']-box['min'] + for coord in range(3): # calc the dimension of the bounding box + if box['delta'][coord] != 0.0: + for extremum in ['min','max']: + rounded = round(box[extremum][coord]*1e+15/box['delta'][coord]) * \ + 1e-15*box['delta'][coord] # rounding to 1e-15 of dimension + box[extremum][coord] = 0.0 if rounded == 0.0 else rounded # get rid of -0.0 (negative zeros) + baseNode = {} + linkNodes = [] + +#------------------------------------------------------------------------------------------------- +# loop over all nodes + for node in range(Nnodes): + key = {} + maxFlag = [False, False, False] + Nmax = 0 + Nmin = 0 + for coord in range(3): # for each direction + if box['delta'][coord] != 0.0: + rounded = round(NodeCoords[node,coord]*1e+15/box['delta'][coord]) * \ + 1e-15*box['delta'][coord] # rounding to 1e-15 of dimension + NodeCoords[node,coord] = 0.0 if rounded == 0.0 else rounded # get rid of -0.0 (negative zeros) + key[base[coord]] = "%.8e"%NodeCoords[node,coord] # translate position to string + if (key[base[coord]] == "%.8e"%box['min'][coord]): # compare to min of bounding box (i.e. is on outer face?) + Nmin += 1 # count outer (back) face membership + elif (key[base[coord]] == "%.8e"%box['max'][coord]): # compare to max of bounding box (i.e. is on outer face?) + Nmax += 1 # count outer (front) face membership + maxFlag[coord] = True # remember face membership (for linked nodes) + + if Nmin > 0: # node is on a back face + # prepare for any non-existing entries in the data structure + if key['x'] not in baseNode.keys(): + baseNode[key['x']] = {} + if key['y'] not in baseNode[key['x']].keys(): + baseNode[key['x']][key['y']] = {} + if key['z'] not in baseNode[key['x']][key['y']].keys(): + baseNode[key['x']][key['y']][key['z']] = 0 + + baseNode[key['x']][key['y']][key['z']] = node+1 # remember the base node id + + if Nmax > 0 and Nmax >= Nmin: # node is on at least as many front than back faces + if any([maxFlag[i] and active[i] for i in range(3)]): + linkNodes.append({'id':node+1,'coord':NodeCoords[node],'faceMember':[maxFlag[i] and active[i] for i in range(3)]}) + + mfd_data[mfd_dict['entities']]['els'][0][0] += len(linkNodes) * 3 + + baseCorner = baseNode["%.8e"%box['min'][0]]["%.8e"%box['min'][1]]["%.8e"%box['min'][2]] # detect ultimate base node + + links = {'uid': 1705, 'label': 'links', 'els': [[7,0],[9,0]]} + linkID = 0 + for node in linkNodes: # loop over all linked nodes + linkCoord = [node['coord']] # start list of control node coords with my coords + for dir in range(3): # check for each direction + if node['faceMember'][dir]: # me on this front face + linkCoord[0][dir] = box['min'][dir] # project me onto rear face along dir + linkCoord.append(np.array(box['min'])) # append base corner + linkCoord[-1][dir] = box['max'][dir] # stretch it to corresponding control leg of "dir" + + nLinks = len(linkCoord) + for dof in [1,2,3]: + tied_node = node['id'] + nterms = 1 + nLinks + + linkID += 1 + # Link header + links['els'].append('link{0}\n'.format(linkID)) + links['els'].append([linkID, 1]) + links['els'].append([0]) + links['els'].append([0]) + links['els'].append([0, 0, 0, tied_node]) + + # these need to be put in groups of four + link_payload = [dof, 0, nterms] + + # Individual node contributions (node, dof, coef.) + for i in range(nterms): + if i == nLinks: + link_payload.append(baseCorner) + else: + link_payload.append(baseNode["%.8e"%linkCoord[i][0]]["%.8e"%linkCoord[i][1]]["%.8e"%linkCoord[i][2]]) + for i in range(nterms): + link_payload.append(dof) + for i in range(nterms): + if i == nLinks: + link_payload.append(1.0 - nLinks) + else: + link_payload.append(1.0) + + # Needs to be formatted 4 data points per row, character width of 20, so 80 total + for j in range(0, len(link_payload), 4): + links['els'].append(link_payload[j:j+4]) + if j+4 < len(link_payload): + links['els'].append(link_payload[j+4:]) + + i = 0 + while i < len(mfd_data) and mfd_data[i]['uid'] < 1705: i += 1 + + if mfd_data[i]['uid'] == 1705: del mfd_data[i] + mfd_data.insert(i, links) + + +#-------------------------------------------------------------------------------------------------- +# MAIN +#-------------------------------------------------------------------------------------------------- + +parser = OptionParser(usage='%prog options [file[s]]', description = """ +Set up servo linking to achieve periodic boundary conditions for a regular hexahedral mesh. +Use *py_connection to operate on model presently opened in MSC.Mentat. +""", version = script_id) + +parser.add_option('-p', '--port', + type = int, metavar = 'int', default = None, + help = 'Mentat connection port') +parser.add_option('-x', + action = 'store_false', default = True, + help = 'no PBC along x direction') +parser.add_option('-y', + action = 'store_false', default = True, + help = 'no PBC along y direction') +parser.add_option('-z', + action = 'store_false', default = True, + help = 'no PBC along z direction') + +(options, filenames) = parser.parse_args() + +remote = options.port is not None + +if remote and filenames != []: + parser.error('file can not be specified when port is given.') +if filenames == []: filenames = [None] + +if remote: + sys.path.append(str(damask.solver.Marc().library_path)) + import py_mentat + + print(script_name+': waiting to connect...') + filenames = [os.path.join(tempfile._get_default_tempdir(), next(tempfile._get_candidate_names()) + '.mfd')] + try: + py_mentat.py_connect('',options.port) + py_mentat.py_send('*set_save_formatted on') + py_mentat.py_send('*save_as_model "{}" yes'.format(filenames[0])) + py_mentat.py_get_int("nnodes()") + except py_mentat.InputError as err: + print(f'{err}. Try Tools/Python/"Run as Separate Process" & "Initiate".') + sys.exit(-1) + print( 'connected...') + +for name in filenames: + while remote and not os.path.exists(name): time.sleep(0.5) + with open( name,'r') if name is not None else sys.stdin as file_in: + print(script_name+': '+name) + mfd = parseMFD(file_in) + + add_servoLinks(mfd,[options.x,options.y,options.z]) + with open( name,'w') if name is not None else sys.stdout as file_out: + file_out.write(asMFD(mfd)) + +if remote: + py_mentat.py_send('*open_model "{}"'.format(filenames[0])) diff --git a/processing/pre/mentat_spectralBox.py b/processing/mentat_spectralBox.py similarity index 94% rename from processing/pre/mentat_spectralBox.py rename to processing/mentat_spectralBox.py index 72206a8f4..de6307469 100755 --- a/processing/pre/mentat_spectralBox.py +++ b/processing/mentat_spectralBox.py @@ -7,8 +7,8 @@ from optparse import OptionParser import damask -scriptName = os.path.splitext(os.path.basename(__file__))[0] -scriptID = ' '.join([scriptName,damask.version]) +script_name = os.path.splitext(os.path.basename(__file__))[0] +script_id = ' '.join([script_name,damask.version]) #------------------------------------------------------------------------------------------------- def outMentat(cmd,locals): @@ -45,7 +45,7 @@ def output(cmds,locals,dest): #------------------------------------------------------------------------------------------------- def init(): return [ - "|"+' '.join([scriptID] + sys.argv[1:]), + "|"+' '.join([script_id] + sys.argv[1:]), "*draw_manual", # prevent redrawing in Mentat, should be much faster "*new_model yes", "*reset", @@ -170,7 +170,7 @@ def initial_conditions(material): parser = OptionParser(usage='%prog options [file[s]]', description = """ Generate MSC.Marc FE hexahedral mesh from geom file. -""", version = scriptID) +""", version = script_id) parser.add_option('-p', '--port', dest = 'port', @@ -194,7 +194,7 @@ if options.port is not None: if filenames == []: filenames = [None] for name in filenames: - print(scriptName+': '+name) + print(script_name+': '+name) geom = damask.Grid.load(StringIO(''.join(sys.stdin.read())) if name is None else name) material = geom.material.flatten(order='F') @@ -211,11 +211,11 @@ for name in filenames: '*draw_automatic', ] - outputLocals = {} + output_locals = {} if options.port: py_mentat.py_connect('',options.port) - output(cmds,outputLocals,'Mentat') + output(cmds,output_locals,'Mentat') py_mentat.py_disconnect() else: with sys.stdout if name is None else open(os.path.splitext(name)[0]+'.proc','w') as f: - output(cmds,outputLocals,f) + output(cmds,output_locals,f) diff --git a/processing/pre/mentat_pbcOnBoxMesh.py b/processing/pre/mentat_pbcOnBoxMesh.py deleted file mode 100755 index 1cf18eeda..000000000 --- a/processing/pre/mentat_pbcOnBoxMesh.py +++ /dev/null @@ -1,262 +0,0 @@ -#!/usr/bin/env python3 - -import sys -import os -import re -import time -import tempfile -from optparse import OptionParser - -import numpy as np - -import damask - -scriptName = os.path.splitext(os.path.basename(__file__))[0] -scriptID = ' '.join([scriptName,damask.version]) - -# Convert .mfd file into a usable format -# Broken into labeled sections (eg. nodes, links, etc) -# Each section has a list of labeled elements with formatted numerical data -def parseMFD(dat): - formatted = [] - section = 0 - formatted.append({'label': 'header', 'uid': -1, 'els': []}) - # in between =beg= and =end= part of file - in_block = False - for line in dat: - if in_block: # currently in a section - # lines that start with a space are numerical data - if line[0] == ' ': - formatted[section]['els'].append([]) - - # grab numbers - nums = re.split(r'\s+', line.strip()) - - for num in nums: - # floating point has format ' -x.xxxxxxxxxxxxe+yy' - # scientific notation is used for float - if (len(num) >= 4) and (num[-4] == 'e'): - formatted[section]['els'][-1].append(float(num)) - else: # integer - formatted[section]['els'][-1].append(int(num)) - else: # not numerical data, so it is a label for an element or section end - if line[0] == '=' and re.search(r'=end=$', line) is not None: # End of section, avoiding regex if possible - in_block = False - else: - formatted[section]['els'].append([]) - formatted[section]['els'][-1] = line - - else: # Not in a section, we are looking for a =beg= now - search = re.search(r'=beg=\s+(\d+)\s\((.*?)\)', line) - if search is not None: # found start of a new section - section += 1 - in_block = True - formatted.append({'label': search.group(2), 'uid': int(search.group(1)), 'els': []}) - else: # No =beg= found, probably in the header - # Either header or somthing we didn't plan for - just save the line so it isn't lost - if formatted[section]['uid'] > 0: - section += 1 - formatted.append({'label': '', 'uid': -2, 'els': []}) # make dummy section to store unrecognized data - formatted[section]['els'].append(line) - - return formatted - -def asMFD(mfd_data): - result = '' - for section in mfd_data: - if section['uid'] > 0: - result += '=beg={0:5d} ({1})\n'.format(section['uid'], section['label']) - for el in section['els']: - if type(el) == str: - result += el - elif type(el) == list: - for num in el: - if type(num) == int: - result += '{:20d}'.format(num) - elif type(num) == float: - result += '{:20.12e}'.format(num) - else: - print(f'WARNING: encountered unknown type: {type(el)}') - result += '\n' - else: - print(f'WARNING: encountered unknown type: {type(el)}') - if section['uid'] > 0: - result += '=end=\n' - return result.strip() - - -def add_servoLinks(mfd_data,active=[True,True,True]): # directions on which to add PBC - base = ['x','y','z'] - box = {'min': np.zeros(3,dtype='d'), - 'max': np.zeros(3,dtype='d'), - 'delta': np.zeros(3,dtype='d'), - } - - mfd_dict = {} - for i in range(len(mfd_data)): - mfd_dict[mfd_data[i]['label']] = i - - NodeCoords = np.array(mfd_data[mfd_dict['nodes']]['els'][1::4])[:,1:4] - Nnodes = NodeCoords.shape[0] - - box['min'] = NodeCoords.min(axis=0) # find the bounding box - box['max'] = NodeCoords.max(axis=0) - box['delta'] = box['max']-box['min'] - for coord in range(3): # calc the dimension of the bounding box - if box['delta'][coord] != 0.0: - for extremum in ['min','max']: - rounded = round(box[extremum][coord]*1e+15/box['delta'][coord]) * \ - 1e-15*box['delta'][coord] # rounding to 1e-15 of dimension - box[extremum][coord] = 0.0 if rounded == 0.0 else rounded # get rid of -0.0 (negative zeros) - baseNode = {} - linkNodes = [] - -#------------------------------------------------------------------------------------------------- -# loop over all nodes - for node in range(Nnodes): - key = {} - maxFlag = [False, False, False] - Nmax = 0 - Nmin = 0 - for coord in range(3): # for each direction - if box['delta'][coord] != 0.0: - rounded = round(NodeCoords[node,coord]*1e+15/box['delta'][coord]) * \ - 1e-15*box['delta'][coord] # rounding to 1e-15 of dimension - NodeCoords[node,coord] = 0.0 if rounded == 0.0 else rounded # get rid of -0.0 (negative zeros) - key[base[coord]] = "%.8e"%NodeCoords[node,coord] # translate position to string - if (key[base[coord]] == "%.8e"%box['min'][coord]): # compare to min of bounding box (i.e. is on outer face?) - Nmin += 1 # count outer (back) face membership - elif (key[base[coord]] == "%.8e"%box['max'][coord]): # compare to max of bounding box (i.e. is on outer face?) - Nmax += 1 # count outer (front) face membership - maxFlag[coord] = True # remember face membership (for linked nodes) - - if Nmin > 0: # node is on a back face - # prepare for any non-existing entries in the data structure - if key['x'] not in baseNode.keys(): - baseNode[key['x']] = {} - if key['y'] not in baseNode[key['x']].keys(): - baseNode[key['x']][key['y']] = {} - if key['z'] not in baseNode[key['x']][key['y']].keys(): - baseNode[key['x']][key['y']][key['z']] = 0 - - baseNode[key['x']][key['y']][key['z']] = node+1 # remember the base node id - - if Nmax > 0 and Nmax >= Nmin: # node is on at least as many front than back faces - if any([maxFlag[i] and active[i] for i in range(3)]): - linkNodes.append({'id': node+1,'coord': NodeCoords[node], 'faceMember': [maxFlag[i] and active[i] for i in range(3)]}) - - mfd_data[mfd_dict['entities']]['els'][0][0] += len(linkNodes) * 3 - - baseCorner = baseNode["%.8e"%box['min'][0]]["%.8e"%box['min'][1]]["%.8e"%box['min'][2]] # detect ultimate base node - - links = {'uid': 1705, 'label': 'links', 'els': [[7,0],[9,0]]} - linkID = 0 - for node in linkNodes: # loop over all linked nodes - linkCoord = [node['coord']] # start list of control node coords with my coords - for dir in range(3): # check for each direction - if node['faceMember'][dir]: # me on this front face - linkCoord[0][dir] = box['min'][dir] # project me onto rear face along dir - linkCoord.append(np.array(box['min'])) # append base corner - linkCoord[-1][dir] = box['max'][dir] # stretch it to corresponding control leg of "dir" - - nLinks = len(linkCoord) - for dof in [1,2,3]: - tied_node = node['id'] - nterms = 1 + nLinks - - linkID += 1 - # Link header - links['els'].append('link{0}\n'.format(linkID)) - links['els'].append([linkID, 1]) - links['els'].append([0]) - links['els'].append([0]) - links['els'].append([0, 0, 0, tied_node]) - - # these need to be put in groups of four - link_payload = [dof, 0, nterms] - - # Individual node contributions (node, dof, coef.) - for i in range(nterms): - if i == nLinks: - link_payload.append(baseCorner) - else: - link_payload.append(baseNode["%.8e"%linkCoord[i][0]]["%.8e"%linkCoord[i][1]]["%.8e"%linkCoord[i][2]]) - for i in range(nterms): - link_payload.append(dof) - for i in range(nterms): - if i == nLinks: - link_payload.append(1.0 - nLinks) - else: - link_payload.append(1.0) - - # Needs to be formatted 4 data points per row, character width of 20, so 80 total - for j in range(0, len(link_payload), 4): - links['els'].append(link_payload[j:j+4]) - if j+4 < len(link_payload): - links['els'].append(link_payload[j+4:]) - - i = 0 - while i < len(mfd_data) and mfd_data[i]['uid'] < 1705: i += 1 - - if mfd_data[i]['uid'] == 1705: del mfd_data[i] - mfd_data.insert(i, links) - - -#-------------------------------------------------------------------------------------------------- -# MAIN -#-------------------------------------------------------------------------------------------------- - -parser = OptionParser(usage='%prog options [file[s]]', description = """ -Set up servo linking to achieve periodic boundary conditions for a regular hexahedral mesh. -Use *py_connection to operate on model presently opened in MSC.Mentat. -""", version = scriptID) - -parser.add_option('-p', '--port', - type = int, metavar = 'int', default = None, - help = 'Mentat connection port') -parser.add_option('-x', - action = 'store_false', default = True, - help = 'no PBC along x direction') -parser.add_option('-y', - action = 'store_false', default = True, - help = 'no PBC along y direction') -parser.add_option('-z', - action = 'store_false', default = True, - help = 'no PBC along z direction') - -(options, filenames) = parser.parse_args() - -remote = options.port is not None - -if remote and filenames != []: - parser.error('file can not be specified when port is given.') -if filenames == []: filenames = [None] - -if remote: - sys.path.append(str(damask.solver.Marc().library_path)) - import py_mentat - - print(scriptName+': waiting to connect...') - filenames = [os.path.join(tempfile._get_default_tempdir(), next(tempfile._get_candidate_names()) + '.mfd')] - try: - py_mentat.py_connect('',options.port) - py_mentat.py_send('*set_save_formatted on') - py_mentat.py_send('*save_as_model "{}" yes'.format(filenames[0])) - py_mentat.py_get_int("nnodes()") - except py_mentat.InputError as err: - print(f'{err}. Try Tools/Python/"Run as Separate Process" & "Initiate".') - sys.exit(-1) - print( 'connected...') - -for name in filenames: - while remote and not os.path.exists(name): time.sleep(0.5) - with open( name,'r') if name is not None else sys.stdin as fileIn: - print(scriptName+': '+name) - mfd = parseMFD(fileIn) - - add_servoLinks(mfd,[options.x,options.y,options.z]) - with open( name,'w') if name is not None else sys.stdout as fileOut: - fileOut.write(asMFD(mfd)) - -if remote: - py_mentat.py_send('*open_model "{}"'.format(filenames[0])) diff --git a/python/damask/_colormap.py b/python/damask/_colormap.py index 688070529..50ff910e6 100644 --- a/python/damask/_colormap.py +++ b/python/damask/_colormap.py @@ -2,7 +2,8 @@ import os import json import functools import colorsys -from typing import Union, TextIO +from typing import Optional, Union, TextIO +from itertools import chain import numpy as np import scipy.interpolate as interp @@ -248,7 +249,7 @@ class Colormap(mpl.colors.ListedColormap): Parameters ---------- - fraction : float or sequence of float + fraction : (sequence of) float Fractional coordinate(s) to evaluate Colormap at. Returns @@ -274,8 +275,8 @@ class Colormap(mpl.colors.ListedColormap): def shade(self, field: np.ndarray, - bounds: FloatSequence = None, - gap: float = None) -> Image: + bounds: Optional[FloatSequence] = None, + gap: Optional[float] = None) -> Image: """ Generate PIL image of 2D field using colormap. @@ -314,7 +315,7 @@ class Colormap(mpl.colors.ListedColormap): def reversed(self, - name: str = None) -> 'Colormap': + name: Optional[str] = None) -> 'Colormap': """ Reverse. @@ -363,7 +364,7 @@ class Colormap(mpl.colors.ListedColormap): def save_paraview(self, - fname: FileHandle = None): + fname: Optional[FileHandle] = None): """ Save as JSON file for use in Paraview. @@ -373,16 +374,12 @@ class Colormap(mpl.colors.ListedColormap): File to store results. Defaults to colormap name + '.json'. """ - colors = [] - for i,c in enumerate(np.round(self.colors,6).tolist()): - colors+=[i]+c - out = [{ 'Creator':util.execution_stamp('Colormap'), 'ColorSpace':'RGB', 'Name':self.name, 'DefaultMap':True, - 'RGBPoints':colors + 'RGBPoints':list(chain.from_iterable([(i,*c) for i,c in enumerate(self.colors.round(6))])) }] fhandle = self._get_file_handle(fname,'.json') @@ -391,7 +388,7 @@ class Colormap(mpl.colors.ListedColormap): def save_ASCII(self, - fname: FileHandle = None): + fname: Optional[FileHandle] = None): """ Save as ASCII file. @@ -402,11 +399,11 @@ class Colormap(mpl.colors.ListedColormap): """ labels = {'RGBA':4} if self.colors.shape[1] == 4 else {'RGB': 3} - t = Table(labels,self.colors,f'Creator: {util.execution_stamp("Colormap")}') + t = Table(labels,self.colors,[f'Creator: {util.execution_stamp("Colormap")}']) t.save(self._get_file_handle(fname,'.txt')) - def save_GOM(self, fname: FileHandle = None): + def save_GOM(self, fname: Optional[FileHandle] = None): """ Save as ASCII file for use in GOM Aramis. @@ -427,7 +424,7 @@ class Colormap(mpl.colors.ListedColormap): def save_gmsh(self, - fname: FileHandle = None): + fname: Optional[FileHandle] = None): """ Save as ASCII file for use in gmsh. diff --git a/python/damask/_config.py b/python/damask/_config.py index 5423699db..1be1e313a 100644 --- a/python/damask/_config.py +++ b/python/damask/_config.py @@ -2,14 +2,16 @@ import copy from io import StringIO from collections.abc import Iterable import abc -from typing import Union, Dict, Any, Type, TypeVar +from typing import Optional, Union, Dict, Any, Type, TypeVar import numpy as np import yaml try: from yaml import CSafeLoader as SafeLoader + from yaml import CSafeDumper as SafeDumper except ImportError: from yaml import SafeLoader # type: ignore + from yaml import SafeDumper # type: ignore from ._typehints import FileHandle from . import Rotation @@ -17,20 +19,20 @@ from . import util MyType = TypeVar('MyType', bound='Config') -class NiceDumper(yaml.SafeDumper): +class NiceDumper(SafeDumper): """Make YAML readable for humans.""" def write_line_break(self, - data: str = None): - super().write_line_break(data) + data: Optional[str] = None): + super().write_line_break(data) # type: ignore - if len(self.indents) == 1: - super().write_line_break() + if len(self.indents) == 1: # type: ignore + super().write_line_break() # type: ignore def increase_indent(self, flow: bool = False, indentless: bool = False): - return super().increase_indent(flow, False) + return super().increase_indent(flow, False) # type: ignore def represent_data(self, data: Any): @@ -41,8 +43,10 @@ class NiceDumper(yaml.SafeDumper): return self.represent_data(data.tolist()) if isinstance(data, Rotation): return self.represent_data(data.quaternion.tolist()) - else: - return super().represent_data(data) + if hasattr(data, 'dtype'): + return self.represent_data(data.item()) + + return super().represent_data(data) def ignore_aliases(self, data: Any) -> bool: @@ -53,7 +57,7 @@ class Config(dict): """YAML-based configuration.""" def __init__(self, - yml: Union[str, Dict[str, Any]] = None, + yml: Union[None, str, Dict[str, Any]] = None, **kwargs): """Initialize from YAML, dict, or key=value pairs.""" if isinstance(yml,str): diff --git a/python/damask/_configmaterial.py b/python/damask/_configmaterial.py index 7a06a2c69..5ee8ea73d 100644 --- a/python/damask/_configmaterial.py +++ b/python/damask/_configmaterial.py @@ -1,6 +1,6 @@ import numpy as np import h5py -from typing import Sequence, Dict, Any, Collection +from typing import Optional, Union, Sequence, Dict, Any, Collection from ._typehints import FileHandle from . import Config @@ -22,7 +22,7 @@ class ConfigMaterial(Config): """ def __init__(self, - d: Dict[str, Any] = None, + d: Optional[Dict[str, Any]] = None, **kwargs): """ New material configuration. @@ -83,13 +83,13 @@ class ConfigMaterial(Config): @staticmethod def load_DREAM3D(fname: str, - grain_data: str = None, - cell_data: str = None, + grain_data: Optional[str] = None, + cell_data: Optional[str] = None, cell_ensemble_data: str = 'CellEnsembleData', phases: str = 'Phases', Euler_angles: str = 'EulerAngles', phase_names: str = 'PhaseName', - base_group: str = None) -> 'ConfigMaterial': + base_group: Optional[str] = None) -> 'ConfigMaterial': """ Load DREAM.3D (HDF5) file. @@ -160,7 +160,7 @@ class ConfigMaterial(Config): pass - base_config = ConfigMaterial({'phase':{k if isinstance(k,int) else str(k):'t.b.d.' for k in np.unique(phase)}, + base_config = ConfigMaterial({'phase':{k if isinstance(k,int) else str(k): None for k in np.unique(phase)}, 'homogenization':{'direct':{'N_constituents':1}}}) constituent = {k:np.atleast_1d(v[idx].squeeze()) for k,v in zip(['O','phase'],[O,phase])} @@ -193,10 +193,10 @@ class ConfigMaterial(Config): >>> import damask.ConfigMaterial as cm >>> t = damask.Table.load('small.txt') >>> t - pos pos pos qu qu qu qu phase homog - 0 0 0 0 0.19 0.8 0.24 -0.51 Aluminum SX - 1 1 0 0 0.8 0.19 0.24 -0.51 Steel SX - 1 1 1 0 0.8 0.19 0.24 -0.51 Steel SX + 3:pos pos pos 4:qu qu qu qu phase homog + 0 0 0 0 0.19 0.8 0.24 -0.51 Aluminum SX + 1 1 0 0 0.8 0.19 0.24 -0.51 Steel SX + 2 1 1 0 0.8 0.19 0.24 -0.51 Steel SX >>> cm.from_table(t,O='qu',phase='phase',homogenization='homog') material: - constituents: @@ -209,8 +209,8 @@ class ConfigMaterial(Config): v: 1.0 phase: Steel homogenization: SX - homogenization: {} - phase: {} + homogenization: {SX: null} + phase: {Aluminum: null, Steel: null} >>> cm.from_table(t,O='qu',phase='phase',homogenization='single_crystal') material: @@ -224,8 +224,8 @@ class ConfigMaterial(Config): v: 1.0 phase: Steel homogenization: single_crystal - homogenization: {} - phase: {} + homogenization: {single_crystal: null} + phase: {Aluminum: null, Steel: null} """ kwargs_ = {k:table.get(v) if v in table.labels else np.atleast_2d([v]*len(table)).T for k,v in kwargs.items()} @@ -233,6 +233,8 @@ class ConfigMaterial(Config): _,idx = np.unique(np.hstack(list(kwargs_.values())),return_index=True,axis=0) idx = np.sort(idx) kwargs_ = {k:np.atleast_1d(v[idx].squeeze()) for k,v in kwargs_.items()} + for what in ['phase','homogenization']: + if what not in kwargs_: kwargs_[what] = what+'_label' return ConfigMaterial().material_add(**kwargs_) @@ -243,7 +245,7 @@ class ConfigMaterial(Config): Check for completeness. Only the general file layout is considered. - This check does not consider whether parameters for + This check does not consider whether specific parameters for a particular phase/homogenization model are missing. Returns @@ -252,52 +254,56 @@ class ConfigMaterial(Config): Whether the material.yaml definition is complete. """ + def LabeledList(label,items): + return f'{label.capitalize()}{"s" if len(items)>1 else ""} {util.srepr(items,",",quote=True)}' + ok = True - for top_level in ['homogenization','phase','material']: - ok &= top_level in self - if top_level not in self: print(f'{top_level} entry missing') + msg = [] + all = set(['homogenization','phase','material']) + miss = set([item for item in all if item not in self]) + empty = set([item for item in all-miss if self[item] is None]) + + if miss: + msg.append(f'{LabeledList("top-level",miss)} missing') + ok = False + if empty: + msg.append(f'{LabeledList("top-level",empty)} empty') if ok: - ok &= len(self['material']) > 0 - if len(self['material']) < 1: print('Incomplete material definition') + ok &= len(self['material']) > 0 + if len(self['material']) < 1: msg.append('No materials defined') - if ok: homogenization = set() phase = set() for i,v in enumerate(self['material']): if 'homogenization' in v: homogenization.add(v['homogenization']) else: - print(f'No homogenization specified in material {i}') + msg.append(f'No homogenization specified for material {i}') ok = False if 'constituents' in v: for ii,vv in enumerate(v['constituents']): if 'O' not in vv: - print('No orientation specified in constituent {ii} of material {i}') + msg.append(f'No orientation specified for constituent {ii} of material {i}') ok = False if 'phase' in vv: phase.add(vv['phase']) else: - print(f'No phase specified in constituent {ii} of material {i}') + msg.append(f'No phase specified for constituent {ii} of material {i}') ok = False - for k,v in self['phase'].items(): - if 'lattice' not in v: - print(f'No lattice specified in phase {k}') + for v,other in {'phase':phase, + 'homogenization':homogenization}.items(): + me = set([] if v in empty else self[v]) + if _miss := other - me: + msg.append(f'{LabeledList(v,_miss)} missing') + ok = False + if len(_empty := [item for item in me if self[v][item] is None]) > 0: + msg.append(f'{LabeledList(v,_empty)} undefined') ok = False - for k,v in self['homogenization'].items(): - if 'N_constituents' not in v: - print(f'No. of constituents not specified in homogenization {k}') - ok = False - - if phase - set(self['phase']): - print(f'Phase(s) {phase-set(self["phase"])} missing') - ok = False - if homogenization - set(self['homogenization']): - print(f'Homogenization(s) {homogenization-set(self["homogenization"])} missing') - ok = False + print(util.srepr(msg)) return ok @@ -320,7 +326,7 @@ class ConfigMaterial(Config): if 'phase' in self: for k,v in self['phase'].items(): - if 'lattice' in v: + if v is not None and 'lattice' in v: try: Orientation(lattice=v['lattice']) except KeyError: @@ -348,8 +354,8 @@ class ConfigMaterial(Config): def material_rename_phase(self, mapping: Dict[str, str], - ID: Sequence[int] = None, - constituent: Sequence[int] = None) -> 'ConfigMaterial': + ID: Optional[Sequence[int]] = None, + constituent: Optional[Sequence[int]] = None) -> 'ConfigMaterial': """ Change phase name in material. @@ -382,7 +388,7 @@ class ConfigMaterial(Config): def material_rename_homogenization(self, mapping: Dict[str, str], - ID: Sequence[int] = None) -> 'ConfigMaterial': + ID: Optional[Sequence[int]] = None) -> 'ConfigMaterial': """ Change homogenization name in material. @@ -409,30 +415,47 @@ class ConfigMaterial(Config): return dup - def material_add(self, - **kwargs: Any) -> 'ConfigMaterial': + def material_add(self,*, + homogenization: Any = None, + phase: Any = None, + v: Any = None, + O: Any = None, + V_e: Any = None) -> 'ConfigMaterial': """ Add material entries. Parameters ---------- - **kwargs - Key-value pairs. + homogenization: (array-like) of str, optional + Homogenization label. + phase: (array-like) of str, optional + Phase label (per constituent). + v: (array-like) of float, optional + Constituent volume fraction (per constituent). + O: (array-like) of damask.Rotation or np.array/list of shape(4), optional + Orientation as unit quaternion (per constituent). + V_e: (array-like) of np.array/list of shape(3,3), optional + Left elastic stretch (per constituent). Returns ------- updated : damask.ConfigMaterial Updated material configuration. + Notes + ----- + First index of array-like values that are defined per + consituent runs over materials, whereas second index runs + over constituents. + Examples -------- - Create a dual-phase steel microstructure for micromechanical simulations: + Create two grains of ferrite and one grain of martensite, each with random orientation: - >>> import numpy as np >>> import damask >>> m = damask.ConfigMaterial() - >>> m = m.material_add(phase = ['Ferrite','Martensite'], - ... O = damask.Rotation.from_random(2), + >>> m = m.material_add(phase = ['Ferrite','Martensite','Ferrite'], + ... O = damask.Rotation.from_random(3), ... homogenization = 'SX') >>> m material: @@ -446,60 +469,95 @@ class ConfigMaterial(Config): v: 1.0 phase: Martensite homogenization: SX - homogenization: {} - phase: {} + - constituents: + - O: [0.47925185, -0.04294454, 0.78760173, -0.3849116 ] + v: 1.0 + phase: Ferrite + homogenization: SX + homogenization: {SX: null} + phase: {Ferrite: null, Martensite: null} - Create a duplex stainless steel microstructure for forming simulations: + Create hundred materials that each approximate a duplex stainless steel microstructure + with three austenite and one relatively bigger ferrite grain of random orientation each: - >>> import numpy as np >>> import damask >>> m = damask.ConfigMaterial() - >>> m = m.material_add(phase = np.array(['Austenite','Ferrite']).reshape(1,2), - ... O = damask.Rotation.from_random((2,2)), - ... v = np.array([0.2,0.8]).reshape(1,2), + >>> m = m.material_add(phase = np.array(['Austenite']*3+['Ferrite']), + ... O = damask.Rotation.from_random((100,4)), + ... v = np.array([0.2]*3+[0.4]), ... homogenization = 'Taylor') >>> m material: - constituents: - - phase: Austenite - O: [0.659802978293224, 0.6953785848195171, 0.22426295326327111, -0.17554139512785227] - v: 0.2 - - phase: Ferrite - O: [0.49356745891301596, 0.2841806579193434, -0.7487679215072818, -0.339085707289975] - v: 0.8 + - v: 0.2 + phase: Austenite + O: [0.46183665006602664, 0.2215160420973196, -0.5594313187331139, 0.6516702781083836] + - v: 0.2 + phase: Austenite + O: [0.11321658382410027, 0.6354079414360444, 0.00562701344273936, 0.7638108992590535] + - v: 0.2 + phase: Austenite + O: [0.050991978809077604, 0.8069522034362003, -0.11352928955610851, -0.5773552285027659] + - v: 0.4 + phase: Ferrite + O: [0.9460076150721788, 0.15880754622367604, -0.0069841062241482385, -0.28249066842661014] homogenization: Taylor + . + . + . - constituents: - - phase: Austenite - O: [0.26542221365204055, 0.7268854930702071, 0.4474726435701472, -0.44828201137283735] - v: 0.2 - - phase: Ferrite - O: [0.6545817158479885, -0.08004812803625233, -0.6226561293931374, 0.4212059104577611] - v: 0.8 + - v: 0.2 + phase: Austenite + O: [0.12531400788494199, -0.18637769037997565, 0.31737548053338394, -0.9213210951197429] + - v: 0.2 + phase: Austenite + O: [0.37453930577161404, -0.33529507696450805, -0.3266564259130028, -0.800370601162502] + - v: 0.2 + phase: Austenite + O: [0.035776891752713764, -0.720706371010592, -0.4540438656728926, -0.5226342017569017] + - v: 0.4 + phase: Ferrite + O: [0.6782596727966124, -0.20800082041703685, -0.138636083554039, 0.6909989227925536] homogenization: Taylor - homogenization: {} - phase: {} + + homogenization: {Taylor: null} + + phase: {Austenite: null, Ferrite: null} """ - N,n,shaped = 1,1,{} + kwargs = {} + for keyword,value in zip(['homogenization','phase','v','O','V_e'],[homogenization,phase,v,O,V_e]): + if value is not None: kwargs[keyword] = value + + _constituent_properties = ['phase','O','v','V_e'] + _dim = {'O':(4,),'V_e':(3,3,)} + _ex = dict((k, -len(v)) for k, v in _dim.items()) + + N,n = 1,1 + shaped : Dict[str, Union[None,np.ndarray]] = \ + {'v': None, + 'phase': None, + 'homogenization': None, + } - map_dim = {'O':-1,'V_e':-2} for k,v in kwargs.items(): shaped[k] = np.array(v) - s = shaped[k].shape[:map_dim.get(k,None)] + s = shaped[k].shape[:_ex.get(k,None)] # type: ignore N = max(N,s[0]) if len(s)>0 else N n = max(n,s[1]) if len(s)>1 else n + shaped['v'] = np.array(1./n) if shaped['v'] is None else shaped['v'] + mat: Sequence[dict] = [{'constituents':[{} for _ in range(n)]} for _ in range(N)] - if 'v' not in kwargs: - shaped['v'] = np.broadcast_to(1/n,(N,n)) - - map_shape = {'O':(N,n,4),'V_e':(N,n,3,3)} for k,v in shaped.items(): - target = map_shape.get(k,(N,n)) - obj = np.broadcast_to(v.reshape(util.shapeshifter(v.shape, target, mode = 'right')), target) + target = (N,n) + _dim.get(k,()) + obj = np.broadcast_to(np.array(v).reshape(util.shapeshifter(() if v is None else v.shape, + target, + mode = 'right')), + target) for i in range(N): - if k in ['phase','O','v','V_e']: + if k in _constituent_properties: for j in range(n): mat[i]['constituents'][j][k] = obj[i,j].item() if isinstance(obj[i,j],np.generic) else obj[i,j] else: @@ -508,4 +566,8 @@ class ConfigMaterial(Config): dup = self.copy() dup['material'] = dup['material'] + mat if 'material' in dup else mat + for what in [item for item in ['phase','homogenization'] if shaped[item] is not None]: + for k in np.unique(shaped[what]): # type: ignore + if k not in dup[what]: dup[what][str(k)] = None + return dup diff --git a/python/damask/_crystal.py b/python/damask/_crystal.py index fb2dc3438..ed694fb12 100644 --- a/python/damask/_crystal.py +++ b/python/damask/_crystal.py @@ -1,4 +1,4 @@ -from typing import Union, Dict, List, Tuple +from typing import Optional, Union, Dict, List, Tuple import numpy as np @@ -324,10 +324,10 @@ class Crystal(): """ def __init__(self, *, - family: CrystalFamily = None, - lattice: CrystalLattice = None, - a: float = None, b: float = None, c: float = None, - alpha: float = None, beta: float = None, gamma: float = None, + family: Optional[CrystalFamily] = None, + lattice: Optional[CrystalLattice] = None, + a: Optional[float] = None, b: Optional[float] = None, c: Optional[float] = None, + alpha: Optional[float] = None, beta: Optional[float] = None, gamma: Optional[float] = None, degrees: bool = False): """ New representation of a crystal. @@ -690,8 +690,8 @@ class Crystal(): self.lattice[-1],None),dtype=float) def to_lattice(self, *, - direction: FloatSequence = None, - plane: FloatSequence = None) -> np.ndarray: + direction: Optional[FloatSequence] = None, + plane: Optional[FloatSequence] = None) -> np.ndarray: """ Calculate lattice vector corresponding to crystal frame direction or plane normal. @@ -717,8 +717,8 @@ class Crystal(): def to_frame(self, *, - uvw: FloatSequence = None, - hkl: FloatSequence = None) -> np.ndarray: + uvw: Optional[FloatSequence] = None, + hkl: Optional[FloatSequence] = None) -> np.ndarray: """ Calculate crystal frame vector corresponding to lattice direction [uvw] or plane normal (hkl). diff --git a/python/damask/_grid.py b/python/damask/_grid.py index 5810f89c2..5f58a9c75 100644 --- a/python/damask/_grid.py +++ b/python/damask/_grid.py @@ -4,13 +4,13 @@ import warnings import multiprocessing as mp from functools import partial import typing -from typing import Union, Optional, TextIO, List, Sequence, Dict +from typing import Optional, Union, TextIO, Sequence, Dict from pathlib import Path import numpy as np import pandas as pd import h5py -from scipy import ndimage, spatial +from scipy import ndimage, spatial, interpolate from . import VTK from . import util @@ -18,7 +18,15 @@ from . import grid_filters from . import Rotation from . import Table from . import Colormap -from ._typehints import FloatSequence, IntSequence, IntCollection, NumpyRngSeed +from ._typehints import FloatSequence, IntSequence, NumpyRngSeed +try: + import numba as nb # type: ignore +except ImportError: + nb = False + +def numba_njit_wrapper(**kwargs): + return (lambda function: nb.njit(function) if nb else function) + class Grid: """ @@ -34,14 +42,14 @@ class Grid: material: np.ndarray, size: FloatSequence, origin: FloatSequence = np.zeros(3), - initial_conditions: Dict[str,np.ndarray] = None, - comments: Union[str, Sequence[str]] = None): + initial_conditions: Optional[Dict[str,np.ndarray]] = None, + comments: Union[None, str, Sequence[str]] = None): """ New geometry definition for grid solvers. Parameters ---------- - material : numpy.ndarray, shape (:,:,:) + material : numpy.ndarray of int, shape (:,:,:) Material indices. The shape of the material array defines the number of cells. size : sequence of float, len (3) @@ -50,16 +58,17 @@ class Grid: Coordinates of grid origin in meter. Defaults to [0.0,0.0,0.0]. initial_conditions : dictionary, optional Labels and values of the inital conditions at each material point. - comments : str or iterable of str, optional + comments : (sequence of) str, optional Additional, human-readable information, e.g. history of operations. """ self.material = material - self.size = size # type: ignore - self.origin = origin # type: ignore + self.size = size # type: ignore + self.origin = origin # type: ignore self.initial_conditions = {} if initial_conditions is None else initial_conditions - comments_ = [comments] if isinstance(comments,str) else comments - self.comments = [] if comments_ is None else [str(c) for c in comments_] + self.comments = [] if comments is None else \ + [comments] if isinstance(comments,str) else \ + [str(c) for c in comments] def __repr__(self) -> str: """ @@ -175,17 +184,6 @@ class Grid: self._ic = ic - @property - def comments(self) -> List[str]: - """Comments, e.g. history of operations.""" - return self._comments - - @comments.setter - def comments(self, - comments: Union[str, Sequence[str]]): - self._comments = [str(c) for c in comments] if isinstance(comments,list) else [str(comments)] - - @property def cells(self) -> np.ndarray: """Number of cells in x,y,z direction.""" @@ -218,14 +216,13 @@ class Grid: v = VTK.load(fname if str(fname).endswith('.vti') else str(fname)+'.vti') cells = np.array(v.vtk_data.GetDimensions())-1 bbox = np.array(v.vtk_data.GetBounds()).reshape(3,2).T - comments = v.comments ic = {label:v.get(label).reshape(cells,order='F') for label in set(v.labels['Cell Data']) - {'material'}} return Grid(material = v.get('material').reshape(cells,order='F'), size = bbox[1] - bbox[0], origin = bbox[0], initial_conditions = ic, - comments = comments, + comments = v.comments, ) @@ -348,9 +345,11 @@ class Grid: @staticmethod def load_DREAM3D(fname: Union[str, Path], - feature_IDs: str = None, cell_data: str = None, - phases: str = 'Phases', Euler_angles: str = 'EulerAngles', - base_group: str = None) -> 'Grid': + feature_IDs: Optional[str] = None, + cell_data: Optional[str] = None, + phases: str = 'Phases', + Euler_angles: str = 'EulerAngles', + base_group: Optional[str] = None) -> 'Grid': """ Load DREAM.3D (HDF5) file. @@ -427,7 +426,7 @@ class Grid: coordinates : str Label of the vector column containing the spatial coordinates. Need to be ordered (1./x fast, 3./z slow). - labels : (list of) str + labels : (sequence of) str Label(s) of the columns containing the material definition. Each unique combination of values results in one material ID. @@ -463,7 +462,7 @@ class Grid: size: FloatSequence, seeds: np.ndarray, weights: FloatSequence, - material: IntSequence = None, + material: Optional[IntSequence] = None, periodic: bool = True): """ Create grid from Laguerre tessellation. @@ -474,7 +473,7 @@ class Grid: Number of cells in x,y,z direction. size : sequence of float, len (3) Physical size of the grid in meter. - seeds : numpy.ndarray, shape (:,3) + seeds : numpy.ndarray of float, shape (:,3) Position of the seed points in meter. All points need to lay within the box. weights : sequence of float, len (seeds.shape[0]) Weights of the seeds. Setting all weights to 1.0 gives a standard Voronoi tessellation. @@ -520,7 +519,7 @@ class Grid: def from_Voronoi_tessellation(cells: IntSequence, size: FloatSequence, seeds: np.ndarray, - material: IntSequence = None, + material: Optional[IntSequence] = None, periodic: bool = True) -> 'Grid': """ Create grid from Voronoi tessellation. @@ -531,7 +530,7 @@ class Grid: Number of cells in x,y,z direction. size : sequence of float, len (3) Physical size of the grid in meter. - seeds : numpy.ndarray, shape (:,3) + seeds : numpy.ndarray of float, shape (:,3) Position of the seed points in meter. All points need to lay within the box. material : sequence of int, len (seeds.shape[0]), optional Material ID of the seeds. @@ -763,9 +762,9 @@ class Grid: def canvas(self, - cells: IntSequence = None, - offset: IntSequence = None, - fill: int = None) -> 'Grid': + cells: Optional[IntSequence] = None, + offset: Optional[IntSequence] = None, + fill: Optional[int] = None) -> 'Grid': """ Crop or enlarge/pad grid. @@ -901,7 +900,7 @@ class Grid: def rotate(self, R: Rotation, - fill: int = None) -> 'Grid': + fill: Optional[int] = None) -> 'Grid': """ Rotate grid (and pad if required). @@ -940,17 +939,14 @@ class Grid: def scale(self, - cells: IntSequence, - periodic: bool = True) -> 'Grid': + cells: IntSequence) -> 'Grid': """ - Scale grid to new cells. + Scale grid to new cell count. Parameters ---------- cells : sequence of int, len (3) Number of cells in x,y,z direction. - periodic : bool, optional - Assume grid to be periodic. Defaults to True. Returns ------- @@ -963,7 +959,11 @@ class Grid: >>> import numpy as np >>> import damask - >>> g = damask.Grid(np.zeros([32]*3,int),np.ones(3)*1e-4) + >>> (g := damask.Grid(np.zeros([32]*3,int),np.ones(3)*1e-4)) + cells: 32 × 32 × 32 + size: 0.0001 × 0.0001 × 0.0001 m³ + origin: 0.0 0.0 0.0 m + # materials: 1 >>> g.scale(g.cells*2) cells : 64 x 64 x 64 size : 0.0001 x 0.0001 x 0.0001 m³ @@ -971,20 +971,50 @@ class Grid: # materials: 1 """ - return Grid(material = ndimage.interpolation.zoom( - self.material, - cells/self.cells, - output=self.material.dtype, - order=0, - mode='wrap' if periodic else 'nearest', - prefilter=False - ), + orig = tuple(map(np.linspace,self.origin + self.size/self.cells*.5, + self.origin + self.size - self.size/self.cells*.5,self.cells)) + interpolator = partial(interpolate.RegularGridInterpolator, + points=orig,method='nearest',bounds_error=False,fill_value=None) + new = grid_filters.coordinates0_point(cells,self.size,self.origin) + + return Grid(material = interpolator(values=self.material)(new).astype(int), size = self.size, origin = self.origin, + initial_conditions = {k: interpolator(values=v)(new) + for k,v in self.initial_conditions.items()}, comments = self.comments+[util.execution_stamp('Grid','scale')], ) + def assemble(self, + idx: np.ndarray) -> 'Grid': + """ + Assemble new grid from index map. + + Parameters + ---------- + idx : numpy.ndarray of int, shape (:,:,:) or (:,:,:,3) + Grid of flat indices or coordinate indices. + + Returns + ------- + updated : damask.Grid + Updated grid-based geometry. + Cell count of resulting grid matches shape of index map. + + """ + cells = idx.shape[:3] + flat = (idx if len(idx.shape)==3 else grid_filters.ravel_index(idx)).flatten(order='F') + ic = {k: v.flatten(order='F')[flat].reshape(cells,order='F') for k,v in self.initial_conditions.items()} + + return Grid(material = self.material.flatten(order='F')[flat].reshape(cells,order='F'), + size = self.size, + origin = self.origin, + initial_conditions = ic, + comments = self.comments+[util.execution_stamp('Grid','assemble')], + ) + + def renumber(self) -> 'Grid': """ Renumber sorted material indices as 0,...,N-1. @@ -1013,9 +1043,9 @@ class Grid: Parameters ---------- - from_material : int or sequence of int + from_material : (sequence of) int Material indices to be substituted. - to_material : int or sequence of int + to_material : (sequence of) int New material indices. Returns @@ -1062,10 +1092,10 @@ class Grid: def clean(self, distance: float = np.sqrt(3), - selection: IntCollection = None, + selection: Optional[IntSequence] = None, invert_selection: bool = False, periodic: bool = True, - rng_seed: NumpyRngSeed = None) -> 'Grid': + rng_seed: Optional[NumpyRngSeed] = None) -> 'Grid': """ Smooth grid by selecting most frequent material ID within given stencil at each location. @@ -1074,7 +1104,7 @@ class Grid: distance : float, optional Voxel distance checked for presence of other materials. Defaults to sqrt(3). - selection : int or collection of int, optional + selection : (sequence of) int, optional Material IDs to consider. Defaults to all. invert_selection : bool, optional Consider all material IDs except those in selection. Defaults to False. @@ -1095,8 +1125,8 @@ class Grid: """ def most_frequent(stencil: np.ndarray, - selection: Union[None,set], - rng): + selection: Union[None,np.ndarray], + rng: np.random.Generator): me = stencil[stencil.size//2] if selection is None or me in selection: unique, counts = np.unique(stencil,return_counts=True) @@ -1111,15 +1141,15 @@ class Grid: xx,yy,zz = np.meshgrid(ext,ext,ext) footprint = xx**2+yy**2+zz**2 <= distance**2+distance*1e-8 selection_ = None if selection is None else \ - set(self.material.flatten()) - set(util.aslist(selection)) if invert_selection else \ - set(self.material.flatten()) & set(util.aslist(selection)) - material = ndimage.filters.generic_filter( - self.material, - most_frequent, - footprint=footprint, - mode='wrap' if periodic else 'nearest', - extra_keywords=dict(selection=selection_,rng=rng), - ).astype(self.material.dtype) + np.setdiff1d(self.material,selection) if invert_selection else \ + np.intersect1d(self.material,selection) + material = ndimage.generic_filter( + self.material, + most_frequent, + footprint=footprint, + mode='wrap' if periodic else 'nearest', + extra_keywords=dict(selection=selection_,rng=rng), + ).astype(self.material.dtype) return Grid(material = material, size = self.size, origin = self.origin, @@ -1132,7 +1162,7 @@ class Grid: dimension: Union[FloatSequence, IntSequence], center: Union[FloatSequence, IntSequence], exponent: Union[FloatSequence, float], - fill: int = None, + fill: Optional[int] = None, R: Rotation = Rotation(), inverse: bool = False, periodic: bool = True) -> 'Grid': @@ -1149,7 +1179,7 @@ class Grid: Center of the primitive. If given as integers, cell centers are addressed. If given as floats, physical coordinates are addressed. - exponent : float or sequence of float, len (3) + exponent : (sequence of) float, len (3) Exponents for the three axes. 0 gives octahedron (ǀxǀ^(2^0) + ǀyǀ^(2^0) + ǀzǀ^(2^0) < 1) 1 gives sphere (ǀxǀ^(2^1) + ǀyǀ^(2^1) + ǀzǀ^(2^1) < 1) @@ -1223,8 +1253,8 @@ class Grid: def vicinity_offset(self, distance: float = np.sqrt(3), - offset: int = None, - selection: IntCollection = None, + offset: Optional[int] = None, + selection: Optional[IntSequence] = None, invert_selection: bool = False, periodic: bool = True) -> 'Grid': """ @@ -1241,7 +1271,7 @@ class Grid: offset : int, optional Offset (positive or negative) to tag material IDs. Defaults to material.max()+1. - selection : int or collection of int, optional + selection : (sequence of) int, optional Material IDs that trigger an offset. Defaults to any other than own material ID. invert_selection : bool, optional @@ -1256,25 +1286,33 @@ class Grid: Updated grid-based geometry. """ - def tainted_neighborhood(stencil: np.ndarray, selection: Union[None,set]): + @numba_njit_wrapper() + def tainted_neighborhood(stencil: np.ndarray, + selection: Optional[np.ndarray] = None): me = stencil[stencil.size//2] - return np.any(stencil != me if selection is None else - np.in1d(stencil,np.array(list(selection - {me})))) - + if selection is None: + return np.any(stencil != me) + elif not len(selection)==0: + for stencil_item in stencil: + for selection_item in selection: + if stencil_item==selection_item and selection_item!=me: + return True + return False d = np.floor(distance).astype(np.int64) ext = np.linspace(-d,d,1+2*d,dtype=float), xx,yy,zz = np.meshgrid(ext,ext,ext) footprint = xx**2+yy**2+zz**2 <= distance**2+distance*1e-8 offset_ = np.nanmax(self.material)+1 if offset is None else offset selection_ = None if selection is None else \ - set(self.material.flatten()) - set(util.aslist(selection)) if invert_selection else \ - set(self.material.flatten()) & set(util.aslist(selection)) - mask = ndimage.filters.generic_filter(self.material, - tainted_neighborhood, - footprint=footprint, - mode='wrap' if periodic else 'nearest', - extra_keywords=dict(selection=selection_), - ) + np.setdiff1d(self.material,selection) if invert_selection else \ + np.intersect1d(self.material,selection) + + mask = ndimage.generic_filter(self.material, + tainted_neighborhood, + footprint=footprint, + mode='wrap' if periodic else 'nearest', + extra_keywords=dict(selection=selection_), + ) return Grid(material = np.where(mask, self.material + offset_,self.material), size = self.size, diff --git a/python/damask/_orientation.py b/python/damask/_orientation.py index 8bbcb7957..2206d5b2a 100644 --- a/python/damask/_orientation.py +++ b/python/damask/_orientation.py @@ -1,6 +1,6 @@ import inspect import copy -from typing import Union, Callable, Dict, Any, Tuple, TypeVar +from typing import Optional, Union, Callable, Dict, Any, Tuple, TypeVar import numpy as np @@ -94,14 +94,14 @@ class Orientation(Rotation,Crystal): """ - @util.extend_docstring(_parameter_doc) + @util.extend_docstring(extra_parameters=_parameter_doc) def __init__(self, rotation: Union[FloatSequence, Rotation] = np.array([1.,0.,0.,0.]), *, - family: CrystalFamily = None, - lattice: CrystalLattice = None, - a: float = None, b: float = None, c: float = None, - alpha: float = None, beta: float = None, gamma: float = None, + family: Optional[CrystalFamily] = None, + lattice: Optional[CrystalLattice] = None, + a: Optional[float] = None, b: Optional[float] = None, c: Optional[float] = None, + alpha: Optional[float] = None, beta: Optional[float] = None, gamma: Optional[float] = None, degrees: bool = False): """ New orientation. @@ -131,7 +131,7 @@ class Orientation(Rotation,Crystal): def __copy__(self: MyType, - rotation: Union[FloatSequence, Rotation] = None) -> MyType: + rotation: Union[None, FloatSequence, Rotation] = None) -> MyType: """ Return deepcopy(self). @@ -300,84 +300,95 @@ class Orientation(Rotation,Crystal): @classmethod - @util.extended_docstring(Rotation.from_random, _parameter_doc) + @util.extend_docstring(Rotation.from_random, + extra_parameters=_parameter_doc) def from_random(cls, **kwargs) -> 'Orientation': kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_random) return cls(rotation=Rotation.from_random(**kwargs_rot),**kwargs_ori) @classmethod - @util.extended_docstring(Rotation.from_quaternion,_parameter_doc) + @util.extend_docstring(Rotation.from_quaternion, + extra_parameters=_parameter_doc) def from_quaternion(cls, **kwargs) -> 'Orientation': kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_quaternion) return cls(rotation=Rotation.from_quaternion(**kwargs_rot),**kwargs_ori) @classmethod - @util.extended_docstring(Rotation.from_Euler_angles,_parameter_doc) + @util.extend_docstring(Rotation.from_Euler_angles, + extra_parameters=_parameter_doc) def from_Euler_angles(cls, **kwargs) -> 'Orientation': kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_Euler_angles) return cls(rotation=Rotation.from_Euler_angles(**kwargs_rot),**kwargs_ori) @classmethod - @util.extended_docstring(Rotation.from_axis_angle,_parameter_doc) + @util.extend_docstring(Rotation.from_axis_angle, + extra_parameters=_parameter_doc) def from_axis_angle(cls, **kwargs) -> 'Orientation': kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_axis_angle) return cls(rotation=Rotation.from_axis_angle(**kwargs_rot),**kwargs_ori) @classmethod - @util.extended_docstring(Rotation.from_basis,_parameter_doc) + @util.extend_docstring(Rotation.from_basis, + extra_parameters=_parameter_doc) def from_basis(cls, **kwargs) -> 'Orientation': kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_basis) return cls(rotation=Rotation.from_basis(**kwargs_rot),**kwargs_ori) @classmethod - @util.extended_docstring(Rotation.from_matrix,_parameter_doc) + @util.extend_docstring(Rotation.from_matrix, + extra_parameters=_parameter_doc) def from_matrix(cls, **kwargs) -> 'Orientation': kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_matrix) return cls(rotation=Rotation.from_matrix(**kwargs_rot),**kwargs_ori) @classmethod - @util.extended_docstring(Rotation.from_Rodrigues_vector,_parameter_doc) + @util.extend_docstring(Rotation.from_Rodrigues_vector, + extra_parameters=_parameter_doc) def from_Rodrigues_vector(cls, **kwargs) -> 'Orientation': kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_Rodrigues_vector) return cls(rotation=Rotation.from_Rodrigues_vector(**kwargs_rot),**kwargs_ori) @classmethod - @util.extended_docstring(Rotation.from_homochoric,_parameter_doc) + @util.extend_docstring(Rotation.from_homochoric, + extra_parameters=_parameter_doc) def from_homochoric(cls, **kwargs) -> 'Orientation': kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_homochoric) return cls(rotation=Rotation.from_homochoric(**kwargs_rot),**kwargs_ori) @classmethod - @util.extended_docstring(Rotation.from_cubochoric,_parameter_doc) + @util.extend_docstring(Rotation.from_cubochoric, + extra_parameters=_parameter_doc) def from_cubochoric(cls, **kwargs) -> 'Orientation': kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_cubochoric) return cls(rotation=Rotation.from_cubochoric(**kwargs_rot),**kwargs_ori) @classmethod - @util.extended_docstring(Rotation.from_spherical_component,_parameter_doc) + @util.extend_docstring(Rotation.from_spherical_component, + extra_parameters=_parameter_doc) def from_spherical_component(cls, **kwargs) -> 'Orientation': kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_spherical_component) return cls(rotation=Rotation.from_spherical_component(**kwargs_rot),**kwargs_ori) @classmethod - @util.extended_docstring(Rotation.from_fiber_component,_parameter_doc) + @util.extend_docstring(Rotation.from_fiber_component, + extra_parameters=_parameter_doc) def from_fiber_component(cls, **kwargs) -> 'Orientation': kwargs_rot,kwargs_ori = Orientation._split_kwargs(kwargs,Rotation.from_fiber_component) return cls(rotation=Rotation.from_fiber_component(**kwargs_rot),**kwargs_ori) @classmethod - @util.extend_docstring(_parameter_doc) + @util.extend_docstring(extra_parameters=_parameter_doc) def from_directions(cls, uvw: FloatSequence, hkl: FloatSequence, @@ -392,6 +403,10 @@ class Orientation(Rotation,Crystal): hkl : numpy.ndarray, shape (...,3) Lattice plane normal aligned with lab frame z-direction. + Returns + ------- + new : damask.Orientation + """ o = cls(**kwargs) x = o.to_frame(uvw=uvw) @@ -538,8 +553,7 @@ class Orientation(Rotation,Crystal): Notes ----- - Currently requires same crystal family for both orientations. - For extension to cases with differing symmetry see A. Heinz and P. Neumann 1991 and 10.1107/S0021889808016373. + Requires same crystal family for both orientations. Examples -------- @@ -569,6 +583,8 @@ class Orientation(Rotation,Crystal): >>> plt.show() """ + # For extension to cases with differing symmetry see + # https://doi.org/10.1107/S0021889808016373 and https://doi.org/10.1107/S0108767391006864 if self.family != other.family: raise NotImplementedError('disorientation between different crystal families') @@ -601,7 +617,7 @@ class Orientation(Rotation,Crystal): def average(self, - weights: FloatSequence = None, + weights: Optional[FloatSequence] = None, return_cloud: bool = False): """ Return orientation average over last dimension. @@ -611,7 +627,7 @@ class Orientation(Rotation,Crystal): weights : numpy.ndarray, shape (self.shape), optional Relative weights of orientations. return_cloud : bool, optional - Return the set of symmetrically equivalent orientations that was used in averaging. + Return the specific (symmetrically equivalent) orientations that were averaged. Defaults to False. Returns @@ -619,7 +635,7 @@ class Orientation(Rotation,Crystal): average : Orientation Weighted average of original Orientation field. cloud : Orientations, conditional - Set of symmetrically equivalent orientations that were used in averaging. + Symmetrically equivalent version of each orientation that were actually used in averaging. References ---------- @@ -644,7 +660,7 @@ class Orientation(Rotation,Crystal): proper: bool = False, return_operators: bool = False) -> np.ndarray: """ - Rotate vector to ensure it falls into (improper or proper) standard stereographic triangle of crystal symmetry. + Rotate lab frame vector to ensure it falls into (improper or proper) standard stereographic triangle of crystal symmetry. Parameters ---------- @@ -663,7 +679,7 @@ class Orientation(Rotation,Crystal): ------- vector_SST : numpy.ndarray, shape (...,3) Rotated vector falling into SST. - operators : numpy.ndarray of int, shape (...), conditional + operator : numpy.ndarray of int, shape (...), conditional Index of symmetrically equivalent orientation that rotated vector to SST. """ @@ -733,12 +749,12 @@ class Orientation(Rotation,Crystal): in_SST: bool = True, proper: bool = False) -> np.ndarray: """ - Map vector to RGB color within standard stereographic triangle of own symmetry. + Map lab frame vector to RGB color within standard stereographic triangle of own symmetry. Parameters ---------- vector : numpy.ndarray, shape (...,3) - Vector to colorize. + Lab frame vector to colorize. Shape of vector blends with shape of own rotation array. For example, a rotation array of shape (3,2) and a vector array of shape (2,4) result in (3,2,4) outputs. in_SST : bool, optional @@ -755,13 +771,26 @@ class Orientation(Rotation,Crystal): Examples -------- - Inverse pole figure color of the e_3 direction for a crystal in "Cube" orientation with cubic symmetry: + Inverse pole figure color of the e_3 lab direction for a + crystal in "Cube" orientation with cubic symmetry: >>> import damask >>> o = damask.Orientation(family='cubic') >>> o.IPF_color([0,0,1]) array([1., 0., 0.]) + Sample standard triangle for hexagonal symmetry: + + >>> import damask + >>> from matplotlib import pyplot as plt + >>> lab = [0,0,1] + >>> o = damask.Orientation.from_random(shape=500000,family='hexagonal') + >>> coord = damask.util.project_equal_area(o.to_SST(lab)) + >>> color = o.IPF_color(lab) + >>> plt.scatter(coord[:,0],coord[:,1],color=color,s=.06) + >>> plt.axis('scaled') + >>> plt.show() + """ if np.array(vector).shape[-1] != 3: raise ValueError('input is not a field of three-dimensional vectors') @@ -791,7 +820,7 @@ class Orientation(Rotation,Crystal): in_SST_ = np.all(components >= 0.0,axis=-1) with np.errstate(invalid='ignore',divide='ignore'): - rgb = (components/np.linalg.norm(components,axis=-1,keepdims=True))**0.5 # smoothen color ramps + rgb = (components/np.linalg.norm(components,axis=-1,keepdims=True))**(1./3.) # smoothen color ramps rgb = np.clip(rgb,0.,1.) # clip intensity rgb /= np.max(rgb,axis=-1,keepdims=True) # normalize to (HS)V = 1 rgb[np.broadcast_to(~in_SST_[...,np.newaxis],rgb.shape)] = 0.0 @@ -803,8 +832,8 @@ class Orientation(Rotation,Crystal): # functions that require lattice, not just family def to_pole(self, *, - uvw: FloatSequence = None, - hkl: FloatSequence = None, + uvw: Optional[FloatSequence] = None, + hkl: Optional[FloatSequence] = None, with_symmetry: bool = False, normalize: bool = True) -> np.ndarray: """ @@ -845,8 +874,8 @@ class Orientation(Rotation,Crystal): def Schmid(self, *, - N_slip: IntSequence = None, - N_twin: IntSequence = None) -> np.ndarray: + N_slip: Optional[IntSequence] = None, + N_twin: Optional[IntSequence] = None) -> np.ndarray: u""" Calculate Schmid matrix P = d ⨂ n in the lab frame for selected deformation systems. diff --git a/python/damask/_result.py b/python/damask/_result.py index d991e898c..c545b52e8 100644 --- a/python/damask/_result.py +++ b/python/damask/_result.py @@ -11,7 +11,7 @@ from pathlib import Path from functools import partial from collections import defaultdict from collections.abc import Iterable -from typing import Union, Callable, Any, Sequence, Literal, Dict, List, Tuple +from typing import Optional, Union, Callable, Any, Sequence, Literal, Dict, List, Tuple import h5py import numpy as np @@ -109,7 +109,7 @@ class Result: if self.version_major != 0 or not 12 <= self.version_minor <= 14: raise TypeError(f'unsupported DADF5 version "{self.version_major}.{self.version_minor}"') if self.version_major == 0 and self.version_minor < 14: - self.export_setup = None # type: ignore + self.export_simulation_setup = None # type: ignore self.structured = 'cells' in f['geometry'].attrs.keys() @@ -122,7 +122,7 @@ class Result: r = re.compile(rf'{prefix_inc}([0-9]+)') self.increments = sorted([i for i in f.keys() if r.match(i)],key=util.natural_sort) - self.times = [round(f[i].attrs['t/s'],12) for i in self.increments] + self.times = np.around([f[i].attrs['t/s'] for i in self.increments],12) if len(self.increments) == 0: raise ValueError('incomplete DADF5 file') @@ -189,11 +189,11 @@ class Result: def _manage_view(self, action: Literal['set', 'add', 'del'], - increments: Union[int, Sequence[int], str, Sequence[str], bool] = None, - times: Union[float, Sequence[float], str, Sequence[str], bool] = None, - phases: Union[str, Sequence[str], bool] = None, - homogenizations: Union[str, Sequence[str], bool] = None, - fields: Union[str, Sequence[str], bool] = None) -> "Result": + increments: Union[None, int, Sequence[int], str, Sequence[str], bool] = None, + times: Union[None, float, Sequence[float], str, Sequence[str], bool] = None, + phases: Union[None, str, Sequence[str], bool] = None, + homogenizations: Union[None, str, Sequence[str], bool] = None, + fields: Union[None, str, Sequence[str], bool] = None) -> "Result": """ Manages the visibility of the groups. @@ -228,19 +228,19 @@ class Result: self.increments[c] if isinstance(c,int) and c<0 else f'{prefix_inc}{c}' for c in choice] elif what == 'times': + atol = 1e-2 * np.min(np.diff(self.times)) what = 'increments' if choice == ['*']: choice = self.increments else: - iterator = map(float,choice) # type: ignore + iterator = np.array(choice).astype(float) choice = [] for c in iterator: - idx = np.searchsorted(self.times,c) - if idx >= len(self.times): continue - if np.isclose(c,self.times[idx]): + idx = np.searchsorted(self.times,c,side='left') + if idx0 and np.isclose(c,self.times[idx-1],rtol=0,atol=atol): + choice.append(self.increments[idx-1]) valid = _match(choice,getattr(self,what)) existing = set(self.visible[what]) @@ -248,18 +248,16 @@ class Result: if action == 'set': dup.visible[what] = sorted(set(valid), key=util.natural_sort) elif action == 'add': - add = existing.union(valid) - dup.visible[what] = sorted(add, key=util.natural_sort) + dup.visible[what] = sorted(existing.union(valid), key=util.natural_sort) elif action == 'del': - diff = existing.difference(valid) - dup.visible[what] = sorted(diff, key=util.natural_sort) + dup.visible[what] = sorted(existing.difference(valid), key=util.natural_sort) return dup def increments_in_range(self, - start: Union[str, int] = None, - end: Union[str, int] = None) -> Sequence[int]: + start: Union[None, str, int] = None, + end: Union[None, str, int] = None) -> Sequence[int]: """ Get all increments within a given range. @@ -276,23 +274,23 @@ class Result: Increment number of all increments within the given bounds. """ - s,e = map(lambda x: int(x[10:] if isinstance(x,str) and x.startswith(prefix_inc) else x), + s,e = map(lambda x: int(x.split(prefix_inc)[-1] if isinstance(x,str) and x.startswith(prefix_inc) else x), (self.incs[ 0] if start is None else start, self.incs[-1] if end is None else end)) return [i for i in self.incs if s <= i <= e] def times_in_range(self, - start: float = None, - end: float = None) -> Sequence[int]: + start: Optional[float] = None, + end: Optional[float] = None) -> Sequence[float]: """ - Get all increments within a given time range. + Get times of all increments within a given time range. Parameters ---------- start : float, optional - Time of start increment. Defaults to first. + Time of start increment. Defaults to time of first. end : float, optional - Time of end increment. Defaults to last. + Time of end increment. Defaults to time of last. Returns ------- @@ -306,12 +304,12 @@ class Result: def view(self,*, - increments: Union[int, Sequence[int], str, Sequence[str], bool] = None, - times: Union[float, Sequence[float], str, Sequence[str], bool] = None, - phases: Union[str, Sequence[str], bool] = None, - homogenizations: Union[str, Sequence[str], bool] = None, - fields: Union[str, Sequence[str], bool] = None, - protected: bool = None) -> "Result": + increments: Union[None, int, Sequence[int], str, Sequence[str], bool] = None, + times: Union[None, float, Sequence[float], str, Sequence[str], bool] = None, + phases: Union[None, str, Sequence[str], bool] = None, + homogenizations: Union[None, str, Sequence[str], bool] = None, + fields: Union[None, str, Sequence[str], bool] = None, + protected: Optional[bool] = None) -> "Result": """ Set view. @@ -363,11 +361,11 @@ class Result: def view_more(self,*, - increments: Union[int, Sequence[int], str, Sequence[str], bool] = None, - times: Union[float, Sequence[float], str, Sequence[str], bool] = None, - phases: Union[str, Sequence[str], bool] = None, - homogenizations: Union[str, Sequence[str], bool] = None, - fields: Union[str, Sequence[str], bool] = None) -> "Result": + increments: Union[None, int, Sequence[int], str, Sequence[str], bool] = None, + times: Union[None, float, Sequence[float], str, Sequence[str], bool] = None, + phases: Union[None, str, Sequence[str], bool] = None, + homogenizations: Union[None, str, Sequence[str], bool] = None, + fields: Union[None, str, Sequence[str], bool] = None) -> "Result": """ Add to view. @@ -406,11 +404,11 @@ class Result: def view_less(self,*, - increments: Union[int, Sequence[int], str, Sequence[str], bool] = None, - times: Union[float, Sequence[float], str, Sequence[str], bool] = None, - phases: Union[str, Sequence[str], bool] = None, - homogenizations: Union[str, Sequence[str], bool] = None, - fields: Union[str, Sequence[str], bool] = None) -> "Result": + increments: Union[None, int, Sequence[int], str, Sequence[str], bool] = None, + times: Union[None, float, Sequence[float], str, Sequence[str], bool] = None, + phases: Union[None, str, Sequence[str], bool] = None, + homogenizations: Union[None, str, Sequence[str], bool] = None, + fields: Union[None, str, Sequence[str], bool] = None) -> "Result": """ Remove from view. @@ -561,6 +559,14 @@ class Result: print(f'Function {func.__name__} enabled in add_calculation.') + @property + def simulation_setup_files(self): + """Simulation setup files used to generate the Result object.""" + files = [] + with h5py.File(self.fname,'r') as f_in: + f_in['setup'].visititems(lambda name,obj: files.append(name) if isinstance(obj,h5py.Dataset) else None) + return files + @property def incs(self): return [int(i.split(prefix_inc)[-1]) for i in self.increments] @@ -644,7 +650,7 @@ class Result: formula: str, name: str, unit: str = 'n/a', - description: str = None): + description: Optional[str] = None): """ Add result of a general formula. @@ -817,7 +823,7 @@ class Result: ---------- T_sym : str Name of symmetric tensor dataset. - eigenvalue : {'max', 'mid', 'min'} + eigenvalue : {'max', 'mid', 'min'}, optional Eigenvalue. Defaults to 'max'. Examples @@ -863,7 +869,7 @@ class Result: ---------- T_sym : str Name of symmetric tensor dataset. - eigenvalue : {'max', 'mid', 'min'} + eigenvalue : {'max', 'mid', 'min'}, optional Eigenvalue to which the eigenvector corresponds. Defaults to 'max'. @@ -897,7 +903,7 @@ class Result: ---------- l : numpy.array of shape (3) Lab frame direction for inverse pole figure. - q : str + q : str, optional Name of the dataset containing the crystallographic orientation as quaternions. Defaults to 'O'. @@ -960,7 +966,7 @@ class Result: } def add_equivalent_Mises(self, T_sym: str, - kind: str = None): + kind: Optional[str] = None): """ Add the equivalent Mises stress or strain of a symmetric tensor. @@ -1015,7 +1021,7 @@ class Result: } def add_norm(self, x: str, - ord: Union[int, float, Literal['fro', 'nuc']] = None): + ord: Union[None, int, float, Literal['fro', 'nuc']] = None): """ Add the norm of vector or tensor. @@ -1095,8 +1101,8 @@ class Result: def add_pole(self, q: str = 'O', *, - uvw: FloatSequence = None, - hkl: FloatSequence = None, + uvw: Optional[FloatSequence] = None, + hkl: Optional[FloatSequence] = None, with_symmetry: bool = False, normalize: bool = True): """ @@ -1104,7 +1110,7 @@ class Result: Parameters ---------- - q : str + q : str, optional Name of the dataset containing the crystallographic orientation as quaternions. Defaults to 'O'. uvw|hkl : numpy.ndarray of shape (3) @@ -1188,12 +1194,14 @@ class Result: @staticmethod def _add_strain(F: Dict[str, Any], t: Literal['V', 'U'], m: float) -> Dict[str, Any]: + side = 'left' if t == 'V' else 'right' return { 'data': mechanics.strain(F['data'],t,m), 'label': f"epsilon_{t}^{m}({F['label']})", 'meta': { 'unit': F['meta']['unit'], - 'description': f"strain tensor of {F['label']} ({F['meta']['description']})", + 'description': f'strain tensor of order {m} based on {side} stretch tensor '+\ + f"of {F['label']} ({F['meta']['description']})", 'creator': 'add_strain' } } @@ -1218,18 +1226,24 @@ class Result: Examples -------- - Add the Biot strain based on the deformation gradient 'F': + Add the Euler-Almansi strain: >>> import damask >>> r = damask.Result('my_file.hdf5') - >>> r.add_strain(t='U',m=0.5) + >>> r.add_strain(t='V',m=-1.0) - Add the plastic Euler-Almansi strain based on the - plastic deformation gradient 'F_p': + Add the plastic Biot strain: >>> import damask >>> r = damask.Result('my_file.hdf5') - >>> r.add_strain('F_p','V',-1) + >>> r.add_strain('F_p','U',0.5) + + Notes + ----- + The incoporation of rotational parts into the elastic and plastic + deformation gradient requires it to use material/Lagragian strain measures + (based on 'U') for plastic strains and spatial/Eulerian strain measures + (based on 'V') for elastic strains when calculating averages. """ self._add_generic_pointwise(self._add_strain,{'F':F},{'t':t,'m':m}) @@ -1515,121 +1529,6 @@ class Result: pool.join() - def export_XDMF(self, - output: Union[str, List[str]] = '*'): - """ - Write XDMF file to directly visualize data from DADF5 file. - - The XDMF format is only supported for structured grids - with single phase and single constituent. - For other cases use `export_VTK`. - - Parameters - ---------- - output : (list of) str - Names of the datasets included in the XDMF file. - Defaults to '*', in which case all datasets are considered. - - """ - if self.N_constituents != 1 or len(self.phases) != 1 or not self.structured: - raise TypeError('XDMF output requires structured grid with single phase and single constituent.') - - - attribute_type_map = defaultdict(lambda:'Matrix', ( ((),'Scalar'), ((3,),'Vector'), ((3,3),'Tensor')) ) - - def number_type_map(dtype): - if dtype in np.sctypes['int']: return 'Int' - if dtype in np.sctypes['uint']: return 'UInt' - if dtype in np.sctypes['float']: return 'Float' - - - xdmf = ET.Element('Xdmf') - xdmf.attrib={'Version': '2.0', - 'xmlns:xi': 'http://www.w3.org/2001/XInclude'} - - domain = ET.SubElement(xdmf, 'Domain') - - collection = ET.SubElement(domain, 'Grid') - collection.attrib={'GridType': 'Collection', - 'CollectionType': 'Temporal', - 'Name': 'Increments'} - - time = ET.SubElement(collection, 'Time') - time.attrib={'TimeType': 'List'} - - time_data = ET.SubElement(time, 'DataItem') - times = [self.times[self.increments.index(i)] for i in self.visible['increments']] - time_data.attrib={'Format': 'XML', - 'NumberType': 'Float', - 'Dimensions': f'{len(times)}'} - time_data.text = ' '.join(map(str,times)) - - attributes = [] - data_items = [] - - with h5py.File(self.fname,'r') as f: - for inc in self.visible['increments']: - - grid = ET.SubElement(collection,'Grid') - grid.attrib = {'GridType': 'Uniform', - 'Name': inc} - - topology = ET.SubElement(grid, 'Topology') - topology.attrib = {'TopologyType': '3DCoRectMesh', - 'Dimensions': '{} {} {}'.format(*(self.cells[::-1]+1))} - - geometry = ET.SubElement(grid, 'Geometry') - geometry.attrib = {'GeometryType':'Origin_DxDyDz'} - - origin = ET.SubElement(geometry, 'DataItem') - origin.attrib = {'Format': 'XML', - 'NumberType': 'Float', - 'Dimensions': '3'} - origin.text = "{} {} {}".format(*self.origin[::-1]) - - delta = ET.SubElement(geometry, 'DataItem') - delta.attrib = {'Format': 'XML', - 'NumberType': 'Float', - 'Dimensions': '3'} - delta.text="{} {} {}".format(*(self.size/self.cells)[::-1]) - - attributes.append(ET.SubElement(grid, 'Attribute')) - attributes[-1].attrib = {'Name': 'u / m', - 'Center': 'Node', - 'AttributeType': 'Vector'} - data_items.append(ET.SubElement(attributes[-1], 'DataItem')) - data_items[-1].attrib = {'Format': 'HDF', - 'Precision': '8', - 'Dimensions': '{} {} {} 3'.format(*(self.cells[::-1]+1))} - data_items[-1].text = f'{os.path.split(self.fname)[1]}:/{inc}/geometry/u_n' - - for ty in ['phase','homogenization']: - for label in self.visible[ty+'s']: - for field in _match(self.visible['fields'],f['/'.join([inc,ty,label])].keys()): - for out in _match(output,f['/'.join([inc,ty,label,field])].keys()): - name = '/'.join([inc,ty,label,field,out]) - shape = f[name].shape[1:] - dtype = f[name].dtype - - unit = f[name].attrs['unit'] if h5py3 else \ - f[name].attrs['unit'].decode() - - attributes.append(ET.SubElement(grid, 'Attribute')) - attributes[-1].attrib = {'Name': '/'.join([ty,field,out])+f' / {unit}', - 'Center': 'Cell', - 'AttributeType': attribute_type_map[shape]} - data_items.append(ET.SubElement(attributes[-1], 'DataItem')) - data_items[-1].attrib = {'Format': 'HDF', - 'NumberType': number_type_map(dtype), - 'Precision': f'{dtype.itemsize}', - 'Dimensions': '{} {} {} {}'.format(*self.cells[::-1],1 if shape == () else - np.prod(shape))} - data_items[-1].text = f'{os.path.split(self.fname)[1]}:{name}' - - with util.open_text(self.fname.with_suffix('.xdmf').name,'w') as f: - f.write(xml.dom.minidom.parseString(ET.tostring(xdmf).decode()).toprettyxml()) - - def _mappings(self): """Mappings to place data spatially.""" with h5py.File(self.fname,'r') as f: @@ -1650,120 +1549,23 @@ class Result: return at_cell_ph,in_data_ph,at_cell_ho,in_data_ho - def export_VTK(self, - output: Union[str,list] = '*', - mode: str = 'cell', - constituents: IntSequence = None, - fill_float: float = np.nan, - fill_int: int = 0, - parallel: bool = True): - """ - Export to VTK cell/point data. - - One VTK file per visible increment is created. - For point data, the VTK format is poly data (.vtp). - For cell data, either an image (.vti) or unstructured (.vtu) dataset - is written for grid-based or mesh-based simulations, respectively. - - Parameters - ---------- - output : (list of) str, optional - Names of the datasets to export to the VTK file. - Defaults to '*', in which case all datasets are exported. - mode : {'cell', 'point'} - Export in cell format or point format. - Defaults to 'cell'. - constituents : (list of) int, optional - Constituents to consider. - Defaults to None, in which case all constituents are considered. - fill_float : float - Fill value for non-existent entries of floating point type. - Defaults to NaN. - fill_int : int - Fill value for non-existent entries of integer type. - Defaults to 0. - parallel : bool - Write VTK files in parallel in a separate background process. - Defaults to True. - - """ - if mode.lower()=='cell': - v = self.geometry0 - elif mode.lower()=='point': - v = VTK.from_poly_data(self.coordinates0_point) - else: - raise ValueError(f'invalid mode "{mode}"') - - v.comments = [util.execution_stamp('Result','export_VTK')] - - N_digits = int(np.floor(np.log10(max(1,self.incs[-1]))))+1 - - constituents_ = constituents if isinstance(constituents,Iterable) else \ - (range(self.N_constituents) if constituents is None else [constituents]) # type: ignore - - suffixes = [''] if self.N_constituents == 1 or isinstance(constituents,int) else \ - [f'#{c}' for c in constituents_] - - at_cell_ph,in_data_ph,at_cell_ho,in_data_ho = self._mappings() - - with h5py.File(self.fname,'r') as f: - if self.version_minor >= 13: - creator = f.attrs['creator'] if h5py3 else f.attrs['creator'].decode() - created = f.attrs['created'] if h5py3 else f.attrs['created'].decode() - v.comments += f'{creator} ({created})' - - for inc in util.show_progress(self.visible['increments']): - - u = _read(f['/'.join([inc,'geometry','u_n' if mode.lower() == 'cell' else 'u_p'])]) - v = v.set('u',u) - - for ty in ['phase','homogenization']: - for field in self.visible['fields']: - outs: Dict[str, np.ma.core.MaskedArray] = {} - for label in self.visible[ty+'s']: - if field not in f['/'.join([inc,ty,label])].keys(): continue - - for out in _match(output,f['/'.join([inc,ty,label,field])].keys()): - data = ma.array(_read(f['/'.join([inc,ty,label,field,out])])) - - if ty == 'phase': - if out+suffixes[0] not in outs.keys(): - for c,suffix in zip(constituents_,suffixes): - outs[out+suffix] = \ - _empty_like(data,self.N_materialpoints,fill_float,fill_int) - - for c,suffix in zip(constituents_,suffixes): - outs[out+suffix][at_cell_ph[c][label]] = data[in_data_ph[c][label]] - - if ty == 'homogenization': - if out not in outs.keys(): - outs[out] = _empty_like(data,self.N_materialpoints,fill_float,fill_int) - - outs[out][at_cell_ho[label]] = data[in_data_ho[label]] - - for label,dataset in outs.items(): - v = v.set(' / '.join(['/'.join([ty,field,label]),dataset.dtype.metadata['unit']]),dataset) - - v.save(f'{self.fname.stem}_inc{inc[10:].zfill(N_digits)}',parallel=parallel) - - def get(self, output: Union[str, List[str]] = '*', flatten: bool = True, - prune: bool = True): + prune: bool = True) -> Optional[Dict[str,Any]]: """ Collect data per phase/homogenization reflecting the group/folder structure in the DADF5 file. Parameters ---------- - output : (list of) str + output : (list of) str, optional Names of the datasets to read. Defaults to '*', in which case all datasets are read. - flatten : bool + flatten : bool, optional Remove singular levels of the folder hierarchy. This might be beneficial in case of single increment, phase/homogenization, or field. Defaults to True. - prune : bool + prune : bool, optional Remove branches with no data. Defaults to True. Returns @@ -1772,7 +1574,7 @@ class Result: Datasets structured by phase/homogenization and according to selected view. """ - r = {} # type: ignore + r: Dict[str,Any] = {} with h5py.File(self.fname,'r') as f: for inc in util.show_progress(self.visible['increments']): @@ -1799,14 +1601,13 @@ class Result: output: Union[str, List[str]] = '*', flatten: bool = True, prune: bool = True, - constituents: IntSequence = None, + constituents: Optional[IntSequence] = None, fill_float: float = np.nan, - fill_int: int = 0): + fill_int: int = 0) -> Optional[Dict[str,Any]]: """ Merge data into spatial order that is compatible with the damask.VTK geometry representation. - The returned data structure reflects the group/folder structure - in the DADF5 file. + The returned data structure reflects the group/folder structure in the DADF5 file. Multi-phase data is fused into a single output. `place` is equivalent to `get` if only one phase/homogenization @@ -1816,20 +1617,20 @@ class Result: ---------- output : (list of) str, optional Names of the datasets to read. - Defaults to '*', in which case all datasets are placed. - flatten : bool + Defaults to '*', in which case all visible datasets are placed. + flatten : bool, optional Remove singular levels of the folder hierarchy. This might be beneficial in case of single increment or field. Defaults to True. - prune : bool + prune : bool, optional Remove branches with no data. Defaults to True. constituents : (list of) int, optional Constituents to consider. Defaults to None, in which case all constituents are considered. - fill_float : float + fill_float : float, optional Fill value for non-existent entries of floating point type. Defaults to NaN. - fill_int : int + fill_int : int, optional Fill value for non-existent entries of integer type. Defaults to 0. @@ -1839,9 +1640,9 @@ class Result: Datasets structured by spatial position and according to selected view. """ - r = {} # type: ignore + r: Dict[str,Any] = {} - constituents_ = list(map(int,constituents)) if isinstance(constituents,Iterable) else \ + constituents_ = map(int,constituents) if isinstance(constituents,Iterable) else \ (range(self.N_constituents) if constituents is None else [constituents]) # type: ignore suffixes = [''] if self.N_constituents == 1 or isinstance(constituents,int) else \ @@ -1888,32 +1689,319 @@ class Result: return None if (type(r) == dict and r == {}) else r - def export_setup(self, - output: Union[str, List[str]] = '*', - overwrite: bool = False): + def export_XDMF(self, + output: Union[str, List[str]] = '*', + target_dir: Union[None, str, Path] = None, + absolute_path: bool = False): """ - Export configuration files. + Write XDMF file to directly visualize data from DADF5 file. + + The XDMF format is only supported for structured grids + with single phase and single constituent. + For other cases use `export_VTK`. + + Parameters + ---------- + output : (list of) str, optional + Names of the datasets included in the XDMF file. + Defaults to '*', in which case all datasets are considered. + target_dir : str or pathlib.Path, optional + Directory to save XDMF file. Will be created if non-existent. + absolute_path : bool, optional + Store absolute (instead of relative) path to DADF5 file. + Defaults to False, i.e. the XDMF file expects the + DADF5 file at a stable relative path. + + """ + if self.N_constituents != 1 or len(self.phases) != 1 or not self.structured: + raise TypeError('XDMF output requires structured grid with single phase and single constituent.') + + attribute_type_map = defaultdict(lambda:'Matrix', ( ((),'Scalar'), ((3,),'Vector'), ((3,3),'Tensor')) ) + + def number_type_map(dtype): + if dtype in np.sctypes['int']: return 'Int' + if dtype in np.sctypes['uint']: return 'UInt' + if dtype in np.sctypes['float']: return 'Float' + + + xdmf = ET.Element('Xdmf') + xdmf.attrib = {'Version': '2.0', + 'xmlns:xi': 'http://www.w3.org/2001/XInclude'} + + domain = ET.SubElement(xdmf, 'Domain') + + collection = ET.SubElement(domain, 'Grid') + collection.attrib = {'GridType': 'Collection', + 'CollectionType': 'Temporal', + 'Name': 'Increments'} + + time = ET.SubElement(collection, 'Time') + time.attrib = {'TimeType': 'List'} + + time_data = ET.SubElement(time, 'DataItem') + times = [self.times[self.increments.index(i)] for i in self.visible['increments']] + time_data.attrib = {'Format': 'XML', + 'NumberType': 'Float', + 'Dimensions': f'{len(times)}'} + time_data.text = ' '.join(map(str,times)) + + attributes = [] + data_items = [] + + hdf5_name = self.fname.name + hdf5_dir = self.fname.parent + xdmf_dir = Path.cwd() if target_dir is None else Path(target_dir) + hdf5_link = (hdf5_dir if absolute_path else Path(os.path.relpath(hdf5_dir,xdmf_dir.resolve())))/hdf5_name + + with h5py.File(self.fname,'r') as f: + for inc in self.visible['increments']: + + grid = ET.SubElement(collection,'Grid') + grid.attrib = {'GridType': 'Uniform', + 'Name': inc} + + topology = ET.SubElement(grid, 'Topology') + topology.attrib = {'TopologyType': '3DCoRectMesh', + 'Dimensions': '{} {} {}'.format(*(self.cells[::-1]+1))} + + geometry = ET.SubElement(grid, 'Geometry') + geometry.attrib = {'GeometryType':'Origin_DxDyDz'} + + origin = ET.SubElement(geometry, 'DataItem') + origin.attrib = {'Format': 'XML', + 'NumberType': 'Float', + 'Dimensions': '3'} + origin.text = "{} {} {}".format(*self.origin[::-1]) + + delta = ET.SubElement(geometry, 'DataItem') + delta.attrib = {'Format': 'XML', + 'NumberType': 'Float', + 'Dimensions': '3'} + delta.text="{} {} {}".format(*(self.size/self.cells)[::-1]) + + attributes.append(ET.SubElement(grid, 'Attribute')) + attributes[-1].attrib = {'Name': 'u / m', + 'Center': 'Node', + 'AttributeType': 'Vector'} + data_items.append(ET.SubElement(attributes[-1], 'DataItem')) + data_items[-1].attrib = {'Format': 'HDF', + 'Precision': '8', + 'Dimensions': '{} {} {} 3'.format(*(self.cells[::-1]+1))} + data_items[-1].text = f'{hdf5_link}:/{inc}/geometry/u_n' + for ty in ['phase','homogenization']: + for label in self.visible[ty+'s']: + for field in _match(self.visible['fields'],f['/'.join([inc,ty,label])].keys()): + for out in _match(output,f['/'.join([inc,ty,label,field])].keys()): + name = '/'.join([inc,ty,label,field,out]) + shape = f[name].shape[1:] + dtype = f[name].dtype + + unit = f[name].attrs['unit'] if h5py3 else \ + f[name].attrs['unit'].decode() + + attributes.append(ET.SubElement(grid, 'Attribute')) + attributes[-1].attrib = {'Name': '/'.join([ty,field,out])+f' / {unit}', + 'Center': 'Cell', + 'AttributeType': attribute_type_map[shape]} + data_items.append(ET.SubElement(attributes[-1], 'DataItem')) + data_items[-1].attrib = {'Format': 'HDF', + 'NumberType': number_type_map(dtype), + 'Precision': f'{dtype.itemsize}', + 'Dimensions': '{} {} {} {}'.format(*self.cells[::-1],1 if shape == () else + np.prod(shape))} + data_items[-1].text = f'{hdf5_link}:{name}' + + xdmf_dir.mkdir(parents=True,exist_ok=True) + with util.open_text((xdmf_dir/hdf5_name).with_suffix('.xdmf'),'w') as f: + f.write(xml.dom.minidom.parseString(ET.tostring(xdmf).decode()).toprettyxml()) + + + def export_VTK(self, + output: Union[str,List[str]] = '*', + mode: str = 'cell', + constituents: Optional[IntSequence] = None, + target_dir: Union[None, str, Path] = None, + fill_float: float = np.nan, + fill_int: int = 0, + parallel: bool = True): + """ + Export to VTK cell/point data. + + One VTK file per visible increment is created. + For point data, the VTK format is poly data (.vtp). + For cell data, either an image (.vti) or unstructured (.vtu) dataset + is written for grid-based or mesh-based simulations, respectively. + + Parameters + ---------- + output : (list of) str, optional + Names of the datasets to export to the VTK file. + Defaults to '*', in which case all visible datasets are exported. + mode : {'cell', 'point'}, optional + Export in cell format or point format. + Defaults to 'cell'. + constituents : (list of) int, optional + Constituents to consider. + Defaults to None, in which case all constituents are considered. + target_dir : str or pathlib.Path, optional + Directory to save VTK files. Will be created if non-existent. + fill_float : float, optional + Fill value for non-existent entries of floating point type. + Defaults to NaN. + fill_int : int, optional + Fill value for non-existent entries of integer type. + Defaults to 0. + parallel : bool, optional + Write VTK files in parallel in a separate background process. + Defaults to True. + + """ + if mode.lower()=='cell': + v = self.geometry0 + elif mode.lower()=='point': + v = VTK.from_poly_data(self.coordinates0_point) + else: + raise ValueError(f'invalid mode "{mode}"') + + v.comments = [util.execution_stamp('Result','export_VTK')] + + N_digits = int(np.floor(np.log10(max(1,self.incs[-1]))))+1 + + constituents_ = constituents if isinstance(constituents,Iterable) else \ + (range(self.N_constituents) if constituents is None else [constituents]) # type: ignore + + suffixes = [''] if self.N_constituents == 1 or isinstance(constituents,int) else \ + [f'#{c}' for c in constituents_] + + at_cell_ph,in_data_ph,at_cell_ho,in_data_ho = self._mappings() + + vtk_dir = Path.cwd() if target_dir is None else Path(target_dir) + vtk_dir.mkdir(parents=True,exist_ok=True) + + with h5py.File(self.fname,'r') as f: + if self.version_minor >= 13: + creator = f.attrs['creator'] if h5py3 else f.attrs['creator'].decode() + created = f.attrs['created'] if h5py3 else f.attrs['created'].decode() + v.comments += [f'{creator} ({created})'] + + for inc in util.show_progress(self.visible['increments']): + + u = _read(f['/'.join([inc,'geometry','u_n' if mode.lower() == 'cell' else 'u_p'])]) + v = v.set('u',u) + + for ty in ['phase','homogenization']: + for field in self.visible['fields']: + outs: Dict[str, np.ma.core.MaskedArray] = {} + for label in self.visible[ty+'s']: + if field not in f['/'.join([inc,ty,label])].keys(): continue + + for out in _match(output,f['/'.join([inc,ty,label,field])].keys()): + data = ma.array(_read(f['/'.join([inc,ty,label,field,out])])) + + if ty == 'phase': + if out+suffixes[0] not in outs.keys(): + for c,suffix in zip(constituents_,suffixes): + outs[out+suffix] = \ + _empty_like(data,self.N_materialpoints,fill_float,fill_int) + + for c,suffix in zip(constituents_,suffixes): + outs[out+suffix][at_cell_ph[c][label]] = data[in_data_ph[c][label]] + + if ty == 'homogenization': + if out not in outs.keys(): + outs[out] = _empty_like(data,self.N_materialpoints,fill_float,fill_int) + + outs[out][at_cell_ho[label]] = data[in_data_ho[label]] + + for label,dataset in outs.items(): + v = v.set(' / '.join(['/'.join([ty,field,label]),dataset.dtype.metadata['unit']]),dataset) + + + v.save(vtk_dir/f'{self.fname.stem}_inc{inc.split(prefix_inc)[-1].zfill(N_digits)}', + parallel=parallel) + + def export_DADF5(self, + fname, + output: Union[str, List[str]] = '*'): + """ + Export visible components into a new DADF5 file. + + A DADF5 (DAMASK HDF5) file contains DAMASK results. + Its group/folder structure reflects the layout in material.yaml. + + Parameters + ---------- + fname : str or pathlib.Path + Name of the DADF5 file to be created. + output : (list of) str, optional + Names of the datasets to export. + Defaults to '*', in which case all visible datasets are exported. + + """ + if Path(fname).expanduser().absolute() == self.fname: + raise PermissionError(f'cannot overwrite {self.fname}') + with h5py.File(self.fname,'r') as f_in, h5py.File(fname,'w') as f_out: + for k,v in f_in.attrs.items(): + f_out.attrs.create(k,v) + for g in ['setup','geometry','cell_to']: + f_in.copy(g,f_out) + + for inc in util.show_progress(self.visible['increments']): + f_in.copy(inc,f_out,shallow=True) + for out in _match(output,f_in['/'.join([inc,'geometry'])].keys()): + f_in[inc]['geometry'].copy(out,f_out[inc]['geometry']) + + for label in self.homogenizations: + f_in[inc]['homogenization'].copy(label,f_out[inc]['homogenization'],shallow=True) + for label in self.phases: + f_in[inc]['phase'].copy(label,f_out[inc]['phase'],shallow=True) + + for ty in ['phase','homogenization']: + for label in self.visible[ty+'s']: + for field in _match(self.visible['fields'],f_in['/'.join([inc,ty,label])].keys()): + p = '/'.join([inc,ty,label,field]) + for out in _match(output,f_in[p].keys()): + f_in[p].copy(out,f_out[p]) + + + def export_simulation_setup(self, + output: Union[str, List[str]] = '*', + target_dir: Union[None, str, Path] = None, + overwrite: bool = False, + ): + """ + Export original simulation setup of the Result object. Parameters ---------- output : (list of) str, optional Names of the datasets to export to the file. - Defaults to '*', in which case all datasets are exported. + Defaults to '*', in which case all setup files are exported. + target_dir : str or pathlib.Path, optional + Directory to save setup files. Will be created if non-existent. overwrite : bool, optional - Overwrite existing configuration files. + Overwrite any existing setup files. Defaults to False. """ - def export(name: str, obj: Union[h5py.Dataset,h5py.Group], output: Union[str,List[str]], overwrite: bool): - if type(obj) == h5py.Dataset and _match(output,[name]): - d = obj.attrs['description'] if h5py3 else obj.attrs['description'].decode() - if not Path(name).exists() or overwrite: - with util.open_text(name,'w') as f_out: f_out.write(obj[0].decode()) - print(f'Exported {d} to "{name}".') - else: - print(f'"{name}" exists, {d} not exported.') - elif type(obj) == h5py.Group: - os.makedirs(name, exist_ok=True) + def export(name: str, + obj: Union[h5py.Dataset,h5py.Group], + output: Union[str,List[str]], + cfg_dir: Path, + overwrite: bool): + cfg = cfg_dir/name + + if type(obj) == h5py.Dataset and _match(output,[name]): + if cfg.exists() and not overwrite: + raise PermissionError(f'"{cfg}" exists') + else: + cfg.parent.mkdir(parents=True,exist_ok=True) + with util.open_text(cfg,'w') as f_out: f_out.write(obj[0].decode()) + + cfg_dir = (Path.cwd() if target_dir is None else Path(target_dir)) with h5py.File(self.fname,'r') as f_in: - f_in['setup'].visititems(partial(export,output=output,overwrite=overwrite)) + f_in['setup'].visititems(partial(export, + output=output, + cfg_dir=cfg_dir, + overwrite=overwrite)) diff --git a/python/damask/_rotation.py b/python/damask/_rotation.py index 229e1324e..f986a50b4 100644 --- a/python/damask/_rotation.py +++ b/python/damask/_rotation.py @@ -1,5 +1,5 @@ import copy -from typing import Union, Sequence, Tuple, Literal, List, TypeVar +from typing import Optional, Union, Sequence, Tuple, Literal, List, TypeVar import numpy as np @@ -26,11 +26,8 @@ class Rotation: - Coordinate frames are right-handed. - A rotation angle ω is taken to be positive for a counterclockwise rotation when viewing from the end point of the rotation axis towards the origin. - - Rotations will be interpreted in the passive sense. - - Euler angle triplets are implemented using the Bunge convention, - with angular ranges of [0,2π], [0,π], [0,2π]. - - The rotation angle ω is limited to the interval [0,π]. - - The real part of a quaternion is positive, Re(q) ≥ 0 + - Rotations will be interpreted in the passive sense, i.e. as rotation of + the coordinate frame. - P = -1 (as default). Examples @@ -66,7 +63,7 @@ class Rotation: __slots__ = ['quaternion'] def __init__(self, - rotation: Union[FloatSequence, 'Rotation'] = np.array([1.0,0.0,0.0,0.0])): + rotation: Union[FloatSequence, 'Rotation'] = np.array([1.,0.,0.,0.])): """ New rotation. @@ -82,7 +79,7 @@ class Rotation: if isinstance(rotation,Rotation): self.quaternion = rotation.quaternion.copy() elif np.array(rotation).shape[-1] == 4: - self.quaternion = np.array(rotation) + self.quaternion = np.array(rotation,dtype=float) else: raise TypeError('"rotation" is neither a Rotation nor a quaternion') @@ -99,7 +96,7 @@ class Rotation: def __copy__(self: MyType, - rotation: Union[FloatSequence, 'Rotation'] = None) -> MyType: + rotation: Union[None, FloatSequence, 'Rotation'] = None) -> MyType: """ Return deepcopy(self). @@ -140,8 +137,8 @@ class Rotation: """ return NotImplemented if not isinstance(other, Rotation) else \ - np.logical_or(np.all(self.quaternion == other.quaternion,axis=-1), - np.all(self.quaternion == -1.0*other.quaternion,axis=-1)) + np.logical_or(np.all(self.quaternion == other.quaternion,axis=-1), + np.all(self.quaternion == -1.*other.quaternion,axis=-1)) def __ne__(self, @@ -161,8 +158,8 @@ class Rotation: def isclose(self: MyType, other: MyType, - rtol: float = 1e-5, - atol: float = 1e-8, + rtol: float = 1.e-5, + atol: float = 1.e-8, equal_nan: bool = True) -> bool: """ Report where values are approximately equal to corresponding ones of other Rotation. @@ -186,14 +183,14 @@ class Rotation: """ s = self.quaternion o = other.quaternion - return np.logical_or(np.all(np.isclose(s, o,rtol,atol,equal_nan),axis=-1), - np.all(np.isclose(s,-1.0*o,rtol,atol,equal_nan),axis=-1)) + return np.logical_or(np.all(np.isclose(s, o,rtol,atol,equal_nan),axis=-1), + np.all(np.isclose(s,-1.*o,rtol,atol,equal_nan),axis=-1)) def allclose(self: MyType, other: MyType, - rtol: float = 1e-5, - atol: float = 1e-8, + rtol: float = 1.e-5, + atol: float = 1.e-8, equal_nan: bool = True) -> Union[np.bool_, bool]: """ Test whether all values are approximately equal to corresponding ones of other Rotation. @@ -250,7 +247,7 @@ class Rotation: """ dup = self.copy() - dup.quaternion[...,1:] *= -1 + dup.quaternion[...,1:] *= -1. return dup @@ -393,9 +390,9 @@ class Rotation: if self.shape + (3,) == other.shape: q_m = self.quaternion[...,0] p_m = self.quaternion[...,1:] - A = q_m**2.0 - np.einsum('...i,...i',p_m,p_m) - B = 2.0 * np.einsum('...i,...i',p_m,other) - C = 2.0 * _P * q_m + A = q_m**2 - np.einsum('...i,...i',p_m,p_m) + B = 2. * np.einsum('...i,...i',p_m,other) + C = 2. * _P * q_m return np.block([(A * other[...,i]).reshape(self.shape+(1,)) + (B * p_m[...,i]).reshape(self.shape+(1,)) + (C * ( p_m[...,(i+1)%3]*other[...,(i+2)%3]\ @@ -419,7 +416,7 @@ class Rotation: def _standardize(self: MyType) -> MyType: """Standardize quaternion (ensure positive real hemisphere).""" - self.quaternion[self.quaternion[...,0] < 0.0] *= -1 + self.quaternion[self.quaternion[...,0] < 0.] *= -1. return self @@ -468,7 +465,7 @@ class Rotation: Parameters ---------- - shape : int or sequence of ints + shape : (sequence of) int New shape, number of elements needs to match the original shape. If an integer is supplied, then the result will be a 1-D array of that length. order : {'C', 'F', 'A'}, optional @@ -496,7 +493,7 @@ class Rotation: Parameters ---------- - shape : int or sequence of ints + shape : (sequence of) int Shape of broadcasted array, needs to be compatible with the original shape. mode : str, optional Where to preferentially locate missing dimensions. @@ -510,11 +507,11 @@ class Rotation: """ shape_ = (shape,) if isinstance(shape,(int,np.integer)) else tuple(shape) return self.copy(np.broadcast_to(self.quaternion.reshape(util.shapeshifter(self.shape,shape_,mode)+(4,)), - shape_+(4,))) + shape_+(4,))) def average(self: MyType, - weights: FloatSequence = None) -> MyType: + weights: Optional[FloatSequence] = None) -> MyType: """ Average along last array dimension. @@ -540,7 +537,7 @@ class Rotation: weights_ = np.ones(self.shape,dtype=float) if weights is None else np.array(weights,float) - eig, vec = np.linalg.eig(np.sum(_M(self.quaternion) * weights_[...,np.newaxis,np.newaxis],axis=-3) \ + eig, vec = np.linalg.eig(np.sum(_M(self.quaternion) * weights_[...,np.newaxis,np.newaxis],axis=-3) /np.sum( weights_[...,np.newaxis,np.newaxis],axis=-3)) return self.copy(Rotation.from_quaternion(np.real( @@ -611,8 +608,7 @@ class Rotation: Cube orientation as Bunge Euler angles. >>> import damask - >>> import numpy as np - >>> damask.Rotation(np.array([1,0,0,0])).as_Euler_angles() + >>> damask.Rotation([1,0,0,0]).as_Euler_angles() array([0., 0., 0.]) """ @@ -634,7 +630,7 @@ class Rotation: Returns ------- - axis_angle : numpy.ndarray, shape (...,4) or tuple ((...,3), (...)) if pair == True + n_omega : numpy.ndarray, shape (...,4) or tuple ((...,3), (...)) if pair == True Axis and angle [n_1, n_2, n_3, ω] with ǀnǀ = 1 and ω ∈ [0,π] or ω ∈ [0,180] if degrees == True. @@ -643,8 +639,7 @@ class Rotation: Cube orientation as axis–angle pair. >>> import damask - >>> import numpy as np - >>> damask.Rotation(np.array([1,0,0,0])).as_axis_angle(pair=True) + >>> damask.Rotation([1,0,0,0]).as_axis_angle(pair=True) (array([0., 0., 1.]), array(0.)) """ @@ -666,8 +661,7 @@ class Rotation: Cube orientation as rotation matrix. >>> import damask - >>> import numpy as np - >>> damask.Rotation(np.array([1,0,0,0])).as_matrix() + >>> damask.Rotation([1,0,0,0]).as_matrix() array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]]) @@ -697,8 +691,7 @@ class Rotation: Cube orientation as three-component Rodrigues–Frank vector. >>> import damask - >>> import numpy as np - >>> damask.Rotation(np.array([1,0,0,0])).as_Rodrigues_vector(compact=True) + >>> damask.Rotation([1,0,0,0]).as_Rodrigues_vector(compact=True) array([ 0., 0., 0.]) """ @@ -723,8 +716,7 @@ class Rotation: Cube orientation as homochoric vector. >>> import damask - >>> import numpy as np - >>> damask.Rotation(np.array([1,0,0,0])).as_homochoric() + >>> damask.Rotation([1,0,0,0]).as_homochoric() array([0., 0., 0.]) """ @@ -737,15 +729,14 @@ class Rotation: Returns ------- x : numpy.ndarray, shape (...,3) - Cubochoric vector (x_1, x_2, x_3) with max(x_i) < 1/2*π^(2/3). + Cubochoric vector (x_1, x_2, x_3) with max(x_i) < 1/2*π^(2/3). Examples -------- Cube orientation as cubochoric vector. >>> import damask - >>> import numpy as np - >>> damask.Rotation(np.array([1,0,0,0])).as_cubochoric() + >>> damask.Rotation([1,0,0,0]).as_cubochoric() array([0., 0., 0.]) """ @@ -757,6 +748,7 @@ class Rotation: @staticmethod def from_quaternion(q: Union[Sequence[FloatSequence], np.ndarray], accept_homomorph: bool = False, + normalize: bool = False, P: Literal[1, -1] = -1) -> 'Rotation': """ Initialize from quaternion. @@ -768,23 +760,29 @@ class Rotation: accept_homomorph : bool, optional Allow homomorphic variants, i.e. q_0 < 0 (negative real hemisphere). Defaults to False. + normalize: bool, optional + Allow ǀqǀ ≠ 1. Defaults to False. P : int ∈ {-1,1}, optional Sign convention. Defaults to -1. + Returns + ------- + new : damask.Rotation + """ qu = np.array(q,dtype=float) - if qu.shape[:-2:-1] != (4,): - raise ValueError('invalid shape') - if abs(P) != 1: - raise ValueError('P ∉ {-1,1}') + if qu.shape[:-2:-1] != (4,): raise ValueError('invalid shape') + if abs(P) != 1: raise ValueError('P ∉ {-1,1}') qu[...,1:4] *= -P + if accept_homomorph: - qu[qu[...,0] < 0.0] *= -1 - else: - if np.any(qu[...,0] < 0.0): - raise ValueError('quaternion with negative first (real) component') - if not np.all(np.isclose(np.linalg.norm(qu,axis=-1), 1.0,rtol=0.0)): + qu[qu[...,0]<0.] *= -1. + elif np.any(qu[...,0] < 0.): + raise ValueError('quaternion with negative first (real) component') + if normalize: + qu /= np.linalg.norm(qu,axis=-1,keepdims=True) + elif not np.allclose(np.linalg.norm(qu,axis=-1),1.,rtol=1.e-8): raise ValueError('quaternion is not of unit length') return Rotation(qu) @@ -803,23 +801,26 @@ class Rotation: degrees : bool, optional Euler angles are given in degrees. Defaults to False. + Returns + ------- + new : damask.Rotation + Notes ----- Bunge Euler angles correspond to a rotation axis sequence of z–x'–z''. """ eu = np.array(phi,dtype=float) - if eu.shape[:-2:-1] != (3,): - raise ValueError('invalid shape') + if eu.shape[:-2:-1] != (3,): raise ValueError('invalid shape') eu = np.radians(eu) if degrees else eu - if np.any(eu < 0.0) or np.any(eu > 2.0*np.pi) or np.any(eu[...,1] > np.pi): # ToDo: No separate check for PHI + if np.any(eu < 0.) or np.any(eu > np.pi*np.array([2.,1.,2.])): raise ValueError('Euler angles outside of [0..2π],[0..π],[0..2π]') return Rotation(Rotation._eu2qu(eu)) @staticmethod - def from_axis_angle(axis_angle: np.ndarray, + def from_axis_angle(n_omega: np.ndarray, degrees: bool = False, normalize: bool = False, P: Literal[1, -1] = -1) -> 'Rotation': @@ -828,7 +829,7 @@ class Rotation: Parameters ---------- - axis_angle : numpy.ndarray, shape (...,4) + n_omega : numpy.ndarray, shape (...,4) Axis and angle (n_1, n_2, n_3, ω) with ǀnǀ = 1 and ω ∈ [0,π] or ω ∈ [0,180] if degrees == True. degrees : bool, optional @@ -838,20 +839,23 @@ class Rotation: P : int ∈ {-1,1}, optional Sign convention. Defaults to -1. + Returns + ------- + new : damask.Rotation + """ - ax = np.array(axis_angle,dtype=float) - if ax.shape[:-2:-1] != (4,): - raise ValueError('invalid shape') - if abs(P) != 1: - raise ValueError('P ∉ {-1,1}') + ax = np.array(n_omega,dtype=float) + if ax.shape[:-2:-1] != (4,): raise ValueError('invalid shape') + if abs(P) != 1: raise ValueError('P ∉ {-1,1}') ax[...,0:3] *= -P - if degrees: ax[..., 3] = np.radians(ax[...,3]) - if normalize: ax[...,0:3] /= np.linalg.norm(ax[...,0:3],axis=-1,keepdims=True) - if np.any(ax[...,3] < 0.0) or np.any(ax[...,3] > np.pi): + if degrees: ax[..., 3] = np.radians(ax[...,3]) + if np.any(ax[...,3] < 0.) or np.any(ax[...,3] > np.pi): raise ValueError('axis–angle rotation angle outside of [0..π]') - if not np.all(np.isclose(np.linalg.norm(ax[...,0:3],axis=-1), 1.0)): - print(np.linalg.norm(ax[...,0:3],axis=-1)) + + if normalize: + ax[...,0:3] /= np.linalg.norm(ax[...,0:3],axis=-1,keepdims=True) + elif not np.allclose(np.linalg.norm(ax[...,0:3],axis=-1),1.): raise ValueError('axis–angle rotation axis is not of unit length') return Rotation(Rotation._ax2qu(ax)) @@ -872,28 +876,34 @@ class Rotation: reciprocal : bool, optional Basis vectors are given in reciprocal (instead of real) space. Defaults to False. + Returns + ------- + new : damask.Rotation + """ om = np.array(basis,dtype=float) - if om.shape[-2:] != (3,3): - raise ValueError('invalid shape') + if om.shape[-2:] != (3,3): raise ValueError('invalid shape') if reciprocal: om = np.linalg.inv(tensor.transpose(om)/np.pi) # transform reciprocal basis set orthonormal = False # contains stretch + if not orthonormal: (U,S,Vh) = np.linalg.svd(om) # singular value decomposition om = np.einsum('...ij,...jl',U,Vh) - if not np.all(np.isclose(np.linalg.det(om),1.0)): - raise ValueError('orientation matrix has determinant ≠ 1') - if not np.all(np.isclose(np.einsum('...i,...i',om[...,0],om[...,1]), 0.0)) \ - or not np.all(np.isclose(np.einsum('...i,...i',om[...,1],om[...,2]), 0.0)) \ - or not np.all(np.isclose(np.einsum('...i,...i',om[...,2],om[...,0]), 0.0)): + elif not np.allclose(np.einsum('...i,...i',om[...,0],om[...,1]),0.) \ + or not np.allclose(np.einsum('...i,...i',om[...,1],om[...,2]),0.) \ + or not np.allclose(np.einsum('...i,...i',om[...,2],om[...,0]),0.): raise ValueError('orientation matrix is not orthogonal') + if not np.allclose(np.linalg.det(om),1.): + raise ValueError('orientation matrix has determinant ≠ 1') + return Rotation(Rotation._om2qu(om)) @staticmethod - def from_matrix(R: np.ndarray) -> 'Rotation': + def from_matrix(R: np.ndarray, + normalize: bool = False) -> 'Rotation': """ Initialize from rotation matrix. @@ -901,9 +911,17 @@ class Rotation: ---------- R : numpy.ndarray, shape (...,3,3) Rotation matrix with det(R) = 1 and R.T ∙ R = I. + normalize : bool, optional + Rescales rotation matrix to unit determinant. Defaults to False. + + Returns + ------- + new : damask.Rotation """ - return Rotation.from_basis(R) + return Rotation.from_basis(np.array(R,dtype=float) * (np.linalg.det(R)**(-1./3.))[...,np.newaxis,np.newaxis] + if normalize else + R) @staticmethod def from_parallel(a: np.ndarray, @@ -918,9 +936,13 @@ class Rotation: b : numpy.ndarray, shape (...,2,3) Corresponding three-dimensional vectors of second basis. + Returns + ------- + new : damask.Rotation + """ - a_ = np.array(a) - b_ = np.array(b) + a_ = np.array(a,dtype=float) + b_ = np.array(b,dtype=float) if a_.shape[-2:] != (2,3) or b_.shape[-2:] != (2,3) or a_.shape != b_.shape: raise ValueError('invalid shape') am = np.stack([ a_[...,0,:], @@ -950,18 +972,21 @@ class Rotation: P : int ∈ {-1,1}, optional Sign convention. Defaults to -1. + Returns + ------- + new : damask.Rotation + """ ro = np.array(rho,dtype=float) - if ro.shape[:-2:-1] != (4,): - raise ValueError('invalid shape') - if abs(P) != 1: - raise ValueError('P ∉ {-1,1}') + if ro.shape[:-2:-1] != (4,): raise ValueError('invalid shape') + if abs(P) != 1: raise ValueError('P ∉ {-1,1}') ro[...,0:3] *= -P - if normalize: ro[...,0:3] /= np.linalg.norm(ro[...,0:3],axis=-1,keepdims=True) - if np.any(ro[...,3] < 0.0): - raise ValueError('Rodrigues vector rotation angle is negative') - if not np.all(np.isclose(np.linalg.norm(ro[...,0:3],axis=-1), 1.0)): + if np.any(ro[...,3] < 0.): raise ValueError('Rodrigues vector rotation angle is negative') + + if normalize: + ro[...,0:3] /= np.linalg.norm(ro[...,0:3],axis=-1,keepdims=True) + elif not np.allclose(np.linalg.norm(ro[...,0:3],axis=-1),1.): raise ValueError('Rodrigues vector rotation axis is not of unit length') return Rotation(Rotation._ro2qu(ro)) @@ -979,16 +1004,18 @@ class Rotation: P : int ∈ {-1,1}, optional Sign convention. Defaults to -1. + Returns + ------- + new : damask.Rotation + """ ho = np.array(h,dtype=float) - if ho.shape[:-2:-1] != (3,): - raise ValueError('invalid shape') - if abs(P) != 1: - raise ValueError('P ∉ {-1,1}') + if ho.shape[:-2:-1] != (3,): raise ValueError('invalid shape') + if abs(P) != 1: raise ValueError('P ∉ {-1,1}') ho *= -P - if np.any(np.linalg.norm(ho,axis=-1) >_R1+1e-9): + if np.any(np.linalg.norm(ho,axis=-1) > _R1+1.e-9): raise ValueError('homochoric coordinate outside of the sphere') return Rotation(Rotation._ho2qu(ho)) @@ -1006,14 +1033,15 @@ class Rotation: P : int ∈ {-1,1}, optional Sign convention. Defaults to -1. + Returns + ------- + new : damask.Rotation + """ cu = np.array(x,dtype=float) - if cu.shape[:-2:-1] != (3,): - raise ValueError('invalid shape') - if abs(P) != 1: - raise ValueError('P ∉ {-1,1}') - - if np.abs(np.max(cu)) > np.pi**(2./3.) * 0.5+1e-9: + if cu.shape[:-2:-1] != (3,): raise ValueError('invalid shape') + if abs(P) != 1: raise ValueError('P ∉ {-1,1}') + if np.abs(np.max(cu)) > np.pi**(2./3.) * 0.5+1.e-9: raise ValueError('cubochoric coordinate outside of the cube') ho = -P * Rotation._cu2ho(cu) @@ -1022,29 +1050,33 @@ class Rotation: @staticmethod - def from_random(shape: Union[int, IntSequence] = None, - rng_seed: NumpyRngSeed = None) -> 'Rotation': + def from_random(shape: Union[None, int, IntSequence] = None, + rng_seed: Optional[NumpyRngSeed] = None) -> 'Rotation': """ Initialize with samples from a uniform distribution. Parameters ---------- - shape : int or sequence of ints, optional + shape : (sequence of) int, optional Shape of the returned array. Defaults to None, which gives a scalar. rng_seed : {None, int, array_like[ints], SeedSequence, BitGenerator, Generator}, optional A seed to initialize the BitGenerator. Defaults to None, i.e. unpredictable entropy will be pulled from the OS. + Returns + ------- + new : damask.Rotation + """ rng = np.random.default_rng(rng_seed) r = rng.random(3 if shape is None else tuple(shape)+(3,) if hasattr(shape, '__iter__') else (shape,3)) # type: ignore A = np.sqrt(r[...,2]) - B = np.sqrt(1.0-r[...,2]) - q = np.stack([np.cos(2.0*np.pi*r[...,0])*A, - np.sin(2.0*np.pi*r[...,1])*B, - np.cos(2.0*np.pi*r[...,1])*B, - np.sin(2.0*np.pi*r[...,0])*A],axis=-1) + B = np.sqrt(1.-r[...,2]) + q = np.stack([np.cos(2.*np.pi*r[...,0])*A, + np.sin(2.*np.pi*r[...,1])*B, + np.cos(2.*np.pi*r[...,1])*B, + np.sin(2.*np.pi*r[...,0])*A],axis=-1) return Rotation(q if shape is None else q.reshape(r.shape[:-1]+(4,)))._standardize() @@ -1052,10 +1084,10 @@ class Rotation: @staticmethod def from_ODF(weights: np.ndarray, phi: np.ndarray, - shape: Union[int, IntSequence] = None, + shape: Union[None, int, IntSequence] = None, degrees: bool = False, fractions: bool = True, - rng_seed: NumpyRngSeed = None) -> 'Rotation': + rng_seed: Optional[NumpyRngSeed] = None) -> 'Rotation': """ Initialize with samples from a binned orientation distribution function (ODF). @@ -1065,7 +1097,7 @@ class Rotation: Texture intensity values (probability density or volume fraction) at Euler space grid points. phi : numpy.ndarray, shape (n,3) Grid coordinates in Euler space at which weights are defined. - shape : int or sequence of ints, optional + shape : (sequence of) int, optional Shape of the returned array. Defaults to None, which gives a scalar. degrees : bool, optional Euler space grid coordinates are in degrees. Defaults to True. @@ -1076,6 +1108,10 @@ class Rotation: A seed to initialize the BitGenerator. Defaults to None, i.e. unpredictable entropy will be pulled from the OS. + Returns + ------- + new : damask.Rotation + Notes ----- Due to the distortion of Euler space in the vicinity of ϕ = 0, probability densities, p, defined on @@ -1093,21 +1129,21 @@ class Rotation: phi_sorted = eu[np.lexsort((eu[:,0],eu[:,1],eu[:,2]))] steps,size,_ = grid_filters.cellsSizeOrigin_coordinates0_point(phi_sorted) delta = np.radians(size/steps) if deg else size/steps - return delta[0]*2.0*np.sin(delta[1]/2.0)*delta[2] / 8.0 / np.pi**2 * np.sin(np.radians(eu[:,1]) if deg else eu[:,1]) + return delta[0]*2.*np.sin(delta[1]/2.)*delta[2] / 8. / np.pi**2 * np.sin(np.radians(eu[:,1]) if deg else eu[:,1]) - dg = 1.0 if fractions else _dg(phi,degrees) - dV_V = dg * np.maximum(0.0,weights.squeeze()) + dg = 1. if fractions else _dg(phi,degrees) + dV_V = dg * np.maximum(0.,weights.squeeze()) - N = 1 if shape is None else np.prod(shape) + N = 1 if shape is None else np.prod(shape).astype(int) return Rotation.from_Euler_angles(phi[util.hybrid_IA(dV_V,N,rng_seed)],degrees).reshape(() if shape is None else shape) @staticmethod def from_spherical_component(center: 'Rotation', sigma: float, - shape: Union[int, IntSequence] = None, + shape: Union[None, int, IntSequence] = None, degrees: bool = False, - rng_seed: NumpyRngSeed = None) -> 'Rotation': + rng_seed: Optional[NumpyRngSeed] = None) -> 'Rotation': """ Initialize with samples from a Gaussian distribution around a given center. @@ -1117,22 +1153,38 @@ class Rotation: Central rotation. sigma : float Standard deviation of (Gaussian) misorientation distribution. - shape : int or sequence of ints, optional + shape : (sequence of) int, optional Shape of the returned array. Defaults to None, which gives a scalar. degrees : bool, optional - sigma is given in degrees. Defaults to True. + sigma is given in degrees. Defaults to False. rng_seed : {None, int, array_like[ints], SeedSequence, BitGenerator, Generator}, optional A seed to initialize the BitGenerator. Defaults to None, i.e. unpredictable entropy will be pulled from the OS. + Examples + -------- + Create a brass texture consisting of + 200 orientations: + + >>> import damask + >>> center = damask.Rotation.from_Euler_angles([35.,45.,0.],degrees=True) + >>> brass = damask.Rotation.from_spherical_component(center=center,sigma=3.,shape=200,degrees=True) + + Create a Goss texture consisting of + 100 orientations: + + >>> import damask + >>> center = damask.Rotation.from_Euler_angles([0.,45.,0.],degrees=True) + >>> goss = damask.Rotation.from_spherical_component(center=center,sigma=3.,shape=100,degrees=True) + """ rng = np.random.default_rng(rng_seed) sigma = np.radians(sigma) if degrees else sigma N = 1 if shape is None else np.prod(shape) - u,Theta = (rng.random((N,2)) * 2.0 * np.array([1,np.pi]) - np.array([1.0, 0])).T + u,Theta = (rng.random((N,2)) * 2. * np.array([1.,np.pi]) - np.array([1.,0.])).T omega = abs(rng.normal(scale=sigma,size=N)) - p = np.column_stack([np.sqrt(1-u**2)*np.cos(Theta), - np.sqrt(1-u**2)*np.sin(Theta), + p = np.column_stack([np.sqrt(1.-u**2)*np.cos(Theta), + np.sqrt(1.-u**2)*np.sin(Theta), u, omega]) return Rotation.from_axis_angle(p).reshape(() if shape is None else shape) * center @@ -1141,10 +1193,10 @@ class Rotation: @staticmethod def from_fiber_component(crystal: IntSequence, sample: IntSequence, - sigma: float = 0.0, - shape: Union[int, IntSequence] = None, + sigma: float = 0., + shape: Union[None, int, IntSequence] = None, degrees: bool = False, - rng_seed: NumpyRngSeed = None): + rng_seed: Optional[NumpyRngSeed] = None) -> 'Rotation': """ Initialize with samples from a Gaussian distribution around a given direction. @@ -1159,14 +1211,18 @@ class Rotation: sigma : float, optional Standard deviation of (Gaussian) misorientation distribution. Defaults to 0. - shape : int or sequence of ints, optional + shape : (sequence of) int, optional Shape of the returned array. Defaults to None, which gives a scalar. degrees : bool, optional - sigma and polar coordinates are given in degrees. + sigma and polar coordinates are given in degrees. Defaults to False. rng_seed : {None, int, array_like[ints], SeedSequence, BitGenerator, Generator}, optional A seed to initialize the BitGenerator. Defaults to None, i.e. unpredictable entropy will be pulled from the OS. + Returns + ------- + new : damask.Rotation + Notes ----- The crystal direction for (θ=0,φ=0) is [0 0 1], @@ -1191,7 +1247,7 @@ class Rotation: 100 orientations: >>> import damask - >>> gamma = damask.Rotation.from_fiber_component([54.7,45.0],[0.,0.],shape=100,degrees=True) + >>> gamma = damask.Rotation.from_fiber_component([54.7,45.],[0.,0.],shape=100,degrees=True) """ rng = np.random.default_rng(rng_seed) @@ -1201,18 +1257,18 @@ class Rotation: d_cr = np.array([np.sin(alpha[0])*np.cos(alpha[1]), np.sin(alpha[0])*np.sin(alpha[1]), np.cos(alpha[0])]) d_lab = np.array([np.sin( beta[0])*np.cos( beta[1]), np.sin( beta[0])*np.sin( beta[1]), np.cos( beta[0])]) ax_align = np.append(np.cross(d_lab,d_cr), np.arccos(np.dot(d_lab,d_cr))) - if np.isclose(ax_align[3],0.0): ax_align[:3] = np.array([1,0,0]) - R_align = Rotation.from_axis_angle(ax_align if ax_align[3] > 0.0 else -ax_align,normalize=True) # rotate fiber axis from sample to crystal frame + if np.isclose(ax_align[3],0.): ax_align[:3] = np.array([1.,0.,0.]) + R_align = Rotation.from_axis_angle(ax_align if ax_align[3] > 0. else -ax_align,normalize=True) # rotate fiber axis from sample to crystal frame - N = 1 if shape is None else np.prod(shape) - u,Theta = (rng.random((N,2)) * 2.0 * np.array([1,np.pi]) - np.array([1.0, 0])).T + N = 1 if shape is None else np.prod(shape).astype(int) + u,Theta = (rng.random((N,2)) * 2. * np.array([1.,np.pi]) - np.array([1.,0.])).T omega = abs(rng.normal(scale=sigma_,size=N)) - p = np.column_stack([np.sqrt(1-u**2)*np.cos(Theta), - np.sqrt(1-u**2)*np.sin(Theta), + p = np.column_stack([np.sqrt(1.-u**2)*np.cos(Theta), + np.sqrt(1.-u**2)*np.sin(Theta), u, omega]) p[:,:3] = np.einsum('ij,...j',np.eye(3)-np.outer(d_lab,d_lab),p[:,:3]) # remove component along fiber axis f = np.column_stack((np.broadcast_to(d_lab,(N,3)),rng.random(N)*np.pi)) - f[::2,:3] *= -1 # flip half the rotation axes to negative sense + f[::2,:3] *= -1. # flip half the rotation axes to negative sense return (R_align.broadcast_to(N) * Rotation.from_axis_angle(p,normalize=True) @@ -1253,15 +1309,15 @@ class Rotation: @staticmethod def _qu2om(qu: np.ndarray) -> np.ndarray: qq = qu[...,0:1]**2-(qu[...,1:2]**2 + qu[...,2:3]**2 + qu[...,3:4]**2) - om = np.block([qq + 2.0*qu[...,1:2]**2, - 2.0*(qu[...,2:3]*qu[...,1:2]-_P*qu[...,0:1]*qu[...,3:4]), - 2.0*(qu[...,3:4]*qu[...,1:2]+_P*qu[...,0:1]*qu[...,2:3]), - 2.0*(qu[...,1:2]*qu[...,2:3]+_P*qu[...,0:1]*qu[...,3:4]), - qq + 2.0*qu[...,2:3]**2, - 2.0*(qu[...,3:4]*qu[...,2:3]-_P*qu[...,0:1]*qu[...,1:2]), - 2.0*(qu[...,1:2]*qu[...,3:4]-_P*qu[...,0:1]*qu[...,2:3]), - 2.0*(qu[...,2:3]*qu[...,3:4]+_P*qu[...,0:1]*qu[...,1:2]), - qq + 2.0*qu[...,3:4]**2, + om = np.block([qq + 2.*qu[...,1:2]**2, + 2.*(qu[...,2:3]*qu[...,1:2]-_P*qu[...,0:1]*qu[...,3:4]), + 2.*(qu[...,3:4]*qu[...,1:2]+_P*qu[...,0:1]*qu[...,2:3]), + 2.*(qu[...,1:2]*qu[...,2:3]+_P*qu[...,0:1]*qu[...,3:4]), + qq + 2.*qu[...,2:3]**2, + 2.*(qu[...,3:4]*qu[...,2:3]-_P*qu[...,0:1]*qu[...,1:2]), + 2.*(qu[...,1:2]*qu[...,3:4]-_P*qu[...,0:1]*qu[...,2:3]), + 2.*(qu[...,2:3]*qu[...,3:4]+_P*qu[...,0:1]*qu[...,1:2]), + qq + 2.*qu[...,3:4]**2, ]).reshape(qu.shape[:-1]+(3,3)) return om @@ -1276,22 +1332,20 @@ class Rotation: q12_s = qu[...,1:2]**2+qu[...,2:3]**2 chi = np.sqrt(q03_s*q12_s) - eu = np.where(np.abs(q12_s) < 1.0e-8, - np.block([np.arctan2(-_P*2.0*qu[...,0:1]*qu[...,3:4],qu[...,0:1]**2-qu[...,3:4]**2), + eu = np.where(np.abs(q12_s) < 1.e-8, + np.block([np.arctan2(-_P*2.*qu[...,0:1]*qu[...,3:4],qu[...,0:1]**2-qu[...,3:4]**2), np.zeros(qu.shape[:-1]+(2,))]), - np.where(np.abs(q03_s) < 1.0e-8, - np.block([np.arctan2( 2.0*qu[...,1:2]*qu[...,2:3],qu[...,1:2]**2-qu[...,2:3]**2), + np.where(np.abs(q03_s) < 1.e-8, + np.block([np.arctan2( 2.*qu[...,1:2]*qu[...,2:3],qu[...,1:2]**2-qu[...,2:3]**2), np.broadcast_to(np.pi,qu[...,0:1].shape), np.zeros(qu.shape[:-1]+(1,))]), np.block([np.arctan2((-_P*q02+q13)*chi, (-_P*q01-q23)*chi), - np.arctan2( 2.0*chi, q03_s-q12_s ), + np.arctan2( 2.*chi, q03_s-q12_s ), np.arctan2(( _P*q02+q13)*chi, (-_P*q01+q23)*chi)]) ) ) - # reduce Euler angles to definition range - eu[np.abs(eu)<1.e-6] = 0.0 - eu = np.where(eu<0, (eu+2.0*np.pi)%np.array([2.0*np.pi,np.pi,2.0*np.pi]),eu) # needed? - return eu + eu[np.abs(eu) < 1.e-6] = 0. + return np.where(eu < 0., eu%(np.pi*np.array([2.,1.,2.])),eu) @staticmethod def _qu2ax(qu: np.ndarray) -> np.ndarray: @@ -1302,11 +1356,11 @@ class Rotation: """ with np.errstate(invalid='ignore',divide='ignore'): s = np.sign(qu[...,0:1])/np.sqrt(qu[...,1:2]**2+qu[...,2:3]**2+qu[...,3:4]**2) - omega = 2.0 * np.arccos(np.clip(qu[...,0:1],-1.0,1.0)) - ax = np.where(np.broadcast_to(qu[...,0:1] < 1.0e-8,qu.shape), + omega = 2. * np.arccos(np.clip(qu[...,0:1],-1.,1.)) + ax = np.where(np.broadcast_to(qu[...,0:1] < 1.e-8,qu.shape), np.block([qu[...,1:4],np.broadcast_to(np.pi,qu[...,0:1].shape)]), np.block([qu[...,1:4]*s,omega])) - ax[np.isclose(qu[...,0],1.,rtol=0.0)] = [0.0, 0.0, 1.0, 0.0] + ax[np.isclose(qu[...,0],1.,rtol=0.)] = np.array([0.,0.,1.,0.]) return ax @staticmethod @@ -1314,23 +1368,23 @@ class Rotation: """Quaternion to Rodrigues–Frank vector.""" with np.errstate(invalid='ignore',divide='ignore'): s = np.linalg.norm(qu[...,1:4],axis=-1,keepdims=True) - ro = np.where(np.broadcast_to(np.abs(qu[...,0:1]) < 1.0e-12,qu.shape), + ro = np.where(np.broadcast_to(np.abs(qu[...,0:1]) < 1.e-12,qu.shape), np.block([qu[...,1:2], qu[...,2:3], qu[...,3:4], np.broadcast_to(np.inf,qu[...,0:1].shape)]), np.block([qu[...,1:2]/s,qu[...,2:3]/s,qu[...,3:4]/s, - np.tan(np.arccos(np.clip(qu[...,0:1],-1.0,1.0))) + np.tan(np.arccos(np.clip(qu[...,0:1],-1.,1.))) ]) ) - ro[np.abs(s).squeeze(-1) < 1.0e-12] = [0.0,0.0,_P,0.0] + ro[np.abs(s).squeeze(-1) < 1.e-12] = np.array([0.,0.,_P,0.]) return ro @staticmethod def _qu2ho(qu: np.ndarray) -> np.ndarray: """Quaternion to homochoric vector.""" with np.errstate(invalid='ignore'): - omega = 2.0 * np.arccos(np.clip(qu[...,0:1],-1.0,1.0)) - ho = np.where(np.abs(omega) < 1.0e-12, + omega = 2. * np.arccos(np.clip(qu[...,0:1],-1.,1.)) + ho = np.where(np.abs(omega) < 1.e-12, np.zeros(3), - qu[...,1:4]/np.linalg.norm(qu[...,1:4],axis=-1,keepdims=True) \ + qu[...,1:4]/np.linalg.norm(qu[...,1:4],axis=-1,keepdims=True) * (0.75*(omega - np.sin(omega)))**(1./3.)) return ho @@ -1349,48 +1403,48 @@ class Rotation: This formulation is from www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion. The original formulation had issues. """ - trace = om[...,0,0:1]+om[...,1,1:2]+om[...,2,2:3] + trace = om[...,0,0:1] + om[...,1,1:2] + om[...,2,2:3] with np.errstate(invalid='ignore',divide='ignore'): - s = [ - 0.5 / np.sqrt( 1.0 + trace), - 2.0 * np.sqrt( 1.0 + om[...,0,0:1] - om[...,1,1:2] - om[...,2,2:3]), - 2.0 * np.sqrt( 1.0 + om[...,1,1:2] - om[...,2,2:3] - om[...,0,0:1]), - 2.0 * np.sqrt( 1.0 + om[...,2,2:3] - om[...,0,0:1] - om[...,1,1:2] ) - ] - qu= np.where(trace>0, - np.block([0.25 / s[0], - (om[...,2,1:2] - om[...,1,2:3] ) * s[0], - (om[...,0,2:3] - om[...,2,0:1] ) * s[0], - (om[...,1,0:1] - om[...,0,1:2] ) * s[0]]), - np.where(om[...,0,0:1] > np.maximum(om[...,1,1:2],om[...,2,2:3]), - np.block([(om[...,2,1:2] - om[...,1,2:3]) / s[1], - 0.25 * s[1], - (om[...,0,1:2] + om[...,1,0:1]) / s[1], - (om[...,0,2:3] + om[...,2,0:1]) / s[1]]), - np.where(om[...,1,1:2] > om[...,2,2:3], - np.block([(om[...,0,2:3] - om[...,2,0:1]) / s[2], - (om[...,0,1:2] + om[...,1,0:1]) / s[2], - 0.25 * s[2], - (om[...,1,2:3] + om[...,2,1:2]) / s[2]]), - np.block([(om[...,1,0:1] - om[...,0,1:2]) / s[3], - (om[...,0,2:3] + om[...,2,0:1]) / s[3], - (om[...,1,2:3] + om[...,2,1:2]) / s[3], - 0.25 * s[3]]), - ) - ) - )*np.array([1,_P,_P,_P]) - qu[qu[...,0]<0] *=-1 + s = np.array([ + 0.5 / np.sqrt( 1. + trace), + 2. * np.sqrt( 1. + om[...,0,0:1] - om[...,1,1:2] - om[...,2,2:3]), + 2. * np.sqrt( 1. + om[...,1,1:2] - om[...,2,2:3] - om[...,0,0:1]), + 2. * np.sqrt( 1. + om[...,2,2:3] - om[...,0,0:1] - om[...,1,1:2] ) + ]) + qu = np.where(trace>0, + np.block([0.25 / s[0], + (om[...,2,1:2] - om[...,1,2:3] ) * s[0], + (om[...,0,2:3] - om[...,2,0:1] ) * s[0], + (om[...,1,0:1] - om[...,0,1:2] ) * s[0]]), + np.where(om[...,0,0:1] > np.maximum(om[...,1,1:2],om[...,2,2:3]), + np.block([(om[...,2,1:2] - om[...,1,2:3]) / s[1], + 0.25 * s[1], + (om[...,0,1:2] + om[...,1,0:1]) / s[1], + (om[...,0,2:3] + om[...,2,0:1]) / s[1]]), + np.where(om[...,1,1:2] > om[...,2,2:3], + np.block([(om[...,0,2:3] - om[...,2,0:1]) / s[2], + (om[...,0,1:2] + om[...,1,0:1]) / s[2], + 0.25 * s[2], + (om[...,1,2:3] + om[...,2,1:2]) / s[2]]), + np.block([(om[...,1,0:1] - om[...,0,1:2]) / s[3], + (om[...,0,2:3] + om[...,2,0:1]) / s[3], + (om[...,1,2:3] + om[...,2,1:2]) / s[3], + 0.25 * s[3]]), + ) + ) + )*np.array([1.,_P,_P,_P]) + qu[qu[...,0] < 0.] *= -1. return qu @staticmethod def _om2eu(om: np.ndarray) -> np.ndarray: """Rotation matrix to Bunge Euler angles.""" with np.errstate(invalid='ignore',divide='ignore'): - zeta = 1.0/np.sqrt(1.0-om[...,2,2:3]**2) - eu = np.where(np.isclose(np.abs(om[...,2,2:3]),1.0,0.0), + zeta = 1./np.sqrt(1.-om[...,2,2:3]**2) + eu = np.where(np.isclose(np.abs(om[...,2,2:3]),1.,0.), np.block([np.arctan2(om[...,0,1:2],om[...,0,0:1]), - np.pi*0.5*(1-om[...,2,2:3]), + np.pi*0.5*(1.-om[...,2,2:3]), np.zeros(om.shape[:-2]+(1,)), ]), np.block([np.arctan2(om[...,2,0:1]*zeta,-om[...,2,1:2]*zeta), @@ -1398,9 +1452,8 @@ class Rotation: np.arctan2(om[...,0,2:3]*zeta,+om[...,1,2:3]*zeta) ]) ) - eu[np.abs(eu)<1.e-8] = 0.0 - eu = np.where(eu<0, (eu+2.0*np.pi)%np.array([2.0*np.pi,np.pi,2.0*np.pi]),eu) - return eu + eu[np.abs(eu) < 1.e-8] = 0.0 + return np.where(eu < 0., eu%(np.pi*np.array([2.,1.,2.])),eu) @staticmethod def _om2ax(om: np.ndarray) -> np.ndarray: @@ -1409,18 +1462,18 @@ class Rotation: om[...,2,0:1]-om[...,0,2:3], om[...,0,1:2]-om[...,1,0:1] ]) - t = 0.5*(om.trace(axis2=-2,axis1=-1) -1.0).reshape(om.shape[:-2]+(1,)) + t = 0.5*(om.trace(axis2=-2,axis1=-1) -1.).reshape(om.shape[:-2]+(1,)) w,vr = np.linalg.eig(om) # mask duplicated real eigenvalues - w[np.isclose(w[...,0],1.0+0.0j),1:] = 0. - w[np.isclose(w[...,1],1.0+0.0j),2:] = 0. + w[np.isclose(w[...,0],1.+0.j),1:] = 0. + w[np.isclose(w[...,1],1.+0.j),2:] = 0. vr = np.swapaxes(vr,-1,-2) - ax = np.where(np.abs(diag_delta)<1e-13, - np.real(vr[np.isclose(w,1.0+0.0j)]).reshape(om.shape[:-2]+(3,)), - np.abs(np.real(vr[np.isclose(w,1.0+0.0j)]).reshape(om.shape[:-2]+(3,))) \ + ax = np.where(np.abs(diag_delta)<1.e-13, + np.real(vr[np.isclose(w,1.+0.j)]).reshape(om.shape[:-2]+(3,)), + np.abs(np.real(vr[np.isclose(w,1.+0.j)]).reshape(om.shape[:-2]+(3,))) *np.sign(diag_delta)) - ax = np.block([ax,np.arccos(np.clip(t,-1.0,1.0))]) - ax[np.abs(ax[...,3])<1.e-8] = [ 0.0, 0.0, 1.0, 0.0] + ax = np.block([ax,np.arccos(np.clip(t,-1.,1.))]) + ax[np.abs(ax[...,3]) < 1.e-8] = np.array([0.,0.,1.,0.]) return ax @staticmethod @@ -1450,7 +1503,7 @@ class Rotation: -_P*sPhi*np.cos(ee[...,0:1]-ee[...,2:3]), -_P*sPhi*np.sin(ee[...,0:1]-ee[...,2:3]), -_P*cPhi*np.sin(ee[...,0:1]+ee[...,2:3])]) - qu[qu[...,0]<0.0]*=-1 + qu[qu[...,0] < 0.] *= -1. return qu @staticmethod @@ -1468,7 +1521,7 @@ class Rotation: -c[...,0:1]*s[...,1:2], +c[...,1:2] ]).reshape(eu.shape[:-1]+(3,3)) - om[np.abs(om)<1.e-12] = 0.0 + om[np.abs(om) < 1.e-12] = 0. return om @staticmethod @@ -1478,16 +1531,16 @@ class Rotation: sigma = 0.5*(eu[...,0:1]+eu[...,2:3]) delta = 0.5*(eu[...,0:1]-eu[...,2:3]) tau = np.linalg.norm(np.block([t,np.sin(sigma)]),axis=-1,keepdims=True) - alpha = np.where(np.abs(np.cos(sigma))<1.e-12,np.pi,2.0*np.arctan(tau/np.cos(sigma))) + alpha = np.where(np.abs(np.cos(sigma))<1.e-12,np.pi,2.*np.arctan(tau/np.cos(sigma))) with np.errstate(invalid='ignore',divide='ignore'): - ax = np.where(np.broadcast_to(np.abs(alpha)<1.0e-12,eu.shape[:-1]+(4,)), - [0.0,0.0,1.0,0.0], + ax = np.where(np.broadcast_to(np.abs(alpha)<1.e-12,eu.shape[:-1]+(4,)), + [0.,0.,1.,0.], np.block([-_P/tau*t*np.cos(delta), -_P/tau*t*np.sin(delta), -_P/tau* np.sin(sigma), alpha ])) - ax[(alpha<0.0).squeeze()] *=-1 + ax[(alpha<0.).squeeze()] *= -1. return ax @staticmethod @@ -1495,8 +1548,8 @@ class Rotation: """Bunge Euler angles to Rodrigues–Frank vector.""" ax = Rotation._eu2ax(eu) ro = np.block([ax[...,:3],np.tan(ax[...,3:4]*.5)]) - ro[ax[...,3]>=np.pi,3] = np.inf - ro[np.abs(ax[...,3])<1.e-16] = [ 0.0, 0.0, _P, 0.0 ] + ro[ax[...,3] >= np.pi,3] = np.inf + ro[np.abs(ax[...,3])<1.e-16] = np.array([0.,0.,_P,0.]) return ro @staticmethod @@ -1516,7 +1569,7 @@ class Rotation: """Axis–angle pair to quaternion.""" c = np.cos(ax[...,3:4]*.5) s = np.sin(ax[...,3:4]*.5) - qu = np.where(np.abs(ax[...,3:4])<1.e-6,[1.0, 0.0, 0.0, 0.0],np.block([c, ax[...,:3]*s])) + qu = np.where(np.abs(ax[...,3:4]) < 1.e-6,[1.,0.,0.,0.],np.block([c,ax[...,:3]*s])) return qu @staticmethod @@ -1524,17 +1577,17 @@ class Rotation: """Axis-angle pair to rotation matrix.""" c = np.cos(ax[...,3:4]) s = np.sin(ax[...,3:4]) - omc = 1. -c + omc = 1.-c om = np.block([c+omc*ax[...,0:1]**2, - omc*ax[...,0:1]*ax[...,1:2] + s*ax[...,2:3], - omc*ax[...,0:1]*ax[...,2:3] - s*ax[...,1:2], - omc*ax[...,0:1]*ax[...,1:2] - s*ax[...,2:3], + omc*ax[...,0:1]*ax[...,1:2] + s*ax[...,2:3], + omc*ax[...,0:1]*ax[...,2:3] - s*ax[...,1:2], + omc*ax[...,0:1]*ax[...,1:2] - s*ax[...,2:3], c+omc*ax[...,1:2]**2, - omc*ax[...,1:2]*ax[...,2:3] + s*ax[...,0:1], - omc*ax[...,0:1]*ax[...,2:3] + s*ax[...,1:2], - omc*ax[...,1:2]*ax[...,2:3] - s*ax[...,0:1], + omc*ax[...,1:2]*ax[...,2:3] + s*ax[...,0:1], + omc*ax[...,0:1]*ax[...,2:3] + s*ax[...,1:2], + omc*ax[...,1:2]*ax[...,2:3] - s*ax[...,0:1], c+omc*ax[...,2:3]**2]).reshape(ax.shape[:-1]+(3,3)) - return om if _P < 0.0 else np.swapaxes(om,-1,-2) + return om if _P < 0. else np.swapaxes(om,-1,-2) @staticmethod def _ax2eu(ax: np.ndarray) -> np.ndarray: @@ -1549,15 +1602,14 @@ class Rotation: np.inf, np.tan(ax[...,3:4]*0.5)) ]) - ro[np.abs(ax[...,3])<1.e-6] = [.0,.0,_P,.0] + ro[np.abs(ax[...,3]) < 1.e-6] = np.array([.0,.0,_P,.0]) return ro @staticmethod def _ax2ho(ax: np.ndarray) -> np.ndarray: """Axis–angle pair to homochoric vector.""" - f = (0.75 * ( ax[...,3:4] - np.sin(ax[...,3:4]) ))**(1.0/3.0) - ho = ax[...,:3] * f - return ho + f = (0.75 * ( ax[...,3:4] - np.sin(ax[...,3:4]) ))**(1./3.) + return ax[...,:3] * f @staticmethod def _ax2cu(ax: np.ndarray) -> np.ndarray: @@ -1588,16 +1640,15 @@ class Rotation: ax = np.where(np.isfinite(ro[...,3:4]), np.block([ro[...,0:3]*np.linalg.norm(ro[...,0:3],axis=-1,keepdims=True),2.*np.arctan(ro[...,3:4])]), np.block([ro[...,0:3],np.broadcast_to(np.pi,ro[...,3:4].shape)])) - ax[np.abs(ro[...,3]) < 1.e-8] = np.array([ 0.0, 0.0, 1.0, 0.0 ]) + ax[np.abs(ro[...,3]) < 1.e-8] = np.array([0.,0.,1.,0.]) return ax @staticmethod def _ro2ho(ro: np.ndarray) -> np.ndarray: """Rodrigues–Frank vector to homochoric vector.""" - f = np.where(np.isfinite(ro[...,3:4]),2.0*np.arctan(ro[...,3:4]) -np.sin(2.0*np.arctan(ro[...,3:4])),np.pi) - ho = np.where(np.broadcast_to(np.sum(ro[...,0:3]**2.0,axis=-1,keepdims=True) < 1.e-8,ro[...,0:3].shape), - np.zeros(3), ro[...,0:3]* (0.75*f)**(1.0/3.0)) - return ho + f = np.where(np.isfinite(ro[...,3:4]),2.*np.arctan(ro[...,3:4]) -np.sin(2.*np.arctan(ro[...,3:4])),np.pi) + return np.where(np.broadcast_to(np.sum(ro[...,0:3]**2,axis=-1,keepdims=True) < 1.e-8,ro[...,0:3].shape), + np.zeros(3), ro[...,0:3]* (0.75*f)**(1./3.)) @staticmethod def _ro2cu(ro: np.ndarray) -> np.ndarray: @@ -1631,13 +1682,12 @@ class Rotation: +9.528014229335313e-6, -5.660288876265125e-6, +1.2844901692764126e-6, +1.1255185726258763e-6, -1.3834391419956455e-6, +7.513691751164847e-7, -2.401996891720091e-7, +4.386887017466388e-8, -3.5917775353564864e-9]) - hmag_squared = np.sum(ho**2.,axis=-1,keepdims=True) + hmag_squared = np.sum(ho**2,axis=-1,keepdims=True) s = np.sum(tfit*hmag_squared**np.arange(len(tfit)),axis=-1,keepdims=True) with np.errstate(invalid='ignore'): - ax = np.where(np.broadcast_to(np.abs(hmag_squared)<1.e-8,ho.shape[:-1]+(4,)), - [ 0.0, 0.0, 1.0, 0.0 ], - np.block([ho/np.sqrt(hmag_squared),2.0*np.arccos(np.clip(s,-1.0,1.0))])) - return ax + return np.where(np.broadcast_to(np.abs(hmag_squared)<1.e-8,ho.shape[:-1]+(4,)), + [0.,0.,1.,0.], + np.block([ho/np.sqrt(hmag_squared),2.*np.arccos(np.clip(s,-1.,1.))])) @staticmethod def _ho2ro(ho: np.ndarray) -> np.ndarray: @@ -1661,27 +1711,25 @@ class Rotation: with np.errstate(invalid='ignore',divide='ignore'): # inverse M_3 - xyz2 = xyz3[...,0:2] * np.sqrt( 2.0*rs/(rs+np.abs(xyz3[...,2:3])) ) + xyz2 = xyz3[...,0:2] * np.sqrt( 2.*rs/(rs+np.abs(xyz3[...,2:3])) ) qxy = np.sum(xyz2**2,axis=-1,keepdims=True) q2 = qxy + np.max(np.abs(xyz2),axis=-1,keepdims=True)**2 sq2 = np.sqrt(q2) - q = (_beta/np.sqrt(2.0)/_R1) * np.sqrt(q2*qxy/(q2-np.max(np.abs(xyz2),axis=-1,keepdims=True)*sq2)) + q = (_beta/np.sqrt(2.)/_R1) * np.sqrt(q2*qxy/(q2-np.max(np.abs(xyz2),axis=-1,keepdims=True)*sq2)) tt = np.clip((np.min(np.abs(xyz2),axis=-1,keepdims=True)**2\ - +np.max(np.abs(xyz2),axis=-1,keepdims=True)*sq2)/np.sqrt(2.0)/qxy,-1.0,1.0) + +np.max(np.abs(xyz2),axis=-1,keepdims=True)*sq2)/np.sqrt(2.)/qxy,-1.,1.) T_inv = np.where(np.abs(xyz2[...,1:2]) <= np.abs(xyz2[...,0:1]), - np.block([np.ones_like(tt),np.arccos(tt)/np.pi*12.0]), - np.block([np.arccos(tt)/np.pi*12.0,np.ones_like(tt)]))*q - T_inv[xyz2<0.0] *= -1.0 - T_inv[np.broadcast_to(np.isclose(qxy,0.0,rtol=0.0,atol=1.0e-12),T_inv.shape)] = 0.0 - cu = np.block([T_inv, np.where(xyz3[...,2:3]<0.0,-np.ones_like(xyz3[...,2:3]),np.ones_like(xyz3[...,2:3])) \ - * rs/np.sqrt(6.0/np.pi), + np.block([np.ones_like(tt),np.arccos(tt)/np.pi*12.]), + np.block([np.arccos(tt)/np.pi*12.,np.ones_like(tt)]))*q + T_inv[xyz2<0.] *= -1. + T_inv[np.broadcast_to(np.isclose(qxy,0.,rtol=0.,atol=1.e-12),T_inv.shape)] = 0. + cu = np.block([T_inv, np.where(xyz3[...,2:3]<0.,-np.ones_like(xyz3[...,2:3]),np.ones_like(xyz3[...,2:3])) \ + * rs/np.sqrt(6./np.pi), ])/ _sc - cu[np.isclose(np.sum(np.abs(ho),axis=-1),0.0,rtol=0.0,atol=1.0e-16)] = 0.0 - cu = np.take_along_axis(cu,Rotation._get_pyramid_order(ho,'backward'),-1) - - return cu + cu[np.isclose(np.sum(np.abs(ho),axis=-1),0.,rtol=0.,atol=1.e-16)] = 0. + return np.take_along_axis(cu,Rotation._get_pyramid_order(ho,'backward'),-1) #---------- Cubochoric ---------- @staticmethod @@ -1724,32 +1772,30 @@ class Rotation: # get pyramid and scale by grid parameter ratio XYZ = np.take_along_axis(cu,Rotation._get_pyramid_order(cu,'forward'),-1) * _sc order = np.abs(XYZ[...,1:2]) <= np.abs(XYZ[...,0:1]) - q = np.pi/12.0 * np.where(order,XYZ[...,1:2],XYZ[...,0:1]) \ + q = np.pi/12. * np.where(order,XYZ[...,1:2],XYZ[...,0:1]) \ / np.where(order,XYZ[...,0:1],XYZ[...,1:2]) c = np.cos(q) s = np.sin(q) - q = _R1*2.0**0.25/_beta/ np.sqrt(np.sqrt(2.0)-c) \ + q = _R1*2.**0.25/_beta/ np.sqrt(np.sqrt(2.)-c) \ * np.where(order,XYZ[...,0:1],XYZ[...,1:2]) - T = np.block([ (np.sqrt(2.0)*c - 1.0), np.sqrt(2.0) * s]) * q + T = np.block([(np.sqrt(2.)*c - 1.), np.sqrt(2.) * s]) * q # transform to sphere grid (inverse Lambert) c = np.sum(T**2,axis=-1,keepdims=True) - s = c * np.pi/24.0 /XYZ[...,2:3]**2 - c = c * np.sqrt(np.pi/24.0)/XYZ[...,2:3] - q = np.sqrt( 1.0 - s) + s = c * np.pi/24. /XYZ[...,2:3]**2 + c = c * np.sqrt(np.pi/24.)/XYZ[...,2:3] + q = np.sqrt( 1. - s) - ho = np.where(np.isclose(np.sum(np.abs(XYZ[...,0:2]),axis=-1,keepdims=True),0.0,rtol=0.0,atol=1.0e-16), - np.block([np.zeros_like(XYZ[...,0:2]),np.sqrt(6.0/np.pi) *XYZ[...,2:3]]), + ho = np.where(np.isclose(np.sum(np.abs(XYZ[...,0:2]),axis=-1,keepdims=True),0.,rtol=0.,atol=1.e-16), + np.block([np.zeros_like(XYZ[...,0:2]),np.sqrt(6./np.pi)*XYZ[...,2:3]]), np.block([np.where(order,T[...,0:1],T[...,1:2])*q, np.where(order,T[...,1:2],T[...,0:1])*q, - np.sqrt(6.0/np.pi) * XYZ[...,2:3] - c]) + np.sqrt(6./np.pi) * XYZ[...,2:3] - c]) ) - ho[np.isclose(np.sum(np.abs(cu),axis=-1),0.0,rtol=0.0,atol=1.0e-16)] = 0.0 - ho = np.take_along_axis(ho,Rotation._get_pyramid_order(cu,'backward'),-1) - - return ho + ho[np.isclose(np.sum(np.abs(cu),axis=-1),0.,rtol=0.,atol=1.e-16)] = 0. + return np.take_along_axis(ho,Rotation._get_pyramid_order(cu,'backward'),-1) @staticmethod diff --git a/python/damask/_table.py b/python/damask/_table.py index 356e73730..e213243a4 100644 --- a/python/damask/_table.py +++ b/python/damask/_table.py @@ -1,6 +1,6 @@ import re import copy -from typing import Union, Tuple, List, Iterable +from typing import Optional, Union, Tuple, List, Iterable import pandas as pd import numpy as np @@ -13,8 +13,8 @@ class Table: def __init__(self, shapes: dict = {}, - data: np.ndarray = None, - comments: Union[str, Iterable[str]] = None): + data: Optional[np.ndarray] = None, + comments: Union[None, str, Iterable[str]] = None): """ New spreadsheet. @@ -25,12 +25,13 @@ class Table: For instance, 'F':(3,3) for a deformation gradient, or 'r':(1,) for a scalar. data : numpy.ndarray or pandas.DataFrame, optional Data. Existing column labels of a pandas.DataFrame will be replaced. - comments : str or iterable of str, optional + comments : (iterable of) str, optional Additional, human-readable information. """ - comments_ = [comments] if isinstance(comments,str) else comments - self.comments = [] if comments_ is None else [str(c) for c in comments_] + self.comments = [] if comments is None else \ + [comments] if isinstance(comments,str) else \ + [str(c) for c in comments] self.shapes = { k:(v,) if isinstance(v,(np.int64,np.int32,int)) else v for k,v in shapes.items() } self.data = pd.DataFrame(data=data) self._relabel('uniform') @@ -185,16 +186,6 @@ class Table: self.data.columns = self._label(self.shapes,how) # type: ignore - def _add_comment(self, - label: str, - shape: Tuple[int, ...], - info: str = None): - if info is not None: - specific = f'{label}{" "+str(shape) if np.prod(shape,dtype=np.int64) > 1 else ""}: {info}' - general = util.execution_stamp('Table') - self.comments.append(f'{specific} / {general}') - - def isclose(self, other: 'Table', rtol: float = 1e-5, @@ -383,7 +374,7 @@ class Table: def set(self, label: str, data: np.ndarray, - info: str = None) -> 'Table': + info: Optional[str] = None) -> 'Table': """ Add new or replace existing column data. @@ -402,13 +393,15 @@ class Table: Updated table. """ - dup = self.copy() - dup._add_comment(label, data.shape[1:], info) + def add_comment(label: str, shape: Tuple[int, ...],info: str) -> List[str]: + specific = f'{label}{" "+str(shape) if np.prod(shape,dtype=np.int64) > 1 else ""}: {info}' + general = util.execution_stamp('Table') + return [f'{specific} / {general}'] - if m := re.match(r'(.*)\[((\d+,)*(\d+))\]',label): - key = m.group(1) - else: - key = label + dup = self.copy() + if info is not None: self.comments += add_comment(label,data.shape[1:],info) + + key = m.group(1) if (m := re.match(r'(.*)\[((\d+,)*(\d+))\]',label)) else label if key in dup.shapes: @@ -458,15 +451,15 @@ class Table: def rename(self, old: Union[str, Iterable[str]], new: Union[str, Iterable[str]], - info: str = None) -> 'Table': + info: Optional[str] = None) -> 'Table': """ Rename column data. Parameters ---------- - label_old : str or iterable of str + label_old : (iterable of) str Old column label(s). - label_new : str or iterable of str + label_new : (iterable of) str New column label(s). Returns diff --git a/python/damask/_typehints.py b/python/damask/_typehints.py index f836e1f59..5fcf39a41 100644 --- a/python/damask/_typehints.py +++ b/python/damask/_typehints.py @@ -1,6 +1,6 @@ """Functionality for typehints.""" -from typing import Sequence, Union, Literal, TextIO, Collection +from typing import Sequence, Union, Literal, TextIO from pathlib import Path import numpy as np @@ -8,7 +8,6 @@ import numpy as np FloatSequence = Union[np.ndarray,Sequence[float]] IntSequence = Union[np.ndarray,Sequence[int]] -IntCollection = Union[np.ndarray,Collection[int]] FileHandle = Union[TextIO, str, Path] CrystalFamily = Union[None,Literal['triclinic', 'monoclinic', 'orthorhombic', 'tetragonal', 'hexagonal', 'cubic']] CrystalLattice = Union[None,Literal['aP', 'mP', 'mS', 'oP', 'oS', 'oI', 'oF', 'tP', 'tI', 'hP', 'cP', 'cI', 'cF']] diff --git a/python/damask/_vtk.py b/python/damask/_vtk.py index 46d779023..95eee8bd3 100644 --- a/python/damask/_vtk.py +++ b/python/damask/_vtk.py @@ -1,7 +1,7 @@ import os import multiprocessing as mp from pathlib import Path -from typing import Union, Literal, List, Sequence +from typing import Optional, Union, Literal, List, Sequence import numpy as np import vtk @@ -104,19 +104,19 @@ class VTK: @comments.setter def comments(self, - comments: Union[str, Sequence[str]]): + comments: Sequence[str]): """ Set comments. Parameters ---------- - comments : str or sequence of str + comments : sequence of str Comments. """ s = vtk.vtkStringArray() s.SetName('comments') - for c in util.tail_repack(comments,self.comments): + for c in comments: s.InsertNextValue(c) self.vtk_data.GetFieldData().AddArray(s) @@ -286,7 +286,7 @@ class VTK: @staticmethod def load(fname: Union[str, Path], - dataset_type: Literal['ImageData', 'UnstructuredGrid', 'PolyData', 'RectilinearGrid'] = None) -> 'VTK': + dataset_type: Literal[None, 'ImageData', 'UnstructuredGrid', 'PolyData', 'RectilinearGrid'] = None) -> 'VTK': """ Load from VTK file. @@ -409,11 +409,11 @@ class VTK: # Check https://blog.kitware.com/ghost-and-blanking-visibility-changes/ for missing data def set(self, - label: str = None, - data: Union[np.ndarray, np.ma.MaskedArray] = None, - info: str = None, + label: Optional[str] = None, + data: Union[None, np.ndarray, np.ma.MaskedArray] = None, + info: Optional[str] = None, *, - table: 'Table' = None): + table: Optional['Table'] = None): """ Add new or replace existing point or cell data. @@ -475,13 +475,13 @@ class VTK: _add_array(dup.vtk_data, label, np.where(data.mask,data.fill_value,data) if isinstance(data,np.ma.MaskedArray) else data) - if info is not None: dup.comments += f'{label}: {info}' + if info is not None: dup.comments += [f'{label}: {info}'] else: raise ValueError('no label defined for data') elif isinstance(table,Table): for l in table.labels: _add_array(dup.vtk_data,l,table.get(l)) - if info is not None: dup.comments += f'{l}: {info}' + if info is not None: dup.comments += [f'{l}: {info}'] else: raise TypeError @@ -533,7 +533,7 @@ class VTK: def show(self, - label: str = None, + label: Optional[str] = None, colormap: Union[Colormap, str] = 'cividis'): """ Render. @@ -547,9 +547,11 @@ class VTK: Notes ----- - See http://compilatrix.com/article/vtk-1 for further ideas. + The first component is shown when visualizing vector datasets + (this includes tensor datasets because they are flattened). """ + # See http://compilatrix.com/article/vtk-1 for possible improvements. try: import wx _ = wx.App(False) # noqa diff --git a/python/damask/grid_filters.py b/python/damask/grid_filters.py index 747fc629d..fab346c4e 100644 --- a/python/damask/grid_filters.py +++ b/python/damask/grid_filters.py @@ -75,8 +75,8 @@ def curl(size: _FloatSequence, e[0, 2, 1] = e[2, 1, 0] = e[1, 0, 2] = -1.0 f_fourier = _np.fft.rfftn(f,axes=(0,1,2)) - curl_ = (_np.einsum('slm,ijkl,ijkm ->ijks', e,k_s,f_fourier)*2.0j*_np.pi if n == 3 else # vector, 3 -> 3 - _np.einsum('slm,ijkl,ijknm->ijksn',e,k_s,f_fourier)*2.0j*_np.pi) # tensor, 3x3 -> 3x3 + curl_ = (_np.einsum('slm,ijkl,ijkm ->ijks' if n == 3 else + 'slm,ijkl,ijknm->ijksn',e,k_s,f_fourier)*2.0j*_np.pi) # vector 3->3, tensor 3x3->3x3 return _np.fft.irfftn(curl_,axes=(0,1,2),s=f.shape[:3]) @@ -103,10 +103,10 @@ def divergence(size: _FloatSequence, k_s = _ks(size,f.shape[:3],True) f_fourier = _np.fft.rfftn(f,axes=(0,1,2)) - div_ = (_np.einsum('ijkl,ijkl ->ijk', k_s,f_fourier)*2.0j*_np.pi if n == 3 else # vector, 3 -> 1 - _np.einsum('ijkm,ijklm->ijkl',k_s,f_fourier)*2.0j*_np.pi) # tensor, 3x3 -> 3 + divergence_ = (_np.einsum('ijkl,ijkl ->ijk' if n == 3 else + 'ijkm,ijklm->ijkl', k_s,f_fourier)*2.0j*_np.pi) # vector 3->1, tensor 3x3->3 - return _np.fft.irfftn(div_,axes=(0,1,2),s=f.shape[:3]) + return _np.fft.irfftn(divergence_,axes=(0,1,2),s=f.shape[:3]) def gradient(size: _FloatSequence, @@ -124,17 +124,17 @@ def gradient(size: _FloatSequence, Returns ------- ∇ f : numpy.ndarray, shape (:,:,:,3) or (:,:,:,3,3) - Divergence of f. + Gradient of f. """ n = _np.prod(f.shape[3:]) k_s = _ks(size,f.shape[:3],True) f_fourier = _np.fft.rfftn(f,axes=(0,1,2)) - grad_ = (_np.einsum('ijkl,ijkm->ijkm', f_fourier,k_s)*2.0j*_np.pi if n == 1 else # scalar, 1 -> 3 - _np.einsum('ijkl,ijkm->ijklm',f_fourier,k_s)*2.0j*_np.pi) # vector, 3 -> 3x3 + gradient_ = (_np.einsum('ijkl,ijkm->ijkm' if n == 1 else + 'ijkl,ijkm->ijklm',f_fourier,k_s)*2.0j*_np.pi) # scalar 1->3, vector 3->3x3 - return _np.fft.irfftn(grad_,axes=(0,1,2),s=f.shape[:3]) + return _np.fft.irfftn(gradient_,axes=(0,1,2),s=f.shape[:3]) def coordinates0_point(cells: _IntSequence, @@ -296,8 +296,8 @@ def cellsSizeOrigin_coordinates0_point(coordinates0: _np.ndarray, origin = mincorner - delta*.5 # 1D/2D: size/origin combination undefined, set origin to 0.0 - size [_np.where(cells==1)] = origin[_np.where(cells==1)]*2. - origin[_np.where(cells==1)] = 0.0 + size [_np.where(cells == 1)] = origin[_np.where(cells == 1)]*2. + origin[_np.where(cells == 1)] = 0.0 if cells.prod() != len(coordinates0): raise ValueError(f'data count {len(coordinates0)} does not match cells {cells}') @@ -541,28 +541,118 @@ def coordinates0_valid(coordinates0: _np.ndarray) -> bool: return False +def unravel_index(idx: _np.ndarray) -> _np.ndarray: + """ + Convert flat indices to coordinate indices. + + Parameters + ---------- + idx : numpy.ndarray, shape (:,:,:) + Grid of flat indices. + + Returns + ------- + unravelled : numpy.ndarray, shape (:,:,:,3) + Grid of coordinate indices. + + Examples + -------- + Unravel a linearly increasing sequence of material indices on a 3 × 2 × 1 grid. + + >>> import numpy as np + >>> import damask + >>> seq = np.arange(6).reshape((3,2,1),order='F') + >>> (coord_idx := damask.grid_filters.unravel_index(seq)) + array([[[[0, 0, 0]], + + [[0, 1, 0]]], + + + [[[1, 0, 0]], + + [[1, 1, 0]]], + + + [[[2, 0, 0]], + + [[2, 1, 0]]]]) + >>> coord_idx[1,1,0] + array([1, 1, 0]) + + """ + cells = idx.shape + idx_ = _np.expand_dims(idx,3) + return _np.block([ idx_ %cells[0], + (idx_//cells[0]) %cells[1], + ((idx_//cells[0])//cells[1])%cells[2]]) + +def ravel_index(idx: _np.ndarray) -> _np.ndarray: + """ + Convert coordinate indices to flat indices. + + Parameters + ---------- + idx : numpy.ndarray, shape (:,:,:,3) + Grid of coordinate indices. + + Returns + ------- + ravelled : numpy.ndarray, shape (:,:,:) + Grid of flat indices. + + Examples + -------- + Ravel a reversed sequence of coordinate indices on a 2 × 2 × 1 grid. + + >>> import numpy as np + >>> import damask + >>> (rev := np.array([[1,1,0],[0,1,0],[1,0,0],[0,0,0]]).reshape((2,2,1,3))) + array([[[[1, 1, 0]], + + [[0, 1, 0]]], + + + [[[1, 0, 0]], + + [[0, 0, 0]]]]) + >>> (flat_idx := damask.grid_filters.ravel_index(rev)) + array([[[3], + [2]], + + [[1], + [0]]]) + + """ + cells = idx.shape[:3] + return idx[:,:,:,0] \ + + idx[:,:,:,1]*cells[0] \ + + idx[:,:,:,2]*cells[0]*cells[1] + + def regrid(size: _FloatSequence, F: _np.ndarray, cells: _IntSequence) -> _np.ndarray: """ - Return mapping from coordinates in deformed configuration to a regular grid. + Map a deformed grid A back to a rectilinear grid B. + + The size of grid B is chosen as the average deformed size of grid A. Parameters ---------- size : sequence of float, len (3) - Physical size. - F : numpy.ndarray, shape (:,:,:,3,3), shape (:,:,:,3,3) - Deformation gradient field. + Physical size of grid A. + F : numpy.ndarray, shape (:,:,:,3,3) + Deformation gradient field on grid A. cells : sequence of int, len (3) - Cell count along x,y,z of remapping grid. + Cell count along x,y,z of grid B. + + Returns + ------- + idx : numpy.ndarray of int, shape (cells) + Flat index of closest point on deformed grid A for each point on grid B. """ - c = coordinates_point(size,F) - - outer = _np.dot(_np.average(F,axis=(0,1,2)),size) - for d in range(3): - c[_np.where(c[:,:,:,d]<0)] += outer[d] - c[_np.where(c[:,:,:,d]>outer[d])] -= outer[d] - - tree = _spatial.cKDTree(c.reshape(-1,3),boxsize=outer) - return tree.query(coordinates0_point(cells,outer))[1].flatten() + box = _np.dot(_np.average(F,axis=(0,1,2)),size) + c = coordinates_point(size,F)%box + tree = _spatial.cKDTree(c.reshape((-1,3),order='F'),boxsize=box) + return tree.query(coordinates0_point(cells,box))[1] diff --git a/python/damask/seeds.py b/python/damask/seeds.py index 11be5cc93..f8cb19995 100644 --- a/python/damask/seeds.py +++ b/python/damask/seeds.py @@ -1,21 +1,20 @@ - """Functionality for generation of seed points for Voronoi or Laguerre tessellation.""" -from typing import Tuple as _Tuple +from typing import Optional as _Optional, Tuple as _Tuple from scipy import spatial as _spatial import numpy as _np from ._typehints import FloatSequence as _FloatSequence, IntSequence as _IntSequence, \ - NumpyRngSeed as _NumpyRngSeed, IntCollection as _IntCollection + NumpyRngSeed as _NumpyRngSeed from . import util as _util from . import grid_filters as _grid_filters def from_random(size: _FloatSequence, N_seeds: int, - cells: _IntSequence = None, - rng_seed: _NumpyRngSeed = None) -> _np.ndarray: + cells: _Optional[_IntSequence] = None, + rng_seed: _Optional[_NumpyRngSeed] = None) -> _np.ndarray: """ Place seeds randomly in space. @@ -55,7 +54,7 @@ def from_Poisson_disc(size: _FloatSequence, N_candidates: int, distance: float, periodic: bool = True, - rng_seed: _NumpyRngSeed = None) -> _np.ndarray: + rng_seed: _Optional[_NumpyRngSeed] = None) -> _np.ndarray: """ Place seeds according to a Poisson disc distribution. @@ -107,7 +106,7 @@ def from_Poisson_disc(size: _FloatSequence, def from_grid(grid, - selection: _IntCollection = None, + selection: _Optional[_IntSequence] = None, invert_selection: bool = False, average: bool = False, periodic: bool = True) -> _Tuple[_np.ndarray, _np.ndarray]: @@ -118,7 +117,7 @@ def from_grid(grid, ---------- grid : damask.Grid Grid from which the material IDs are used as seeds. - selection : int or collection of int, optional + selection : (sequence of) int, optional Material IDs to consider. invert_selection : bool, optional Consider all material IDs except those in selection. Defaults to False. @@ -135,7 +134,7 @@ def from_grid(grid, """ material = grid.material.reshape((-1,1),order='F') mask = _np.full(grid.cells.prod(),True,dtype=bool) if selection is None else \ - _np.isin(material,_util.aslist(selection),invert=invert_selection).flatten() + _np.isin(material,selection,invert=invert_selection).flatten() coords = _grid_filters.coordinates0_point(grid.cells,grid.size).reshape(-1,3,order='F') if not average: diff --git a/python/damask/solver/_marc.py b/python/damask/solver/_marc.py index 51c65a695..1afb5ddc6 100644 --- a/python/damask/solver/_marc.py +++ b/python/damask/solver/_marc.py @@ -3,7 +3,7 @@ import shlex import re from pathlib import Path -_marc_version = '2022.1' +_marc_version = '2022.4' _marc_root = '/opt/msc' _damask_root = str(Path(__file__).parents[3]) diff --git a/python/damask/util.py b/python/damask/util.py index ec42dede0..666bffc0b 100644 --- a/python/damask/util.py +++ b/python/damask/util.py @@ -10,16 +10,16 @@ import signal as _signal import fractions as _fractions from collections import abc as _abc from functools import reduce as _reduce, partial as _partial -from typing import Callable as _Callable, Union as _Union, Iterable as _Iterable, Sequence as _Sequence, Dict as _Dict, \ - List as _List, Tuple as _Tuple, Literal as _Literal, Any as _Any, Collection as _Collection, TextIO as _TextIO +from typing import Optional as _Optional, Callable as _Callable, Union as _Union, Iterable as _Iterable, \ + Dict as _Dict, List as _List, Tuple as _Tuple, Literal as _Literal, \ + Any as _Any, TextIO as _TextIO from pathlib import Path as _Path import numpy as _np import h5py as _h5py from . import version as _version -from ._typehints import FloatSequence as _FloatSequence, NumpyRngSeed as _NumpyRngSeed, IntCollection as _IntCollection, \ - FileHandle as _FileHandle +from ._typehints import FloatSequence as _FloatSequence, NumpyRngSeed as _NumpyRngSeed, FileHandle as _FileHandle # https://svn.blender.org/svnroot/bf-blender/trunk/blender/build_files/scons/tools/bcolors.py # https://stackoverflow.com/questions/287871 @@ -40,29 +40,33 @@ _colors = { # Functions #################################################################################################### def srepr(msg, - glue: str = '\n') -> str: + glue: str = '\n', + quote: bool = False) -> str: r""" - Join items with glue string. + Join (quoted) items with glue string. Parameters ---------- - msg : object with __repr__ or sequence of objects with __repr__ + msg : (sequence of) object with __repr__ Items to join. glue : str, optional Glue used for joining operation. Defaults to '\n'. + quote : bool, optional + Quote items. Defaults to False. Returns ------- joined : str - String representation of the joined items. + String representation of the joined and quoted items. """ + q = '"' if quote else '' if (not hasattr(msg, 'strip') and (hasattr(msg, '__getitem__') or hasattr(msg, '__iter__'))): - return glue.join(str(x) for x in msg) + return glue.join(q+str(x)+q for x in msg) else: - return msg if isinstance(msg,str) else repr(msg) + return q+(msg if isinstance(msg,str) else repr(msg))+q def emph(msg) -> str: @@ -71,7 +75,7 @@ def emph(msg) -> str: Parameters ---------- - msg : object with __repr__ or sequence of objects with __repr__ + msg : (sequence of) object with __repr__ Message to format. Returns @@ -88,7 +92,7 @@ def deemph(msg) -> str: Parameters ---------- - msg : object with __repr__ or sequence of objects with __repr__ + msg : (sequence of) object with __repr__ Message to format. Returns @@ -105,7 +109,7 @@ def warn(msg) -> str: Parameters ---------- - msg : object with __repr__ or sequence of objects with __repr__ + msg : (sequence of) object with __repr__ Message to format. Returns @@ -122,7 +126,7 @@ def strikeout(msg) -> str: Parameters ---------- - msg : object with __repr__ or iterable of objects with __repr__ + msg : (iterable of) object with __repr__ Message to format. Returns @@ -136,8 +140,8 @@ def strikeout(msg) -> str: def run(cmd: str, wd: str = './', - env: _Dict[str, str] = None, - timeout: int = None) -> _Tuple[str, str]: + env: _Optional[_Dict[str, str]] = None, + timeout: _Optional[int] = None) -> _Tuple[str, str]: """ Run a command. @@ -210,6 +214,14 @@ def open_text(fname: _FileHandle, open(_Path(fname).expanduser(),mode,newline=('\n' if mode == 'w' else None)) +def execution_stamp(class_name: str, + function_name: _Optional[str] = None) -> str: + """Timestamp the execution of a (function within a) class.""" + now = _datetime.datetime.now().astimezone().strftime('%Y-%m-%d %H:%M:%S%z') + _function_name = '' if function_name is None else f'.{function_name}' + return f'damask.{class_name}{_function_name} v{_version} ({now})' + + def natural_sort(key: str) -> _List[_Union[int, str]]: """ Natural sort. @@ -226,7 +238,7 @@ def natural_sort(key: str) -> _List[_Union[int, str]]: def show_progress(iterable: _Iterable, - N_iter: int = None, + N_iter: _Optional[int] = None, prefix: str = '', bar_length: int = 50) -> _Any: """ @@ -403,36 +415,35 @@ def project_equal_area(vector: _np.ndarray, return _np.roll(_np.block([v[...,:2]/_np.sqrt(1.0+_np.abs(v[...,2:3])),_np.zeros_like(v[...,2:3])]), -shift if keepdims else 0,axis=-1)[...,:3 if keepdims else 2] -def execution_stamp(class_name: str, - function_name: str = None) -> str: - """Timestamp the execution of a (function within a) class.""" - now = _datetime.datetime.now().astimezone().strftime('%Y-%m-%d %H:%M:%S%z') - _function_name = '' if function_name is None else f'.{function_name}' - return f'damask.{class_name}{_function_name} v{_version} ({now})' - -def hybrid_IA(dist: _np.ndarray, +def hybrid_IA(dist: _FloatSequence, N: int, - rng_seed: _NumpyRngSeed = None) -> _np.ndarray: + rng_seed: _Optional[_NumpyRngSeed] = None) -> _np.ndarray: """ Hybrid integer approximation. Parameters ---------- dist : numpy.ndarray - Distribution to be approximated + Distribution to be approximated. N : int Number of samples to draw. rng_seed : {None, int, array_like[ints], SeedSequence, BitGenerator, Generator}, optional A seed to initialize the BitGenerator. Defaults to None. If None, then fresh, unpredictable entropy will be pulled from the OS. + Returns + ------- + hist : numpy.ndarray, shape (N) + Integer approximation of the distribution. + """ - N_opt_samples,N_inv_samples = (max(_np.count_nonzero(dist),N),0) # random subsampling if too little samples requested + N_opt_samples = max(_np.count_nonzero(dist),N) # random subsampling if too little samples requested + N_inv_samples = 0 scale_,scale,inc_factor = (0.0,float(N_opt_samples),1.0) while (not _np.isclose(scale, scale_)) and (N_inv_samples != N_opt_samples): - repeats = _np.rint(scale*dist).astype(_np.int64) + repeats = _np.rint(scale*_np.array(dist)).astype(_np.int64) N_inv_samples = _np.sum(repeats) scale_,scale,inc_factor = (scale,scale+inc_factor*0.5*(scale - scale_), inc_factor*2.0) \ if N_inv_samples < N_opt_samples else \ @@ -486,18 +497,18 @@ def shapeshifter(fro: _Tuple[int, ...], final_shape: _List[int] = [] index = 0 for i,item in enumerate(_to): - if item==_fro[index]: + if item == _fro[index]: final_shape.append(item) index+=1 else: final_shape.append(1) - if _fro[index]==1 and not keep_ones: + if _fro[index] == 1 and not keep_ones: index+=1 - if index==len(_fro): + if index == len(_fro): final_shape = final_shape+[1]*(len(_to)-i-1) break - if index!=len(_fro): raise ValueError(f'shapes cannot be shifted {fro} --> {to}') - return tuple(final_shape[::-1] if mode=='left' else final_shape) + if index != len(_fro): raise ValueError(f'shapes cannot be shifted {fro} --> {to}') + return tuple(final_shape[::-1] if mode == 'left' else final_shape) def shapeblender(a: _Tuple[int, ...], b: _Tuple[int, ...]) -> _Tuple[int, ...]: @@ -528,37 +539,82 @@ def shapeblender(a: _Tuple[int, ...], return a + b[i:] -def extend_docstring(extra_docstring: str) -> _Callable: +def _docstringer(docstring: _Union[str, _Callable], + extra_parameters: _Optional[str] = None, + # extra_examples: _Optional[str] = None, + # extra_notes: _Optional[str] = None, + return_type: _Union[None, str, _Callable] = None) -> str: """ - Decorator: Append to function's docstring. + Extend a docstring. Parameters ---------- - extra_docstring : str - Docstring to append. + docstring : str or callable, optional + Docstring (of callable) to extend. + extra_parameters : str, optional + Additional information to append to Parameters section. + return_type : str or callable, optional + Type of return variable. """ - def _decorator(func): - func.__doc__ += extra_docstring - return func - return _decorator + docstring_ = str( docstring if isinstance(docstring,str) + else docstring.__doc__ if hasattr(docstring,'__doc__') + else '') + d = dict(Parameters=extra_parameters, + # Examples=extra_examples, + # Notes=extra_notes, + ) + for key,extra in [(k,v) for (k,v) in d.items() if v is not None]: + if not (heading := _re.search(fr'^([ ]*){key}\s*\n\1{"-"*len(key)}', + docstring_,flags=_re.MULTILINE)): + raise RuntimeError(f"Docstring {docstring_} lacks a correctly formatted {key} section to insert values into") + content = [line for line in extra.split('\n') if line.strip()] + indent = len(heading.group(1)) + shift = min([len(line)-len(line.lstrip(' '))-indent for line in content]) + extra = '\n'.join([(line[shift:] if shift > 0 else + f'{" "*-shift}{line}') for line in content]) + docstring_ = _re.sub(fr'(^([ ]*){key}\s*\n\2{"-"*len(key)}[\n ]*[A-Za-z0-9_ ]*: ([^\n]+\n)*)', + fr'\1{extra}\n', + docstring_,flags=_re.MULTILINE) + if return_type is None: + return docstring_ + else: + if isinstance(return_type,str): + return_type_ = return_type + else: + return_class = return_type.__annotations__.get('return','') + return_type_ = (_sys.modules[return_type.__module__].__name__.split('.')[0] + +'.' + +(return_class.__name__ if not isinstance(return_class,str) else return_class) + ) -def extended_docstring(f: _Callable, - extra_docstring: str) -> _Callable: + return _re.sub(r'(^([ ]*)Returns\s*\n\2-------\s*\n[ ]*[A-Za-z0-9_ ]*: )(.*)\n', + fr'\1{return_type_}\n', + docstring_,flags=_re.MULTILINE) + +def extend_docstring(docstring: _Union[None, str, _Callable] = None, + extra_parameters: _Optional[str] = None) -> _Callable: """ - Decorator: Combine another function's docstring with a given docstring. + Decorator: Extend the function's docstring. Parameters ---------- - f : function - Function of which the docstring is taken. - extra_docstring : str - Docstring to append. + docstring : str or callable, optional + Docstring to extend. Defaults to that of decorated function. + extra_parameters : str, optional + Additional information to append to Parameters section. + + Notes + ----- + Return type will become own type if docstring is callable. """ def _decorator(func): - func.__doc__ = f.__doc__ + extra_docstring + func.__doc__ = _docstringer(func.__doc__ if docstring is None else docstring, + extra_parameters, + func if isinstance(docstring,_Callable) else None, + ) return func return _decorator @@ -622,8 +678,8 @@ def DREAM3D_cell_data_group(fname: _Union[str, _Path]) -> str: def Bravais_to_Miller(*, - uvtw: _np.ndarray = None, - hkil: _np.ndarray = None) -> _np.ndarray: + uvtw: _Optional[_np.ndarray] = None, + hkil: _Optional[_np.ndarray] = None) -> _np.ndarray: """ Transform 4 Miller–Bravais indices to 3 Miller indices of crystal direction [uvw] or plane normal (hkl). @@ -649,10 +705,9 @@ def Bravais_to_Miller(*, [0,0,0,1]])) return _np.einsum('il,...l',basis,axis) - def Miller_to_Bravais(*, - uvw: _np.ndarray = None, - hkl: _np.ndarray = None) -> _np.ndarray: + uvw: _Optional[_np.ndarray] = None, + hkl: _Optional[_np.ndarray] = None) -> _np.ndarray: """ Transform 3 Miller indices to 4 Miller–Bravais indices of crystal direction [uvtw] or plane normal (hkil). @@ -706,7 +761,6 @@ def dict_prune(d: _Dict) -> _Dict: return new - def dict_flatten(d: _Dict) -> _Dict: """ Recursively remove keys of single-entry dictionaries. @@ -731,54 +785,6 @@ def dict_flatten(d: _Dict) -> _Dict: return new -def tail_repack(extended: _Union[str, _Sequence[str]], - existing: _List[str] = []) -> _List[str]: - """ - Repack tailing characters into single string if all are new. - - Parameters - ---------- - extended : str or list of str - Extended string list with potentially autosplitted tailing string relative to `existing`. - existing : list of str - Base string list. - - Returns - ------- - repacked : list of str - Repacked version of `extended`. - - Examples - -------- - >>> tail_repack(['a','new','e','n','t','r','y'],['a','new']) - ['a','new','entry'] - >>> tail_repack(['a','new','shiny','e','n','t','r','y'],['a','new']) - ['a','new','shiny','e','n','t','r','y'] - - """ - return [extended] if isinstance(extended,str) else existing + \ - ([''.join(extended[len(existing):])] if _np.prod([len(i) for i in extended[len(existing):]]) == 1 else - list(extended[len(existing):])) - - -def aslist(arg: _Union[_IntCollection, int, None]) -> _List: - """ - Transform argument to list. - - Parameters - ---------- - arg : int or collection of int or None - Entity to transform into list. - - Returns - ------- - transformed : list - Entity transformed into list. - - """ - return [] if arg is None else list(arg) if isinstance(arg,(_np.ndarray,_Collection)) else [arg] - - #################################################################################################### # Classes #################################################################################################### diff --git a/python/setup.cfg b/python/setup.cfg index 321040658..e183e6b3f 100644 --- a/python/setup.cfg +++ b/python/setup.cfg @@ -6,7 +6,7 @@ author_email = damask@mpie.de url = https://damask.mpie.de description = DAMASK processing tools long_description = Pre- and post-processing tools for DAMASK -license: AGPL3 +license = AGPL3 classifiers = Intended Audience :: Science/Research Topic :: Scientific/Engineering @@ -19,12 +19,11 @@ packages = find: include_package_data = true python_requires = >= 3.8 install_requires = - importlib-metadata; python_version<"3.8" - pandas; python_version<="0.24" # requires numpy - numpy; python_version<="1.17" # needed for default_rng - scipy; python_version<="1.2" - h5py; python_version<="2.9" # requires numpy - vtk; python_version<="8.1" - matplotlib; python_version<="3.0" # requires numpy, pillow - pyyaml; python_version<="3.12" + pandas>=0.24 # requires numpy + numpy>=1.17 # needed for default_rng + scipy>=1.2 + h5py>=2.9 # requires numpy + vtk>=8.1 + matplotlib>=3.0 # requires numpy, pillow + pyyaml>=3.12 setup_requires = setuptools diff --git a/python/tests/reference/ConfigMaterial/measured.material.yaml b/python/tests/reference/ConfigMaterial/measured.material.yaml index bc7e73968..508d03039 100644 --- a/python/tests/reference/ConfigMaterial/measured.material.yaml +++ b/python/tests/reference/ConfigMaterial/measured.material.yaml @@ -1,4 +1,4 @@ -phase: {'1': t.b.d., '2': t.b.d.} +phase: {'1': null, '2': null} homogenization: direct: {N_constituents: 1} diff --git a/python/tests/reference/Grid/clean_1.0__False.vti b/python/tests/reference/Grid/clean_1.0_None_False.vti similarity index 100% rename from python/tests/reference/Grid/clean_1.0__False.vti rename to python/tests/reference/Grid/clean_1.0_None_False.vti diff --git a/python/tests/reference/Grid/clean_1.0__True.vti b/python/tests/reference/Grid/clean_1.0_None_True.vti similarity index 100% rename from python/tests/reference/Grid/clean_1.0__True.vti rename to python/tests/reference/Grid/clean_1.0_None_True.vti diff --git a/python/tests/reference/Grid/clean_1.7320508075688772__False.vti b/python/tests/reference/Grid/clean_1.7320508075688772_None_False.vti similarity index 100% rename from python/tests/reference/Grid/clean_1.7320508075688772__False.vti rename to python/tests/reference/Grid/clean_1.7320508075688772_None_False.vti diff --git a/python/tests/reference/Grid/clean_1.7320508075688772__True.vti b/python/tests/reference/Grid/clean_1.7320508075688772_None_True.vti similarity index 100% rename from python/tests/reference/Grid/clean_1.7320508075688772__True.vti rename to python/tests/reference/Grid/clean_1.7320508075688772_None_True.vti diff --git a/python/tests/reference/Grid/scale_grid_10-10-10.vti b/python/tests/reference/Grid/scale_grid_10-10-10.vti index b459414f2..ee07a347f 100644 --- a/python/tests/reference/Grid/scale_grid_10-10-10.vti +++ b/python/tests/reference/Grid/scale_grid_10-10-10.vti @@ -3,7 +3,7 @@ - AQAAAACAAAA+AAAAQQAAAA==eF5LScxNLM7Wc0/Nz9UrTk7MSVUos7TUAyNdSyDQLagsSS0uUdAwMjC01DU01DUwUjA0tDK1sDIw0GQAAFYKEKs= + AQAAAACAAAA+AAAAQQAAAA==eF5LScxNLM7Wcy/KTNErTk7MSVUos7TUAyNdSyDQLagsSS0uUdAwMjC01DU01DUwUjA0tDK1sDIw0GQAAFW2EKk= @@ -11,7 +11,7 @@ - AQAAAACAAABAHwAA+QAAAA==eF7t2DcSAjEQRFF28d57t3i4/wUJaCVdpYCqH46Sl/1oklZR+70iDMMwDP+wlHXZMJuyJdtmR3Yl3evJvhyYQzmSY3Mip5LuzeRcLsylXMm1uZFbSfd2ci8P5lGe5Nms5EXSvau8ybv5kE/5Mt/yI+kefc90j75nukffM92j75nu0fdM9+h7pnv0PdM9+p7pHn3PdI++Z7pXhmEYhmEYhqi5fyzfD74bfD+k3UD3cjvE94PvBt8PaTfQvdwO8f3gu8H3Q9oNdC+3Q3w/+G7w/VBJupfbIb4ffDf4fki7ge7R90z36Hume/Q90z36nukefc907wt6sixX + AQAAAACAAABAHwAACgEAAA==eF7t1zcSAjEQRFEW7723i4f7X5CAVtJVCqB+OEpe9qMJWkXl+4owDMMw/MGqrMm62ZBN2TLbsiPpXlf2ZN8cyKEcmWM5kXRvKmdybi7kUq7MtdxIureVO7k3D/IoT2Ypz5LuXeRV3sy7fMin+ZJvSffoe6Z79D3TPfqe6R59z3SPvme6R98z3aPvme7R90z36Hume/Q9071qGIZhGP5h7p/u+8h3ke+jtIvoXm5n+T7yXeT7KO0iupfbWb6PfBf5Pkq7iO7ldpbvI99Fvo9KSfdyO8v3ke8i30dpF9E9+p7pHn3PdI++Z7pH3zPdo++Z7tH3TPfoe6Z79D3TPfqe6R59z3TvAxSdM5E= diff --git a/python/tests/reference/Grid/scale_grid_10-11-10.vti b/python/tests/reference/Grid/scale_grid_10-11-10.vti index 0d6362eba..b4f346556 100644 --- a/python/tests/reference/Grid/scale_grid_10-11-10.vti +++ b/python/tests/reference/Grid/scale_grid_10-11-10.vti @@ -3,7 +3,7 @@ - AQAAAACAAAA+AAAAQQAAAA==eF5LScxNLM7Wc0/Nz9UrTk7MSVUos7TUAyNdSyDQLagsSS0uUdAwMjC01DU01DUwUjA0tDK1sDIw0GQAAFYKEKs= + AQAAAACAAAA+AAAAQQAAAA==eF5LScxNLM7Wcy/KTNErTk7MSVUos7TUAyNdSyDQLagsSS0uUdAwMjC01DU01DUwUjA0tDK1sDIw0GQAAFW2EKk= @@ -11,7 +11,7 @@ - AQAAAACAAABgIgAA/gAAAA==eF7t2CcOA0EQRFHnnHPO8f4XNHAtKWmQPxhZveSxj6ZBbbn0/cphGIZh+EdWZFXWzLpsyKbZkm1J9zqyK3tmXw7k0BzJsaR7EzmVM3MuF3JpruRa5t7byK3cmXt5kEfzJM+S7l3kVd7Mu3zIp/mSb0n36Puge/R90D36Pefeo++D7tH3Qffo+6B79H3QPfo9596j74Pu0fdB9yphGIZhGIZh+IOp/5S+v3x3+f4qdhfdS+0431++u3x/FbuL7qV2nO8l30m+l4qdlHsvteN8f/nu8v11knQvteN8f/nu8v1V7C66R98H3aPvg+7R7zn3Hn0fdI++D7r3AZqNMMY= + AQAAAACAAABgIgAAEAEAAA==eF7t2DcOAkEQRFG8996zeLj/BQmoTUqa7Acj1Ju87EfTUmmrld9XDcMwDMM/sibrsmE2ZUu2zY7sSrrXk305MIdyJMfmRE4l3ZvJuVyYS7mSa3MjtzL33k7u5cE8ypM8m4W8SLp3lTd5Nx/yKV/mW34k3aPvg+7R90H36Pece4++D7pH3wfdo++D7tH3Qffo95x7j74PukffB92rhWEYhuEfmvpv4nvQd6DvwXIH0r3UrvQ96DvQ92C5A+lealf6fvPd5vut3G2591K70veg70Dfg4Wke6ld6XvQd6DvwXIH0j36PugefR90j37Puffo+6B79H3QPfo+6B59H3SPfs+59+j7oHv0fdC9L3s9OLk= diff --git a/python/tests/reference/Grid/scale_grid_10-13-10.vti b/python/tests/reference/Grid/scale_grid_10-13-10.vti index 786452b7b..1b086b3a0 100644 --- a/python/tests/reference/Grid/scale_grid_10-13-10.vti +++ b/python/tests/reference/Grid/scale_grid_10-13-10.vti @@ -3,7 +3,7 @@ - AQAAAACAAAA+AAAAQQAAAA==eF5LScxNLM7Wc0/Nz9UrTk7MSVUos7TUAyNdSyDQLagsSS0uUdAwMjC01DU01DUwUjA0tDK1sDIw0GQAAFYKEKs= + AQAAAACAAAA+AAAAQQAAAA==eF5LScxNLM7Wcy/KTNErTk7MSVUos7TUAyNdSyDQLagsSS0uUdAwMjC01DU01DUwUjA0tDK1sDIw0GQAAFW2EKk= @@ -11,7 +11,7 @@ - AQAAAACAAACgKAAACQEAAA==eF7t2blWAlEURFEBlcGJQcAZZBD4/x804HRSa72sghtUJzs72Q3qde/m+vVijDHGGLGPA7wV7/Aeh+IIx+juTfABH8UnfMYXcYozrN6b4wJfxSWucC2+4TtW733gJ36J3/iDG3GLv1i9t8M9HsQj/uFJPOMF3T33/bp77nur3nPfW/We+96q99z36+6579fdc99b9Z773qr33PdWvee+X3evH2OMMcYYY4wNW/8ZdP/r7tf93+1+d6/1jqB7XXe67vVup1fvtd4RdK/rTte93u306r3WO4Ludd3pute3WL3XekfQ/a+7X/d/t/vdPff9unvue6vec99b9Z773qr33Pfr7v0DeUA5pA== + AQAAAACAAACgKAAAFwEAAA==eF7t2DduA1EUQ1ErWcHK0co57X+DKsRpCPyOBQtOc7rbEXh/aj/frxZjjDHGCOuwAZtkC/7CNtmBXeje68E/2CcHcAhH5BhOoLo3hTM4JxdwCVfkP1xD994GbuGO3MMDPJIneIbq3gVe4Y28wwd8ki/4hu499d7ce+r9qnvqvbn31PtV99R7c++p9+beU+9X3VPvzb2n3q+6p96be68eY4wxxkiW/ivyfc53Od/n1V3u3iu9G/je5zuf7/3qzlf3Su8Gvs/5Luf7vLrL3XuldwPf+3zn871/gupe6d3A9znf5XyfV3e5e0+9N/eeer/qnnpv7j31ftU99d7ce+q9uffU+1X31Htz76n3q+6p9+be+wA2m0MJ diff --git a/python/tests/reference/Grid/scale_grid_10-20-2.vti b/python/tests/reference/Grid/scale_grid_10-20-2.vti index 8cb531701..23413e8b3 100644 --- a/python/tests/reference/Grid/scale_grid_10-20-2.vti +++ b/python/tests/reference/Grid/scale_grid_10-20-2.vti @@ -3,7 +3,7 @@ - AQAAAACAAAA+AAAAQQAAAA==eF5LScxNLM7Wc0/Nz9UrTk7MSVUos7TUAyNdSyDQLagsSS0uUdAwMjC01DU01DUwUjA0tDK1sDIw0GQAAFYKEKs= + AQAAAACAAAA+AAAAQQAAAA==eF5LScxNLM7Wcy/KTNErTk7MSVUos7TUAyNdSyDQLagsSS0uUdAwMjC01DU01DUwUjA0tDK1sDIw0GQAAFW2EKk= @@ -11,7 +11,7 @@ - AQAAAACAAACADAAAdgAAAA==eF7tzMsWgQAYReEuKJUoRKGLS3n/JzSwJ51ZRq3l35Nvtl3nm2uapmmaP+ihLy5wiSsxwBDn/ltjhLGY4AZTcYs7tN/Yqb8Mc9yLBzxiIZ7wjP/2K7HCi3jFG9Zigy3ab+zUX4d3fIhPfGEvDvjGuf8+MEUQzQ== + AQAAAACAAACADAAAbQAAAA==eF7tzDcCggAQBVGiooCYQcFM8P4ntGCqX9ruTvO6CYO50HVd13X/MMJYTDDFhbjEDK39VrjGXCywxI1Y4Rat/Xa4x4N4xBOexRobtPa74BVbscMb3sUHPtHa74Vv/Ig9DjiKE37R2u8H6ycQzQ== diff --git a/python/tests/reference/Grid/scale_grid_5-4-20.vti b/python/tests/reference/Grid/scale_grid_5-4-20.vti index 55477492a..778152fb1 100644 --- a/python/tests/reference/Grid/scale_grid_5-4-20.vti +++ b/python/tests/reference/Grid/scale_grid_5-4-20.vti @@ -3,7 +3,7 @@ - AQAAAACAAAA+AAAAQQAAAA==eF5LScxNLM7Wc0/Nz9UrTk7MSVUos7TUAyNdSyDQLagsSS0uUdAwMjC01DU01DUwUjA0tDK1sDIw0GQAAFYKEKs= + AQAAAACAAAA+AAAAQQAAAA==eF5LScxNLM7Wcy/KTNErTk7MSVUos7TUAyNdSyDQLagsSS0uUdAwMjC01DU01DUwUjA0tDK1sDIw0GQAAFW2EKk= @@ -11,7 +11,7 @@ - AQAAAACAAACADAAAeAAAAA==eF7t1TkWggAUQ1EREZS5BFQmB9j/Bin++40b8OBJmtumSoKDJZDyBx7xhGeM8YJXzLDAEmts8YYP7HHECZ/4xg+uqH4W9bOon+W7n5Ryf/oPhxih70yCvjMp5ug7U2GDHd7Rd2ZA35kZX+g7s6D6Wf613wZ8oBHR + AQAAAACAAACADAAAeAAAAA==eF7t1bkWglAUQ1GfiICAQMngwKTy/z9occ+t6LVJmt2myUo4WIKUcucRTxhjghlesMASK2ywwwFv+MARJ1xwxTduqH4W9bP8q5+Ucq//SIS+4zOm6DvO0Xd8xRpb7NF3fMcn+o5n9B2/8IPqZ1E/y6/7fQE+LBGB diff --git a/python/tests/reference/Grid/scale_grid_8-10-12.vti b/python/tests/reference/Grid/scale_grid_8-10-12.vti index a2a3523a7..bfd90c466 100644 --- a/python/tests/reference/Grid/scale_grid_8-10-12.vti +++ b/python/tests/reference/Grid/scale_grid_8-10-12.vti @@ -3,7 +3,7 @@ - AQAAAACAAAA+AAAAQQAAAA==eF5LScxNLM7Wc0/Nz9UrTk7MSVUos7TUAyNdSyDQLagsSS0uUdAwMjC01DU01DUwUjA0tDK1sDIw0GQAAFYKEKs= + AQAAAACAAAA+AAAAQQAAAA==eF5LScxNLM7Wcy/KTNErTk7MSVUos7TUAyNdSyDQLagsSS0uUdAwMjC01DU01DUwUjA0tDK1sDIw0GQAAFW2EKk= @@ -11,7 +11,7 @@ - AQAAAACAAAAAHgAAyAAAAA==eF7t2LcBAkEUxFDu8N5776H/BglQBwpvNnmRskn+FrX/K2KMsWKWWMcGNrGFbexgF23fwz4OcIgjHOMEp2j7Gc5xgUtc4Ro3uEXb73CPBzziCc94wSva/oZ3fOATX/jGD37R9nY/trf7sb3dj+3tfmxv92N7ux/b2/3Y3u7H9nY/trf7sb3dj+3tfmxv92N7ux/b2/3YvowxxhhjjJXS/gPa3t4htrd3iO3tHWJ7e4fY3u7H9nY/trf7sb3dj+3tfmz/A1V7KtE= + AQAAAACAAAAAHgAAyQAAAA==eF7t17cRw0AUxFCR8t5776X+G1QgdIAZRnvJi5Bt8K+o/V8RY4wxxsossY4NbGIL29jBLtq+h30c4BBHOMYJTtH2M5zjApe4wjVucIu23+EeD3jEE57xgle0/Q3v+MAnvvCNH/yi7e1+bG/3Y3u7H9vb/dje7sf2dj+2t/uxvd2P7e1+bG/3Y/syxhhjjJVr/8G2t3eg7e0daHt7B9re3oG2t/uxvd2P7e1+bG/3Y3u7H9vb/dje7sf2dj+2t/uxvd2P7X9ILyox diff --git a/python/tests/reference/Result/12grains6x7x8_tensionY.hdf5 b/python/tests/reference/Result/12grains6x7x8_tensionY.hdf5 index 6cfc9b4b4..de5082a0d 100644 Binary files a/python/tests/reference/Result/12grains6x7x8_tensionY.hdf5 and b/python/tests/reference/Result/12grains6x7x8_tensionY.hdf5 differ diff --git a/python/tests/reference/Result/12grains6x7x8_tensionY_restart.hdf5 b/python/tests/reference/Result/12grains6x7x8_tensionY_restart.hdf5 new file mode 100644 index 000000000..d3c5a8004 Binary files /dev/null and b/python/tests/reference/Result/12grains6x7x8_tensionY_restart.hdf5 differ diff --git a/python/tests/reference/Result/12grains6x7x8_tensionY_restart_restart.hdf5 b/python/tests/reference/Result/12grains6x7x8_tensionY_restart_restart.hdf5 new file mode 100644 index 000000000..64430ba9a Binary files /dev/null and b/python/tests/reference/Result/12grains6x7x8_tensionY_restart_restart.hdf5 differ diff --git a/python/tests/reference/Result/4grains2x4x3.material.yaml b/python/tests/reference/Result/4grains2x4x3.material.yaml index aebdc0338..96be5f483 100644 --- a/python/tests/reference/Result/4grains2x4x3.material.yaml +++ b/python/tests/reference/Result/4grains2x4x3.material.yaml @@ -648,7 +648,7 @@ phase: atol_xi: 1.0 dot_gamma_0_sl: 0.001 h_0_sl-sl: 75e6 - h_sl-sl: [1, 1, 1.4, 1.4, 1.4, 1.4] + h_sl-sl: [1, 1, 1.4, 1.4, 1.4, 1.4, 1.4] n_sl: 20 output: [xi_sl] type: phenopowerlaw diff --git a/python/tests/reference/Result/4grains2x4x3_compressionY.hdf5 b/python/tests/reference/Result/4grains2x4x3_compressionY.hdf5 index 369cab8fc..2d1d0ee33 100644 Binary files a/python/tests/reference/Result/4grains2x4x3_compressionY.hdf5 and b/python/tests/reference/Result/4grains2x4x3_compressionY.hdf5 differ diff --git a/python/tests/reference/Result/6grains6x7x8_single_phase_tensionY.hdf5 b/python/tests/reference/Result/6grains6x7x8_single_phase_tensionY.hdf5 index bab0b0ead..cb7838332 100644 Binary files a/python/tests/reference/Result/6grains6x7x8_single_phase_tensionY.hdf5 and b/python/tests/reference/Result/6grains6x7x8_single_phase_tensionY.hdf5 differ diff --git a/python/tests/reference/Result/6grains6x7x8_single_phase_tensionY.xdmf b/python/tests/reference/Result/6grains6x7x8_single_phase_tensionY.xdmf index 87352e5f9..cc92cd571 100644 --- a/python/tests/reference/Result/6grains6x7x8_single_phase_tensionY.xdmf +++ b/python/tests/reference/Result/6grains6x7x8_single_phase_tensionY.xdmf @@ -6,1664 +6,1664 @@ 0.0 2.0 4.0 6.0 8.0 10.0 12.0 14.0 16.0 18.0 20.0 - + 0.0 0.0 0.0 0.125 0.125 0.125 - 6grains6x7x8_single_phase_tensionY.hdf5:/increment_0/geometry/u_n + 6grains6x7x8_single_phase_tensionY.hdf5:/increment_0/geometry/u_n - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/F + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/F - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/F_e + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/F_e - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/F_p + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/F_p - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/L_p + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/L_p - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/O + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/O - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/P + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/P - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/matrix_f4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/matrix_f4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/matrix_f8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/matrix_f8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/matrix_i1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/matrix_i1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/matrix_i2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/matrix_i2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/matrix_i4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/matrix_i4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/matrix_i8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/matrix_i8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/matrix_u1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/matrix_u1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/matrix_u2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/matrix_u2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/matrix_u4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/matrix_u4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/matrix_u8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/matrix_u8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/scalar_f4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/scalar_f4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/scalar_f8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/scalar_f8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/scalar_i1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/scalar_i1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/scalar_i2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/scalar_i2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/scalar_i4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/scalar_i4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/scalar_i8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/scalar_i8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/scalar_u1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/scalar_u1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/scalar_u2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/scalar_u2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/scalar_u4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/scalar_u4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/scalar_u8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/scalar_u8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/tensor_f4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/tensor_f4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/tensor_f8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/tensor_f8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/tensor_i1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/tensor_i1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/tensor_i2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/tensor_i2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/tensor_i4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/tensor_i4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/tensor_i8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/tensor_i8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/tensor_u1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/tensor_u1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/tensor_u2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/tensor_u2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/tensor_u4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/tensor_u4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/tensor_u8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/tensor_u8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/vector_f4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/vector_f4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/vector_f8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/vector_f8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/vector_i1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/vector_i1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/vector_i2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/vector_i2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/vector_i4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/vector_i4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/vector_i8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/vector_i8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/vector_u1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/vector_u1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/vector_u2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/vector_u2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/vector_u4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/vector_u4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/vector_u8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/vector_u8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/xi_sl + 6grains6x7x8_single_phase_tensionY.hdf5:increment_0/phase/pheno_fcc/mechanical/xi_sl - + 0.0 0.0 0.0 0.125 0.125 0.125 - 6grains6x7x8_single_phase_tensionY.hdf5:/increment_4/geometry/u_n + 6grains6x7x8_single_phase_tensionY.hdf5:/increment_4/geometry/u_n - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/F + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/F - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/F_e + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/F_e - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/F_p + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/F_p - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/L_p + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/L_p - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/O + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/O - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/P + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/P - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/matrix_f4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/matrix_f4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/matrix_f8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/matrix_f8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/matrix_i1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/matrix_i1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/matrix_i2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/matrix_i2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/matrix_i4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/matrix_i4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/matrix_i8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/matrix_i8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/matrix_u1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/matrix_u1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/matrix_u2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/matrix_u2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/matrix_u4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/matrix_u4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/matrix_u8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/matrix_u8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/scalar_f4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/scalar_f4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/scalar_f8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/scalar_f8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/scalar_i1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/scalar_i1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/scalar_i2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/scalar_i2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/scalar_i4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/scalar_i4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/scalar_i8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/scalar_i8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/scalar_u1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/scalar_u1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/scalar_u2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/scalar_u2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/scalar_u4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/scalar_u4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/scalar_u8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/scalar_u8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/tensor_f4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/tensor_f4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/tensor_f8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/tensor_f8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/tensor_i1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/tensor_i1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/tensor_i2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/tensor_i2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/tensor_i4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/tensor_i4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/tensor_i8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/tensor_i8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/tensor_u1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/tensor_u1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/tensor_u2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/tensor_u2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/tensor_u4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/tensor_u4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/tensor_u8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/tensor_u8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/vector_f4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/vector_f4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/vector_f8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/vector_f8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/vector_i1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/vector_i1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/vector_i2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/vector_i2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/vector_i4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/vector_i4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/vector_i8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/vector_i8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/vector_u1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/vector_u1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/vector_u2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/vector_u2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/vector_u4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/vector_u4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/vector_u8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/vector_u8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/xi_sl + 6grains6x7x8_single_phase_tensionY.hdf5:increment_4/phase/pheno_fcc/mechanical/xi_sl - + 0.0 0.0 0.0 0.125 0.125 0.125 - 6grains6x7x8_single_phase_tensionY.hdf5:/increment_8/geometry/u_n + 6grains6x7x8_single_phase_tensionY.hdf5:/increment_8/geometry/u_n - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/F + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/F - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/F_e + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/F_e - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/F_p + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/F_p - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/L_p + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/L_p - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/O + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/O - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/P + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/P - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/matrix_f4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/matrix_f4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/matrix_f8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/matrix_f8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/matrix_i1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/matrix_i1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/matrix_i2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/matrix_i2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/matrix_i4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/matrix_i4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/matrix_i8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/matrix_i8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/matrix_u1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/matrix_u1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/matrix_u2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/matrix_u2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/matrix_u4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/matrix_u4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/matrix_u8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/matrix_u8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/scalar_f4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/scalar_f4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/scalar_f8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/scalar_f8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/scalar_i1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/scalar_i1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/scalar_i2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/scalar_i2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/scalar_i4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/scalar_i4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/scalar_i8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/scalar_i8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/scalar_u1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/scalar_u1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/scalar_u2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/scalar_u2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/scalar_u4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/scalar_u4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/scalar_u8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/scalar_u8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/tensor_f4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/tensor_f4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/tensor_f8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/tensor_f8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/tensor_i1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/tensor_i1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/tensor_i2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/tensor_i2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/tensor_i4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/tensor_i4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/tensor_i8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/tensor_i8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/tensor_u1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/tensor_u1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/tensor_u2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/tensor_u2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/tensor_u4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/tensor_u4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/tensor_u8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/tensor_u8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/vector_f4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/vector_f4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/vector_f8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/vector_f8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/vector_i1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/vector_i1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/vector_i2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/vector_i2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/vector_i4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/vector_i4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/vector_i8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/vector_i8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/vector_u1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/vector_u1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/vector_u2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/vector_u2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/vector_u4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/vector_u4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/vector_u8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/vector_u8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/xi_sl + 6grains6x7x8_single_phase_tensionY.hdf5:increment_8/phase/pheno_fcc/mechanical/xi_sl - + 0.0 0.0 0.0 0.125 0.125 0.125 - 6grains6x7x8_single_phase_tensionY.hdf5:/increment_12/geometry/u_n + 6grains6x7x8_single_phase_tensionY.hdf5:/increment_12/geometry/u_n - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/F + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/F - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/F_e + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/F_e - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/F_p + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/F_p - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/L_p + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/L_p - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/O + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/O - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/P + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/P - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/matrix_f4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/matrix_f4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/matrix_f8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/matrix_f8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/matrix_i1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/matrix_i1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/matrix_i2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/matrix_i2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/matrix_i4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/matrix_i4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/matrix_i8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/matrix_i8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/matrix_u1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/matrix_u1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/matrix_u2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/matrix_u2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/matrix_u4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/matrix_u4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/matrix_u8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/matrix_u8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/scalar_f4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/scalar_f4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/scalar_f8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/scalar_f8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/scalar_i1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/scalar_i1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/scalar_i2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/scalar_i2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/scalar_i4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/scalar_i4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/scalar_i8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/scalar_i8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/scalar_u1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/scalar_u1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/scalar_u2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/scalar_u2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/scalar_u4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/scalar_u4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/scalar_u8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/scalar_u8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/tensor_f4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/tensor_f4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/tensor_f8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/tensor_f8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/tensor_i1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/tensor_i1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/tensor_i2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/tensor_i2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/tensor_i4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/tensor_i4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/tensor_i8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/tensor_i8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/tensor_u1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/tensor_u1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/tensor_u2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/tensor_u2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/tensor_u4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/tensor_u4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/tensor_u8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/tensor_u8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/vector_f4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/vector_f4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/vector_f8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/vector_f8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/vector_i1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/vector_i1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/vector_i2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/vector_i2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/vector_i4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/vector_i4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/vector_i8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/vector_i8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/vector_u1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/vector_u1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/vector_u2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/vector_u2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/vector_u4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/vector_u4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/vector_u8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/vector_u8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/xi_sl + 6grains6x7x8_single_phase_tensionY.hdf5:increment_12/phase/pheno_fcc/mechanical/xi_sl - + 0.0 0.0 0.0 0.125 0.125 0.125 - 6grains6x7x8_single_phase_tensionY.hdf5:/increment_16/geometry/u_n + 6grains6x7x8_single_phase_tensionY.hdf5:/increment_16/geometry/u_n - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/F + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/F - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/F_e + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/F_e - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/F_p + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/F_p - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/L_p + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/L_p - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/O + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/O - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/P + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/P - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/matrix_f4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/matrix_f4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/matrix_f8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/matrix_f8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/matrix_i1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/matrix_i1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/matrix_i2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/matrix_i2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/matrix_i4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/matrix_i4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/matrix_i8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/matrix_i8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/matrix_u1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/matrix_u1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/matrix_u2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/matrix_u2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/matrix_u4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/matrix_u4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/matrix_u8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/matrix_u8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/scalar_f4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/scalar_f4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/scalar_f8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/scalar_f8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/scalar_i1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/scalar_i1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/scalar_i2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/scalar_i2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/scalar_i4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/scalar_i4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/scalar_i8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/scalar_i8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/scalar_u1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/scalar_u1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/scalar_u2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/scalar_u2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/scalar_u4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/scalar_u4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/scalar_u8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/scalar_u8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/tensor_f4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/tensor_f4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/tensor_f8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/tensor_f8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/tensor_i1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/tensor_i1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/tensor_i2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/tensor_i2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/tensor_i4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/tensor_i4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/tensor_i8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/tensor_i8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/tensor_u1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/tensor_u1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/tensor_u2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/tensor_u2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/tensor_u4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/tensor_u4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/tensor_u8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/tensor_u8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/vector_f4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/vector_f4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/vector_f8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/vector_f8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/vector_i1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/vector_i1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/vector_i2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/vector_i2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/vector_i4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/vector_i4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/vector_i8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/vector_i8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/vector_u1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/vector_u1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/vector_u2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/vector_u2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/vector_u4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/vector_u4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/vector_u8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/vector_u8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/xi_sl + 6grains6x7x8_single_phase_tensionY.hdf5:increment_16/phase/pheno_fcc/mechanical/xi_sl - + 0.0 0.0 0.0 0.125 0.125 0.125 - 6grains6x7x8_single_phase_tensionY.hdf5:/increment_20/geometry/u_n + 6grains6x7x8_single_phase_tensionY.hdf5:/increment_20/geometry/u_n - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/F + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/F - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/F_e + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/F_e - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/F_p + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/F_p - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/L_p + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/L_p - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/O + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/O - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/P + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/P - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/matrix_f4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/matrix_f4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/matrix_f8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/matrix_f8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/matrix_i1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/matrix_i1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/matrix_i2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/matrix_i2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/matrix_i4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/matrix_i4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/matrix_i8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/matrix_i8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/matrix_u1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/matrix_u1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/matrix_u2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/matrix_u2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/matrix_u4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/matrix_u4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/matrix_u8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/matrix_u8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/scalar_f4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/scalar_f4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/scalar_f8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/scalar_f8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/scalar_i1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/scalar_i1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/scalar_i2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/scalar_i2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/scalar_i4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/scalar_i4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/scalar_i8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/scalar_i8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/scalar_u1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/scalar_u1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/scalar_u2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/scalar_u2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/scalar_u4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/scalar_u4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/scalar_u8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/scalar_u8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/tensor_f4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/tensor_f4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/tensor_f8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/tensor_f8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/tensor_i1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/tensor_i1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/tensor_i2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/tensor_i2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/tensor_i4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/tensor_i4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/tensor_i8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/tensor_i8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/tensor_u1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/tensor_u1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/tensor_u2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/tensor_u2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/tensor_u4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/tensor_u4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/tensor_u8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/tensor_u8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/vector_f4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/vector_f4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/vector_f8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/vector_f8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/vector_i1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/vector_i1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/vector_i2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/vector_i2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/vector_i4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/vector_i4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/vector_i8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/vector_i8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/vector_u1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/vector_u1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/vector_u2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/vector_u2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/vector_u4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/vector_u4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/vector_u8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/vector_u8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/xi_sl + 6grains6x7x8_single_phase_tensionY.hdf5:increment_20/phase/pheno_fcc/mechanical/xi_sl - + 0.0 0.0 0.0 0.125 0.125 0.125 - 6grains6x7x8_single_phase_tensionY.hdf5:/increment_24/geometry/u_n + 6grains6x7x8_single_phase_tensionY.hdf5:/increment_24/geometry/u_n - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/F + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/F - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/F_e + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/F_e - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/F_p + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/F_p - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/L_p + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/L_p - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/O + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/O - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/P + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/P - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/matrix_f4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/matrix_f4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/matrix_f8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/matrix_f8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/matrix_i1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/matrix_i1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/matrix_i2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/matrix_i2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/matrix_i4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/matrix_i4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/matrix_i8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/matrix_i8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/matrix_u1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/matrix_u1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/matrix_u2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/matrix_u2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/matrix_u4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/matrix_u4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/matrix_u8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/matrix_u8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/scalar_f4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/scalar_f4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/scalar_f8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/scalar_f8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/scalar_i1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/scalar_i1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/scalar_i2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/scalar_i2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/scalar_i4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/scalar_i4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/scalar_i8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/scalar_i8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/scalar_u1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/scalar_u1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/scalar_u2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/scalar_u2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/scalar_u4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/scalar_u4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/scalar_u8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/scalar_u8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/tensor_f4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/tensor_f4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/tensor_f8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/tensor_f8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/tensor_i1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/tensor_i1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/tensor_i2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/tensor_i2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/tensor_i4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/tensor_i4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/tensor_i8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/tensor_i8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/tensor_u1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/tensor_u1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/tensor_u2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/tensor_u2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/tensor_u4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/tensor_u4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/tensor_u8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/tensor_u8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/vector_f4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/vector_f4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/vector_f8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/vector_f8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/vector_i1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/vector_i1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/vector_i2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/vector_i2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/vector_i4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/vector_i4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/vector_i8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/vector_i8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/vector_u1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/vector_u1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/vector_u2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/vector_u2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/vector_u4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/vector_u4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/vector_u8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/vector_u8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/xi_sl + 6grains6x7x8_single_phase_tensionY.hdf5:increment_24/phase/pheno_fcc/mechanical/xi_sl - + 0.0 0.0 0.0 0.125 0.125 0.125 - 6grains6x7x8_single_phase_tensionY.hdf5:/increment_28/geometry/u_n + 6grains6x7x8_single_phase_tensionY.hdf5:/increment_28/geometry/u_n - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/F + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/F - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/F_e + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/F_e - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/F_p + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/F_p - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/L_p + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/L_p - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/O + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/O - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/P + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/P - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/matrix_f4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/matrix_f4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/matrix_f8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/matrix_f8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/matrix_i1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/matrix_i1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/matrix_i2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/matrix_i2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/matrix_i4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/matrix_i4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/matrix_i8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/matrix_i8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/matrix_u1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/matrix_u1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/matrix_u2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/matrix_u2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/matrix_u4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/matrix_u4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/matrix_u8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/matrix_u8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/scalar_f4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/scalar_f4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/scalar_f8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/scalar_f8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/scalar_i1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/scalar_i1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/scalar_i2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/scalar_i2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/scalar_i4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/scalar_i4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/scalar_i8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/scalar_i8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/scalar_u1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/scalar_u1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/scalar_u2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/scalar_u2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/scalar_u4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/scalar_u4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/scalar_u8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/scalar_u8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/tensor_f4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/tensor_f4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/tensor_f8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/tensor_f8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/tensor_i1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/tensor_i1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/tensor_i2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/tensor_i2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/tensor_i4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/tensor_i4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/tensor_i8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/tensor_i8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/tensor_u1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/tensor_u1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/tensor_u2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/tensor_u2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/tensor_u4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/tensor_u4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/tensor_u8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/tensor_u8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/vector_f4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/vector_f4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/vector_f8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/vector_f8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/vector_i1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/vector_i1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/vector_i2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/vector_i2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/vector_i4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/vector_i4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/vector_i8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/vector_i8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/vector_u1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/vector_u1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/vector_u2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/vector_u2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/vector_u4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/vector_u4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/vector_u8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/vector_u8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/xi_sl + 6grains6x7x8_single_phase_tensionY.hdf5:increment_28/phase/pheno_fcc/mechanical/xi_sl - + 0.0 0.0 0.0 0.125 0.125 0.125 - 6grains6x7x8_single_phase_tensionY.hdf5:/increment_32/geometry/u_n + 6grains6x7x8_single_phase_tensionY.hdf5:/increment_32/geometry/u_n - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/F + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/F - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/F_e + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/F_e - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/F_p + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/F_p - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/L_p + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/L_p - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/O + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/O - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/P + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/P - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/matrix_f4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/matrix_f4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/matrix_f8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/matrix_f8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/matrix_i1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/matrix_i1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/matrix_i2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/matrix_i2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/matrix_i4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/matrix_i4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/matrix_i8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/matrix_i8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/matrix_u1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/matrix_u1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/matrix_u2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/matrix_u2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/matrix_u4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/matrix_u4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/matrix_u8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/matrix_u8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/scalar_f4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/scalar_f4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/scalar_f8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/scalar_f8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/scalar_i1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/scalar_i1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/scalar_i2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/scalar_i2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/scalar_i4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/scalar_i4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/scalar_i8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/scalar_i8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/scalar_u1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/scalar_u1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/scalar_u2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/scalar_u2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/scalar_u4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/scalar_u4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/scalar_u8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/scalar_u8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/tensor_f4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/tensor_f4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/tensor_f8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/tensor_f8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/tensor_i1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/tensor_i1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/tensor_i2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/tensor_i2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/tensor_i4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/tensor_i4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/tensor_i8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/tensor_i8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/tensor_u1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/tensor_u1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/tensor_u2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/tensor_u2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/tensor_u4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/tensor_u4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/tensor_u8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/tensor_u8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/vector_f4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/vector_f4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/vector_f8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/vector_f8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/vector_i1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/vector_i1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/vector_i2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/vector_i2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/vector_i4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/vector_i4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/vector_i8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/vector_i8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/vector_u1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/vector_u1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/vector_u2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/vector_u2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/vector_u4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/vector_u4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/vector_u8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/vector_u8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/xi_sl + 6grains6x7x8_single_phase_tensionY.hdf5:increment_32/phase/pheno_fcc/mechanical/xi_sl - + 0.0 0.0 0.0 0.125 0.125 0.125 - 6grains6x7x8_single_phase_tensionY.hdf5:/increment_36/geometry/u_n + 6grains6x7x8_single_phase_tensionY.hdf5:/increment_36/geometry/u_n - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/F + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/F - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/F_e + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/F_e - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/F_p + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/F_p - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/L_p + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/L_p - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/O + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/O - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/P + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/P - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/matrix_f4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/matrix_f4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/matrix_f8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/matrix_f8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/matrix_i1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/matrix_i1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/matrix_i2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/matrix_i2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/matrix_i4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/matrix_i4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/matrix_i8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/matrix_i8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/matrix_u1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/matrix_u1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/matrix_u2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/matrix_u2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/matrix_u4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/matrix_u4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/matrix_u8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/matrix_u8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/scalar_f4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/scalar_f4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/scalar_f8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/scalar_f8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/scalar_i1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/scalar_i1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/scalar_i2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/scalar_i2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/scalar_i4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/scalar_i4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/scalar_i8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/scalar_i8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/scalar_u1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/scalar_u1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/scalar_u2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/scalar_u2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/scalar_u4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/scalar_u4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/scalar_u8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/scalar_u8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/tensor_f4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/tensor_f4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/tensor_f8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/tensor_f8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/tensor_i1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/tensor_i1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/tensor_i2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/tensor_i2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/tensor_i4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/tensor_i4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/tensor_i8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/tensor_i8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/tensor_u1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/tensor_u1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/tensor_u2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/tensor_u2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/tensor_u4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/tensor_u4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/tensor_u8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/tensor_u8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/vector_f4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/vector_f4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/vector_f8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/vector_f8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/vector_i1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/vector_i1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/vector_i2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/vector_i2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/vector_i4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/vector_i4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/vector_i8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/vector_i8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/vector_u1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/vector_u1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/vector_u2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/vector_u2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/vector_u4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/vector_u4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/vector_u8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/vector_u8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/xi_sl + 6grains6x7x8_single_phase_tensionY.hdf5:increment_36/phase/pheno_fcc/mechanical/xi_sl - + 0.0 0.0 0.0 0.125 0.125 0.125 - 6grains6x7x8_single_phase_tensionY.hdf5:/increment_40/geometry/u_n + 6grains6x7x8_single_phase_tensionY.hdf5:/increment_40/geometry/u_n - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/F + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/F - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/F_e + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/F_e - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/F_p + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/F_p - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/L_p + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/L_p - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/O + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/O - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/P + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/P - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/matrix_f4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/matrix_f4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/matrix_f8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/matrix_f8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/matrix_i1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/matrix_i1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/matrix_i2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/matrix_i2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/matrix_i4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/matrix_i4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/matrix_i8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/matrix_i8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/matrix_u1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/matrix_u1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/matrix_u2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/matrix_u2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/matrix_u4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/matrix_u4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/matrix_u8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/matrix_u8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/scalar_f4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/scalar_f4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/scalar_f8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/scalar_f8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/scalar_i1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/scalar_i1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/scalar_i2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/scalar_i2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/scalar_i4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/scalar_i4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/scalar_i8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/scalar_i8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/scalar_u1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/scalar_u1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/scalar_u2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/scalar_u2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/scalar_u4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/scalar_u4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/scalar_u8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/scalar_u8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/tensor_f4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/tensor_f4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/tensor_f8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/tensor_f8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/tensor_i1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/tensor_i1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/tensor_i2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/tensor_i2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/tensor_i4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/tensor_i4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/tensor_i8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/tensor_i8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/tensor_u1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/tensor_u1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/tensor_u2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/tensor_u2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/tensor_u4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/tensor_u4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/tensor_u8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/tensor_u8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/vector_f4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/vector_f4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/vector_f8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/vector_f8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/vector_i1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/vector_i1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/vector_i2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/vector_i2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/vector_i4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/vector_i4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/vector_i8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/vector_i8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/vector_u1 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/vector_u1 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/vector_u2 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/vector_u2 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/vector_u4 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/vector_u4 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/vector_u8 + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/vector_u8 - 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/xi_sl + 6grains6x7x8_single_phase_tensionY.hdf5:increment_40/phase/pheno_fcc/mechanical/xi_sl diff --git a/python/tests/reference/Result/export_VTK/test_export_vtk[0-0-0].md5 b/python/tests/reference/Result/export_VTK/test_export_vtk[0-0-0].md5 new file mode 100644 index 000000000..80b468fbb --- /dev/null +++ b/python/tests/reference/Result/export_VTK/test_export_vtk[0-0-0].md5 @@ -0,0 +1 @@ +85ce65348539cc823f103a29e3e237f0 diff --git a/python/tests/reference/Result/export_VTK/test_export_vtk[0-0-1].md5 b/python/tests/reference/Result/export_VTK/test_export_vtk[0-0-1].md5 new file mode 100644 index 000000000..20beaee70 --- /dev/null +++ b/python/tests/reference/Result/export_VTK/test_export_vtk[0-0-1].md5 @@ -0,0 +1 @@ +27972d6a0955e4e6e27a6ac5762abda8 diff --git a/python/tests/reference/Result/export_VTK/test_export_vtk[0-0-2].md5 b/python/tests/reference/Result/export_VTK/test_export_vtk[0-0-2].md5 new file mode 100644 index 000000000..baedd0b60 --- /dev/null +++ b/python/tests/reference/Result/export_VTK/test_export_vtk[0-0-2].md5 @@ -0,0 +1 @@ +3971cf9ac0a9598d3171c049ebb213f3 diff --git a/python/tests/reference/Result/export_VTK/test_export_vtk[0-0-3].md5 b/python/tests/reference/Result/export_VTK/test_export_vtk[0-0-3].md5 new file mode 100644 index 000000000..65ee728f7 --- /dev/null +++ b/python/tests/reference/Result/export_VTK/test_export_vtk[0-0-3].md5 @@ -0,0 +1 @@ +e7d52ecf304e56e6ef81702b5a5845f3 diff --git a/python/tests/reference/Result/export_VTK/test_vtk[1-0-0].md5 b/python/tests/reference/Result/export_VTK/test_export_vtk[1-0-0].md5 similarity index 100% rename from python/tests/reference/Result/export_VTK/test_vtk[1-0-0].md5 rename to python/tests/reference/Result/export_VTK/test_export_vtk[1-0-0].md5 diff --git a/python/tests/reference/Result/export_VTK/test_export_vtk[1-0-1].md5 b/python/tests/reference/Result/export_VTK/test_export_vtk[1-0-1].md5 new file mode 100644 index 000000000..9f551820c --- /dev/null +++ b/python/tests/reference/Result/export_VTK/test_export_vtk[1-0-1].md5 @@ -0,0 +1 @@ +dd71d25ccb52c3fdfd2ab727fc852a98 diff --git a/python/tests/reference/Result/export_VTK/test_export_vtk[1-0-2].md5 b/python/tests/reference/Result/export_VTK/test_export_vtk[1-0-2].md5 new file mode 100644 index 000000000..4d7ea4021 --- /dev/null +++ b/python/tests/reference/Result/export_VTK/test_export_vtk[1-0-2].md5 @@ -0,0 +1 @@ +17dfe701be0c3a5e1a29d7a2b49c3afe diff --git a/python/tests/reference/Result/export_VTK/test_export_vtk[1-0-3].md5 b/python/tests/reference/Result/export_VTK/test_export_vtk[1-0-3].md5 new file mode 100644 index 000000000..73ca96212 --- /dev/null +++ b/python/tests/reference/Result/export_VTK/test_export_vtk[1-0-3].md5 @@ -0,0 +1 @@ +ff8883bb1d5c3de706e7c69bc67a366d diff --git a/python/tests/reference/Result/export_VTK/test_vtk[0-0-0].md5 b/python/tests/reference/Result/export_VTK/test_vtk[0-0-0].md5 deleted file mode 100644 index dc8144b94..000000000 --- a/python/tests/reference/Result/export_VTK/test_vtk[0-0-0].md5 +++ /dev/null @@ -1 +0,0 @@ -a40baead936c79dd4f86f84ad858b9fa diff --git a/python/tests/reference/Result/export_VTK/test_vtk[0-0-1].md5 b/python/tests/reference/Result/export_VTK/test_vtk[0-0-1].md5 deleted file mode 100644 index b5782429c..000000000 --- a/python/tests/reference/Result/export_VTK/test_vtk[0-0-1].md5 +++ /dev/null @@ -1 +0,0 @@ -6fb37bd65934de859dd6b6e0191e7d64 diff --git a/python/tests/reference/Result/export_VTK/test_vtk[0-0-2].md5 b/python/tests/reference/Result/export_VTK/test_vtk[0-0-2].md5 deleted file mode 100644 index 92d3956b6..000000000 --- a/python/tests/reference/Result/export_VTK/test_vtk[0-0-2].md5 +++ /dev/null @@ -1 +0,0 @@ -61953c35f61f3234b98d78a912e7dc83 diff --git a/python/tests/reference/Result/export_VTK/test_vtk[0-0-3].md5 b/python/tests/reference/Result/export_VTK/test_vtk[0-0-3].md5 deleted file mode 100644 index 42ccd0e25..000000000 --- a/python/tests/reference/Result/export_VTK/test_vtk[0-0-3].md5 +++ /dev/null @@ -1 +0,0 @@ -bb783bb80ff04dd435e814f4b82a3234 diff --git a/python/tests/reference/Result/export_VTK/test_vtk[1-0-1].md5 b/python/tests/reference/Result/export_VTK/test_vtk[1-0-1].md5 deleted file mode 100644 index c53be5801..000000000 --- a/python/tests/reference/Result/export_VTK/test_vtk[1-0-1].md5 +++ /dev/null @@ -1 +0,0 @@ -e1ca5306082fc3ab411f5ddab1a2e370 diff --git a/python/tests/reference/Result/export_VTK/test_vtk[1-0-2].md5 b/python/tests/reference/Result/export_VTK/test_vtk[1-0-2].md5 deleted file mode 100644 index 90f0ebc9c..000000000 --- a/python/tests/reference/Result/export_VTK/test_vtk[1-0-2].md5 +++ /dev/null @@ -1 +0,0 @@ -1641c3b3641e942ffc325d471bdfaf00 diff --git a/python/tests/reference/Result/export_VTK/test_vtk[1-0-3].md5 b/python/tests/reference/Result/export_VTK/test_vtk[1-0-3].md5 deleted file mode 100644 index cfe43f9cb..000000000 --- a/python/tests/reference/Result/export_VTK/test_vtk[1-0-3].md5 +++ /dev/null @@ -1 +0,0 @@ -ba97286c5d95bf817143f7bb9cf58421 diff --git a/python/tests/reference/Result/get/test_get[0].pbz2 b/python/tests/reference/Result/get/test_get[0].pbz2 index e4ef0bde9..9a598fd44 100644 Binary files a/python/tests/reference/Result/get/test_get[0].pbz2 and b/python/tests/reference/Result/get/test_get[0].pbz2 differ diff --git a/python/tests/reference/Result/get/test_get[2].pbz2 b/python/tests/reference/Result/get/test_get[2].pbz2 index c8398ab2f..e85ab0a06 100644 Binary files a/python/tests/reference/Result/get/test_get[2].pbz2 and b/python/tests/reference/Result/get/test_get[2].pbz2 differ diff --git a/python/tests/reference/Result/get/test_get[3].pbz2 b/python/tests/reference/Result/get/test_get[3].pbz2 index d2eb08545..b28255817 100644 Binary files a/python/tests/reference/Result/get/test_get[3].pbz2 and b/python/tests/reference/Result/get/test_get[3].pbz2 differ diff --git a/python/tests/reference/Result/get/test_get[4].pbz2 b/python/tests/reference/Result/get/test_get[4].pbz2 index c10fa916b..d293c5c52 100644 Binary files a/python/tests/reference/Result/get/test_get[4].pbz2 and b/python/tests/reference/Result/get/test_get[4].pbz2 differ diff --git a/python/tests/reference/Result/get/test_get[6].pbz2 b/python/tests/reference/Result/get/test_get[6].pbz2 index 4459d2e59..9f1706371 100644 Binary files a/python/tests/reference/Result/get/test_get[6].pbz2 and b/python/tests/reference/Result/get/test_get[6].pbz2 differ diff --git a/python/tests/reference/Result/get/test_get[7].pbz2 b/python/tests/reference/Result/get/test_get[7].pbz2 index c1e4c31e9..67fb5ff13 100644 Binary files a/python/tests/reference/Result/get/test_get[7].pbz2 and b/python/tests/reference/Result/get/test_get[7].pbz2 differ diff --git a/python/tests/reference/Result/place/test_place[0].pbz2 b/python/tests/reference/Result/place/test_place[0].pbz2 index 2d1d432b9..fdfef5961 100644 Binary files a/python/tests/reference/Result/place/test_place[0].pbz2 and b/python/tests/reference/Result/place/test_place[0].pbz2 differ diff --git a/python/tests/reference/Result/place/test_place[2].pbz2 b/python/tests/reference/Result/place/test_place[2].pbz2 index cfc94f1ee..19caac392 100644 Binary files a/python/tests/reference/Result/place/test_place[2].pbz2 and b/python/tests/reference/Result/place/test_place[2].pbz2 differ diff --git a/python/tests/reference/Result/place/test_place[3].pbz2 b/python/tests/reference/Result/place/test_place[3].pbz2 index 96f782ae2..1ef2bfec3 100644 Binary files a/python/tests/reference/Result/place/test_place[3].pbz2 and b/python/tests/reference/Result/place/test_place[3].pbz2 differ diff --git a/python/tests/reference/Result/place/test_place[4].pbz2 b/python/tests/reference/Result/place/test_place[4].pbz2 index f2f744121..beae7e608 100644 Binary files a/python/tests/reference/Result/place/test_place[4].pbz2 and b/python/tests/reference/Result/place/test_place[4].pbz2 differ diff --git a/python/tests/reference/Result/place/test_place[6].pbz2 b/python/tests/reference/Result/place/test_place[6].pbz2 index 2844addcb..0246231f4 100644 Binary files a/python/tests/reference/Result/place/test_place[6].pbz2 and b/python/tests/reference/Result/place/test_place[6].pbz2 differ diff --git a/python/tests/reference/Result/place/test_place[7].pbz2 b/python/tests/reference/Result/place/test_place[7].pbz2 index cd4f098a1..808f4c514 100644 Binary files a/python/tests/reference/Result/place/test_place[7].pbz2 and b/python/tests/reference/Result/place/test_place[7].pbz2 differ diff --git a/python/tests/reference/Result/tensionY_restart.yaml b/python/tests/reference/Result/tensionY_restart.yaml new file mode 100644 index 000000000..89cfcc325 --- /dev/null +++ b/python/tests/reference/Result/tensionY_restart.yaml @@ -0,0 +1,18 @@ +--- +solver: + mechanical: spectral_basic + +loadstep: + - boundary_conditions: + mechanical: + dot_F: [[x, 0, 0], + [0, 1.0e-3, 0], + [0, 0, x]] + P: [[0, x, x], + [x, x, x], + [x, x, 0]] + discretization: + t: 10 + N: 20 + f_out: 4 + f_restart: 20 diff --git a/python/tests/test_Config.py b/python/tests/test_Config.py index e6fa2daff..0fce31106 100644 --- a/python/tests/test_Config.py +++ b/python/tests/test_Config.py @@ -46,7 +46,8 @@ class TestConfig: assert Config.load(tmp_path/'config.yaml') == config def test_numpy(self,tmp_path): - assert Config({'A':np.ones(3,'i')}).__repr__() == Config({'A':[1,1,1]}).__repr__() + assert Config({'A':np.ones(3,'i'), 'B':np.ones(1)[0]}).__repr__() == \ + Config({'A':[1,1,1], 'B':1.0}).__repr__() def test_abstract_is_valid(self): with pytest.raises(NotImplementedError): diff --git a/python/tests/test_ConfigMaterial.py b/python/tests/test_ConfigMaterial.py index f003e254e..a9cf9089d 100644 --- a/python/tests/test_ConfigMaterial.py +++ b/python/tests/test_ConfigMaterial.py @@ -65,17 +65,6 @@ class TestConfigMaterial: del material_config['material'][0]['homogenization'] assert not material_config.is_complete - def test_incomplete_homogenization_N_constituents(self,ref_path): - material_config = ConfigMaterial.load(ref_path/'material.yaml') - for h in material_config['homogenization'].keys(): - del material_config['homogenization'][h]['N_constituents'] - assert not material_config.is_complete - - def test_incomplete_phase_lattice(self,ref_path): - material_config = ConfigMaterial.load(ref_path/'material.yaml') - del material_config['phase']['Aluminum']['lattice'] - assert not material_config.is_complete - def test_incomplete_wrong_phase(self,ref_path): material_config = ConfigMaterial.load(ref_path/'material.yaml') new = material_config.material_rename_phase({'Steel':'FeNbC'}) @@ -86,6 +75,16 @@ class TestConfigMaterial: new = material_config.material_rename_homogenization({'Taylor':'isostrain'}) assert not new.is_complete + def test_empty_phase(self,ref_path): + material_config = ConfigMaterial.load(ref_path/'material.yaml') + material_config['phase'] = None + assert not material_config.is_complete + + def test_empty_homogenization(self,ref_path): + material_config = ConfigMaterial.load(ref_path/'material.yaml') + material_config['homogenization'] = None + assert not material_config.is_complete + def test_from_table(self): N = np.random.randint(3,10) a = np.vstack((np.hstack((np.arange(N),np.arange(N)[::-1])), @@ -98,6 +97,15 @@ class TestConfigMaterial: for i,m in enumerate(c['material']): assert m['homogenization'] == 1 and (m['constituents'][0]['O'] == [1,0,1,1]).all() + def test_updated_dicts(self,ref_path): + m1 = ConfigMaterial().material_add(phase=['Aluminum'],O=[1.0,0.0,0.0,0.0],homogenization='SX') + m2 = ConfigMaterial.load(ref_path/'material.yaml') + for k in m2['phase']: + m2 = m2.material_add(phase=[k],O=[1.0,0.0,0.0,0.0],homogenization='SX') + assert not m2['phase'].get(k) is None + assert m1['phase'].get('Aluminum') is None + assert m1['homogenization'].get('SX') is None + def test_from_table_with_constant(self): N = np.random.randint(3,10) a = np.vstack((np.hstack((np.arange(N),np.arange(N)[::-1])), diff --git a/python/tests/test_Grid.py b/python/tests/test_Grid.py index fc1af09b6..43207b1e4 100644 --- a/python/tests/test_Grid.py +++ b/python/tests/test_Grid.py @@ -17,11 +17,13 @@ from damask import grid_filters @pytest.fixture def default(): """Simple geometry.""" - x=np.concatenate((np.ones(40,dtype=int), - np.arange(2,42), - np.ones(40,dtype=int)*2, - np.arange(1,41))).reshape(8,5,4,order='F') - return Grid(x,[8e-6,5e-6,4e-6]) + g = np.array([8,5,4]) + l = np.prod(g[:2]) + return Grid(np.concatenate((np.ones (l,dtype=int), + np.arange(l,dtype=int)+2, + np.ones (l,dtype=int)*2, + np.arange(l,dtype=int)+1)).reshape(g,order='F'), + g*1e-6) @pytest.fixture def random(): @@ -166,15 +168,15 @@ class TestGrid: @pytest.mark.parametrize('periodic',[True,False]) def test_clean_reference(self,default,update,ref_path,distance,selection,periodic): current = default.clean(distance,selection,periodic=periodic,rng_seed=0) - reference = ref_path/f'clean_{distance}_{"+".join(map(str,util.aslist(selection)))}_{periodic}.vti' + reference = ref_path/f'clean_{distance}_{util.srepr(selection,"+")}_{periodic}.vti' if update: current.save(reference) assert Grid.load(reference) == current - @pytest.mark.parametrize('selection',[list(np.random.randint(1,20,6)),set(np.random.randint(1,20,6)),np.random.randint(1,20,6)]) + @pytest.mark.parametrize('selection',[list(np.random.randint(1,20,6)),np.random.randint(1,20,6)]) @pytest.mark.parametrize('invert',[True,False]) def test_clean_invert(self,default,selection,invert): - selection_inverse = set(default.material.flatten()) - set(selection) + selection_inverse = np.setdiff1d(default.material,selection) assert default.clean(selection=selection,invert_selection=invert,rng_seed=0) == \ default.clean(selection=selection_inverse,invert_selection=not invert,rng_seed=0) @@ -212,6 +214,14 @@ class TestGrid: assert default == modified.renumber() + def test_assemble(self): + cells = np.random.randint(8,16,3) + N = cells.prod() + g = Grid(np.arange(N).reshape(cells),np.ones(3)) + idx = np.random.randint(0,N,N).reshape(cells) + assert (idx == g.assemble(idx).material).all + + def test_substitute(self,default): offset = np.random.randint(1,500) modified = Grid(default.material + offset, @@ -343,10 +353,10 @@ class TestGrid: assert np.all(m2==grid.material) - @pytest.mark.parametrize('selection',[list(np.random.randint(1,20,6)),set(np.random.randint(1,20,6)),np.random.randint(1,20,6)]) + @pytest.mark.parametrize('selection',[list(np.random.randint(1,20,6)),np.random.randint(1,20,6)]) @pytest.mark.parametrize('invert',[True,False]) def test_vicinity_offset_invert(self,random,selection,invert): - selection_inverse = set(random.material.flatten()) - set(selection) + selection_inverse = np.setdiff1d(random.material,selection) assert random.vicinity_offset(selection=selection ,invert_selection=not invert) == \ random.vicinity_offset(selection=selection_inverse,invert_selection= invert) diff --git a/python/tests/test_Orientation.py b/python/tests/test_Orientation.py index 2cb97d252..67fbeb51d 100644 --- a/python/tests/test_Orientation.py +++ b/python/tests/test_Orientation.py @@ -121,7 +121,7 @@ class TestOrientation: == np.eye(3)) def test_from_axis_angle(self): - assert np.all(Orientation.from_axis_angle(axis_angle=[1,0,0,0],family='triclinic').as_matrix() + assert np.all(Orientation.from_axis_angle(n_omega=[1,0,0,0],family='triclinic').as_matrix() == np.eye(3)) def test_from_basis(self): @@ -210,7 +210,7 @@ class TestOrientation: @pytest.mark.parametrize('family',crystal_families) @pytest.mark.parametrize('angle',[10,20,30,40]) def test_average(self,angle,family): - o = Orientation.from_axis_angle(family=family,axis_angle=[[0,0,1,10],[0,0,1,angle]],degrees=True) + o = Orientation.from_axis_angle(family=family,n_omega=[[0,0,1,10],[0,0,1,angle]],degrees=True) avg_angle = o.average().as_axis_angle(degrees=True,pair=True)[1] assert np.isclose(avg_angle,10+(angle-10)/2.) diff --git a/python/tests/test_Result.py b/python/tests/test_Result.py index 7e107494a..f0de16937 100644 --- a/python/tests/test_Result.py +++ b/python/tests/test_Result.py @@ -5,10 +5,13 @@ import shutil import os import sys import hashlib +import fnmatch +import random from datetime import datetime import pytest import vtk +import h5py import numpy as np from damask import Result @@ -97,6 +100,16 @@ class TestResult: assert n0.get('F') is n1.get('F') is None and \ len(n0.visible[label]) == len(n1.visible[label]) == 0 + def test_view_invalid_incstimes(self,default): + with pytest.raises(ValueError): + default.view(increments=0,times=0) + + @pytest.mark.parametrize('inc',[0,10]) + @pytest.mark.parametrize('sign',[+1,-1]) + def test_view_approxtimes(self,default,inc,sign): + eps = sign*1e-3 + assert [default.increments[inc]] == default.view(times=default.times[inc]+eps).visible['increments'] + def test_add_invalid(self,default): default.add_absolute('xxxx') @@ -291,7 +304,7 @@ class TestResult: default.add_curl('x') in_file = default.place('curl(x)') in_memory = grid_filters.curl(default.size,x.reshape(tuple(default.cells)+x.shape[1:])).reshape(in_file.shape) - assert (in_file==in_memory).all() + assert (in_file == in_memory).all() @pytest.mark.parametrize('shape',['vector','tensor']) def test_add_divergence(self,default,shape): @@ -301,7 +314,7 @@ class TestResult: default.add_divergence('x') in_file = default.place('divergence(x)') in_memory = grid_filters.divergence(default.size,x.reshape(tuple(default.cells)+x.shape[1:])).reshape(in_file.shape) - assert (in_file==in_memory).all() + assert (in_file == in_memory).all() @pytest.mark.parametrize('shape',['scalar','pseudo_scalar','vector']) def test_add_gradient(self,default,shape): @@ -312,7 +325,7 @@ class TestResult: default.add_gradient('x') in_file = default.place('gradient(x)') in_memory = grid_filters.gradient(default.size,x.reshape(tuple(default.cells)+x.shape[1:])).reshape(in_file.shape) - assert (in_file==in_memory).all() + assert (in_file == in_memory).all() @pytest.mark.parametrize('overwrite',['off','on']) def test_add_overwrite(self,default,overwrite): @@ -323,12 +336,9 @@ class TestResult: created_first = last.place('sigma').dtype.metadata['created'] created_first = datetime.strptime(created_first,'%Y-%m-%d %H:%M:%S%z') - if overwrite == 'on': - last = last.view(protected=False) - else: - last = last.view(protected=True) + last = last.view(protected=overwrite != 'on') - time.sleep(2.) + time.sleep(2) try: last.add_calculation('#sigma#*0.0+311.','sigma','not the Cauchy stress') except ValueError: @@ -338,7 +348,7 @@ class TestResult: created_second = datetime.strptime(created_second,'%Y-%m-%d %H:%M:%S%z') if overwrite == 'on': - assert created_first < created_second and np.allclose(last.place('sigma'),311.) + assert created_first < created_second and np.allclose(last.place('sigma'),311.) else: assert created_first == created_second and not np.allclose(last.place('sigma'),311.) @@ -378,15 +388,14 @@ class TestResult: @pytest.mark.parametrize('fname',['12grains6x7x8_tensionY.hdf5'],ids=range(1)) @pytest.mark.parametrize('inc',[4,0],ids=range(2)) @pytest.mark.xfail(int(vtk.vtkVersion.GetVTKVersion().split('.')[0])<9, reason='missing "Direction" attribute') - def test_vtk(self,request,tmp_path,ref_path,update,patch_execution_stamp,patch_datetime_now,output,fname,inc): + def test_export_vtk(self,request,tmp_path,ref_path,update,patch_execution_stamp,patch_datetime_now,output,fname,inc): result = Result(ref_path/fname).view(increments=inc) - os.chdir(tmp_path) - result.export_VTK(output,parallel=False) + result.export_VTK(output,target_dir=tmp_path,parallel=False) fname = fname.split('.')[0]+f'_inc{(inc if type(inc) == int else inc[0]):0>2}.vti' v = VTK.load(tmp_path/fname) - v.comments = 'n/a' + v.comments = ['n/a'] v.save(tmp_path/fname,parallel=False) - with open(fname) as f: + with open(tmp_path/fname) as f: cur = hashlib.md5(f.read().encode()).hexdigest() if update: with open((ref_path/'export_VTK'/request.node.name).with_suffix('.md5'),'w') as f: @@ -396,7 +405,7 @@ class TestResult: @pytest.mark.parametrize('mode',['point','cell']) @pytest.mark.parametrize('output',[False,True]) - def test_vtk_marc(self,tmp_path,ref_path,mode,output): + def test_export_vtk_marc(self,tmp_path,ref_path,mode,output): os.chdir(tmp_path) result = Result(ref_path/'check_compile_job1.hdf5') result.export_VTK(output,mode) @@ -416,34 +425,34 @@ class TestResult: with pytest.raises(ValueError): single_phase.export_VTK(mode='invalid') + def test_vtk_custom_path(self,tmp_path,single_phase): + export_dir = tmp_path/'export_dir' + single_phase.export_VTK(mode='point',target_dir=export_dir,parallel=False) + assert set(os.listdir(export_dir)) == set([f'{single_phase.fname.stem}_inc{i:02}.vtp' for i in range(0,40+1,4)]) def test_XDMF_datatypes(self,tmp_path,single_phase,update,ref_path): - for shape in [('scalar',()),('vector',(3,)),('tensor',(3,3)),('matrix',(12,))]: + for what,shape in {'scalar':(),'vector':(3,),'tensor':(3,3),'matrix':(12,)}.items(): for dtype in ['f4','f8','i1','i2','i4','i8','u1','u2','u4','u8']: - single_phase.add_calculation(f"np.ones(np.shape(#F#)[0:1]+{shape[1]},'{dtype}')",f'{shape[0]}_{dtype}') - fname = os.path.splitext(os.path.basename(single_phase.fname))[0]+'.xdmf' - os.chdir(tmp_path) - single_phase.export_XDMF() + single_phase.add_calculation(f"np.ones(np.shape(#F#)[0:1]+{shape},'{dtype}')",f'{what}_{dtype}') + xdmf_path = tmp_path/single_phase.fname.with_suffix('.xdmf').name + single_phase.export_XDMF(target_dir=tmp_path) if update: - shutil.copy(tmp_path/fname,ref_path/fname) - - assert sorted(open(tmp_path/fname).read()) == sorted(open(ref_path/fname).read()) # XML is not ordered + shutil.copy(xdmf_path,ref_path/xdmf_path.name) + assert sorted(open(xdmf_path).read()) == sorted(open(ref_path/xdmf_path.name).read()) @pytest.mark.skipif(not (hasattr(vtk,'vtkXdmfReader') and hasattr(vtk.vtkXdmfReader(),'GetOutput')), reason='https://discourse.vtk.org/t/2450') def test_XDMF_shape(self,tmp_path,single_phase): - os.chdir(tmp_path) - - single_phase.export_XDMF() - fname = os.path.splitext(os.path.basename(single_phase.fname))[0]+'.xdmf' + single_phase.export_XDMF(target_dir=single_phase.fname.parent) + fname = single_phase.fname.with_suffix('.xdmf') reader_xdmf = vtk.vtkXdmfReader() reader_xdmf.SetFileName(fname) reader_xdmf.Update() dim_xdmf = reader_xdmf.GetOutput().GetDimensions() bounds_xdmf = reader_xdmf.GetOutput().GetBounds() - single_phase.view(increments=0).export_VTK(parallel=False) - fname = os.path.splitext(os.path.basename(single_phase.fname))[0]+'_inc00.vti' + single_phase.view(increments=0).export_VTK(target_dir=single_phase.fname.parent,parallel=False) + fname = single_phase.fname.with_name(single_phase.fname.stem+'_inc00.vti') reader_vti = vtk.vtkXMLImageDataReader() reader_vti.SetFileName(fname) reader_vti.Update() @@ -455,6 +464,40 @@ class TestResult: with pytest.raises(TypeError): default.export_XDMF() + def test_XDMF_custom_path(self,single_phase,tmp_path): + os.chdir(tmp_path) + single_phase.export_XDMF() + assert single_phase.fname.with_suffix('.xdmf').name in os.listdir(tmp_path) + export_dir = tmp_path/'export_dir' + single_phase.export_XDMF(target_dir=export_dir) + assert single_phase.fname.with_suffix('.xdmf').name in os.listdir(export_dir) + + @pytest.mark.skipif(not (hasattr(vtk,'vtkXdmfReader') and hasattr(vtk.vtkXdmfReader(),'GetOutput')), + reason='https://discourse.vtk.org/t/2450') + def test_XDMF_relabs_path(self,single_phase,tmp_path): + def dims(xdmf): + reader_xdmf = vtk.vtkXdmfReader() + reader_xdmf.SetFileName(xdmf) + reader_xdmf.Update() + return reader_xdmf.GetOutput().GetDimensions() + + single_phase.export_XDMF(target_dir=tmp_path) + xdmfname = single_phase.fname.with_suffix('.xdmf').name + ref_dims = dims(tmp_path/xdmfname) + + for (d,info) in { + 'A': dict(absolute_path=True, + mv='..', + ), + 'B': dict(absolute_path=False, + mv='../A', + ), + }.items(): + sub = tmp_path/d; sub.mkdir(exist_ok=True) + single_phase.export_XDMF(target_dir=sub,absolute_path=info['absolute_path']) + os.replace(sub/xdmfname,sub/info['mv']/xdmfname) + assert ref_dims == dims(sub/info['mv']/xdmfname) + @pytest.mark.parametrize('view,output,flatten,prune', [({},['F','P','F','L_p','F_e','F_p'],True,True), ({'increments':3},'F',True,True), @@ -505,13 +548,69 @@ class TestResult: ref = pickle.load(f) assert cur is None if ref is None else dict_equal(cur,ref) + def test_simulation_setup_files(self,default): + assert set(default.simulation_setup_files) == set(['12grains6x7x8.vti', + 'material.yaml', + 'tensionY.yaml', + 'previous/12grains6x7x8.vti', + 'previous/material.yaml', + 'previous/tensionY.yaml']) + + def test_export_simulation_setup_files(self,tmp_path,default): + sub = 'deep/down' + default.export_simulation_setup(target_dir=tmp_path/sub,overwrite=True) + for f in default.simulation_setup_files: + assert (tmp_path/sub/f).exists() + + def test_export_simulation_setup_overwrite(self,tmp_path,default): + os.chdir(tmp_path) + default.export_simulation_setup('material.yaml',overwrite=True) + with pytest.raises(PermissionError): + default.export_simulation_setup('material.yaml',overwrite=False) + + @pytest.mark.parametrize('output',['12grains6x7x8.vti', + 'tensionY.yaml', + ]) + def test_export_simulation_setup_content(self,ref_path,tmp_path,default,output): + default.export_simulation_setup(output,target_dir=tmp_path,overwrite=True) + assert open(tmp_path/output).read() == open(ref_path/output).read() @pytest.mark.parametrize('fname',['4grains2x4x3_compressionY.hdf5', '6grains6x7x8_single_phase_tensionY.hdf5']) @pytest.mark.parametrize('output',['material.yaml','*']) - @pytest.mark.parametrize('overwrite',[True,False]) - def test_export_setup(self,ref_path,tmp_path,fname,output,overwrite): - os.chdir(tmp_path) + def test_export_simulation_setup_consistency(self,ref_path,tmp_path,fname,output): r = Result(ref_path/fname) - r.export_setup(output,overwrite) - r.export_setup(output,overwrite) + r.export_simulation_setup(output,target_dir=tmp_path) + with h5py.File(ref_path/fname,'r') as f_hdf5: + for file in fnmatch.filter(f_hdf5['setup'].keys(),output): + with open(tmp_path/file) as f: + assert f_hdf5[f'setup/{file}'][()][0].decode() == f.read() + + def test_export_simulation_setup_custom_path(self,ref_path,tmp_path): + subdir = 'export_dir' + absdir = tmp_path/subdir + absdir.mkdir(exist_ok=True) + + r = Result(ref_path/'4grains2x4x3_compressionY.hdf5') + for t,cwd in zip([absdir,subdir,None],[tmp_path,tmp_path,absdir]): + os.chdir(cwd) + r.export_simulation_setup('material.yaml',target_dir=t) + assert 'material.yaml' in os.listdir(absdir); (absdir/'material.yaml').unlink() + + @pytest.mark.parametrize('fname',['4grains2x4x3_compressionY.hdf5', + '6grains6x7x8_single_phase_tensionY.hdf5']) + def test_export_DADF5(self,ref_path,tmp_path,fname): + r = Result(ref_path/fname) + r = r.view(phases = random.sample(r.phases,1)) + r = r.view(increments = random.sample(r.increments,np.random.randint(2,len(r.increments)))) + r.export_DADF5(tmp_path/fname) + r_exp = Result(tmp_path/fname) + assert str(r.get()) == str(r_exp.get()) + assert str(r.place()) == str(r_exp.place()) + + @pytest.mark.parametrize('fname',['4grains2x4x3_compressionY.hdf5', + '6grains6x7x8_single_phase_tensionY.hdf5']) + def test_export_DADF5_name_clash(self,ref_path,tmp_path,fname): + r = Result(ref_path/fname) + with pytest.raises(PermissionError): + r.export_DADF5(r.fname) diff --git a/python/tests/test_Rotation.py b/python/tests/test_Rotation.py index 8b1bd0de8..056af2a93 100644 --- a/python/tests/test_Rotation.py +++ b/python/tests/test_Rotation.py @@ -6,7 +6,7 @@ from damask import Rotation from damask import Table from damask import _rotation from damask import grid_filters -from damask import util +from damask import tensor n = 1000 atol=1.e-4 @@ -20,6 +20,16 @@ def ref_path(ref_path_base): def set_of_rotations(set_of_quaternions): return [Rotation.from_quaternion(s) for s in set_of_quaternions] +@pytest.fixture +def multidim_rotations(set_of_quaternions): + L = len(set_of_quaternions) + i = 0 + while L%(f:=np.random.randint(2,np.sqrt(L).astype(int))) > 0 and i= 0.).all and (v < np.pi+1.e-9).all() - @pytest.mark.parametrize('P',[1,-1]) - def test_homochoric(self,set_of_rotations,P): - cutoff = np.tan(np.pi*.5*(1.-1e-4)) - for rot in set_of_rotations: - m = rot.as_Rodrigues_vector() - o = Rotation.from_homochoric(rot.as_homochoric()*P*-1,P).as_Rodrigues_vector() - ok = np.allclose(np.clip(m,None,cutoff),np.clip(o,None,cutoff),atol=atol) - ok |= np.isclose(m[3],0.0,atol=atol) - assert ok and np.isclose(np.linalg.norm(o[:3]),1.0), f'{m},{o},{rot.as_quaternion()}' + r = m.as_matrix() + assert np.allclose(1.,np.linalg.det(r)) + + e = m.as_Euler_angles(degrees=False) + assert (e >= 0.).all and (e < np.pi*np.array([2.,1.,2.])+1.e-9).all() + + c = m.as_cubochoric() + assert (np.linalg.norm(c,ord=np.inf,axis=-1) < np.pi**(2./3.)*0.5+1.e-9).all() + + h = m.as_homochoric() + assert (np.linalg.norm(h,axis=-1) < (3.*np.pi/4.)**(1./3.) + 1.e-9).all() - @pytest.mark.parametrize('P',[1,-1]) - def test_cubochoric(self,set_of_rotations,P): - for rot in set_of_rotations: - m = rot.as_homochoric() - o = Rotation.from_cubochoric(rot.as_cubochoric()*P*-1,P).as_homochoric() - ok = np.allclose(m,o,atol=atol) - assert ok and np.linalg.norm(o) < (3.*np.pi/4.)**(1./3.) + 1.e-9, f'{m},{o},{rot.as_quaternion()}' - @pytest.mark.parametrize('P',[1,-1]) @pytest.mark.parametrize('accept_homomorph',[True,False]) - def test_quaternion(self,set_of_rotations,P,accept_homomorph): - c = np.array([1,P*-1,P*-1,P*-1]) * (-1 if accept_homomorph else 1) - for rot in set_of_rotations: - m = rot.as_cubochoric() - o = Rotation.from_quaternion(rot.as_quaternion()*c,accept_homomorph,P).as_cubochoric() - ok = np.allclose(m,o,atol=atol) - if np.count_nonzero(np.isclose(np.abs(o),np.pi**(2./3.)*.5)): - ok |= np.allclose(m*-1.,o,atol=atol) - assert ok and o.max() < np.pi**(2./3.)*0.5+1.e-9, f'{m},{o},{rot.as_quaternion()}' + @pytest.mark.parametrize('normalize',[True,False]) + @pytest.mark.parametrize('P',[1,-1]) + def test_quaternion(self,multidim_rotations,accept_homomorph,normalize,P): + c = np.array([1,-P,-P,-P]) * (-1 if accept_homomorph else 1) * (0.9 if normalize else 1.0) + m = multidim_rotations + o = Rotation.from_quaternion(m.as_quaternion()*c, + accept_homomorph=accept_homomorph, + normalize=normalize, + P=P) + f = Rotation(np.where(np.isclose(m.as_quaternion()[...,0],0.0,atol=atol)[...,np.newaxis],~o,o)) + assert np.logical_or(m.isclose(o,atol=atol), + m.isclose(f,atol=atol) + ).all() + + + @pytest.mark.parametrize('degrees',[True,False]) + def test_Eulers(self,multidim_rotations,degrees): + m = multidim_rotations + o = Rotation.from_Euler_angles(m.as_Euler_angles(degrees), + degrees=degrees) + f = Rotation(np.where(np.isclose(m.as_quaternion()[...,0],0.0,atol=atol)[...,np.newaxis],~o,o)) + assert np.logical_or(m.isclose(o,atol=atol), + m.isclose(f,atol=atol) + ).all() + + + @pytest.mark.parametrize('degrees',[True,False]) + @pytest.mark.parametrize('normalize',[True,False]) + @pytest.mark.parametrize('P',[1,-1]) + def test_axis_angle(self,multidim_rotations,degrees,normalize,P): + c = np.array([-P,-P,-P,1.]) + c[:3] *= 0.9 if normalize else 1.0 + + m = multidim_rotations + o = Rotation.from_axis_angle(m.as_axis_angle(degrees)*c, + degrees=degrees, + normalize=normalize, + P=P) + f = Rotation(np.where(np.isclose(m.as_quaternion()[...,0],0.0,atol=atol)[...,np.newaxis],~o,o)) + assert np.logical_or(m.isclose(o,atol=atol), + m.isclose(f,atol=atol) + ).all() + + + @pytest.mark.parametrize('normalize',[True,False]) + def test_matrix(self,multidim_rotations,normalize): + m = multidim_rotations + o = Rotation.from_matrix(m.as_matrix()*(0.9 if normalize else 1.0), + normalize=normalize) + f = Rotation(np.where(np.isclose(m.as_quaternion()[...,0],0.0,atol=atol)[...,np.newaxis],~o,o)) + assert np.logical_or(m.isclose(o,atol=atol), + m.isclose(f,atol=atol) + ).all() + + + def test_parallel(self,multidim_rotations): + m = multidim_rotations + a = np.broadcast_to(np.array([[1.0,0.0,0.0], + [0.0,1.0,0.0]]),m.shape+(2,3)) + assert m.allclose(Rotation.from_parallel(a,m.broadcast_to(m.shape+(2,))@a)) + + + @pytest.mark.parametrize('normalize',[True,False]) + @pytest.mark.parametrize('P',[1,-1]) + def test_Rodrigues(self,multidim_rotations,normalize,P): + c = np.array([-P,-P,-P,1.]) + c[:3] *= 0.9 if normalize else 1.0 + m = multidim_rotations + o = Rotation.from_Rodrigues_vector(m.as_Rodrigues_vector()*c, + normalize=normalize, + P=P) + f = Rotation(np.where(np.isclose(m.as_quaternion()[...,0],0.0,atol=atol)[...,np.newaxis],~o,o)) + assert np.logical_or(m.isclose(o,atol=atol), + m.isclose(f,atol=atol) + ).all() + + + def test_Rodrigues_compact(self,multidim_rotations): + m = multidim_rotations + c = m.as_Rodrigues_vector(compact=True) + r = m.as_Rodrigues_vector(compact=False) + assert np.allclose(r[...,:3]*r[...,3:], c, equal_nan=True) + + + @pytest.mark.parametrize('P',[1,-1]) + def test_homochoric(self,multidim_rotations,P): + m = multidim_rotations + o = Rotation.from_homochoric(m.as_homochoric()*-P, + P=P) + f = Rotation(np.where(np.isclose(m.as_quaternion()[...,0],0.0,atol=atol)[...,np.newaxis],~o,o)) + assert np.logical_or(m.isclose(o,atol=atol), + m.isclose(f,atol=atol) + ).all() + + + @pytest.mark.parametrize('P',[1,-1]) + def test_cubochoric(self,multidim_rotations,P): + m = multidim_rotations + o = Rotation.from_cubochoric(m.as_cubochoric()*-P, + P=P) + f = Rotation(np.where(np.isclose(m.as_quaternion()[...,0],0.0,atol=atol)[...,np.newaxis],~o,o)) + assert np.logical_or(m.isclose(o,atol=atol), + m.isclose(f,atol=atol) + ).all() + @pytest.mark.parametrize('reciprocal',[True,False]) - def test_basis(self,set_of_rotations,reciprocal): - for rot in set_of_rotations: - om = rot.as_matrix() + 0.1*np.eye(3) - rot = Rotation.from_basis(om,False,reciprocal=reciprocal) - assert np.isclose(np.linalg.det(rot.as_matrix()),1.0) + def test_basis(self,multidim_rotations,reciprocal): + m = multidim_rotations + r = m.as_matrix() + r = np.linalg.inv(tensor.transpose(r)/np.pi) if reciprocal else r + o = Rotation.from_basis(r, + reciprocal=reciprocal) + f = Rotation(np.where(np.isclose(m.as_quaternion()[...,0],0.0,atol=atol)[...,np.newaxis],~o,o)) + assert np.logical_or(m.isclose(o,atol=atol), + m.isclose(f,atol=atol) + ).all() + @pytest.mark.parametrize('shape',[None,1,(4,4)]) def test_random(self,shape): r = Rotation.from_random(shape) - if shape is None: - assert r.shape == () - elif shape == 1: - assert r.shape == (1,) - else: - assert r.shape == shape + assert r.shape == () if shape is None else (1,) if shape == 1 else shape @pytest.mark.parametrize('shape',[None,5,(4,6)]) def test_equal(self,shape): @@ -806,7 +873,7 @@ class TestRotation: def test_equal_ambiguous(self): qu = np.random.rand(10,4) qu[:,0] = 0. - qu/=np.linalg.norm(qu,axis=1,keepdims=True) + qu /= np.linalg.norm(qu,axis=1,keepdims=True) assert (Rotation(qu) == Rotation(-qu)).all() def test_inversion(self): @@ -889,6 +956,15 @@ class TestRotation: with pytest.raises(ValueError): fr(eval(f'R.{to}()'),P=-30) + + def test_invalid_multiplication(self): + rot = Rotation.from_random() + with pytest.raises(TypeError): + rot@Rotation.from_random() + with pytest.raises(TypeError): + rot@[1,2,3,4] + + @pytest.mark.parametrize('shape',[None,(3,),(4,2)]) def test_broadcast(self,shape): rot = Rotation.from_random(shape) @@ -899,9 +975,10 @@ class TestRotation: assert np.allclose(rot_broadcast.quaternion[...,i,:], rot.quaternion) - @pytest.mark.parametrize('function,invalid',[(Rotation.from_quaternion, np.array([-1,0,0,0])), + @pytest.mark.parametrize('function,invalid',[(Rotation.from_quaternion, np.array([-1,0,0,0])), (Rotation.from_quaternion, np.array([1,1,1,0])), (Rotation.from_Euler_angles, np.array([1,4,0])), + (Rotation.from_Euler_angles, np.array([-1,0,0])), (Rotation.from_axis_angle, np.array([1,0,0,4])), (Rotation.from_axis_angle, np.array([1,1,0,1])), (Rotation.from_matrix, np.random.rand(3,3)), @@ -909,7 +986,8 @@ class TestRotation: (Rotation.from_Rodrigues_vector, np.array([1,0,0,-1])), (Rotation.from_Rodrigues_vector, np.array([1,1,0,1])), (Rotation.from_homochoric, np.array([2,2,2])), - (Rotation.from_cubochoric, np.array([1.1,0,0])) ]) + (Rotation.from_cubochoric, np.array([1.1,0,0])), + ]) def test_invalid_value(self,function,invalid): with pytest.raises(ValueError): function(invalid) @@ -920,13 +998,13 @@ class TestRotation: p = np.random.rand(n,3) o = Rotation._get_pyramid_order(p,direction) for i,o_i in enumerate(o): - assert np.all(o_i==Rotation._get_pyramid_order(p[i],direction)) + assert (o_i==Rotation._get_pyramid_order(p[i],direction)).all() def test_pyramid_invariant(self): a = np.random.rand(n,3) f = Rotation._get_pyramid_order(a,'forward') b = Rotation._get_pyramid_order(a,'backward') - assert np.all(np.take_along_axis(np.take_along_axis(a,f,-1),b,-1) == a) + assert (np.take_along_axis(np.take_along_axis(a,f,-1),b,-1) == a).all() @pytest.mark.parametrize('data',[np.random.rand(5,3), @@ -1074,19 +1152,22 @@ class TestRotation: @pytest.mark.parametrize('sigma',[5,10,15,20]) @pytest.mark.parametrize('shape',[1000,10000,100000,(10,100)]) def test_from_fiber_component(self,sigma,shape): + + def astuple(a): + return tuple(a) if hasattr(a,'__len__') else (a,) + p = [] - for run in range(5): + for run in range(9): alpha = np.arccos(np.random.random()),np.random.random()*2*np.pi beta = np.arccos(np.random.random()),np.random.random()*2*np.pi f_in_C = np.array([np.sin(alpha[0])*np.cos(alpha[1]), np.sin(alpha[0])*np.sin(alpha[1]), np.cos(alpha[0])]) f_in_S = np.array([np.sin( beta[0])*np.cos( beta[1]), np.sin( beta[0])*np.sin( beta[1]), np.cos( beta[0])]) ax = np.append(np.cross(f_in_C,f_in_S), - np.arccos(np.dot(f_in_C,f_in_S))) - n = Rotation.from_axis_angle(ax if ax[3] > 0.0 else ax*-1.0 ,normalize=True) # rotation to align fiber axis in crystal and sample system - + n = Rotation.from_axis_angle(ax if ax[3] > 0.0 else -ax,normalize=True) # rotation to align fiber axis in crystal and sample system o = Rotation.from_fiber_component(alpha,beta,np.radians(sigma),shape,False) - angles = np.arccos(np.clip(np.dot(o@np.broadcast_to(f_in_S,tuple(util.aslist(shape))+(3,)),n@f_in_S),-1,1)) - dist = np.array(angles) * (np.random.randint(0,2,util.aslist(shape))*2-1) + angles = np.arccos(np.clip(np.dot(o@np.broadcast_to(f_in_S,astuple(shape)+(3,)),n@f_in_S),-1,1)) + dist = np.array(angles) * (np.random.randint(0,2,shape)*2-1) p.append(stats.normaltest(dist)[1]) diff --git a/python/tests/test_VTK.py b/python/tests/test_VTK.py index 58855c831..2efa148b2 100644 --- a/python/tests/test_VTK.py +++ b/python/tests/test_VTK.py @@ -217,7 +217,7 @@ class TestVTK: def test_comments(self,tmp_path,default): - default.comments += 'this is a comment' + default.comments += ['this is a comment'] default.save(tmp_path/'with_comments',parallel=False) new = VTK.load(tmp_path/'with_comments.vti') assert new.comments == ['this is a comment'] diff --git a/python/tests/test_grid_filters.py b/python/tests/test_grid_filters.py index 6b01ff44d..bbf30e2e1 100644 --- a/python/tests/test_grid_filters.py +++ b/python/tests/test_grid_filters.py @@ -144,16 +144,15 @@ class TestGridFilters: def test_regrid_identity(self): size = np.random.random(3) # noqa cells = np.random.randint(8,32,(3)) - F = np.broadcast_to(np.eye(3), tuple(cells)+(3,3)) - assert all(grid_filters.regrid(size,F,cells) == np.arange(cells.prod())) + F = np.broadcast_to(np.eye(3), (*cells,3,3)) + assert (grid_filters.regrid(size,F,cells).flatten() == np.arange(cells.prod())).all def test_regrid_double_cells(self): size = np.random.random(3) # noqa cells = np.random.randint(8,32,(3)) g = Grid.from_Voronoi_tessellation(cells,size,seeds.from_random(size,10)) - F = np.broadcast_to(np.eye(3), tuple(cells)+(3,3)) - assert all(g.scale(cells*2).material.flatten() == - g.material.flatten()[grid_filters.regrid(size,F,cells*2)]) + F = np.broadcast_to(np.eye(3), (*cells,3,3)) + assert g.scale(cells*2) == g.assemble(grid_filters.regrid(size,F,cells*2)) @pytest.mark.parametrize('differential_operator',[grid_filters.curl, grid_filters.divergence, @@ -319,7 +318,6 @@ class TestGridFilters: ] @pytest.mark.parametrize('field_def,div_def',div_test_data) - def test_div(self,field_def,div_def): size = np.random.random(3)+1.0 cells = np.random.randint(8,32,(3)) @@ -336,3 +334,31 @@ class TestGridFilters: div=div.reshape(tuple(cells)) assert np.allclose(div,grid_filters.divergence(size,field)) + + + def test_ravel_index(self): + cells = np.random.randint(8,32,(3)) + + indices = np.block(np.meshgrid(np.arange(cells[0]), + np.arange(cells[1]), + np.arange(cells[2]),indexing='ij')).reshape(tuple(cells)+(3,),order='F') + x,y,z = map(np.random.randint,cells) + assert grid_filters.ravel_index(indices)[x,y,z] == np.arange(0,np.product(cells)).reshape(cells,order='F')[x,y,z] + + def test_unravel_index(self): + cells = np.random.randint(8,32,(3)) + indices = np.arange(np.prod(cells)).reshape(cells,order='F') + x,y,z = map(np.random.randint,cells) + assert np.all(grid_filters.unravel_index(indices)[x,y,z] == [x,y,z]) + + def test_ravel_unravel_index(self): + cells = np.random.randint(8,32,(3)) + indices = np.random.randint(0,np.prod(cells),cells).reshape(cells) + assert np.all(indices==grid_filters.ravel_index(grid_filters.unravel_index(indices))) + + def test_unravel_ravel_index(self): + cells = np.hstack([np.random.randint(8,32,(3)),1]) + indices = np.block([np.random.randint(0,cells[0],cells), + np.random.randint(0,cells[1],cells), + np.random.randint(0,cells[2],cells)]) + assert np.all(indices==grid_filters.unravel_index(grid_filters.ravel_index(indices))) diff --git a/python/tests/test_util.py b/python/tests/test_util.py index 80786249a..4e6c31820 100644 --- a/python/tests/test_util.py +++ b/python/tests/test_util.py @@ -8,7 +8,6 @@ import h5py from damask import util - class TestUtil: @pytest.mark.xfail(sys.platform == 'win32', reason='echo is not a Windows command') @@ -26,6 +25,17 @@ class TestUtil: with pytest.raises(RuntimeError): util.run('false') + @pytest.mark.parametrize('input,glue,quote,output', + [ + (None,'',False,'None'), + ([None,None],'\n',False,'None\nNone'), + ([-0.5,0.5],'=',False,'-0.5=0.5'), + ([1,2,3],'_',False,'1_2_3'), + ([1,2,3],'/',True,'"1"/"2"/"3"'), + ]) + def test_srepr(self,input,glue,quote,output): + assert output == util.srepr(input,glue,quote) + @pytest.mark.parametrize('input,output', [ ([0,-2],[0,-1]), @@ -33,7 +43,6 @@ class TestUtil: ([1./2.,1./3.],[3,2]), ([2./3.,1./2.,1./3.],[4,3,2]), ]) - def test_scale2coprime(self,input,output): assert np.allclose(util.scale_to_coprime(np.array(input)), np.array(output).astype(int)) @@ -44,7 +53,7 @@ class TestUtil: @pytest.mark.parametrize('rv',[stats.rayleigh(),stats.weibull_min(1.2),stats.halfnorm(),stats.pareto(2.62)]) - def test_hybridIA(self,rv): + def test_hybridIA_distribution(self,rv): bins = np.linspace(0,10,100000) centers = (bins[1:]+bins[:-1])/2 N_samples = bins.shape[0]-1000 @@ -53,6 +62,21 @@ class TestUtil: dist_sampled = np.histogram(centers[selected],bins)[0]/N_samples*np.sum(dist) assert np.sqrt(((dist - dist_sampled) ** 2).mean()) < .025 and selected.shape[0]==N_samples + def test_hybridIA_constant(self): + N_bins = np.random.randint(20,400) + m = np.random.randint(1,20) + N_samples = m * N_bins + dist = np.ones(N_bins)*np.random.rand() + assert np.all(np.sort(util.hybrid_IA(dist,N_samples))==np.arange(N_samples).astype(int)//m) + + def test_hybridIA_linear(self): + N_points = np.random.randint(10,200) + m = np.random.randint(1,20) + dist = np.arange(N_points) + N_samples = m * np.sum(dist) + assert np.all(np.bincount(util.hybrid_IA(dist*np.random.rand(),N_samples)) == dist*m) + + @pytest.mark.parametrize('point,direction,normalize,keepdims,answer', [ ([1,0,0],'z',False,True, [1,0,0]), @@ -120,10 +144,6 @@ class TestUtil: def test_decorate(self,style): assert 'DAMASK' in style('DAMASK') - @pytest.mark.parametrize('lst',[1,[1,2],set([1,2,3]),np.arange(4)]) - def test_aslist(self,lst): - assert len(util.aslist(lst)) > 0 - @pytest.mark.parametrize('complete',[True,False]) def test_D3D_base_group(self,tmp_path,complete): base_group = ''.join(random.choices('DAMASK', k=10)) @@ -208,3 +228,116 @@ class TestUtil: @pytest.mark.parametrize('kw_Miller,kw_Bravais',[('uvw','uvtw'),('hkl','hkil')]) def test_Bravais_Miller_Bravais(self,vector,kw_Miller,kw_Bravais): assert np.all(vector == util.Miller_to_Bravais(**{kw_Miller:util.Bravais_to_Miller(**{kw_Bravais:vector})})) + + + @pytest.mark.parametrize('extra_parameters',[""" + p2 : str, optional + p2 description 1 + p2 description 2 + """, + """ + + p2 : str, optional + p2 description 1 + p2 description 2 + + """, + """ +p2 : str, optional + p2 description 1 + p2 description 2 + """]) + @pytest.mark.parametrize('invalid_docstring',[""" + Function description + + Parameters ---------- + p0 : numpy.ndarray, shape (...,4) + p0 description 1 + p0 description 2 + p1 : int, optional + p1 description + + Remaining description + """, + """ + Function description + + Parameters + ---------- + p0 : numpy.ndarray, shape (...,4) + p0 description 1 + p0 description 2 + p1 : int, optional + p1 description + + Remaining description + """,]) + def test_extend_docstring_parameters(self,extra_parameters,invalid_docstring): + test_docstring = """ + Function description + + Parameters + ---------- + p0 : numpy.ndarray, shape (...,4) + p0 description 1 + p0 description 2 + p1 : int, optional + p1 description + + Remaining description + """ + expected = """ + Function description + + Parameters + ---------- + p0 : numpy.ndarray, shape (...,4) + p0 description 1 + p0 description 2 + p1 : int, optional + p1 description + p2 : str, optional + p2 description 1 + p2 description 2 + + Remaining description + """.split("\n") + assert expected == util._docstringer(test_docstring,extra_parameters).split('\n') + with pytest.raises(RuntimeError): + util._docstringer(invalid_docstring,extra_parameters) + + def test_replace_docstring_return_type(self): + class TestClassOriginal: + pass + + def original_func() -> TestClassOriginal: + pass + + class TestClassDecorated: + def decorated_func_bound(self) -> 'TestClassDecorated': + pass + + def decorated_func() -> TestClassDecorated: + pass + + original_func.__doc__ = """ + Function description/Parameters + + Returns + ------- + Return value : test_util.TestClassOriginal + + Remaining description + """ + + expected = """ + Function description/Parameters + + Returns + ------- + Return value : test_util.TestClassDecorated + + Remaining description + """ + assert expected == util._docstringer(original_func,return_type=decorated_func) + assert expected == util._docstringer(original_func,return_type=TestClassDecorated.decorated_func_bound) diff --git a/src/CLI.f90 b/src/CLI.f90 index ee1555cb2..ad458c34b 100644 --- a/src/CLI.f90 +++ b/src/CLI.f90 @@ -5,9 +5,8 @@ !> @author Philip Eisenlohr, Max-Planck-Institut für Eisenforschung GmbH !> @brief Parse command line interface for PETSc-based solvers !-------------------------------------------------------------------------------------------------- -#define PETSC_MAJOR 3 #define PETSC_MINOR_MIN 12 -#define PETSC_MINOR_MAX 17 +#define PETSC_MINOR_MAX 18 module CLI use, intrinsic :: ISO_fortran_env @@ -134,7 +133,7 @@ subroutine CLI_init print'(a)',' and "debug.yaml" in that directory.' print'(/,a)',' --restart N' print'(a)', ' Reads in increment N and continues with calculating' - print'(a)', ' increment N+1 based on this.' + print'(a)', ' increment N+1, N+2, ... based on this.' print'(a)', ' Appends to existing results file' print'(a)', ' "NameOfGeom_NameOfLoadFile.hdf5".' print'(a)', ' Works only if the restart information for increment N' @@ -209,7 +208,7 @@ subroutine setWorkingDirectory(workingDirectoryArg) workingDirectory = trim(rectifyPath(workingDirectory)) error = setCWD(trim(workingDirectory)) - if(error) then + if (error) then print*, 'ERROR: Invalid Working directory: '//trim(workingDirectory) call quit(1) end if @@ -324,7 +323,7 @@ function rectifyPath(path) end if i = j+index(rectifyPath(j+1:l),'../') end do - if(len_trim(rectifyPath) == 0) rectifyPath = '/' + if (len_trim(rectifyPath) == 0) rectifyPath = '/' rectifyPath = trim(rectifyPath) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a473069b9..c1466ebdd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,7 +1,8 @@ # special flags for some files if(CMAKE_Fortran_COMPILER_ID STREQUAL "GNU") # long lines for interaction matrix - SET_SOURCE_FILES_PROPERTIES("lattice.f90" PROPERTIES COMPILE_FLAGS "-ffree-line-length-240") + set_source_files_properties("lattice.f90" PROPERTIES COMPILE_FLAGS "-ffree-line-length-240") + set_source_files_properties("parallelization.f90" PROPERTIES COMPILE_FLAGS "-ffree-line-length-none") endif() file(GLOB damask-sources CONFIGURE_DEPENDS *.f90 *.c) @@ -14,6 +15,15 @@ elseif(PROJECT_NAME STREQUAL "damask-mesh") file(GLOB solver-sources CONFIGURE_DEPENDS mesh/*.f90) endif() +foreach(solver-source ${solver-sources}) + file(READ ${solver-source} content) + string(FIND "${content}" "CHKERR" found) + if((NOT ${found} EQUAL -1) AND (CMAKE_Fortran_COMPILER_ID STREQUAL "GNU")) + set_source_files_properties(${solver-source} PROPERTIES COMPILE_FLAGS "-ffree-line-length-none") + endif() +endforeach() + + if(NOT CMAKE_BUILD_TYPE STREQUAL "SYNTAXONLY") add_executable(${executable-name} ${damask-sources} ${solver-sources}) install(TARGETS ${executable-name} RUNTIME DESTINATION bin) diff --git a/src/HDF5_utilities.f90 b/src/HDF5_utilities.f90 index ee1e3cf8c..a87046c5a 100644 --- a/src/HDF5_utilities.f90 +++ b/src/HDF5_utilities.f90 @@ -183,7 +183,7 @@ integer(HID_T) function HDF5_openFile(fileName,mode,parallel) end if call H5Pcreate_f(H5P_FILE_ACCESS_F, plist_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' #ifdef PETSC if (present(parallel)) then @@ -197,24 +197,24 @@ integer(HID_T) function HDF5_openFile(fileName,mode,parallel) call H5Pset_fapl_mpio_f(plist_id, PETSC_COMM_WORLD, MPI_INFO_NULL, hdferr) #endif end if - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' #endif if (m == 'w') then call H5Fcreate_f(fileName,H5F_ACC_TRUNC_F,HDF5_openFile,hdferr,access_prp = plist_id) - if(hdferr < 0) error stop 'HDF5 error' - elseif(m == 'a') then + if (hdferr < 0) error stop 'HDF5 error' + elseif (m == 'a') then call H5Fopen_f(fileName,H5F_ACC_RDWR_F,HDF5_openFile,hdferr,access_prp = plist_id) - if(hdferr < 0) error stop 'HDF5 error' - elseif(m == 'r') then + if (hdferr < 0) error stop 'HDF5 error' + elseif (m == 'r') then call H5Fopen_f(fileName,H5F_ACC_RDONLY_F,HDF5_openFile,hdferr,access_prp = plist_id) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' else error stop 'unknown access mode' end if call H5Pclose_f(plist_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' end function HDF5_openFile @@ -229,7 +229,7 @@ subroutine HDF5_closeFile(fileHandle) integer :: hdferr call H5Fclose_f(fileHandle,hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' end subroutine HDF5_closeFile @@ -248,19 +248,19 @@ integer(HID_T) function HDF5_addGroup(fileHandle,groupName) !------------------------------------------------------------------------------------------------- ! creating a property list for data access properties call H5Pcreate_f(H5P_GROUP_ACCESS_F, aplist_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' !------------------------------------------------------------------------------------------------- ! setting I/O mode to collective #ifdef PETSC call H5Pset_all_coll_metadata_ops_f(aplist_id, .true., hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' #endif !------------------------------------------------------------------------------------------------- ! Create group call H5Gcreate_f(fileHandle, trim(groupName), HDF5_addGroup, hdferr, OBJECT_NAMELEN_DEFAULT_F,gapl_id = aplist_id) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Pclose_f(aplist_id,hdferr) @@ -284,19 +284,19 @@ integer(HID_T) function HDF5_openGroup(fileHandle,groupName) !------------------------------------------------------------------------------------------------- ! creating a property list for data access properties call H5Pcreate_f(H5P_GROUP_ACCESS_F, aplist_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' !------------------------------------------------------------------------------------------------- ! setting I/O mode to collective #ifdef PETSC call H5Pget_all_coll_metadata_ops_f(aplist_id, is_collective, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' #endif !------------------------------------------------------------------------------------------------- ! opening the group call H5Gopen_f(fileHandle, trim(groupName), HDF5_openGroup, hdferr, gapl_id = aplist_id) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Pclose_f(aplist_id,hdferr) @@ -313,7 +313,7 @@ subroutine HDF5_closeGroup(group_id) integer :: hdferr call H5Gclose_f(group_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' end subroutine HDF5_closeGroup @@ -337,11 +337,11 @@ logical function HDF5_objectExists(loc_id,path) end if call H5Lexists_f(loc_id, p, HDF5_objectExists, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' - if(HDF5_objectExists) then + if (HDF5_objectExists) then call H5Oexists_by_name_f(loc_id, p, HDF5_objectExists, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' end if end function HDF5_objectExists @@ -374,24 +374,24 @@ subroutine HDF5_addAttribute_str(loc_id,attrLabel,attrValue,path) ptr(1) = c_loc(attrValue_(1)) call H5Screate_f(H5S_SCALAR_F,space_id,hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Aexists_by_name_f(loc_id,trim(p),attrLabel,attrExists,hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' if (attrExists) then call H5Adelete_by_name_f(loc_id, trim(p), attrLabel, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' end if call H5Acreate_by_name_f(loc_id,trim(p),trim(attrLabel),H5T_STRING,space_id,attr_id,hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Awrite_f(attr_id, H5T_STRING, c_loc(ptr), hdferr) ! ptr instead of c_loc(ptr) works on gfortran, not on ifort - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Aclose_f(attr_id,hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Sclose_f(space_id,hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' end subroutine HDF5_addAttribute_str @@ -419,24 +419,24 @@ subroutine HDF5_addAttribute_int(loc_id,attrLabel,attrValue,path) end if call H5Screate_f(H5S_SCALAR_F,space_id,hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Aexists_by_name_f(loc_id,trim(p),attrLabel,attrExists,hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' if (attrExists) then call H5Adelete_by_name_f(loc_id, trim(p), attrLabel, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' end if call H5Acreate_by_name_f(loc_id,trim(p),trim(attrLabel),H5T_NATIVE_INTEGER,space_id,attr_id,hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Awrite_f(attr_id, H5T_NATIVE_INTEGER, attrValue, int([1],HSIZE_T), hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Aclose_f(attr_id,hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Sclose_f(space_id,hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' end subroutine HDF5_addAttribute_int @@ -464,24 +464,24 @@ subroutine HDF5_addAttribute_real(loc_id,attrLabel,attrValue,path) end if call H5Screate_f(H5S_SCALAR_F,space_id,hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Aexists_by_name_f(loc_id,trim(p),attrLabel,attrExists,hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' if (attrExists) then call H5Adelete_by_name_f(loc_id, trim(p), attrLabel, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' end if call H5Acreate_by_name_f(loc_id,trim(p),trim(attrLabel),H5T_NATIVE_DOUBLE,space_id,attr_id,hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Awrite_f(attr_id, H5T_NATIVE_DOUBLE, attrValue, int([1],HSIZE_T), hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Aclose_f(attr_id,hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Sclose_f(space_id,hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' end subroutine HDF5_addAttribute_real @@ -516,24 +516,24 @@ subroutine HDF5_addAttribute_str_array(loc_id,attrLabel,attrValue,path) end do call H5Screate_simple_f(1,shape(attrValue_,kind=HSIZE_T),space_id,hdferr,shape(attrValue_,kind=HSIZE_T)) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Aexists_by_name_f(loc_id,trim(p),attrLabel,attrExists,hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' if (attrExists) then call H5Adelete_by_name_f(loc_id, trim(p), attrLabel, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' end if call H5Acreate_by_name_f(loc_id,trim(p),trim(attrLabel),H5T_STRING,space_id,attr_id,hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Awrite_f(attr_id, H5T_STRING, c_loc(ptr), hdferr) ! ptr instead of c_loc(ptr) works on gfortran, not on ifort - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Aclose_f(attr_id,hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Sclose_f(space_id,hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' end subroutine HDF5_addAttribute_str_array @@ -564,24 +564,24 @@ subroutine HDF5_addAttribute_int_array(loc_id,attrLabel,attrValue,path) array_size = size(attrValue,kind=HSIZE_T) call H5Screate_simple_f(1, array_size, space_id, hdferr, array_size) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Aexists_by_name_f(loc_id,trim(p),attrLabel,attrExists,hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' if (attrExists) then call H5Adelete_by_name_f(loc_id, trim(p), attrLabel, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' end if call H5Acreate_by_name_f(loc_id,trim(p),trim(attrLabel),H5T_NATIVE_INTEGER,space_id,attr_id,hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Awrite_f(attr_id, H5T_NATIVE_INTEGER, attrValue, array_size, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Aclose_f(attr_id,hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Sclose_f(space_id,hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' end subroutine HDF5_addAttribute_int_array @@ -612,24 +612,24 @@ subroutine HDF5_addAttribute_real_array(loc_id,attrLabel,attrValue,path) array_size = size(attrValue,kind=HSIZE_T) call H5Screate_simple_f(1, array_size, space_id, hdferr, array_size) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Aexists_by_name_f(loc_id,trim(p),attrLabel,attrExists,hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' if (attrExists) then call H5Adelete_by_name_f(loc_id, trim(p), attrLabel, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' end if call H5Acreate_by_name_f(loc_id,trim(p),trim(attrLabel),H5T_NATIVE_DOUBLE,space_id,attr_id,hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Awrite_f(attr_id, H5T_NATIVE_DOUBLE, attrValue, array_size, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Aclose_f(attr_id,hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Sclose_f(space_id,hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' end subroutine HDF5_addAttribute_real_array @@ -645,13 +645,13 @@ subroutine HDF5_setLink(loc_id,target_name,link_name) logical :: linkExists call H5Lexists_f(loc_id, link_name,linkExists, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' if (linkExists) then call H5Ldelete_f(loc_id,link_name, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' end if call H5Lcreate_soft_f(target_name, loc_id, link_name, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' end subroutine HDF5_setLink @@ -673,13 +673,9 @@ subroutine HDF5_read_real1(dataset,loc_id,datasetName,parallel) totalShape !< shape of the dataset (all processes) integer :: hdferr -!--------------------------------------------------------------------------------------------------- -! determine shape of dataset - myShape = int(shape(dataset),HSIZE_T) - if (any(myShape(1:size(myShape)-1) == 0)) return !< empty dataset (last dimension can be empty) -!--------------------------------------------------------------------------------------------------- -! initialize HDF5 data structures + myShape = int(shape(dataset),HSIZE_T) + if (present(parallel)) then call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, & myStart, totalShape, loc_id,myShape,datasetName,parallel) @@ -687,10 +683,11 @@ subroutine HDF5_read_real1(dataset,loc_id,datasetName,parallel) call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, & myStart, totalShape, loc_id,myShape,datasetName,parallel_default) end if + if (any(totalShape == 0)) return call H5Dread_f(dset_id, H5T_NATIVE_DOUBLE,dataset,totalShape, hdferr,& file_space_id = filespace_id, xfer_prp = plist_id, mem_space_id = memspace_id) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call finalize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id) @@ -713,13 +710,9 @@ subroutine HDF5_read_real2(dataset,loc_id,datasetName,parallel) totalShape !< shape of the dataset (all processes) integer :: hdferr -!--------------------------------------------------------------------------------------------------- -! determine shape of dataset - myShape = int(shape(dataset),HSIZE_T) - if (any(myShape(1:size(myShape)-1) == 0)) return !< empty dataset (last dimension can be empty) -!--------------------------------------------------------------------------------------------------- -! initialize HDF5 data structures + myShape = int(shape(dataset),HSIZE_T) + if (present(parallel)) then call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, & myStart, totalShape, loc_id,myShape,datasetName,parallel) @@ -727,10 +720,11 @@ subroutine HDF5_read_real2(dataset,loc_id,datasetName,parallel) call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, & myStart, totalShape, loc_id,myShape,datasetName,parallel_default) end if + if (any(totalShape == 0)) return call H5Dread_f(dset_id, H5T_NATIVE_DOUBLE,dataset,totalShape, hdferr,& file_space_id = filespace_id, xfer_prp = plist_id, mem_space_id = memspace_id) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call finalize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id) @@ -753,13 +747,9 @@ subroutine HDF5_read_real3(dataset,loc_id,datasetName,parallel) totalShape !< shape of the dataset (all processes) integer :: hdferr -!--------------------------------------------------------------------------------------------------- -! determine shape of dataset - myShape = int(shape(dataset),HSIZE_T) - if (any(myShape(1:size(myShape)-1) == 0)) return !< empty dataset (last dimension can be empty) -!--------------------------------------------------------------------------------------------------- -! initialize HDF5 data structures + myShape = int(shape(dataset),HSIZE_T) + if (present(parallel)) then call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, & myStart, totalShape, loc_id,myShape,datasetName,parallel) @@ -767,10 +757,11 @@ subroutine HDF5_read_real3(dataset,loc_id,datasetName,parallel) call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, & myStart, totalShape, loc_id,myShape,datasetName,parallel_default) end if + if (any(totalShape == 0)) return call H5Dread_f(dset_id, H5T_NATIVE_DOUBLE,dataset,totalShape, hdferr,& file_space_id = filespace_id, xfer_prp = plist_id, mem_space_id = memspace_id) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call finalize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id) @@ -793,13 +784,10 @@ subroutine HDF5_read_real4(dataset,loc_id,datasetName,parallel) totalShape !< shape of the dataset (all processes) integer :: hdferr -!--------------------------------------------------------------------------------------------------- -! determine shape of dataset + myShape = int(shape(dataset),HSIZE_T) if (any(myShape(1:size(myShape)-1) == 0)) return !< empty dataset (last dimension can be empty) -!--------------------------------------------------------------------------------------------------- -! initialize HDF5 data structures if (present(parallel)) then call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, & myStart, totalShape, loc_id,myShape,datasetName,parallel) @@ -807,10 +795,11 @@ subroutine HDF5_read_real4(dataset,loc_id,datasetName,parallel) call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, & myStart, totalShape, loc_id,myShape,datasetName,parallel_default) end if + if (any(totalShape == 0)) return call H5Dread_f(dset_id, H5T_NATIVE_DOUBLE,dataset,totalShape, hdferr,& file_space_id = filespace_id, xfer_prp = plist_id, mem_space_id = memspace_id) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call finalize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id) @@ -833,13 +822,10 @@ subroutine HDF5_read_real5(dataset,loc_id,datasetName,parallel) totalShape !< shape of the dataset (all processes) integer :: hdferr -!--------------------------------------------------------------------------------------------------- -! determine shape of dataset + myShape = int(shape(dataset),HSIZE_T) if (any(myShape(1:size(myShape)-1) == 0)) return !< empty dataset (last dimension can be empty) -!--------------------------------------------------------------------------------------------------- -! initialize HDF5 data structures if (present(parallel)) then call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, & myStart, totalShape, loc_id,myShape,datasetName,parallel) @@ -847,10 +833,11 @@ subroutine HDF5_read_real5(dataset,loc_id,datasetName,parallel) call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, & myStart, totalShape, loc_id,myShape,datasetName,parallel_default) end if + if (any(totalShape == 0)) return call H5Dread_f(dset_id, H5T_NATIVE_DOUBLE,dataset,totalShape, hdferr,& file_space_id = filespace_id, xfer_prp = plist_id, mem_space_id = memspace_id) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call finalize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id) @@ -873,13 +860,10 @@ subroutine HDF5_read_real6(dataset,loc_id,datasetName,parallel) totalShape !< shape of the dataset (all processes) integer :: hdferr -!--------------------------------------------------------------------------------------------------- -! determine shape of dataset + myShape = int(shape(dataset),HSIZE_T) if (any(myShape(1:size(myShape)-1) == 0)) return !< empty dataset (last dimension can be empty) -!--------------------------------------------------------------------------------------------------- -! initialize HDF5 data structures if (present(parallel)) then call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, & myStart, totalShape, loc_id,myShape,datasetName,parallel) @@ -887,10 +871,11 @@ subroutine HDF5_read_real6(dataset,loc_id,datasetName,parallel) call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, & myStart, totalShape, loc_id,myShape,datasetName,parallel_default) end if + if (any(totalShape == 0)) return call H5Dread_f(dset_id, H5T_NATIVE_DOUBLE,dataset,totalShape, hdferr,& file_space_id = filespace_id, xfer_prp = plist_id, mem_space_id = memspace_id) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call finalize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id) @@ -913,13 +898,10 @@ subroutine HDF5_read_real7(dataset,loc_id,datasetName,parallel) totalShape !< shape of the dataset (all processes) integer :: hdferr -!--------------------------------------------------------------------------------------------------- -! determine shape of dataset + myShape = int(shape(dataset),HSIZE_T) if (any(myShape(1:size(myShape)-1) == 0)) return !< empty dataset (last dimension can be empty) -!--------------------------------------------------------------------------------------------------- -! initialize HDF5 data structures if (present(parallel)) then call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, & myStart, totalShape, loc_id,myShape,datasetName,parallel) @@ -927,10 +909,11 @@ subroutine HDF5_read_real7(dataset,loc_id,datasetName,parallel) call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, & myStart, totalShape, loc_id,myShape,datasetName,parallel_default) end if + if (any(totalShape == 0)) return call H5Dread_f(dset_id, H5T_NATIVE_DOUBLE,dataset,totalShape, hdferr,& file_space_id = filespace_id, xfer_prp = plist_id, mem_space_id = memspace_id) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call finalize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id) @@ -955,13 +938,8 @@ subroutine HDF5_read_int1(dataset,loc_id,datasetName,parallel) totalShape !< shape of the dataset (all processes) integer :: hdferr -!--------------------------------------------------------------------------------------------------- -! determine shape of dataset myShape = int(shape(dataset),HSIZE_T) - if (any(myShape(1:size(myShape)-1) == 0)) return !< empty dataset (last dimension can be empty) -!--------------------------------------------------------------------------------------------------- -! initialize HDF5 data structures if (present(parallel)) then call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, & myStart, totalShape, loc_id,myShape,datasetName,parallel) @@ -969,10 +947,11 @@ subroutine HDF5_read_int1(dataset,loc_id,datasetName,parallel) call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, & myStart, totalShape, loc_id,myShape,datasetName,parallel_default) end if + if (any(totalShape == 0)) return call H5Dread_f(dset_id, H5T_NATIVE_INTEGER,dataset,totalShape, hdferr,& file_space_id = filespace_id, xfer_prp = plist_id, mem_space_id = memspace_id) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call finalize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id) @@ -995,13 +974,10 @@ subroutine HDF5_read_int2(dataset,loc_id,datasetName,parallel) totalShape !< shape of the dataset (all processes) integer :: hdferr -!--------------------------------------------------------------------------------------------------- -! determine shape of dataset + myShape = int(shape(dataset),HSIZE_T) if (any(myShape(1:size(myShape)-1) == 0)) return !< empty dataset (last dimension can be empty) -!--------------------------------------------------------------------------------------------------- -! initialize HDF5 data structures if (present(parallel)) then call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, & myStart, totalShape, loc_id,myShape,datasetName,parallel) @@ -1009,10 +985,11 @@ subroutine HDF5_read_int2(dataset,loc_id,datasetName,parallel) call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, & myStart, totalShape, loc_id,myShape,datasetName,parallel_default) end if + if (any(totalShape == 0)) return call H5Dread_f(dset_id, H5T_NATIVE_INTEGER,dataset,totalShape, hdferr,& file_space_id = filespace_id, xfer_prp = plist_id, mem_space_id = memspace_id) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call finalize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id) @@ -1035,13 +1012,9 @@ subroutine HDF5_read_int3(dataset,loc_id,datasetName,parallel) totalShape !< shape of the dataset (all processes) integer :: hdferr -!--------------------------------------------------------------------------------------------------- -! determine shape of dataset - myShape = int(shape(dataset),HSIZE_T) - if (any(myShape(1:size(myShape)-1) == 0)) return !< empty dataset (last dimension can be empty) -!--------------------------------------------------------------------------------------------------- -! initialize HDF5 data structures + myShape = int(shape(dataset),HSIZE_T) + if (present(parallel)) then call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, & myStart, totalShape, loc_id,myShape,datasetName,parallel) @@ -1049,10 +1022,11 @@ subroutine HDF5_read_int3(dataset,loc_id,datasetName,parallel) call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, & myStart, totalShape, loc_id,myShape,datasetName,parallel_default) end if + if (any(totalShape == 0)) return call H5Dread_f(dset_id, H5T_NATIVE_INTEGER,dataset,totalShape, hdferr,& file_space_id = filespace_id, xfer_prp = plist_id, mem_space_id = memspace_id) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call finalize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id) @@ -1075,13 +1049,9 @@ subroutine HDF5_read_int4(dataset,loc_id,datasetName,parallel) totalShape !< shape of the dataset (all processes) integer :: hdferr -!--------------------------------------------------------------------------------------------------- -! determine shape of dataset - myShape = int(shape(dataset),HSIZE_T) - if (any(myShape(1:size(myShape)-1) == 0)) return !< empty dataset (last dimension can be empty) -!--------------------------------------------------------------------------------------------------- -! initialize HDF5 data structures + myShape = int(shape(dataset),HSIZE_T) + if (present(parallel)) then call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, & myStart, totalShape, loc_id,myShape,datasetName,parallel) @@ -1089,10 +1059,11 @@ subroutine HDF5_read_int4(dataset,loc_id,datasetName,parallel) call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, & myStart, totalShape, loc_id,myShape,datasetName,parallel_default) end if + if (any(totalShape == 0)) return call H5Dread_f(dset_id, H5T_NATIVE_INTEGER,dataset,totalShape, hdferr,& file_space_id = filespace_id, xfer_prp = plist_id, mem_space_id = memspace_id) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call finalize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id) @@ -1115,13 +1086,9 @@ subroutine HDF5_read_int5(dataset,loc_id,datasetName,parallel) totalShape !< shape of the dataset (all processes) integer :: hdferr -!--------------------------------------------------------------------------------------------------- -! determine shape of dataset - myShape = int(shape(dataset),HSIZE_T) - if (any(myShape(1:size(myShape)-1) == 0)) return !< empty dataset (last dimension can be empty) -!--------------------------------------------------------------------------------------------------- -! initialize HDF5 data structures + myShape = int(shape(dataset),HSIZE_T) + if (present(parallel)) then call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, & myStart, totalShape, loc_id,myShape,datasetName,parallel) @@ -1129,10 +1096,11 @@ subroutine HDF5_read_int5(dataset,loc_id,datasetName,parallel) call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, & myStart, totalShape, loc_id,myShape,datasetName,parallel_default) end if + if (any(totalShape == 0)) return call H5Dread_f(dset_id, H5T_NATIVE_INTEGER,dataset,totalShape, hdferr,& file_space_id = filespace_id, xfer_prp = plist_id, mem_space_id = memspace_id) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call finalize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id) @@ -1155,13 +1123,10 @@ subroutine HDF5_read_int6(dataset,loc_id,datasetName,parallel) totalShape !< shape of the dataset (all processes) integer :: hdferr -!--------------------------------------------------------------------------------------------------- -! determine shape of dataset + myShape = int(shape(dataset),HSIZE_T) if (any(myShape(1:size(myShape)-1) == 0)) return !< empty dataset (last dimension can be empty) -!--------------------------------------------------------------------------------------------------- -! initialize HDF5 data structures if (present(parallel)) then call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, & myStart, totalShape, loc_id,myShape,datasetName,parallel) @@ -1169,10 +1134,11 @@ subroutine HDF5_read_int6(dataset,loc_id,datasetName,parallel) call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, & myStart, totalShape, loc_id,myShape,datasetName,parallel_default) end if + if (any(totalShape == 0)) return call H5Dread_f(dset_id, H5T_NATIVE_INTEGER,dataset,totalShape, hdferr,& file_space_id = filespace_id, xfer_prp = plist_id, mem_space_id = memspace_id) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call finalize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id) @@ -1195,13 +1161,10 @@ subroutine HDF5_read_int7(dataset,loc_id,datasetName,parallel) totalShape !< shape of the dataset (all processes) integer :: hdferr -!--------------------------------------------------------------------------------------------------- -! determine shape of dataset + myShape = int(shape(dataset),HSIZE_T) if (any(myShape(1:size(myShape)-1) == 0)) return !< empty dataset (last dimension can be empty) -!--------------------------------------------------------------------------------------------------- -! initialize HDF5 data structures if (present(parallel)) then call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, & myStart, totalShape, loc_id,myShape,datasetName,parallel) @@ -1209,10 +1172,11 @@ subroutine HDF5_read_int7(dataset,loc_id,datasetName,parallel) call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, & myStart, totalShape, loc_id,myShape,datasetName,parallel_default) end if + if (any(totalShape == 0)) return call H5Dread_f(dset_id, H5T_NATIVE_INTEGER,dataset,totalShape, hdferr,& file_space_id = filespace_id, xfer_prp = plist_id, mem_space_id = memspace_id) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call finalize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id) @@ -1254,7 +1218,7 @@ subroutine HDF5_write_real1(dataset,loc_id,datasetName,parallel) if (product(totalShape) /= 0) then call H5Dwrite_f(dset_id, H5T_NATIVE_DOUBLE,dataset,int(totalShape,HSIZE_T), hdferr,& file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' end if call finalize_write(plist_id, dset_id, filespace_id, memspace_id) @@ -1295,7 +1259,7 @@ subroutine HDF5_write_real2(dataset,loc_id,datasetName,parallel) if (product(totalShape) /= 0) then call H5Dwrite_f(dset_id, H5T_NATIVE_DOUBLE,dataset,int(totalShape,HSIZE_T), hdferr,& file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' end if call finalize_write(plist_id, dset_id, filespace_id, memspace_id) @@ -1336,7 +1300,7 @@ subroutine HDF5_write_real3(dataset,loc_id,datasetName,parallel) if (product(totalShape) /= 0) then call H5Dwrite_f(dset_id, H5T_NATIVE_DOUBLE,dataset,int(totalShape,HSIZE_T), hdferr,& file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' end if call finalize_write(plist_id, dset_id, filespace_id, memspace_id) @@ -1377,7 +1341,7 @@ subroutine HDF5_write_real4(dataset,loc_id,datasetName,parallel) if (product(totalShape) /= 0) then call H5Dwrite_f(dset_id, H5T_NATIVE_DOUBLE,dataset,int(totalShape,HSIZE_T), hdferr,& file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' end if call finalize_write(plist_id, dset_id, filespace_id, memspace_id) @@ -1419,7 +1383,7 @@ subroutine HDF5_write_real5(dataset,loc_id,datasetName,parallel) if (product(totalShape) /= 0) then call H5Dwrite_f(dset_id, H5T_NATIVE_DOUBLE,dataset,int(totalShape,HSIZE_T), hdferr,& file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' end if call finalize_write(plist_id, dset_id, filespace_id, memspace_id) @@ -1460,7 +1424,7 @@ subroutine HDF5_write_real6(dataset,loc_id,datasetName,parallel) if (product(totalShape) /= 0) then call H5Dwrite_f(dset_id, H5T_NATIVE_DOUBLE,dataset,int(totalShape,HSIZE_T), hdferr,& file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' end if call finalize_write(plist_id, dset_id, filespace_id, memspace_id) @@ -1501,7 +1465,7 @@ subroutine HDF5_write_real7(dataset,loc_id,datasetName,parallel) if (product(totalShape) /= 0) then call H5Dwrite_f(dset_id, H5T_NATIVE_DOUBLE,dataset,int(totalShape,HSIZE_T), hdferr,& file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' end if call finalize_write(plist_id, dset_id, filespace_id, memspace_id) @@ -1565,7 +1529,7 @@ subroutine HDF5_write_real(dataset,loc_id,datasetName,parallel) call H5Dwrite_f(dset_id, H5T_NATIVE_DOUBLE,dataset,int(totalShape,HSIZE_T), hdferr,& file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id) end select - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' end if call finalize_write(plist_id, dset_id, filespace_id, memspace_id) @@ -1592,14 +1556,14 @@ subroutine HDF5_write_str(dataset,loc_id,datasetName) dataset_ = trim(dataset) call H5Tcopy_f(H5T_C_S1, filetype_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Tset_size_f(filetype_id, int(len(dataset_)+1,HSIZE_T), hdferr) ! +1 for NULL - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Tcopy_f(H5T_FORTRAN_S1, memtype_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Tset_size_f(memtype_id, int(len(dataset_),HSIZE_T), hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Pcreate_f(H5P_DATASET_CREATE_F, dcpl, hdferr) if (hdferr < 0) error stop 'HDF5 error' @@ -1615,23 +1579,23 @@ subroutine HDF5_write_str(dataset,loc_id,datasetName) end if call H5Screate_simple_f(1, [1_HSIZE_T], space_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' CALL H5Dcreate_f(loc_id, datasetName, filetype_id, space_id, dataset_id, hdferr, dcpl) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Dwrite_f(dataset_id, memtype_id, c_loc(dataset_(1:1)), hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Pclose_f(dcpl, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Dclose_f(dataset_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Sclose_f(space_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Tclose_f(memtype_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Tclose_f(filetype_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' end subroutine HDF5_write_str @@ -1671,7 +1635,7 @@ subroutine HDF5_write_int1(dataset,loc_id,datasetName,parallel) if (product(totalShape) /= 0) then call H5Dwrite_f(dset_id, H5T_NATIVE_INTEGER,dataset,int(totalShape,HSIZE_T), hdferr,& file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' end if call finalize_write(plist_id, dset_id, filespace_id, memspace_id) @@ -1712,7 +1676,7 @@ subroutine HDF5_write_int2(dataset,loc_id,datasetName,parallel) if (product(totalShape) /= 0) then call H5Dwrite_f(dset_id, H5T_NATIVE_INTEGER,dataset,int(totalShape,HSIZE_T), hdferr,& file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' end if call finalize_write(plist_id, dset_id, filespace_id, memspace_id) @@ -1753,7 +1717,7 @@ subroutine HDF5_write_int3(dataset,loc_id,datasetName,parallel) if (product(totalShape) /= 0) then call H5Dwrite_f(dset_id, H5T_NATIVE_INTEGER,dataset,int(totalShape,HSIZE_T), hdferr,& file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' end if call finalize_write(plist_id, dset_id, filespace_id, memspace_id) @@ -1794,7 +1758,7 @@ subroutine HDF5_write_int4(dataset,loc_id,datasetName,parallel) if (product(totalShape) /= 0) then call H5Dwrite_f(dset_id, H5T_NATIVE_INTEGER,dataset,int(totalShape,HSIZE_T), hdferr,& file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' end if call finalize_write(plist_id, dset_id, filespace_id, memspace_id) @@ -1835,7 +1799,7 @@ subroutine HDF5_write_int5(dataset,loc_id,datasetName,parallel) if (product(totalShape) /= 0) then call H5Dwrite_f(dset_id, H5T_NATIVE_INTEGER,dataset,int(totalShape,HSIZE_T), hdferr,& file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' end if call finalize_write(plist_id, dset_id, filespace_id, memspace_id) @@ -1876,7 +1840,7 @@ subroutine HDF5_write_int6(dataset,loc_id,datasetName,parallel) if (product(totalShape) /= 0) then call H5Dwrite_f(dset_id, H5T_NATIVE_INTEGER,dataset,int(totalShape,HSIZE_T), hdferr,& file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' end if call finalize_write(plist_id, dset_id, filespace_id, memspace_id) @@ -1917,7 +1881,7 @@ subroutine HDF5_write_int7(dataset,loc_id,datasetName,parallel) if (product(totalShape) /= 0) then call H5Dwrite_f(dset_id, H5T_NATIVE_INTEGER,dataset,int(totalShape,HSIZE_T), hdferr,& file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' end if call finalize_write(plist_id, dset_id, filespace_id, memspace_id) @@ -1981,7 +1945,7 @@ subroutine HDF5_write_int(dataset,loc_id,datasetName,parallel) call H5Dwrite_f(dset_id, H5T_NATIVE_INTEGER,dataset,int(totalShape,HSIZE_T), hdferr,& file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id) end select - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' end if call finalize_write(plist_id, dset_id, filespace_id, memspace_id) @@ -2014,7 +1978,7 @@ subroutine initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_ !------------------------------------------------------------------------------------------------- ! creating a property list for transfer properties (is collective for MPI) call H5Pcreate_f(H5P_DATASET_XFER_F, plist_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' !-------------------------------------------------------------------------------------------------- readSize = 0_MPI_INTEGER_KIND @@ -2022,7 +1986,7 @@ subroutine initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_ #ifdef PETSC if (parallel) then call H5Pset_dxpl_mpio_f(plist_id, H5FD_MPIO_COLLECTIVE_F, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call MPI_Allreduce(MPI_IN_PLACE,readSize,worldsize,MPI_INTEGER,MPI_SUM,MPI_COMM_WORLD,err_MPI) ! get total output size over each process if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' end if @@ -2031,31 +1995,37 @@ subroutine initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_ myStart(ubound(myStart)) = int(sum(readSize(1:worldrank)),HSIZE_T) globalShape = [localShape(1:ubound(localShape,1)-1),int(sum(readSize),HSIZE_T)] + if (any(globalShape == 0)) then + call H5Pclose_f(plist_id, hdferr) + if (hdferr < 0) error stop 'HDF5 error' + return + end if + !-------------------------------------------------------------------------------------------------- ! create dataspace in memory (local shape) call H5Screate_simple_f(size(localShape), localShape, memspace_id, hdferr, localShape) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' !-------------------------------------------------------------------------------------------------- ! creating a property list for IO and set it to collective call H5Pcreate_f(H5P_DATASET_ACCESS_F, aplist_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' #ifdef PETSC call H5Pset_all_coll_metadata_ops_f(aplist_id, .true., hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' #endif !-------------------------------------------------------------------------------------------------- ! open the dataset in the file and get the space ID call H5Dopen_f(loc_id,datasetName,dset_id,hdferr, dapl_id = aplist_id) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Dget_space_f(dset_id, filespace_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' !-------------------------------------------------------------------------------------------------- ! select a hyperslab (the portion of the current process) in the file call H5Sselect_hyperslab_f(filespace_id, H5S_SELECT_SET_F, myStart, localShape, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' end subroutine initialize_read @@ -2069,15 +2039,15 @@ subroutine finalize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id integer :: hdferr call H5Pclose_f(plist_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Pclose_f(aplist_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Dclose_f(dset_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Sclose_f(filespace_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Sclose_f(memspace_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' end subroutine finalize_read @@ -2110,11 +2080,11 @@ subroutine initialize_write(dset_id, filespace_id, memspace_id, plist_id, & !------------------------------------------------------------------------------------------------- ! creating a property list for transfer properties (is collective when writing in parallel) call H5Pcreate_f(H5P_DATASET_XFER_F, plist_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' #ifdef PETSC if (parallel) then call H5Pset_dxpl_mpio_f(plist_id, H5FD_MPIO_COLLECTIVE_F, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' end if #endif @@ -2159,19 +2129,19 @@ subroutine initialize_write(dset_id, filespace_id, memspace_id, plist_id, & !-------------------------------------------------------------------------------------------------- ! create dataspace in memory (local shape) and in file (global shape) call H5Screate_simple_f(size(myShape), myShape, memspace_id, hdferr, myShape) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Screate_simple_f(size(totalShape), totalShape, filespace_id, hdferr, totalShape) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' !-------------------------------------------------------------------------------------------------- ! create dataset in the file and select a hyperslab from it (the portion of the current process) call H5Dcreate_f(loc_id, trim(datasetName), datatype, filespace_id, dset_id, hdferr, dcpl) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Sselect_hyperslab_f(filespace_id, H5S_SELECT_SET_F, myStart, myShape, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Pclose_f(dcpl , hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' contains !------------------------------------------------------------------------------------------------ @@ -2200,13 +2170,13 @@ subroutine finalize_write(plist_id, dset_id, filespace_id, memspace_id) integer :: hdferr call H5Pclose_f(plist_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Dclose_f(dset_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Sclose_f(filespace_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Sclose_f(memspace_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' end subroutine finalize_write diff --git a/src/IO.f90 b/src/IO.f90 index 31bb0ed2d..c83ea1a22 100644 --- a/src/IO.f90 +++ b/src/IO.f90 @@ -36,6 +36,7 @@ module IO IO_floatValue, & IO_lc, & IO_rmComment, & + IO_intAsString, & IO_stringAsInt, & IO_stringAsFloat, & IO_stringAsBool, & @@ -251,12 +252,12 @@ pure function IO_lc(string) integer :: i,n - do i=1,len(string) + do i = 1,len(string) n = index(UPPER,string(i:i)) - if (n/=0) then - IO_lc(i:i) = LOWER(n:n) - else + if (n==0) then IO_lc(i:i) = string(i:i) + else + IO_lc(i:i) = LOWER(n:n) end if end do @@ -285,6 +286,21 @@ function IO_rmComment(line) end function IO_rmComment +!-------------------------------------------------------------------------------------------------- +!> @brief Return given int value as string. +!-------------------------------------------------------------------------------------------------- +function IO_intAsString(i) + + integer, intent(in) :: i + + character(len=:), allocatable :: IO_intAsString + + allocate(character(len=merge(2,1,i<0) + floor(log10(real(abs(merge(1,i,i==0))))))::IO_intAsString) + write(IO_intAsString,'(i0)') i + +end function IO_intAsString + + !-------------------------------------------------------------------------------------------------- !> @brief Return integer value from given string. !-------------------------------------------------------------------------------------------------- @@ -463,11 +479,15 @@ subroutine IO_error(error_ID,ext_msg,label1,ID1,label2,ID2) ! homogenization errors case (500) msg = 'unknown homogenization specified' + case (501) + msg = 'homogenization description absent' !-------------------------------------------------------------------------------------------------- ! user errors case (602) msg = 'invalid selection for debug' + case (603) + msg = 'invalid data for table' !------------------------------------------------------------------------------------------------ ! errors related to YAML data @@ -527,7 +547,7 @@ subroutine IO_error(error_ID,ext_msg,label1,ID1,label2,ID2) msg = 'MPI error' case (950) - msg = 'max number of cut back exceeded, terminating' + msg = 'max number of cutbacks exceeded, terminating' case default error stop 'invalid error number' @@ -665,66 +685,69 @@ end subroutine panel subroutine selfTest() integer, dimension(:), allocatable :: chunkPos - character(len=:), allocatable :: str + character(len=:), allocatable :: str,out - if(dNeq(1.0_pReal, IO_stringAsFloat('1.0'))) error stop 'IO_stringAsFloat' - if(dNeq(1.0_pReal, IO_stringAsFloat('1e0'))) error stop 'IO_stringAsFloat' - if(dNeq(0.1_pReal, IO_stringAsFloat('1e-1'))) error stop 'IO_stringAsFloat' - if(dNeq(0.1_pReal, IO_stringAsFloat('1.0e-1'))) error stop 'IO_stringAsFloat' - if(dNeq(0.1_pReal, IO_stringAsFloat('1.00e-1'))) error stop 'IO_stringAsFloat' - if(dNeq(10._pReal, IO_stringAsFloat(' 1.0e+1 '))) error stop 'IO_stringAsFloat' + if (dNeq(1.0_pReal, IO_stringAsFloat('1.0'))) error stop 'IO_stringAsFloat' + if (dNeq(1.0_pReal, IO_stringAsFloat('1e0'))) error stop 'IO_stringAsFloat' + if (dNeq(0.1_pReal, IO_stringAsFloat('1e-1'))) error stop 'IO_stringAsFloat' + if (dNeq(0.1_pReal, IO_stringAsFloat('1.0e-1'))) error stop 'IO_stringAsFloat' + if (dNeq(0.1_pReal, IO_stringAsFloat('1.00e-1'))) error stop 'IO_stringAsFloat' + if (dNeq(10._pReal, IO_stringAsFloat(' 1.0e+1 '))) error stop 'IO_stringAsFloat' - if(3112019 /= IO_stringAsInt( '3112019')) error stop 'IO_stringAsInt' - if(3112019 /= IO_stringAsInt(' 3112019')) error stop 'IO_stringAsInt' - if(-3112019 /= IO_stringAsInt('-3112019')) error stop 'IO_stringAsInt' - if(3112019 /= IO_stringAsInt('+3112019 ')) error stop 'IO_stringAsInt' - if(3112019 /= IO_stringAsInt('03112019 ')) error stop 'IO_stringAsInt' - if(3112019 /= IO_stringAsInt('+03112019')) error stop 'IO_stringAsInt' + if (3112019 /= IO_stringAsInt( '3112019')) error stop 'IO_stringAsInt' + if (3112019 /= IO_stringAsInt(' 3112019')) error stop 'IO_stringAsInt' + if (-3112019 /= IO_stringAsInt('-3112019')) error stop 'IO_stringAsInt' + if (3112019 /= IO_stringAsInt('+3112019 ')) error stop 'IO_stringAsInt' + if (3112019 /= IO_stringAsInt('03112019 ')) error stop 'IO_stringAsInt' + if (3112019 /= IO_stringAsInt('+03112019')) error stop 'IO_stringAsInt' - if(.not. IO_stringAsBool(' true')) error stop 'IO_stringAsBool' - if(.not. IO_stringAsBool(' True ')) error stop 'IO_stringAsBool' - if( IO_stringAsBool(' false')) error stop 'IO_stringAsBool' - if( IO_stringAsBool('False')) error stop 'IO_stringAsBool' + if (.not. IO_stringAsBool(' true')) error stop 'IO_stringAsBool' + if (.not. IO_stringAsBool(' True ')) error stop 'IO_stringAsBool' + if ( IO_stringAsBool(' false')) error stop 'IO_stringAsBool' + if ( IO_stringAsBool('False')) error stop 'IO_stringAsBool' - if(any([1,1,1] /= IO_stringPos('a'))) error stop 'IO_stringPos' - if(any([2,2,3,5,5] /= IO_stringPos(' aa b'))) error stop 'IO_stringPos' + if ('1234' /= IO_intAsString(1234)) error stop 'IO_intAsString' + if ('-12' /= IO_intAsString(-0012)) error stop 'IO_intAsString' + + if (any([1,1,1] /= IO_stringPos('a'))) error stop 'IO_stringPos' + if (any([2,2,3,5,5] /= IO_stringPos(' aa b'))) error stop 'IO_stringPos' str = ' 1.0 xxx' chunkPos = IO_stringPos(str) - if(dNeq(1.0_pReal,IO_floatValue(str,chunkPos,1))) error stop 'IO_floatValue' + if (dNeq(1.0_pReal,IO_floatValue(str,chunkPos,1))) error stop 'IO_floatValue' - str='M 3112019 F' + str = 'M 3112019 F' chunkPos = IO_stringPos(str) - if(3112019 /= IO_intValue(str,chunkPos,2)) error stop 'IO_intValue' + if (3112019 /= IO_intValue(str,chunkPos,2)) error stop 'IO_intValue' - if (CRLF2LF('') /= '') error stop 'CRLF2LF/0' - if (CRLF2LF(LF) /= LF) error stop 'CRLF2LF/1a' - if (CRLF2LF(CR//LF) /= LF) error stop 'CRLF2LF/1b' - if (CRLF2LF(' '//LF) /= ' '//LF) error stop 'CRLF2LF/2a' - if (CRLF2LF(' '//CR//LF) /= ' '//LF) error stop 'CRLF2LF/2b' - if (CRLF2LF('A'//CR//LF//'B') /= 'A'//LF//'B') error stop 'CRLF2LF/3' + if (CRLF2LF('') /= '') error stop 'CRLF2LF/0' + if (CRLF2LF(LF) /= LF) error stop 'CRLF2LF/1a' + if (CRLF2LF(CR//LF) /= LF) error stop 'CRLF2LF/1b' + if (CRLF2LF(' '//LF) /= ' '//LF) error stop 'CRLF2LF/2a' + if (CRLF2LF(' '//CR//LF) /= ' '//LF) error stop 'CRLF2LF/2b' + if (CRLF2LF('A'//CR//LF//'B') /= 'A'//LF//'B') error stop 'CRLF2LF/3' if (CRLF2LF('A'//CR//LF//'B'//CR//LF) /= & - 'A'//LF//'B'//LF) error stop 'CRLF2LF/4' + 'A'//LF//'B'//LF) error stop 'CRLF2LF/4' - if(.not. IO_isBlank(' ')) error stop 'IO_isBlank/1' - if(.not. IO_isBlank(' #isBlank')) error stop 'IO_isBlank/2' - if( IO_isBlank(' i#s')) error stop 'IO_isBlank/3' + str=' '; if (.not. IO_isBlank(str)) error stop 'IO_isBlank/1' + str=' #isBlank';if (.not. IO_isBlank(str)) error stop 'IO_isBlank/2' + str=' i#s'; if ( IO_isBlank(str)) error stop 'IO_isBlank/3' - str = IO_rmComment('#') - if (str /= '' .or. len(str) /= 0) error stop 'IO_rmComment/1' - str = IO_rmComment(' #') - if (str /= '' .or. len(str) /= 0) error stop 'IO_rmComment/2' - str = IO_rmComment(' # ') - if (str /= '' .or. len(str) /= 0) error stop 'IO_rmComment/3' - str = IO_rmComment(' # a') - if (str /= '' .or. len(str) /= 0) error stop 'IO_rmComment/4' - str = IO_rmComment(' # a') - if (str /= '' .or. len(str) /= 0) error stop 'IO_rmComment/5' - str = IO_rmComment(' a#') - if (str /= ' a' .or. len(str) /= 2) error stop 'IO_rmComment/6' - str = IO_rmComment(' ab #') - if (str /= ' ab'.or. len(str) /= 3) error stop 'IO_rmComment/7' + str='*(HiU!)3';if ('*(hiu!)3' /= IO_lc(str)) error stop 'IO_lc' + + str='#';out=IO_rmComment(str) + if (out /= '' .or. len(out) /= 0) error stop 'IO_rmComment/1' + str=' #';out=IO_rmComment(str) + if (out /= '' .or. len(out) /= 0) error stop 'IO_rmComment/2' + str=' # ';out=IO_rmComment(str) + if (out /= '' .or. len(out) /= 0) error stop 'IO_rmComment/3' + str=' # a';out=IO_rmComment(str) + if (out /= '' .or. len(out) /= 0) error stop 'IO_rmComment/4' + str=' a#';out=IO_rmComment(str) + if (out /= ' a' .or. len(out) /= 2) error stop 'IO_rmComment/5' + str=' ab #';out=IO_rmComment(str) + if (out /= ' ab'.or. len(out) /= 3) error stop 'IO_rmComment/6' end subroutine selfTest diff --git a/src/Marc/DAMASK_Marc.f90 b/src/Marc/DAMASK_Marc.f90 index 7a4a24ee1..65f406668 100644 --- a/src/Marc/DAMASK_Marc.f90 +++ b/src/Marc/DAMASK_Marc.f90 @@ -70,7 +70,7 @@ subroutine DAMASK_interface_init if (ierr /= 0) then print*, 'working directory "'//trim(wd)//'" does not exist' call quit(1) - endif + end if symmetricSolver = solverIsSymmetric() end subroutine DAMASK_interface_init @@ -105,14 +105,14 @@ logical function solverIsSymmetric() status='old', position='rewind', action='read',iostat=myStat) do read (fileUnit,'(A)',END=100) line - if(index(trim(lc(line)),'solver') == 1) then + if (index(trim(lc(line)),'solver') == 1) then read (fileUnit,'(A)',END=100) line ! next line s = verify(line, ' ') ! start of first chunk s = s + verify(line(s+1:),' ') ! start of second chunk e = s + scan (line(s+1:),' ') ! end of second chunk solverIsSymmetric = line(s:e) /= '1' - endif - enddo + end if + end do 100 close(fileUnit) contains @@ -134,7 +134,7 @@ logical function solverIsSymmetric() lc(i:i) = string(i:i) n = index(UPPER,lc(i:i)) if (n/=0) lc(i:i) = LOWER(n:n) - enddo + end do end function lc end function solverIsSymmetric @@ -147,12 +147,13 @@ end module DAMASK_interface #include "../YAML_types.f90" #include "../YAML_parse.f90" #include "../HDF5_utilities.f90" -#include "../results.f90" +#include "../result.f90" #include "../config.f90" #include "../LAPACK_interface.f90" #include "../math.f90" #include "../rotations.f90" #include "../polynomials.f90" +#include "../tables.f90" #include "../lattice.f90" #include "element.f90" #include "../geometry_plastic_nonlocal.f90" @@ -283,10 +284,10 @@ subroutine hypela2(d,g,e,de,s,t,dt,ngens,m,nn,kcus,matus,ndi,nshear,disp, & outdatedByNewInc = .false., & !< needs description materialpoint_init_done = .false., & !< remember whether init has been done already debug_basic = .true. - class(tNode), pointer :: & + type(tList), pointer :: & debug_Marc ! pointer to Marc debug options - if(debug_basic) then + if (debug_basic) then print'(a,/,i8,i8,i2)', ' MSC.Marc information on shape of element(2), IP:', m, nn print'(a,2(i1))', ' Jacobian: ', ngens,ngens print'(a,i1)', ' Direct stress: ', ndi @@ -299,7 +300,7 @@ subroutine hypela2(d,g,e,de,s,t,dt,ngens,m,nn,kcus,matus,ndi,nshear,disp, & transpose(ffn) write(6,'(/,a,/,3(3(f12.7,1x)/))',advance='no') ' Deformation gradient at t=n+1:', & transpose(ffn1) - endif + end if defaultNumThreadsInt = omp_get_num_threads() ! remember number of threads set by Marc call omp_set_num_threads(1_pI32) ! no openMP @@ -307,9 +308,9 @@ subroutine hypela2(d,g,e,de,s,t,dt,ngens,m,nn,kcus,matus,ndi,nshear,disp, & if (.not. materialpoint_init_done) then materialpoint_init_done = .true. call materialpoint_initAll - debug_Marc => config_debug%get('Marc',defaultVal=emptyList) + debug_Marc => config_debug%get_list('Marc',defaultVal=emptyList) debug_basic = debug_Marc%contains('basic') - endif + end if computationMode = 0 ! save initialization value, since it does not result in any calculation if (lovl == 4 ) then ! jacobian requested by marc @@ -333,35 +334,35 @@ subroutine hypela2(d,g,e,de,s,t,dt,ngens,m,nn,kcus,matus,ndi,nshear,disp, & lastIncConverged = .true. outdatedByNewInc = .true. print'(a,i6,1x,i2)', '<< HYPELA2 >> new increment..! ',m(1),nn - endif + end if else if ( timinc < theDelta ) then ! >> cutBack << lastIncConverged = .false. outdatedByNewInc = .false. terminallyIll = .false. cycleCounter = -1 ! first calc step increments this to cycle = 0 print'(a,i6,1x,i2)', '<< HYPELA2 >> cutback detected..! ',m(1),nn - endif ! convergence treatment end + end if ! convergence treatment end flush(6) if (lastLovl /= lovl) then cycleCounter = cycleCounter + 1 !mesh_cellnode = mesh_build_cellnodes() ! update cell node coordinates !call mesh_build_ipCoordinates() ! update ip coordinates - endif + end if if (outdatedByNewInc) then computationMode = ior(computationMode,materialpoint_AGERESULTS) outdatedByNewInc = .false. - endif + end if if (lastIncConverged) then computationMode = ior(computationMode,materialpoint_BACKUPJACOBIAN) lastIncConverged = .false. - endif + end if theTime = cptim theDelta = timinc theInc = inc - endif + end if lastLovl = lovl call materialpoint_general(computationMode,ffn,ffn1,t(1),timinc,int(m(1)),int(nn),stress,ddsdde) @@ -369,7 +370,7 @@ subroutine hypela2(d,g,e,de,s,t,dt,ngens,m,nn,kcus,matus,ndi,nshear,disp, & d = ddsdde(1:ngens,1:ngens) s = stress(1:ndi+nshear) g = 0.0_pReal - if(symmetricSolver) d = 0.5_pReal*(d+transpose(d)) + if (symmetricSolver) d = 0.5_pReal*(d+transpose(d)) call omp_set_num_threads(defaultNumThreadsInt) ! reset number of threads to stored default value @@ -413,6 +414,8 @@ subroutine uedinc(inc,incsub) use discretization_Marc implicit none(type,external) + + external :: nodvar integer(pI64), intent(in) :: inc, incsub integer :: n, nqncomp, nqdatatype @@ -426,14 +429,14 @@ subroutine uedinc(inc,incsub) do n = lbound(discretization_Marc_FEM2DAMASK_node,1), ubound(discretization_Marc_FEM2DAMASK_node,1) if (discretization_Marc_FEM2DAMASK_node(n) /= -1) then call nodvar(1,n,d_n(1:3,discretization_Marc_FEM2DAMASK_node(n)),nqncomp,nqdatatype) - if(nqncomp == 2) d_n(3,discretization_Marc_FEM2DAMASK_node(n)) = 0.0_pReal - endif - enddo + if (nqncomp == 2) d_n(3,discretization_Marc_FEM2DAMASK_node(n)) = 0.0_pReal + end if + end do call discretization_Marc_UpdateNodeAndIpCoords(d_n) - call materialpoint_results(int(inc),cptim) + call materialpoint_result(int(inc),cptim) inc_written = int(inc) - endif + end if end subroutine uedinc diff --git a/src/Marc/discretization_Marc.f90 b/src/Marc/discretization_Marc.f90 index a0667d049..b0cc8be61 100644 --- a/src/Marc/discretization_Marc.f90 +++ b/src/Marc/discretization_Marc.f90 @@ -15,7 +15,7 @@ module discretization_Marc use element use discretization use geometry_plastic_nonlocal - use results + use result implicit none(type,external) private @@ -69,7 +69,7 @@ subroutine discretization_Marc_init real(pReal), dimension(:,:,:,:), allocatable :: & unscaledNormals - class(tNode), pointer :: & + type(tDict), pointer :: & num_commercialFEM @@ -78,7 +78,7 @@ subroutine discretization_Marc_init debug_e = config_debug%get_asInt('element',defaultVal=1) debug_i = config_debug%get_asInt('integrationpoint',defaultVal=1) - num_commercialFEM => config_numerics%get('commercialFEM',defaultVal = emptyDict) + num_commercialFEM => config_numerics%get_dict('commercialFEM',defaultVal = emptyDict) mesh_unitlength = num_commercialFEM%get_asFloat('unitlength',defaultVal=1.0_pReal) ! set physical extent of a length unit in mesh if (mesh_unitlength <= 0.0_pReal) call IO_error(301,'unitlength') @@ -110,7 +110,7 @@ subroutine discretization_Marc_init call geometry_plastic_nonlocal_setIParea(norm2(unscaledNormals,1)) call geometry_plastic_nonlocal_setIPareaNormal(unscaledNormals/spread(norm2(unscaledNormals,1),1,3)) call geometry_plastic_nonlocal_setIPneighborhood(IPneighborhood(elem)) - call geometry_plastic_nonlocal_results + call geometry_plastic_nonlocal_result end subroutine discretization_Marc_init @@ -167,23 +167,23 @@ subroutine writeGeometry(elem, & coordinates_points - call results_openJobFile - call results_closeGroup(results_addGroup('geometry')) + call result_openJobFile + call result_closeGroup(result_addGroup('geometry')) - call results_writeDataset(connectivity_elem,'geometry','T_e',& - 'connectivity of the elements','-') + call result_writeDataset(connectivity_elem,'geometry','T_e',& + 'connectivity of the elements','-') - call results_writeDataset(connectivity_cell_reshaped,'geometry','T_c', & - 'connectivity of the cells','-') - call results_addAttribute('VTK_TYPE',elem%vtkType,'geometry/T_c') + call result_writeDataset(connectivity_cell_reshaped,'geometry','T_c', & + 'connectivity of the cells','-') + call result_addAttribute('VTK_TYPE',elem%vtkType,'geometry/T_c') - call results_writeDataset(coordinates_nodes,'geometry','x_n', & - 'initial coordinates of the nodes','m') + call result_writeDataset(coordinates_nodes,'geometry','x_n', & + 'initial coordinates of the nodes','m') - call results_writeDataset(coordinates_points,'geometry','x_p', & - 'initial coordinates of the materialpoints (cell centers)','m') + call result_writeDataset(coordinates_points,'geometry','x_p', & + 'initial coordinates of the materialpoints (cell centers)','m') - call results_closeJobFile + call result_closeJobFile end subroutine writeGeometry @@ -216,11 +216,11 @@ subroutine inputRead(elem,node0_elem,connectivity_elem,materialAt) mapElemSet !< list of elements in elementSet - call results_openJobFile - call results_writeDataset_str(IO_read(trim(getSolverJobName())//InputFileExtension), 'setup', & + call result_openJobFile + call result_writeDataset_str(IO_read(trim(getSolverJobName())//InputFileExtension), 'setup', & trim(getSolverJobName())//InputFileExtension, & 'MSC.Marc input deck') - call results_closeJobFile + call result_closeJobFile inputFile = IO_readlines(trim(getSolverJobName())//InputFileExtension) call inputRead_fileFormat(fileFormatVersion, & @@ -271,12 +271,12 @@ subroutine inputRead_fileFormat(fileFormat,fileContent) do l = 1, size(fileContent) chunkPos = IO_stringPos(fileContent(l)) - if(chunkPos(1) < 2) cycle - if(IO_lc(IO_stringValue(fileContent(l),chunkPos,1)) == 'version') then + if (chunkPos(1) < 2) cycle + if (IO_lc(IO_stringValue(fileContent(l),chunkPos,1)) == 'version') then fileFormat = IO_intValue(fileContent(l),chunkPos,2) exit - endif - enddo + end if + end do end subroutine inputRead_fileFormat @@ -297,13 +297,13 @@ subroutine inputRead_tableStyles(initialcond,hypoelastic,fileContent) do l = 1, size(fileContent) chunkPos = IO_stringPos(fileContent(l)) - if(chunkPos(1) < 6) cycle - if(IO_lc(IO_stringValue(fileContent(l),chunkPos,1)) == 'table') then + if (chunkPos(1) < 6) cycle + if (IO_lc(IO_stringValue(fileContent(l),chunkPos,1)) == 'table') then initialcond = IO_intValue(fileContent(l),chunkPos,4) hypoelastic = IO_intValue(fileContent(l),chunkPos,5) exit - endif - enddo + end if + end do end subroutine inputRead_tableStyles @@ -324,23 +324,23 @@ subroutine inputRead_matNumber(matNumber, & do l = 1, size(fileContent) chunkPos = IO_stringPos(fileContent(l)) - if(chunkPos(1) < 1) cycle - if(IO_lc(IO_stringValue(fileContent(l),chunkPos,1)) == 'hypoelastic') then + if (chunkPos(1) < 1) cycle + if (IO_lc(IO_stringValue(fileContent(l),chunkPos,1)) == 'hypoelastic') then if (len_trim(fileContent(l+1))/=0) then chunkPos = IO_stringPos(fileContent(l+1)) data_blocks = IO_intValue(fileContent(l+1),chunkPos,1) else data_blocks = 1 - endif + end if allocate(matNumber(data_blocks), source = 0) do i = 0, data_blocks - 1 j = i*(2+tableStyle) + 1 chunkPos = IO_stringPos(fileContent(l+1+j)) matNumber(i+1) = IO_intValue(fileContent(l+1+j),chunkPos,1) - enddo + end do exit - endif - enddo + end if + end do end subroutine inputRead_matNumber @@ -362,14 +362,14 @@ subroutine inputRead_NnodesAndElements(nNodes,nElems,& do l = 1, size(fileContent) chunkPos = IO_stringPos(fileContent(l)) - if(chunkPos(1) < 1) cycle + if (chunkPos(1) < 1) cycle if (IO_lc(IO_StringValue(fileContent(l),chunkPos,1)) == 'sizing') then nElems = IO_IntValue (fileContent(l),chunkPos,3) - elseif(IO_lc(IO_StringValue(fileContent(l),chunkPos,1)) == 'coordinates') then + elseif (IO_lc(IO_StringValue(fileContent(l),chunkPos,1)) == 'coordinates') then chunkPos = IO_stringPos(fileContent(l+1)) nNodes = IO_IntValue (fileContent(l+1),chunkPos,2) - endif - enddo + end if + end do end subroutine inputRead_NnodesAndElements @@ -392,13 +392,13 @@ subroutine inputRead_NelemSets(nElemSets,maxNelemInSet,& do l = 1, size(fileContent) chunkPos = IO_stringPos(fileContent(l)) - if(chunkPos(1) < 2) cycle - if(IO_lc(IO_StringValue(fileContent(l),chunkPos,1)) == 'define' .and. & + if (chunkPos(1) < 2) cycle + if (IO_lc(IO_StringValue(fileContent(l),chunkPos,1)) == 'define' .and. & IO_lc(IO_StringValue(fileContent(l),chunkPos,2)) == 'element') then nElemSets = nElemSets + 1 chunkPos = IO_stringPos(fileContent(l+1)) - if(containsRange(fileContent(l+1),chunkPos)) then + if (containsRange(fileContent(l+1),chunkPos)) then elemInCurrentSet = 1 + abs( IO_intValue(fileContent(l+1),chunkPos,3) & -IO_intValue(fileContent(l+1),chunkPos,1)) else @@ -408,15 +408,15 @@ subroutine inputRead_NelemSets(nElemSets,maxNelemInSet,& i = i + 1 chunkPos = IO_stringPos(fileContent(l+i)) elemInCurrentSet = elemInCurrentSet + chunkPos(1) - 1 ! add line's count when assuming 'c' - if(IO_lc(IO_stringValue(fileContent(l+i),chunkPos,chunkPos(1))) /= 'c') then ! line finished, read last value + if (IO_lc(IO_stringValue(fileContent(l+i),chunkPos,chunkPos(1))) /= 'c') then ! line finished, read last value elemInCurrentSet = elemInCurrentSet + 1 ! data ended exit - endif - enddo - endif + end if + end do + end if maxNelemInSet = max(maxNelemInSet, elemInCurrentSet) - endif - enddo + end if + end do end subroutine inputRead_NelemSets @@ -442,14 +442,14 @@ subroutine inputRead_mapElemSets(nameElemSet,mapElemSet,& do l = 1, size(fileContent) chunkPos = IO_stringPos(fileContent(l)) - if(chunkPos(1) < 2) cycle - if(IO_lc(IO_stringValue(fileContent(l),chunkPos,1)) == 'define' .and. & + if (chunkPos(1) < 2) cycle + if (IO_lc(IO_stringValue(fileContent(l),chunkPos,1)) == 'define' .and. & IO_lc(IO_stringValue(fileContent(l),chunkPos,2)) == 'element') then elemSet = elemSet+1 nameElemSet(elemSet) = trim(IO_stringValue(fileContent(l),chunkPos,4)) mapElemSet(:,elemSet) = continuousIntValues(fileContent(l+1:),size(mapElemSet,1)-1,nameElemSet,mapElemSet,size(nameElemSet)) - endif - enddo + end if + end do end subroutine inputRead_mapElemSets @@ -473,8 +473,8 @@ subroutine inputRead_mapElems(FEM2DAMASK, & do l = 1, size(fileContent) chunkPos = IO_stringPos(fileContent(l)) - if(chunkPos(1) < 1) cycle - if(IO_lc(IO_stringValue(fileContent(l),chunkPos,1)) == 'connectivity') then + if (chunkPos(1) < 1) cycle + if (IO_lc(IO_stringValue(fileContent(l),chunkPos,1)) == 'connectivity') then j = 0 do i = 1,nElems chunkPos = IO_stringPos(fileContent(l+1+i+j)) @@ -484,17 +484,17 @@ subroutine inputRead_mapElems(FEM2DAMASK, & j = j + 1 chunkPos = IO_stringPos(fileContent(l+1+i+j)) nNodesAlreadyRead = nNodesAlreadyRead + chunkPos(1) - enddo - enddo + end do + end do exit - endif - enddo + end if + end do call math_sort(map_unsorted) allocate(FEM2DAMASK(minval(map_unsorted(1,:)):maxval(map_unsorted(1,:))),source=-1) do i = 1, nElems FEM2DAMASK(map_unsorted(1,i)) = map_unsorted(2,i) - enddo + end do end subroutine inputRead_mapElems @@ -517,21 +517,21 @@ subroutine inputRead_mapNodes(FEM2DAMASK, & do l = 1, size(fileContent) chunkPos = IO_stringPos(fileContent(l)) - if(chunkPos(1) < 1) cycle - if(IO_lc(IO_stringValue(fileContent(l),chunkPos,1)) == 'coordinates') then + if (chunkPos(1) < 1) cycle + if (IO_lc(IO_stringValue(fileContent(l),chunkPos,1)) == 'coordinates') then chunkPos = [1,1,10] do i = 1,nNodes map_unsorted(:,i) = [IO_intValue(fileContent(l+1+i),chunkPos,1),i] - enddo + end do exit - endif - enddo + end if + end do call math_sort(map_unsorted) allocate(FEM2DAMASK(minval(map_unsorted(1,:)):maxval(map_unsorted(1,:))),source=-1) do i = 1, nNodes FEM2DAMASK(map_unsorted(1,i)) = map_unsorted(2,i) - enddo + end do end subroutine inputRead_mapNodes @@ -554,16 +554,16 @@ subroutine inputRead_elemNodes(nodes, & do l = 1, size(fileContent) chunkPos = IO_stringPos(fileContent(l)) - if(chunkPos(1) < 1) cycle - if(IO_lc(IO_stringValue(fileContent(l),chunkPos,1)) == 'coordinates') then + if (chunkPos(1) < 1) cycle + if (IO_lc(IO_stringValue(fileContent(l),chunkPos,1)) == 'coordinates') then chunkPos = [4,1,10,11,30,31,50,51,70] do i=1,nNode m = discretization_Marc_FEM2DAMASK_node(IO_intValue(fileContent(l+1+i),chunkPos,1)) nodes(1:3,m) = [(mesh_unitlength * IO_floatValue(fileContent(l+1+i),chunkPos,j+1),j=1,3)] - enddo + end do exit - endif - enddo + end if + end do end subroutine inputRead_elemNodes @@ -585,8 +585,8 @@ subroutine inputRead_elemType(elem, & t = -1 do l = 1, size(fileContent) chunkPos = IO_stringPos(fileContent(l)) - if(chunkPos(1) < 1) cycle - if(IO_lc(IO_stringValue(fileContent(l),chunkPos,1)) == 'connectivity') then + if (chunkPos(1) < 1) cycle + if (IO_lc(IO_stringValue(fileContent(l),chunkPos,1)) == 'connectivity') then j = 0 do i=1,nElem ! read all elements chunkPos = IO_stringPos(fileContent(l+1+i+j)) @@ -596,17 +596,17 @@ subroutine inputRead_elemType(elem, & else t_ = mapElemtype(IO_stringValue(fileContent(l+1+i+j),chunkPos,2)) if (t /= t_) call IO_error(191,IO_stringValue(fileContent(l+1+i+j),chunkPos,2),label1='type',ID1=t) - endif + end if remainingChunks = elem%nNodes - (chunkPos(1) - 2) do while(remainingChunks > 0) j = j + 1 chunkPos = IO_stringPos(fileContent(l+1+i+j)) remainingChunks = remainingChunks - chunkPos(1) - enddo - enddo + end do + end do exit - endif - enddo + end if + end do contains @@ -676,8 +676,8 @@ function inputRead_connectivityElem(nElem,nNodes,fileContent) do l = 1, size(fileContent) chunkPos = IO_stringPos(fileContent(l)) - if(chunkPos(1) < 1) cycle - if(IO_lc(IO_stringValue(fileContent(l),chunkPos,1)) == 'connectivity') then + if (chunkPos(1) < 1) cycle + if (IO_lc(IO_stringValue(fileContent(l),chunkPos,1)) == 'connectivity') then j = 0 do i = 1,nElem chunkPos = IO_stringPos(fileContent(l+1+i+j)) @@ -686,7 +686,7 @@ function inputRead_connectivityElem(nElem,nNodes,fileContent) do k = 1,chunkPos(1)-2 inputRead_connectivityElem(k,e) = & discretization_Marc_FEM2DAMASK_node(IO_IntValue(fileContent(l+1+i+j),chunkPos,k+2)) - enddo + end do nNodesAlreadyRead = chunkPos(1) - 2 do while(nNodesAlreadyRead < nNodes) ! read on if not all nodes in one line j = j + 1 @@ -694,14 +694,14 @@ function inputRead_connectivityElem(nElem,nNodes,fileContent) do k = 1,chunkPos(1) inputRead_connectivityElem(nNodesAlreadyRead+k,e) = & discretization_Marc_FEM2DAMASK_node(IO_IntValue(fileContent(l+1+i+j),chunkPos,k)) - enddo + end do nNodesAlreadyRead = nNodesAlreadyRead + chunkPos(1) - enddo - endif - enddo + end do + end if + end do exit - endif - enddo + end if + end do end function inputRead_connectivityElem @@ -733,8 +733,8 @@ subroutine inputRead_material(materialAt,& do l = 1, size(fileContent) chunkPos = IO_stringPos(fileContent(l)) - if(chunkPos(1) < 2) cycle - if(IO_lc(IO_stringValue(fileContent(l),chunkPos,1)) == 'initial' .and. & + if (chunkPos(1) < 2) cycle + if (IO_lc(IO_stringValue(fileContent(l),chunkPos,1)) == 'initial' .and. & IO_lc(IO_stringValue(fileContent(l),chunkPos,2)) == 'state') then k = merge(2,1,initialcondTableStyle == 2) chunkPos = IO_stringPos(fileContent(l+k)) @@ -749,14 +749,14 @@ subroutine inputRead_material(materialAt,& do i = 1,contInts(1) e = discretization_Marc_FEM2DAMASK_elem(contInts(1+i)) materialAt(e) = ID + 1 - enddo + end do if (initialcondTableStyle == 0) m = m + 1 - enddo - endif - endif - enddo + end do + end if + end if + end do - if(any(materialAt < 1)) call IO_error(180) + if (any(materialAt < 1)) call IO_error(180) end subroutine inputRead_material @@ -791,9 +791,9 @@ pure subroutine buildCells(connectivity,definition, & do c = 1, elem%NcellNodes realNode: if (count(elem%cellNodeParentNodeWeights(:,c) /= 0) == 1) then where(connectivity(:,:,e) == -c) connectivity(:,:,e) = connectivity_elem(c,e) - endif realNode - enddo - enddo + end if realNode + end do + end do nCellNode = maxval(connectivity_elem) @@ -806,7 +806,7 @@ pure subroutine buildCells(connectivity,definition, & do c = 1, elem%NcellNodes if (count(elem%cellNodeParentNodeWeights(:,c) /= 0) == nParentNodes) & candidates_local = [candidates_local,c] - enddo + end do s = size(candidates_local) if (allocated(candidates_global)) deallocate(candidates_global) @@ -822,8 +822,8 @@ pure subroutine buildCells(connectivity,definition, & if (elem%cellNodeParentNodeWeights(j,c) /= 0) then ! real node 'j' partly defines cell node 'c' p = p + 1 parentsAndWeights(p,1:2) = [connectivity_elem(j,e),elem%cellNodeParentNodeWeights(j,c)] - endif - enddo + end if + end do ! store (and order) real node IDs and their weights together with the element number and local ID do p = 1, nParentNodes m = maxloc(parentsAndWeights(:,1),1) @@ -833,9 +833,9 @@ pure subroutine buildCells(connectivity,definition, & candidates_global(nParentNodes*2+1:nParentNodes*2+2,candidateID) = [e,c] parentsAndWeights(m,1) = -huge(parentsAndWeights(m,1)) ! out of the competition - enddo - enddo - enddo + end do + end do + end do ! sort according to real node IDs + weight (from left to right) call math_sort(candidates_global,sortDim=1) ! sort according to first column @@ -847,13 +847,13 @@ pure subroutine buildCells(connectivity,definition, & do while (n+j<= size(candidates_local)*Nelem) if (candidates_global(p-1,n+j)/=candidates_global(p-1,n)) exit j = j + 1 - enddo + end do e = n+j-1 if (any(candidates_global(p,n:e)/=candidates_global(p,n))) & call math_sort(candidates_global(:,n:e),sortDim=p) n = e+1 - enddo - enddo + end do + end do i = uniqueRows(candidates_global(1:2*nParentNodes,:)) allocate(definition(nParentNodes-1)%parents(i,nParentNodes)) @@ -876,15 +876,15 @@ pure subroutine buildCells(connectivity,definition, & end where j = j+1 - enddo + end do nCellNode = nCellNode + 1 definition(nParentNodes-1)%parents(i,:) = parentsAndWeights(:,1) definition(nParentNodes-1)%weights(i,:) = parentsAndWeights(:,2) i = i + 1 n = n+j - enddo + end do - enddo + end do contains !------------------------------------------------------------------------------------------------ @@ -906,10 +906,10 @@ pure subroutine buildCells(connectivity,definition, & do while (r+d<= size(A,2)) if (any(A(:,r)/=A(:,r+d))) exit d = d+1 - enddo + end do u = u+1 r = r+d - enddo + end do end function uniqueRows @@ -939,10 +939,10 @@ pure function buildCellNodes(node_elem) buildCellNodes(:,n) = buildCellNodes(:,n) & + buildCellNodes(:,cellNodeDefinition(i)%parents(j,k)) & * real(cellNodeDefinition(i)%weights(j,k),pReal) - enddo + end do buildCellNodes(:,n) = buildCellNodes(:,n)/real(sum(cellNodeDefinition(i)%weights(j,:)),pReal) - enddo - enddo + end do + end do end function buildCellNodes @@ -970,9 +970,9 @@ pure function buildIPcoordinates(node_cell) do n = 1, size(connectivity_cell_reshaped,1) buildIPcoordinates(:,i) = buildIPcoordinates(:,i) & + node_cell(:,connectivity_cell_reshaped(n,i)) - enddo + end do buildIPcoordinates(:,i) = buildIPcoordinates(:,i)/real(size(connectivity_cell_reshaped,1),pReal) - enddo + end do end function buildIPcoordinates @@ -1031,8 +1031,8 @@ pure function IPvolume(elem,node) + dot_product((x7-x1), math_cross((x5-x0), (x7-x4)+(x3-x0))) IPvolume(i,e) = IPvolume(i,e)/12.0_pReal end select - enddo - enddo + end do + end do end function IPvolume @@ -1075,11 +1075,11 @@ pure function IPareaNormal(elem,nElem,node) IPareaNormal(1:3,f,i,e) = IPareaNormal(1:3,f,i,e) & + math_cross(nodePos(1:3,mod(n+0,m)+1) - nodePos(1:3,n), & nodePos(1:3,mod(n+1,m)+1) - nodePos(1:3,n)) * 0.5_pReal - enddo + end do end select - enddo - enddo - enddo + end do + end do + end do end function IPareaNormal @@ -1109,10 +1109,10 @@ function IPneighborhood(elem) do n = 1, size(face_unordered) face(n,c) = minval(face_unordered) face_unordered(minloc(face_unordered)) = huge(face_unordered) - enddo + end do face(n:n+3,c) = [e,i,f] - enddo - enddo; enddo + end do + end do; end do !-------------------------------------------------------------------------------------------------- ! sort face definitions @@ -1122,20 +1122,20 @@ function IPneighborhood(elem) e = 1 do while (e < size(face,2)) e = e + 1 - if(any(face(:c,s) /= face(:c,e))) then - if(e-1/=s) call math_sort(face(:,s:e-1),sortDim=c) + if (any(face(:c,s) /= face(:c,e))) then + if (e-1/=s) call math_sort(face(:,s:e-1),sortDim=c) s = e - endif - enddo - enddo + end if + end do + end do IPneighborhood = 0 do c=1, size(face,2) - 1 - if(all(face(:n-1,c) == face(:n-1,c+1))) then + if (all(face(:n-1,c) == face(:n-1,c+1))) then IPneighborhood(:,face(n+2,c+1),face(n+1,c+1),face(n+0,c+1)) = face(n:n+3,c+0) IPneighborhood(:,face(n+2,c+0),face(n+1,c+0),face(n+0,c+0)) = face(n:n+3,c+1) - endif - enddo + end if + end do end function IPneighborhood @@ -1171,29 +1171,29 @@ function continuousIntValues(fileContent,maxN,lookupName,lookupMap,lookupMaxN) if (IO_stringValue(fileContent(l),chunkPos,1) == lookupName(i)) then ! found matching name continuousIntValues = lookupMap(:,i) ! return resp. entity list exit - endif - enddo + end if + end do exit - elseif(containsRange(fileContent(l),chunkPos)) then + elseif (containsRange(fileContent(l),chunkPos)) then first = IO_intValue(fileContent(l),chunkPos,1) last = IO_intValue(fileContent(l),chunkPos,3) do i = first, last, sign(1,last-first) continuousIntValues(1) = continuousIntValues(1) + 1 continuousIntValues(1+continuousIntValues(1)) = i - enddo + end do exit else do i = 1,chunkPos(1)-1 ! interpret up to second to last value continuousIntValues(1) = continuousIntValues(1) + 1 continuousIntValues(1+continuousIntValues(1)) = IO_intValue(fileContent(l),chunkPos,i) - enddo + end do if ( IO_lc(IO_stringValue(fileContent(l),chunkPos,chunkPos(1))) /= 'c' ) then ! line finished, read last value continuousIntValues(1) = continuousIntValues(1) + 1 continuousIntValues(1+continuousIntValues(1)) = IO_intValue(fileContent(l),chunkPos,chunkPos(1)) exit - endif - endif - enddo + end if + end if + end do end function continuousIntValues @@ -1208,9 +1208,9 @@ logical function containsRange(str,chunkPos) containsRange = .False. - if(chunkPos(1) == 3) then - if(IO_lc(IO_stringValue(str,chunkPos,2)) == 'to') containsRange = .True. - endif + if (chunkPos(1) == 3) then + if (IO_lc(IO_stringValue(str,chunkPos,2)) == 'to') containsRange = .True. + end if end function containsRange diff --git a/src/Marc/include/concom2022.2 b/src/Marc/include/concom2022.2 new file mode 100644 index 000000000..2d4deaa34 --- /dev/null +++ b/src/Marc/include/concom2022.2 @@ -0,0 +1,466 @@ +! common block definition file taken from respective MSC.Marc release and reformated to free format +!*********************************************************************** +! +! File: concom.cmn +! +! MSC.Marc include file +! +integer & + iacous, iasmbl, iautth, ibear, icompl, iconj, icreep, ideva, idyn, idynt,& + ielas, ielcma, ielect, iform, ifour, iharm, ihcps, iheat, iheatt, ihresp,& + ijoule, ilem, ilnmom, iloren, inc, incext, incsub, ipass, iplres, ipois,& + ipoist, irpflo, ismall, ismalt, isoil, ispect, ispnow, istore, iswep, ithcrp,& + itherm, iupblg, iupdat, jacflg, jel, jparks, largst, lfond, loadup, loaduq,& + lodcor, lovl, lsub, magnet, ncycle, newtnt, newton, noshr, linear, ivscpl,& + icrpim, iradrt, ipshft, itshr, iangin, iupmdr, iconjf, jincfl, jpermg, jhour,& + isolvr, jritz, jtable, jshell, jdoubl, jform, jcentr, imini, kautth, iautof,& + ibukty, iassum, icnstd, icnstt, kmakmas, imethvp, iradrte, iradrtp, iupdate, iupdatp,& + ncycnt, marmen , idynme, ihavca, ispf, kmini, imixex, largtt, kdoela, iautofg,& + ipshftp, idntrc, ipore, jtablm, jtablc, isnecma, itrnspo, imsdif, jtrnspo, mcnear,& + imech, imecht, ielcmat, ielectt, magnett, imsdift, noplas, jtabls, jactch, jtablth,& + kgmsto , jpzo, ifricsh, iremkin, iremfor, ishearp, jspf, machining, jlshell, icompsol,& + iupblgfo, jcondir, nstcrp, nactive, ipassref, nstspnt, ibeart, icheckmpc, noline, icuring,& + ishrink, ioffsflg, isetoff, ioffsetm,iharmt, inc_incdat, iautspc, ibrake, icbush, istream_input,& + iprsinp, ivlsinp, ifirst_time,ipin_m, jgnstr_glb, imarc_return,iqvcinp, nqvceid, istpnx, imicro1,& + iaxisymm, jbreakglue,iglstif, jfastasm,iwear, iwearcf, imixmeth, ielcmadyn, idinout, igena_meth,& + magf_meth, non_assumed, iredoboudry, ioffsz0,icomplt, mesh_dual, iactrp, mgnewton, iusedens,igsigd0,& + iaem, icosim, inodels, nlharm, iampini, iphasetr, inonlcl, inonlct, iforminp,ispecerror,& + icsprg, imol, imolt, idatafit,iharmpar, inclcase, imultifreq,init_elas, ifatig, iftgmat,& + nchybrid, ibuckle, iexpande +dimension :: ideva(60) +integer num_concom +parameter(num_concom=263) +common/marc_concom/& + iacous, iasmbl, iautth, ibear, icompl, iconj, icreep, ideva, idyn, idynt,& + ielas, ielcma, ielect, iform, ifour, iharm, ihcps, iheat, iheatt, ihresp,& + ijoule, ilem, ilnmom, iloren, inc, incext, incsub, ipass, iplres, ipois,& + ipoist, irpflo, ismall, ismalt, isoil, ispect, ispnow, istore, iswep, ithcrp,& + itherm, iupblg, iupdat, jacflg, jel, jparks, largst, lfond, loadup, loaduq,& + lodcor, lovl, lsub, magnet, ncycle, newtnt, newton, noshr, linear, ivscpl,& + icrpim, iradrt, ipshft, itshr, iangin, iupmdr, iconjf, jincfl, jpermg, jhour,& + isolvr, jritz, jtable, jshell, jdoubl, jform, jcentr, imini, kautth, iautof,& + ibukty, iassum, icnstd, icnstt, kmakmas, imethvp, iradrte, iradrtp, iupdate, iupdatp,& + ncycnt, marmen, idynme, ihavca, ispf, kmini, imixex, largtt, kdoela, iautofg,& + ipshftp, idntrc, ipore, jtablm, jtablc, isnecma, itrnspo, imsdif, jtrnspo, mcnear,& + imech, imecht, ielcmat, ielectt, magnett, imsdift, noplas, jtabls, jactch, jtablth,& + kgmsto , jpzo, ifricsh, iremkin, iremfor, ishearp, jspf, machining, jlshell, icompsol,& + iupblgfo, jcondir, nstcrp, nactive, ipassref, nstspnt, ibeart, icheckmpc, noline, icuring,& + ishrink, ioffsflg, isetoff, ioffsetm,iharmt, inc_incdat, iautspc, ibrake, icbush, istream_input,& + iprsinp, ivlsinp, ifirst_time,ipin_m, jgnstr_glb, imarc_return,iqvcinp, nqvceid, istpnx, imicro1,& + iaxisymm, jbreakglue,iglstif, jfastasm,iwear, iwearcf, imixmeth, ielcmadyn, idinout, igena_meth,& + magf_meth, non_assumed, iredoboudry, ioffsz0,icomplt, mesh_dual, iactrp, mgnewton, iusedens,igsigd0,& + iaem, icosim, inodels, nlharm, iampini, iphasetr, inonlcl, inonlct, iforminp,ispecerror,& + icsprg, imol, imolt, idatafit,iharmpar, inclcase, imultifreq,init_elas, ifatig, iftgmat,& + nchybrid, ibuckle, iexpande +! +! comments of variables: +! +! iacous Control flag for acoustic analysis. Input data. +! iacous=1 modal acoustic analysis. +! iacous=2 harmonic acoustic-structural analysis. +! iasmbl Control flag to indicate that operator matrix should be +! recalculated. +! iautth Control flag for AUTO THERM option. +! ibear Control flag for bearing analysis. Input data. +! icompl Control variable to indicate that a complex analysis is +! being performed. Either a Harmonic analysis with damping, +! or a harmonic electro-magnetic analysis. Input data. +! iconj Flag for EBE conjugate gradient solver (=solver 1, retired) +! Also used for VKI iterative solver. +! icreep Control flag for creep analysis. Input data. +! ideva(60) - debug print out flag +! 1 print element stiffness matrices, mass matrix +! 2 output matrices used in tying +! 3 force the solution of a nonpositive definite matrix +! 4 print info of connections to each node +! 5 info of gap convergence, internal heat generated, contact +! touching and separation +! 6 nodal value array during rezoning +! 7 tying info in CONRAD GAP option, fluid element numbers in +! CHANNEL option +! 8 output incremental displacements in local coord. system +! 9 latent heat output +! 10 stress-strain in local coord. system +! 11 additional info on interlaminar stress +! 12 output right hand side and solution vector +! 13 info of CPU resources used and memory available on NT +! 14 info of mesh adaption process, 2D outline information +! info of penetration checking for remeshing +! save .fem files after afmesh3d meshing +! print local adaptivity info +! 15 surface energy balance flag +! 16 print info regarding pyrolysis +! 17 print info of "streamline topology" +! 18 print mesh data changes after remeshing +! 19 print material flow stress data read in from *.mat file +! if unit flag is on, print out flow stress after conversion +! 20 print information on table input +! 21 print out information regarding kinematic boundary conditions +! 22 print out information regarding dist loads, point loads, film +! and foundations +! 23 print out information about automatic domain decomposition +! 24 print out iteration information in SuperForm status report file +! 25 print out information for ablation +! 26 print out information for films - Table input +! 27 print out the tying forces +! 28 print out for CASI solver, convection, +! 29 DDM single file debug printout +! 30 print out cavity debug info +! 31 print out welding related info +! 32 prints categorized DDM memory usage +! 33 print out the cutting info regarding machining feature +! 34 print out the list of quantities which can be defined via a table +! and for each quantity the supported independent variables +! 35 print out detailed coupling region info +! 36 print out solver debug info level 1 (Least Detailed) +! 37 print out solver debug info level 1 (Medium Detailed) +! 38 print out solver debug info level 1 (Very Detailed) +! 39 print detailed memory allocation info +! 40 print out marc-adams debug info +! 41 output rezone mapping post file for debugging +! 42 output post file after calling oprofos() for debugging +! 43 debug printout for vcct +! 44 debug printout for progressive failure +! 45 print out automatically generated midside node coordinates (arecrd) +! 46 print out message about routine and location, where the ibort is raised (ibort_inc) +! 47 print out summary message of element variables on a +! group-basis after all the automatic changes have been +! made (em_ellibp) +! 48 Automatically generate check results based on max and min vals. +! These vals are stored in the checkr file, which is inserted +! into the *dat file by the generate_check_results script from /marc/tools +! 49 Automatically generate check results based on the real calculated values +! at the sppecified check result locations. +! These vals are stored in the checkr file, which is inserted +! into the *dat file by the update_check_results script from /marc/tools +! 50 generate a file containing the resistance or capacity matrix; +! this file can be used to compare results with a reference file +! 51 print out detailed information for segment-to-segment contact +! 52 print out detailed relative displacement information +! for uniaxial sliding contact +! 53 print out detailed sliding direction information for +! uniaxial sliding contact +! 54 print out detailed information for edges attached to a curve +! 55 print information related to viscoelasticity calculations +! 56 print out detailed information for element coloring for multithreading +! 57 print out extra overheads due to multi-threading. +! These overhead includes (i) time and (ii) memory. +! The memory report will be summed over all the children. +! 58 debug output for ELSTO usage +! 59 print out contact body forces and nodes in contact +! +! idyn Control flag for dynamics. Input data. +! 1 = eigenvalue extraction and / or modal superposition +! 2 = Newmark Beta and Single Step Houbolt (ssh with idynme=1) +! 3 = Houbolt +! 4 = Central difference +! 5 = Newer central difference +! idynt Copy of idyn at begining of increment +! ielas Control flag for ELASTIC analysis. Input data. +! Set by user or automatically turned on by Fourier option. +! Implies that each load case is treated separately. +! In Adaptive meshing analysis , forces re-analysis until +! convergence obtained. +! Also seriously misused to indicate no convergence. +! = 1 elastic option with fourier analysis +! = 2 elastic option without fourier analysis +! =-1 no convergence in recycles or max # increments reached +! Set to 1 if ELASTIC or SUBSTRUC parameter cards are used, +! or if fourier option is used. +! Then set to 2 if not fourier analysis. +! ielcma Control flag for electromagnetic analysis. Input data. +! ielcma = 1 Harmonic formulation +! ielcma = 2 Transient formulation +! ielect Control flag for electrostatic option. Input data. +! iform Control flag indicating that contact will be performed. +! ifour Control flag for Fourier analysis. +! 0 = Odd and even terms. +! 1 = symmetric (cosine) terms +! 2 = antisymmetric (sine) terms. +! iharm Control flag to indicate that a harmonic analysis will +! be performed. May change between passes. +! ihcps Control flag for coupled thermal - stress analysis. +! iheat Control flag for heat transfer analysis. Input data. +! iheatt Permanent control flag for heat transfer analysis. +! Note in coupled analysis iheatt will remain as one, +! but iheat will be zero in stress pass. +! ihresp Control flag to indicate to perform a harmonic subincrement. +! ijoule Control flag for Joule heating. +! ilem Control flag to determin which vector is to be transformed. +! Control flag to see where one is: +! ilem = 1 - elem.f +! ilem = 2 - initst.f +! ilem = 3 - pressr.f +! ilem = 3 - fstif.f +! ilem = 4 - jflux.f +! ilem = 4 - strass.f +! ilem = 5 - mass.f +! ilem = 5 - osolty.f +! ilnmom Control flag for soil - pore pressure calculation. Input data. +! ilnmom = 0 - perform only pore pressure calculation. +! = 1 - couples pore pressure - displacement analysis +! iloren Control flag for DeLorenzi J-Integral evaluation. Input data. +! inc Increment number. +! incext Control flag indicating that currently working on a +! subincrement. +! Could be due to harmonics , damping component (bearing), +! stiffness component (bearing), auto therm creep or +! old viscoplaticity +! incsub Sub-increment number. +! inonlcl control flag for nonlocal pass +! inonlct permanent control flag for nonlocal pass +! ipass Control flag for which part of coupled analysis. +! ipass = -1 - reset to base values +! ipass = 0 - do nothing +! ipass = 1 - stress part +! ipass = 2 - heat transfer part +! 3 - fluid pass +! 4 - joule heating pass +! 5 - pore pressure pass +! 6 - electrostatic pass +! 7 - magnetostatic pass +! 8 - electromagnetic pass +! 9 - diffusion pass +! ipass = 10 - nonlocal part +! iplres Flag indicating that either second matrix is stored. +! dynamic analysis - mass matrix +! heat transfer - specific heat matrix +! buckle - initial stress stiffness +! ipois Control flag indicating Poisson type analysis +! ipois = 1 for heat transfer +! = 1 for heat transfer part of coupled +! = 1 for bearing +! = 1 for electrostatic +! = 1 for magnetostatic +! = 1 for nonlocal part +! ipoist Permanent copy of ipois. In coupled analysis , ipois = 0 +! in stress portion, yet ipoist will still =1. +! irpflo global flag for rigid plastic flow analysis +! = 1 eularian formulation +! = 2 regular formulation; rigid material present in the analysis +! ismall control flag to indicate small displacement analysis. input data. +! ismall = 0 - large disp included. +! ismall = 1 - small displacement. +! the flag is changing between passes. +! ismalt permanent copy of ismall . in heat transfer portion of +! coupled analysis ismall =0 , but ismalt remains the same. +! isoil control flag indicating that soil / pore pressure +! calculation . input data. +! ispect control flag for response spectrum calculation. input data. +! ispnow control flag to indicate to perform a spectrum response +! calculation now. +! istore store stresses flag. +! istore = 0 in elem.f and if first pass of creep +! convergence checking in ogetst.f +! or harmonic analysis or thruc.f if not +! converged. +! iswep control flag for eigenvalue analysis. +! iswep=1 - go do extraction process +! ithcrp control flag for auto therm creep option. input data. +! itherm control flag for either temperature dependent material +! properties and/or thermal loads. +! iupblg control flag for follower force option. input data. +! iupdat control flag for update lagrange option for current element. +! jacflg control flag for lanczos iteration method. input data. +! jel control flag indicating that total load applied in +! increment, ignore previous solution. +! jel = 1 in increment 0 +! = 1 if elastic or fourier +! = 1 in subincrements with elastic and adaptive +! jparks control flag for j integral by parks method. input data. +! largst control flag for finite strain plasticity. input data. +! lfond control variable that indicates if doing elastic +! foundation or film calculation. influences whether +! this is volumetric or surface integration. +! loadup control flag that indicates that nonlinearity occurred +! during previous increment. +! loaduq control flag that indicates that nonlinearity occurred. +! lodcor control flag for switching on the residual load correction. +! notice in input stage lodcor=0 means no loadcor, +! after omarc lodcor=1 means no loadcor +! lovl control flag for determining which "overlay" is to +! be called from ellib. +! lovl = 1 omarc +! = 2 oaread +! = 3 opress +! = 4 oasemb +! = 5 osolty +! = 6 ogetst +! = 7 oscinc +! = 8 odynam +! = 9 opmesh +! = 10 omesh2 +! = 11 osetz +! = 12 oass +! = 13 oincdt +! = 14 oasmas +! = 15 ofluas +! = 16 ofluso +! = 17 oshtra +! = 18 ocass +! = 19 osoltc +! = 20 orezon +! = 21 otest +! = 22 oeigen +! lsub control variable to determine which part of element +! assembly function is being done. +! lsub = 1 - no longer used +! = 2 - beta* +! = 3 - cons* +! = 4 - ldef* +! = 5 - posw* +! = 6 - theta* +! = 7 - tmarx* +! = 8 - geom* +! magnet control flag for magnetostatic analysis. input data. +! ncycle cycle number. accumulated in osolty.f +! note first time through oasemb.f , ncycle = 0. +! newtnt control flag for permanent copy of newton. +! newton iteration type. input data. +! newton : = 1 full newton raphson +! 2 modified newton raphson +! 3 newton raphson with strain correct. +! 4 direct substitution +! 5 direct substitution followed by n.r. +! 6 direct substitution with line search +! 7 full newton raphson with secant initial stress +! 8 secant method +! 9 full newton raphson with line search +! noshr control flag for calculation interlaminar shears for +! elements 22,45, and 75. input data. +!ees +! +! jactch = 1 or 2 if elements are activated or deactivated +! = 3 if elements are adaptively remeshed or rezoned +! = 0 normally / reset to 0 when assembly is done +! ifricsh = 0 call to fricsh in otest not needed +! = 1 call to fricsh (nodal friction) in otest needed +! iremkin = 0 remove deactivated kinematic boundary conditions +! immediately - only in new input format (this is default) +! = 1 remove deactivated kinematic boundary conditions +! gradually - only in new input format +! iremfor = 0 remove force boundary conditions immediately - +! only in new input format (this is default) +! = 1 remove force boundary conditions gradually - +! only in new input format (this is default) +! ishearp set to 1 if shear panel elements are present in the model +! +! jspf = 0 not in spf loadcase +! > 0 in spf loadcase (jspf=1 during first increment) +! machining = 1 if the metal cutting feature is used, for memory allocation purpose +! = 0 (default) if no metal cutting feature required +! +! jlshell = 1 if there is a shell element in the mesh +! icompsol = 1 if there is a composite solid element in the mesh +! iupblgfo = 1 if follower force for point loads +! jcondir = 1 if contact priority option is used +! nstcrp = 0 (default) steady state creep flag (undocumented feature. +! if not 0, turns off special ncycle = 0 code in radial.f) +! nactive = number of active passes, if =1 then it's not a coupled analysis +! ipassref = reference ipass, if not in a multiphysics pass ipass=ipassref +! icheckmpc = value of mpc-check parameter option +! noline = set to 1 in osolty if no line seacrh should be done in ogetst +! icuring = set to 1 if the curing is included for the heat transfer analysis. +! ishrink = set to 1 if shrinkage strain is included for mechancial analysis. +! ioffsflg = 1 for small displacement beam/shell offsets +! = 2 for large displacement beam/shell offsets +! isetoff = 0 - do not apply beam/shell offsets +! = 1 - apply beam/shell offsets +! ioffsetm = min. value of offset flag +! iharmt = 1 global flag if a coupled analysis contains an harmonic pass +! inc_incdat = flag to record increment number of a new loadcase in incdat.f +! iautspc = flag for AutoSPC option +! ibrake = brake squeal in this increment +! icbush = set to 1 if cbush elements present in model +! istream_input = set to 1 for streaming input calling Marc as library +! iprsinp = set to 1 if pressure input, introduced so other variables +! such as h could be a function of pressure +! ivlsinp = set to 1 if velocity input, introduced so other variables +! such as h could be a function of velocity +! ipin_m = # of beam element with PIN flag +! jgnstr_glb = global control over pre or fast integrated composite shells +! imarc_return = Marc return flag for streaming input control +! iqvcimp = if non-zero, then the number of QVECT boundary conditions +! nqvceid = number of QVECT boundary conditions, where emisivity/absorbtion id entered +! istpnx = 1 if to stop at end of increment +! imicro1 = 1 if micro1 interface is used +! iaxisymm = set to 1 if axisymmetric analysis +! jbreakglue = set to 1 if breaking glued option is used +! iglstif = 1 if ddm and global stiffness matrix formed (sgi solver 6 or solver9) +! jfastasm = 1 do fast assembly using SuperForm code +! iwear = set to 1 if wear model, set to 2 if wear model and coordinates updated +! iwearcf = set to 1 to store nodal coefficient of friction for wear calculation +! imixmeth = set=1 then use nonlinear mixture material - allocate memory +! ielcmadyn = flag for magnetodynamics +! 0 - electromagnetics using newmark beta +! 1 - transient magnetics using backward euler +! idinout = flag to control if inside out elements should be deactivated +! igena_meth = 0 - generalized alpha parameters depend on whether or not contact +! is flagged (dynamic,7) +! 10 - generalized alpha parameters are optimized for a contact +! analysis (dynamic,8) +! 11 - generalized alpha parameters are optimized for an analysis +! without contact (dynamic,8) +! magf_meth = - Method to compute force in magnetostatic - structural +! = 1 - Virtual work method based on finite difference for the force computation +! = 2 - Maxwell stress tensor +! = 3 - Virtual work method based on local derivative for the force computation +! non_assumed = 1 no assumed strain formulation (forced) +! iredoboudry set to 1 if contact boundary needs to be recalculated +! ioffsz0 = 1 if composite are used with reference position.ne.0 +! icomplt = 1 global flag if a coupled analysis contains an complex pass +! mesh_dual = 1 two independent meshes are used in magnetodynamic/thermal/structural +! one for magnetodynamic and the other for the remaining passes +! iactrp = 1 in an analysis with global remeshing, include inactive +! rigid bodies on post file +! mgnewton = 1 Use full Newton Raphson iteration for magnetostatic pass +! +! iusedens > 0 if mass density is used in the analysis (dynamics, mass dependent loading) +! igsigd0 = 1 set varselem(igsigd) to zero in next oasemb +! iaem = 1 if marc is called from aem (0 - off - default) +! icosim = 1 if marc is used in co-simulation analysis with ADAMS using the CosimEngine +! = 2 if marc is used in co-simulation analysis with ADAMS using the ACSI interface +! = 3 if marc is used in co-simulation analysis with scFLOW using the CosimEngine +! = 4 if marc is used in co-simulation analysis with scFLOW and ADAMS using the CosimEngine +! inodels = 1 nodal integration elements 239/240/241 present +! nlharm = 0 harmonic subincrements are linear +! = 1 harmonic subincrements are nonlinear +! iampini = 0 amplitude of previous harmonic subinc is initial estimate (default) +! = 1 zero amplitude is initial estimate +! iphasetr = 1 phase transformation material model is used +! iforminp flag indicating that contact is switched on via the CONTACT +! option in the input file (as opposed to the case that contact +! is switched on internally due to cyclic symmetry or model +! section creation) +! ispecerror = a+10*b (only for spectrum response analysis with missing mass option) +! a=0 or a=1 (modal shape with non-zero shift) +! b=0 or b=1 (recover with new assembly of stiffness matrix) +! icsprg = set to 1 if spring elements present in model +! imol Control flag for molecualr diffusion pass +! imolt Permanent control flag for molecualr diffusion pass +! Note in coupled analysis imolt will remain as one, +! but imol will be zero in stress pass or thermal pass. +! idatafit = run Marc to fit parameters +! iharmpar = 1 if harmonic parameter option is used +! inclcase load case increment use for cyclic plasticity data fitting +! imultifreq flag to indicate how many harmonic magnetodynamic passes are computed in coupled +! magnetodynamic/thermal(/structural) analyses. +! 0 or 1 one pass 2 two passes 3 or more is not supported +! init_elas use elastic stress-strain law as the material tangent for +! the first cycle of an increment +! ifatig packed integer telling which fatigue mode is active +! 1 = elastomer +! 10 = stress-life +! 100 = strain-life +! = 2 strain-life fatigue +! iftgmat = 0 no fatigue material properties in the dat file +! = 1 fatigue material properties in the dat file +! nchybrid cycle count used for hybrid contact; meant to force an extra iteration +! if the overlap for a node in hybrid contact is too large +! ibuckle buckle parameter option is active +! iexpande set to 1 if expanded elements (248, 249, 250 or 251) are +! present, 0 otherwise +! +!*********************************************************************** +!$omp threadprivate(/marc_concom/) +!! diff --git a/src/Marc/include/concom2022.3 b/src/Marc/include/concom2022.3 new file mode 100644 index 000000000..2d4deaa34 --- /dev/null +++ b/src/Marc/include/concom2022.3 @@ -0,0 +1,466 @@ +! common block definition file taken from respective MSC.Marc release and reformated to free format +!*********************************************************************** +! +! File: concom.cmn +! +! MSC.Marc include file +! +integer & + iacous, iasmbl, iautth, ibear, icompl, iconj, icreep, ideva, idyn, idynt,& + ielas, ielcma, ielect, iform, ifour, iharm, ihcps, iheat, iheatt, ihresp,& + ijoule, ilem, ilnmom, iloren, inc, incext, incsub, ipass, iplres, ipois,& + ipoist, irpflo, ismall, ismalt, isoil, ispect, ispnow, istore, iswep, ithcrp,& + itherm, iupblg, iupdat, jacflg, jel, jparks, largst, lfond, loadup, loaduq,& + lodcor, lovl, lsub, magnet, ncycle, newtnt, newton, noshr, linear, ivscpl,& + icrpim, iradrt, ipshft, itshr, iangin, iupmdr, iconjf, jincfl, jpermg, jhour,& + isolvr, jritz, jtable, jshell, jdoubl, jform, jcentr, imini, kautth, iautof,& + ibukty, iassum, icnstd, icnstt, kmakmas, imethvp, iradrte, iradrtp, iupdate, iupdatp,& + ncycnt, marmen , idynme, ihavca, ispf, kmini, imixex, largtt, kdoela, iautofg,& + ipshftp, idntrc, ipore, jtablm, jtablc, isnecma, itrnspo, imsdif, jtrnspo, mcnear,& + imech, imecht, ielcmat, ielectt, magnett, imsdift, noplas, jtabls, jactch, jtablth,& + kgmsto , jpzo, ifricsh, iremkin, iremfor, ishearp, jspf, machining, jlshell, icompsol,& + iupblgfo, jcondir, nstcrp, nactive, ipassref, nstspnt, ibeart, icheckmpc, noline, icuring,& + ishrink, ioffsflg, isetoff, ioffsetm,iharmt, inc_incdat, iautspc, ibrake, icbush, istream_input,& + iprsinp, ivlsinp, ifirst_time,ipin_m, jgnstr_glb, imarc_return,iqvcinp, nqvceid, istpnx, imicro1,& + iaxisymm, jbreakglue,iglstif, jfastasm,iwear, iwearcf, imixmeth, ielcmadyn, idinout, igena_meth,& + magf_meth, non_assumed, iredoboudry, ioffsz0,icomplt, mesh_dual, iactrp, mgnewton, iusedens,igsigd0,& + iaem, icosim, inodels, nlharm, iampini, iphasetr, inonlcl, inonlct, iforminp,ispecerror,& + icsprg, imol, imolt, idatafit,iharmpar, inclcase, imultifreq,init_elas, ifatig, iftgmat,& + nchybrid, ibuckle, iexpande +dimension :: ideva(60) +integer num_concom +parameter(num_concom=263) +common/marc_concom/& + iacous, iasmbl, iautth, ibear, icompl, iconj, icreep, ideva, idyn, idynt,& + ielas, ielcma, ielect, iform, ifour, iharm, ihcps, iheat, iheatt, ihresp,& + ijoule, ilem, ilnmom, iloren, inc, incext, incsub, ipass, iplres, ipois,& + ipoist, irpflo, ismall, ismalt, isoil, ispect, ispnow, istore, iswep, ithcrp,& + itherm, iupblg, iupdat, jacflg, jel, jparks, largst, lfond, loadup, loaduq,& + lodcor, lovl, lsub, magnet, ncycle, newtnt, newton, noshr, linear, ivscpl,& + icrpim, iradrt, ipshft, itshr, iangin, iupmdr, iconjf, jincfl, jpermg, jhour,& + isolvr, jritz, jtable, jshell, jdoubl, jform, jcentr, imini, kautth, iautof,& + ibukty, iassum, icnstd, icnstt, kmakmas, imethvp, iradrte, iradrtp, iupdate, iupdatp,& + ncycnt, marmen, idynme, ihavca, ispf, kmini, imixex, largtt, kdoela, iautofg,& + ipshftp, idntrc, ipore, jtablm, jtablc, isnecma, itrnspo, imsdif, jtrnspo, mcnear,& + imech, imecht, ielcmat, ielectt, magnett, imsdift, noplas, jtabls, jactch, jtablth,& + kgmsto , jpzo, ifricsh, iremkin, iremfor, ishearp, jspf, machining, jlshell, icompsol,& + iupblgfo, jcondir, nstcrp, nactive, ipassref, nstspnt, ibeart, icheckmpc, noline, icuring,& + ishrink, ioffsflg, isetoff, ioffsetm,iharmt, inc_incdat, iautspc, ibrake, icbush, istream_input,& + iprsinp, ivlsinp, ifirst_time,ipin_m, jgnstr_glb, imarc_return,iqvcinp, nqvceid, istpnx, imicro1,& + iaxisymm, jbreakglue,iglstif, jfastasm,iwear, iwearcf, imixmeth, ielcmadyn, idinout, igena_meth,& + magf_meth, non_assumed, iredoboudry, ioffsz0,icomplt, mesh_dual, iactrp, mgnewton, iusedens,igsigd0,& + iaem, icosim, inodels, nlharm, iampini, iphasetr, inonlcl, inonlct, iforminp,ispecerror,& + icsprg, imol, imolt, idatafit,iharmpar, inclcase, imultifreq,init_elas, ifatig, iftgmat,& + nchybrid, ibuckle, iexpande +! +! comments of variables: +! +! iacous Control flag for acoustic analysis. Input data. +! iacous=1 modal acoustic analysis. +! iacous=2 harmonic acoustic-structural analysis. +! iasmbl Control flag to indicate that operator matrix should be +! recalculated. +! iautth Control flag for AUTO THERM option. +! ibear Control flag for bearing analysis. Input data. +! icompl Control variable to indicate that a complex analysis is +! being performed. Either a Harmonic analysis with damping, +! or a harmonic electro-magnetic analysis. Input data. +! iconj Flag for EBE conjugate gradient solver (=solver 1, retired) +! Also used for VKI iterative solver. +! icreep Control flag for creep analysis. Input data. +! ideva(60) - debug print out flag +! 1 print element stiffness matrices, mass matrix +! 2 output matrices used in tying +! 3 force the solution of a nonpositive definite matrix +! 4 print info of connections to each node +! 5 info of gap convergence, internal heat generated, contact +! touching and separation +! 6 nodal value array during rezoning +! 7 tying info in CONRAD GAP option, fluid element numbers in +! CHANNEL option +! 8 output incremental displacements in local coord. system +! 9 latent heat output +! 10 stress-strain in local coord. system +! 11 additional info on interlaminar stress +! 12 output right hand side and solution vector +! 13 info of CPU resources used and memory available on NT +! 14 info of mesh adaption process, 2D outline information +! info of penetration checking for remeshing +! save .fem files after afmesh3d meshing +! print local adaptivity info +! 15 surface energy balance flag +! 16 print info regarding pyrolysis +! 17 print info of "streamline topology" +! 18 print mesh data changes after remeshing +! 19 print material flow stress data read in from *.mat file +! if unit flag is on, print out flow stress after conversion +! 20 print information on table input +! 21 print out information regarding kinematic boundary conditions +! 22 print out information regarding dist loads, point loads, film +! and foundations +! 23 print out information about automatic domain decomposition +! 24 print out iteration information in SuperForm status report file +! 25 print out information for ablation +! 26 print out information for films - Table input +! 27 print out the tying forces +! 28 print out for CASI solver, convection, +! 29 DDM single file debug printout +! 30 print out cavity debug info +! 31 print out welding related info +! 32 prints categorized DDM memory usage +! 33 print out the cutting info regarding machining feature +! 34 print out the list of quantities which can be defined via a table +! and for each quantity the supported independent variables +! 35 print out detailed coupling region info +! 36 print out solver debug info level 1 (Least Detailed) +! 37 print out solver debug info level 1 (Medium Detailed) +! 38 print out solver debug info level 1 (Very Detailed) +! 39 print detailed memory allocation info +! 40 print out marc-adams debug info +! 41 output rezone mapping post file for debugging +! 42 output post file after calling oprofos() for debugging +! 43 debug printout for vcct +! 44 debug printout for progressive failure +! 45 print out automatically generated midside node coordinates (arecrd) +! 46 print out message about routine and location, where the ibort is raised (ibort_inc) +! 47 print out summary message of element variables on a +! group-basis after all the automatic changes have been +! made (em_ellibp) +! 48 Automatically generate check results based on max and min vals. +! These vals are stored in the checkr file, which is inserted +! into the *dat file by the generate_check_results script from /marc/tools +! 49 Automatically generate check results based on the real calculated values +! at the sppecified check result locations. +! These vals are stored in the checkr file, which is inserted +! into the *dat file by the update_check_results script from /marc/tools +! 50 generate a file containing the resistance or capacity matrix; +! this file can be used to compare results with a reference file +! 51 print out detailed information for segment-to-segment contact +! 52 print out detailed relative displacement information +! for uniaxial sliding contact +! 53 print out detailed sliding direction information for +! uniaxial sliding contact +! 54 print out detailed information for edges attached to a curve +! 55 print information related to viscoelasticity calculations +! 56 print out detailed information for element coloring for multithreading +! 57 print out extra overheads due to multi-threading. +! These overhead includes (i) time and (ii) memory. +! The memory report will be summed over all the children. +! 58 debug output for ELSTO usage +! 59 print out contact body forces and nodes in contact +! +! idyn Control flag for dynamics. Input data. +! 1 = eigenvalue extraction and / or modal superposition +! 2 = Newmark Beta and Single Step Houbolt (ssh with idynme=1) +! 3 = Houbolt +! 4 = Central difference +! 5 = Newer central difference +! idynt Copy of idyn at begining of increment +! ielas Control flag for ELASTIC analysis. Input data. +! Set by user or automatically turned on by Fourier option. +! Implies that each load case is treated separately. +! In Adaptive meshing analysis , forces re-analysis until +! convergence obtained. +! Also seriously misused to indicate no convergence. +! = 1 elastic option with fourier analysis +! = 2 elastic option without fourier analysis +! =-1 no convergence in recycles or max # increments reached +! Set to 1 if ELASTIC or SUBSTRUC parameter cards are used, +! or if fourier option is used. +! Then set to 2 if not fourier analysis. +! ielcma Control flag for electromagnetic analysis. Input data. +! ielcma = 1 Harmonic formulation +! ielcma = 2 Transient formulation +! ielect Control flag for electrostatic option. Input data. +! iform Control flag indicating that contact will be performed. +! ifour Control flag for Fourier analysis. +! 0 = Odd and even terms. +! 1 = symmetric (cosine) terms +! 2 = antisymmetric (sine) terms. +! iharm Control flag to indicate that a harmonic analysis will +! be performed. May change between passes. +! ihcps Control flag for coupled thermal - stress analysis. +! iheat Control flag for heat transfer analysis. Input data. +! iheatt Permanent control flag for heat transfer analysis. +! Note in coupled analysis iheatt will remain as one, +! but iheat will be zero in stress pass. +! ihresp Control flag to indicate to perform a harmonic subincrement. +! ijoule Control flag for Joule heating. +! ilem Control flag to determin which vector is to be transformed. +! Control flag to see where one is: +! ilem = 1 - elem.f +! ilem = 2 - initst.f +! ilem = 3 - pressr.f +! ilem = 3 - fstif.f +! ilem = 4 - jflux.f +! ilem = 4 - strass.f +! ilem = 5 - mass.f +! ilem = 5 - osolty.f +! ilnmom Control flag for soil - pore pressure calculation. Input data. +! ilnmom = 0 - perform only pore pressure calculation. +! = 1 - couples pore pressure - displacement analysis +! iloren Control flag for DeLorenzi J-Integral evaluation. Input data. +! inc Increment number. +! incext Control flag indicating that currently working on a +! subincrement. +! Could be due to harmonics , damping component (bearing), +! stiffness component (bearing), auto therm creep or +! old viscoplaticity +! incsub Sub-increment number. +! inonlcl control flag for nonlocal pass +! inonlct permanent control flag for nonlocal pass +! ipass Control flag for which part of coupled analysis. +! ipass = -1 - reset to base values +! ipass = 0 - do nothing +! ipass = 1 - stress part +! ipass = 2 - heat transfer part +! 3 - fluid pass +! 4 - joule heating pass +! 5 - pore pressure pass +! 6 - electrostatic pass +! 7 - magnetostatic pass +! 8 - electromagnetic pass +! 9 - diffusion pass +! ipass = 10 - nonlocal part +! iplres Flag indicating that either second matrix is stored. +! dynamic analysis - mass matrix +! heat transfer - specific heat matrix +! buckle - initial stress stiffness +! ipois Control flag indicating Poisson type analysis +! ipois = 1 for heat transfer +! = 1 for heat transfer part of coupled +! = 1 for bearing +! = 1 for electrostatic +! = 1 for magnetostatic +! = 1 for nonlocal part +! ipoist Permanent copy of ipois. In coupled analysis , ipois = 0 +! in stress portion, yet ipoist will still =1. +! irpflo global flag for rigid plastic flow analysis +! = 1 eularian formulation +! = 2 regular formulation; rigid material present in the analysis +! ismall control flag to indicate small displacement analysis. input data. +! ismall = 0 - large disp included. +! ismall = 1 - small displacement. +! the flag is changing between passes. +! ismalt permanent copy of ismall . in heat transfer portion of +! coupled analysis ismall =0 , but ismalt remains the same. +! isoil control flag indicating that soil / pore pressure +! calculation . input data. +! ispect control flag for response spectrum calculation. input data. +! ispnow control flag to indicate to perform a spectrum response +! calculation now. +! istore store stresses flag. +! istore = 0 in elem.f and if first pass of creep +! convergence checking in ogetst.f +! or harmonic analysis or thruc.f if not +! converged. +! iswep control flag for eigenvalue analysis. +! iswep=1 - go do extraction process +! ithcrp control flag for auto therm creep option. input data. +! itherm control flag for either temperature dependent material +! properties and/or thermal loads. +! iupblg control flag for follower force option. input data. +! iupdat control flag for update lagrange option for current element. +! jacflg control flag for lanczos iteration method. input data. +! jel control flag indicating that total load applied in +! increment, ignore previous solution. +! jel = 1 in increment 0 +! = 1 if elastic or fourier +! = 1 in subincrements with elastic and adaptive +! jparks control flag for j integral by parks method. input data. +! largst control flag for finite strain plasticity. input data. +! lfond control variable that indicates if doing elastic +! foundation or film calculation. influences whether +! this is volumetric or surface integration. +! loadup control flag that indicates that nonlinearity occurred +! during previous increment. +! loaduq control flag that indicates that nonlinearity occurred. +! lodcor control flag for switching on the residual load correction. +! notice in input stage lodcor=0 means no loadcor, +! after omarc lodcor=1 means no loadcor +! lovl control flag for determining which "overlay" is to +! be called from ellib. +! lovl = 1 omarc +! = 2 oaread +! = 3 opress +! = 4 oasemb +! = 5 osolty +! = 6 ogetst +! = 7 oscinc +! = 8 odynam +! = 9 opmesh +! = 10 omesh2 +! = 11 osetz +! = 12 oass +! = 13 oincdt +! = 14 oasmas +! = 15 ofluas +! = 16 ofluso +! = 17 oshtra +! = 18 ocass +! = 19 osoltc +! = 20 orezon +! = 21 otest +! = 22 oeigen +! lsub control variable to determine which part of element +! assembly function is being done. +! lsub = 1 - no longer used +! = 2 - beta* +! = 3 - cons* +! = 4 - ldef* +! = 5 - posw* +! = 6 - theta* +! = 7 - tmarx* +! = 8 - geom* +! magnet control flag for magnetostatic analysis. input data. +! ncycle cycle number. accumulated in osolty.f +! note first time through oasemb.f , ncycle = 0. +! newtnt control flag for permanent copy of newton. +! newton iteration type. input data. +! newton : = 1 full newton raphson +! 2 modified newton raphson +! 3 newton raphson with strain correct. +! 4 direct substitution +! 5 direct substitution followed by n.r. +! 6 direct substitution with line search +! 7 full newton raphson with secant initial stress +! 8 secant method +! 9 full newton raphson with line search +! noshr control flag for calculation interlaminar shears for +! elements 22,45, and 75. input data. +!ees +! +! jactch = 1 or 2 if elements are activated or deactivated +! = 3 if elements are adaptively remeshed or rezoned +! = 0 normally / reset to 0 when assembly is done +! ifricsh = 0 call to fricsh in otest not needed +! = 1 call to fricsh (nodal friction) in otest needed +! iremkin = 0 remove deactivated kinematic boundary conditions +! immediately - only in new input format (this is default) +! = 1 remove deactivated kinematic boundary conditions +! gradually - only in new input format +! iremfor = 0 remove force boundary conditions immediately - +! only in new input format (this is default) +! = 1 remove force boundary conditions gradually - +! only in new input format (this is default) +! ishearp set to 1 if shear panel elements are present in the model +! +! jspf = 0 not in spf loadcase +! > 0 in spf loadcase (jspf=1 during first increment) +! machining = 1 if the metal cutting feature is used, for memory allocation purpose +! = 0 (default) if no metal cutting feature required +! +! jlshell = 1 if there is a shell element in the mesh +! icompsol = 1 if there is a composite solid element in the mesh +! iupblgfo = 1 if follower force for point loads +! jcondir = 1 if contact priority option is used +! nstcrp = 0 (default) steady state creep flag (undocumented feature. +! if not 0, turns off special ncycle = 0 code in radial.f) +! nactive = number of active passes, if =1 then it's not a coupled analysis +! ipassref = reference ipass, if not in a multiphysics pass ipass=ipassref +! icheckmpc = value of mpc-check parameter option +! noline = set to 1 in osolty if no line seacrh should be done in ogetst +! icuring = set to 1 if the curing is included for the heat transfer analysis. +! ishrink = set to 1 if shrinkage strain is included for mechancial analysis. +! ioffsflg = 1 for small displacement beam/shell offsets +! = 2 for large displacement beam/shell offsets +! isetoff = 0 - do not apply beam/shell offsets +! = 1 - apply beam/shell offsets +! ioffsetm = min. value of offset flag +! iharmt = 1 global flag if a coupled analysis contains an harmonic pass +! inc_incdat = flag to record increment number of a new loadcase in incdat.f +! iautspc = flag for AutoSPC option +! ibrake = brake squeal in this increment +! icbush = set to 1 if cbush elements present in model +! istream_input = set to 1 for streaming input calling Marc as library +! iprsinp = set to 1 if pressure input, introduced so other variables +! such as h could be a function of pressure +! ivlsinp = set to 1 if velocity input, introduced so other variables +! such as h could be a function of velocity +! ipin_m = # of beam element with PIN flag +! jgnstr_glb = global control over pre or fast integrated composite shells +! imarc_return = Marc return flag for streaming input control +! iqvcimp = if non-zero, then the number of QVECT boundary conditions +! nqvceid = number of QVECT boundary conditions, where emisivity/absorbtion id entered +! istpnx = 1 if to stop at end of increment +! imicro1 = 1 if micro1 interface is used +! iaxisymm = set to 1 if axisymmetric analysis +! jbreakglue = set to 1 if breaking glued option is used +! iglstif = 1 if ddm and global stiffness matrix formed (sgi solver 6 or solver9) +! jfastasm = 1 do fast assembly using SuperForm code +! iwear = set to 1 if wear model, set to 2 if wear model and coordinates updated +! iwearcf = set to 1 to store nodal coefficient of friction for wear calculation +! imixmeth = set=1 then use nonlinear mixture material - allocate memory +! ielcmadyn = flag for magnetodynamics +! 0 - electromagnetics using newmark beta +! 1 - transient magnetics using backward euler +! idinout = flag to control if inside out elements should be deactivated +! igena_meth = 0 - generalized alpha parameters depend on whether or not contact +! is flagged (dynamic,7) +! 10 - generalized alpha parameters are optimized for a contact +! analysis (dynamic,8) +! 11 - generalized alpha parameters are optimized for an analysis +! without contact (dynamic,8) +! magf_meth = - Method to compute force in magnetostatic - structural +! = 1 - Virtual work method based on finite difference for the force computation +! = 2 - Maxwell stress tensor +! = 3 - Virtual work method based on local derivative for the force computation +! non_assumed = 1 no assumed strain formulation (forced) +! iredoboudry set to 1 if contact boundary needs to be recalculated +! ioffsz0 = 1 if composite are used with reference position.ne.0 +! icomplt = 1 global flag if a coupled analysis contains an complex pass +! mesh_dual = 1 two independent meshes are used in magnetodynamic/thermal/structural +! one for magnetodynamic and the other for the remaining passes +! iactrp = 1 in an analysis with global remeshing, include inactive +! rigid bodies on post file +! mgnewton = 1 Use full Newton Raphson iteration for magnetostatic pass +! +! iusedens > 0 if mass density is used in the analysis (dynamics, mass dependent loading) +! igsigd0 = 1 set varselem(igsigd) to zero in next oasemb +! iaem = 1 if marc is called from aem (0 - off - default) +! icosim = 1 if marc is used in co-simulation analysis with ADAMS using the CosimEngine +! = 2 if marc is used in co-simulation analysis with ADAMS using the ACSI interface +! = 3 if marc is used in co-simulation analysis with scFLOW using the CosimEngine +! = 4 if marc is used in co-simulation analysis with scFLOW and ADAMS using the CosimEngine +! inodels = 1 nodal integration elements 239/240/241 present +! nlharm = 0 harmonic subincrements are linear +! = 1 harmonic subincrements are nonlinear +! iampini = 0 amplitude of previous harmonic subinc is initial estimate (default) +! = 1 zero amplitude is initial estimate +! iphasetr = 1 phase transformation material model is used +! iforminp flag indicating that contact is switched on via the CONTACT +! option in the input file (as opposed to the case that contact +! is switched on internally due to cyclic symmetry or model +! section creation) +! ispecerror = a+10*b (only for spectrum response analysis with missing mass option) +! a=0 or a=1 (modal shape with non-zero shift) +! b=0 or b=1 (recover with new assembly of stiffness matrix) +! icsprg = set to 1 if spring elements present in model +! imol Control flag for molecualr diffusion pass +! imolt Permanent control flag for molecualr diffusion pass +! Note in coupled analysis imolt will remain as one, +! but imol will be zero in stress pass or thermal pass. +! idatafit = run Marc to fit parameters +! iharmpar = 1 if harmonic parameter option is used +! inclcase load case increment use for cyclic plasticity data fitting +! imultifreq flag to indicate how many harmonic magnetodynamic passes are computed in coupled +! magnetodynamic/thermal(/structural) analyses. +! 0 or 1 one pass 2 two passes 3 or more is not supported +! init_elas use elastic stress-strain law as the material tangent for +! the first cycle of an increment +! ifatig packed integer telling which fatigue mode is active +! 1 = elastomer +! 10 = stress-life +! 100 = strain-life +! = 2 strain-life fatigue +! iftgmat = 0 no fatigue material properties in the dat file +! = 1 fatigue material properties in the dat file +! nchybrid cycle count used for hybrid contact; meant to force an extra iteration +! if the overlap for a node in hybrid contact is too large +! ibuckle buckle parameter option is active +! iexpande set to 1 if expanded elements (248, 249, 250 or 251) are +! present, 0 otherwise +! +!*********************************************************************** +!$omp threadprivate(/marc_concom/) +!! diff --git a/src/Marc/include/concom2022.4 b/src/Marc/include/concom2022.4 new file mode 100644 index 000000000..2d4deaa34 --- /dev/null +++ b/src/Marc/include/concom2022.4 @@ -0,0 +1,466 @@ +! common block definition file taken from respective MSC.Marc release and reformated to free format +!*********************************************************************** +! +! File: concom.cmn +! +! MSC.Marc include file +! +integer & + iacous, iasmbl, iautth, ibear, icompl, iconj, icreep, ideva, idyn, idynt,& + ielas, ielcma, ielect, iform, ifour, iharm, ihcps, iheat, iheatt, ihresp,& + ijoule, ilem, ilnmom, iloren, inc, incext, incsub, ipass, iplres, ipois,& + ipoist, irpflo, ismall, ismalt, isoil, ispect, ispnow, istore, iswep, ithcrp,& + itherm, iupblg, iupdat, jacflg, jel, jparks, largst, lfond, loadup, loaduq,& + lodcor, lovl, lsub, magnet, ncycle, newtnt, newton, noshr, linear, ivscpl,& + icrpim, iradrt, ipshft, itshr, iangin, iupmdr, iconjf, jincfl, jpermg, jhour,& + isolvr, jritz, jtable, jshell, jdoubl, jform, jcentr, imini, kautth, iautof,& + ibukty, iassum, icnstd, icnstt, kmakmas, imethvp, iradrte, iradrtp, iupdate, iupdatp,& + ncycnt, marmen , idynme, ihavca, ispf, kmini, imixex, largtt, kdoela, iautofg,& + ipshftp, idntrc, ipore, jtablm, jtablc, isnecma, itrnspo, imsdif, jtrnspo, mcnear,& + imech, imecht, ielcmat, ielectt, magnett, imsdift, noplas, jtabls, jactch, jtablth,& + kgmsto , jpzo, ifricsh, iremkin, iremfor, ishearp, jspf, machining, jlshell, icompsol,& + iupblgfo, jcondir, nstcrp, nactive, ipassref, nstspnt, ibeart, icheckmpc, noline, icuring,& + ishrink, ioffsflg, isetoff, ioffsetm,iharmt, inc_incdat, iautspc, ibrake, icbush, istream_input,& + iprsinp, ivlsinp, ifirst_time,ipin_m, jgnstr_glb, imarc_return,iqvcinp, nqvceid, istpnx, imicro1,& + iaxisymm, jbreakglue,iglstif, jfastasm,iwear, iwearcf, imixmeth, ielcmadyn, idinout, igena_meth,& + magf_meth, non_assumed, iredoboudry, ioffsz0,icomplt, mesh_dual, iactrp, mgnewton, iusedens,igsigd0,& + iaem, icosim, inodels, nlharm, iampini, iphasetr, inonlcl, inonlct, iforminp,ispecerror,& + icsprg, imol, imolt, idatafit,iharmpar, inclcase, imultifreq,init_elas, ifatig, iftgmat,& + nchybrid, ibuckle, iexpande +dimension :: ideva(60) +integer num_concom +parameter(num_concom=263) +common/marc_concom/& + iacous, iasmbl, iautth, ibear, icompl, iconj, icreep, ideva, idyn, idynt,& + ielas, ielcma, ielect, iform, ifour, iharm, ihcps, iheat, iheatt, ihresp,& + ijoule, ilem, ilnmom, iloren, inc, incext, incsub, ipass, iplres, ipois,& + ipoist, irpflo, ismall, ismalt, isoil, ispect, ispnow, istore, iswep, ithcrp,& + itherm, iupblg, iupdat, jacflg, jel, jparks, largst, lfond, loadup, loaduq,& + lodcor, lovl, lsub, magnet, ncycle, newtnt, newton, noshr, linear, ivscpl,& + icrpim, iradrt, ipshft, itshr, iangin, iupmdr, iconjf, jincfl, jpermg, jhour,& + isolvr, jritz, jtable, jshell, jdoubl, jform, jcentr, imini, kautth, iautof,& + ibukty, iassum, icnstd, icnstt, kmakmas, imethvp, iradrte, iradrtp, iupdate, iupdatp,& + ncycnt, marmen, idynme, ihavca, ispf, kmini, imixex, largtt, kdoela, iautofg,& + ipshftp, idntrc, ipore, jtablm, jtablc, isnecma, itrnspo, imsdif, jtrnspo, mcnear,& + imech, imecht, ielcmat, ielectt, magnett, imsdift, noplas, jtabls, jactch, jtablth,& + kgmsto , jpzo, ifricsh, iremkin, iremfor, ishearp, jspf, machining, jlshell, icompsol,& + iupblgfo, jcondir, nstcrp, nactive, ipassref, nstspnt, ibeart, icheckmpc, noline, icuring,& + ishrink, ioffsflg, isetoff, ioffsetm,iharmt, inc_incdat, iautspc, ibrake, icbush, istream_input,& + iprsinp, ivlsinp, ifirst_time,ipin_m, jgnstr_glb, imarc_return,iqvcinp, nqvceid, istpnx, imicro1,& + iaxisymm, jbreakglue,iglstif, jfastasm,iwear, iwearcf, imixmeth, ielcmadyn, idinout, igena_meth,& + magf_meth, non_assumed, iredoboudry, ioffsz0,icomplt, mesh_dual, iactrp, mgnewton, iusedens,igsigd0,& + iaem, icosim, inodels, nlharm, iampini, iphasetr, inonlcl, inonlct, iforminp,ispecerror,& + icsprg, imol, imolt, idatafit,iharmpar, inclcase, imultifreq,init_elas, ifatig, iftgmat,& + nchybrid, ibuckle, iexpande +! +! comments of variables: +! +! iacous Control flag for acoustic analysis. Input data. +! iacous=1 modal acoustic analysis. +! iacous=2 harmonic acoustic-structural analysis. +! iasmbl Control flag to indicate that operator matrix should be +! recalculated. +! iautth Control flag for AUTO THERM option. +! ibear Control flag for bearing analysis. Input data. +! icompl Control variable to indicate that a complex analysis is +! being performed. Either a Harmonic analysis with damping, +! or a harmonic electro-magnetic analysis. Input data. +! iconj Flag for EBE conjugate gradient solver (=solver 1, retired) +! Also used for VKI iterative solver. +! icreep Control flag for creep analysis. Input data. +! ideva(60) - debug print out flag +! 1 print element stiffness matrices, mass matrix +! 2 output matrices used in tying +! 3 force the solution of a nonpositive definite matrix +! 4 print info of connections to each node +! 5 info of gap convergence, internal heat generated, contact +! touching and separation +! 6 nodal value array during rezoning +! 7 tying info in CONRAD GAP option, fluid element numbers in +! CHANNEL option +! 8 output incremental displacements in local coord. system +! 9 latent heat output +! 10 stress-strain in local coord. system +! 11 additional info on interlaminar stress +! 12 output right hand side and solution vector +! 13 info of CPU resources used and memory available on NT +! 14 info of mesh adaption process, 2D outline information +! info of penetration checking for remeshing +! save .fem files after afmesh3d meshing +! print local adaptivity info +! 15 surface energy balance flag +! 16 print info regarding pyrolysis +! 17 print info of "streamline topology" +! 18 print mesh data changes after remeshing +! 19 print material flow stress data read in from *.mat file +! if unit flag is on, print out flow stress after conversion +! 20 print information on table input +! 21 print out information regarding kinematic boundary conditions +! 22 print out information regarding dist loads, point loads, film +! and foundations +! 23 print out information about automatic domain decomposition +! 24 print out iteration information in SuperForm status report file +! 25 print out information for ablation +! 26 print out information for films - Table input +! 27 print out the tying forces +! 28 print out for CASI solver, convection, +! 29 DDM single file debug printout +! 30 print out cavity debug info +! 31 print out welding related info +! 32 prints categorized DDM memory usage +! 33 print out the cutting info regarding machining feature +! 34 print out the list of quantities which can be defined via a table +! and for each quantity the supported independent variables +! 35 print out detailed coupling region info +! 36 print out solver debug info level 1 (Least Detailed) +! 37 print out solver debug info level 1 (Medium Detailed) +! 38 print out solver debug info level 1 (Very Detailed) +! 39 print detailed memory allocation info +! 40 print out marc-adams debug info +! 41 output rezone mapping post file for debugging +! 42 output post file after calling oprofos() for debugging +! 43 debug printout for vcct +! 44 debug printout for progressive failure +! 45 print out automatically generated midside node coordinates (arecrd) +! 46 print out message about routine and location, where the ibort is raised (ibort_inc) +! 47 print out summary message of element variables on a +! group-basis after all the automatic changes have been +! made (em_ellibp) +! 48 Automatically generate check results based on max and min vals. +! These vals are stored in the checkr file, which is inserted +! into the *dat file by the generate_check_results script from /marc/tools +! 49 Automatically generate check results based on the real calculated values +! at the sppecified check result locations. +! These vals are stored in the checkr file, which is inserted +! into the *dat file by the update_check_results script from /marc/tools +! 50 generate a file containing the resistance or capacity matrix; +! this file can be used to compare results with a reference file +! 51 print out detailed information for segment-to-segment contact +! 52 print out detailed relative displacement information +! for uniaxial sliding contact +! 53 print out detailed sliding direction information for +! uniaxial sliding contact +! 54 print out detailed information for edges attached to a curve +! 55 print information related to viscoelasticity calculations +! 56 print out detailed information for element coloring for multithreading +! 57 print out extra overheads due to multi-threading. +! These overhead includes (i) time and (ii) memory. +! The memory report will be summed over all the children. +! 58 debug output for ELSTO usage +! 59 print out contact body forces and nodes in contact +! +! idyn Control flag for dynamics. Input data. +! 1 = eigenvalue extraction and / or modal superposition +! 2 = Newmark Beta and Single Step Houbolt (ssh with idynme=1) +! 3 = Houbolt +! 4 = Central difference +! 5 = Newer central difference +! idynt Copy of idyn at begining of increment +! ielas Control flag for ELASTIC analysis. Input data. +! Set by user or automatically turned on by Fourier option. +! Implies that each load case is treated separately. +! In Adaptive meshing analysis , forces re-analysis until +! convergence obtained. +! Also seriously misused to indicate no convergence. +! = 1 elastic option with fourier analysis +! = 2 elastic option without fourier analysis +! =-1 no convergence in recycles or max # increments reached +! Set to 1 if ELASTIC or SUBSTRUC parameter cards are used, +! or if fourier option is used. +! Then set to 2 if not fourier analysis. +! ielcma Control flag for electromagnetic analysis. Input data. +! ielcma = 1 Harmonic formulation +! ielcma = 2 Transient formulation +! ielect Control flag for electrostatic option. Input data. +! iform Control flag indicating that contact will be performed. +! ifour Control flag for Fourier analysis. +! 0 = Odd and even terms. +! 1 = symmetric (cosine) terms +! 2 = antisymmetric (sine) terms. +! iharm Control flag to indicate that a harmonic analysis will +! be performed. May change between passes. +! ihcps Control flag for coupled thermal - stress analysis. +! iheat Control flag for heat transfer analysis. Input data. +! iheatt Permanent control flag for heat transfer analysis. +! Note in coupled analysis iheatt will remain as one, +! but iheat will be zero in stress pass. +! ihresp Control flag to indicate to perform a harmonic subincrement. +! ijoule Control flag for Joule heating. +! ilem Control flag to determin which vector is to be transformed. +! Control flag to see where one is: +! ilem = 1 - elem.f +! ilem = 2 - initst.f +! ilem = 3 - pressr.f +! ilem = 3 - fstif.f +! ilem = 4 - jflux.f +! ilem = 4 - strass.f +! ilem = 5 - mass.f +! ilem = 5 - osolty.f +! ilnmom Control flag for soil - pore pressure calculation. Input data. +! ilnmom = 0 - perform only pore pressure calculation. +! = 1 - couples pore pressure - displacement analysis +! iloren Control flag for DeLorenzi J-Integral evaluation. Input data. +! inc Increment number. +! incext Control flag indicating that currently working on a +! subincrement. +! Could be due to harmonics , damping component (bearing), +! stiffness component (bearing), auto therm creep or +! old viscoplaticity +! incsub Sub-increment number. +! inonlcl control flag for nonlocal pass +! inonlct permanent control flag for nonlocal pass +! ipass Control flag for which part of coupled analysis. +! ipass = -1 - reset to base values +! ipass = 0 - do nothing +! ipass = 1 - stress part +! ipass = 2 - heat transfer part +! 3 - fluid pass +! 4 - joule heating pass +! 5 - pore pressure pass +! 6 - electrostatic pass +! 7 - magnetostatic pass +! 8 - electromagnetic pass +! 9 - diffusion pass +! ipass = 10 - nonlocal part +! iplres Flag indicating that either second matrix is stored. +! dynamic analysis - mass matrix +! heat transfer - specific heat matrix +! buckle - initial stress stiffness +! ipois Control flag indicating Poisson type analysis +! ipois = 1 for heat transfer +! = 1 for heat transfer part of coupled +! = 1 for bearing +! = 1 for electrostatic +! = 1 for magnetostatic +! = 1 for nonlocal part +! ipoist Permanent copy of ipois. In coupled analysis , ipois = 0 +! in stress portion, yet ipoist will still =1. +! irpflo global flag for rigid plastic flow analysis +! = 1 eularian formulation +! = 2 regular formulation; rigid material present in the analysis +! ismall control flag to indicate small displacement analysis. input data. +! ismall = 0 - large disp included. +! ismall = 1 - small displacement. +! the flag is changing between passes. +! ismalt permanent copy of ismall . in heat transfer portion of +! coupled analysis ismall =0 , but ismalt remains the same. +! isoil control flag indicating that soil / pore pressure +! calculation . input data. +! ispect control flag for response spectrum calculation. input data. +! ispnow control flag to indicate to perform a spectrum response +! calculation now. +! istore store stresses flag. +! istore = 0 in elem.f and if first pass of creep +! convergence checking in ogetst.f +! or harmonic analysis or thruc.f if not +! converged. +! iswep control flag for eigenvalue analysis. +! iswep=1 - go do extraction process +! ithcrp control flag for auto therm creep option. input data. +! itherm control flag for either temperature dependent material +! properties and/or thermal loads. +! iupblg control flag for follower force option. input data. +! iupdat control flag for update lagrange option for current element. +! jacflg control flag for lanczos iteration method. input data. +! jel control flag indicating that total load applied in +! increment, ignore previous solution. +! jel = 1 in increment 0 +! = 1 if elastic or fourier +! = 1 in subincrements with elastic and adaptive +! jparks control flag for j integral by parks method. input data. +! largst control flag for finite strain plasticity. input data. +! lfond control variable that indicates if doing elastic +! foundation or film calculation. influences whether +! this is volumetric or surface integration. +! loadup control flag that indicates that nonlinearity occurred +! during previous increment. +! loaduq control flag that indicates that nonlinearity occurred. +! lodcor control flag for switching on the residual load correction. +! notice in input stage lodcor=0 means no loadcor, +! after omarc lodcor=1 means no loadcor +! lovl control flag for determining which "overlay" is to +! be called from ellib. +! lovl = 1 omarc +! = 2 oaread +! = 3 opress +! = 4 oasemb +! = 5 osolty +! = 6 ogetst +! = 7 oscinc +! = 8 odynam +! = 9 opmesh +! = 10 omesh2 +! = 11 osetz +! = 12 oass +! = 13 oincdt +! = 14 oasmas +! = 15 ofluas +! = 16 ofluso +! = 17 oshtra +! = 18 ocass +! = 19 osoltc +! = 20 orezon +! = 21 otest +! = 22 oeigen +! lsub control variable to determine which part of element +! assembly function is being done. +! lsub = 1 - no longer used +! = 2 - beta* +! = 3 - cons* +! = 4 - ldef* +! = 5 - posw* +! = 6 - theta* +! = 7 - tmarx* +! = 8 - geom* +! magnet control flag for magnetostatic analysis. input data. +! ncycle cycle number. accumulated in osolty.f +! note first time through oasemb.f , ncycle = 0. +! newtnt control flag for permanent copy of newton. +! newton iteration type. input data. +! newton : = 1 full newton raphson +! 2 modified newton raphson +! 3 newton raphson with strain correct. +! 4 direct substitution +! 5 direct substitution followed by n.r. +! 6 direct substitution with line search +! 7 full newton raphson with secant initial stress +! 8 secant method +! 9 full newton raphson with line search +! noshr control flag for calculation interlaminar shears for +! elements 22,45, and 75. input data. +!ees +! +! jactch = 1 or 2 if elements are activated or deactivated +! = 3 if elements are adaptively remeshed or rezoned +! = 0 normally / reset to 0 when assembly is done +! ifricsh = 0 call to fricsh in otest not needed +! = 1 call to fricsh (nodal friction) in otest needed +! iremkin = 0 remove deactivated kinematic boundary conditions +! immediately - only in new input format (this is default) +! = 1 remove deactivated kinematic boundary conditions +! gradually - only in new input format +! iremfor = 0 remove force boundary conditions immediately - +! only in new input format (this is default) +! = 1 remove force boundary conditions gradually - +! only in new input format (this is default) +! ishearp set to 1 if shear panel elements are present in the model +! +! jspf = 0 not in spf loadcase +! > 0 in spf loadcase (jspf=1 during first increment) +! machining = 1 if the metal cutting feature is used, for memory allocation purpose +! = 0 (default) if no metal cutting feature required +! +! jlshell = 1 if there is a shell element in the mesh +! icompsol = 1 if there is a composite solid element in the mesh +! iupblgfo = 1 if follower force for point loads +! jcondir = 1 if contact priority option is used +! nstcrp = 0 (default) steady state creep flag (undocumented feature. +! if not 0, turns off special ncycle = 0 code in radial.f) +! nactive = number of active passes, if =1 then it's not a coupled analysis +! ipassref = reference ipass, if not in a multiphysics pass ipass=ipassref +! icheckmpc = value of mpc-check parameter option +! noline = set to 1 in osolty if no line seacrh should be done in ogetst +! icuring = set to 1 if the curing is included for the heat transfer analysis. +! ishrink = set to 1 if shrinkage strain is included for mechancial analysis. +! ioffsflg = 1 for small displacement beam/shell offsets +! = 2 for large displacement beam/shell offsets +! isetoff = 0 - do not apply beam/shell offsets +! = 1 - apply beam/shell offsets +! ioffsetm = min. value of offset flag +! iharmt = 1 global flag if a coupled analysis contains an harmonic pass +! inc_incdat = flag to record increment number of a new loadcase in incdat.f +! iautspc = flag for AutoSPC option +! ibrake = brake squeal in this increment +! icbush = set to 1 if cbush elements present in model +! istream_input = set to 1 for streaming input calling Marc as library +! iprsinp = set to 1 if pressure input, introduced so other variables +! such as h could be a function of pressure +! ivlsinp = set to 1 if velocity input, introduced so other variables +! such as h could be a function of velocity +! ipin_m = # of beam element with PIN flag +! jgnstr_glb = global control over pre or fast integrated composite shells +! imarc_return = Marc return flag for streaming input control +! iqvcimp = if non-zero, then the number of QVECT boundary conditions +! nqvceid = number of QVECT boundary conditions, where emisivity/absorbtion id entered +! istpnx = 1 if to stop at end of increment +! imicro1 = 1 if micro1 interface is used +! iaxisymm = set to 1 if axisymmetric analysis +! jbreakglue = set to 1 if breaking glued option is used +! iglstif = 1 if ddm and global stiffness matrix formed (sgi solver 6 or solver9) +! jfastasm = 1 do fast assembly using SuperForm code +! iwear = set to 1 if wear model, set to 2 if wear model and coordinates updated +! iwearcf = set to 1 to store nodal coefficient of friction for wear calculation +! imixmeth = set=1 then use nonlinear mixture material - allocate memory +! ielcmadyn = flag for magnetodynamics +! 0 - electromagnetics using newmark beta +! 1 - transient magnetics using backward euler +! idinout = flag to control if inside out elements should be deactivated +! igena_meth = 0 - generalized alpha parameters depend on whether or not contact +! is flagged (dynamic,7) +! 10 - generalized alpha parameters are optimized for a contact +! analysis (dynamic,8) +! 11 - generalized alpha parameters are optimized for an analysis +! without contact (dynamic,8) +! magf_meth = - Method to compute force in magnetostatic - structural +! = 1 - Virtual work method based on finite difference for the force computation +! = 2 - Maxwell stress tensor +! = 3 - Virtual work method based on local derivative for the force computation +! non_assumed = 1 no assumed strain formulation (forced) +! iredoboudry set to 1 if contact boundary needs to be recalculated +! ioffsz0 = 1 if composite are used with reference position.ne.0 +! icomplt = 1 global flag if a coupled analysis contains an complex pass +! mesh_dual = 1 two independent meshes are used in magnetodynamic/thermal/structural +! one for magnetodynamic and the other for the remaining passes +! iactrp = 1 in an analysis with global remeshing, include inactive +! rigid bodies on post file +! mgnewton = 1 Use full Newton Raphson iteration for magnetostatic pass +! +! iusedens > 0 if mass density is used in the analysis (dynamics, mass dependent loading) +! igsigd0 = 1 set varselem(igsigd) to zero in next oasemb +! iaem = 1 if marc is called from aem (0 - off - default) +! icosim = 1 if marc is used in co-simulation analysis with ADAMS using the CosimEngine +! = 2 if marc is used in co-simulation analysis with ADAMS using the ACSI interface +! = 3 if marc is used in co-simulation analysis with scFLOW using the CosimEngine +! = 4 if marc is used in co-simulation analysis with scFLOW and ADAMS using the CosimEngine +! inodels = 1 nodal integration elements 239/240/241 present +! nlharm = 0 harmonic subincrements are linear +! = 1 harmonic subincrements are nonlinear +! iampini = 0 amplitude of previous harmonic subinc is initial estimate (default) +! = 1 zero amplitude is initial estimate +! iphasetr = 1 phase transformation material model is used +! iforminp flag indicating that contact is switched on via the CONTACT +! option in the input file (as opposed to the case that contact +! is switched on internally due to cyclic symmetry or model +! section creation) +! ispecerror = a+10*b (only for spectrum response analysis with missing mass option) +! a=0 or a=1 (modal shape with non-zero shift) +! b=0 or b=1 (recover with new assembly of stiffness matrix) +! icsprg = set to 1 if spring elements present in model +! imol Control flag for molecualr diffusion pass +! imolt Permanent control flag for molecualr diffusion pass +! Note in coupled analysis imolt will remain as one, +! but imol will be zero in stress pass or thermal pass. +! idatafit = run Marc to fit parameters +! iharmpar = 1 if harmonic parameter option is used +! inclcase load case increment use for cyclic plasticity data fitting +! imultifreq flag to indicate how many harmonic magnetodynamic passes are computed in coupled +! magnetodynamic/thermal(/structural) analyses. +! 0 or 1 one pass 2 two passes 3 or more is not supported +! init_elas use elastic stress-strain law as the material tangent for +! the first cycle of an increment +! ifatig packed integer telling which fatigue mode is active +! 1 = elastomer +! 10 = stress-life +! 100 = strain-life +! = 2 strain-life fatigue +! iftgmat = 0 no fatigue material properties in the dat file +! = 1 fatigue material properties in the dat file +! nchybrid cycle count used for hybrid contact; meant to force an extra iteration +! if the overlap for a node in hybrid contact is too large +! ibuckle buckle parameter option is active +! iexpande set to 1 if expanded elements (248, 249, 250 or 251) are +! present, 0 otherwise +! +!*********************************************************************** +!$omp threadprivate(/marc_concom/) +!! diff --git a/src/Marc/include/creeps2022.2 b/src/Marc/include/creeps2022.2 new file mode 100644 index 000000000..b35d2b6bf --- /dev/null +++ b/src/Marc/include/creeps2022.2 @@ -0,0 +1,73 @@ +! common block definition file taken from respective MSC.Marc release and reformated to free format +!*********************************************************************** +! +! File: creeps.cmn +! +! MSC.Marc include file +! +real(pReal) cptim,timinc,timinc_p,timinc_s,timincm,timinc_a,timinc_b +integer icfte,icfst,icfeq,icftm,icetem,mcreep,jcreep,icpa,icftmp,icfstr,& + icfqcp,icfcpm,icrppr,icrcha,icpb,iicpmt,iicpa +real(pReal) time_beg_lcase,time_beg_inc,fractol,time_beg_pst +real(pReal) fraction_donn,timinc_ol2 +! +integer num_creepsr,num_creepsi,num_creeps2r,ncrp_arry +parameter(num_creepsr=7) +parameter(num_creepsi=17) +parameter(num_creeps2r=6) +parameter(ncrp_arry=7) +common/marc_creeps/cptim,timinc,timinc_p,timinc_s,timincm,timinc_a,timinc_b,icfte,icfst,& + icfeq,icftm,icetem,mcreep,jcreep,icpa,icftmp,icfstr,icfqcp,icfcpm,icrppr,icrcha,icpb,iicpmt,iicpa +common/marc_creeps2/time_beg_lcase,time_beg_inc,fractol,time_beg_pst,fraction_donn,timinc_ol2 +! +! cptim Total time at begining of increment. +! timinc Incremental time for this step. +! icfte Local copy number of slopes of creep strain rate function +! versus temperature. Is -1 if exponent law used. +! icfst Local copy number of slopes of creep strain rate function +! versus equivalent stress. Is -1 if exponent law used. +! icfeq Local copy number of slopes of creep strain rate function +! versus equivalent strain. Is -1 if exponent law used. +! icftm Local copy number of slopes of creep strain rate function +! versus time. Is -1 if exponent law used. +! icetem Element number that needs to be checked for creep convergence +! or, if negative, the number of elements that need to +! be checked. In the latter case the elements to check +! are stored in ielcp. +! mcreep Maximum nuber of iterations for explicit creep. +! jcreep Counter of number of iterations for explicit creep +! procedure. jcreep must be .le. mcreep +! icpa(1-6) Pointer to constants in creep strain rate expression. +! icftmp Pointer to temperature dependent creep strain rate data. +! icfstr Pointer to equivalent stress dependent creep strain rate data. +! icfqcp Pointer to equivalent creep strain dependent creep strain +! rate data. +! icfcpm Pointer to equivalent creep strain rate dependent +! creep strain rate data. +! icrppr Permanent copy of icreep +! icrcha Control flag for creep convergence checking , if set to +! 1 then testing on absolute change in stress and creep +! strain, not relative testing. Input data. +! icpb(1-4) Pointer to storage of material id cross reference numbers. +! iicpmt creep law type ID +! =1 - power law +! =2 - solder +! =3 - steady-creep +! =4 - hyperbolic steady-creep +! iicpa Pointer to table IDs for constants in creep strain rate +! expression +! +! +! time_beg_lcase time at the beginning of the current load case +! time_beg_inc time at the beginning of the current increment +! fractol fraction of loadcase or increment time when we +! consider it to be finished +! time_beg_pst time corresponding to first increment to be +! read in from thermal post file for auto step +! +! timinc_old Time step of the previous increment +! +!*********************************************************************** +!!$omp threadprivate(/marc_creeps/) +!!$omp threadprivate(/marc_creeps2/) +!! diff --git a/src/Marc/include/creeps2022.3 b/src/Marc/include/creeps2022.3 new file mode 100644 index 000000000..b35d2b6bf --- /dev/null +++ b/src/Marc/include/creeps2022.3 @@ -0,0 +1,73 @@ +! common block definition file taken from respective MSC.Marc release and reformated to free format +!*********************************************************************** +! +! File: creeps.cmn +! +! MSC.Marc include file +! +real(pReal) cptim,timinc,timinc_p,timinc_s,timincm,timinc_a,timinc_b +integer icfte,icfst,icfeq,icftm,icetem,mcreep,jcreep,icpa,icftmp,icfstr,& + icfqcp,icfcpm,icrppr,icrcha,icpb,iicpmt,iicpa +real(pReal) time_beg_lcase,time_beg_inc,fractol,time_beg_pst +real(pReal) fraction_donn,timinc_ol2 +! +integer num_creepsr,num_creepsi,num_creeps2r,ncrp_arry +parameter(num_creepsr=7) +parameter(num_creepsi=17) +parameter(num_creeps2r=6) +parameter(ncrp_arry=7) +common/marc_creeps/cptim,timinc,timinc_p,timinc_s,timincm,timinc_a,timinc_b,icfte,icfst,& + icfeq,icftm,icetem,mcreep,jcreep,icpa,icftmp,icfstr,icfqcp,icfcpm,icrppr,icrcha,icpb,iicpmt,iicpa +common/marc_creeps2/time_beg_lcase,time_beg_inc,fractol,time_beg_pst,fraction_donn,timinc_ol2 +! +! cptim Total time at begining of increment. +! timinc Incremental time for this step. +! icfte Local copy number of slopes of creep strain rate function +! versus temperature. Is -1 if exponent law used. +! icfst Local copy number of slopes of creep strain rate function +! versus equivalent stress. Is -1 if exponent law used. +! icfeq Local copy number of slopes of creep strain rate function +! versus equivalent strain. Is -1 if exponent law used. +! icftm Local copy number of slopes of creep strain rate function +! versus time. Is -1 if exponent law used. +! icetem Element number that needs to be checked for creep convergence +! or, if negative, the number of elements that need to +! be checked. In the latter case the elements to check +! are stored in ielcp. +! mcreep Maximum nuber of iterations for explicit creep. +! jcreep Counter of number of iterations for explicit creep +! procedure. jcreep must be .le. mcreep +! icpa(1-6) Pointer to constants in creep strain rate expression. +! icftmp Pointer to temperature dependent creep strain rate data. +! icfstr Pointer to equivalent stress dependent creep strain rate data. +! icfqcp Pointer to equivalent creep strain dependent creep strain +! rate data. +! icfcpm Pointer to equivalent creep strain rate dependent +! creep strain rate data. +! icrppr Permanent copy of icreep +! icrcha Control flag for creep convergence checking , if set to +! 1 then testing on absolute change in stress and creep +! strain, not relative testing. Input data. +! icpb(1-4) Pointer to storage of material id cross reference numbers. +! iicpmt creep law type ID +! =1 - power law +! =2 - solder +! =3 - steady-creep +! =4 - hyperbolic steady-creep +! iicpa Pointer to table IDs for constants in creep strain rate +! expression +! +! +! time_beg_lcase time at the beginning of the current load case +! time_beg_inc time at the beginning of the current increment +! fractol fraction of loadcase or increment time when we +! consider it to be finished +! time_beg_pst time corresponding to first increment to be +! read in from thermal post file for auto step +! +! timinc_old Time step of the previous increment +! +!*********************************************************************** +!!$omp threadprivate(/marc_creeps/) +!!$omp threadprivate(/marc_creeps2/) +!! diff --git a/src/Marc/include/creeps2022.4 b/src/Marc/include/creeps2022.4 new file mode 100644 index 000000000..b35d2b6bf --- /dev/null +++ b/src/Marc/include/creeps2022.4 @@ -0,0 +1,73 @@ +! common block definition file taken from respective MSC.Marc release and reformated to free format +!*********************************************************************** +! +! File: creeps.cmn +! +! MSC.Marc include file +! +real(pReal) cptim,timinc,timinc_p,timinc_s,timincm,timinc_a,timinc_b +integer icfte,icfst,icfeq,icftm,icetem,mcreep,jcreep,icpa,icftmp,icfstr,& + icfqcp,icfcpm,icrppr,icrcha,icpb,iicpmt,iicpa +real(pReal) time_beg_lcase,time_beg_inc,fractol,time_beg_pst +real(pReal) fraction_donn,timinc_ol2 +! +integer num_creepsr,num_creepsi,num_creeps2r,ncrp_arry +parameter(num_creepsr=7) +parameter(num_creepsi=17) +parameter(num_creeps2r=6) +parameter(ncrp_arry=7) +common/marc_creeps/cptim,timinc,timinc_p,timinc_s,timincm,timinc_a,timinc_b,icfte,icfst,& + icfeq,icftm,icetem,mcreep,jcreep,icpa,icftmp,icfstr,icfqcp,icfcpm,icrppr,icrcha,icpb,iicpmt,iicpa +common/marc_creeps2/time_beg_lcase,time_beg_inc,fractol,time_beg_pst,fraction_donn,timinc_ol2 +! +! cptim Total time at begining of increment. +! timinc Incremental time for this step. +! icfte Local copy number of slopes of creep strain rate function +! versus temperature. Is -1 if exponent law used. +! icfst Local copy number of slopes of creep strain rate function +! versus equivalent stress. Is -1 if exponent law used. +! icfeq Local copy number of slopes of creep strain rate function +! versus equivalent strain. Is -1 if exponent law used. +! icftm Local copy number of slopes of creep strain rate function +! versus time. Is -1 if exponent law used. +! icetem Element number that needs to be checked for creep convergence +! or, if negative, the number of elements that need to +! be checked. In the latter case the elements to check +! are stored in ielcp. +! mcreep Maximum nuber of iterations for explicit creep. +! jcreep Counter of number of iterations for explicit creep +! procedure. jcreep must be .le. mcreep +! icpa(1-6) Pointer to constants in creep strain rate expression. +! icftmp Pointer to temperature dependent creep strain rate data. +! icfstr Pointer to equivalent stress dependent creep strain rate data. +! icfqcp Pointer to equivalent creep strain dependent creep strain +! rate data. +! icfcpm Pointer to equivalent creep strain rate dependent +! creep strain rate data. +! icrppr Permanent copy of icreep +! icrcha Control flag for creep convergence checking , if set to +! 1 then testing on absolute change in stress and creep +! strain, not relative testing. Input data. +! icpb(1-4) Pointer to storage of material id cross reference numbers. +! iicpmt creep law type ID +! =1 - power law +! =2 - solder +! =3 - steady-creep +! =4 - hyperbolic steady-creep +! iicpa Pointer to table IDs for constants in creep strain rate +! expression +! +! +! time_beg_lcase time at the beginning of the current load case +! time_beg_inc time at the beginning of the current increment +! fractol fraction of loadcase or increment time when we +! consider it to be finished +! time_beg_pst time corresponding to first increment to be +! read in from thermal post file for auto step +! +! timinc_old Time step of the previous increment +! +!*********************************************************************** +!!$omp threadprivate(/marc_creeps/) +!!$omp threadprivate(/marc_creeps2/) +!! diff --git a/src/Marc/materialpoint_Marc.f90 b/src/Marc/materialpoint_Marc.f90 index 72c718a87..847834003 100644 --- a/src/Marc/materialpoint_Marc.f90 +++ b/src/Marc/materialpoint_Marc.f90 @@ -10,11 +10,12 @@ module materialpoint_Marc use YAML_types use YAML_parse use HDF5_utilities - use results + use result use config use math use rotations use polynomials + use tables use lattice use material use phase @@ -64,7 +65,7 @@ module materialpoint_Marc public :: & materialpoint_general, & materialpoint_initAll, & - materialpoint_results + materialpoint_result contains @@ -72,26 +73,27 @@ contains !-------------------------------------------------------------------------------------------------- !> @brief Initialize all modules. !-------------------------------------------------------------------------------------------------- -subroutine materialpoint_initAll +subroutine materialpoint_initAll() - call DAMASK_interface_init - call prec_init - call IO_init - call YAML_types_init - call YAML_parse_init - call HDF5_utilities_init - call results_init(.false.) - call config_init - call math_init - call rotations_init - call polynomials_init - call lattice_init - call discretization_Marc_init + call DAMASK_interface_init() + call prec_init() + call IO_init() + call YAML_types_init() + call YAML_parse_init() + call HDF5_utilities_init() + call result_init(.false.) + call config_init() + call math_init() + call rotations_init() + call polynomials_init() + call tables_init() + call lattice_init() + call discretization_Marc_init() call material_init(.false.) - call phase_init - call homogenization_init - call materialpoint_init - call config_deallocate + call phase_init() + call homogenization_init() + call materialpoint_init() + call config_deallocate() end subroutine materialpoint_initAll @@ -99,11 +101,12 @@ end subroutine materialpoint_initAll !-------------------------------------------------------------------------------------------------- !> @brief allocate the arrays defined in module materialpoint and initialize them !-------------------------------------------------------------------------------------------------- -subroutine materialpoint_init +subroutine materialpoint_init() - class(tNode), pointer :: & + type(tList), pointer :: & debug_materialpoint + print'(/,1x,a)', '<<<+- materialpoint init -+>>>'; flush(IO_STDOUT) allocate(materialpoint_cs( 6,discretization_nIPs,discretization_Nelems), source= 0.0_pReal) @@ -113,19 +116,19 @@ subroutine materialpoint_init !------------------------------------------------------------------------------ ! read debug options - debug_materialpoint => config_debug%get('materialpoint',defaultVal=emptyList) + debug_materialpoint => config_debug%get_list('materialpoint',defaultVal=emptyList) debugmaterialpoint%basic = debug_materialpoint%contains('basic') debugmaterialpoint%extensive = debug_materialpoint%contains('extensive') debugmaterialpoint%selective = debug_materialpoint%contains('selective') debugmaterialpoint%element = config_debug%get_asInt('element',defaultVal = 1) debugmaterialpoint%ip = config_debug%get_asInt('integrationpoint',defaultVal = 1) - if(debugmaterialpoint%basic) then + if (debugmaterialpoint%basic) then print'(a32,1x,6(i8,1x))', 'materialpoint_cs: ', shape(materialpoint_cs) print'(a32,1x,6(i8,1x))', 'materialpoint_dcsdE: ', shape(materialpoint_dcsdE) print'(a32,1x,6(i8,1x),/)', 'materialpoint_dcsdE_knownGood: ', shape(materialpoint_dcsdE_knownGood) flush(IO_STDOUT) - endif + end if end subroutine materialpoint_init @@ -170,7 +173,7 @@ subroutine materialpoint_general(mode, ffn, ffn1, temperature_inp, dt, elFE, ip, if (terminallyIll) & print'(a,/)', '# --- terminallyIll --- #' print'(a,/)', '#############################################'; flush (6) - endif + end if if (iand(mode, materialpoint_BACKUPJACOBIAN) /= 0) & materialpoint_dcsde_knownGood = materialpoint_dcsde @@ -219,15 +222,15 @@ subroutine materialpoint_general(mode, ffn, ffn1, temperature_inp, dt, elFE, ip, - math_delta(j,l) * homogenization_F(i,m,ce) * homogenization_P(k,m,ce) & + 0.5_pReal * ( Kirchhoff(j,l)*math_delta(i,k) + Kirchhoff(i,k)*math_delta(j,l) & + Kirchhoff(j,k)*math_delta(i,l) + Kirchhoff(i,l)*math_delta(j,k)) - enddo; enddo; enddo; enddo; enddo; enddo + end do; end do; end do; end do; end do; end do forall(i=1:3, j=1:3,k=1:3,l=1:3) & H_sym(i,j,k,l) = 0.25_pReal * (H(i,j,k,l) + H(j,i,k,l) + H(i,j,l,k) + H(j,i,l,k)) materialpoint_dcsde(1:6,1:6,ip,elCP) = math_sym3333to66(J_inverse * H_sym,weighted=.false.) - endif terminalIllness - endif validCalculation + end if terminalIllness + end if validCalculation if (debugmaterialpoint%extensive & .and. ((debugmaterialpoint%element == elCP .and. debugmaterialpoint%ip == ip) .or. .not. debugmaterialpoint%selective)) then @@ -236,9 +239,9 @@ subroutine materialpoint_general(mode, ffn, ffn1, temperature_inp, dt, elFE, ip, print'(a,i8,1x,i2,/,6(12x,6(f10.3,1x)/))', & '<< materialpoint >> Jacobian/GPa at elFE ip ', elFE, ip, transpose(materialpoint_dcsdE(1:6,1:6,ip,elCP))*1.0e-9_pReal flush(IO_STDOUT) - endif + end if - endif + end if if (all(abs(materialpoint_dcsdE(1:6,1:6,ip,elCP)) < 1e-10_pReal)) & call IO_warning(601,label1='element (CP)',ID1=elCP,label2='IP',ID2=ip) @@ -263,19 +266,19 @@ end subroutine materialpoint_forward !-------------------------------------------------------------------------------------------------- !> @brief Trigger writing of results. !-------------------------------------------------------------------------------------------------- -subroutine materialpoint_results(inc,time) +subroutine materialpoint_result(inc,time) integer, intent(in) :: inc real(pReal), intent(in) :: time - call results_openJobFile - call results_addIncrement(inc,time) - call phase_results - call homogenization_results - call discretization_results - call results_finalizeIncrement - call results_closeJobFile + call result_openJobFile + call result_addIncrement(inc,time) + call phase_result + call homogenization_result + call discretization_result + call result_finalizeIncrement + call result_closeJobFile -end subroutine materialpoint_results +end subroutine materialpoint_result end module materialpoint_Marc diff --git a/src/YAML_parse.f90 b/src/YAML_parse.f90 index e7d64770d..b1f5aaf71 100644 --- a/src/YAML_parse.f90 +++ b/src/YAML_parse.f90 @@ -17,7 +17,8 @@ module YAML_parse public :: & YAML_parse_init, & - YAML_parse_str + YAML_parse_str_asList, & + YAML_parse_str_asDict #ifdef FYAML interface @@ -53,16 +54,39 @@ end subroutine YAML_parse_init !-------------------------------------------------------------------------------------------------- -!> @brief Parse a YAML string into a a structure of nodes. +!> @brief Parse a YAML string with list as root into a a structure of nodes. +!> @details The string needs to end with a newline (unless using libfyaml). !-------------------------------------------------------------------------------------------------- -function YAML_parse_str(str) result(node) +function YAML_parse_str_asList(str) result(list) character(len=*), intent(in) :: str - class (tNode), pointer :: node + type(tList), pointer :: list + + class(tNode), pointer :: node + node => parse_flow(to_flow(str)) + list => node%asList() -end function YAML_parse_str +end function YAML_parse_str_asList + + +!-------------------------------------------------------------------------------------------------- +!> @brief Parse a YAML string with dict as root into a a structure of nodes. +!> @details The string needs to end with a newline (unless using libfyaml). +!-------------------------------------------------------------------------------------------------- +function YAML_parse_str_asDict(str) result(dict) + + character(len=*), intent(in) :: str + type(tDict), pointer :: dict + + class(tNode), pointer :: node + + + node => parse_flow(to_flow(str)) + dict => node%asDict() + +end function YAML_parse_str_asDict !-------------------------------------------------------------------------------------------------- @@ -72,9 +96,9 @@ end function YAML_parse_str recursive function parse_flow(YAML_flow) result(node) character(len=*), intent(in) :: YAML_flow !< YAML file in flow style - class (tNode), pointer :: node + class(tNode), pointer :: node - class (tNode), pointer :: & + class(tNode), pointer :: & myVal character(len=:), allocatable :: & flow_string, & @@ -96,7 +120,7 @@ recursive function parse_flow(YAML_flow) result(node) d = s + scan(flow_string(s+1:),':') e = d + find_end(flow_string(d+1:),'}') key = trim(adjustl(flow_string(s+1:d-1))) - if(quotedString(key)) key = key(2:len(key)-1) + if (quotedString(key)) key = key(2:len(key)-1) myVal => parse_flow(flow_string(d+1:e-1)) ! parse items (recursively) select type (node) @@ -121,7 +145,7 @@ recursive function parse_flow(YAML_flow) result(node) allocate(tScalar::node) select type (node) class is (tScalar) - if(quotedString(flow_string)) then + if (quotedString(flow_string)) then node = trim(adjustl(flow_string(2:len(flow_string)-1))) else node = trim(adjustl(flow_string)) @@ -176,7 +200,7 @@ logical function quotedString(line) if (scan(line(:1),IO_QUOTES) == 1) then quotedString = .true. - if(line(len(line):len(line)) /= line(:1)) call IO_error(710,ext_msg=line) + if (line(len(line):len(line)) /= line(:1)) call IO_error(710,ext_msg=line) end if end function quotedString @@ -223,7 +247,7 @@ integer function indentDepth(line,offset) integer, optional,intent(in) :: offset indentDepth = verify(line,IO_WHITESPACE) -1 - if(present(offset)) indentDepth = indentDepth + offset + if (present(offset)) indentDepth = indentDepth + offset end function indentDepth @@ -263,7 +287,7 @@ logical function isListItem(line) character(len=*), intent(in) :: line isListItem = .false. - if(len_trim(adjustl(line))> 2 .and. index(trim(adjustl(line)), '-') == 1) then + if (len_trim(adjustl(line))> 2 .and. index(trim(adjustl(line)), '-') == 1) then isListItem = scan(trim(adjustl(line)),' ') == 2 else isListItem = trim(adjustl(line)) == '-' @@ -280,8 +304,8 @@ logical function isKeyValue(line) character(len=*), intent(in) :: line isKeyValue = .false. - if( .not. isKey(line) .and. index(IO_rmComment(line),':') > 0 .and. .not. isFlow(line)) then - if(index(IO_rmComment(line),': ') > 0) isKeyValue = .true. + if ( .not. isKey(line) .and. index(IO_rmComment(line),':') > 0 .and. .not. isFlow(line)) then + if (index(IO_rmComment(line),': ') > 0) isKeyValue = .true. end if end function isKeyValue @@ -295,7 +319,7 @@ logical function isKey(line) character(len=*), intent(in) :: line - if(len(IO_rmComment(line)) == 0) then + if (len(IO_rmComment(line)) == 0) then isKey = .false. else isKey = index(IO_rmComment(line),':',back=.false.) == len(IO_rmComment(line)) .and. & @@ -332,7 +356,7 @@ subroutine skip_empty_lines(blck,s_blck) empty = .true. do while(empty .and. len_trim(blck(s_blck:)) /= 0) empty = len_trim(IO_rmComment(blck(s_blck:s_blck + index(blck(s_blck:),IO_EOL) - 2))) == 0 - if(empty) s_blck = s_blck + index(blck(s_blck:),IO_EOL) + if (empty) s_blck = s_blck + index(blck(s_blck:),IO_EOL) end do end subroutine skip_empty_lines @@ -350,10 +374,10 @@ subroutine skip_file_header(blck,s_blck) character(len=:), allocatable :: line line = IO_rmComment(blck(s_blck:s_blck + index(blck(s_blck:),IO_EOL) - 2)) - if(index(adjustl(line),'%YAML') == 1) then + if (index(adjustl(line),'%YAML') == 1) then s_blck = s_blck + index(blck(s_blck:),IO_EOL) call skip_empty_lines(blck,s_blck) - if(trim(IO_rmComment(blck(s_blck:s_blck + index(blck(s_blck:),IO_EOL) - 2))) == '---') then + if (trim(IO_rmComment(blck(s_blck:s_blck + index(blck(s_blck:),IO_EOL) - 2))) == '---') then s_blck = s_blck + index(blck(s_blck:),IO_EOL) else call IO_error(708,ext_msg = line) @@ -378,8 +402,8 @@ logical function flow_is_closed(str,e_char) flow_is_closed = .false. N_sq = 0 N_cu = 0 - if(e_char == ']') line = str(index(str(:),'[')+1:) - if(e_char == '}') line = str(index(str(:),'{')+1:) + if (e_char == ']') line = str(index(str(:),'[')+1:) + if (e_char == '}') line = str(index(str(:),'{')+1:) do i = 1, len_trim(line) flow_is_closed = (N_sq==0 .and. N_cu==0 .and. scan(line(i:i),e_char) == 1) @@ -441,7 +465,7 @@ subroutine list_item_inline(blck,s_blck,inline,offset) indent_next = indentDepth(blck(s_blck:)) end do - if(scan(inline,",") > 0) inline = '"'//inline//'"' + if (scan(inline,",") > 0) inline = '"'//inline//'"' end subroutine list_item_inline @@ -461,19 +485,19 @@ recursive subroutine line_isFlow(flow,s_flow,line) list_chunk, & dict_chunk - if(index(adjustl(line),'[') == 1) then + if (index(adjustl(line),'[') == 1) then s = index(line,'[') flow(s_flow:s_flow) = '[' s_flow = s_flow +1 do while(s < len_trim(line)) list_chunk = s + find_end(line(s+1:),']') - if(iskeyValue(line(s+1:list_chunk-1))) then + if (iskeyValue(line(s+1:list_chunk-1))) then flow(s_flow:s_flow) = '{' s_flow = s_flow +1 call keyValue_toFlow(flow,s_flow,line(s+1:list_chunk-1)) flow(s_flow:s_flow) = '}' s_flow = s_flow +1 - elseif(isFlow(line(s+1:list_chunk-1))) then + elseif (isFlow(line(s+1:list_chunk-1))) then call line_isFlow(flow,s_flow,line(s+1:list_chunk-1)) else call line_toFlow(flow,s_flow,line(s+1:list_chunk-1)) @@ -487,20 +511,20 @@ recursive subroutine line_isFlow(flow,s_flow,line) flow(s_flow:s_flow) = ']' s_flow = s_flow+1 - elseif(index(adjustl(line),'{') == 1) then + elseif (index(adjustl(line),'{') == 1) then s = index(line,'{') flow(s_flow:s_flow) = '{' s_flow = s_flow +1 do while(s < len_trim(line)) dict_chunk = s + find_end(line(s+1:),'}') - if( .not. iskeyValue(line(s+1:dict_chunk-1))) call IO_error(705,ext_msg=line) + if ( .not. iskeyValue(line(s+1:dict_chunk-1))) call IO_error(705,ext_msg=line) call keyValue_toFlow(flow,s_flow,line(s+1:dict_chunk-1)) flow(s_flow:s_flow+1) = ', ' s_flow = s_flow +2 s = s + find_end(line(s+1:),'}') end do s_flow = s_flow -1 - if(flow(s_flow-1:s_flow-1) == ',') s_flow = s_flow -1 + if (flow(s_flow-1:s_flow-1) == ',') s_flow = s_flow -1 flow(s_flow:s_flow) = '}' s_flow = s_flow +1 else @@ -527,8 +551,8 @@ recursive subroutine keyValue_toFlow(flow,s_flow,line) offset_value col_pos = index(line,':') - if(line(col_pos+1:col_pos+1) /= ' ') call IO_error(704,ext_msg=line) - if(isFlow(line(col_pos+1:))) then + if (line(col_pos+1:col_pos+1) /= ' ') call IO_error(704,ext_msg=line) + if (isFlow(line(col_pos+1:))) then d_flow = len_trim(adjustl(line(:col_pos))) flow(s_flow:s_flow+d_flow+1) = trim(adjustl(line(:col_pos)))//' ' s_flow = s_flow + d_flow+1 @@ -583,35 +607,35 @@ recursive subroutine lst(blck,flow,s_blck,s_flow,offset) do while (s_blck <= len_trim(blck)) e_blck = s_blck + index(blck(s_blck:),IO_EOL) - 2 line = IO_rmComment(blck(s_blck:e_blck)) - if(trim(line) == '---' .or. trim(line) == '...') then + if (trim(line) == '---' .or. trim(line) == '...') then exit elseif (len_trim(line) == 0) then s_blck = e_blck + 2 ! forward to next line cycle - elseif(indentDepth(line,offset) > indent) then + elseif (indentDepth(line,offset) > indent) then call decide(blck,flow,s_blck,s_flow,offset) offset = 0 flow(s_flow:s_flow+1) = ', ' s_flow = s_flow + 2 - elseif(indentDepth(line,offset) < indent .or. .not. isListItem(line)) then + elseif (indentDepth(line,offset) < indent .or. .not. isListItem(line)) then offset = 0 exit ! job done (lower level) else - if(trim(adjustl(line)) == '-') then ! list item in next line + if (trim(adjustl(line)) == '-') then ! list item in next line s_blck = e_blck + 2 call skip_empty_lines(blck,s_blck) e_blck = s_blck + index(blck(s_blck:),IO_EOL) - 2 line = IO_rmComment(blck(s_blck:e_blck)) - if(trim(line) == '---') call IO_error(707,ext_msg=line) - if(indentDepth(line) < indent .or. indentDepth(line) == indent) & + if (trim(line) == '---') call IO_error(707,ext_msg=line) + if (indentDepth(line) < indent .or. indentDepth(line) == indent) & call IO_error(701,ext_msg=line) - if(isScalar(line)) then + if (isScalar(line)) then call line_toFlow(flow,s_flow,line) s_blck = e_blck +2 offset = 0 - elseif(isFlow(line)) then - if(isFlowList(line)) then + elseif (isFlow(line)) then + if (isFlowList(line)) then call remove_line_break(blck,s_blck,']',flow_line) else call remove_line_break(blck,s_blck,'}',flow_line) @@ -621,13 +645,13 @@ recursive subroutine lst(blck,flow,s_blck,s_flow,offset) end if else ! list item in the same line line = line(indentDepth(line)+3:) - if(isScalar(line)) then + if (isScalar(line)) then call list_item_inline(blck,s_blck,inline,offset) offset = 0 call line_toFlow(flow,s_flow,inline) - elseif(isFlow(line)) then + elseif (isFlow(line)) then s_blck = s_blck + index(blck(s_blck:),'-') - if(isFlowList(line)) then + if (isFlowList(line)) then call remove_line_break(blck,s_blck,']',flow_line) else call remove_line_break(blck,s_blck,'}',flow_line) @@ -641,7 +665,7 @@ recursive subroutine lst(blck,flow,s_blck,s_flow,offset) end if end if - if(isScalar(line) .or. isFlow(line)) then + if (isScalar(line) .or. isFlow(line)) then flow(s_flow:s_flow+1) = ', ' s_flow = s_flow + 2 end if @@ -680,33 +704,33 @@ recursive subroutine dct(blck,flow,s_blck,s_flow,offset) do while (s_blck <= len_trim(blck)) e_blck = s_blck + index(blck(s_blck:),IO_EOL) - 2 line = IO_rmComment(blck(s_blck:e_blck)) - if(trim(line) == '---' .or. trim(line) == '...') then + if (trim(line) == '---' .or. trim(line) == '...') then exit elseif (len_trim(line) == 0) then s_blck = e_blck + 2 ! forward to next line cycle - elseif(indentDepth(line,offset) < indent) then - if(isScalar(line) .or. isFlow(line) .and. previous_isKey) & + elseif (indentDepth(line,offset) < indent) then + if (isScalar(line) .or. isFlow(line) .and. previous_isKey) & call IO_error(701,ext_msg=line) offset = 0 exit ! job done (lower level) - elseif(indentDepth(line,offset) > indent .or. isListItem(line)) then + elseif (indentDepth(line,offset) > indent .or. isListItem(line)) then offset = 0 call decide(blck,flow,s_blck,s_flow,offset) else - if(isScalar(line)) call IO_error(701,ext_msg=line) - if(isFlow(line)) call IO_error(702,ext_msg=line) + if (isScalar(line)) call IO_error(701,ext_msg=line) + if (isFlow(line)) call IO_error(702,ext_msg=line) line = line(indentDepth(line)+1:) - if(previous_isKey) then + if (previous_isKey) then flow(s_flow-1:s_flow) = ', ' s_flow = s_flow + 1 end if - if(isKeyValue(line)) then + if (isKeyValue(line)) then col_pos = index(line,':') - if(isFlow(line(col_pos+1:))) then - if(isFlowList(line(col_pos+1:))) then + if (isFlow(line(col_pos+1:))) then + if (isFlowList(line(col_pos+1:))) then call remove_line_break(blck,s_blck,']',flow_line) else call remove_line_break(blck,s_blck,'}',flow_line) @@ -722,7 +746,7 @@ recursive subroutine dct(blck,flow,s_blck,s_flow,offset) end if end if - if(isScalar(line) .or. isKeyValue(line)) then + if (isScalar(line) .or. isKeyValue(line)) then flow(s_flow:s_flow) = ',' s_flow = s_flow + 1 previous_isKey = .false. @@ -742,7 +766,7 @@ end subroutine dct !-------------------------------------------------------------------------------------------------- -! @brief decide whether next block is list or dict +! @brief Decide whether next block is list or dict. !-------------------------------------------------------------------------------------------------- recursive subroutine decide(blck,flow,s_blck,s_flow,offset) @@ -754,13 +778,13 @@ recursive subroutine decide(blck,flow,s_blck,s_flow,offset) integer :: e_blck character(len=:), allocatable :: line,flow_line - if(s_blck <= len(blck)) then + if (s_blck <= len(blck)) then call skip_empty_lines(blck,s_blck) e_blck = s_blck + index(blck(s_blck:),IO_EOL) - 2 line = IO_rmComment(blck(s_blck:e_blck)) - if(trim(line) == '---' .or. trim(line) == '...') then + if (trim(line) == '---' .or. trim(line) == '...') then continue ! end parsing at this point but not stop the simulation - elseif(len_trim(line) == 0) then + elseif (len_trim(line) == 0) then s_blck = e_blck +2 call decide(blck,flow,s_blck,s_flow,offset) elseif (isListItem(line)) then @@ -769,14 +793,14 @@ recursive subroutine decide(blck,flow,s_blck,s_flow,offset) call lst(blck,flow,s_blck,s_flow,offset) flow(s_flow:s_flow) = ']' s_flow = s_flow + 1 - elseif(isKey(line) .or. isKeyValue(line)) then + elseif (isKey(line) .or. isKeyValue(line)) then flow(s_flow:s_flow) = '{' s_flow = s_flow + 1 call dct(blck,flow,s_blck,s_flow,offset) flow(s_flow:s_flow) = '}' s_flow = s_flow + 1 - elseif(isFlow(line)) then - if(isFlowList(line)) then + elseif (isFlow(line)) then + if (isFlowList(line)) then call remove_line_break(blck,s_blck,']',flow_line) else call remove_line_break(blck,s_blck,'}',flow_line) @@ -789,11 +813,12 @@ recursive subroutine decide(blck,flow,s_blck,s_flow,offset) end if end if -end subroutine +end subroutine decide !-------------------------------------------------------------------------------------------------- -! @brief Convert all block style YAML parts to flow style. +!> @brief Convert all block style YAML parts to flow style. +!> @details The input needs to end with a newline. !-------------------------------------------------------------------------------------------------- function to_flow(blck) @@ -811,18 +836,18 @@ function to_flow(blck) s_blck = 1 offset = 0 - if(len_trim(blck) /= 0) then + if (len_trim(blck) /= 0) then call skip_empty_lines(blck,s_blck) call skip_file_header(blck,s_blck) line = IO_rmComment(blck(s_blck:s_blck + index(blck(s_blck:),IO_EOL) - 2)) - if(trim(line) == '---') s_blck = s_blck + index(blck(s_blck:),IO_EOL) + if (trim(line) == '---') s_blck = s_blck + index(blck(s_blck:),IO_EOL) call decide(blck,to_flow,s_blck,s_flow,offset) end if line = IO_rmComment(blck(s_blck:s_blck+index(blck(s_blck:),IO_EOL)-2)) - if(trim(line)== '---') call IO_warning(709,ext_msg=line) + if (trim(line)== '---') call IO_warning(709,ext_msg=line) to_flow = trim(to_flow(:s_flow-1)) end_line = index(to_flow,IO_EOL) - if(end_line > 0) to_flow = to_flow(:end_line-1) + if (end_line > 0) to_flow = to_flow(:end_line-1) end function to_flow @@ -830,7 +855,7 @@ end function to_flow !-------------------------------------------------------------------------------------------------- !> @brief Check correctness of some YAML functions. !-------------------------------------------------------------------------------------------------- -subroutine selfTest +subroutine selfTest() if (indentDepth(' a') /= 1) error stop 'indentDepth' if (indentDepth('a') /= 0) error stop 'indentDepth' @@ -858,124 +883,139 @@ subroutine selfTest if (.not. isKey(' a:')) error stop 'isKey' if (.not. isKey(' a: #')) error stop 'isKey' - if( isScalar('a: ')) error stop 'isScalar' - if( isScalar('a: b')) error stop 'isScalar' - if( isScalar('{a:b}')) error stop 'isScalar' - if( isScalar('- a:')) error stop 'isScalar' - if(.not. isScalar(' a')) error stop 'isScalar' + if ( isScalar('a: ')) error stop 'isScalar' + if ( isScalar('a: b')) error stop 'isScalar' + if ( isScalar('{a:b}')) error stop 'isScalar' + if ( isScalar('- a:')) error stop 'isScalar' + if (.not. isScalar(' a')) error stop 'isScalar' basic_list: block - character(len=*), parameter :: block_list = & - " - Casablanca"//IO_EOL//& - " - North by Northwest"//IO_EOL - character(len=*), parameter :: block_list_newline = & - " -"//IO_EOL//& - " Casablanca"//IO_EOL//& - " -"//IO_EOL//& - " North by Northwest"//IO_EOL - character(len=*), parameter :: flow_list = & - "[Casablanca, North by Northwest]" + character(len=*), parameter :: block_list = & + " - Casablanca"//IO_EOL//& + " - North by Northwest"//IO_EOL + character(len=*), parameter :: block_list_newline = & + " -"//IO_EOL//& + " Casablanca"//IO_EOL//& + " -"//IO_EOL//& + " North by Northwest"//IO_EOL + character(len=*), parameter :: flow_list = & + "[Casablanca, North by Northwest]" - if (.not. to_flow(block_list) == flow_list) error stop 'to_flow' - if (.not. to_flow(block_list_newline) == flow_list) error stop 'to_flow' + if (.not. to_flow(block_list) == flow_list) error stop 'to_flow' + if (.not. to_flow(block_list_newline) == flow_list) error stop 'to_flow' end block basic_list basic_dict: block - character(len=*), parameter :: block_dict = & - " aa: Casablanca"//IO_EOL//& - " bb: North by Northwest"//IO_EOL - character(len=*), parameter :: block_dict_newline = & - " aa:"//IO_EOL//& - " Casablanca"//IO_EOL//& - " bb:"//IO_EOL//& - " North by Northwest"//IO_EOL - character(len=*), parameter :: flow_dict = & - "{aa: Casablanca, bb: North by Northwest}" + character(len=*), parameter :: block_dict = & + " aa: Casablanca"//IO_EOL//& + " bb: North by Northwest"//IO_EOL + character(len=*), parameter :: block_dict_newline = & + " aa:"//IO_EOL//& + " Casablanca"//IO_EOL//& + " bb:"//IO_EOL//& + " North by Northwest"//IO_EOL + character(len=*), parameter :: flow_dict = & + "{aa: Casablanca, bb: North by Northwest}" - if (.not. to_flow(block_dict) == flow_dict) error stop 'to_flow' - if (.not. to_flow(block_dict_newline) == flow_dict) error stop 'to_flow' + if (.not. to_flow(block_dict) == flow_dict) error stop 'to_flow' + if (.not. to_flow(block_dict_newline) == flow_dict) error stop 'to_flow' end block basic_dict only_flow: block - character(len=*), parameter :: flow_dict = & - " {a: [b,c: {d: e}, f: g, e]}"//IO_EOL - character(len=*), parameter :: flow_list = & - " [a,b: c, d,e: {f: g}]"//IO_EOL - character(len=*), parameter :: flow_1 = & - "{a: [b, {c: {d: e}}, {f: g}, e]}" - character(len=*), parameter :: flow_2 = & - "[a, {b: c}, d, {e: {f: g}}]" + character(len=*), parameter :: flow_dict = & + " {a: [b,c: {d: e}, f: g, e]}"//IO_EOL + character(len=*), parameter :: flow_list = & + " [a,b: c, d,e: {f: g}]"//IO_EOL + character(len=*), parameter :: flow_1 = & + "{a: [b, {c: {d: e}}, {f: g}, e]}" + character(len=*), parameter :: flow_2 = & + "[a, {b: c}, d, {e: {f: g}}]" - if (.not. to_flow(flow_dict) == flow_1) error stop 'to_flow' - if (.not. to_flow(flow_list) == flow_2) error stop 'to_flow' + if (.not. to_flow(flow_dict) == flow_1) error stop 'to_flow' + if (.not. to_flow(flow_list) == flow_2) error stop 'to_flow' end block only_flow basic_flow: block - character(len=*), parameter :: flow_braces = & - " source: [{param: 1}, {param: 2}, {param: 3}, {param: 4}]"//IO_EOL - character(len=*), parameter :: flow_mixed_braces = & - " source: [param: 1, {param: 2}, param: 3, {param: 4}]"//IO_EOL - character(len=*), parameter :: flow = & - "{source: [{param: 1}, {param: 2}, {param: 3}, {param: 4}]}" + character(len=*), parameter :: flow_braces = & + " source: [{param: 1}, {param: 2}, {param: 3}, {param: 4}]"//IO_EOL + character(len=*), parameter :: flow_mixed_braces = & + " source: [param: 1, {param: 2}, param: 3, {param: 4}]"//IO_EOL + character(len=*), parameter :: flow = & + "{source: [{param: 1}, {param: 2}, {param: 3}, {param: 4}]}" - if (.not. to_flow(flow_braces) == flow) error stop 'to_flow' - if (.not. to_flow(flow_mixed_braces) == flow) error stop 'to_flow' + if (.not. to_flow(flow_braces) == flow) error stop 'to_flow' + if (.not. to_flow(flow_mixed_braces) == flow) error stop 'to_flow' end block basic_flow multi_line_flow1: block - character(len=*), parameter :: flow_multi = & - '%YAML 1.1'//IO_EOL//& - '---'//IO_EOL//& - 'a: ["b",'//IO_EOL//& - 'c: '//IO_EOL//& - '"d", "e"]'//IO_EOL + character(len=*), parameter :: flow_multi = & + '%YAML 1.1'//IO_EOL//& + '---'//IO_EOL//& + 'a: ["b",'//IO_EOL//& + 'c: '//IO_EOL//& + '"d", "e"]'//IO_EOL - character(len=*), parameter :: flow = & - '{a: ["b", {c: "d"}, "e"]}' + character(len=*), parameter :: flow = & + '{a: ["b", {c: "d"}, "e"]}' - if( .not. to_flow(flow_multi) == flow) error stop 'to_flow' + if ( .not. to_flow(flow_multi) == flow) error stop 'to_flow' end block multi_line_flow1 multi_line_flow2: block - character(len=*), parameter :: flow_multi = & - "%YAML 1.1"//IO_EOL//& - "---"//IO_EOL//& - "-"//IO_EOL//& - " a: {b:"//IO_EOL//& - "[c,"//IO_EOL//& - "d"//IO_EOL//& - "e, f]}"//IO_EOL + character(len=*), parameter :: flow_multi = & + "%YAML 1.1"//IO_EOL//& + "---"//IO_EOL//& + "-"//IO_EOL//& + " a: {b:"//IO_EOL//& + "[c,"//IO_EOL//& + "d"//IO_EOL//& + "e, f]}"//IO_EOL - character(len=*), parameter :: flow = & - "[{a: {b: [c, d e, f]}}]" + character(len=*), parameter :: flow = & + "[{a: {b: [c, d e, f]}}]" - if( .not. to_flow(flow_multi) == flow) error stop 'to_flow' + if ( .not. to_flow(flow_multi) == flow) error stop 'to_flow' end block multi_line_flow2 basic_mixed: block - character(len=*), parameter :: block_flow = & - "%YAML 1.1"//IO_EOL//& - " "//IO_EOL//& - " "//IO_EOL//& - "---"//IO_EOL//& - " aa:"//IO_EOL//& - " - "//IO_EOL//& - " "//IO_EOL//& - " "//IO_EOL//& - " param_1: [a: b, c, {d: {e: [f: g, h]}}]"//IO_EOL//& - " - c:d"//IO_EOL//& - " e.f,"//IO_EOL//& - " bb:"//IO_EOL//& - " "//IO_EOL//& - " - "//IO_EOL//& - " {param_1: [{a: b}, c, {d: {e: [{f: g}, h]}}]}"//IO_EOL//& - "..."//IO_EOL - character(len=*), parameter :: mixed_flow = & - '{aa: [{param_1: [{a: b}, c, {d: {e: [{f: g}, h]}}]}, "c:d e.f,"], bb: [{param_1: [{a: b}, c, {d: {e: [{f: g}, h]}}]}]}' + character(len=*), parameter :: block_flow = & + "%YAML 1.1"//IO_EOL//& + " "//IO_EOL//& + " "//IO_EOL//& + "---"//IO_EOL//& + " aa:"//IO_EOL//& + " - "//IO_EOL//& + " "//IO_EOL//& + " "//IO_EOL//& + " param_1: [a: b, c, {d: {e: [f: g, h]}}]"//IO_EOL//& + " - c:d"//IO_EOL//& + " e.f,"//IO_EOL//& + " bb:"//IO_EOL//& + " "//IO_EOL//& + " - "//IO_EOL//& + " {param_1: [{a: b}, c, {d: {e: [{f: g}, h]}}]}"//IO_EOL//& + "..."//IO_EOL + character(len=*), parameter :: mixed_flow = & + '{aa: [{param_1: [{a: b}, c, {d: {e: [{f: g}, h]}}]}, "c:d e.f,"], bb: [{param_1: [{a: b}, c, {d: {e: [{f: g}, h]}}]}]}' - if(.not. to_flow(block_flow) == mixed_flow) error stop 'to_flow' + if (.not. to_flow(block_flow) == mixed_flow) error stop 'to_flow' end block basic_mixed + parse: block + + type(tDict), pointer :: dict + type(tList), pointer :: list + character(len=*), parameter :: & + lst = '[1, 2, 3, 4]', & + dct = '{a: 1, b: 2}' + + list => YAML_parse_str_asList(lst//IO_EOL) + if (list%asFormattedString() /= lst) error stop 'str_asList' + dict => YAML_parse_str_asDict(dct//IO_EOL) + if (dict%asFormattedString() /= dct) error stop 'str_asDict' + + end block parse + end subroutine selfTest #endif diff --git a/src/YAML_types.f90 b/src/YAML_types.f90 index e9bdff88d..a6ac9766d 100644 --- a/src/YAML_types.f90 +++ b/src/YAML_types.f90 @@ -15,141 +15,112 @@ module YAML_types private type, abstract, public :: tNode - integer :: length = 0 + integer :: & + length = 0 contains - procedure(asFormattedString), deferred :: asFormattedString + procedure(asFormattedString), deferred :: & + asFormattedString procedure :: & - asScalar => tNode_asScalar - procedure :: & - asList => tNode_asList - procedure :: & - asDict => tNode_asDict - procedure :: & - tNode_get_byIndex => tNode_get_byIndex - procedure :: & - tNode_get_byIndex_asFloat => tNode_get_byIndex_asFloat - procedure :: & - tNode_get_byIndex_as1dFloat => tNode_get_byIndex_as1dFloat - procedure :: & - tNode_get_byIndex_asInt => tNode_get_byIndex_asInt - procedure :: & - tNode_get_byIndex_as1dInt => tNode_get_byIndex_as1dInt - procedure :: & - tNode_get_byIndex_asBool => tNode_get_byIndex_asBool - procedure :: & - tNode_get_byIndex_as1dBool => tNode_get_byIndex_as1dBool - procedure :: & - tNode_get_byIndex_asString => tNode_get_byIndex_asString - procedure :: & - tNode_get_byIndex_as1dString => tNode_get_byIndex_as1dString - procedure :: & - tNode_get_byKey => tNode_get_byKey - procedure :: & - tNode_get_byKey_asFloat => tNode_get_byKey_asFloat - procedure :: & - tNode_get_byKey_as1dFloat => tNode_get_byKey_as1dFloat - procedure :: & - tNode_get_byKey_asInt => tNode_get_byKey_asInt - procedure :: & - tNode_get_byKey_as1dInt => tNode_get_byKey_as1dInt - procedure :: & - tNode_get_byKey_asBool => tNode_get_byKey_asBool - procedure :: & - tNode_get_byKey_as1dBool => tNode_get_byKey_as1dBool - procedure :: & - tNode_get_byKey_asString => tNode_get_byKey_asString - procedure :: & - tNode_get_byKey_as1dString => tNode_get_byKey_as1dString - procedure :: & - getKey => tNode_get_byIndex_asKey - procedure :: & - Keys => tNode_getKeys - procedure :: & - getIndex => tNode_get_byKey_asIndex - procedure :: & - contains => tNode_contains - procedure :: & - get_as2dFloat => tNode_get_byKey_as2dFloat - - generic :: & - get => tNode_get_byIndex, & - tNode_get_byKey - generic :: & - get_asFloat => tNode_get_byIndex_asFloat, & - tNode_get_byKey_asFloat - generic :: & - get_as1dFloat => tNode_get_byIndex_as1dFloat, & - tNode_get_byKey_as1dFloat - generic :: & - get_asInt => tNode_get_byIndex_asInt, & - tNode_get_byKey_asInt - generic :: & - get_as1dInt => tNode_get_byIndex_as1dInt, & - tNode_get_byKey_as1dInt - generic :: & - get_asBool => tNode_get_byIndex_asBool, & - tNode_get_byKey_asBool - generic :: & - get_as1dBool => tNode_get_byIndex_as1dBool, & - tNode_get_byKey_as1dBool - generic :: & - get_asString => tNode_get_byIndex_asString, & - tNode_get_byKey_asString - generic :: & - get_as1dString => tNode_get_byIndex_as1dString, & - tNode_get_byKey_as1dString + asScalar => tNode_asScalar, & + asList => tNode_asList, & + asDict => tNode_asDict end type tNode - type, extends(tNode), public :: tScalar - - character(len=:), allocatable, private :: value - + character(len=:), allocatable, private :: & + value contains - procedure :: asFormattedString => tScalar_asFormattedString - procedure :: & - asFloat => tScalar_asFloat - procedure :: & - asInt => tScalar_asInt - procedure :: & - asBool => tScalar_asBool procedure :: & + asFormattedString => tScalar_asFormattedString, & + asFloat => tScalar_asFloat, & + asInt => tScalar_asInt, & + asBool => tScalar_asBool, & asString => tScalar_asString end type tScalar type, extends(tNode), public :: tList - - class(tItem), pointer :: first => NULL(), & - last => NULL() - + class(tItem), pointer :: & + first => NULL(), & + last => NULL() contains - procedure :: asFormattedString => tList_asFormattedString - procedure :: append => tList_append procedure :: & - as1dFloat => tList_as1dFloat - procedure :: & - as2dFloat => tList_as2dFloat - procedure :: & - as1dInt => tList_as1dInt - procedure :: & - as1dBool => tList_as1dBool - procedure :: & - as1dString => tList_as1dString + asFormattedString => tList_asFormattedString, & + append => tList_append, & + as1dFloat => tList_as1dFloat, & + as2dFloat => tList_as2dFloat, & + as1dInt => tList_as1dInt, & + as1dBool => tList_as1dBool, & + as1dString => tList_as1dString, & + contains => tList_contains, & + tList_get, & + tList_get_scalar, & + tList_get_list, & + tList_get_dict, & + tList_get_asFloat, & + tList_get_as1dFloat, & + tList_get_asInt, & + tList_get_as1dInt, & + tList_get_asBool, & + tList_get_as1dBool, & + tList_get_asString, & + tList_get_as1dString + generic :: get => tList_get + generic :: get_scalar => tList_get_scalar + generic :: get_list => tList_get_list + generic :: get_dict => tList_get_dict + generic :: get_asFloat => tList_get_asFloat + generic :: get_as1dFloat => tList_get_as1dFloat + generic :: get_asInt => tList_get_asInt + generic :: get_as1dInt => tList_get_as1dInt + generic :: get_asBool => tList_get_asBool + generic :: get_as1dBool => tList_get_as1dBool + generic :: get_asString => tList_get_asString + generic :: get_as1dString => tList_get_as1dString final :: tList_finalize end type tList type, extends(tList), public :: tDict contains - procedure :: asFormattedString => tDict_asFormattedString - procedure :: set => tDict_set - end type tDict + procedure :: & + asFormattedString => tDict_asFormattedString, & + set => tDict_set, & + index => tDict_index, & + key => tDict_key, & + keys => tDict_keys, & + contains => tDict_contains, & + tDict_get, & + tDict_get_scalar, & + tDict_get_list, & + tDict_get_dict, & + tDict_get_asFloat, & + tDict_get_as1dFloat, & + tDict_get_as2dFloat, & + tDict_get_asInt, & + tDict_get_as1dInt, & + tDict_get_asBool, & + tDict_get_as1dBool, & + tDict_get_asString, & + tDict_get_as1dString + generic :: get => tDict_get + generic :: get_scalar => tDict_get_scalar + generic :: get_list => tDict_get_list + generic :: get_dict => tDict_get_dict + generic :: get_asFloat => tDict_get_asFloat + generic :: get_as1dFloat => tDict_get_as1dFloat + generic :: get_as2dFloat => tDict_get_as2dFloat + generic :: get_asInt => tDict_get_asInt + generic :: get_as1dInt => tDict_get_as1dInt + generic :: get_asBool => tDict_get_asBool + generic :: get_as1dBool => tDict_get_as1dBool + generic :: get_asString => tDict_get_asString + generic :: get_as1dString => tDict_get_as1dString + end type tDict type, public :: tItem character(len=:), allocatable :: key class(tNode), pointer :: node => NULL() class(tItem), pointer :: next => NULL() - contains final :: tItem_finalize end type tItem @@ -161,11 +132,10 @@ module YAML_types abstract interface - recursive function asFormattedString(self,indent) + recursive function asFormattedString(self) import tNode character(len=:), allocatable :: asFormattedString class(tNode), intent(in), target :: self - integer, intent(in), optional :: indent end function asFormattedString end interface @@ -180,7 +150,9 @@ module YAML_types public :: & YAML_types_init, & +#ifdef __GFORTRAN__ output_as1dString, & !ToDo: Hack for GNU. Remove later +#endif assignment(=) contains @@ -192,7 +164,7 @@ subroutine YAML_types_init print'(/,1x,a)', '<<<+- YAML_types init -+>>>' - call selfTest + call selfTest() end subroutine YAML_types_init @@ -200,135 +172,146 @@ end subroutine YAML_types_init !-------------------------------------------------------------------------------------------------- !> @brief Check correctness of some type bound procedures. !-------------------------------------------------------------------------------------------------- -subroutine selfTest +subroutine selfTest() - class(tNode), pointer :: s1,s2,s3,s4 - allocate(tScalar::s1) - allocate(tScalar::s2) - allocate(tScalar::s3) - allocate(tScalar::s4) - select type(s1) - class is(tScalar) - s1 = '1' - if (s1%asInt() /= 1) error stop 'tScalar_asInt' - if (dNeq(s1%asFloat(),1.0_pReal)) error stop 'tScalar_asFloat' - s1 = 'true' - if (.not. s1%asBool()) error stop 'tScalar_asBool' - if (s1%asString() /= 'true') error stop 'tScalar_asString' - end select - - block - class(tNode), pointer :: l1, l2, l3, n - real(pReal), allocatable, dimension(:,:) :: x - - select type(s1) - class is(tScalar) - s1 = '2' - end select - - select type(s2) - class is(tScalar) - s2 = '3' - end select - - select type(s3) - class is(tScalar) - s3 = '4' - end select - - select type(s4) - class is(tScalar) - s4 = '5' - end select + scalar: block + type(tScalar), target :: s + type(tScalar), pointer :: s_pointer - allocate(tList::l1) - select type(l1) - class is(tList) - call l1%append(s1) - call l1%append(s2) - n => l1 - if (any(l1%as1dInt() /= [2,3])) error stop 'tList_as1dInt' - if (any(dNeq(l1%as1dFloat(),[2.0_pReal,3.0_pReal]))) error stop 'tList_as1dFloat' - if (n%get_asInt(1) /= 2) error stop 'byIndex_asInt' - if (dNeq(n%get_asFloat(2),3.0_pReal)) error stop 'byIndex_asFloat' - end select + s_pointer => s%asScalar() + s = '1' + if (s%asInt() /= 1) error stop 'tScalar_asInt' + if (s_pointer%asInt() /= 1) error stop 'tScalar_asInt(pointer)' + if (dNeq(s%asFloat(),1.0_pReal)) error stop 'tScalar_asFloat' + s = 'true' + if (.not. s%asBool()) error stop 'tScalar_asBool' + if (.not. s_pointer%asBool()) error stop 'tScalar_asBool(pointer)' + if (s%asString() /= 'true') error stop 'tScalar_asString' + if (s%asFormattedString() /= 'true') error stop 'tScalar_asFormattedString' - allocate(tList::l3) - select type(l3) - class is(tList) - call l3%append(s3) - call l3%append(s4) - end select - allocate(tList::l2) - select type(l2) - class is(tList) - call l2%append(l1) - if(any(l2%get_as1dInt(1) /= [2,3])) error stop 'byIndex_as1dInt' - if(any(dNeq(l2%get_as1dFloat(1),[2.0_pReal,3.0_pReal]))) error stop 'byIndex_as1dFloat' - call l2%append(l3) - x = l2%as2dFloat() - if(dNeq(x(2,1),4.0_pReal)) error stop 'byKey_as2dFloat' - if(any(dNeq(pack(l2%as2dFloat(),.true.),& - [2.0_pReal,4.0_pReal,3.0_pReal,5.0_pReal]))) error stop 'byKey_as2dFloat' - n => l2 - end select - deallocate(n) - end block + end block scalar - block - type(tList), target :: l1 - type(tScalar),pointer :: s3,s4 - class(tNode), pointer :: n + list: block + type(tList), pointer :: l, l_pointer + type(tScalar), pointer :: s1,s2 - allocate(tScalar::s1) - allocate(tScalar::s2) - s3 => s1%asScalar() - s4 => s2%asScalar() - s3 = 'true' - s4 = 'False' - call l1%append(s1) - call l1%append(s2) - n => l1 + allocate(s1) + allocate(s2) + s1 = '1' + s2 = '2' + allocate(l) + l_pointer => l%asList() + if (l%contains('1')) error stop 'empty tList_contains' + if (l_pointer%contains('1')) error stop 'empty tList_contains(pointer)' + call l%append(s1) + call l%append(s2) + if (l%length /= 2) error stop 'tList%len' + if (dNeq(l%get_asFloat(1),1.0_pReal)) error stop 'tList_get_asFloat' + if (l%get_asInt(1) /= 1) error stop 'tList_get_asInt' + if (l%get_asString(2) /= '2') error stop 'tList_get_asString' + if (any(l%as1dInt() /= [1,2])) error stop 'tList_as1dInt' + if (any(dNeq(l%as1dFloat(),real([1.0,2.0],pReal)))) error stop 'tList_as1dFloat' + s1 = 'true' + s2 = 'false' + if (any(l%as1dBool() .neqv. [.true.,.false.])) error stop 'tList_as1dBool' + if (any(l%as1dString() /= ['true ','false'])) error stop 'tList_as1dString' + if (l%asFormattedString() /= '[true, false]') error stop 'tList_asFormattedString' + if ( .not. l%contains('true') & + .or. .not. l%contains('false')) error stop 'tList_contains' - if (any(l1%as1dBool() .neqv. [.true., .false.])) error stop 'tList_as1dBool' - if (any(l1%as1dString() /= ['true ','False'])) error stop 'tList_as1dString' - if (n%get_asBool(2)) error stop 'byIndex_asBool' - if (n%get_asString(1) /= 'true') error stop 'byIndex_asString' - end block + end block list + + dict: block + type(tDict), pointer :: d, d_pointer + type(tList), pointer :: l + type(tScalar), pointer :: s1,s2,s3,s4 + + + allocate(s1) + allocate(s2) + s1 = '1' + s2 = '2' + allocate(l) + call l%append(s1) + call l%append(s2) + + allocate(s3) + allocate(s4) + s3 = '3' + s4 = '4' + allocate(d) + d_pointer => d%asDict() + if (d%contains('one-two')) error stop 'empty tDict_contains' + if (d_pointer%contains('one-two')) error stop 'empty tDict_contains(pointer)' + if (d%get_asInt('one-two',defaultVal=-1) /= -1) error stop 'empty tDict_get' + call d%set('one-two',l) + call d%set('three',s3) + call d%set('four',s4) + if (d%asFormattedString() /= '{one-two: [1, 2], three: 3, four: 4}') & + error stop 'tDict_asFormattedString' + if (d%get_asInt('three') /= 3) error stop 'tDict_get_asInt' + if (dNeq(d%get_asFloat('three'),3.0_pReal)) error stop 'tDict_get_asFloat' + if (d%get_asString('three') /= '3') error stop 'tDict_get_asString' + if (any(d%get_as1dInt('one-two') /= [1,2])) error stop 'tDict_get_as1dInt' + call d%set('one-two',s4) + if (d%asFormattedString() /= '{one-two: 4, three: 3, four: 4}') & + error stop 'tDict_set overwrite' + if ( .not. d%contains('one-two') & + .or. .not. d%contains('three') & + .or. .not. d%contains('four') & + ) error stop 'tDict_contains' + + end block dict end subroutine selfTest !--------------------------------------------------------------------------------------------------- -!> @brief init from string +!> @brief Init from string. !--------------------------------------------------------------------------------------------------- type(tScalar) pure function tScalar_init__(value) character(len=*), intent(in) :: value - tScalar_init__%value =value + + tScalar_init__%value = value end function tScalar_init__ !--------------------------------------------------------------------------------------------------- -!> @brief set value from string +!> @brief Set value from string. !--------------------------------------------------------------------------------------------------- elemental pure subroutine tScalar_assign__(self,value) type(tScalar), intent(out) :: self character(len=*), intent(in) :: value + self%value = value end subroutine tScalar_assign__ !-------------------------------------------------------------------------------------------------- -!> @brief Type guard, guarantee scalar +!> @brief Format as string (YAML flow style). +!-------------------------------------------------------------------------------------------------- +recursive function tScalar_asFormattedString(self) result(str) + + class (tScalar), intent(in), target :: self + character(len=:), allocatable :: str + + + str = trim(self%value) + +end function tScalar_asFormattedString + + +!-------------------------------------------------------------------------------------------------- +!> @brief Type guard, guarantee scalar. !-------------------------------------------------------------------------------------------------- function tNode_asScalar(self) result(scalar) @@ -341,13 +324,14 @@ function tNode_asScalar(self) result(scalar) scalar => self class default nullify(scalar) + call IO_error(706,'"'//trim(self%asFormattedString())//'" is not a scalar') end select end function tNode_asScalar !-------------------------------------------------------------------------------------------------- -!> @brief Type guard, guarantee list +!> @brief Type guard, guarantee list. !-------------------------------------------------------------------------------------------------- function tNode_asList(self) result(list) @@ -360,13 +344,14 @@ function tNode_asList(self) result(list) list => self class default nullify(list) + call IO_error(706,'"'//trim(self%asFormattedString())//'" is not a list') end select end function tNode_asList !-------------------------------------------------------------------------------------------------- -!> @brief Type guard, guarantee dict +!> @brief Type guard, guarantee dict. !-------------------------------------------------------------------------------------------------- function tNode_asDict(self) result(dict) @@ -379,967 +364,92 @@ function tNode_asDict(self) result(dict) dict => self class default nullify(dict) + call IO_error(706,'"'//trim(self%asFormattedString())//'" is not a dict') end select end function tNode_asDict !-------------------------------------------------------------------------------------------------- -!> @brief Access by index -!-------------------------------------------------------------------------------------------------- -function tNode_get_byIndex(self,i) result(node) - - class(tNode), intent(in), target :: self - integer, intent(in) :: i - class(tNode), pointer :: node - - class(tList), pointer :: self_ - class(tItem), pointer :: item - integer :: j - - - select type(self) - class is(tList) - self_ => self%asList() - class default - call IO_error(706,ext_msg='Expected list') - end select - - item => self_%first - - if (i < 1 .or. i > self_%length) call IO_error(150,ext_msg='tNode_get_byIndex') - - do j = 2,i - item => item%next - end do - node => item%node - -end function tNode_get_byIndex - - -!-------------------------------------------------------------------------------------------------- -!> @brief Access by index and convert to float -!-------------------------------------------------------------------------------------------------- -function tNode_get_byIndex_asFloat(self,i) result(nodeAsFloat) - - class(tNode), intent(in) :: self - integer, intent(in) :: i - real(pReal) :: nodeAsFloat - - type(tScalar), pointer :: scalar - - - select type(node => self%get(i)) - class is(tScalar) - scalar => node%asScalar() - nodeAsFloat = scalar%asFloat() - class default - call IO_error(706,ext_msg='Expected scalar float') - end select - -end function tNode_get_byIndex_asFloat - - -!-------------------------------------------------------------------------------------------------- -!> @brief Access by index and convert to int -!-------------------------------------------------------------------------------------------------- -function tNode_get_byIndex_asInt(self,i) result(nodeAsInt) - - class(tNode), intent(in) :: self - integer, intent(in) :: i - integer :: nodeAsInt - - class(tNode), pointer :: node - type(tScalar), pointer :: scalar - - - select type(node => self%get(i)) - class is(tScalar) - scalar => node%asScalar() - nodeAsInt = scalar%asInt() - class default - call IO_error(706,ext_msg='Expected scalar integer') - end select - -end function tNode_get_byIndex_asInt - - -!-------------------------------------------------------------------------------------------------- -!> @brief Access by index and convert to bool -!-------------------------------------------------------------------------------------------------- -function tNode_get_byIndex_asBool(self,i) result(nodeAsBool) - - class(tNode), intent(in) :: self - integer, intent(in) :: i - logical :: nodeAsBool - - type(tScalar), pointer :: scalar - - - select type(node => self%get(i)) - class is(tScalar) - scalar => node%asScalar() - nodeAsBool = scalar%asBool() - class default - call IO_error(706,ext_msg='Expected scalar Boolean') - end select - -end function tNode_get_byIndex_asBool - - -!-------------------------------------------------------------------------------------------------- -!> @brief Access by index and convert to string -!-------------------------------------------------------------------------------------------------- -function tNode_get_byIndex_asString(self,i) result(nodeAsString) - - class(tNode), intent(in) :: self - integer, intent(in) :: i - character(len=:), allocatable :: nodeAsString - - type(tScalar), pointer :: scalar - - - select type(node => self%get(i)) - class is(tScalar) - scalar => node%asScalar() - nodeAsString = scalar%asString() - class default - call IO_error(706,ext_msg='Expected scalar string') - end select - -end function tNode_get_byIndex_asString - - -!-------------------------------------------------------------------------------------------------- -!> @brief Access by index and convert to float array (1D) -!-------------------------------------------------------------------------------------------------- -function tNode_get_byIndex_as1dFloat(self,i) result(nodeAs1dFloat) - - class(tNode), intent(in) :: self - integer, intent(in) :: i - real(pReal), dimension(:), allocatable :: nodeAs1dFloat - - class(tList), pointer :: list - - - select type(node => self%get(i)) - class is(tList) - list => node%asList() - nodeAs1dFloat = list%as1dFloat() - class default - call IO_error(706,ext_msg='Expected list of floats') - end select - -end function tNode_get_byIndex_as1dFloat - - -!-------------------------------------------------------------------------------------------------- -!> @brief Access by index and convert to int array (1D) -!-------------------------------------------------------------------------------------------------- -function tNode_get_byIndex_as1dInt(self,i) result(nodeAs1dInt) - - class(tNode), intent(in) :: self - integer, intent(in) :: i - integer, dimension(:), allocatable :: nodeAs1dInt - - class(tList), pointer :: list - - - select type(node => self%get(i)) - class is(tList) - list => node%asList() - nodeAs1dInt = list%as1dInt() - class default - call IO_error(706,ext_msg='Expected list of integers') - end select - -end function tNode_get_byIndex_as1dInt - - -!-------------------------------------------------------------------------------------------------- -!> @brief Access by index and convert to bool array (1D) -!-------------------------------------------------------------------------------------------------- -function tNode_get_byIndex_as1dBool(self,i) result(nodeAs1dBool) - - class(tNode), intent(in) :: self - integer, intent(in) :: i - logical, dimension(:), allocatable :: nodeAs1dBool - - class(tList), pointer :: list - - - select type(node => self%get(i)) - class is(tList) - list => node%asList() - nodeAs1dBool = list%as1dBool() - class default - call IO_error(706,ext_msg='Expected list of Booleans') - end select - -end function tNode_get_byIndex_as1dBool - - -!-------------------------------------------------------------------------------------------------- -!> @brief Access by index and convert to string array (1D) -!-------------------------------------------------------------------------------------------------- -function tNode_get_byIndex_as1dString(self,i) result(nodeAs1dString) - - class(tNode), intent(in) :: self - integer, intent(in) :: i - character(len=:), allocatable, dimension(:) :: nodeAs1dString - - type(tList), pointer :: list - - - select type(node => self%get(i)) - class is(tList) - list => node%asList() - nodeAs1dString = list%as1dString() - class default - call IO_error(706,ext_msg='Expected list of strings') - end select - -end function tNode_get_byIndex_as1dString - - -!-------------------------------------------------------------------------------------------------- -!> @brief Returns the key in a dictionary as a string -!-------------------------------------------------------------------------------------------------- -function tNode_get_byIndex_asKey(self,i) result(key) - - class(tNode), intent(in), target :: self - integer, intent(in) :: i - - character(len=:), allocatable :: key - integer :: j - type(tDict), pointer :: dict - type(tItem), pointer :: item - - - select type(self) - class is(tDict) - dict => self%asDict() - item => dict%first - do j = 1, min(i,dict%length)-1 - item => item%next - end do - class default - call IO_error(706,ext_msg='Expected dict') - end select - - key = item%key - -end function tNode_get_byIndex_asKey - - -!-------------------------------------------------------------------------------------------------- -!> @brief Get all keys from a dictionary -!-------------------------------------------------------------------------------------------------- -function tNode_getKeys(self) result(keys) - - class(tNode), intent(in) :: self - character(len=:), dimension(:), allocatable :: keys - - character(len=pStringLen), dimension(:), allocatable :: temp - integer :: j, l - - - allocate(temp(self%length)) - l = 0 - do j = 1, self%length - temp(j) = self%getKey(j) - l = max(len_trim(temp(j)),l) - end do - - allocate(character(l)::keys(self%length)) - do j = 1, self%length - keys(j) = trim(temp(j)) - end do - -end function tNode_getKeys - - -!------------------------------------------------------------------------------------------------- -!> @brief Checks if a given key/item is present in the dict/list -!------------------------------------------------------------------------------------------------- -function tNode_contains(self,k) result(exists) - - class(tNode), intent(in), target :: self - character(len=*), intent(in) :: k - - logical :: exists - integer :: j - type(tList), pointer :: list - type(tDict), pointer :: dict - - exists = .false. - select type(self) - class is(tDict) - dict => self%asDict() - do j=1, dict%length - if (dict%getKey(j) == k) then - exists = .true. - return - end if - end do - class is(tList) - list => self%asList() - do j=1, list%length - if (list%get_asString(j) == k) then - exists = .true. - return - end if - end do - class default - call IO_error(706,ext_msg='Expected list or dict') - end select - -end function tNode_contains - - -!-------------------------------------------------------------------------------------------------- -!> @brief Access by key -!-------------------------------------------------------------------------------------------------- -function tNode_get_byKey(self,k,defaultVal) result(node) - - class(tNode), intent(in), target :: self - character(len=*), intent(in) :: k - class(tNode), intent(in),optional,target :: defaultVal - class(tNode), pointer :: node - - type(tDict), pointer :: self_ - type(tItem), pointer :: item - integer :: j - logical :: found - - found = present(defaultVal) - if (found) node => defaultVal - - select type(self) - class is(tDict) - self_ => self%asDict() - class default - call IO_error(706,ext_msg='Expected dict for key '//k) - end select - - j = 1 - item => self_%first - do while(j <= self_%length) - if (item%key == k) then - found = .true. - exit - end if - item => item%next - j = j + 1 - end do - - if (.not. found) then - call IO_error(143,ext_msg=k) - else - if (associated(item)) node => item%node - end if - -end function tNode_get_byKey - - -!-------------------------------------------------------------------------------------------------- -!> @brief Access by key and convert to float -!-------------------------------------------------------------------------------------------------- -function tNode_get_byKey_asFloat(self,k,defaultVal) result(nodeAsFloat) - - class(tNode), intent(in) :: self - character(len=*), intent(in) :: k - real(pReal), intent(in), optional :: defaultVal - real(pReal) :: nodeAsFloat - - type(tScalar), pointer :: scalar - - - if (self%contains(k)) then - select type(node => self%get(k)) - class is(tScalar) - scalar => node%asScalar() - nodeAsFloat = scalar%asFloat() - class default - call IO_error(706,ext_msg='Expected scalar float for key '//k) - end select - elseif (present(defaultVal)) then - nodeAsFloat = defaultVal - else - call IO_error(143,ext_msg=k) - end if - -end function tNode_get_byKey_asFloat - - -!-------------------------------------------------------------------------------------------------- -!> @brief Access by key and convert to int -!-------------------------------------------------------------------------------------------------- -function tNode_get_byKey_asInt(self,k,defaultVal) result(nodeAsInt) - - class(tNode), intent(in) :: self - character(len=*), intent(in) :: k - integer, intent(in), optional :: defaultVal - integer :: nodeAsInt - - type(tScalar), pointer :: scalar - - - if (self%contains(k)) then - select type(node => self%get(k)) - class is(tScalar) - scalar => node%asScalar() - nodeAsInt = scalar%asInt() - class default - call IO_error(706,ext_msg='Expected scalar integer for key '//k) - end select - elseif (present(defaultVal)) then - nodeAsInt = defaultVal - else - call IO_error(143,ext_msg=k) - end if - -end function tNode_get_byKey_asInt - - -!-------------------------------------------------------------------------------------------------- -!> @brief Access by key and convert to bool -!-------------------------------------------------------------------------------------------------- -function tNode_get_byKey_asBool(self,k,defaultVal) result(nodeAsBool) - - class(tNode), intent(in) :: self - character(len=*), intent(in) :: k - logical, intent(in), optional :: defaultVal - logical :: nodeAsBool - - type(tScalar), pointer :: scalar - - - if (self%contains(k)) then - select type(node => self%get(k)) - class is(tScalar) - scalar => node%asScalar() - nodeAsBool = scalar%asBool() - class default - call IO_error(706,ext_msg='Expected scalar Boolean for key '//k) - end select - elseif (present(defaultVal)) then - nodeAsBool = defaultVal - else - call IO_error(143,ext_msg=k) - end if - -end function tNode_get_byKey_asBool - - -!-------------------------------------------------------------------------------------------------- -!> @brief Access by key and convert to string -!-------------------------------------------------------------------------------------------------- -function tNode_get_byKey_asString(self,k,defaultVal) result(nodeAsString) - - class(tNode), intent(in) :: self - character(len=*), intent(in) :: k - character(len=*), intent(in), optional :: defaultVal - character(len=:), allocatable :: nodeAsString - - type(tScalar), pointer :: scalar - - - if (self%contains(k)) then - select type(node => self%get(k)) - class is(tScalar) - scalar => node%asScalar() - nodeAsString = scalar%asString() - class default - call IO_error(706,ext_msg='Expected scalar string for key '//k) - end select - elseif (present(defaultVal)) then - nodeAsString = defaultVal - else - call IO_error(143,ext_msg=k) - end if - -end function tNode_get_byKey_asString - - -!-------------------------------------------------------------------------------------------------- -!> @brief Access by key and convert to float array (1D) -!-------------------------------------------------------------------------------------------------- -function tNode_get_byKey_as1dFloat(self,k,defaultVal,requiredSize) result(nodeAs1dFloat) - - class(tNode), intent(in) :: self - character(len=*), intent(in) :: k - real(pReal), intent(in), dimension(:), optional :: defaultVal - integer, intent(in), optional :: requiredSize - - real(pReal), dimension(:), allocatable :: nodeAs1dFloat - - type(tList), pointer :: list - - - if (self%contains(k)) then - select type(node => self%get(k)) - class is(tList) - list => node%asList() - nodeAs1dFloat = list%as1dFloat() - class default - call IO_error(706,ext_msg='Expected 1D float array for key '//k) - end select - elseif (present(defaultVal)) then - nodeAs1dFloat = defaultVal - else - call IO_error(143,ext_msg=k) - end if - - if (present(requiredSize)) then - if (requiredSize /= size(nodeAs1dFloat)) call IO_error(146,ext_msg=k) - end if - -end function tNode_get_byKey_as1dFloat - - -!-------------------------------------------------------------------------------------------------- -!> @brief Access by key and convert to float array (2D) -!-------------------------------------------------------------------------------------------------- -function tNode_get_byKey_as2dFloat(self,k,defaultVal,requiredShape) result(nodeAs2dFloat) - - class(tNode), intent(in) :: self - character(len=*), intent(in) :: k - real(pReal), intent(in), dimension(:,:), optional :: defaultVal - integer, intent(in), dimension(2), optional :: requiredShape - - real(pReal), dimension(:,:), allocatable :: nodeAs2dFloat - - type(tList), pointer :: rows - - - if(self%contains(k)) then - select type(node => self%get(k)) - class is(tList) - rows => node%asList() - nodeAs2dFloat = rows%as2dFloat() - class default - call IO_error(706,ext_msg='Expected 2D float array for key '//k) - end select - elseif(present(defaultVal)) then - nodeAs2dFloat = defaultVal - else - call IO_error(143,ext_msg=k) - end if - - if (present(requiredShape)) then - if (any(requiredShape /= shape(nodeAs2dFloat))) call IO_error(146,ext_msg=k) - end if - -end function tNode_get_byKey_as2dFloat - - -!-------------------------------------------------------------------------------------------------- -!> @brief Access by key and convert to int array (1D) -!-------------------------------------------------------------------------------------------------- -function tNode_get_byKey_as1dInt(self,k,defaultVal,requiredSize) result(nodeAs1dInt) - - class(tNode), intent(in) :: self - character(len=*), intent(in) :: k - integer, dimension(:), intent(in), optional :: defaultVal - integer, intent(in), optional :: requiredSize - integer, dimension(:), allocatable :: nodeAs1dInt - - type(tList), pointer :: list - - if (self%contains(k)) then - select type(node => self%get(k)) - class is(tList) - list => node%asList() - nodeAs1dInt = list%as1dInt() - class default - call IO_error(706,ext_msg='Expected 1D integer array for key '//k) - end select - elseif (present(defaultVal)) then - nodeAs1dInt = defaultVal - else - call IO_error(143,ext_msg=k) - end if - - if (present(requiredSize)) then - if (requiredSize /= size(nodeAs1dInt)) call IO_error(146,ext_msg=k) - end if - -end function tNode_get_byKey_as1dInt - - -!-------------------------------------------------------------------------------------------------- -!> @brief Access by key and convert to bool array (1D) -!-------------------------------------------------------------------------------------------------- -function tNode_get_byKey_as1dBool(self,k,defaultVal) result(nodeAs1dBool) - - class(tNode), intent(in) :: self - character(len=*), intent(in) :: k - logical, dimension(:), intent(in), optional :: defaultVal - logical, dimension(:), allocatable :: nodeAs1dBool - - type(tList), pointer :: list - - - if (self%contains(k)) then - select type(node => self%get(k)) - class is(tList) - list => node%asList() - nodeAs1dBool = list%as1dBool() - class default - call IO_error(706,ext_msg='Expected 1D Boolean array for key '//k) - end select - elseif (present(defaultVal)) then - nodeAs1dBool = defaultVal - else - call IO_error(143,ext_msg=k) - end if - -end function tNode_get_byKey_as1dBool - - -!-------------------------------------------------------------------------------------------------- -!> @brief Access by key and convert to string array (1D) -!-------------------------------------------------------------------------------------------------- -function tNode_get_byKey_as1dString(self,k,defaultVal) result(nodeAs1dString) - - class(tNode), intent(in) :: self - character(len=*), intent(in) :: k - character(len=*), intent(in), dimension(:), optional :: defaultVal - character(len=:), allocatable, dimension(:) :: nodeAs1dString - - type(tList), pointer :: list - - - if (self%contains(k)) then - select type(node => self%get(k)) - class is(tList) - list => node%asList() - nodeAs1dString = list%as1dString() - class default - call IO_error(706,ext_msg='Expected 1D string array for key '//k) - end select - elseif (present(defaultVal)) then - nodeAs1dString = defaultVal - else - call IO_error(143,ext_msg=k) - end if - -end function tNode_get_byKey_as1dString - - -!-------------------------------------------------------------------------------------------------- -!> @brief Returns string output array (1D) (hack for GNU) -!-------------------------------------------------------------------------------------------------- -function output_as1dString(self) result(output) !ToDo: SR: Remove whenever GNU works - - class(tNode), pointer,intent(in) :: self - character(len=pStringLen), allocatable, dimension(:) :: output - - class(tNode), pointer :: output_list - integer :: o - - output_list => self%get('output',defaultVal=emptyList) - allocate(output(output_list%length)) - do o = 1, output_list%length - output(o) = output_list%get_asString(o) - end do - -end function output_as1dString - - -!-------------------------------------------------------------------------------------------------- -!> @brief Returns the index of a key in a dictionary -!-------------------------------------------------------------------------------------------------- -function tNode_get_byKey_asIndex(self,key) result(keyIndex) - - class(tNode), intent(in), target :: self - character(len=*), intent(in) :: key - - integer :: keyIndex - type(tDict), pointer :: dict - type(tItem), pointer :: item - - dict => self%asDict() - item => dict%first - keyIndex = 1 - do while (associated(item%next) .and. item%key /= key) - item => item%next - keyIndex = keyIndex+1 - end do - - if (item%key /= key) call IO_error(140,ext_msg=key) - -end function tNode_get_byKey_asIndex - - -!-------------------------------------------------------------------------------------------------- -!> @brief Scalar as string (YAML block style) -!-------------------------------------------------------------------------------------------------- -recursive function tScalar_asFormattedString(self,indent) - - character(len=:), allocatable :: tScalar_asFormattedString - class (tScalar), intent(in), target :: self - integer, intent(in), optional :: indent - - tScalar_asFormattedString = trim(self%value)//IO_EOL - -end function tScalar_asFormattedString - - -!-------------------------------------------------------------------------------------------------- -!> @brief List as string (YAML block style) -!-------------------------------------------------------------------------------------------------- -recursive function tList_asFormattedString(self,indent) result(str) - - class (tList),intent(in),target :: self - integer, intent(in),optional :: indent - - type (tItem), pointer :: item - character(len=:), allocatable :: str - integer :: i, indent_ - - str = '' - if (present(indent)) then - indent_ = indent - else - indent_ = 0 - end if - - item => self%first - do i = 1, self%length - if (i /= 1) str = str//repeat(' ',indent_) - str = str//'- '//item%node%asFormattedString(indent_+2) - item => item%next - end do - -end function tList_asFormattedString - - -!-------------------------------------------------------------------------------------------------- -!> @brief Dictionary as string (YAML block style) -!-------------------------------------------------------------------------------------------------- -recursive function tDict_asFormattedString(self,indent) result(str) - - class (tDict),intent(in),target :: self - integer, intent(in),optional :: indent - - type (tItem),pointer :: item - character(len=:), allocatable :: str - integer :: i, indent_ - - str = '' - if (present(indent)) then - indent_ = indent - else - indent_ = 0 - end if - - item => self%first - do i = 1, self%length - if (i /= 1) str = str//repeat(' ',indent_) - select type(node_1 =>item%node) - class is(tScalar) - str = str//trim(item%key)//': '//item%node%asFormattedString(indent_+len_trim(item%key)+2) - class default - str = str//trim(item%key)//':'//IO_EOL//repeat(' ',indent_+2)//item%node%asFormattedString(indent_+2) - end select - item => item%next - end do - -end function tDict_asFormattedString - - -!-------------------------------------------------------------------------------------------------- -!> @brief Convert to float +!> @brief Convert to float. !-------------------------------------------------------------------------------------------------- function tScalar_asFloat(self) class(tScalar), intent(in), target :: self real(pReal) :: tScalar_asFloat + tScalar_asFloat = IO_stringAsFloat(self%value) end function tScalar_asFloat !-------------------------------------------------------------------------------------------------- -!> @brief Convert to int +!> @brief Convert to int. !-------------------------------------------------------------------------------------------------- function tScalar_asInt(self) class(tScalar), intent(in), target :: self integer :: tScalar_asInt + tScalar_asInt = IO_stringAsInt(self%value) end function tScalar_asInt !-------------------------------------------------------------------------------------------------- -!> @brief Convert to bool +!> @brief Convert to bool. !-------------------------------------------------------------------------------------------------- function tScalar_asBool(self) class(tScalar), intent(in), target :: self logical :: tScalar_asBool + tScalar_asBool = IO_stringAsBool(self%value) end function tScalar_asBool !-------------------------------------------------------------------------------------------------- -!> @brief Convert to string +!> @brief Convert to string. !-------------------------------------------------------------------------------------------------- function tScalar_asString(self) class(tScalar), intent(in), target :: self character(len=:), allocatable :: tScalar_asString + tScalar_asString = self%value end function tScalar_asString !-------------------------------------------------------------------------------------------------- -!> @brief Convert to float array (1D) +!> @brief Format as string (YAML flow style). !-------------------------------------------------------------------------------------------------- -function tList_as1dFloat(self) +recursive function tList_asFormattedString(self) result(str) - class(tList), intent(in), target :: self - real(pReal), dimension(:), allocatable :: tList_as1dFloat + class(tList),intent(in),target :: self + type(tItem), pointer :: item + character(len=:), allocatable :: str integer :: i - type(tItem), pointer :: item - type(tScalar), pointer :: scalar - - allocate(tList_as1dFloat(self%length)) + str = '[' item => self%first - do i = 1, self%length - scalar => item%node%asScalar() - if (.not. associated(scalar)) call IO_error(711,ext_msg='float scalar') - tList_as1dFloat(i) = scalar%asFloat() + do i = 2, self%length + str = str//item%node%asFormattedString()//', ' item => item%next end do + str = str//item%node%asFormattedString()//']' -end function tList_as1dFloat +end function tList_asFormattedString !-------------------------------------------------------------------------------------------------- -!> @brief Convert to float array (2D) -!-------------------------------------------------------------------------------------------------- -function tList_as2dFloat(self) - - class(tList), intent(in), target :: self - real(pReal), dimension(:,:), allocatable :: tList_as2dFloat - - integer :: i - class(tNode), pointer :: row - type(tList), pointer :: row_data - - - row => self%get(1) - row_data => row%asList() - allocate(tList_as2dFloat(self%length,row_data%length)) - - do i=1,self%length - row => self%get(i) - row_data => row%asList() - if (.not. associated(row_data)) call IO_error(711,ext_msg='list of floats') - if (row_data%length /= size(tList_as2dFloat,2)) call IO_error(709,ext_msg='Varying number of columns') - tList_as2dFloat(i,:) = self%get_as1dFloat(i) - end do - -end function tList_as2dFloat - - -!-------------------------------------------------------------------------------------------------- -!> @brief Convert to int array (1D) -!-------------------------------------------------------------------------------------------------- -function tList_as1dInt(self) - - class(tList), intent(in), target :: self - integer, dimension(:), allocatable :: tList_as1dInt - - integer :: i - type(tItem), pointer :: item - type(tScalar), pointer :: scalar - - - allocate(tList_as1dInt(self%length)) - item => self%first - do i = 1, self%length - scalar => item%node%asScalar() - if (.not. associated(scalar)) call IO_error(711,ext_msg='int scalar') - tList_as1dInt(i) = scalar%asInt() - item => item%next - end do - -end function tList_as1dInt - - -!-------------------------------------------------------------------------------------------------- -!> @brief Convert to bool array (1D) -!-------------------------------------------------------------------------------------------------- -function tList_as1dBool(self) - - class(tList), intent(in), target :: self - logical, dimension(:), allocatable :: tList_as1dBool - - integer :: i - type(tItem), pointer :: item - type(tScalar), pointer :: scalar - - - allocate(tList_as1dBool(self%length)) - item => self%first - do i = 1, self%length - scalar => item%node%asScalar() - if (.not. associated(scalar)) call IO_error(711,ext_msg='bool scalar') - tList_as1dBool(i) = scalar%asBool() - item => item%next - end do - -end function tList_as1dBool - - -!-------------------------------------------------------------------------------------------------- -!> @brief Convert to string array (1D) -!-------------------------------------------------------------------------------------------------- -function tList_as1dString(self) - - class(tList), intent(in), target :: self - character(len=:), allocatable, dimension(:) :: tList_as1dString - - integer :: i,len_max - type(tItem), pointer :: item - type(tScalar), pointer :: scalar - - - len_max = 0 - item => self%first - do i = 1, self%length - scalar => item%node%asScalar() - if (.not. associated(scalar)) call IO_error(711,ext_msg='string scalar') - len_max = max(len_max, len_trim(scalar%asString())) - item => item%next - end do - - allocate(character(len=len_max) :: tList_as1dString(self%length)) - item => self%first - do i = 1, self%length - scalar => item%node%asScalar() - tList_as1dString(i) = scalar%asString() - item => item%next - end do - -end function tList_as1dString - - -!-------------------------------------------------------------------------------------------------- -!> @brief Append element +!> @brief Append element. !-------------------------------------------------------------------------------------------------- subroutine tList_append(self,node) @@ -1348,6 +458,7 @@ subroutine tList_append(self,node) type(tItem), pointer :: item + if (.not. associated(self%first)) then allocate(item) self%first => item @@ -1365,7 +476,428 @@ end subroutine tList_append !-------------------------------------------------------------------------------------------------- -!> @brief Set the value of a key (either replace or add new) +!> @brief Convert to float array (1D). +!-------------------------------------------------------------------------------------------------- +function tList_as1dFloat(self) + + class(tList), intent(in), target :: self + real(pReal), dimension(:), allocatable :: tList_as1dFloat + + integer :: i + type(tItem), pointer :: item + type(tScalar), pointer :: scalar + + + allocate(tList_as1dFloat(self%length)) + item => self%first + do i = 1, self%length + scalar => item%node%asScalar() + tList_as1dFloat(i) = scalar%asFloat() + item => item%next + end do + +end function tList_as1dFloat + + +!-------------------------------------------------------------------------------------------------- +!> @brief Convert to float array (2D). +!-------------------------------------------------------------------------------------------------- +function tList_as2dFloat(self) + + class(tList), intent(in), target :: self + real(pReal), dimension(:,:), allocatable :: tList_as2dFloat + + integer :: i + type(tList), pointer :: row_data + + + row_data => self%get_list(1) + allocate(tList_as2dFloat(self%length,row_data%length)) + + do i = 1, self%length + row_data => self%get_list(i) + if (row_data%length /= size(tList_as2dFloat,2)) call IO_error(709,ext_msg='inconsistent column count in tList_as2dFloat') + tList_as2dFloat(i,:) = self%get_as1dFloat(i) + end do + +end function tList_as2dFloat + + +!-------------------------------------------------------------------------------------------------- +!> @brief Convert to int array (1D). +!-------------------------------------------------------------------------------------------------- +function tList_as1dInt(self) + + class(tList), intent(in), target :: self + integer, dimension(:), allocatable :: tList_as1dInt + + integer :: i + type(tItem), pointer :: item + type(tScalar), pointer :: scalar + + + allocate(tList_as1dInt(self%length)) + item => self%first + do i = 1, self%length + scalar => item%node%asScalar() + tList_as1dInt(i) = scalar%asInt() + item => item%next + end do + +end function tList_as1dInt + + +!-------------------------------------------------------------------------------------------------- +!> @brief Convert to bool array (1D). +!-------------------------------------------------------------------------------------------------- +function tList_as1dBool(self) + + class(tList), intent(in), target :: self + logical, dimension(:), allocatable :: tList_as1dBool + + integer :: i + type(tItem), pointer :: item + type(tScalar), pointer :: scalar + + + allocate(tList_as1dBool(self%length)) + item => self%first + do i = 1, self%length + scalar => item%node%asScalar() + tList_as1dBool(i) = scalar%asBool() + item => item%next + end do + +end function tList_as1dBool + + +!-------------------------------------------------------------------------------------------------- +!> @brief Convert to string array (1D). +!-------------------------------------------------------------------------------------------------- +function tList_as1dString(self) + + class(tList), intent(in), target :: self +#ifdef __GFORTRAN__ + character(len=pStringLen), allocatable, dimension(:) :: tList_as1dString +#else + character(len=:), allocatable, dimension(:) :: tList_as1dString +#endif + + integer :: j + type(tItem), pointer :: item + type(tScalar), pointer :: scalar + + +#ifdef __GFORTRAN__ + allocate(tList_as1dString(self%length)) +#else + integer :: len_max + len_max = 0 + item => self%first + do j = 1, self%length + scalar => item%node%asScalar() + len_max = max(len_max, len_trim(scalar%asString())) + item => item%next + end do + + allocate(character(len=len_max) :: tList_as1dString(self%length)) +#endif + item => self%first + do j = 1, self%length + scalar => item%node%asScalar() + tList_as1dString(j) = scalar%asString() + item => item%next + end do + +end function tList_as1dString + + +!------------------------------------------------------------------------------------------------- +!> @brief Check for existence of (string) value. +!------------------------------------------------------------------------------------------------- +function tList_contains(self,k) result(exists) + + class(tList), intent(in), target :: self + character(len=*), intent(in) :: k + logical :: exists + + integer :: j + type(tItem), pointer :: item + type(tScalar), pointer :: scalar + + + item => self%first + exists = .false. + j = 1 + do while (j <= self%length .and. .not. exists) + scalar => item%node%asScalar() + exists = scalar%value == k + item => item%next + j = j + 1 + end do + +end function tList_contains + + +!-------------------------------------------------------------------------------------------------- +!> @brief Get by index. +!-------------------------------------------------------------------------------------------------- +function tList_get(self,i) result(node) + + class(tList), intent(in), target :: self + integer, intent(in) :: i + class(tNode), pointer :: node + + class(tItem), pointer :: item + integer :: j + + + if (i < 1 .or. i > self%length) call IO_error(150,ext_msg='tList_get @ '//IO_intAsString(i) & + //' of '//IO_intAsString(self%length) ) + item => self%first + do j = 2, i + item => item%next + end do + node => item%node + +end function tList_get + + +!-------------------------------------------------------------------------------------------------- +!> @brief Get scalar by index. +!-------------------------------------------------------------------------------------------------- +function tList_get_scalar(self,i) result(nodeAsScalar) + + class(tList), intent(in) :: self + integer, intent(in) :: i + type(tScalar), pointer :: nodeAsScalar + + class(tNode), pointer :: node + + + node => self%get(i) + nodeAsScalar => node%asScalar() + +end function tList_get_scalar + + +!-------------------------------------------------------------------------------------------------- +!> @brief Get list by index. +!-------------------------------------------------------------------------------------------------- +function tList_get_list(self,i) result(nodeAsList) + + class(tList), intent(in) :: self + integer, intent(in) :: i + type(tList), pointer :: nodeAsList + + class(tNode), pointer :: node + + + node => self%get(i) + nodeAsList => node%asList() + +end function tList_get_list + + +!-------------------------------------------------------------------------------------------------- +!> @brief Get dict by index. +!-------------------------------------------------------------------------------------------------- +function tList_get_dict(self,i) result(nodeAsDict) + + class(tList), intent(in) :: self + integer, intent(in) :: i + type(tDict), pointer :: nodeAsDict + + class(tNode), pointer :: node + + + node => self%get(i) + nodeAsDict => node%asDict() + +end function tList_get_dict + + +!-------------------------------------------------------------------------------------------------- +!> @brief Get scalar by index and convert to float. +!-------------------------------------------------------------------------------------------------- +function tList_get_asFloat(self,i) result(nodeAsFloat) + + class(tList), intent(in) :: self + integer, intent(in) :: i + real(pReal) :: nodeAsFloat + + class(tScalar), pointer :: scalar + + + scalar => self%get_scalar(i) + nodeAsFloat = scalar%asFloat() + +end function tList_get_asFloat + + +!-------------------------------------------------------------------------------------------------- +!> @brief Get list by index and convert to float array (1D). +!-------------------------------------------------------------------------------------------------- +function tList_get_as1dFloat(self,i) result(nodeAs1dFloat) + + class(tList), intent(in) :: self + integer, intent(in) :: i + real(pReal), dimension(:), allocatable :: nodeAs1dFloat + + class(tList), pointer :: list + + + list => self%get_list(i) + nodeAs1dFloat = list%as1dFloat() + +end function tList_get_as1dFloat + + +!-------------------------------------------------------------------------------------------------- +!> @brief Get scalar by index and convert to int. +!-------------------------------------------------------------------------------------------------- +function tList_get_asInt(self,i) result(nodeAsInt) + + class(tList), intent(in) :: self + integer, intent(in) :: i + integer :: nodeAsInt + + class(tScalar), pointer :: scalar + + + scalar => self%get_scalar(i) + nodeAsInt = scalar%asInt() + +end function tList_get_asInt + + +!-------------------------------------------------------------------------------------------------- +!> @brief Get list by index and convert to int array (1D). +!-------------------------------------------------------------------------------------------------- +function tList_get_as1dInt(self,i) result(nodeAs1dInt) + + class(tList), intent(in) :: self + integer, intent(in) :: i + integer, dimension(:), allocatable :: nodeAs1dInt + + class(tList), pointer :: list + + + list => self%get_list(i) + nodeAs1dInt = list%as1dInt() + +end function tList_get_as1dInt + + +!-------------------------------------------------------------------------------------------------- +!> @brief Get scalar by index and convert to bool +!-------------------------------------------------------------------------------------------------- +function tList_get_asBool(self,i) result(nodeAsBool) + + class(tList), intent(in) :: self + integer, intent(in) :: i + logical :: nodeAsBool + + class(tScalar), pointer :: scalar + + + scalar => self%get_scalar(i) + nodeAsBool = scalar%asBool() + +end function tList_get_asBool + + +!-------------------------------------------------------------------------------------------------- +!> @brief Get list by index and convert to bool array (1D). +!-------------------------------------------------------------------------------------------------- +function tList_get_as1dBool(self,i) result(nodeAs1dBool) + + class(tList), intent(in) :: self + integer, intent(in) :: i + logical, dimension(:), allocatable :: nodeAs1dBool + + class(tList), pointer :: list + + + list => self%get_list(i) + nodeAs1dBool = list%as1dBool() + +end function tList_get_as1dBool + + +!-------------------------------------------------------------------------------------------------- +!> @brief Get scalar by index and convert to string. +!-------------------------------------------------------------------------------------------------- +function tList_get_asString(self,i) result(nodeAsString) + + class(tList), intent(in) :: self + integer, intent(in) :: i + character(len=:), allocatable :: nodeAsString + + class(tScalar), pointer :: scalar + + + scalar => self%get_scalar(i) + nodeAsString = scalar%asString() + +end function tList_get_asString + + +!-------------------------------------------------------------------------------------------------- +!> @brief Get list by index and convert to string array (1D). +!-------------------------------------------------------------------------------------------------- +function tList_get_as1dString(self,i) result(nodeAs1dString) + + class(tList), intent(in) :: self + integer, intent(in) :: i + character(len=:), allocatable, dimension(:) :: nodeAs1dString + + type(tList), pointer :: list + + + list => self%get_list(i) + nodeAs1dString = list%as1dString() + +end function tList_get_as1dString + + +!-------------------------------------------------------------------------------------------------- +!> @brief Free associated memory. +!-------------------------------------------------------------------------------------------------- +recursive subroutine tList_finalize(self) + + type (tList),intent(inout) :: self + + deallocate(self%first) + +end subroutine tList_finalize + + +!-------------------------------------------------------------------------------------------------- +!> @brief Format as string (YAML flow style). +!-------------------------------------------------------------------------------------------------- +recursive function tDict_asFormattedString(self) result(str) + + class(tDict),intent(in),target :: self + + type(tItem),pointer :: item + character(len=:), allocatable :: str + integer :: i + + + str = '{' + item => self%first + do i = 2, self%length + str = str//trim(item%key)//': '//item%node%asFormattedString()//', ' + item => item%next + end do + str = str//trim(item%key)//': '//item%node%asFormattedString()//'}' + +end function tDict_asFormattedString + + +!-------------------------------------------------------------------------------------------------- +!> @brief Set value (either replace or add new). !-------------------------------------------------------------------------------------------------- subroutine tDict_set(self,key,node) @@ -1375,14 +907,14 @@ subroutine tDict_set(self,key,node) type(tItem), pointer :: item + if (.not. associated(self%first)) then allocate(self%first) item => self%first self%length = 1 else item => self%first - searchExisting: do while (associated(item%next)) - if (item%key == key) exit + searchExisting: do while (associated(item%next) .and. item%key /= key) item => item%next end do searchExisting if (item%key /= key) then @@ -1399,20 +931,456 @@ end subroutine tDict_set !-------------------------------------------------------------------------------------------------- -!> @brief empties lists and dicts and free associated memory -!> @details called when variable goes out of scope. +!> @brief Return the index of a key. !-------------------------------------------------------------------------------------------------- -recursive subroutine tList_finalize(self) +function tDict_index(self,key) result(keyIndex) - type (tList),intent(inout) :: self + class(tDict), intent(in), target :: self + character(len=*), intent(in) :: key - deallocate(self%first) + integer :: keyIndex + type(tItem), pointer :: item -end subroutine tList_finalize + + item => self%first + keyIndex = 1 + do while (associated(item%next) .and. item%key /= key) + item => item%next + keyIndex = keyIndex+1 + end do + + if (item%key /= key) call IO_error(140,ext_msg=key) + +end function tDict_index !-------------------------------------------------------------------------------------------------- -!> @brief empties nodes and frees associated memory +!> @brief Get key of given index. +!-------------------------------------------------------------------------------------------------- +function tDict_key(self,i) result(key) + + class(tDict), intent(in), target :: self + integer, intent(in) :: i + + character(len=:), allocatable :: key + integer :: j + type(tItem), pointer :: item + + + if (i < 1 .or. i > self%length) call IO_error(150,ext_msg='tDict_key @ '//IO_intAsString(i) & + //' of '//IO_intAsString(self%length) ) + item => self%first + do j = 2, i + item => item%next + end do + + key = item%key + +end function tDict_key + + +!-------------------------------------------------------------------------------------------------- +!> @brief Get all keys. +!-------------------------------------------------------------------------------------------------- +function tDict_keys(self) result(keys) + + class(tDict), intent(in) :: self + character(len=:), dimension(:), allocatable :: keys + + character(len=pStringLen), dimension(:), allocatable :: temp + integer :: j, l + + + allocate(temp(self%length)) + l = 0 + do j = 1, self%length + temp(j) = self%key(j) + l = max(len_trim(temp(j)),l) + end do + + allocate(character(l)::keys(self%length)) + do j = 1, self%length + keys(j) = trim(temp(j)) + end do + +end function tDict_keys + + +!------------------------------------------------------------------------------------------------- +!> @brief Check whether a given key is present. +!------------------------------------------------------------------------------------------------- +function tDict_contains(self,k) result(exists) + + class(tDict), intent(in), target :: self + character(len=*), intent(in) :: k + logical :: exists + + integer :: j + + + exists = .false. + j = 1 + do while(j <= self%length .and. .not. exists) + exists = self%key(j) == k + j = j + 1 + end do + +end function tDict_contains + + +!-------------------------------------------------------------------------------------------------- +!> @brief Get by key. +!-------------------------------------------------------------------------------------------------- +function tDict_get(self,k,defaultVal) result(node) + + class(tDict), intent(in), target :: self + character(len=*), intent(in) :: k + class(tNode), intent(in),optional,target :: defaultVal + class(tNode), pointer :: node + + type(tItem), pointer :: item + integer :: j + + item => self%first + + do j=1, self%length + if (item%key == k) then + node => item%node + return + end if + item => item%next + end do + + if (present(defaultVal)) then + node => defaultVal + else + call IO_error(143,ext_msg=k) + end if + +end function tDict_get + + +!-------------------------------------------------------------------------------------------------- +!> @brief Get scalar by key. +!-------------------------------------------------------------------------------------------------- +function tDict_get_scalar(self,k,defaultVal) result(nodeAsScalar) + + class(tDict), intent(in) :: self + character(len=*), intent(in) :: k + type(tScalar), intent(in), optional, target :: defaultVal + type(tScalar), pointer :: nodeAsScalar + + class(tNode), pointer :: node + + + node => self%get(k,defaultVal) + nodeAsScalar => node%asScalar() + +end function tDict_get_scalar + + +!-------------------------------------------------------------------------------------------------- +!> @brief Get list by key. +!-------------------------------------------------------------------------------------------------- +function tDict_get_list(self,k,defaultVal) result(nodeAsList) + + class(tDict), intent(in) :: self + character(len=*), intent(in) :: k + type(tList), intent(in), optional, target :: defaultVal + type(tList), pointer :: nodeAsList + + class(tNode), pointer :: node + + + node => self%get(k,defaultVal) + nodeAsList => node%asList() + +end function tDict_get_list + + +!-------------------------------------------------------------------------------------------------- +!> @brief Get dict by key. +!-------------------------------------------------------------------------------------------------- +function tDict_get_dict(self,k,defaultVal) result(nodeAsDict) + + class(tDict), intent(in) :: self + character(len=*), intent(in) :: k + type(tDict), intent(in), optional, target :: defaultVal + type(tDict), pointer :: nodeAsDict + + class(tNode), pointer :: node + + + node => self%get(k,defaultVal) + nodeAsDict => node%asDict() + +end function tDict_get_dict + + +!-------------------------------------------------------------------------------------------------- +!> @brief Get scalar by key and convert to float. +!-------------------------------------------------------------------------------------------------- +function tDict_get_asFloat(self,k,defaultVal) result(nodeAsFloat) + + class(tDict), intent(in) :: self + character(len=*), intent(in) :: k + real(pReal), intent(in), optional :: defaultVal + real(pReal) :: nodeAsFloat + + type(tScalar), pointer :: scalar + + + if (self%contains(k)) then + scalar => self%get_scalar(k) + nodeAsFloat = scalar%asFloat() + elseif (present(defaultVal)) then + nodeAsFloat = defaultVal + else + call IO_error(143,ext_msg=k) + end if + +end function tDict_get_asFloat + + +!-------------------------------------------------------------------------------------------------- +!> @brief Get list by key and convert to float array (1D). +!-------------------------------------------------------------------------------------------------- +function tDict_get_as1dFloat(self,k,defaultVal,requiredSize) result(nodeAs1dFloat) + + class(tDict), intent(in) :: self + character(len=*), intent(in) :: k + real(pReal), intent(in), dimension(:), optional :: defaultVal + integer, intent(in), optional :: requiredSize + real(pReal), dimension(:), allocatable :: nodeAs1dFloat + + type(tList), pointer :: list + + + if (self%contains(k)) then + list => self%get_list(k) + nodeAs1dFloat = list%as1dFloat() + elseif (present(defaultVal)) then + nodeAs1dFloat = defaultVal + else + call IO_error(143,ext_msg=k) + end if + + if (present(requiredSize)) then + if (requiredSize /= size(nodeAs1dFloat)) call IO_error(146,ext_msg=k) + end if + +end function tDict_get_as1dFloat + + +!-------------------------------------------------------------------------------------------------- +!> @brief Get list of lists by key and convert to float array (2D). +!-------------------------------------------------------------------------------------------------- +function tDict_get_as2dFloat(self,k,defaultVal,requiredShape) result(nodeAs2dFloat) + + class(tDict), intent(in) :: self + character(len=*), intent(in) :: k + real(pReal), intent(in), dimension(:,:), optional :: defaultVal + integer, intent(in), dimension(2), optional :: requiredShape + real(pReal), dimension(:,:), allocatable :: nodeAs2dFloat + + type(tList), pointer :: list + + + if (self%contains(k)) then + list => self%get_list(k) + nodeAs2dFloat = list%as2dFloat() + elseif (present(defaultVal)) then + nodeAs2dFloat = defaultVal + else + call IO_error(143,ext_msg=k) + end if + + if (present(requiredShape)) then + if (any(requiredShape /= shape(nodeAs2dFloat))) call IO_error(146,ext_msg=k) + end if + +end function tDict_get_as2dFloat + + +!-------------------------------------------------------------------------------------------------- +!> @brief Get scalar by key and convert to int. +!-------------------------------------------------------------------------------------------------- +function tDict_get_asInt(self,k,defaultVal) result(nodeAsInt) + + class(tDict), intent(in) :: self + character(len=*), intent(in) :: k + integer, intent(in), optional :: defaultVal + integer :: nodeAsInt + + type(tScalar), pointer :: scalar + + + if (self%contains(k)) then + scalar => self%get_scalar(k) + nodeAsInt = scalar%asInt() + elseif (present(defaultVal)) then + nodeAsInt = defaultVal + else + call IO_error(143,ext_msg=k) + end if + +end function tDict_get_asInt + + +!-------------------------------------------------------------------------------------------------- +!> @brief Get list by key and convert to int array (1D). +!-------------------------------------------------------------------------------------------------- +function tDict_get_as1dInt(self,k,defaultVal,requiredSize) result(nodeAs1dInt) + + class(tDict), intent(in) :: self + character(len=*), intent(in) :: k + integer, dimension(:), intent(in), optional :: defaultVal + integer, intent(in), optional :: requiredSize + integer, dimension(:), allocatable :: nodeAs1dInt + + type(tList), pointer :: list + + + if (self%contains(k)) then + list => self%get_list(k) + nodeAs1dInt = list%as1dInt() + elseif (present(defaultVal)) then + nodeAs1dInt = defaultVal + else + call IO_error(143,ext_msg=k) + end if + + if (present(requiredSize)) then + if (requiredSize /= size(nodeAs1dInt)) call IO_error(146,ext_msg=k) + end if + +end function tDict_get_as1dInt + + +!-------------------------------------------------------------------------------------------------- +!> @brief Get scalar by key and convert to bool. +!-------------------------------------------------------------------------------------------------- +function tDict_get_asBool(self,k,defaultVal) result(nodeAsBool) + + class(tDict), intent(in) :: self + character(len=*), intent(in) :: k + logical, intent(in), optional :: defaultVal + logical :: nodeAsBool + + type(tScalar), pointer :: scalar + + + if (self%contains(k)) then + scalar => self%get_scalar(k) + nodeAsBool = scalar%asBool() + elseif (present(defaultVal)) then + nodeAsBool = defaultVal + else + call IO_error(143,ext_msg=k) + end if + +end function tDict_get_asBool + + +!-------------------------------------------------------------------------------------------------- +!> @brief Get list by key and convert to bool array (1D). +!-------------------------------------------------------------------------------------------------- +function tDict_get_as1dBool(self,k,defaultVal) result(nodeAs1dBool) + + class(tDict), intent(in) :: self + character(len=*), intent(in) :: k + logical, dimension(:), intent(in), optional :: defaultVal + logical, dimension(:), allocatable :: nodeAs1dBool + + type(tList), pointer :: list + + + if (self%contains(k)) then + list => self%get_list(k) + nodeAs1dBool = list%as1dBool() + elseif (present(defaultVal)) then + nodeAs1dBool = defaultVal + else + call IO_error(143,ext_msg=k) + end if + +end function tDict_get_as1dBool + + +!-------------------------------------------------------------------------------------------------- +!> @brief Get scalar by key and convert to string. +!-------------------------------------------------------------------------------------------------- +function tDict_get_asString(self,k,defaultVal) result(nodeAsString) + + class(tDict), intent(in) :: self + character(len=*), intent(in) :: k + character(len=*), intent(in), optional :: defaultVal + character(len=:), allocatable :: nodeAsString + + type(tScalar), pointer :: scalar + + + if (self%contains(k)) then + scalar => self%get_scalar(k) + nodeAsString = scalar%asString() + elseif (present(defaultVal)) then + nodeAsString = defaultVal + else + call IO_error(143,ext_msg=k) + end if + +end function tDict_get_asString + + +!-------------------------------------------------------------------------------------------------- +!> @brief Get list by key and convert to string array (1D). +!-------------------------------------------------------------------------------------------------- +function tDict_get_as1dString(self,k,defaultVal) result(nodeAs1dString) + + class(tDict), intent(in) :: self + character(len=*), intent(in) :: k + character(len=*), intent(in), dimension(:), optional :: defaultVal + character(len=:), allocatable, dimension(:) :: nodeAs1dString + + type(tList), pointer :: list + + + if (self%contains(k)) then + list => self%get_list(k) + nodeAs1dString = list%as1dString() + elseif (present(defaultVal)) then + nodeAs1dString = defaultVal + else + call IO_error(143,ext_msg=k) + end if + +end function tDict_get_as1dString + + +#ifdef __GFORTRAN__ +!-------------------------------------------------------------------------------------------------- +!> @brief Returns string output array (1D) (hack for GNU). +!-------------------------------------------------------------------------------------------------- +function output_as1dString(self) result(output) + + class(tDict), pointer,intent(in) :: self + character(len=pStringLen), allocatable, dimension(:) :: output + + type(tList), pointer :: output_list + integer :: o + + output_list => self%get_list('output',defaultVal=emptyList) + allocate(output(output_list%length)) + do o = 1, output_list%length + output(o) = output_list%get_asString(o) + end do + +end function output_as1dString +#endif + + +!-------------------------------------------------------------------------------------------------- +!> @brief Free associated memory. !-------------------------------------------------------------------------------------------------- recursive subroutine tItem_finalize(self) diff --git a/src/config.f90 b/src/config.f90 index 5c31e3b25..bb7386414 100644 --- a/src/config.f90 +++ b/src/config.f90 @@ -6,13 +6,13 @@ module config use IO use YAML_parse use YAML_types - use results + use result use parallelization implicit none(type,external) private - class(tNode), pointer, public :: & + type(tDict), pointer, public :: & config_material, & config_numerics, & config_debug @@ -52,13 +52,13 @@ subroutine parse_material() if (worldrank == 0) then print'(/,1x,a)', 'reading material.yaml'; flush(IO_STDOUT) fileContent = IO_read('material.yaml') - call results_openJobFile(parallel=.false.) - call results_writeDataset_str(fileContent,'setup','material.yaml','main configuration') - call results_closeJobFile + call result_openJobFile(parallel=.false.) + call result_writeDataset_str(fileContent,'setup','material.yaml','main configuration') + call result_closeJobFile end if call parallelization_bcast_str(fileContent) - config_material => YAML_parse_str(fileContent) + config_material => YAML_parse_str_asDict(fileContent) end subroutine parse_material @@ -81,14 +81,14 @@ subroutine parse_numerics() print'(1x,a)', 'reading numerics.yaml'; flush(IO_STDOUT) fileContent = IO_read('numerics.yaml') if (len(fileContent) > 0) then - call results_openJobFile(parallel=.false.) - call results_writeDataset_str(fileContent,'setup','numerics.yaml','numerics configuration') - call results_closeJobFile + call result_openJobFile(parallel=.false.) + call result_writeDataset_str(fileContent,'setup','numerics.yaml','numerics configuration') + call result_closeJobFile end if end if call parallelization_bcast_str(fileContent) - config_numerics => YAML_parse_str(fileContent) + config_numerics => YAML_parse_str_asDict(fileContent) end if @@ -113,14 +113,14 @@ subroutine parse_debug() print'(1x,a)', 'reading debug.yaml'; flush(IO_STDOUT) fileContent = IO_read('debug.yaml') if (len(fileContent) > 0) then - call results_openJobFile(parallel=.false.) - call results_writeDataset_str(fileContent,'setup','debug.yaml','debug configuration') - call results_closeJobFile + call result_openJobFile(parallel=.false.) + call result_writeDataset_str(fileContent,'setup','debug.yaml','debug configuration') + call result_closeJobFile end if end if call parallelization_bcast_str(fileContent) - config_debug => YAML_parse_str(fileContent) + config_debug => YAML_parse_str_asDict(fileContent) end if diff --git a/src/constants.f90 b/src/constants.f90 index 7d1892e9d..1cdbcc128 100644 --- a/src/constants.f90 +++ b/src/constants.f90 @@ -9,7 +9,7 @@ module constants public real(pReal), parameter :: & - T_ROOM = 293.15_pReal, & !< Room temperature in K (20°C) + T_ROOM = 293.15_pReal, & !< Room temperature (20°C) in K (https://en.wikipedia.org/wiki/ISO_1) K_B = 1.380649e-23_pReal, & !< Boltzmann constant in J/Kelvin (https://doi.org/10.1351/goldbook) N_A = 6.02214076e23_pReal !< Avogadro constant in 1/mol (https://doi.org/10.1351/goldbook) diff --git a/src/discretization.f90 b/src/discretization.f90 index f24b0eadf..ad08c5bff 100644 --- a/src/discretization.f90 +++ b/src/discretization.f90 @@ -5,7 +5,7 @@ module discretization use prec - use results + use result implicit none(type,external) private @@ -29,7 +29,7 @@ module discretization public :: & discretization_init, & - discretization_results, & + discretization_result, & discretization_setIPcoords, & discretization_setNodeCoords @@ -64,7 +64,7 @@ subroutine discretization_init(materialAt,& discretization_NodeCoords0 = NodeCoords0 discretization_NodeCoords = NodeCoords0 - if(present(sharedNodesBegin)) then + if (present(sharedNodesBegin)) then discretization_sharedNodesBegin = sharedNodesBegin else discretization_sharedNodesBegin = size(discretization_NodeCoords0,2) @@ -76,21 +76,21 @@ end subroutine discretization_init !-------------------------------------------------------------------------------------------------- !> @brief write the displacements !-------------------------------------------------------------------------------------------------- -subroutine discretization_results +subroutine discretization_result() real(pReal), dimension(:,:), allocatable :: u - call results_closeGroup(results_addGroup('current/geometry')) + call result_closeGroup(result_addGroup('current/geometry')) u = discretization_NodeCoords (:,:discretization_sharedNodesBegin) & - discretization_NodeCoords0(:,:discretization_sharedNodesBegin) - call results_writeDataset(u,'current/geometry','u_n','displacements of the nodes','m') + call result_writeDataset(u,'current/geometry','u_n','displacements of the nodes','m') u = discretization_IPcoords & - discretization_IPcoords0 - call results_writeDataset(u,'current/geometry','u_p','displacements of the materialpoints (cell centers)','m') + call result_writeDataset(u,'current/geometry','u_p','displacements of the materialpoints (cell centers)','m') -end subroutine discretization_results +end subroutine discretization_result !-------------------------------------------------------------------------------------------------- diff --git a/src/geometry_plastic_nonlocal.f90 b/src/geometry_plastic_nonlocal.f90 index 09c40f8b3..a0ec3d644 100644 --- a/src/geometry_plastic_nonlocal.f90 +++ b/src/geometry_plastic_nonlocal.f90 @@ -7,7 +7,7 @@ !-------------------------------------------------------------------------------------------------- module geometry_plastic_nonlocal use prec - use results + use result implicit none(type,external) public @@ -92,16 +92,16 @@ end subroutine geometry_plastic_nonlocal_setIPareaNormal !--------------------------------------------------------------------------------------------------- subroutine geometry_plastic_nonlocal_disable - if(allocated(geometry_plastic_nonlocal_IPneighborhood)) & + if (allocated(geometry_plastic_nonlocal_IPneighborhood)) & deallocate(geometry_plastic_nonlocal_IPneighborhood) - if(allocated(geometry_plastic_nonlocal_IPvolume0)) & + if (allocated(geometry_plastic_nonlocal_IPvolume0)) & deallocate(geometry_plastic_nonlocal_IPvolume0) - if(allocated(geometry_plastic_nonlocal_IParea0)) & + if (allocated(geometry_plastic_nonlocal_IParea0)) & deallocate(geometry_plastic_nonlocal_IParea0) - if(allocated(geometry_plastic_nonlocal_IPareaNormal0)) & + if (allocated(geometry_plastic_nonlocal_IPareaNormal0)) & deallocate(geometry_plastic_nonlocal_IPareaNormal0) end subroutine geometry_plastic_nonlocal_disable @@ -110,39 +110,39 @@ end subroutine geometry_plastic_nonlocal_disable !--------------------------------------------------------------------------------------------------- !> @brief Write geometry data to results file !--------------------------------------------------------------------------------------------------- -subroutine geometry_plastic_nonlocal_results +subroutine geometry_plastic_nonlocal_result() integer, dimension(:), allocatable :: shp - call results_openJobFile + call result_openJobFile writeVolume: block real(pReal), dimension(:), allocatable :: temp shp = shape(geometry_plastic_nonlocal_IPvolume0) temp = reshape(geometry_plastic_nonlocal_IPvolume0,[shp(1)*shp(2)]) - call results_writeDataset(temp,'geometry','v_0',& - 'initial cell volume','m³') + call result_writeDataset(temp,'geometry','v_0',& + 'initial cell volume','m³') end block writeVolume writeAreas: block real(pReal), dimension(:,:), allocatable :: temp shp = shape(geometry_plastic_nonlocal_IParea0) temp = reshape(geometry_plastic_nonlocal_IParea0,[shp(1),shp(2)*shp(3)]) - call results_writeDataset(temp,'geometry','a_0',& - 'initial cell face area','m²') + call result_writeDataset(temp,'geometry','a_0',& + 'initial cell face area','m²') end block writeAreas writeNormals: block real(pReal), dimension(:,:,:), allocatable :: temp shp = shape(geometry_plastic_nonlocal_IPareaNormal0) temp = reshape(geometry_plastic_nonlocal_IPareaNormal0,[shp(1),shp(2),shp(3)*shp(4)]) - call results_writeDataset(temp,'geometry','n_0',& - 'initial cell face normals','-',transposed=.false.) + call result_writeDataset(temp,'geometry','n_0',& + 'initial cell face normals','-',transposed=.false.) end block writeNormals - call results_closeJobFile + call result_closeJobFile -end subroutine geometry_plastic_nonlocal_results +end subroutine geometry_plastic_nonlocal_result end module geometry_plastic_nonlocal diff --git a/src/grid/DAMASK_grid.f90 b/src/grid/DAMASK_grid.f90 index 4395c1581..1af6b474a 100644 --- a/src/grid/DAMASK_grid.f90 +++ b/src/grid/DAMASK_grid.f90 @@ -15,7 +15,7 @@ program DAMASK_grid use prec use parallelization - use signals + use signal use CLI use IO use config @@ -28,7 +28,7 @@ program DAMASK_grid use grid_mechanical_FEM use grid_damage_spectral use grid_thermal_spectral - use results + use result #if (PETSC_VERSION_MAJOR==3 && PETSC_VERSION_MINOR>14) && !defined(PETSC_HAVE_MPI_F90MODULE_VISIBILITY) implicit none(type,external) @@ -73,7 +73,7 @@ program DAMASK_grid guess, & !< guess along former trajectory stagIterate, & cutBack = .false.,& - signal + sig integer :: & i, j, m, field, & errorID = 0, & @@ -106,15 +106,19 @@ program DAMASK_grid external :: & quit - class (tNode), pointer :: & - num_grid, & + type(tDict), pointer :: & config_load, & - load_steps, & + num_grid, & load_step, & solver, & step_bc, & step_mech, & step_discretization + type(tList), pointer :: & +#ifdef __INTEL_LLVM_COMPILER + tensor, & +#endif + load_steps character(len=:), allocatable :: & fileContent, fname @@ -130,7 +134,7 @@ program DAMASK_grid !------------------------------------------------------------------------------------------------- ! reading field paramters from numerics file and do sanity checks - num_grid => config_numerics%get('grid', defaultVal=emptyDict) + num_grid => config_numerics%get_dict('grid', defaultVal=emptyDict) stagItMax = num_grid%get_asInt('maxStaggeredIter',defaultVal=10) maxCutBack = num_grid%get_asInt('maxCutBack',defaultVal=3) @@ -141,14 +145,14 @@ program DAMASK_grid fileContent = IO_read(CLI_loadFile) fname = CLI_loadFile if (scan(fname,'/') /= 0) fname = fname(scan(fname,'/',.true.)+1:) - call results_openJobFile(parallel=.false.) - call results_writeDataset_str(fileContent,'setup',fname,'load case definition (grid solver)') - call results_closeJobFile - endif + call result_openJobFile(parallel=.false.) + call result_writeDataset_str(fileContent,'setup',fname,'load case definition (grid solver)') + call result_closeJobFile + end if call parallelization_bcast_str(fileContent) - config_load => YAML_parse_str(fileContent) - solver => config_load%get('solver') + config_load => YAML_parse_str_asDict(fileContent) + solver => config_load%get_dict('solver') !-------------------------------------------------------------------------------------------------- ! assign mechanics solver depending on selected type @@ -194,42 +198,50 @@ program DAMASK_grid thermalActive: if (solver%get_asString('thermal',defaultVal = 'n/a') == 'spectral') then field = field + 1 ID(field) = FIELD_THERMAL_ID - endif thermalActive + end if thermalActive damageActive: if (solver%get_asString('damage',defaultVal = 'n/a') == 'spectral') then field = field + 1 ID(field) = FIELD_DAMAGE_ID - endif damageActive + end if damageActive !-------------------------------------------------------------------------------------------------- - load_steps => config_load%get('loadstep') + load_steps => config_load%get_list('loadstep') allocate(loadCases(load_steps%length)) ! array of load cases do l = 1, load_steps%length - load_step => load_steps%get(l) - step_bc => load_step%get('boundary_conditions') - step_mech => step_bc%get('mechanical') + load_step => load_steps%get_dict(l) + step_bc => load_step%get_dict('boundary_conditions') + step_mech => step_bc%get_dict('mechanical') loadCases(l)%stress%myType='' readMech: do m = 1, step_mech%length - select case (step_mech%getKey(m)) + select case (step_mech%key(m)) case ('L','dot_F','F') ! assign values for the deformation BC matrix - loadCases(l)%deformation%myType = step_mech%getKey(m) - call getMaskedTensor(loadCases(l)%deformation%values,loadCases(l)%deformation%mask,step_mech%get(m)) + loadCases(l)%deformation%myType = step_mech%key(m) +#ifdef __INTEL_LLVM_COMPILER + tensor => step_mech%get_list(m) + call getMaskedTensor(loadCases(l)%deformation%values,loadCases(l)%deformation%mask,tensor) +#else + call getMaskedTensor(loadCases(l)%deformation%values,loadCases(l)%deformation%mask,step_mech%get_list(m)) +#endif case ('dot_P','P') - loadCases(l)%stress%myType = step_mech%getKey(m) - call getMaskedTensor(loadCases(l)%stress%values,loadCases(l)%stress%mask,step_mech%get(m)) + loadCases(l)%stress%myType = step_mech%key(m) +#ifdef __INTEL_LLVM_COMPILER + tensor => step_mech%get_list(m) + call getMaskedTensor(loadCases(l)%stress%values,loadCases(l)%stress%mask,tensor) +#else + call getMaskedTensor(loadCases(l)%stress%values,loadCases(l)%stress%mask,step_mech%get_list(m)) +#endif end select call loadCases(l)%rot%fromAxisAngle(step_mech%get_as1dFloat('R',defaultVal = real([0.0,0.0,1.0,0.0],pReal)),degrees=.true.) - enddo readMech + end do readMech if (.not. allocated(loadCases(l)%deformation%myType)) call IO_error(error_ID=837,ext_msg = 'L/dot_F/F missing') - step_discretization => load_step%get('discretization') - if (.not. step_discretization%contains('t')) call IO_error(error_ID=837,ext_msg = 't missing') - if (.not. step_discretization%contains('N')) call IO_error(error_ID=837,ext_msg = 'N missing') - loadCases(l)%t = step_discretization%get_asFloat('t') - loadCases(l)%N = step_discretization%get_asInt ('N') - loadCases(l)%r = step_discretization%get_asFloat('r', defaultVal= 1.0_pReal) + step_discretization => load_step%get_dict('discretization') + loadCases(l)%t = step_discretization%get_asFloat('t') + loadCases(l)%N = step_discretization%get_asInt ('N') + loadCases(l)%r = step_discretization%get_asFloat('r',defaultVal= 1.0_pReal) loadCases(l)%f_restart = load_step%get_asInt('f_restart', defaultVal=huge(0)) if (load_step%get_asString('f_out',defaultVal='n/a') == 'none') then @@ -252,9 +264,9 @@ program DAMASK_grid write(IO_STDOUT,'(2x,12a)',advance='no') ' x ' else write(IO_STDOUT,'(2x,f12.7)',advance='no') loadCases(l)%deformation%values(i,j) - endif - enddo; write(IO_STDOUT,'(/)',advance='no') - enddo + end if + end do; write(IO_STDOUT,'(/)',advance='no') + end do if (any(loadCases(l)%stress%mask .eqv. loadCases(l)%deformation%mask)) errorID = 831 if (any(.not.(loadCases(l)%stress%mask .or. transpose(loadCases(l)%stress%mask)) .and. (math_I3<1))) & errorID = 838 ! no rotation is allowed by stress BC @@ -268,10 +280,10 @@ program DAMASK_grid write(IO_STDOUT,'(2x,12a)',advance='no') ' x ' else write(IO_STDOUT,'(2x,f12.4)',advance='no') loadCases(l)%stress%values(i,j)*1e-6_pReal - endif - enddo; write(IO_STDOUT,'(/)',advance='no') - enddo - endif + end if + end do; write(IO_STDOUT,'(/)',advance='no') + end do + end if if (any(dNeq(loadCases(l)%rot%asMatrix(), math_I3))) & write(IO_STDOUT,'(2x,a,/,3(3(3x,f12.7,1x)/))',advance='no') 'R:',& transpose(loadCases(l)%rot%asMatrix()) @@ -286,7 +298,7 @@ program DAMASK_grid print'(2x,a)', 'r: 1 (constant step width)' else print'(2x,a,1x,f0.3)', 'r:', loadCases(l)%r - endif + end if print'(2x,a,1x,f0.3)', 't:', loadCases(l)%t print'(2x,a,1x,i0)', 'N:', loadCases(l)%N if (loadCases(l)%f_out < huge(0)) & @@ -296,8 +308,8 @@ program DAMASK_grid if (errorID > 0) call IO_error(errorID,label1='line',ID1=l) - endif reportAndCheck - enddo + end if reportAndCheck + end do !-------------------------------------------------------------------------------------------------- ! doing initialization depending on active solvers @@ -325,14 +337,14 @@ program DAMASK_grid else writeHeader open(newunit=statUnit,file=trim(getSolverJobName())//& '.sta',form='FORMATTED', position='APPEND', status='OLD') - endif writeHeader - endif + end if writeHeader + end if writeUndeformed: if (CLI_restartInc < 1) then print'(/,1x,a)', '... writing initial configuration to file .................................' flush(IO_STDOUT) - call materialpoint_results(0,0.0_pReal) - endif writeUndeformed + call materialpoint_result(0,0.0_pReal) + end if writeUndeformed loadCaseLooping: do l = 1, size(loadCases) t_0 = t ! load case start time @@ -349,7 +361,7 @@ program DAMASK_grid else Delta_t = loadCases(l)%t * (loadCases(l)%r**(inc-1)-loadCases(l)%r**inc) & / (1.0_pReal-loadCases(l)%r**loadCases(l)%N) - endif + end if Delta_t = Delta_t * real(subStepFactor,pReal)**real(-cutBackLevel,pReal) ! depending on cut back level, decrease time step skipping: if (totalIncsCounter <= CLI_restartInc) then ! not yet at restart inc? @@ -390,7 +402,7 @@ program DAMASK_grid case(FIELD_THERMAL_ID); call grid_thermal_spectral_forward(cutBack) case(FIELD_DAMAGE_ID); call grid_damage_spectral_forward(cutBack) end select - enddo + end do if (.not. cutBack) call materialpoint_forward !-------------------------------------------------------------------------------------------------- @@ -410,12 +422,12 @@ program DAMASK_grid if (.not. solres(field)%converged) exit ! no solution found - enddo + end do stagIter = stagIter + 1 stagIterate = stagIter < stagItMax & .and. all(solres(:)%converged) & .and. .not. all(solres(:)%stagConverged) ! stationary with respect to staggered iteration - enddo + end do !-------------------------------------------------------------------------------------------------- ! check solution for either advance or retry @@ -430,7 +442,7 @@ program DAMASK_grid write(statUnit,*) totalIncsCounter, t, cutBackLevel, & solres(1)%converged, solres(1)%iterationsNeeded flush(statUnit) - endif + end if elseif (cutBackLevel < maxCutBack) then ! further cutbacking tolerated? cutBack = .true. stepFraction = (stepFraction - 1) * subStepFactor ! adjust to new denominator @@ -441,9 +453,9 @@ program DAMASK_grid else ! no more options to continue if (worldrank == 0) close(statUnit) call IO_error(950) - endif + end if - enddo subStepLooping + end do subStepLooping cutBackLevel = max(0, cutBackLevel - 1) ! try half number of subincs next inc @@ -451,38 +463,40 @@ program DAMASK_grid print'(/,1x,a,i0,a)', 'increment ', totalIncsCounter, ' converged' else print'(/,1x,a,i0,a)', 'increment ', totalIncsCounter, ' NOT converged' - endif; flush(IO_STDOUT) + end if; flush(IO_STDOUT) - call MPI_Allreduce(signals_SIGUSR1,signal,1_MPI_INTEGER_KIND,MPI_LOGICAL,MPI_LOR,MPI_COMM_WORLD,err_MPI) + call MPI_Allreduce(signal_SIGUSR1,sig,1_MPI_INTEGER_KIND,MPI_LOGICAL,MPI_LOR,MPI_COMM_WORLD,err_MPI) if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' - if (mod(inc,loadCases(l)%f_out) == 0 .or. signal) then + if (mod(inc,loadCases(l)%f_out) == 0 .or. sig) then print'(/,1x,a)', '... writing results to file ...............................................' flush(IO_STDOUT) - call materialpoint_results(totalIncsCounter,t) - endif - if (signal) call signals_setSIGUSR1(.false.) - call MPI_Allreduce(signals_SIGUSR2,signal,1_MPI_INTEGER_KIND,MPI_LOGICAL,MPI_LOR,MPI_COMM_WORLD,err_MPI) + call materialpoint_result(totalIncsCounter,t) + end if + if (sig) call signal_setSIGUSR1(.false.) + call MPI_Allreduce(signal_SIGUSR2,sig,1_MPI_INTEGER_KIND,MPI_LOGICAL,MPI_LOR,MPI_COMM_WORLD,err_MPI) if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' - if (mod(inc,loadCases(l)%f_restart) == 0 .or. signal) then + if (mod(inc,loadCases(l)%f_restart) == 0 .or. sig) then do field = 1, nActiveFields select case (ID(field)) case(FIELD_MECH_ID) call mechanical_restartWrite case(FIELD_THERMAL_ID) call grid_thermal_spectral_restartWrite + case(FIELD_DAMAGE_ID) + call grid_damage_spectral_restartWrite end select end do call materialpoint_restartWrite - endif - if (signal) call signals_setSIGUSR2(.false.) - call MPI_Allreduce(signals_SIGINT,signal,1_MPI_INTEGER_KIND,MPI_LOGICAL,MPI_LOR,MPI_COMM_WORLD,err_MPI) + end if + if (sig) call signal_setSIGUSR2(.false.) + call MPI_Allreduce(signal_SIGINT,sig,1_MPI_INTEGER_KIND,MPI_LOGICAL,MPI_LOR,MPI_COMM_WORLD,err_MPI) if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' - if (signal) exit loadCaseLooping - endif skipping + if (sig) exit loadCaseLooping + end if skipping - enddo incLooping + end do incLooping - enddo loadCaseLooping + end do loadCaseLooping !-------------------------------------------------------------------------------------------------- @@ -499,21 +513,21 @@ subroutine getMaskedTensor(values,mask,tensor) real(pReal), intent(out), dimension(3,3) :: values logical, intent(out), dimension(3,3) :: mask - class (tNode), pointer :: tensor + type(tList), pointer :: tensor - class (tNode), pointer :: row + type(tList), pointer :: row integer :: i,j values = 0.0_pReal do i = 1,3 - row => tensor%get(i) + row => tensor%get_list(i) do j = 1,3 mask(i,j) = row%get_asString(j) == 'x' if (.not. mask(i,j)) values(i,j) = row%get_asFloat(j) - enddo - enddo + end do + end do -end subroutine +end subroutine getMaskedTensor end program DAMASK_grid diff --git a/src/grid/VTI.f90 b/src/grid/VTI.f90 index 5c3cb864a..cc5a6843b 100644 --- a/src/grid/VTI.f90 +++ b/src/grid/VTI.f90 @@ -222,7 +222,7 @@ subroutine cellsSizeOrigin(c,s,o,header) temp = getXMLValue(header,'Origin') o = [(IO_floatValue(temp,IO_stringPos(temp),i),i=1,3)] -end subroutine +end subroutine cellsSizeOrigin !-------------------------------------------------------------------------------------------------- @@ -421,7 +421,7 @@ pure function getXMLValue(line,key) end if end if -end function +end function getXMLValue !-------------------------------------------------------------------------------------------------- diff --git a/src/grid/base64.f90 b/src/grid/base64.f90 index 6e580f043..40986d783 100644 --- a/src/grid/base64.f90 +++ b/src/grid/base64.f90 @@ -73,27 +73,27 @@ function base64_to_bytes(base64_str,s,e) result(bytes) integer(pI64) :: s_bytes, e_bytes, s_str, e_str integer(C_SIGNED_CHAR), dimension(:), allocatable :: bytes - if(.not. validBase64(base64_str)) call IO_error(114,ext_msg='invalid character') + if (.not. validBase64(base64_str)) call IO_error(114,ext_msg='invalid character') - if(present(s)) then - if(s<1_pI64) call IO_error(114, ext_msg='s out of range') + if (present(s)) then + if (s<1_pI64) call IO_error(114, ext_msg='s out of range') s_str = ((s-1_pI64)/3_pI64)*4_pI64 + 1_pI64 s_bytes = mod(s-1_pI64,3_pI64) + 1_pI64 else s_str = 1_pI64 s_bytes = 1_pI64 - endif + end if - if(present(e)) then - if(e>base64_nByte(len(base64_str,kind=pI64))) call IO_error(114, ext_msg='e out of range') + if (present(e)) then + if (e>base64_nByte(len(base64_str,kind=pI64))) call IO_error(114, ext_msg='e out of range') e_str = ((e-1_pI64)/3_pI64)*4_pI64 + 4_pI64 e_bytes = e - base64_nByte(s_str) else e_str = len(base64_str,kind=pI64) e_bytes = base64_nByte(len(base64_str,kind=pI64)) - base64_nByte(s_str) - if(base64_str(e_str-0_pI64:e_str-0_pI64) == '=') e_bytes = e_bytes - 1_pI64 - if(base64_str(e_str-1_pI64:e_str-1_pI64) == '=') e_bytes = e_bytes - 1_pI64 - endif + if (base64_str(e_str-0_pI64:e_str-0_pI64) == '=') e_bytes = e_bytes - 1_pI64 + if (base64_str(e_str-1_pI64:e_str-1_pI64) == '=') e_bytes = e_bytes - 1_pI64 + end if bytes = decodeBase64(base64_str(s_str:e_str)) bytes = bytes(s_bytes:e_bytes) @@ -118,12 +118,12 @@ pure function decodeBase64(base64_str) result(bytes) do while(c < len(base64_str,kind=pI64)) do p=0_pI64,3_pI64 - if(c+p<=len(base64_str,kind=pI64)) then + if (c+p<=len(base64_str,kind=pI64)) then charPos(p) = int(index(base64_encoding,base64_str(c+p:c+p))-1,C_SIGNED_CHAR) else charPos(p) = 0_C_SIGNED_CHAR - endif - enddo + end if + end do call mvbits(charPos(0),0,6,bytes(b+0),2) call mvbits(charPos(1),4,2,bytes(b+0),0) @@ -133,7 +133,7 @@ pure function decodeBase64(base64_str) result(bytes) call mvbits(charPos(3),0,6,bytes(b+2),0) b = b+3_pI64 c = c+4_pI64 - enddo + end do end function decodeBase64 @@ -151,9 +151,9 @@ pure logical function validBase64(base64_str) l = len(base64_str,pI64) validBase64 = .true. - if(mod(l,4_pI64)/=0_pI64 .or. l < 4_pI64) validBase64 = .false. - if(verify(base64_str(:l-2_pI64),base64_encoding, kind=pI64) /= 0_pI64) validBase64 = .false. - if(verify(base64_str(l-1_pI64:),base64_encoding//'=',kind=pI64) /= 0_pI64) validBase64 = .false. + if (mod(l,4_pI64)/=0_pI64 .or. l < 4_pI64) validBase64 = .false. + if (verify(base64_str(:l-2_pI64),base64_encoding, kind=pI64) /= 0_pI64) validBase64 = .false. + if (verify(base64_str(l-1_pI64:),base64_encoding//'=',kind=pI64) /= 0_pI64) validBase64 = .false. end function validBase64 @@ -167,59 +167,59 @@ subroutine selfTest character(len=*), parameter :: zero_to_three = 'AAECAw==' ! https://en.wikipedia.org/wiki/Base64#Output_padding - if(base64_nChar(20_pI64) /= 28_pI64) error stop 'base64_nChar/20/28' - if(base64_nChar(19_pI64) /= 28_pI64) error stop 'base64_nChar/19/28' - if(base64_nChar(18_pI64) /= 24_pI64) error stop 'base64_nChar/18/24' - if(base64_nChar(17_pI64) /= 24_pI64) error stop 'base64_nChar/17/24' - if(base64_nChar(16_pI64) /= 24_pI64) error stop 'base64_nChar/16/24' + if (base64_nChar(20_pI64) /= 28_pI64) error stop 'base64_nChar/20/28' + if (base64_nChar(19_pI64) /= 28_pI64) error stop 'base64_nChar/19/28' + if (base64_nChar(18_pI64) /= 24_pI64) error stop 'base64_nChar/18/24' + if (base64_nChar(17_pI64) /= 24_pI64) error stop 'base64_nChar/17/24' + if (base64_nChar(16_pI64) /= 24_pI64) error stop 'base64_nChar/16/24' - if(base64_nByte(4_pI64) /= 3_pI64) error stop 'base64_nByte/4/3' - if(base64_nByte(8_pI64) /= 6_pI64) error stop 'base64_nByte/8/6' + if (base64_nByte(4_pI64) /= 3_pI64) error stop 'base64_nByte/4/3' + if (base64_nByte(8_pI64) /= 6_pI64) error stop 'base64_nByte/8/6' bytes = base64_to_bytes(zero_to_three) - if(any(bytes /= int([0,1,2,3],C_SIGNED_CHAR)) .or. size(bytes) /= 4) error stop 'base64_to_bytes//' + if (any(bytes /= int([0,1,2,3],C_SIGNED_CHAR)) .or. size(bytes) /= 4) error stop 'base64_to_bytes//' bytes = base64_to_bytes(zero_to_three,e=1_pI64) - if(any(bytes /= int([0],C_SIGNED_CHAR)) .or. size(bytes) /= 1) error stop 'base64_to_bytes//1' + if (any(bytes /= int([0],C_SIGNED_CHAR)) .or. size(bytes) /= 1) error stop 'base64_to_bytes//1' bytes = base64_to_bytes(zero_to_three,e=2_pI64) - if(any(bytes /= int([0,1],C_SIGNED_CHAR)) .or. size(bytes) /= 2) error stop 'base64_to_bytes//2' + if (any(bytes /= int([0,1],C_SIGNED_CHAR)) .or. size(bytes) /= 2) error stop 'base64_to_bytes//2' bytes = base64_to_bytes(zero_to_three,e=3_pI64) - if(any(bytes /= int([0,1,2],C_SIGNED_CHAR)) .or. size(bytes) /= 3) error stop 'base64_to_bytes//3' + if (any(bytes /= int([0,1,2],C_SIGNED_CHAR)) .or. size(bytes) /= 3) error stop 'base64_to_bytes//3' bytes = base64_to_bytes(zero_to_three,e=4_pI64) - if(any(bytes /= int([0,1,2,3],C_SIGNED_CHAR)) .or. size(bytes) /= 4) error stop 'base64_to_bytes//4' + if (any(bytes /= int([0,1,2,3],C_SIGNED_CHAR)) .or. size(bytes) /= 4) error stop 'base64_to_bytes//4' bytes = base64_to_bytes(zero_to_three,s=1_pI64) - if(any(bytes /= int([0,1,2,3],C_SIGNED_CHAR)) .or. size(bytes) /= 4) error stop 'base64_to_bytes/1/' + if (any(bytes /= int([0,1,2,3],C_SIGNED_CHAR)) .or. size(bytes) /= 4) error stop 'base64_to_bytes/1/' bytes = base64_to_bytes(zero_to_three,s=2_pI64) - if(any(bytes /= int([1,2,3],C_SIGNED_CHAR)) .or. size(bytes) /= 3) error stop 'base64_to_bytes/2/' + if (any(bytes /= int([1,2,3],C_SIGNED_CHAR)) .or. size(bytes) /= 3) error stop 'base64_to_bytes/2/' bytes = base64_to_bytes(zero_to_three,s=3_pI64) - if(any(bytes /= int([2,3],C_SIGNED_CHAR)) .or. size(bytes) /= 2) error stop 'base64_to_bytes/3/' + if (any(bytes /= int([2,3],C_SIGNED_CHAR)) .or. size(bytes) /= 2) error stop 'base64_to_bytes/3/' bytes = base64_to_bytes(zero_to_three,s=4_pI64) - if(any(bytes /= int([3],C_SIGNED_CHAR)) .or. size(bytes) /= 1) error stop 'base64_to_bytes/4/' + if (any(bytes /= int([3],C_SIGNED_CHAR)) .or. size(bytes) /= 1) error stop 'base64_to_bytes/4/' bytes = base64_to_bytes(zero_to_three,s=1_pI64,e=1_pI64) - if(any(bytes /= int([0],C_SIGNED_CHAR)) .or. size(bytes) /= 1) error stop 'base64_to_bytes/1/1' + if (any(bytes /= int([0],C_SIGNED_CHAR)) .or. size(bytes) /= 1) error stop 'base64_to_bytes/1/1' bytes = base64_to_bytes(zero_to_three,s=2_pI64,e=2_pI64) - if(any(bytes /= int([1],C_SIGNED_CHAR)) .or. size(bytes) /= 1) error stop 'base64_to_bytes/2/2' + if (any(bytes /= int([1],C_SIGNED_CHAR)) .or. size(bytes) /= 1) error stop 'base64_to_bytes/2/2' bytes = base64_to_bytes(zero_to_three,s=3_pI64,e=3_pI64) - if(any(bytes /= int([2],C_SIGNED_CHAR)) .or. size(bytes) /= 1) error stop 'base64_to_bytes/3/3' + if (any(bytes /= int([2],C_SIGNED_CHAR)) .or. size(bytes) /= 1) error stop 'base64_to_bytes/3/3' bytes = base64_to_bytes(zero_to_three,s=4_pI64,e=4_pI64) - if(any(bytes /= int([3],C_SIGNED_CHAR)) .or. size(bytes) /= 1) error stop 'base64_to_bytes/4/4' + if (any(bytes /= int([3],C_SIGNED_CHAR)) .or. size(bytes) /= 1) error stop 'base64_to_bytes/4/4' bytes = base64_to_bytes(zero_to_three,s=1_pI64,e=2_pI64) - if(any(bytes /= int([0,1],C_SIGNED_CHAR)) .or. size(bytes) /= 2) error stop 'base64_to_bytes/1/2' + if (any(bytes /= int([0,1],C_SIGNED_CHAR)) .or. size(bytes) /= 2) error stop 'base64_to_bytes/1/2' bytes = base64_to_bytes(zero_to_three,s=2_pI64,e=3_pI64) - if(any(bytes /= int([1,2],C_SIGNED_CHAR)) .or. size(bytes) /= 2) error stop 'base64_to_bytes/2/3' + if (any(bytes /= int([1,2],C_SIGNED_CHAR)) .or. size(bytes) /= 2) error stop 'base64_to_bytes/2/3' bytes = base64_to_bytes(zero_to_three,s=3_pI64,e=4_pI64) - if(any(bytes /= int([2,3],C_SIGNED_CHAR)) .or. size(bytes) /= 2) error stop 'base64_to_bytes/3/4' + if (any(bytes /= int([2,3],C_SIGNED_CHAR)) .or. size(bytes) /= 2) error stop 'base64_to_bytes/3/4' bytes = base64_to_bytes(zero_to_three,s=1_pI64,e=3_pI64) - if(any(bytes /= int([0,1,2],C_SIGNED_CHAR)) .or. size(bytes) /= 3) error stop 'base64_to_bytes/1/3' + if (any(bytes /= int([0,1,2],C_SIGNED_CHAR)) .or. size(bytes) /= 3) error stop 'base64_to_bytes/1/3' bytes = base64_to_bytes(zero_to_three,s=2_pI64,e=4_pI64) - if(any(bytes /= int([1,2,3],C_SIGNED_CHAR)) .or. size(bytes) /= 3) error stop 'base64_to_bytes/2/4' + if (any(bytes /= int([1,2,3],C_SIGNED_CHAR)) .or. size(bytes) /= 3) error stop 'base64_to_bytes/2/4' bytes = base64_to_bytes(zero_to_three,s=1_pI64,e=4_pI64) - if(any(bytes /= int([0,1,2,3],C_SIGNED_CHAR)) .or. size(bytes) /= 4) error stop 'base64_to_bytes/1/4' + if (any(bytes /= int([0,1,2,3],C_SIGNED_CHAR)) .or. size(bytes) /= 4) error stop 'base64_to_bytes/1/4' end subroutine selfTest diff --git a/src/grid/discretization_grid.f90 b/src/grid/discretization_grid.f90 index 158ee0a8d..a4db30f6a 100644 --- a/src/grid/discretization_grid.f90 +++ b/src/grid/discretization_grid.f90 @@ -19,7 +19,7 @@ module discretization_grid use CLI use IO use config - use results + use result use discretization use geometry_plastic_nonlocal @@ -89,9 +89,9 @@ subroutine discretization_grid_init(restart) call IO_error(180,ext_msg='mismatch in # of material IDs and cells') fname = CLI_geomFile if (scan(fname,'/') /= 0) fname = fname(scan(fname,'/',.true.)+1:) - call results_openJobFile(parallel=.false.) - call results_writeDataset_str(fileContent,'setup',fname,'geometry definition (grid solver)') - call results_closeJobFile + call result_openJobFile(parallel=.false.) + call result_writeDataset_str(fileContent,'setup',fname,'geometry definition (grid solver)') + call result_closeJobFile else allocate(materialAt_global(0)) ! needed for IntelMPI end if @@ -147,12 +147,12 @@ subroutine discretization_grid_init(restart) !-------------------------------------------------------------------------------------------------- ! store geometry information for post processing if (.not. restart) then - call results_openJobFile - call results_closeGroup(results_addGroup('geometry')) - call results_addAttribute('cells', cells, '/geometry') - call results_addAttribute('size', geomSize,'/geometry') - call results_addAttribute('origin',origin, '/geometry') - call results_closeJobFile + call result_openJobFile + call result_closeGroup(result_addGroup('geometry')) + call result_addAttribute('cells', cells, '/geometry') + call result_addAttribute('size', geomSize,'/geometry') + call result_addAttribute('origin',origin, '/geometry') + call result_closeJobFile end if !-------------------------------------------------------------------------------------------------- @@ -334,7 +334,7 @@ function discretization_grid_getInitialCondition(label) result(ic) ic_global = VTI_readDataset_real(IO_read(CLI_geomFile),label) else allocate(ic_global(0)) ! needed for IntelMPI - endif + end if call MPI_Gather(product(cells(1:2))*cells3Offset, 1_MPI_INTEGER_KIND,MPI_INTEGER,displs,& 1_MPI_INTEGER_KIND,MPI_INTEGER,0_MPI_INTEGER_KIND,MPI_COMM_WORLD,err_MPI) diff --git a/src/grid/grid_damage_spectral.f90 b/src/grid/grid_damage_spectral.f90 index 8b544ec87..e096ec3ef 100644 --- a/src/grid/grid_damage_spectral.f90 +++ b/src/grid/grid_damage_spectral.f90 @@ -16,6 +16,9 @@ module grid_damage_spectral use prec use parallelization use IO + use CLI + use HDF5_utilities + use HDF5 use spectral_utilities use discretization_grid use homogenization @@ -33,7 +36,7 @@ module grid_damage_spectral integer :: & itmax !< maximum number of iterations real(pReal) :: & - residualStiffness, & !< non-zero residual damage + phi_min, & !< non-zero residual damage eps_damage_atol, & !< absolute tolerance for damage evolution eps_damage_rtol !< relative tolerance for damage evolution end type tNumerics @@ -46,7 +49,7 @@ module grid_damage_spectral SNES :: SNES_damage Vec :: solution_vec real(pReal), dimension(:,:,:), allocatable :: & - phi_current, & !< field of current damage + phi, & !< field of current damage phi_lastInc, & !< field of previous damage phi_stagInc !< field of staggered damage @@ -59,22 +62,26 @@ module grid_damage_spectral public :: & grid_damage_spectral_init, & grid_damage_spectral_solution, & + grid_damage_spectral_restartWrite, & grid_damage_spectral_forward contains !-------------------------------------------------------------------------------------------------- !> @brief allocates all neccessary fields and fills them with data -! ToDo: Restart not implemented !-------------------------------------------------------------------------------------------------- subroutine grid_damage_spectral_init() PetscInt, dimension(0:worldsize-1) :: localK + integer :: i, j, k, ce DM :: damage_grid + real(pReal), dimension(:,:,:), pointer :: phi_PETSc Vec :: uBound, lBound integer(MPI_INTEGER_KIND) :: err_MPI PetscErrorCode :: err_PETSc - class(tNode), pointer :: & + integer(HID_T) :: fileHandle, groupHandle + real(pReal), dimension(1,product(cells(1:2))*cells3) :: tempN + type(tDict), pointer :: & num_grid, & num_generic character(len=pStringLen) :: & @@ -85,17 +92,19 @@ subroutine grid_damage_spectral_init() print'(/,1x,a)', 'P. Shanthraj et al., Handbook of Mechanics of Materials, 2019' print'( 1x,a)', 'https://doi.org/10.1007/978-981-10-6855-3_80' + if (.not. homogenization_damage_active()) call IO_error(501,ext_msg='damage') + !------------------------------------------------------------------------------------------------- ! read numerical parameters and do sanity checks - num_grid => config_numerics%get('grid',defaultVal=emptyDict) + num_grid => config_numerics%get_dict('grid',defaultVal=emptyDict) num%itmax = num_grid%get_asInt ('itmax',defaultVal=250) num%eps_damage_atol = num_grid%get_asFloat ('eps_damage_atol',defaultVal=1.0e-2_pReal) num%eps_damage_rtol = num_grid%get_asFloat ('eps_damage_rtol',defaultVal=1.0e-6_pReal) - num_generic => config_numerics%get('generic',defaultVal=emptyDict) - num%residualStiffness = num_generic%get_asFloat('residualStiffness', defaultVal=1.0e-6_pReal) + num_generic => config_numerics%get_dict('generic',defaultVal=emptyDict) + num%phi_min = num_generic%get_asFloat('phi_min', defaultVal=1.0e-6_pReal) - if (num%residualStiffness < 0.0_pReal) call IO_error(301,ext_msg='residualStiffness') + if (num%phi_min < 0.0_pReal) call IO_error(301,ext_msg='phi_min') if (num%itmax <= 1) call IO_error(301,ext_msg='itmax') if (num%eps_damage_atol <= 0.0_pReal) call IO_error(301,ext_msg='eps_damage_atol') if (num%eps_damage_rtol <= 0.0_pReal) call IO_error(301,ext_msg='eps_damage_rtol') @@ -110,9 +119,9 @@ subroutine grid_damage_spectral_init() !-------------------------------------------------------------------------------------------------- ! init fields - allocate(phi_current(cells(1),cells(2),cells3), source=1.0_pReal) - allocate(phi_lastInc(cells(1),cells(2),cells3), source=1.0_pReal) - allocate(phi_stagInc(cells(1),cells(2),cells3), source=1.0_pReal) + phi = discretization_grid_getInitialCondition('phi') + phi_lastInc = phi + phi_stagInc = phi !-------------------------------------------------------------------------------------------------- ! initialize solver specific parts of PETSc @@ -164,7 +173,29 @@ subroutine grid_damage_spectral_init() call DMRestoreGlobalVector(damage_grid,uBound,err_PETSc) CHKERRQ(err_PETSc) end if - call VecSet(solution_vec,1.0_pReal,err_PETSc) + + restartRead: if (CLI_restartInc > 0) then + print'(/,1x,a,i0,a)', 'reading restart data of increment ', CLI_restartInc, ' from file' + + fileHandle = HDF5_openFile(getSolverJobName()//'_restart.hdf5','r') + groupHandle = HDF5_openGroup(fileHandle,'solver') + + call HDF5_read(tempN,groupHandle,'phi',.false.) + phi = reshape(tempN,[cells(1),cells(2),cells3]) + call HDF5_read(tempN,groupHandle,'phi_lastInc',.false.) + phi_lastInc = reshape(tempN,[cells(1),cells(2),cells3]) + end if restartRead + + ce = 0 + do k = 1, cells3; do j = 1, cells(2); do i = 1, cells(1) + ce = ce + 1 + call homogenization_set_phi(phi(i,j,k),ce) + end do; end do; end do + + call DMDAVecGetArrayF90(damage_grid,solution_vec,phi_PETSc,err_PETSc) + CHKERRQ(err_PETSc) + phi_PETSc = phi + call DMDAVecRestoreArrayF90(damage_grid,solution_vec,phi_PETSc,err_PETSc) CHKERRQ(err_PETSc) call updateReference() @@ -206,20 +237,20 @@ function grid_damage_spectral_solution(Delta_t) result(solution) solution%converged = .true. solution%iterationsNeeded = totalIter end if - stagNorm = maxval(abs(phi_current - phi_stagInc)) + stagNorm = maxval(abs(phi - phi_stagInc)) call MPI_Allreduce(MPI_IN_PLACE,stagNorm,1_MPI_INTEGER_KIND,MPI_DOUBLE,MPI_MAX,MPI_COMM_WORLD,err_MPI) if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' - solution%stagConverged = stagNorm < max(num%eps_damage_atol, num%eps_damage_rtol*maxval(phi_current)) + solution%stagConverged = stagNorm < max(num%eps_damage_atol, num%eps_damage_rtol*maxval(phi)) call MPI_Allreduce(MPI_IN_PLACE,solution%stagConverged,1_MPI_INTEGER_KIND,MPI_LOGICAL,MPI_LAND,MPI_COMM_WORLD,err_MPI) if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' - phi_stagInc = phi_current + phi_stagInc = phi !-------------------------------------------------------------------------------------------------- ! updating damage state ce = 0 do k = 1, cells3; do j = 1, cells(2); do i = 1,cells(1) ce = ce + 1 - call homogenization_set_phi(phi_current(i,j,k),ce) + call homogenization_set_phi(phi(i,j,k),ce) end do; end do; end do call VecMin(solution_vec,devNull,phi_min,err_PETSc) @@ -241,13 +272,15 @@ end function grid_damage_spectral_solution subroutine grid_damage_spectral_forward(cutBack) logical, intent(in) :: cutBack + integer :: i, j, k, ce DM :: dm_local - PetscScalar, dimension(:,:,:), pointer :: phi_PETSc + real(pReal), dimension(:,:,:), pointer :: phi_PETSc PetscErrorCode :: err_PETSc + if (cutBack) then - phi_current = phi_lastInc + phi = phi_lastInc phi_stagInc = phi_lastInc !-------------------------------------------------------------------------------------------------- ! reverting damage field state @@ -255,16 +288,16 @@ subroutine grid_damage_spectral_forward(cutBack) CHKERRQ(err_PETSc) call DMDAVecGetArrayF90(dm_local,solution_vec,phi_PETSc,err_PETSc) !< get the data out of PETSc to work with CHKERRQ(err_PETSc) - phi_PETSc = phi_current + phi_PETSc = phi call DMDAVecRestoreArrayF90(dm_local,solution_vec,phi_PETSc,err_PETSc) CHKERRQ(err_PETSc) ce = 0 do k = 1, cells3; do j = 1, cells(2); do i = 1,cells(1) ce = ce + 1 - call homogenization_set_phi(phi_current(i,j,k),ce) + call homogenization_set_phi(phi(i,j,k),ce) end do; end do; end do else - phi_lastInc = phi_current + phi_lastInc = phi call updateReference end if @@ -272,68 +305,78 @@ end subroutine grid_damage_spectral_forward !-------------------------------------------------------------------------------------------------- -!> @brief forms the spectral damage residual vector +!> @brief Write current solver and constitutive data for restart to file. !-------------------------------------------------------------------------------------------------- -subroutine formResidual(in,x_scal,r,dummy,err_PETSc) +subroutine grid_damage_spectral_restartWrite + + PetscErrorCode :: err_PETSc + DM :: dm_local + integer(HID_T) :: fileHandle, groupHandle + PetscScalar, dimension(:,:,:), pointer :: phi + + call SNESGetDM(SNES_damage,dm_local,err_PETSc); + CHKERRQ(err_PETSc) + call DMDAVecGetArrayF90(dm_local,solution_vec,phi,err_PETSc); + CHKERRQ(err_PETSc) + + print'(1x,a)', 'writing damage solver data required for restart to file'; flush(IO_STDOUT) + + fileHandle = HDF5_openFile(getSolverJobName()//'_restart.hdf5','a') + groupHandle = HDF5_openGroup(fileHandle,'solver') + call HDF5_write(reshape(phi,[1,product(cells(1:2))*cells3]),groupHandle,'phi') + call HDF5_write(reshape(phi_lastInc,[1,product(cells(1:2))*cells3]),groupHandle,'phi_lastInc') + call HDF5_closeGroup(groupHandle) + call HDF5_closeFile(fileHandle) + + call DMDAVecRestoreArrayF90(dm_local,solution_vec,phi,err_PETSc); + CHKERRQ(err_PETSc) + +end subroutine grid_damage_spectral_restartWrite + + +!-------------------------------------------------------------------------------------------------- +!> @brief Construct the residual vector. +!-------------------------------------------------------------------------------------------------- +subroutine formResidual(residual_subdomain,x_scal,r,dummy,err_PETSc) DMDALocalInfo, dimension(DMDA_LOCAL_INFO_SIZE) :: & - in - PetscScalar, dimension( & - XG_RANGE,YG_RANGE,ZG_RANGE), intent(in) :: & + residual_subdomain + real(pReal), dimension(cells(1),cells(2),cells3), intent(in) :: & x_scal - PetscScalar, dimension( & - X_RANGE,Y_RANGE,Z_RANGE), intent(out) :: & - r + real(pReal), dimension(cells(1),cells(2),cells3), intent(out) :: & + r !< residual PetscObject :: dummy - PetscErrorCode :: err_PETSc + PetscErrorCode, intent(out) :: err_PETSc + integer :: i, j, k, ce + real(pReal), dimension(3,cells(1),cells(2),cells3) :: vectorField - phi_current = x_scal -!-------------------------------------------------------------------------------------------------- -! evaluate polarization field - scalarField_real = 0.0_pReal - scalarField_real(1:cells(1),1:cells(2),1:cells3) = phi_current - call utilities_FFTscalarForward - call utilities_fourierScalarGradient !< calculate gradient of damage field - call utilities_FFTvectorBackward + phi = x_scal + vectorField = utilities_ScalarGradient(phi) ce = 0 do k = 1, cells3; do j = 1, cells(2); do i = 1,cells(1) ce = ce + 1 - vectorField_real(1:3,i,j,k) = matmul(homogenization_K_phi(ce) - K_ref, vectorField_real(1:3,i,j,k)) + vectorField(1:3,i,j,k) = matmul(homogenization_K_phi(ce) - K_ref, vectorField(1:3,i,j,k)) end do; end do; end do - call utilities_FFTvectorForward - call utilities_fourierVectorDivergence !< calculate damage divergence in fourier field - call utilities_FFTscalarBackward + r = utilities_VectorDivergence(vectorField) ce = 0 do k = 1, cells3; do j = 1, cells(2); do i = 1,cells(1) ce = ce + 1 - scalarField_real(i,j,k) = params%Delta_t*(scalarField_real(i,j,k) + homogenization_f_phi(phi_current(i,j,k),ce)) & - + homogenization_mu_phi(ce)*(phi_lastInc(i,j,k) - phi_current(i,j,k)) & - + mu_ref*phi_current(i,j,k) + r(i,j,k) = params%Delta_t*(r(i,j,k) + homogenization_f_phi(phi(i,j,k),ce)) & + + homogenization_mu_phi(ce)*(phi_lastInc(i,j,k) - phi(i,j,k)) & + + mu_ref*phi(i,j,k) end do; end do; end do -!-------------------------------------------------------------------------------------------------- -! convolution of damage field with green operator - call utilities_FFTscalarForward - call utilities_fourierGreenConvolution(K_ref, mu_ref, params%Delta_t) - call utilities_FFTscalarBackward - - where(scalarField_real(1:cells(1),1:cells(2),1:cells3) > phi_lastInc) & - scalarField_real(1:cells(1),1:cells(2),1:cells3) = phi_lastInc - where(scalarField_real(1:cells(1),1:cells(2),1:cells3) < num%residualStiffness) & - scalarField_real(1:cells(1),1:cells(2),1:cells3) = num%residualStiffness - -!-------------------------------------------------------------------------------------------------- -! constructing residual - r = scalarField_real(1:cells(1),1:cells(2),1:cells3) - phi_current + r = max(min(utilities_GreenConvolution(r, K_ref, mu_ref, params%Delta_t),phi_lastInc),num%phi_min) & + - phi err_PETSc = 0 end subroutine formResidual !-------------------------------------------------------------------------------------------------- -!> @brief update reference viscosity and conductivity +!> @brief Update reference viscosity and conductivity. !-------------------------------------------------------------------------------------------------- subroutine updateReference() diff --git a/src/grid/grid_mech_FEM.f90 b/src/grid/grid_mech_FEM.f90 index 4bb705807..e247deaad 100644 --- a/src/grid/grid_mech_FEM.f90 +++ b/src/grid/grid_mech_FEM.f90 @@ -111,28 +111,32 @@ subroutine grid_mechanical_FEM_init 1.0_pReal,-1.0_pReal,-1.0_pReal,-1.0_pReal, & 1.0_pReal, 1.0_pReal, 1.0_pReal, 1.0_pReal], [4,8]) real(pReal), dimension(3,3,3,3) :: devNull + real(pReal), dimension(3,3,product(cells(1:2))*cells3) :: temp33n + real(pReal), dimension(3,product(cells(1:2))*cells3) :: temp3n PetscErrorCode :: err_PETSc integer(MPI_INTEGER_KIND) :: err_MPI PetscScalar, pointer, dimension(:,:,:,:) :: & - u_current,u_lastInc + u,u_lastInc PetscInt, dimension(0:worldsize-1) :: localK integer(HID_T) :: fileHandle, groupHandle - class(tNode), pointer :: & - num_grid, & + type(tDict), pointer :: & + num_grid + type(tList), pointer :: & debug_grid character(len=pStringLen) :: & extmsg = '' + print'(/,1x,a)', '<<<+- grid_mechanical_FEM init -+>>>'; flush(IO_STDOUT) !------------------------------------------------------------------------------------------------- ! debugging options - debug_grid => config_debug%get('grid',defaultVal=emptyList) + debug_grid => config_debug%get_list('grid',defaultVal=emptyList) debugRotation = debug_grid%contains('rotation') !------------------------------------------------------------------------------------------------- ! read numerical parameters and do sanity checks - num_grid => config_numerics%get('grid',defaultVal=emptyDict) + num_grid => config_numerics%get_dict('grid',defaultVal=emptyDict) num%eps_div_atol = num_grid%get_asFloat('eps_div_atol', defaultVal=1.0e-4_pReal) num%eps_div_rtol = num_grid%get_asFloat('eps_div_rtol', defaultVal=5.0e-4_pReal) @@ -175,7 +179,7 @@ subroutine grid_mechanical_FEM_init localK = 0_pPetscInt localK(worldrank) = int(cells3,pPetscInt) call MPI_Allreduce(MPI_IN_PLACE,localK,worldsize,MPI_INTEGER,MPI_SUM,MPI_COMM_WORLD,err_MPI) - if(err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' + if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' call DMDACreate3d(PETSC_COMM_WORLD, & DM_BOUNDARY_PERIODIC, DM_BOUNDARY_PERIODIC, DM_BOUNDARY_PERIODIC, & DMDA_STENCIL_BOX, & @@ -218,7 +222,7 @@ subroutine grid_mechanical_FEM_init CHKERRQ(err_PETSc) call VecSet(solution_rate ,0.0_pReal,err_PETSc) CHKERRQ(err_PETSc) - call DMDAVecGetArrayF90(mechanical_grid,solution_current,u_current,err_PETSc) + call DMDAVecGetArrayF90(mechanical_grid,solution_current,u,err_PETSc) CHKERRQ(err_PETSc) call DMDAVecGetArrayF90(mechanical_grid,solution_lastInc,u_lastInc,err_PETSc) CHKERRQ(err_PETSc) @@ -248,32 +252,36 @@ subroutine grid_mechanical_FEM_init call HDF5_read(P_aim,groupHandle,'P_aim',.false.) call MPI_Bcast(P_aim,9_MPI_INTEGER_KIND,MPI_DOUBLE,0_MPI_INTEGER_KIND,MPI_COMM_WORLD,err_MPI) - if(err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' + if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' call HDF5_read(F_aim,groupHandle,'F_aim',.false.) call MPI_Bcast(F_aim,9_MPI_INTEGER_KIND,MPI_DOUBLE,0_MPI_INTEGER_KIND,MPI_COMM_WORLD,err_MPI) - if(err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' + if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' call HDF5_read(F_aim_lastInc,groupHandle,'F_aim_lastInc',.false.) call MPI_Bcast(F_aim_lastInc,9_MPI_INTEGER_KIND,MPI_DOUBLE,0_MPI_INTEGER_KIND,MPI_COMM_WORLD,err_MPI) - if(err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' + if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' call HDF5_read(F_aimDot,groupHandle,'F_aimDot',.false.) call MPI_Bcast(F_aimDot,9_MPI_INTEGER_KIND,MPI_DOUBLE,0_MPI_INTEGER_KIND,MPI_COMM_WORLD,err_MPI) - if(err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' - call HDF5_read(F,groupHandle,'F') - call HDF5_read(F_lastInc,groupHandle,'F_lastInc') - call HDF5_read(u_current,groupHandle,'u') - call HDF5_read(u_lastInc,groupHandle,'u_lastInc') + if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' + call HDF5_read(temp33n,groupHandle,'F') + F = reshape(temp33n,[3,3,cells(1),cells(2),cells3]) + call HDF5_read(temp33n,groupHandle,'F_lastInc') + F_lastInc = reshape(temp33n,[3,3,cells(1),cells(2),cells3]) + call HDF5_read(temp3n,groupHandle,'u') + u = reshape(temp3n,[3,cells(1),cells(2),cells3]) + call HDF5_read(temp3n,groupHandle,'u_lastInc') + u_lastInc = reshape(temp3n,[3,cells(1),cells(2),cells3]) elseif (CLI_restartInc == 0) then restartRead F_lastInc = spread(spread(spread(math_I3,3,cells(1)),4,cells(2)),5,cells3) ! initialize to identity F = spread(spread(spread(math_I3,3,cells(1)),4,cells(2)),5,cells3) - endif restartRead + end if restartRead homogenization_F0 = reshape(F_lastInc, [3,3,product(cells(1:2))*cells3]) ! set starting condition for homogenization_mechanical_response call utilities_updateCoords(F) call utilities_constitutiveResponse(P_current,P_av,C_volAvg,devNull, & ! stress field, stress avg, global average of stiffness and (min+max)/2 F, & ! target F 0.0_pReal) ! time increment - call DMDAVecRestoreArrayF90(mechanical_grid,solution_current,u_current,err_PETSc) + call DMDAVecRestoreArrayF90(mechanical_grid,solution_current,u,err_PETSc) CHKERRQ(err_PETSc) call DMDAVecRestoreArrayF90(mechanical_grid,solution_lastInc,u_lastInc,err_PETSc) CHKERRQ(err_PETSc) @@ -282,15 +290,15 @@ subroutine grid_mechanical_FEM_init print'(1x,a,i0,a)', 'reading more restart data of increment ', CLI_restartInc, ' from file' call HDF5_read(C_volAvg,groupHandle,'C_volAvg',.false.) call MPI_Bcast(C_volAvg,81_MPI_INTEGER_KIND,MPI_DOUBLE,0_MPI_INTEGER_KIND,MPI_COMM_WORLD,err_MPI) - if(err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' + if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' call HDF5_read(C_volAvgLastInc,groupHandle,'C_volAvgLastInc',.false.) call MPI_Bcast(C_volAvgLastInc,81_MPI_INTEGER_KIND,MPI_DOUBLE,0_MPI_INTEGER_KIND,MPI_COMM_WORLD,err_MPI) - if(err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' + if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' call HDF5_closeGroup(groupHandle) call HDF5_closeFile(fileHandle) - endif restartRead2 + end if restartRead2 end subroutine grid_mechanical_FEM_init @@ -350,12 +358,13 @@ subroutine grid_mechanical_FEM_forward(cutBack,guess,Delta_t,Delta_t_old,t_remai deformation_BC type(tRotation), intent(in) :: & rotation_BC + PetscErrorCode :: err_PETSc PetscScalar, pointer, dimension(:,:,:,:) :: & - u_current,u_lastInc + u,u_lastInc - call DMDAVecGetArrayF90(mechanical_grid,solution_current,u_current,err_PETSc) + call DMDAVecGetArrayF90(mechanical_grid,solution_current,u,err_PETSc) CHKERRQ(err_PETSc) call DMDAVecGetArrayF90(mechanical_grid,solution_lastInc,u_lastInc,err_PETSc) CHKERRQ(err_PETSc) @@ -379,7 +388,7 @@ subroutine grid_mechanical_FEM_forward(cutBack,guess,Delta_t,Delta_t_old,t_remai elseif (deformation_BC%myType=='F') then ! aim at end of load case is prescribed F_aimDot = F_aimDot & + merge(.0_pReal,(deformation_BC%values - F_aim_lastInc)/t_remaining,deformation_BC%mask) - endif + end if if (guess) then call VecWAXPY(solution_rate,-1.0_pReal,solution_lastInc,solution_current,err_PETSc) @@ -389,14 +398,14 @@ subroutine grid_mechanical_FEM_forward(cutBack,guess,Delta_t,Delta_t_old,t_remai else call VecSet(solution_rate,0.0_pReal,err_PETSc) CHKERRQ(err_PETSc) - endif + end if call VecCopy(solution_current,solution_lastInc,err_PETSc) CHKERRQ(err_PETSc) F_lastInc = F homogenization_F0 = reshape(F, [3,3,product(cells(1:2))*cells3]) - endif + end if !-------------------------------------------------------------------------------------------------- ! update average and local deformation gradients @@ -408,7 +417,7 @@ subroutine grid_mechanical_FEM_forward(cutBack,guess,Delta_t,Delta_t_old,t_remai call VecAXPY(solution_current,Delta_t,solution_rate,err_PETSc) CHKERRQ(err_PETSc) - call DMDAVecRestoreArrayF90(mechanical_grid,solution_current,u_current,err_PETSc) + call DMDAVecRestoreArrayF90(mechanical_grid,solution_current,u,err_PETSc) CHKERRQ(err_PETSc) call DMDAVecRestoreArrayF90(mechanical_grid,solution_lastInc,u_lastInc,err_PETSc) CHKERRQ(err_PETSc) @@ -439,10 +448,10 @@ subroutine grid_mechanical_FEM_restartWrite PetscErrorCode :: err_PETSc integer(HID_T) :: fileHandle, groupHandle - PetscScalar, dimension(:,:,:,:), pointer :: u_current,u_lastInc + PetscScalar, dimension(:,:,:,:), pointer :: u,u_lastInc - call DMDAVecGetArrayF90(mechanical_grid,solution_current,u_current,err_PETSc) + call DMDAVecGetArrayF90(mechanical_grid,solution_current,u,err_PETSc) CHKERRQ(err_PETSc) call DMDAVecGetArrayF90(mechanical_grid,solution_lastInc,u_lastInc,err_PETSc) CHKERRQ(err_PETSc) @@ -451,10 +460,10 @@ subroutine grid_mechanical_FEM_restartWrite fileHandle = HDF5_openFile(getSolverJobName()//'_restart.hdf5','w') groupHandle = HDF5_addGroup(fileHandle,'solver') - call HDF5_write(F,groupHandle,'F') - call HDF5_write(F_lastInc,groupHandle,'F_lastInc') - call HDF5_write(u_current,groupHandle,'u') - call HDF5_write(u_lastInc,groupHandle,'u_lastInc') + call HDF5_write(reshape(F,[3,3,product(cells(1:2))*cells3]),groupHandle,'F') + call HDF5_write(reshape(F_lastInc,[3,3,product(cells(1:2))*cells3]),groupHandle,'F_lastInc') + call HDF5_write(reshape(u,[3,product(cells(1:2))*cells3]),groupHandle,'u') + call HDF5_write(reshape(u_lastInc,[3,product(cells(1:2))*cells3]),groupHandle,'u_lastInc') call HDF5_closeGroup(groupHandle) call HDF5_closeFile(fileHandle) @@ -469,9 +478,9 @@ subroutine grid_mechanical_FEM_restartWrite call HDF5_write(C_volAvgLastInc,groupHandle,'C_volAvgLastInc',.false.) call HDF5_closeGroup(groupHandle) call HDF5_closeFile(fileHandle) - endif + end if - call DMDAVecRestoreArrayF90(mechanical_grid,solution_current,u_current,err_PETSc) + call DMDAVecRestoreArrayF90(mechanical_grid,solution_current,u,err_PETSc) CHKERRQ(err_PETSc) call DMDAVecRestoreArrayF90(mechanical_grid,solution_lastInc,u_lastInc,err_PETSc) CHKERRQ(err_PETSc) @@ -509,7 +518,7 @@ subroutine converged(snes_local,PETScIter,devNull1,devNull2,fnorm,reason,dummy,e reason = -1 else reason = 0 - endif + end if print'(/,1x,a)', '... reporting .............................................................' print'(/,1x,a,f12.2,a,es8.2,a,es9.2,a)', 'error divergence = ', & @@ -529,16 +538,17 @@ end subroutine converged subroutine formResidual(da_local,x_local, & f_local,dummy,err_PETSc) - DM :: da_local - Vec :: x_local, f_local - PetscScalar, pointer,dimension(:,:,:,:) :: x_scal, r - PetscScalar, dimension(8,3) :: x_elem, f_elem + DM :: da_local + Vec :: x_local, f_local + PetscObject :: dummy + PetscErrorCode :: err_PETSc + + real(pReal), pointer,dimension(:,:,:,:) :: x_scal, r + real(pReal), dimension(8,3) :: x_elem, f_elem PetscInt :: i, ii, j, jj, k, kk, ctr, ele PetscInt :: & PETScIter, & nfuncs - PetscObject :: dummy - PetscErrorCode :: err_PETSc integer(MPI_INTEGER_KIND) :: err_MPI real(pReal), dimension(3,3,3,3) :: devNull @@ -547,6 +557,7 @@ subroutine formResidual(da_local,x_local, & call SNESGetIterationNumber(SNES_mechanical,PETScIter,err_PETSc) CHKERRQ(err_PETSc) + if (nfuncs == 0 .and. PETScIter == 0) totalIter = -1 ! new increment !-------------------------------------------------------------------------------------------------- @@ -559,7 +570,7 @@ subroutine formResidual(da_local,x_local, & print'(/,1x,a,/,2(3(f12.7,1x)/),3(f12.7,1x))', & 'deformation gradient aim =', transpose(F_aim) flush(IO_STDOUT) - endif newIteration + end if newIteration !-------------------------------------------------------------------------------------------------- ! get deformation gradient @@ -570,9 +581,9 @@ subroutine formResidual(da_local,x_local, & do kk = -1, 0; do jj = -1, 0; do ii = -1, 0 ctr = ctr + 1 x_elem(ctr,1:3) = x_scal(0:2,i+ii,j+jj,k+kk) - enddo; enddo; enddo + end do; end do; end do F(1:3,1:3,i,j,k-cells3Offset) = params%rotation_BC%rotate(F_aim,active=.true.) + transpose(matmul(BMat,x_elem)) - enddo; enddo; enddo + end do; end do; end do call DMDAVecRestoreArrayF90(da_local,x_local,x_scal,err_PETSc) CHKERRQ(err_PETSc) @@ -582,7 +593,7 @@ subroutine formResidual(da_local,x_local, & P_av,C_volAvg,devNull, & F,params%Delta_t,params%rotation_BC) call MPI_Allreduce(MPI_IN_PLACE,terminallyIll,1_MPI_INTEGER_KIND,MPI_LOGICAL,MPI_LOR,MPI_COMM_WORLD,err_MPI) - if(err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' + if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' !-------------------------------------------------------------------------------------------------- ! stress BC handling @@ -603,7 +614,7 @@ subroutine formResidual(da_local,x_local, & do kk = -1, 0; do jj = -1, 0; do ii = -1, 0 ctr = ctr + 1 x_elem(ctr,1:3) = x_scal(0:2,i+ii,j+jj,k+kk) - enddo; enddo; enddo + end do; end do; end do ele = ele + 1 f_elem = matmul(transpose(BMat),transpose(P_current(1:3,1:3,i,j,k-cells3Offset)))*detJ + & matmul(HGMat,x_elem)*(homogenization_dPdF(1,1,1,1,ele) + & @@ -613,8 +624,8 @@ subroutine formResidual(da_local,x_local, & do kk = -1, 0; do jj = -1, 0; do ii = -1, 0 ctr = ctr + 1 r(0:2,i+ii,j+jj,k+kk) = r(0:2,i+ii,j+jj,k+kk) + f_elem(ctr,1:3) - enddo; enddo; enddo - enddo; enddo; enddo + end do; end do; end do + end do; end do; end do call DMDAVecRestoreArrayF90(da_local,x_local,x_scal,err_PETSc) CHKERRQ(err_PETSc) call DMDAVecRestoreArrayF90(da_local,f_local,r,err_PETSc) @@ -643,23 +654,26 @@ end subroutine formResidual !-------------------------------------------------------------------------------------------------- -!> @brief forms the FEM stiffness matrix +!> @brief Form the FEM stiffness matrix. !-------------------------------------------------------------------------------------------------- subroutine formJacobian(da_local,x_local,Jac_pre,Jac,dummy,err_PETSc) DM :: da_local - Vec :: x_local, coordinates + Vec :: x_local Mat :: Jac_pre, Jac + PetscObject :: dummy + PetscErrorCode :: err_PETSc + MatStencil,dimension(4,24) :: row, col - PetscScalar,pointer,dimension(:,:,:,:) :: x_scal - PetscScalar,dimension(24,24) :: K_ele - PetscScalar,dimension(9,24) :: BMatFull + real(pReal),pointer,dimension(:,:,:,:) :: x_scal + real(pReal),dimension(24,24) :: K_ele + real(pReal),dimension(9,24) :: BMatFull PetscInt :: i, ii, j, jj, k, kk, ctr, ce PetscInt,dimension(3),parameter :: rows = [0, 1, 2] - PetscScalar :: diag - PetscObject :: dummy + real(pReal) :: diag MatNullSpace :: matnull - PetscErrorCode :: err_PETSc + Vec :: coordinates + BMatFull = 0.0_pReal BMatFull(1:3,1 :8 ) = BMat @@ -688,7 +702,7 @@ subroutine formJacobian(da_local,x_local,Jac_pre,Jac,dummy,err_PETSc) col(MatStencil_j,ctr+16) = j+jj col(MatStencil_k,ctr+16) = k+kk col(MatStencil_c,ctr+16) = 2 - enddo; enddo; enddo + end do; end do; end do row = col ce = ce + 1 K_ele = 0.0_pReal @@ -707,7 +721,7 @@ subroutine formJacobian(da_local,x_local,Jac_pre,Jac,dummy,err_PETSc) shape=[3,3,3,3], order=[2,1,4,3]),shape=[9,9]),BMatFull))*detJ call MatSetValuesStencil(Jac,24_pPETScInt,row,24_pPetscInt,col,K_ele,ADD_VALUES,err_PETSc) CHKERRQ(err_PETSc) - enddo; enddo; enddo + end do; end do; end do call MatAssemblyBegin(Jac,MAT_FINAL_ASSEMBLY,err_PETSc) CHKERRQ(err_PETSc) call MatAssemblyEnd(Jac,MAT_FINAL_ASSEMBLY,err_PETSc) @@ -727,15 +741,11 @@ subroutine formJacobian(da_local,x_local,Jac_pre,Jac,dummy,err_PETSc) CHKERRQ(err_PETSc) call DMDAVecGetArrayF90(da_local,coordinates,x_scal,err_PETSc) CHKERRQ(err_PETSc) - ce = 0 - do k = cells3Offset+1, cells3Offset+cells3; do j = 1, cells(2); do i = 1, cells(1) - ce = ce + 1 - x_scal(0:2,i-1,j-1,k-1) = discretization_IPcoords(1:3,ce) - enddo; enddo; enddo - call DMDAVecRestoreArrayF90(da_local,coordinates,x_scal,err_PETSc) - CHKERRQ(err_PETSc) ! initialize to undeformed coordinates (ToDo: use ip coordinates) - call MatNullSpaceCreateRigidBody(coordinates,matnull,err_PETSc) - CHKERRQ(err_PETSc) ! get rigid body deformation modes + x_scal = reshape(discretization_IPcoords,[3,cells(1),cells(2),cells3]) + call DMDAVecRestoreArrayF90(da_local,coordinates,x_scal,err_PETSc) ! ToDo: use undeformed or deformed configuration? + CHKERRQ(err_PETSc) + call MatNullSpaceCreateRigidBody(coordinates,matnull,err_PETSc) ! get rigid body deformation modes + CHKERRQ(err_PETSc) call DMRestoreGlobalVector(da_local,coordinates,err_PETSc) CHKERRQ(err_PETSc) call MatSetNullSpace(Jac,matnull,err_PETSc) diff --git a/src/grid/grid_mech_spectral_basic.f90 b/src/grid/grid_mech_spectral_basic.f90 index dec677df8..6f5a85815 100644 --- a/src/grid/grid_mech_spectral_basic.f90 +++ b/src/grid/grid_mech_spectral_basic.f90 @@ -77,6 +77,7 @@ module grid_mechanical_spectral_basic C_volAvgLastInc = 0.0_pReal, & !< previous volume average stiffness C_minMaxAvg = 0.0_pReal, & !< current (min+max)/2 stiffness C_minMaxAvgLastInc = 0.0_pReal, & !< previous (min+max)/2 stiffness + C_minMaxAvgRestart = 0.0_pReal, & !< (min+max)/2 stiffnes (restart) S = 0.0_pReal !< current compliance (filled up with zeros) real(pReal) :: & @@ -104,26 +105,29 @@ contains !-------------------------------------------------------------------------------------------------- !> @brief allocates all necessary fields and fills them with data, potentially from restart info !-------------------------------------------------------------------------------------------------- -subroutine grid_mechanical_spectral_basic_init +subroutine grid_mechanical_spectral_basic_init() real(pReal), dimension(3,3,cells(1),cells(2),cells3) :: P PetscErrorCode :: err_PETSc integer(MPI_INTEGER_KIND) :: err_MPI - PetscScalar, pointer, dimension(:,:,:,:) :: & + real(pReal), pointer, dimension(:,:,:,:) :: & F ! pointer to solution data PetscInt, dimension(0:worldsize-1) :: localK + real(pReal), dimension(3,3,product(cells(1:2))*cells3) :: temp33n integer(HID_T) :: fileHandle, groupHandle #if (PETSC_VERSION_MAJOR==3 && PETSC_VERSION_MINOR>14) && !defined(PETSC_HAVE_MPI_F90MODULE_VISIBILITY) type(MPI_File) :: fileUnit #else integer :: fileUnit #endif - class (tNode), pointer :: & - num_grid, & + type(tDict), pointer :: & + num_grid + type(tList), pointer :: & debug_grid character(len=pStringLen) :: & extmsg = '' + print'(/,1x,a)', '<<<+- grid_mechanical_spectral_basic init -+>>>'; flush(IO_STDOUT) print'(/,1x,a)', 'P. Eisenlohr et al., International Journal of Plasticity 46:37–53, 2013' @@ -134,12 +138,12 @@ subroutine grid_mechanical_spectral_basic_init !------------------------------------------------------------------------------------------------- ! debugging options - debug_grid => config_debug%get('grid',defaultVal=emptyList) + debug_grid => config_debug%get_list('grid',defaultVal=emptyList) debugRotation = debug_grid%contains('rotation') !------------------------------------------------------------------------------------------------- ! read numerical parameters and do sanity checks - num_grid => config_numerics%get('grid',defaultVal=emptyDict) + num_grid => config_numerics%get_dict('grid',defaultVal=emptyDict) num%update_gamma = num_grid%get_asBool ('update_gamma', defaultVal=.false.) num%eps_div_atol = num_grid%get_asFloat('eps_div_atol', defaultVal=1.0e-4_pReal) @@ -227,8 +231,10 @@ subroutine grid_mechanical_spectral_basic_init call HDF5_read(F_aimDot,groupHandle,'F_aimDot',.false.) call MPI_Bcast(F_aimDot,9_MPI_INTEGER_KIND,MPI_DOUBLE,0_MPI_INTEGER_KIND,MPI_COMM_WORLD,err_MPI) if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' - call HDF5_read(F,groupHandle,'F') - call HDF5_read(F_lastInc,groupHandle,'F_lastInc') + call HDF5_read(temp33n,groupHandle,'F') + F = reshape(temp33n,[9,cells(1),cells(2),cells3]) + call HDF5_read(temp33n,groupHandle,'F_lastInc') + F_lastInc = reshape(temp33n,[3,3,cells(1),cells(2),cells3]) elseif (CLI_restartInc == 0) then restartRead F_lastInc = spread(spread(spread(math_I3,3,cells(1)),4,cells(2)),5,cells3) ! initialize to identity @@ -251,21 +257,17 @@ subroutine grid_mechanical_spectral_basic_init call HDF5_read(C_volAvgLastInc,groupHandle,'C_volAvgLastInc',.false.) call MPI_Bcast(C_volAvgLastInc,81_MPI_INTEGER_KIND,MPI_DOUBLE,0_MPI_INTEGER_KIND,MPI_COMM_WORLD,err_MPI) if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' + call HDF5_read(C_minMaxAvg,groupHandle,'C_minMaxAvg',.false.) + call MPI_Bcast(C_minMaxAvg,81_MPI_INTEGER_KIND,MPI_DOUBLE,0_MPI_INTEGER_KIND,MPI_COMM_WORLD,err_MPI) + if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' call HDF5_closeGroup(groupHandle) call HDF5_closeFile(fileHandle) - call MPI_File_open(MPI_COMM_WORLD, trim(getSolverJobName())//'.C_ref', & - MPI_MODE_RDONLY,MPI_INFO_NULL,fileUnit,err_MPI) - if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' - call MPI_File_read(fileUnit,C_minMaxAvg,81_MPI_INTEGER_KIND,MPI_DOUBLE,status,err_MPI) - if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' - call MPI_File_close(fileUnit,err_MPI) - if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' end if restartRead2 call utilities_updateGamma(C_minMaxAvg) - call utilities_saveReferenceStiffness + C_minMaxAvgRestart = C_minMaxAvg end subroutine grid_mechanical_spectral_basic_init @@ -327,7 +329,7 @@ subroutine grid_mechanical_spectral_basic_forward(cutBack,guess,Delta_t,Delta_t_ type(tRotation), intent(in) :: & rotation_BC PetscErrorCode :: err_PETSc - PetscScalar, pointer, dimension(:,:,:,:) :: F + real(pReal), pointer, dimension(:,:,:,:) :: F call DMDAVecGetArrayF90(da,solution_vec,F,err_PETSc) @@ -392,7 +394,7 @@ end subroutine grid_mechanical_spectral_basic_forward subroutine grid_mechanical_spectral_basic_updateCoords PetscErrorCode :: err_PETSc - PetscScalar, dimension(:,:,:,:), pointer :: F + real(pReal), dimension(:,:,:,:), pointer :: F call DMDAVecGetArrayF90(da,solution_vec,F,err_PETSc) CHKERRQ(err_PETSc) @@ -410,17 +412,19 @@ subroutine grid_mechanical_spectral_basic_restartWrite PetscErrorCode :: err_PETSc integer(HID_T) :: fileHandle, groupHandle - PetscScalar, dimension(:,:,:,:), pointer :: F + real(pReal), dimension(:,:,:,:), pointer :: F call DMDAVecGetArrayF90(da,solution_vec,F,err_PETSc) CHKERRQ(err_PETSc) + if (num%update_gamma) C_minMaxAvgRestart = C_minMaxAvg + print'(1x,a)', 'writing solver data required for restart to file'; flush(IO_STDOUT) fileHandle = HDF5_openFile(getSolverJobName()//'_restart.hdf5','w') groupHandle = HDF5_addGroup(fileHandle,'solver') - call HDF5_write(F,groupHandle,'F') - call HDF5_write(F_lastInc,groupHandle,'F_lastInc') + call HDF5_write(reshape(F,[3,3,product(cells(1:2))*cells3]),groupHandle,'F') + call HDF5_write(reshape(F_lastInc,[3,3,product(cells(1:2))*cells3]),groupHandle,'F_lastInc') call HDF5_closeGroup(groupHandle) call HDF5_closeFile(fileHandle) @@ -433,13 +437,11 @@ subroutine grid_mechanical_spectral_basic_restartWrite call HDF5_write(F_aimDot,groupHandle,'F_aimDot',.false.) call HDF5_write(C_volAvg,groupHandle,'C_volAvg',.false.) call HDF5_write(C_volAvgLastInc,groupHandle,'C_volAvgLastInc',.false.) - call HDF5_write(C_minMaxAvg,groupHandle,'C_minMaxAvg',.false.) + call HDF5_write(C_minMaxAvgRestart,groupHandle,'C_minMaxAvg',.false.) call HDF5_closeGroup(groupHandle) call HDF5_closeFile(fileHandle) end if - if (num%update_gamma) call utilities_saveReferenceStiffness - call DMDAVecRestoreArrayF90(da,solution_vec,F,err_PETSc) CHKERRQ(err_PETSc) @@ -489,25 +491,28 @@ end subroutine converged !-------------------------------------------------------------------------------------------------- -!> @brief forms the residual vector +!> @brief Construct the residual vector. !-------------------------------------------------------------------------------------------------- -subroutine formResidual(in, F, & +subroutine formResidual(residual_subdomain, F, & r, dummy, err_PETSc) - DMDALocalInfo, dimension(DMDA_LOCAL_INFO_SIZE) :: in !< DMDA info (needs to be named "in" for macros like XRANGE to work) - PetscScalar, dimension(3,3,XG_RANGE,YG_RANGE,ZG_RANGE), & - intent(in) :: F !< deformation gradient field - PetscScalar, dimension(3,3,X_RANGE,Y_RANGE,Z_RANGE), & - intent(out) :: r !< residuum field + DMDALocalInfo, dimension(DMDA_LOCAL_INFO_SIZE) :: & + residual_subdomain !< DMDA info (needs to be named "in" for macros like XRANGE to work) + real(pReal), dimension(3,3,cells(1),cells(2),cells3), intent(in) :: & + F !< deformation gradient field + real(pReal), dimension(3,3,cells(1),cells(2),cells3), intent(out) :: & + r !< residuum field + PetscObject :: dummy + PetscErrorCode :: err_PETSc + real(pReal), dimension(3,3) :: & deltaF_aim PetscInt :: & PETScIter, & nfuncs - PetscObject :: dummy - PetscErrorCode :: err_PETSc integer(MPI_INTEGER_KIND) :: err_MPI + call SNESGetNumberFunctionEvals(SNES_mechanical,nfuncs,err_PETSc) CHKERRQ(err_PETSc) call SNESGetIterationNumber(SNES_mechanical,PETScIter,err_PETSc) @@ -515,8 +520,6 @@ subroutine formResidual(in, F, & if (nfuncs == 0 .and. PETScIter == 0) totalIter = -1 ! new increment -!-------------------------------------------------------------------------------------------------- -! begin of new iteration newIteration: if (totalIter <= PETScIter) then totalIter = totalIter + 1 print'(1x,a,3(a,i0))', trim(incInfo), ' @ Iteration ', num%itmin, '≤',totalIter, '≤', num%itmax @@ -527,32 +530,20 @@ subroutine formResidual(in, F, & flush(IO_STDOUT) end if newIteration -!-------------------------------------------------------------------------------------------------- -! evaluate constitutive response - call utilities_constitutiveResponse(r, & ! residuum gets field of first PK stress (to save memory) - P_av,C_volAvg,C_minMaxAvg, & - F,params%Delta_t,params%rotation_BC) - call MPI_Allreduce(MPI_IN_PLACE,terminallyIll,1_MPI_INTEGER_KIND,MPI_LOGICAL,MPI_LOR,MPI_COMM_WORLD,err_MPI) - if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' + associate (P => r) + call utilities_constitutiveResponse(P, & + P_av,C_volAvg,C_minMaxAvg, & + F,params%Delta_t,params%rotation_BC) + call MPI_Allreduce(MPI_IN_PLACE,terminallyIll,1_MPI_INTEGER_KIND,MPI_LOGICAL,MPI_LOR,MPI_COMM_WORLD,err_MPI) + if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' + err_div = utilities_divergenceRMS(P) + end associate -!-------------------------------------------------------------------------------------------------- -! stress BC handling deltaF_aim = math_mul3333xx33(S, P_av - P_aim) ! S = 0.0 for no bc F_aim = F_aim - deltaF_aim err_BC = maxval(abs(merge(.0_pReal,P_av - P_aim,params%stress_mask))) -!-------------------------------------------------------------------------------------------------- -! updated deformation gradient using fix point algorithm of basic scheme - tensorField_real = 0.0_pReal - tensorField_real(1:3,1:3,1:cells(1),1:cells(2),1:cells3) = r ! store fPK field for subsequent FFT forward transform - call utilities_FFTtensorForward ! FFT forward of global "tensorField_real" - err_div = utilities_divergenceRMS() ! divRMS of tensorField_fourier for later use - call utilities_fourierGammaConvolution(params%rotation_BC%rotate(deltaF_aim,active=.true.)) ! convolution of Gamma and tensorField_fourier - call utilities_FFTtensorBackward ! FFT backward of global tensorField_fourier - -!-------------------------------------------------------------------------------------------------- -! constructing residual - r = tensorField_real(1:3,1:3,1:cells(1),1:cells(2),1:cells3) ! Gamma*P gives correction towards div(P) = 0, so needs to be zero, too + r = utilities_GammaConvolution(r,params%rotation_BC%rotate(deltaF_aim,active=.true.)) end subroutine formResidual diff --git a/src/grid/grid_mech_spectral_polarisation.f90 b/src/grid/grid_mech_spectral_polarisation.f90 index d0d229c46..52b20dfbd 100644 --- a/src/grid/grid_mech_spectral_polarisation.f90 +++ b/src/grid/grid_mech_spectral_polarisation.f90 @@ -85,6 +85,7 @@ module grid_mechanical_spectral_polarisation C_volAvgLastInc = 0.0_pReal, & !< previous volume average stiffness C_minMaxAvg = 0.0_pReal, & !< current (min+max)/2 stiffness C_minMaxAvgLastInc = 0.0_pReal, & !< previous (min+max)/2 stiffness + C_minMaxAvgRestart = 0.0_pReal, & !< (min+max)/2 stiffnes (restart) S = 0.0_pReal, & !< current compliance (filled up with zeros) C_scale = 0.0_pReal, & S_scale = 0.0_pReal @@ -115,24 +116,26 @@ contains !-------------------------------------------------------------------------------------------------- !> @brief allocates all necessary fields and fills them with data, potentially from restart info !-------------------------------------------------------------------------------------------------- -subroutine grid_mechanical_spectral_polarisation_init +subroutine grid_mechanical_spectral_polarisation_init() real(pReal), dimension(3,3,cells(1),cells(2),cells3) :: P PetscErrorCode :: err_PETSc integer(MPI_INTEGER_KIND) :: err_MPI - PetscScalar, pointer, dimension(:,:,:,:) :: & + real(pReal), pointer, dimension(:,:,:,:) :: & FandF_tau, & ! overall pointer to solution data F, & ! specific (sub)pointer F_tau ! specific (sub)pointer PetscInt, dimension(0:worldsize-1) :: localK + real(pReal), dimension(3,3,product(cells(1:2))*cells3) :: temp33n integer(HID_T) :: fileHandle, groupHandle #if (PETSC_VERSION_MAJOR==3 && PETSC_VERSION_MINOR>14) && !defined(PETSC_HAVE_MPI_F90MODULE_VISIBILITY) type(MPI_File) :: fileUnit #else integer :: fileUnit #endif - class (tNode), pointer :: & - num_grid, & + type(tDict), pointer :: & + num_grid + type(tList), pointer :: & debug_grid character(len=pStringLen) :: & extmsg = '' @@ -144,12 +147,12 @@ subroutine grid_mechanical_spectral_polarisation_init !------------------------------------------------------------------------------------------------- ! debugging options - debug_grid => config_debug%get('grid',defaultVal=emptyList) + debug_grid => config_debug%get_list('grid',defaultVal=emptyList) debugRotation = debug_grid%contains('rotation') !------------------------------------------------------------------------------------------------- ! read numerical parameters and do sanity checks - num_grid => config_numerics%get('grid',defaultVal=emptyDict) + num_grid => config_numerics%get_dict('grid',defaultVal=emptyDict) num%update_gamma = num_grid%get_asBool ('update_gamma', defaultVal=.false.) num%eps_div_atol = num_grid%get_asFloat('eps_div_atol', defaultVal=1.0e-4_pReal) @@ -249,10 +252,14 @@ subroutine grid_mechanical_spectral_polarisation_init call HDF5_read(F_aimDot,groupHandle,'F_aimDot',.false.) call MPI_Bcast(F_aimDot,9_MPI_INTEGER_KIND,MPI_DOUBLE,0_MPI_INTEGER_KIND,MPI_COMM_WORLD,err_MPI) if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' - call HDF5_read(F,groupHandle,'F') - call HDF5_read(F_lastInc,groupHandle,'F_lastInc') - call HDF5_read(F_tau,groupHandle,'F_tau') - call HDF5_read(F_tau_lastInc,groupHandle,'F_tau_lastInc') + call HDF5_read(temp33n,groupHandle,'F') + F = reshape(temp33n,[9,cells(1),cells(2),cells3]) + call HDF5_read(temp33n,groupHandle,'F_lastInc') + F_lastInc = reshape(temp33n,[3,3,cells(1),cells(2),cells3]) + call HDF5_read(temp33n,groupHandle,'F_tau') + F_tau = reshape(temp33n,[9,cells(1),cells(2),cells3]) + call HDF5_read(temp33n,groupHandle,'F_tau_lastInc') + F_tau_lastInc = reshape(temp33n,[3,3,cells(1),cells(2),cells3]) elseif (CLI_restartInc == 0) then restartRead F_lastInc = spread(spread(spread(math_I3,3,cells(1)),4,cells(2)),5,cells3) ! initialize to identity @@ -277,21 +284,17 @@ subroutine grid_mechanical_spectral_polarisation_init call HDF5_read(C_volAvgLastInc,groupHandle,'C_volAvgLastInc',.false.) call MPI_Bcast(C_volAvgLastInc,81_MPI_INTEGER_KIND,MPI_DOUBLE,0_MPI_INTEGER_KIND,MPI_COMM_WORLD,err_MPI) if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' + call HDF5_read(C_minMaxAvg,groupHandle,'C_minMaxAvg',.false.) + call MPI_Bcast(C_minMaxAvg,81_MPI_INTEGER_KIND,MPI_DOUBLE,0_MPI_INTEGER_KIND,MPI_COMM_WORLD,err_MPI) + if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' call HDF5_closeGroup(groupHandle) call HDF5_closeFile(fileHandle) - call MPI_File_open(MPI_COMM_WORLD, trim(getSolverJobName())//'.C_ref', & - MPI_MODE_RDONLY,MPI_INFO_NULL,fileUnit,err_MPI) - if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' - call MPI_File_read(fileUnit,C_minMaxAvg,81_MPI_INTEGER_KIND,MPI_DOUBLE,status,err_MPI) - if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' - call MPI_File_close(fileUnit,err_MPI) - if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' end if restartRead2 call utilities_updateGamma(C_minMaxAvg) - call utilities_saveReferenceStiffness + C_minMaxAvgRestart = C_minMaxAvg C_scale = C_minMaxAvg S_scale = math_invSym3333(C_minMaxAvg) @@ -359,7 +362,7 @@ subroutine grid_mechanical_spectral_polarisation_forward(cutBack,guess,Delta_t,D type(tRotation), intent(in) :: & rotation_BC PetscErrorCode :: err_PETSc - PetscScalar, pointer, dimension(:,:,:,:) :: FandF_tau, F, F_tau + real(pReal), pointer, dimension(:,:,:,:) :: FandF_tau, F, F_tau integer :: i, j, k real(pReal), dimension(3,3) :: F_lambda33 @@ -446,7 +449,7 @@ end subroutine grid_mechanical_spectral_polarisation_forward subroutine grid_mechanical_spectral_polarisation_updateCoords PetscErrorCode :: err_PETSc - PetscScalar, dimension(:,:,:,:), pointer :: FandF_tau + real(pReal), dimension(:,:,:,:), pointer :: FandF_tau call DMDAVecGetArrayF90(da,solution_vec,FandF_tau,err_PETSc) CHKERRQ(err_PETSc) @@ -464,21 +467,23 @@ subroutine grid_mechanical_spectral_polarisation_restartWrite PetscErrorCode :: err_PETSc integer(HID_T) :: fileHandle, groupHandle - PetscScalar, dimension(:,:,:,:), pointer :: FandF_tau, F, F_tau + real(pReal), dimension(:,:,:,:), pointer :: FandF_tau, F, F_tau call DMDAVecGetArrayF90(da,solution_vec,FandF_tau,err_PETSc) CHKERRQ(err_PETSc) F => FandF_tau(0: 8,:,:,:) F_tau => FandF_tau(9:17,:,:,:) + if (num%update_gamma) C_minMaxAvgRestart = C_minMaxAvg + print'(1x,a)', 'writing solver data required for restart to file'; flush(IO_STDOUT) fileHandle = HDF5_openFile(getSolverJobName()//'_restart.hdf5','w') groupHandle = HDF5_addGroup(fileHandle,'solver') - call HDF5_write(F,groupHandle,'F') - call HDF5_write(F_lastInc,groupHandle,'F_lastInc') - call HDF5_write(F_tau,groupHandle,'F_tau') - call HDF5_write(F_tau_lastInc,groupHandle,'F_tau_lastInc') + call HDF5_write(reshape(F,[3,3,product(cells(1:2))*cells3]),groupHandle,'F') + call HDF5_write(reshape(F_lastInc,[3,3,product(cells(1:2))*cells3]),groupHandle,'F_lastInc') + call HDF5_write(reshape(F_tau,[3,3,product(cells(1:2))*cells3]),groupHandle,'F_tau') + call HDF5_write(reshape(F_tau_lastInc,[3,3,product(cells(1:2))*cells3]),groupHandle,'F_tau_lastInc') call HDF5_closeGroup(groupHandle) call HDF5_closeFile(fileHandle) @@ -491,12 +496,11 @@ subroutine grid_mechanical_spectral_polarisation_restartWrite call HDF5_write(F_aimDot,groupHandle,'F_aimDot',.false.) call HDF5_write(C_volAvg,groupHandle,'C_volAvg',.false.) call HDF5_write(C_volAvgLastInc,groupHandle,'C_volAvgLastInc',.false.) + call HDF5_write(C_minMaxAvgRestart,groupHandle,'C_minMaxAvg',.false.) call HDF5_closeGroup(groupHandle) call HDF5_closeFile(fileHandle) end if - if (num%update_gamma) call utilities_saveReferenceStiffness - call DMDAVecRestoreArrayF90(da,solution_vec,FandF_tau,err_PETSc) CHKERRQ(err_PETSc) @@ -540,7 +544,7 @@ subroutine converged(snes_local,PETScIter,devNull1,devNull2,devNull3,reason,dumm err_div/divTol, ' (',err_div, ' / m, tol = ',divTol,')' print '(1x,a,f12.2,a,es8.2,a,es9.2,a)', 'error curl = ', & err_curl/curlTol,' (',err_curl,' -, tol = ',curlTol,')' - print '(1x,a,f12.2,a,es8.2,a,es9.2,a)', 'error stress BC = ', & + print '(1x,a,f12.2,a,es8.2,a,es9.2,a)', 'error mech BC = ', & err_BC/BCTol, ' (',err_BC, ' Pa, tol = ',BCTol,')' print'(/,1x,a)', '===========================================================================' flush(IO_STDOUT) @@ -550,17 +554,20 @@ end subroutine converged !-------------------------------------------------------------------------------------------------- -!> @brief forms the residual vector +!> @brief Construct the residual vector. !-------------------------------------------------------------------------------------------------- -subroutine formResidual(in, FandF_tau, & +subroutine formResidual(residual_subdomain, FandF_tau, & r, dummy,err_PETSc) - DMDALocalInfo, dimension(DMDA_LOCAL_INFO_SIZE) :: in !< DMDA info (needs to be named "in" for macros like XRANGE to work) - PetscScalar, dimension(3,3,2,XG_RANGE,YG_RANGE,ZG_RANGE), & - target, intent(in) :: FandF_tau - PetscScalar, dimension(3,3,2,X_RANGE,Y_RANGE,Z_RANGE),& - target, intent(out) :: r !< residuum field - PetscScalar, pointer, dimension(:,:,:,:,:) :: & + DMDALocalInfo, dimension(DMDA_LOCAL_INFO_SIZE) :: residual_subdomain !< DMDA info (needs to be named "in" for macros like XRANGE to work) + real(pReal), dimension(3,3,2,cells(1),cells(2),cells3), target, intent(in) :: & + FandF_tau !< deformation gradient field + real(pReal), dimension(3,3,2,cells(1),cells(2),cells3), target, intent(out) :: & + r !< residuum field + PetscObject :: dummy + PetscErrorCode :: err_PETSc + + real(pReal), pointer, dimension(:,:,:,:,:) :: & F, & F_tau, & r_F, & @@ -568,22 +575,15 @@ subroutine formResidual(in, FandF_tau, & PetscInt :: & PETScIter, & nfuncs - PetscObject :: dummy - PetscErrorCode :: err_PETSc integer(MPI_INTEGER_KIND) :: err_MPI integer :: & i, j, k, e -!--------------------------------------------------------------------------------------------------- - F => FandF_tau(1:3,1:3,1,& - XG_RANGE,YG_RANGE,ZG_RANGE) - F_tau => FandF_tau(1:3,1:3,2,& - XG_RANGE,YG_RANGE,ZG_RANGE) - r_F => r(1:3,1:3,1,& - X_RANGE, Y_RANGE, Z_RANGE) - r_F_tau => r(1:3,1:3,2,& - X_RANGE, Y_RANGE, Z_RANGE) + F => FandF_tau(1:3,1:3,1,1:cells(1),1:cells(2),1:cells3) + F_tau => FandF_tau(1:3,1:3,2,1:cells(1),1:cells(2),1:cells3) + r_F => r(1:3,1:3,1,1:cells(1),1:cells(2),1:cells3) + r_F_tau => r(1:3,1:3,2,1:cells(1),1:cells(2),1:cells3) F_av = sum(sum(sum(F,dim=5),dim=4),dim=3) * wgt call MPI_Allreduce(MPI_IN_PLACE,F_av,9_MPI_INTEGER_KIND,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD,err_MPI) @@ -596,8 +596,6 @@ subroutine formResidual(in, FandF_tau, & if (nfuncs == 0 .and. PETScIter == 0) totalIter = -1 ! new increment -!-------------------------------------------------------------------------------------------------- -! begin of new iteration newIteration: if (totalIter <= PETScIter) then totalIter = totalIter + 1 print'(1x,a,3(a,i0))', trim(incInfo), ' @ Iteration ', num%itmin, '≤',totalIter, '≤', num%itmax @@ -608,63 +606,53 @@ subroutine formResidual(in, FandF_tau, & flush(IO_STDOUT) end if newIteration -!-------------------------------------------------------------------------------------------------- -! - tensorField_real = 0.0_pReal do k = 1, cells3; do j = 1, cells(2); do i = 1, cells(1) - tensorField_real(1:3,1:3,i,j,k) = & + r_F_tau(1:3,1:3,i,j,k) = & num%beta*math_mul3333xx33(C_scale,F(1:3,1:3,i,j,k) - math_I3) -& num%alpha*matmul(F(1:3,1:3,i,j,k), & math_mul3333xx33(C_scale,F_tau(1:3,1:3,i,j,k) - F(1:3,1:3,i,j,k) - math_I3)) end do; end do; end do + r_F_tau = num%beta*F & + - utilities_GammaConvolution(r_F_tau,params%rotation_BC%rotate(num%beta*F_aim,active=.true.)) -!-------------------------------------------------------------------------------------------------- -! doing convolution in Fourier space - call utilities_FFTtensorForward - call utilities_fourierGammaConvolution(params%rotation_BC%rotate(num%beta*F_aim,active=.true.)) - call utilities_FFTtensorBackward + err_curl = utilities_curlRMS(F) -!-------------------------------------------------------------------------------------------------- -! constructing residual - r_F_tau = num%beta*F - tensorField_real(1:3,1:3,1:cells(1),1:cells(2),1:cells3) +#ifdef __GFORTRAN__ + call utilities_constitutiveResponse(r_F, & +#else + associate (P => r_F) + call utilities_constitutiveResponse(P, & +#endif + P_av,C_volAvg,C_minMaxAvg, & + F - r_F_tau/num%beta,params%Delta_t,params%rotation_BC) + call MPI_Allreduce(MPI_IN_PLACE,terminallyIll,1_MPI_INTEGER_KIND,MPI_LOGICAL,MPI_LOR,MPI_COMM_WORLD,err_MPI) +#ifdef __GFORTRAN__ + err_div = utilities_divergenceRMS(r_F) +#else + err_div = utilities_divergenceRMS(P) +#endif + e = 0 + do k = 1, cells3; do j = 1, cells(2); do i = 1, cells(1) + e = e + 1 + r_F(1:3,1:3,i,j,k) = & + math_mul3333xx33(math_invSym3333(homogenization_dPdF(1:3,1:3,1:3,1:3,e) + C_scale), & +#ifdef __GFORTRAN__ + r_F(1:3,1:3,i,j,k) - matmul(F(1:3,1:3,i,j,k), & +#else + P(1:3,1:3,i,j,k) - matmul(F(1:3,1:3,i,j,k), & +#endif + math_mul3333xx33(C_scale,F_tau(1:3,1:3,i,j,k) - F(1:3,1:3,i,j,k) - math_I3))) & + + r_F_tau(1:3,1:3,i,j,k) + end do; end do; end do +#ifndef __GFORTRAN__ + end associate +#endif -!-------------------------------------------------------------------------------------------------- -! evaluate constitutive response - call utilities_constitutiveResponse(r_F, & ! "residuum" gets field of first PK stress (to save memory) - P_av,C_volAvg,C_minMaxAvg, & - F - r_F_tau/num%beta,params%Delta_t,params%rotation_BC) - call MPI_Allreduce(MPI_IN_PLACE,terminallyIll,1_MPI_INTEGER_KIND,MPI_LOGICAL,MPI_LOR,MPI_COMM_WORLD,err_MPI) - -!-------------------------------------------------------------------------------------------------- -! stress BC handling F_aim = F_aim - math_mul3333xx33(S, P_av - P_aim) ! S = 0.0 for no bc err_BC = maxval(abs(merge(math_mul3333xx33(C_scale,F_aim-params%rotation_BC%rotate(F_av)), & P_av-P_aim, & params%stress_mask))) -! calculate divergence - tensorField_real = 0.0_pReal - tensorField_real(1:3,1:3,1:cells(1),1:cells(2),1:cells3) = r_F !< stress field in disguise - call utilities_FFTtensorForward - err_div = utilities_divergenceRMS() !< root mean squared error in divergence of stress -!-------------------------------------------------------------------------------------------------- -! constructing residual - e = 0 - do k = 1, cells3; do j = 1, cells(2); do i = 1, cells(1) - e = e + 1 - r_F(1:3,1:3,i,j,k) = & - math_mul3333xx33(math_invSym3333(homogenization_dPdF(1:3,1:3,1:3,1:3,e) + C_scale), & - r_F(1:3,1:3,i,j,k) - matmul(F(1:3,1:3,i,j,k), & - math_mul3333xx33(C_scale,F_tau(1:3,1:3,i,j,k) - F(1:3,1:3,i,j,k) - math_I3))) & - + r_F_tau(1:3,1:3,i,j,k) - end do; end do; end do - -!-------------------------------------------------------------------------------------------------- -! calculating curl - tensorField_real = 0.0_pReal - tensorField_real(1:3,1:3,1:cells(1),1:cells(2),1:cells3) = F - call utilities_FFTtensorForward - err_curl = utilities_curlRMS() end subroutine formResidual diff --git a/src/grid/grid_thermal_spectral.f90 b/src/grid/grid_thermal_spectral.f90 index ff0c5b403..a5d9f4ec8 100644 --- a/src/grid/grid_thermal_spectral.f90 +++ b/src/grid/grid_thermal_spectral.f90 @@ -48,10 +48,10 @@ module grid_thermal_spectral SNES :: SNES_thermal Vec :: solution_vec real(pReal), dimension(:,:,:), allocatable :: & - T_current, & !< field of current temperature + T, & !< field of current temperature T_lastInc, & !< field of previous temperature - T_stagInc !< field of staggered temperature - + T_stagInc, & !< field of staggered temperature + dotT_lastInc !-------------------------------------------------------------------------------------------------- ! reference diffusion tensor, mobility etc. integer :: totalIter = 0 !< total iteration in current increment @@ -74,11 +74,12 @@ subroutine grid_thermal_spectral_init() PetscInt, dimension(0:worldsize-1) :: localK integer :: i, j, k, ce DM :: thermal_grid - PetscScalar, dimension(:,:,:), pointer :: T_PETSc + real(pReal), dimension(:,:,:), pointer :: T_PETSc integer(MPI_INTEGER_KIND) :: err_MPI PetscErrorCode :: err_PETSc integer(HID_T) :: fileHandle, groupHandle - class(tNode), pointer :: & + real(pReal), dimension(1,product(cells(1:2))*cells3) :: tempN + type(tDict), pointer :: & num_grid print'(/,1x,a)', '<<<+- grid_thermal_spectral init -+>>>' @@ -86,9 +87,11 @@ subroutine grid_thermal_spectral_init() print'(/,1x,a)', 'P. Shanthraj et al., Handbook of Mechanics of Materials, 2019' print'( 1x,a)', 'https://doi.org/10.1007/978-981-10-6855-3_80' + if (.not. homogenization_thermal_active()) call IO_error(501,ext_msg='thermal') + !------------------------------------------------------------------------------------------------- ! read numerical parameters and do sanity checks - num_grid => config_numerics%get('grid',defaultVal=emptyDict) + num_grid => config_numerics%get_dict('grid',defaultVal=emptyDict) num%itmax = num_grid%get_asInt ('itmax', defaultVal=250) num%eps_thermal_atol = num_grid%get_asFloat ('eps_thermal_atol',defaultVal=1.0e-2_pReal) num%eps_thermal_rtol = num_grid%get_asFloat ('eps_thermal_rtol',defaultVal=1.0e-6_pReal) @@ -107,9 +110,10 @@ subroutine grid_thermal_spectral_init() !-------------------------------------------------------------------------------------------------- ! init fields - T_current = discretization_grid_getInitialCondition('T') - T_lastInc = T_current - T_stagInc = T_current + T = discretization_grid_getInitialCondition('T') + T_lastInc = T + T_stagInc = T + dotT_lastInc = 0.0_pReal * T !-------------------------------------------------------------------------------------------------- ! initialize solver specific parts of PETSc @@ -150,19 +154,23 @@ subroutine grid_thermal_spectral_init() fileHandle = HDF5_openFile(getSolverJobName()//'_restart.hdf5','r') groupHandle = HDF5_openGroup(fileHandle,'solver') - call HDF5_read(T_current,groupHandle,'T',.false.) - call HDF5_read(T_lastInc,groupHandle,'T_lastInc',.false.) + call HDF5_read(tempN,groupHandle,'T',.false.) + T = reshape(tempN,[cells(1),cells(2),cells3]) + call HDF5_read(tempN,groupHandle,'T_lastInc',.false.) + T_lastInc = reshape(tempN,[cells(1),cells(2),cells3]) + call HDF5_read(tempN,groupHandle,'dotT_lastInc',.false.) + dotT_lastInc = reshape(tempN,[cells(1),cells(2),cells3]) end if restartRead ce = 0 do k = 1, cells3; do j = 1, cells(2); do i = 1, cells(1) ce = ce + 1 - call homogenization_thermal_setField(T_current(i,j,k),0.0_pReal,ce) + call homogenization_thermal_setField(T(i,j,k),0.0_pReal,ce) end do; end do; end do call DMDAVecGetArrayF90(thermal_grid,solution_vec,T_PETSc,err_PETSc) CHKERRQ(err_PETSc) - T_PETSc = T_current + T_PETSc = T call DMDAVecRestoreArrayF90(thermal_grid,solution_vec,T_PETSc,err_PETSc) CHKERRQ(err_PETSc) @@ -205,20 +213,20 @@ function grid_thermal_spectral_solution(Delta_t) result(solution) solution%converged = .true. solution%iterationsNeeded = totalIter end if - stagNorm = maxval(abs(T_current - T_stagInc)) + stagNorm = maxval(abs(T - T_stagInc)) call MPI_Allreduce(MPI_IN_PLACE,stagNorm,1_MPI_INTEGER_KIND,MPI_DOUBLE,MPI_MAX,MPI_COMM_WORLD,err_MPI) if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' - solution%stagConverged = stagNorm < max(num%eps_thermal_atol, num%eps_thermal_rtol*maxval(T_current)) + solution%stagConverged = stagNorm < max(num%eps_thermal_atol, num%eps_thermal_rtol*maxval(T)) call MPI_Allreduce(MPI_IN_PLACE,solution%stagConverged,1_MPI_INTEGER_KIND,MPI_LOGICAL,MPI_LAND,MPI_COMM_WORLD,err_MPI) if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' - T_stagInc = T_current + T_stagInc = T !-------------------------------------------------------------------------------------------------- ! updating thermal state ce = 0 do k = 1, cells3; do j = 1, cells(2); do i = 1,cells(1) ce = ce + 1 - call homogenization_thermal_setField(T_current(i,j,k),(T_current(i,j,k)-T_lastInc(i,j,k))/params%Delta_t,ce) + call homogenization_thermal_setField(T(i,j,k),(T(i,j,k)-T_lastInc(i,j,k))/params%Delta_t,ce) end do; end do; end do call VecMin(solution_vec,devNull,T_min,err_PETSc) @@ -240,13 +248,15 @@ end function grid_thermal_spectral_solution subroutine grid_thermal_spectral_forward(cutBack) logical, intent(in) :: cutBack + integer :: i, j, k, ce DM :: dm_local - PetscScalar, dimension(:,:,:), pointer :: T_PETSc + real(pReal), dimension(:,:,:), pointer :: T_PETSc PetscErrorCode :: err_PETSc + if (cutBack) then - T_current = T_lastInc + T = T_lastInc T_stagInc = T_lastInc !-------------------------------------------------------------------------------------------------- @@ -255,16 +265,17 @@ subroutine grid_thermal_spectral_forward(cutBack) CHKERRQ(err_PETSc) call DMDAVecGetArrayF90(dm_local,solution_vec,T_PETSc,err_PETSc) !< get the data out of PETSc to work with CHKERRQ(err_PETSc) - T_PETSc = T_current + T_PETSc = T call DMDAVecRestoreArrayF90(dm_local,solution_vec,T_PETSc,err_PETSc) CHKERRQ(err_PETSc) ce = 0 do k = 1, cells3; do j = 1, cells(2); do i = 1,cells(1) ce = ce + 1 - call homogenization_thermal_setField(T_current(i,j,k),(T_current(i,j,k)-T_lastInc(i,j,k))/params%Delta_t,ce) + call homogenization_thermal_setField(T(i,j,k),dotT_lastInc(i,j,k),ce) end do; end do; end do else - T_lastInc = T_current + dotT_lastInc = (T - T_lastInc)/params%Delta_t + T_lastInc = T call updateReference end if @@ -272,14 +283,14 @@ end subroutine grid_thermal_spectral_forward !-------------------------------------------------------------------------------------------------- -!> @brief Write current solver and constitutive data for restart to file +!> @brief Write current solver and constitutive data for restart to file. !-------------------------------------------------------------------------------------------------- subroutine grid_thermal_spectral_restartWrite PetscErrorCode :: err_PETSc DM :: dm_local integer(HID_T) :: fileHandle, groupHandle - PetscScalar, dimension(:,:,:), pointer :: T + real(pReal), dimension(:,:,:), pointer :: T call SNESGetDM(SNES_thermal,dm_local,err_PETSc); CHKERRQ(err_PETSc) @@ -290,8 +301,9 @@ subroutine grid_thermal_spectral_restartWrite fileHandle = HDF5_openFile(getSolverJobName()//'_restart.hdf5','a') groupHandle = HDF5_openGroup(fileHandle,'solver') - call HDF5_write(T,groupHandle,'T') - call HDF5_write(T_lastInc,groupHandle,'T_lastInc') + call HDF5_write(reshape(T,[1,product(cells(1:2))*cells3]),groupHandle,'T') + call HDF5_write(reshape(T_lastInc,[1,product(cells(1:2))*cells3]),groupHandle,'T_lastInc') + call HDF5_write(reshape(dotT_lastInc,[1,product(cells(1:2))*cells3]),groupHandle,'dotT_lastInc') call HDF5_closeGroup(groupHandle) call HDF5_closeFile(fileHandle) @@ -303,62 +315,48 @@ end subroutine grid_thermal_spectral_restartWrite !-------------------------------------------------------------------------------------------------- -!> @brief forms the spectral thermal residual vector +!> @brief Construct the residual vector. !-------------------------------------------------------------------------------------------------- -subroutine formResidual(in,x_scal,r,dummy,err_PETSc) +subroutine formResidual(residual_subdomain,x_scal,r,dummy,err_PETSc) DMDALocalInfo, dimension(DMDA_LOCAL_INFO_SIZE) :: & - in - PetscScalar, dimension( & - XG_RANGE,YG_RANGE,ZG_RANGE), intent(in) :: & + residual_subdomain + real(pReal), dimension(cells(1),cells(2),cells3), intent(in) :: & x_scal - PetscScalar, dimension( & - X_RANGE,Y_RANGE,Z_RANGE), intent(out) :: & - r + real(pReal), dimension(cells(1),cells(2),cells3), intent(out) :: & + r !< residual PetscObject :: dummy - PetscErrorCode :: err_PETSc + PetscErrorCode, intent(out) :: err_PETSc + integer :: i, j, k, ce + real(pReal), dimension(3,cells(1),cells(2),cells3) :: vectorField - T_current = x_scal -!-------------------------------------------------------------------------------------------------- -! evaluate polarization field - scalarField_real = 0.0_pReal - scalarField_real(1:cells(1),1:cells(2),1:cells3) = T_current - call utilities_FFTscalarForward - call utilities_fourierScalarGradient !< calculate gradient of temperature field - call utilities_FFTvectorBackward + + T = x_scal + vectorField = utilities_ScalarGradient(T) ce = 0 do k = 1, cells3; do j = 1, cells(2); do i = 1,cells(1) ce = ce + 1 - vectorField_real(1:3,i,j,k) = matmul(homogenization_K_T(ce) - K_ref, vectorField_real(1:3,i,j,k)) + vectorField(1:3,i,j,k) = matmul(homogenization_K_T(ce) - K_ref, vectorField(1:3,i,j,k)) end do; end do; end do - call utilities_FFTvectorForward - call utilities_fourierVectorDivergence !< calculate temperature divergence in fourier field - call utilities_FFTscalarBackward + r = utilities_VectorDivergence(vectorField) ce = 0 do k = 1, cells3; do j = 1, cells(2); do i = 1,cells(1) ce = ce + 1 - scalarField_real(i,j,k) = params%Delta_t*(scalarField_real(i,j,k) + homogenization_f_T(ce)) & - + homogenization_mu_T(ce) * (T_lastInc(i,j,k) - T_current(i,j,k)) & - + mu_ref*T_current(i,j,k) + r(i,j,k) = params%Delta_t*(r(i,j,k) + homogenization_f_T(ce)) & + + homogenization_mu_T(ce) * (T_lastInc(i,j,k) - T(i,j,k)) & + + mu_ref*T(i,j,k) end do; end do; end do -!-------------------------------------------------------------------------------------------------- -! convolution of temperature field with green operator - call utilities_FFTscalarForward - call utilities_fourierGreenConvolution(K_ref, mu_ref, params%Delta_t) - call utilities_FFTscalarBackward - -!-------------------------------------------------------------------------------------------------- -! constructing residual - r = T_current - scalarField_real(1:cells(1),1:cells(2),1:cells3) + r = T & + - utilities_GreenConvolution(r, K_ref, mu_ref, params%Delta_t) err_PETSc = 0 end subroutine formResidual !-------------------------------------------------------------------------------------------------- -!> @brief update reference viscosity and conductivity +!> @brief Update reference viscosity and conductivity. !-------------------------------------------------------------------------------------------------- subroutine updateReference() diff --git a/src/grid/spectral_utilities.f90 b/src/grid/spectral_utilities.f90 index 5359ac1cc..8fe62012b 100644 --- a/src/grid/spectral_utilities.f90 +++ b/src/grid/spectral_utilities.f90 @@ -42,16 +42,16 @@ module spectral_utilities !-------------------------------------------------------------------------------------------------- ! variables storing information for spectral method and FFTW - real(C_DOUBLE), public, dimension(:,:,:,:,:), pointer :: tensorField_real !< tensor field in real space - real(C_DOUBLE), public, dimension(:,:,:,:), pointer :: vectorField_real !< vector field in real space - real(C_DOUBLE), public, dimension(:,:,:), pointer :: scalarField_real !< scalar field in real space - complex(C_DOUBLE_COMPLEX), dimension(:,:,:,:,:), pointer :: tensorField_fourier !< tensor field in Fourier space - complex(C_DOUBLE_COMPLEX), dimension(:,:,:,:), pointer :: vectorField_fourier !< vector field in Fourier space - complex(C_DOUBLE_COMPLEX), dimension(:,:,:), pointer :: scalarField_fourier !< scalar field in Fourier space - complex(pReal), dimension(:,:,:,:,:,:,:), allocatable :: gamma_hat !< gamma operator (field) for spectral method - complex(pReal), dimension(:,:,:,:), allocatable :: xi1st !< wave vector field for first derivatives - complex(pReal), dimension(:,:,:,:), allocatable :: xi2nd !< wave vector field for second derivatives - real(pReal), dimension(3,3,3,3) :: C_ref !< mechanic reference stiffness + real(C_DOUBLE), dimension(:,:,:,:,:), pointer :: tensorField_real !< tensor field in real space + real(C_DOUBLE), dimension(:,:,:,:), pointer :: vectorField_real !< vector field in real space + real(C_DOUBLE), dimension(:,:,:), pointer :: scalarField_real !< scalar field in real space + complex(C_DOUBLE_COMPLEX), dimension(:,:,:,:,:), pointer :: tensorField_fourier !< tensor field in Fourier space + complex(C_DOUBLE_COMPLEX), dimension(:,:,:,:), pointer :: vectorField_fourier !< vector field in Fourier space + complex(C_DOUBLE_COMPLEX), dimension(:,:,:), pointer :: scalarField_fourier !< scalar field in Fourier space + complex(pReal), dimension(:,:,:,:,:,:,:), allocatable :: gamma_hat !< gamma operator (field) for spectral method + complex(pReal), dimension(:,:,:,:), allocatable :: xi1st !< wave vector field for first derivatives + complex(pReal), dimension(:,:,:,:), allocatable :: xi2nd !< wave vector field for second derivatives + real(pReal), dimension(3,3,3,3) :: C_ref !< mechanic reference stiffness !-------------------------------------------------------------------------------------------------- @@ -116,24 +116,17 @@ module spectral_utilities public :: & spectral_utilities_init, & utilities_updateGamma, & - utilities_FFTtensorForward, & - utilities_FFTtensorBackward, & - utilities_FFTvectorForward, & - utilities_FFTvectorBackward, & - utilities_FFTscalarForward, & - utilities_FFTscalarBackward, & - utilities_fourierGammaConvolution, & - utilities_fourierGreenConvolution, & + utilities_GammaConvolution, & + utilities_GreenConvolution, & utilities_divergenceRMS, & utilities_curlRMS, & - utilities_fourierScalarGradient, & - utilities_fourierVectorDivergence, & + utilities_scalarGradient, & + utilities_vectorDivergence, & utilities_maskedCompliance, & utilities_constitutiveResponse, & utilities_calculateRate, & utilities_forwardField, & - utilities_updateCoords, & - utilities_saveReferenceStiffness + utilities_updateCoords contains @@ -166,9 +159,11 @@ subroutine spectral_utilities_init() tensorSize = 9_C_INTPTR_T character(len=*), parameter :: & PETSCDEBUG = ' -snes_view -snes_monitor ' - class(tNode) , pointer :: & - num_grid, & - debug_grid ! pointer to grid debug options + type(tDict) , pointer :: & + num_grid + type(tList) , pointer :: & + debug_grid + print'(/,1x,a)', '<<<+- spectral_utilities init -+>>>' @@ -186,9 +181,9 @@ subroutine spectral_utilities_init() !-------------------------------------------------------------------------------------------------- ! set debugging parameters - num_grid => config_numerics%get('grid',defaultVal=emptyDict) + num_grid => config_numerics%get_dict('grid',defaultVal=emptyDict) - debug_grid => config_debug%get('grid',defaultVal=emptyList) + debug_grid => config_debug%get_List('grid',defaultVal=emptyList) debugGeneral = debug_grid%contains('basic') debugRotation = debug_grid%contains('rotation') debugPETSc = debug_grid%contains('PETSc') @@ -304,8 +299,8 @@ subroutine spectral_utilities_init() !-------------------------------------------------------------------------------------------------- ! allocation - allocate (xi1st (3,cells1Red,cells(3),cells2),source = cmplx(0.0_pReal,0.0_pReal,pReal)) ! frequencies for first derivatives, only half the size for first dimension - allocate (xi2nd (3,cells1Red,cells(3),cells2),source = cmplx(0.0_pReal,0.0_pReal,pReal)) ! frequencies for second derivatives, only half the size for first dimension + allocate (xi1st (3,cells1Red,cells(3),cells2),source = cmplx(0.0_pReal,0.0_pReal,pReal)) ! frequencies for first derivatives, only half the size for first dimension + allocate (xi2nd (3,cells1Red,cells(3),cells2),source = cmplx(0.0_pReal,0.0_pReal,pReal)) ! frequencies for second derivatives, only half the size for first dimension !-------------------------------------------------------------------------------------------------- ! tensor MPI fftw plans @@ -383,6 +378,7 @@ end subroutine spectral_utilities_init subroutine utilities_updateGamma(C) real(pReal), intent(in), dimension(3,3,3,3) :: C !< input stiffness to store as reference stiffness + complex(pReal), dimension(3,3) :: temp33_cmplx, xiDyad_cmplx real(pReal), dimension(6,6) :: A, A_inv integer :: & @@ -390,7 +386,8 @@ subroutine utilities_updateGamma(C) l, m, n, o logical :: err - C_ref = C + + C_ref = C/wgt if (.not. num%memory_efficient) then gamma_hat = cmplx(0.0_pReal,0.0_pReal,pReal) ! for the singular point and any non invertible A @@ -432,68 +429,6 @@ subroutine utilities_updateGamma(C) end subroutine utilities_updateGamma -!-------------------------------------------------------------------------------------------------- -!> @brief forward FFT of data in field_real to field_fourier -!> @details Does an unweighted FFT transform from real to complex. Extra padding entries are set -! to 0.0 -!-------------------------------------------------------------------------------------------------- -subroutine utilities_FFTtensorForward() - - tensorField_real(1:3,1:3,cells(1)+1:cells1Red*2,:,:) = 0.0_pReal - call fftw_mpi_execute_dft_r2c(planTensorForth,tensorField_real,tensorField_fourier) - -end subroutine utilities_FFTtensorForward - - -!-------------------------------------------------------------------------------------------------- -!> @brief backward FFT of data in field_fourier to field_real -!> @details Does an weighted inverse FFT transform from complex to real -!-------------------------------------------------------------------------------------------------- -subroutine utilities_FFTtensorBackward() - - call fftw_mpi_execute_dft_c2r(planTensorBack,tensorField_fourier,tensorField_real) - tensorField_real = tensorField_real * wgt ! normalize the result by number of elements - -end subroutine utilities_FFTtensorBackward - -!-------------------------------------------------------------------------------------------------- -!> @brief forward FFT of data in scalarField_real to scalarField_fourier -!> @details Does an unweighted FFT transform from real to complex. Extra padding entries are set -! to 0.0 -!-------------------------------------------------------------------------------------------------- -subroutine utilities_FFTscalarForward() - - scalarField_real(cells(1)+1:cells1Red*2,:,:) = 0.0_pReal - call fftw_mpi_execute_dft_r2c(planScalarForth,scalarField_real,scalarField_fourier) - -end subroutine utilities_FFTscalarForward - - -!-------------------------------------------------------------------------------------------------- -!> @brief backward FFT of data in scalarField_fourier to scalarField_real -!> @details Does an weighted inverse FFT transform from complex to real -!-------------------------------------------------------------------------------------------------- -subroutine utilities_FFTscalarBackward() - - call fftw_mpi_execute_dft_c2r(planScalarBack,scalarField_fourier,scalarField_real) - scalarField_real = scalarField_real * wgt ! normalize the result by number of elements - -end subroutine utilities_FFTscalarBackward - - -!-------------------------------------------------------------------------------------------------- -!> @brief forward FFT of data in field_real to field_fourier with highest freqs. removed -!> @details Does an unweighted FFT transform from real to complex. Extra padding entries are set -! to 0.0 -!-------------------------------------------------------------------------------------------------- -subroutine utilities_FFTvectorForward() - - vectorField_real(1:3,cells(1)+1:cells1Red*2,:,:) = 0.0_pReal - call fftw_mpi_execute_dft_r2c(planVectorForth,vectorField_real,vectorField_fourier) - -end subroutine utilities_FFTvectorForward - - !-------------------------------------------------------------------------------------------------- !> @brief backward FFT of data in field_fourier to field_real !> @details Does an weighted inverse FFT transform from complex to real @@ -509,12 +444,14 @@ end subroutine utilities_FFTvectorBackward !-------------------------------------------------------------------------------------------------- !> @brief doing convolution gamma_hat * field_real, ensuring that average value = fieldAim !-------------------------------------------------------------------------------------------------- -subroutine utilities_fourierGammaConvolution(fieldAim) +function utilities_GammaConvolution(field, fieldAim) result(gammaField) + real(pReal), intent(in), dimension(3,3,cells(1),cells(2),cells3) :: field real(pReal), intent(in), dimension(3,3) :: fieldAim !< desired average value of the field after convolution - complex(pReal), dimension(3,3) :: temp33_cmplx, xiDyad_cmplx - real(pReal), dimension(6,6) :: A, A_inv + real(pReal), dimension(3,3,cells(1),cells(2),cells3) :: gammaField + complex(pReal), dimension(3,3) :: temp33_cmplx, xiDyad_cmplx + real(pReal), dimension(6,6) :: A, A_inv integer :: & i, j, k, & l, m, n, o @@ -524,8 +461,10 @@ subroutine utilities_fourierGammaConvolution(fieldAim) print'(/,1x,a)', '... doing gamma convolution ...............................................' flush(IO_STDOUT) -!-------------------------------------------------------------------------------------------------- -! do the actual spectral method calculation (mechanical equilibrium) + tensorField_real(1:3,1:3,cells(1)+1:cells1Red*2,1:cells(2),1:cells3) = 0.0_pReal + tensorField_real(1:3,1:3,1:cells(1), 1:cells(2),1:cells3) = field + call fftw_mpi_execute_dft_r2c(planTensorForth,tensorField_real,tensorField_fourier) + memoryEfficient: if (num%memory_efficient) then !$OMP PARALLEL DO PRIVATE(l,m,n,o,temp33_cmplx,xiDyad_cmplx,A,A_inv,err,gamma_hat) do j = 1, cells2; do k = 1, cells(3); do i = 1, cells1Red @@ -584,47 +523,62 @@ subroutine utilities_fourierGammaConvolution(fieldAim) !$OMP END PARALLEL DO end if memoryEfficient - if (cells3Offset == 0) tensorField_fourier(1:3,1:3,1,1,1) = cmplx(fieldAim/wgt,0.0_pReal,pReal) + if (cells3Offset == 0) tensorField_fourier(1:3,1:3,1,1,1) = cmplx(fieldAim,0.0_pReal,pReal) -end subroutine utilities_fourierGammaConvolution + call fftw_mpi_execute_dft_c2r(planTensorBack,tensorField_fourier,tensorField_real) + gammaField = tensorField_real(1:3,1:3,1:cells(1),1:cells(2),1:cells3) + +end function utilities_GammaConvolution !-------------------------------------------------------------------------------------------------- -!> @brief doing convolution DamageGreenOp_hat * field_real +!> @brief Convolution of Greens' operator for damage/thermal. !-------------------------------------------------------------------------------------------------- -subroutine utilities_fourierGreenConvolution(D_ref, mu_ref, Delta_t) +function utilities_GreenConvolution(field, D_ref, mu_ref, Delta_t) result(greenField) + real(pReal), intent(in), dimension(cells(1),cells(2),cells3) :: field real(pReal), dimension(3,3), intent(in) :: D_ref real(pReal), intent(in) :: mu_ref, Delta_t + real(pReal), dimension(cells(1),cells(2),cells3) :: greenField + complex(pReal) :: GreenOp_hat integer :: i, j, k -!-------------------------------------------------------------------------------------------------- -! do the actual spectral method calculation + + scalarField_real(cells(1)+1:cells1Red*2,1:cells(2),1:cells3) = 0.0_pReal + scalarField_real(1:cells(1), 1:cells(2),1:cells3) = field + call fftw_mpi_execute_dft_r2c(planScalarForth,scalarField_real,scalarField_fourier) + !$OMP PARALLEL DO PRIVATE(GreenOp_hat) do j = 1, cells2; do k = 1, cells(3); do i = 1, cells1Red - GreenOp_hat = cmplx(1.0_pReal,0.0_pReal,pReal) & + GreenOp_hat = cmplx(wgt,0.0_pReal,pReal) & / (cmplx(mu_ref,0.0_pReal,pReal) + cmplx(Delta_t,0.0_pReal,pReal) & * sum(conjg(xi1st(1:3,i,k,j))* matmul(cmplx(D_ref,0.0_pReal,pReal),xi1st(1:3,i,k,j)))) scalarField_fourier(i,k,j) = scalarField_fourier(i,k,j)*GreenOp_hat end do; end do; end do !$OMP END PARALLEL DO -end subroutine utilities_fourierGreenConvolution + call fftw_mpi_execute_dft_c2r(planScalarBack,scalarField_fourier,scalarField_real) + greenField = scalarField_real(1:cells(1),1:cells(2),1:cells3) + +end function utilities_GreenConvolution !-------------------------------------------------------------------------------------------------- -!> @brief calculate root mean square of divergence of field_fourier +!> @brief Calculate root mean square of divergence. !-------------------------------------------------------------------------------------------------- -real(pReal) function utilities_divergenceRMS() +real(pReal) function utilities_divergenceRMS(tensorField) + + real(pReal), dimension(3,3,cells(1),cells(2),cells3), intent(in) :: tensorField integer :: i, j, k integer(MPI_INTEGER_KIND) :: err_MPI complex(pReal), dimension(3) :: rescaledGeom - print'(/,1x,a)', '... calculating divergence ................................................' - flush(IO_STDOUT) + tensorField_real(1:3,1:3,cells(1)+1:cells1Red*2,1:cells(2),1:cells3) = 0.0_pReal + tensorField_real(1:3,1:3,1:cells(1), 1:cells(2),1:cells3) = tensorField + call fftw_mpi_execute_dft_r2c(planTensorForth,tensorField_real,tensorField_fourier) rescaledGeom = cmplx(geomSize/scaledGeomSize,0.0_pReal,pReal) @@ -658,9 +612,11 @@ end function utilities_divergenceRMS !-------------------------------------------------------------------------------------------------- -!> @brief calculate max of curl of field_fourier +!> @brief Calculate root mean square of curl. !-------------------------------------------------------------------------------------------------- -real(pReal) function utilities_curlRMS() +real(pReal) function utilities_curlRMS(tensorField) + + real(pReal), dimension(3,3,cells(1),cells(2),cells3), intent(in) :: tensorField integer :: i, j, k, l integer(MPI_INTEGER_KIND) :: err_MPI @@ -668,8 +624,9 @@ real(pReal) function utilities_curlRMS() complex(pReal), dimension(3) :: rescaledGeom - print'(/,1x,a)', '... calculating curl ......................................................' - flush(IO_STDOUT) + tensorField_real(1:3,1:3,cells(1)+1:cells1Red*2,1:cells(2),1:cells3) = 0.0_pReal + tensorField_real(1:3,1:3,1:cells(1), 1:cells(2),1:cells3) = tensorField + call fftw_mpi_execute_dft_r2c(planTensorForth,tensorField_real,tensorField_fourier) rescaledGeom = cmplx(geomSize/scaledGeomSize,0.0_pReal,pReal) @@ -721,7 +678,7 @@ end function utilities_curlRMS !-------------------------------------------------------------------------------------------------- -!> @brief calculates mask compliance tensor used to adjust F to fullfill stress BC +!> @brief Calculate masked compliance tensor used to adjust F to fullfill stress BC. !-------------------------------------------------------------------------------------------------- function utilities_maskedCompliance(rot_BC,mask_stress,C) @@ -791,29 +748,46 @@ end function utilities_maskedCompliance !-------------------------------------------------------------------------------------------------- -!> @brief calculate scalar gradient in fourier field +!> @brief Calculate gradient of scalar field. !-------------------------------------------------------------------------------------------------- -subroutine utilities_fourierScalarGradient() +function utilities_scalarGradient(field) result(grad) + + real(pReal), intent(in), dimension( cells(1),cells(2),cells3) :: field + real(pReal), dimension(3,cells(1),cells(2),cells3) :: grad integer :: i, j, k + scalarField_real(cells(1)+1:cells1Red*2,1:cells(2),1:cells3) = 0.0_pReal + scalarField_real(1:cells(1), 1:cells(2),1:cells3) = field + call fftw_mpi_execute_dft_r2c(planScalarForth,scalarField_real,scalarField_fourier) do j = 1, cells2; do k = 1, cells(3); do i = 1,cells1Red - vectorField_fourier(1:3,i,k,j) = scalarField_fourier(i,k,j)*xi1st(1:3,i,k,j) ! ToDo: no -conjg? + vectorField_fourier(1:3,i,k,j) = scalarField_fourier(i,k,j)*xi1st(1:3,i,k,j) end do; end do; end do + call fftw_mpi_execute_dft_c2r(planVectorBack,vectorField_fourier,vectorField_real) + grad = vectorField_real(1:3,1:cells(1),1:cells(2),1:cells3)*wgt -end subroutine utilities_fourierScalarGradient +end function utilities_scalarGradient !-------------------------------------------------------------------------------------------------- -!> @brief calculate vector divergence in fourier field +!> @brief Calculate divergence of vector field. !-------------------------------------------------------------------------------------------------- -subroutine utilities_fourierVectorDivergence() +function utilities_vectorDivergence(field) result(div) + real(pReal), intent(in), dimension(3,cells(1),cells(2),cells3) :: field + real(pReal), dimension( cells(1),cells(2),cells3) :: div + + + vectorField_real(1:3,cells(1)+1:cells1Red*2,1:cells(2),1:cells3) = 0.0_pReal + vectorField_real(1:3,1:cells(1), 1:cells(2),1:cells3) = field + call fftw_mpi_execute_dft_r2c(planVectorForth,vectorField_real,vectorField_fourier) scalarField_fourier(1:cells1Red,1:cells(3),1:cells2) = sum(vectorField_fourier(1:3,1:cells1Red,1:cells(3),1:cells2) & - *conjg(-xi1st),1) + *conjg(-xi1st),1) ! ToDo: use "xi1st" instead of "conjg(-xi1st)"? + call fftw_mpi_execute_dft_c2r(planScalarBack,scalarField_fourier,scalarField_real) + div = scalarField_real(1:cells(1),1:cells(2),1:cells3)*wgt -end subroutine utilities_fourierVectorDivergence +end function utilities_vectorDivergence !-------------------------------------------------------------------------------------------------- @@ -955,7 +929,7 @@ end function utilities_forwardField !-------------------------------------------------------------------------------------------------- -!> @brief calculates filter for fourier convolution depending on type given in numerics.config +!> @brief Calculate Filter for Fourier convolution. !> @details this is the full operator to calculate derivatives, i.e. 2 \pi i k for the ! standard approach !-------------------------------------------------------------------------------------------------- @@ -1030,7 +1004,7 @@ subroutine utilities_updateCoords(F) #endif real(pReal), dimension(3) :: step real(pReal), dimension(3,3) :: Favg - integer, dimension(3) :: me + integer, dimension(3) :: me integer, dimension(3,8) :: & neighbor = reshape([ & 0, 0, 0, & @@ -1044,11 +1018,19 @@ subroutine utilities_updateCoords(F) step = geomSize/real(cells, pReal) + + tensorField_real(1:3,1:3,1:cells(1), 1:cells(2),1:cells3) = F + tensorField_real(1:3,1:3,cells(1)+1:cells1Red*2,1:cells(2),1:cells3) = 0.0_pReal + call fftw_mpi_execute_dft_r2c(planTensorForth,tensorField_real,tensorField_fourier) + + !-------------------------------------------------------------------------------------------------- + ! average F + if (cells3Offset == 0) Favg = tensorField_fourier(1:3,1:3,1,1,1)%re*wgt + call MPI_Bcast(Favg,9_MPI_INTEGER_KIND,MPI_DOUBLE,0_MPI_INTEGER_KIND,MPI_COMM_WORLD,err_MPI) + if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' + !-------------------------------------------------------------------------------------------------- ! integration in Fourier space to get fluctuations of cell center discplacements - tensorField_real(1:3,1:3,1:cells(1),1:cells(2),1:cells3) = F - call utilities_FFTtensorForward() - !$OMP PARALLEL DO do j = 1, cells2; do k = 1, cells(3); do i = 1, cells1Red if (any([i,j+cells2Offset,k] /= 1)) then @@ -1060,13 +1042,8 @@ subroutine utilities_updateCoords(F) end do; end do; end do !$OMP END PARALLEL DO - call utilities_FFTvectorBackward() - - !-------------------------------------------------------------------------------------------------- - ! average F - if (cells3Offset == 0) Favg = tensorField_fourier(1:3,1:3,1,1,1)%re*wgt - call MPI_Bcast(Favg,9_MPI_INTEGER_KIND,MPI_DOUBLE,0_MPI_INTEGER_KIND,MPI_COMM_WORLD,err_MPI) - if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' + call fftw_mpi_execute_dft_c2r(planVectorBack,vectorField_fourier,vectorField_real) + vectorField_real = vectorField_real * wgt ! normalize the result by number of elements !-------------------------------------------------------------------------------------------------- ! pad cell center fluctuations along z-direction (needed when running MPI simulation) @@ -1120,27 +1097,6 @@ subroutine utilities_updateCoords(F) end subroutine utilities_updateCoords -!--------------------------------------------------------------------------------------------------- -!> @brief Write out the current reference stiffness for restart. -!--------------------------------------------------------------------------------------------------- -subroutine utilities_saveReferenceStiffness() - - integer :: & - fileUnit,ierr - - - if (worldrank == 0) then - print'(/,1x,a)', '... writing reference stiffness data required for restart to file .........'; flush(IO_STDOUT) - open(newunit=fileUnit, file=getSolverJobName()//'.C_ref',& - status='replace',access='stream',action='write',iostat=ierr) - if (ierr /=0) call IO_error(100,ext_msg='could not open file '//getSolverJobName()//'.C_ref') - write(fileUnit) C_ref - close(fileUnit) - end if - -end subroutine utilities_saveReferenceStiffness - - !-------------------------------------------------------------------------------------------------- !> @brief Check correctness of forward-backward transform. !-------------------------------------------------------------------------------------------------- @@ -1149,43 +1105,116 @@ subroutine selfTest() real(pReal), allocatable, dimension(:,:,:,:,:) :: tensorField_real_ real(pReal), allocatable, dimension(:,:,:,:) :: vectorField_real_ real(pReal), allocatable, dimension(:,:,:) :: scalarField_real_ + real(pReal), dimension(3,3) :: tensorSum + real(pReal), dimension(3) :: vectorSum + real(pReal) :: scalarSum + real(pReal), dimension(3,3) :: r + integer(MPI_INTEGER_KIND) :: err_MPI call random_number(tensorField_real) tensorField_real(1:3,1:3,cells(1)+1:cells1Red*2,:,:) = 0.0_pReal tensorField_real_ = tensorField_real - call utilities_FFTtensorForward() - if (worldsize==1) then - if (any(dNeq(sum(sum(sum(tensorField_real_,dim=5),dim=4),dim=3)/tensorField_fourier(:,:,1,1,1)%re,1.0_pReal,1.0e-12_pReal))) & - error stop 'tensorField avg' - endif - call utilities_FFTtensorBackward() + call fftw_mpi_execute_dft_r2c(planTensorForth,tensorField_real,tensorField_fourier) + call MPI_Allreduce(sum(sum(sum(tensorField_real_,dim=5),dim=4),dim=3),tensorSum,9_MPI_INTEGER_KIND, & + MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD,err_MPI) + if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' + if (worldrank==0) then + if (any(dNeq(tensorSum/tensorField_fourier(:,:,1,1,1)%re,1.0_pReal,1.0e-12_pReal))) & + error stop 'mismatch avg tensorField FFT <-> real' + end if + call fftw_mpi_execute_dft_c2r(planTensorBack,tensorField_fourier,tensorField_real) tensorField_real(1:3,1:3,cells(1)+1:cells1Red*2,:,:) = 0.0_pReal - if (maxval(abs(tensorField_real_ - tensorField_real))>5.0e-15_pReal) error stop 'tensorField' + if (maxval(abs(tensorField_real_ - tensorField_real*wgt))>5.0e-15_pReal) & + error stop 'mismatch tensorField FFT/invFFT <-> real' call random_number(vectorField_real) vectorField_real(1:3,cells(1)+1:cells1Red*2,:,:) = 0.0_pReal vectorField_real_ = vectorField_real - call utilities_FFTvectorForward() - if (worldsize==1) then - if (any(dNeq(sum(sum(sum(vectorField_real_,dim=4),dim=3),dim=2)/vectorField_fourier(:,1,1,1)%re,1.0_pReal,1.0e-12_pReal))) & - error stop 'vector avg' - endif - call utilities_FFTvectorBackward() + call fftw_mpi_execute_dft_r2c(planVectorForth,vectorField_real,vectorField_fourier) + call MPI_Allreduce(sum(sum(sum(vectorField_real_,dim=4),dim=3),dim=2),vectorSum,3_MPI_INTEGER_KIND, & + MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD,err_MPI) + if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' + if (worldrank==0) then + if (any(dNeq(vectorSum/vectorField_fourier(:,1,1,1)%re,1.0_pReal,1.0e-12_pReal))) & + error stop 'mismatch avg vectorField FFT <-> real' + end if + call fftw_mpi_execute_dft_c2r(planVectorBack,vectorField_fourier,vectorField_real) vectorField_real(1:3,cells(1)+1:cells1Red*2,:,:) = 0.0_pReal - if (maxval(abs(vectorField_real_ - vectorField_real))>5.0e-15_pReal) error stop 'vectorField' + if (maxval(abs(vectorField_real_ - vectorField_real*wgt))>5.0e-15_pReal) & + error stop 'mismatch vectorField FFT/invFFT <-> real' call random_number(scalarField_real) scalarField_real(cells(1)+1:cells1Red*2,:,:) = 0.0_pReal scalarField_real_ = scalarField_real - call utilities_FFTscalarForward() - if (worldsize==1) then - if (dNeq(sum(sum(sum(scalarField_real_,dim=3),dim=2),dim=1)/scalarField_fourier(1,1,1)%re,1.0_pReal,1.0e-12_pReal)) & - error stop 'scalar avg' - endif - call utilities_FFTscalarBackward() + call fftw_mpi_execute_dft_r2c(planScalarForth,scalarField_real,scalarField_fourier) + call MPI_Allreduce(sum(sum(sum(scalarField_real_,dim=3),dim=2),dim=1),scalarSum,1_MPI_INTEGER_KIND, & + MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD,err_MPI) + if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' + if (worldrank==0) then + if (dNeq(scalarSum/scalarField_fourier(1,1,1)%re,1.0_pReal,1.0e-12_pReal)) & + error stop 'mismatch avg scalarField FFT <-> real' + end if + call fftw_mpi_execute_dft_c2r(planScalarBack,scalarField_fourier,scalarField_real) scalarField_real(cells(1)+1:cells1Red*2,:,:) = 0.0_pReal - if (maxval(abs(scalarField_real_ - scalarField_real))>5.0e-15_pReal) error stop 'scalarField' + if (maxval(abs(scalarField_real_ - scalarField_real*wgt))>5.0e-15_pReal) & + error stop 'mismatch scalarField FFT/invFFT <-> real' + + call random_number(r) + call MPI_Bcast(r,9_MPI_INTEGER_KIND,MPI_DOUBLE,0_MPI_INTEGER_KIND,MPI_COMM_WORLD,err_MPI) + if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' + + scalarField_real_ = r(1,1) + if (maxval(abs(utilities_scalarGradient(scalarField_real_)))>5.0e-9_pReal) error stop 'non-zero grad(const)' + + vectorField_real_ = spread(spread(spread(r(1,:),2,cells(1)),3,cells(2)),4,cells3) + if (maxval(abs(utilities_vectorDivergence(vectorField_real_)))>5.0e-9_pReal) error stop 'non-zero div(const)' + + tensorField_real_ = spread(spread(spread(r,3,cells(1)),4,cells(2)),5,cells3) + if (utilities_divergenceRMS(tensorField_real_)>5.0e-14_pReal) error stop 'non-zero RMS div(const)' + if (utilities_curlRMS(tensorField_real_)>5.0e-14_pReal) error stop 'non-zero RMS curl(const)' + + if (cells(1) > 2 .and. spectral_derivative_ID == DERIVATIVE_CONTINUOUS_ID) then + scalarField_real_ = spread(spread(planeCosine(cells(1)),2,cells(2)),3,cells3) + vectorField_real_ = utilities_scalarGradient(scalarField_real_)/TAU*geomSize(1) + scalarField_real_ = -spread(spread(planeSine (cells(1)),2,cells(2)),3,cells3) + if (maxval(abs(vectorField_real_(1,:,:,:) - scalarField_real_))>5.0e-14_pReal) error stop 'grad cosine' + scalarField_real_ = spread(spread(planeSine (cells(1)),2,cells(2)),3,cells3) + vectorField_real_ = utilities_scalarGradient(scalarField_real_)/TAU*geomSize(1) + scalarField_real_ = spread(spread(planeCosine(cells(1)),2,cells(2)),3,cells3) + if (maxval(abs(vectorField_real_(1,:,:,:) - scalarField_real_))>5.0e-14_pReal) error stop 'grad sine' + + vectorField_real_(2:3,:,:,:) = 0.0_pReal + vectorField_real_(1,:,:,:) = spread(spread(planeCosine(cells(1)),2,cells(2)),3,cells3) + scalarField_real_ = utilities_vectorDivergence(vectorField_real_)/TAU*geomSize(1) + vectorField_real_(1,:,:,:) =-spread(spread(planeSine( cells(1)),2,cells(2)),3,cells3) + if (maxval(abs(vectorField_real_(1,:,:,:) - scalarField_real_))>5.0e-14_pReal) error stop 'div cosine' + vectorField_real_(2:3,:,:,:) = 0.0_pReal + vectorField_real_(1,:,:,:) = spread(spread(planeSine( cells(1)),2,cells(2)),3,cells3) + scalarField_real_ = utilities_vectorDivergence(vectorField_real_)/TAU*geomSize(1) + vectorField_real_(1,:,:,:) = spread(spread(planeCosine(cells(1)),2,cells(2)),3,cells3) + if (maxval(abs(vectorField_real_(1,:,:,:) - scalarField_real_))>5.0e-14_pReal) error stop 'div sine' + end if + + contains + + function planeCosine(n) + integer, intent(in) :: n + real(pReal), dimension(n) :: planeCosine + + + planeCosine = cos(real(math_range(n),pReal)/real(n,pReal)*TAU-TAU/real(n*2,pReal)) + + end function planeCosine + + function planeSine(n) + integer, intent(in) :: n + real(pReal), dimension(n) :: planeSine + + + planeSine = sin(real(math_range(n),pReal)/real(n,pReal)*TAU-TAU/real(n*2,pReal)) + + end function planeSine end subroutine selfTest diff --git a/src/homogenization.f90 b/src/homogenization.f90 index b1e462794..9f9b92bec 100644 --- a/src/homogenization.f90 +++ b/src/homogenization.f90 @@ -15,7 +15,7 @@ module homogenization use discretization use HDF5 use HDF5_utilities - use results + use result use lattice implicit none(type,external) @@ -101,20 +101,20 @@ module homogenization ce !< cell end subroutine mechanical_homogenize - module subroutine mechanical_results(group_base,ho) + module subroutine mechanical_result(group_base,ho) character(len=*), intent(in) :: group_base integer, intent(in) :: ho - end subroutine mechanical_results + end subroutine mechanical_result - module subroutine damage_results(ho,group) + module subroutine damage_result(ho,group) integer, intent(in) :: ho character(len=*), intent(in) :: group - end subroutine damage_results + end subroutine damage_result - module subroutine thermal_results(ho,group) + module subroutine thermal_result(ho,group) integer, intent(in) :: ho character(len=*), intent(in) :: group - end subroutine thermal_results + end subroutine thermal_result module function mechanical_updateState(subdt,subF,ce) result(doneAndHappy) real(pReal), intent(in) :: & @@ -126,6 +126,10 @@ module homogenization logical, dimension(2) :: doneAndHappy end function mechanical_updateState + module function homogenization_thermal_active() result(active) + logical :: active + end function homogenization_thermal_active + module function homogenization_mu_T(ce) result(mu) integer, intent(in) :: ce real(pReal) :: mu @@ -146,6 +150,10 @@ module homogenization real(pReal), intent(in) :: T, dot_T end subroutine homogenization_thermal_setField + module function homogenization_damage_active() result(active) + logical :: active + end function homogenization_damage_active + module function homogenization_mu_phi(ce) result(mu) integer, intent(in) :: ce real(pReal) :: mu @@ -175,16 +183,18 @@ module homogenization homogenization_mechanical_response, & homogenization_mechanical_response2, & homogenization_thermal_response, & + homogenization_thermal_active, & homogenization_mu_T, & homogenization_K_T, & homogenization_f_T, & homogenization_thermal_setfield, & + homogenization_damage_active, & homogenization_mu_phi, & homogenization_K_phi, & homogenization_f_phi, & homogenization_set_phi, & homogenization_forward, & - homogenization_results, & + homogenization_result, & homogenization_restartRead, & homogenization_restartWrite @@ -196,7 +206,7 @@ contains !-------------------------------------------------------------------------------------------------- subroutine homogenization_init() - class (tNode) , pointer :: & + type(tDict) , pointer :: & num_homog, & num_homogGeneric @@ -207,8 +217,8 @@ subroutine homogenization_init() allocate(damageState_h (size(material_name_homogenization))) call parseHomogenization() - num_homog => config_numerics%get('homogenization',defaultVal=emptyDict) - num_homogGeneric => num_homog%get('generic',defaultVal=emptyDict) + num_homog => config_numerics%get_dict('homogenization',defaultVal=emptyDict) + num_homogGeneric => num_homog%get_dict('generic',defaultVal=emptyDict) num%nMPstate = num_homogGeneric%get_asInt('nMPstate',defaultVal=10) if (num%nMPstate < 1) call IO_error(301,ext_msg='nMPstate') @@ -245,8 +255,8 @@ subroutine homogenization_mechanical_response(Delta_t,cell_start,cell_end) call phase_restore(ce,.false.) ! wrong name (is more a forward function) - if(homogState(ho)%sizeState > 0) homogState(ho)%state(:,en) = homogState(ho)%state0(:,en) - if(damageState_h(ho)%sizeState > 0) damageState_h(ho)%state(:,en) = damageState_h(ho)%state0(:,en) + if (homogState(ho)%sizeState > 0) homogState(ho)%state(:,en) = homogState(ho)%state0(:,en) + if (damageState_h(ho)%sizeState > 0) damageState_h(ho)%state(:,en) = damageState_h(ho)%state0(:,en) call damage_partition(ce) doneAndHappy = [.false.,.true.] @@ -339,35 +349,35 @@ end subroutine homogenization_mechanical_response2 !-------------------------------------------------------------------------------------------------- !> @brief writes homogenization results to HDF5 output file !-------------------------------------------------------------------------------------------------- -subroutine homogenization_results +subroutine homogenization_result integer :: ho character(len=:), allocatable :: group_base,group - call results_closeGroup(results_addGroup('current/homogenization/')) + call result_closeGroup(result_addGroup('current/homogenization/')) do ho=1,size(material_name_homogenization) group_base = 'current/homogenization/'//trim(material_name_homogenization(ho)) - call results_closeGroup(results_addGroup(group_base)) + call result_closeGroup(result_addGroup(group_base)) - call mechanical_results(group_base,ho) + call mechanical_result(group_base,ho) if (damage_active(ho)) then group = trim(group_base)//'/damage' - call results_closeGroup(results_addGroup(group)) - call damage_results(ho,group) + call result_closeGroup(result_addGroup(group)) + call damage_result(ho,group) end if if (thermal_active(ho)) then group = trim(group_base)//'/thermal' - call results_closeGroup(results_addGroup(group)) - call thermal_results(ho,group) + call result_closeGroup(result_addGroup(group)) + call thermal_result(ho,group) end if end do -end subroutine homogenization_results +end subroutine homogenization_result !-------------------------------------------------------------------------------------------------- @@ -381,7 +391,7 @@ subroutine homogenization_forward do ho = 1, size(material_name_homogenization) homogState (ho)%state0 = homogState (ho)%state - if(damageState_h(ho)%sizeState > 0) & + if (damageState_h(ho)%sizeState > 0) & damageState_h(ho)%state0 = damageState_h(ho)%state end do @@ -406,6 +416,9 @@ subroutine homogenization_restartWrite(fileHandle) call HDF5_write(homogState(ho)%state,groupHandle(2),'omega_mechanical') ! ToDo: should be done by mech + if (damageState_h(ho)%sizeState > 0) & + call HDF5_write(damageState_h(ho)%state,groupHandle(2),'omega_damage') ! ToDo: should be done by mech + call HDF5_closeGroup(groupHandle(2)) end do @@ -433,6 +446,9 @@ subroutine homogenization_restartRead(fileHandle) call HDF5_read(homogState(ho)%state0,groupHandle(2),'omega_mechanical') ! ToDo: should be done by mech + if (damageState_h(ho)%sizeState > 0) & + call HDF5_read(damageState_h(ho)%state0,groupHandle(2),'omega_damage') ! ToDo: should be done by mech + call HDF5_closeGroup(groupHandle(2)) end do @@ -447,7 +463,7 @@ end subroutine homogenization_restartRead !-------------------------------------------------------------------------------------------------- subroutine parseHomogenization - class(tNode), pointer :: & + type(tDict), pointer :: & material_homogenization, & homog, & homogThermal, & @@ -455,17 +471,17 @@ subroutine parseHomogenization integer :: h - material_homogenization => config_material%get('homogenization') + material_homogenization => config_material%get_dict('homogenization') allocate(thermal_type(size(material_name_homogenization)),source=THERMAL_UNDEFINED_ID) allocate(thermal_active(size(material_name_homogenization)),source=.false.) allocate(damage_active(size(material_name_homogenization)),source=.false.) do h=1, size(material_name_homogenization) - homog => material_homogenization%get(h) + homog => material_homogenization%get_dict(h) if (homog%contains('thermal')) then - homogThermal => homog%get('thermal') + homogThermal => homog%get_dict('thermal') select case (homogThermal%get_asString('type')) case('pass') thermal_type(h) = THERMAL_PASS_ID @@ -479,7 +495,7 @@ subroutine parseHomogenization end if if (homog%contains('damage')) then - homogDamage => homog%get('damage') + homogDamage => homog%get_dict('damage') select case (homogDamage%get_asString('type')) case('pass') damage_active(h) = .true. diff --git a/src/homogenization_damage.f90 b/src/homogenization_damage.f90 index 3363408d0..ffd07f1ef 100644 --- a/src/homogenization_damage.f90 +++ b/src/homogenization_damage.f90 @@ -32,7 +32,7 @@ contains !-------------------------------------------------------------------------------------------------- module subroutine damage_init() - class(tNode), pointer :: & + type(tDict), pointer :: & configHomogenizations, & configHomogenization, & configHomogenizationDamage @@ -42,17 +42,17 @@ module subroutine damage_init() print'(/,1x,a)', '<<<+- homogenization:damage init -+>>>' - configHomogenizations => config_material%get('homogenization') + configHomogenizations => config_material%get_dict('homogenization') allocate(param(configHomogenizations%length)) allocate(current(configHomogenizations%length)) do ho = 1, configHomogenizations%length Nmembers = count(material_homogenizationID == ho) allocate(current(ho)%phi(Nmembers), source=1.0_pReal) - configHomogenization => configHomogenizations%get(ho) + configHomogenization => configHomogenizations%get_dict(ho) associate(prm => param(ho)) if (configHomogenization%contains('damage')) then - configHomogenizationDamage => configHomogenization%get('damage') + configHomogenizationDamage => configHomogenization%get_dict('damage') #if defined (__GFORTRAN__) prm%output = output_as1dString(configHomogenizationDamage) #else @@ -72,6 +72,18 @@ module subroutine damage_init() end subroutine damage_init +!-------------------------------------------------------------------------------------------------- +!> @brief Check if damage homogemization description is present in the configuration file +!-------------------------------------------------------------------------------------------------- +module function homogenization_damage_active() result(active) + + logical :: active + + active = any(damage_active(:)) + +end function homogenization_damage_active + + !-------------------------------------------------------------------------------------------------- !> @brief Partition temperature onto the individual constituents. !-------------------------------------------------------------------------------------------------- @@ -80,11 +92,15 @@ module subroutine damage_partition(ce) integer, intent(in) :: ce real(pReal) :: phi + integer :: co - if(damageState_h(material_homogenizationID(ce))%sizeState < 1) return + if (damageState_h(material_homogenizationID(ce))%sizeState < 1) return phi = damagestate_h(material_homogenizationID(ce))%state(1,material_homogenizationEntry(ce)) - call phase_set_phi(phi,1,ce) + do co = 1, homogenization_Nconstituents(material_homogenizationID(ce)) + call phase_set_phi(phi,co,ce) + end do + end subroutine damage_partition @@ -156,7 +172,7 @@ end subroutine homogenization_set_phi !-------------------------------------------------------------------------------------------------- !> @brief writes results to HDF5 output file !-------------------------------------------------------------------------------------------------- -module subroutine damage_results(ho,group) +module subroutine damage_result(ho,group) integer, intent(in) :: ho character(len=*), intent(in) :: group @@ -168,12 +184,12 @@ module subroutine damage_results(ho,group) outputsLoop: do o = 1,size(prm%output) select case(prm%output(o)) case ('phi') - call results_writeDataset(damagestate_h(ho)%state(1,:),group,prm%output(o),& - 'damage indicator','-') + call result_writeDataset(current(ho)%phi,group,prm%output(o),& + 'damage indicator','-') end select end do outputsLoop end associate -end subroutine damage_results +end subroutine damage_result end submodule damage diff --git a/src/homogenization_mechanical.f90 b/src/homogenization_mechanical.f90 index b358e680d..eb5ec75a4 100644 --- a/src/homogenization_mechanical.f90 +++ b/src/homogenization_mechanical.f90 @@ -43,10 +43,10 @@ submodule(homogenization) mechanical end function RGC_updateState - module subroutine RGC_results(ho,group) + module subroutine RGC_result(ho,group) integer, intent(in) :: ho !< homogenization type character(len=*), intent(in) :: group !< group name in HDF5 file - end subroutine RGC_results + end subroutine RGC_result end interface @@ -183,7 +183,7 @@ end function mechanical_updateState !-------------------------------------------------------------------------------------------------- !> @brief Write results to file. !-------------------------------------------------------------------------------------------------- -module subroutine mechanical_results(group_base,ho) +module subroutine mechanical_result(group_base,ho) character(len=*), intent(in) :: group_base integer, intent(in) :: ho @@ -193,12 +193,12 @@ module subroutine mechanical_results(group_base,ho) group = trim(group_base)//'/mechanical' - call results_closeGroup(results_addGroup(group)) + call result_closeGroup(result_addGroup(group)) select case(mechanical_type(ho)) case(MECHANICAL_RGC_ID) - call RGC_results(ho,group) + call RGC_result(ho,group) end select @@ -206,15 +206,15 @@ module subroutine mechanical_results(group_base,ho) select case (output_mechanical(ho)%label(ou)) case('F') - call results_writeDataset(reshape(homogenization_F,[3,3,discretization_nCells]),group,'F', & - 'deformation gradient','1') + call result_writeDataset(reshape(homogenization_F,[3,3,discretization_nCells]),group,'F', & + 'deformation gradient','1') case('P') - call results_writeDataset(reshape(homogenization_P,[3,3,discretization_nCells]),group,'P', & - 'first Piola-Kirchhoff stress','Pa') + call result_writeDataset(reshape(homogenization_P,[3,3,discretization_nCells]),group,'P', & + 'first Piola-Kirchhoff stress','Pa') end select end do -end subroutine mechanical_results +end subroutine mechanical_result !-------------------------------------------------------------------------------------------------- @@ -222,7 +222,7 @@ end subroutine mechanical_results !-------------------------------------------------------------------------------------------------- subroutine parseMechanical() - class(tNode), pointer :: & + type(tDict), pointer :: & material_homogenization, & homog, & mechanical @@ -230,14 +230,14 @@ subroutine parseMechanical() integer :: ho - material_homogenization => config_material%get('homogenization') + material_homogenization => config_material%get_dict('homogenization') allocate(mechanical_type(size(material_name_homogenization)), source=MECHANICAL_UNDEFINED_ID) allocate(output_mechanical(size(material_name_homogenization))) do ho=1, size(material_name_homogenization) - homog => material_homogenization%get(ho) - mechanical => homog%get('mechanical') + homog => material_homogenization%get_dict(ho) + mechanical => homog%get_dict('mechanical') #if defined(__GFORTRAN__) output_mechanical(ho)%label = output_as1dString(mechanical) #else diff --git a/src/homogenization_mechanical_RGC.f90 b/src/homogenization_mechanical_RGC.f90 index 8e8ae1df9..8d56a26f2 100644 --- a/src/homogenization_mechanical_RGC.f90 +++ b/src/homogenization_mechanical_RGC.f90 @@ -78,7 +78,7 @@ module subroutine RGC_init() Nmembers, & sizeState, nIntFaceTot - class (tNode), pointer :: & + class(tDict), pointer :: & num_homogenization, & num_mechanical, & num_RGC, & ! pointer to RGC numerics data @@ -98,15 +98,15 @@ module subroutine RGC_init() print'( 1x,a)', 'https://doi.org/10.1088/0965-0393/18/1/015006'//IO_EOL - material_homogenization => config_material%get('homogenization') + material_homogenization => config_material%get_dict('homogenization') allocate(param(material_homogenization%length)) allocate(state(material_homogenization%length)) allocate(state0(material_homogenization%length)) allocate(dependentState(material_homogenization%length)) - num_homogenization => config_numerics%get('homogenization',defaultVal=emptyDict) - num_mechanical => num_homogenization%get('mechanical',defaultVal=emptyDict) - num_RGC => num_mechanical%get('RGC',defaultVal=emptyDict) + num_homogenization => config_numerics%get_dict('homogenization',defaultVal=emptyDict) + num_mechanical => num_homogenization%get_dict('mechanical',defaultVal=emptyDict) + num_RGC => num_mechanical%get_dict('RGC',defaultVal=emptyDict) num%atol = num_RGC%get_asFloat('atol', defaultVal=1.0e+4_pReal) num%rtol = num_RGC%get_asFloat('rtol', defaultVal=1.0e-3_pReal) @@ -139,8 +139,8 @@ module subroutine RGC_init() do ho = 1, size(mechanical_type) if (mechanical_type(ho) /= MECHANICAL_RGC_ID) cycle - homog => material_homogenization%get(ho) - homogMech => homog%get('mechanical') + homog => material_homogenization%get_dict(ho) + homogMech => homog%get_dict('mechanical') associate(prm => param(ho), & stt => state(ho), & st0 => state0(ho), & @@ -652,9 +652,9 @@ module function RGC_updateState(P,F,avgF,dt,dPdF,ce) result(doneAndHappy) real(pReal), dimension(6,6) :: C - C = phase_homogenizedC66(material_phaseID(co,ce),material_phaseEntry(co,ce)) ! damage not included! - equivalentMu = lattice_equivalent_mu(C,'voigt') + + equivalentMu = lattice_isotropic_mu(C,'isostrain') end function equivalentMu @@ -668,7 +668,7 @@ module function RGC_updateState(P,F,avgF,dt,dPdF,ce) result(doneAndHappy) real(pReal), dimension(:,:,:), intent(out) :: F !< partitioned F per grain real(pReal), dimension(:,:), intent(in) :: avgF !< averaged F - integer, intent(in) :: & + integer, intent(in) :: & ho, & en @@ -705,7 +705,7 @@ end function RGC_updateState !-------------------------------------------------------------------------------------------------- !> @brief writes results to HDF5 output file !-------------------------------------------------------------------------------------------------- -module subroutine RGC_results(ho,group) +module subroutine RGC_result(ho,group) integer, intent(in) :: ho character(len=*), intent(in) :: group @@ -713,25 +713,25 @@ module subroutine RGC_results(ho,group) integer :: o associate(stt => state(ho), dst => dependentState(ho), prm => param(ho)) - outputsLoop: do o = 1,size(prm%output) - select case(trim(prm%output(o))) - case('M') - call results_writeDataset(dst%mismatch,group,trim(prm%output(o)), & - 'average mismatch tensor','1') - case('Delta_V') - call results_writeDataset(dst%volumeDiscrepancy,group,trim(prm%output(o)), & - 'volume discrepancy','m³') - case('max_dot_a') - call results_writeDataset(dst%relaxationrate_max,group,trim(prm%output(o)), & - 'maximum relaxation rate','m/s') - case('avg_dot_a') - call results_writeDataset(dst%relaxationrate_avg,group,trim(prm%output(o)), & - 'average relaxation rate','m/s') - end select - end do outputsLoop + outputsLoop: do o = 1,size(prm%output) + select case(trim(prm%output(o))) + case('M') + call result_writeDataset(dst%mismatch,group,trim(prm%output(o)), & + 'average mismatch tensor','1') + case('Delta_V') + call result_writeDataset(dst%volumeDiscrepancy,group,trim(prm%output(o)), & + 'volume discrepancy','m³') + case('max_dot_a') + call result_writeDataset(dst%relaxationrate_max,group,trim(prm%output(o)), & + 'maximum relaxation rate','m/s') + case('avg_dot_a') + call result_writeDataset(dst%relaxationrate_avg,group,trim(prm%output(o)), & + 'average relaxation rate','m/s') + end select + end do outputsLoop end associate -end subroutine RGC_results +end subroutine RGC_result !-------------------------------------------------------------------------------------------------- diff --git a/src/homogenization_thermal.f90 b/src/homogenization_thermal.f90 index ceed47365..401a7df81 100644 --- a/src/homogenization_thermal.f90 +++ b/src/homogenization_thermal.f90 @@ -35,7 +35,7 @@ contains !-------------------------------------------------------------------------------------------------- module subroutine thermal_init() - class(tNode), pointer :: & + type(tDict), pointer :: & configHomogenizations, & configHomogenization, & configHomogenizationThermal @@ -45,18 +45,18 @@ module subroutine thermal_init() print'(/,1x,a)', '<<<+- homogenization:thermal init -+>>>' - configHomogenizations => config_material%get('homogenization') + configHomogenizations => config_material%get_dict('homogenization') allocate(param(configHomogenizations%length)) allocate(current(configHomogenizations%length)) do ho = 1, configHomogenizations%length allocate(current(ho)%T(count(material_homogenizationID==ho)), source=T_ROOM) allocate(current(ho)%dot_T(count(material_homogenizationID==ho)), source=0.0_pReal) - configHomogenization => configHomogenizations%get(ho) + configHomogenization => configHomogenizations%get_dict(ho) associate(prm => param(ho)) if (configHomogenization%contains('thermal')) then - configHomogenizationThermal => configHomogenization%get('thermal') + configHomogenizationThermal => configHomogenization%get_dict('thermal') #if defined (__GFORTRAN__) prm%output = output_as1dString(configHomogenizationThermal) #else @@ -78,10 +78,21 @@ module subroutine thermal_init() end associate end do - end subroutine thermal_init +!-------------------------------------------------------------------------------------------------- +!> @brief Check if thermal homogemization description is present in the configuration file +!-------------------------------------------------------------------------------------------------- +module function homogenization_thermal_active() result(active) + + logical :: active + + active = any(thermal_active(:)) + +end function homogenization_thermal_active + + !-------------------------------------------------------------------------------------------------- !> @brief Partition temperature onto the individual constituents. !-------------------------------------------------------------------------------------------------- @@ -178,7 +189,7 @@ end subroutine homogenization_thermal_setField !-------------------------------------------------------------------------------------------------- !> @brief writes results to HDF5 output file !-------------------------------------------------------------------------------------------------- -module subroutine thermal_results(ho,group) +module subroutine thermal_result(ho,group) integer, intent(in) :: ho character(len=*), intent(in) :: group @@ -190,11 +201,11 @@ module subroutine thermal_results(ho,group) outputsLoop: do o = 1,size(prm%output) select case(trim(prm%output(o))) case('T') - call results_writeDataset(current(ho)%T,group,'T','temperature','K') + call result_writeDataset(current(ho)%T,group,'T','temperature','K') end select end do outputsLoop end associate -end subroutine thermal_results +end subroutine thermal_result end submodule thermal diff --git a/src/lattice.f90 b/src/lattice.f90 index 7bd846d0f..beded840b 100644 --- a/src/lattice.f90 +++ b/src/lattice.f90 @@ -376,8 +376,8 @@ module lattice public :: & lattice_init, & - lattice_equivalent_nu, & - lattice_equivalent_mu, & + lattice_isotropic_nu, & + lattice_isotropic_mu, & lattice_symmetrize_33, & lattice_symmetrize_C66, & lattice_SchmidMatrix_slip, & @@ -405,13 +405,13 @@ module lattice contains !-------------------------------------------------------------------------------------------------- -!> @brief Module initialization +!> @brief Run self test. !-------------------------------------------------------------------------------------------------- -subroutine lattice_init +subroutine lattice_init() print'(/,1x,a)', '<<<+- lattice init -+>>>'; flush(IO_STDOUT) - call selfTest + call selfTest() end subroutine lattice_init @@ -422,7 +422,7 @@ end subroutine lattice_init function lattice_characteristicShear_Twin(Ntwin,lattice,CoverA) result(characteristicShear) integer, dimension(:), intent(in) :: Ntwin !< number of active twin systems per family - character(len=2), intent(in) :: lattice !< Bravais lattice (Pearson symbol) + character(len=*), intent(in) :: lattice !< Bravais lattice (Pearson symbol) real(pReal), intent(in) :: cOverA !< c/a ratio real(pReal), dimension(sum(Ntwin)) :: characteristicShear @@ -496,7 +496,7 @@ end function lattice_characteristicShear_Twin function lattice_C66_twin(Ntwin,C66,lattice,CoverA) integer, dimension(:), intent(in) :: Ntwin !< number of active twin systems per family - character(len=2), intent(in) :: lattice !< Bravais lattice (Pearson symbol) + character(len=*), intent(in) :: lattice !< Bravais lattice (Pearson symbol) real(pReal), dimension(6,6), intent(in) :: C66 !< unrotated parent stiffness matrix real(pReal), intent(in) :: cOverA !< c/a ratio real(pReal), dimension(6,6,sum(Ntwin)) :: lattice_C66_twin @@ -535,7 +535,7 @@ function lattice_C66_trans(Ntrans,C_parent66,lattice_target, & cOverA_trans,a_cF,a_cI) integer, dimension(:), intent(in) :: Ntrans !< number of active twin systems per family - character(len=2), intent(in) :: lattice_target !< Bravais lattice (Pearson symbol) + character(len=*), intent(in) :: lattice_target !< Bravais lattice (Pearson symbol) real(pReal), dimension(6,6), intent(in) :: C_parent66 real(pReal), optional, intent(in) :: cOverA_trans, a_cF, a_cI real(pReal), dimension(6,6,sum(Ntrans)) :: lattice_C66_trans @@ -647,7 +647,7 @@ function lattice_interaction_SlipBySlip(Nslip,interactionValues,lattice) result( integer, dimension(:), intent(in) :: Nslip !< number of active slip systems per family real(pReal), dimension(:), intent(in) :: interactionValues !< values for slip-slip interaction - character(len=2), intent(in) :: lattice !< Bravais lattice (Pearson symbol) + character(len=*), intent(in) :: lattice !< Bravais lattice (Pearson symbol) real(pReal), dimension(sum(Nslip),sum(Nslip)) :: interactionMatrix integer, dimension(:), allocatable :: NslipMax @@ -965,7 +965,7 @@ function lattice_interaction_TwinByTwin(Ntwin,interactionValues,lattice) result( integer, dimension(:), intent(in) :: Ntwin !< number of active twin systems per family real(pReal), dimension(:), intent(in) :: interactionValues !< values for twin-twin interaction - character(len=2), intent(in) :: lattice !< Bravais lattice (Pearson symbol) + character(len=*), intent(in) :: lattice !< Bravais lattice (Pearson symbol) real(pReal), dimension(sum(Ntwin),sum(Ntwin)) :: interactionMatrix integer, dimension(:), allocatable :: NtwinMax @@ -1064,7 +1064,7 @@ function lattice_interaction_TransByTrans(Ntrans,interactionValues,lattice) resu integer, dimension(:), intent(in) :: Ntrans !< number of active trans systems per family real(pReal), dimension(:), intent(in) :: interactionValues !< values for trans-trans interaction - character(len=2), intent(in) :: lattice ! @brief Equivalent Poisson's ratio (ν) !> @details https://doi.org/10.1143/JPSJ.20.635 !-------------------------------------------------------------------------------------------------- -pure function lattice_equivalent_nu(C,assumption) result(nu) +pure function lattice_isotropic_nu(C,assumption,lattice) result(nu) real(pReal), dimension(6,6), intent(in) :: C !< Stiffness tensor (Voigt notation) - character(len=5), intent(in) :: assumption !< Assumption ('Voigt' = isostrain, 'Reuss' = isostress) + character(len=*), intent(in) :: assumption !< Assumption (isostrain = 'Voigt', isostress = 'Reuss') + character(len=*), optional, intent(in) :: lattice real(pReal) :: nu real(pReal) :: K, mu - logical :: error - real(pReal), dimension(6,6) :: S + logical :: error + real(pReal), dimension(6,6) :: S + character(len=:), allocatable :: lattice_ - if (IO_lc(assumption) == 'voigt') then - K = (C(1,1)+C(2,2)+C(3,3) +2.0_pReal*(C(1,2)+C(2,3)+C(1,3))) & - / 9.0_pReal - elseif (IO_lc(assumption) == 'reuss') then + lattice_ = IO_WHITESPACE + if (present(lattice)) lattice_ = lattice + + if (IO_lc(assumption) == 'isostrain') then + K = sum(C(1:3,1:3)) / 9.0_pReal + elseif (IO_lc(assumption) == 'isostress') then call math_invert(S,error,C) if (error) error stop 'matrix inversion failed' - K = 1.0_pReal & - / (S(1,1)+S(2,2)+S(3,3) +2.0_pReal*(S(1,2)+S(2,3)+S(1,3))) + K = 1.0_pReal / sum(S(1:3,1:3)) else error stop 'invalid assumption' end if - mu = lattice_equivalent_mu(C,assumption) + mu = lattice_isotropic_mu(C,assumption,lattice_) nu = (1.5_pReal*K-mu)/(3.0_pReal*K+mu) -end function lattice_equivalent_nu +end function lattice_isotropic_nu !-------------------------------------------------------------------------------------------------- !> @brief Equivalent shear modulus (μ) !> @details https://doi.org/10.1143/JPSJ.20.635 +!> @details Nonlinear Mechanics of Crystals 10.1007/978-94-007-0350-6, pp 563 !-------------------------------------------------------------------------------------------------- -pure function lattice_equivalent_mu(C,assumption) result(mu) +pure function lattice_isotropic_mu(C,assumption,lattice) result(mu) real(pReal), dimension(6,6), intent(in) :: C !< Stiffness tensor (Voigt notation) - character(len=5), intent(in) :: assumption !< Assumption ('Voigt' = isostrain, 'Reuss' = isostress) + character(len=*), intent(in) :: assumption !< Assumption (isostrain = 'Voigt', isostress = 'Reuss') + character(len=*), optional, intent(in) :: lattice real(pReal) :: mu - logical :: error - real(pReal), dimension(6,6) :: S + logical :: error + real(pReal), dimension(6,6) :: S + character(len=:), allocatable :: lattice_ - if (IO_lc(assumption) == 'voigt') then - mu = (1.0_pReal*(C(1,1)+C(2,2)+C(3,3)) -1.0_pReal*(C(1,2)+C(2,3)+C(1,3)) +3.0_pReal*(C(4,4)+C(5,5)+C(6,6))) & - / 15.0_pReal - elseif (IO_lc(assumption) == 'reuss') then - call math_invert(S,error,C) - if (error) error stop 'matrix inversion failed' - mu = 15.0_pReal & - / (4.0_pReal*(S(1,1)+S(2,2)+S(3,3)) -4.0_pReal*(S(1,2)+S(2,3)+S(1,3)) +3.0_pReal*(S(4,4)+S(5,5)+S(6,6))) + lattice_ = IO_WHITESPACE + if (present(lattice)) lattice_ = lattice + + if (IO_lc(assumption) == 'isostrain') then + select case(lattice_) + case('cF','cI') + mu = ( C(1,1) - C(1,2) + C(4,4)*3.0_pReal) / 5.0_pReal + case default + mu = ( C(1,1)+C(2,2)+C(3,3) & + - C(1,2)-C(2,3)-C(1,3) & + +(C(4,4)+C(5,5)+C(6,6)) * 3.0_pReal & + ) / 15.0_pReal + end select + + elseif (IO_lc(assumption) == 'isostress') then + select case(lattice_) + case('cF','cI') + mu = 5.0_pReal & + / (4.0_pReal/(C(1,1)-C(1,2)) + 3.0_pReal/C(4,4)) + case default + call math_invert(S,error,C) + if (error) error stop 'matrix inversion failed' + mu = 15.0_pReal & + / (4.0_pReal*(S(1,1)+S(2,2)+S(3,3)-S(1,2)-S(2,3)-S(1,3)) + 3.0_pReal*(S(4,4)+S(5,5)+S(6,6))) + end select else error stop 'invalid assumption' end if -end function lattice_equivalent_mu +end function lattice_isotropic_mu !-------------------------------------------------------------------------------------------------- @@ -2270,16 +2293,52 @@ subroutine selfTest call random_number(C) C(1,1) = C(1,1) + C(1,2) + 0.1_pReal + C(1,3) = C(1,2) + C(3,3) = C(1,1) C(4,4) = 0.5_pReal * (C(1,1) - C(1,2)) - C = lattice_symmetrize_C66(C,'cI') - if (dNeq(C(4,4),lattice_equivalent_mu(C,'voigt'),1.0e-12_pReal)) error stop 'equivalent_mu/voigt' - if (dNeq(C(4,4),lattice_equivalent_mu(C,'reuss'),1.0e-12_pReal)) error stop 'equivalent_mu/reuss' + C(6,6) = C(4,4) - lambda = C(1,2) - if (dNeq(lambda*0.5_pReal/(lambda+lattice_equivalent_mu(C,'voigt')), & - lattice_equivalent_nu(C,'voigt'),1.0e-12_pReal)) error stop 'equivalent_nu/voigt' - if (dNeq(lambda*0.5_pReal/(lambda+lattice_equivalent_mu(C,'reuss')), & - lattice_equivalent_nu(C,'reuss'),1.0e-12_pReal)) error stop 'equivalent_nu/reuss' + C_cI = lattice_symmetrize_C66(C,'cI') + if (dNeq(C_cI(4,4),lattice_isotropic_mu(C_cI,'isostrain','cI'),1.0e-12_pReal)) error stop 'isotropic_mu/isostrain/cI' + if (dNeq(C_cI(4,4),lattice_isotropic_mu(C_cI,'isostress','cI'),1.0e-12_pReal)) error stop 'isotropic_mu/isostress/cI' + + lambda = C_cI(1,2) + if (dNeq(lambda*0.5_pReal/(lambda+lattice_isotropic_mu(C_cI,'isostrain','cI')), & + lattice_isotropic_nu(C_cI,'isostrain','cI'),1.0e-12_pReal)) error stop 'isotropic_nu/isostrain/cI' + if (dNeq(lambda*0.5_pReal/(lambda+lattice_isotropic_mu(C_cI,'isostress','cI')), & + lattice_isotropic_nu(C_cI,'isostress','cI'),1.0e-12_pReal)) error stop 'isotropic_nu/isostress/cI' + + + C_hP = lattice_symmetrize_C66(C,'hP') + if (dNeq(C(4,4),lattice_isotropic_mu(C_hP,'isostrain','hP'),1.0e-12_pReal)) error stop 'isotropic_mu/isostrain/hP' + if (dNeq(C(4,4),lattice_isotropic_mu(C_hP,'isostress','hP'),1.0e-12_pReal)) error stop 'isotropic_mu/isostress/hP' + + lambda = C_hP(1,2) + if (dNeq(lambda*0.5_pReal/(lambda+lattice_isotropic_mu(C_hP,'isostrain','hP')), & + lattice_isotropic_nu(C_hP,'isostrain','hP'),1.0e-12_pReal)) error stop 'isotropic_nu/isostrain/hP' + if (dNeq(lambda*0.5_pReal/(lambda+lattice_isotropic_mu(C_hP,'isostress','hP')), & + lattice_isotropic_nu(C_hP,'isostress','hP'),1.0e-12_pReal)) error stop 'isotropic_nu/isostress/hP' + + C_tI = lattice_symmetrize_C66(C,'tI') + if (dNeq(C(6,6),lattice_isotropic_mu(C_tI,'isostrain','tI'),1.0e-12_pReal)) error stop 'isotropic_mu/isostrain/tI' + if (dNeq(C(6,6),lattice_isotropic_mu(C_tI,'isostress','tI'),1.0e-12_pReal)) error stop 'isotropic_mu/isostress/tI' + + lambda = C_tI(1,2) + if (dNeq(lambda*0.5_pReal/(lambda+lattice_isotropic_mu(C_tI,'isostrain','tI')), & + lattice_isotropic_nu(C_tI,'isostrain','tI'),1.0e-12_pReal)) error stop 'isotropic_nu/isostrain/tI' + if (dNeq(lambda*0.5_pReal/(lambda+lattice_isotropic_mu(C_tI,'isostress','tI')), & + lattice_isotropic_nu(C_tI,'isostress','tI'),1.0e-12_pReal)) error stop 'isotropic_nu/isostress/tI' + + call random_number(C) + C = lattice_symmetrize_C66(C+math_eye(6),'cI') + if (dNeq(lattice_isotropic_mu(C,'isostrain','cI'), lattice_isotropic_mu(C,'isostrain','hP'), 1.0e-12_pReal)) & + error stop 'isotropic_mu/isostrain/cI-hP' + if (dNeq(lattice_isotropic_nu(C,'isostrain','cF'), lattice_isotropic_nu(C,'isostrain','cI'), 1.0e-12_pReal)) & + error stop 'isotropic_nu/isostrain/cF-tI' + if (dNeq(lattice_isotropic_mu(C,'isostress','cI'), lattice_isotropic_mu(C,'isostress'), 1.0e-12_pReal)) & + error stop 'isotropic_mu/isostress/cI-hP' + if (dNeq(lattice_isotropic_nu(C,'isostress','cF'), lattice_isotropic_nu(C,'isostress'), 1.0e-12_pReal)) & + error stop 'isotropic_nu/isostress/cF-tI' end subroutine selfTest diff --git a/src/material.f90 b/src/material.f90 index 1ec844382..991912fdd 100644 --- a/src/material.f90 +++ b/src/material.f90 @@ -7,7 +7,7 @@ module material use prec use config - use results + use result use math use IO use rotations @@ -69,10 +69,10 @@ subroutine material_init(restart) if (.not. restart) then - call results_openJobFile - call results_mapping_phase(material_phaseID,material_phaseEntry,material_name_phase) - call results_mapping_homogenization(material_homogenizationID,material_homogenizationEntry,material_name_homogenization) - call results_closeJobFile + call result_openJobFile + call result_mapping_phase(material_phaseID,material_phaseEntry,material_name_phase) + call result_mapping_homogenization(material_homogenizationID,material_homogenizationEntry,material_name_homogenization) + call result_closeJobFile end if end subroutine material_init @@ -83,13 +83,13 @@ end subroutine material_init !-------------------------------------------------------------------------------------------------- subroutine parse() - class(tNode), pointer :: materials, & !> list of materials - material, & !> material definition - constituents, & !> list of constituents - constituent, & !> constituent definition - phases, & - homogenizations, & - homogenization + type(tList), pointer :: materials, & !> all materials + constituents !> all constituents of a material + type(tDict), pointer :: phases, & !> all phases + homogenizations, & !> all homogenizations + material, & !> material definition + constituent, & !> constituent definition + homogenization class(tItem), pointer :: item integer, dimension(:), allocatable :: & @@ -107,25 +107,20 @@ subroutine parse() ma - materials => config_material%get('material') - phases => config_material%get('phase') - homogenizations => config_material%get('homogenization') + materials => config_material%get_list('material') + phases => config_material%get_dict('phase') + homogenizations => config_material%get_dict('homogenization') if (maxval(discretization_materialAt) > materials%length) & call IO_error(155,ext_msg='More materials requested than found in material.yaml') -#if defined (__GFORTRAN__) - material_name_phase = getKeys(phases) - material_name_homogenization = getKeys(homogenizations) -#else - material_name_phase = phases%Keys() - material_name_homogenization = homogenizations%Keys() -#endif + material_name_phase = phases%keys() + material_name_homogenization = homogenizations%keys() allocate(homogenization_Nconstituents(homogenizations%length)) do ho=1, homogenizations%length - homogenization => homogenizations%get(ho) + homogenization => homogenizations%get_dict(ho) homogenization_Nconstituents(ho) = homogenization%get_asInt('N_constituents') end do homogenization_maxNconstituents = maxval(homogenization_Nconstituents) @@ -139,41 +134,34 @@ subroutine parse() allocate(ph_of(materials%length,homogenization_maxNconstituents),source=-1) allocate( v_of(materials%length,homogenization_maxNconstituents),source=0.0_pReal) - ! parse YAML structure - select type(materials) + ! Parse YAML structure. Manual loop over linked list to have O(n) instead of O(n^2) complexity + item => materials%first + do ma = 1, materials%length + material => item%node%asDict() + ho_of(ma) = homogenizations%index(material%get_asString('homogenization')) + constituents => material%get_list('constituents') - class is(tList) + homogenization => homogenizations%get_dict(ho_of(ma)) + if (constituents%length /= homogenization%get_asInt('N_constituents')) call IO_error(148) - item => materials%first - do ma = 1, materials%length - material => item%node - ho_of(ma) = homogenizations%getIndex(material%get_asString('homogenization')) - constituents => material%get('constituents') + allocate(material_O_0(ma)%data(constituents%length)) + allocate(material_V_e_0(ma)%data(1:3,1:3,constituents%length)) - homogenization => homogenizations%get(ho_of(ma)) - if (constituents%length /= homogenization%get_asInt('N_constituents')) call IO_error(148) + do co = 1, constituents%length + constituent => constituents%get_dict(co) + v_of(ma,co) = constituent%get_asFloat('v') + ph_of(ma,co) = phases%index(constituent%get_asString('phase')) - allocate(material_O_0(ma)%data(constituents%length)) - allocate(material_V_e_0(ma)%data(1:3,1:3,constituents%length)) + call material_O_0(ma)%data(co)%fromQuaternion(constituent%get_as1dFloat('O',requiredSize=4)) + material_V_e_0(ma)%data(1:3,1:3,co) = constituent%get_as2dFloat('V_e',defaultVal=math_I3,requiredShape=[3,3]) + if (any(dNeq(material_V_e_0(ma)%data(1:3,1:3,co),transpose(material_V_e_0(ma)%data(1:3,1:3,co))))) & + call IO_error(147) - do co = 1, constituents%length - constituent => constituents%get(co) - v_of(ma,co) = constituent%get_asFloat('v') - ph_of(ma,co) = phases%getIndex(constituent%get_asString('phase')) - - call material_O_0(ma)%data(co)%fromQuaternion(constituent%get_as1dFloat('O',requiredSize=4)) - material_V_e_0(ma)%data(1:3,1:3,co) = constituent%get_as2dFloat('V_e',defaultVal=math_I3,requiredShape=[3,3]) - if (any(dNeq(material_V_e_0(ma)%data(1:3,1:3,co),transpose(material_V_e_0(ma)%data(1:3,1:3,co))))) & - call IO_error(147) - - end do - if (dNeq(sum(v_of(ma,:)),1.0_pReal,1.e-9_pReal)) call IO_error(153,ext_msg='constituent') - - item => item%next - end do - - end select + end do + if (dNeq(sum(v_of(ma,:)),1.0_pReal,1.e-9_pReal)) call IO_error(153,ext_msg='constituent') + item => item%next + end do allocate(counterPhase(phases%length),source=0) allocate(counterHomogenization(homogenizations%length),source=0) @@ -223,7 +211,7 @@ end subroutine parse !-------------------------------------------------------------------------------------------------- function getKeys(dict) - class(tNode), intent(in) :: dict + type(tDict), intent(in) :: dict character(len=:), dimension(:), allocatable :: getKeys character(len=pStringLen), dimension(:), allocatable :: temp @@ -232,7 +220,7 @@ function getKeys(dict) allocate(temp(dict%length)) l = 0 do i=1, dict%length - temp(i) = dict%getKey(i) + temp(i) = dict%key(i) l = max(len_trim(temp(i)),l) end do diff --git a/src/materialpoint.f90 b/src/materialpoint.f90 index 5b8b690e0..2490734be 100644 --- a/src/materialpoint.f90 +++ b/src/materialpoint.f90 @@ -5,7 +5,7 @@ !-------------------------------------------------------------------------------------------------- module materialpoint use parallelization - use signals + use signal use CLI use prec use IO @@ -13,11 +13,12 @@ module materialpoint use YAML_parse use HDF5 use HDF5_utilities - use results + use result use config use math use rotations use polynomials + use tables use lattice use material use phase @@ -40,37 +41,38 @@ contains !-------------------------------------------------------------------------------------------------- !> @brief Initialize all modules. !-------------------------------------------------------------------------------------------------- -subroutine materialpoint_initAll +subroutine materialpoint_initAll() - call parallelization_init - call CLI_init ! Spectral and FEM interface to commandline - call signals_init - call prec_init - call IO_init + call parallelization_init() + call CLI_init() ! grid and mesh commandline interface + call signal_init() + call prec_init() + call IO_init() #if defined(MESH) - call FEM_quadrature_init + call FEM_quadrature_init() #elif defined(GRID) - call base64_init + call base64_init() #endif - call YAML_types_init - call YAML_parse_init - call HDF5_utilities_init - call results_init(restart=CLI_restartInc>0) - call config_init - call math_init - call rotations_init - call polynomials_init - call lattice_init + call YAML_types_init() + call YAML_parse_init() + call HDF5_utilities_init() + call result_init(restart=CLI_restartInc>0) + call config_init() + call math_init() + call rotations_init() + call polynomials_init() + call tables_init() + call lattice_init() #if defined(MESH) call discretization_mesh_init(restart=CLI_restartInc>0) #elif defined(GRID) call discretization_grid_init(restart=CLI_restartInc>0) #endif call material_init(restart=CLI_restartInc>0) - call phase_init - call homogenization_init - call materialpoint_init - call config_deallocate + call phase_init() + call homogenization_init() + call materialpoint_init() + call config_deallocate() end subroutine materialpoint_initAll @@ -78,7 +80,7 @@ end subroutine materialpoint_initAll !-------------------------------------------------------------------------------------------------- !> @brief Read restart information if needed. !-------------------------------------------------------------------------------------------------- -subroutine materialpoint_init +subroutine materialpoint_init() integer(HID_T) :: fileHandle @@ -95,7 +97,7 @@ subroutine materialpoint_init call phase_restartRead(fileHandle) call HDF5_closeFile(fileHandle) - endif + end if end subroutine materialpoint_init @@ -103,7 +105,7 @@ end subroutine materialpoint_init !-------------------------------------------------------------------------------------------------- !> @brief Write restart information. !-------------------------------------------------------------------------------------------------- -subroutine materialpoint_restartWrite +subroutine materialpoint_restartWrite() integer(HID_T) :: fileHandle @@ -123,10 +125,10 @@ end subroutine materialpoint_restartWrite !-------------------------------------------------------------------------------------------------- !> @brief Forward data for new time increment. !-------------------------------------------------------------------------------------------------- -subroutine materialpoint_forward +subroutine materialpoint_forward() - call homogenization_forward - call phase_forward + call homogenization_forward() + call phase_forward() end subroutine materialpoint_forward @@ -134,19 +136,19 @@ end subroutine materialpoint_forward !-------------------------------------------------------------------------------------------------- !> @brief Trigger writing of results. !-------------------------------------------------------------------------------------------------- -subroutine materialpoint_results(inc,time) +subroutine materialpoint_result(inc,time) integer, intent(in) :: inc real(pReal), intent(in) :: time - call results_openJobFile - call results_addIncrement(inc,time) - call phase_results - call homogenization_results - call discretization_results - call results_finalizeIncrement - call results_closeJobFile + call result_openJobFile() + call result_addIncrement(inc,time) + call phase_result() + call homogenization_result() + call discretization_result() + call result_finalizeIncrement() + call result_closeJobFile() -end subroutine materialpoint_results +end subroutine materialpoint_result end module materialpoint diff --git a/src/math.f90 b/src/math.f90 index a875741b3..ff0c604b3 100644 --- a/src/math.f90 +++ b/src/math.f90 @@ -10,8 +10,17 @@ module math use IO use config use YAML_types + use parallelization use LAPACK_interface +#ifdef PETSC +#include + use PETScSys +#if (PETSC_VERSION_MAJOR==3 && PETSC_VERSION_MINOR>14) && !defined(PETSC_HAVE_MPI_F90MODULE_VISIBILITY) + use MPI_f08 +#endif +#endif + implicit none(type,external) public #if __INTEL_COMPILER >= 1900 @@ -87,13 +96,13 @@ subroutine math_init() real(pReal), dimension(4) :: randTest integer :: randSize integer, dimension(:), allocatable :: seed - class(tNode), pointer :: & + type(tDict), pointer :: & num_generic print'(/,1x,a)', '<<<+- math init -+>>>'; flush(IO_STDOUT) - num_generic => config_numerics%get('generic',defaultVal=emptyDict) + num_generic => config_numerics%get_dict('generic',defaultVal=emptyDict) call random_seed(size=randSize) allocate(seed(randSize)) @@ -105,7 +114,7 @@ subroutine math_init() call random_seed(get = seed) end if - call random_seed(put = seed) + call random_seed(put = seed + worldrank*42_MPI_INTEGER_KIND) call random_number(randTest) print'(/,a,i2)', ' size of random seed: ', randSize diff --git a/src/mesh/DAMASK_mesh.f90 b/src/mesh/DAMASK_mesh.f90 index 5489ac36e..d28d064df 100644 --- a/src/mesh/DAMASK_mesh.f90 +++ b/src/mesh/DAMASK_mesh.f90 @@ -65,7 +65,7 @@ program DAMASK_mesh statUnit = 0, & !< file unit for statistics output stagIter, & component - class(tNode), pointer :: & + type(tDict), pointer :: & num_mesh character(len=pStringLen), dimension(:), allocatable :: fileContent character(len=pStringLen) :: & @@ -90,7 +90,7 @@ program DAMASK_mesh !--------------------------------------------------------------------- ! reading field information from numerics file and do sanity checks - num_mesh => config_numerics%get('mesh', defaultVal=emptyDict) + num_mesh => config_numerics%get_dict('mesh', defaultVal=emptyDict) stagItMax = num_mesh%get_asInt('maxStaggeredIter',defaultVal=10) maxCutBack = num_mesh%get_asInt('maxCutBack',defaultVal=3) @@ -239,7 +239,7 @@ program DAMASK_mesh print'(/,1x,a)', '... writing initial configuration to file .................................' flush(IO_STDOUT) - call materialpoint_results(0,0.0_pReal) + call materialpoint_result(0,0.0_pReal) loadCaseLooping: do currentLoadCase = 1, size(loadCases) time0 = time ! load case start time @@ -311,7 +311,7 @@ program DAMASK_mesh write(statUnit,*) totalIncsCounter, time, cutBackLevel, & solres%converged, solres%iterationsNeeded ! write statistics about accepted solution flush(statUnit) - endif + end if end do subStepLooping cutBackLevel = max(0, cutBackLevel - 1) ! try half number of subincs next inc @@ -325,7 +325,7 @@ program DAMASK_mesh if (mod(inc,loadCases(currentLoadCase)%outputFrequency) == 0) then ! at output frequency print'(/,1x,a)', '... writing results to file ...............................................' call FEM_mechanical_updateCoords - call materialpoint_results(totalIncsCounter,time) + call materialpoint_result(totalIncsCounter,time) end if diff --git a/src/mesh/FEM_quadrature.f90 b/src/mesh/FEM_quadrature.f90 index a2217847a..dde762eda 100644 --- a/src/mesh/FEM_quadrature.f90 +++ b/src/mesh/FEM_quadrature.f90 @@ -365,16 +365,16 @@ subroutine selfTest do o = lbound(FEM_quadrature_weights(d,:),1), ubound(FEM_quadrature_weights(d,:),1) if (dNeq(sum(FEM_quadrature_weights(d,o)%p),1.0_pReal,5e-15_pReal)) & error stop 'quadrature weights' - enddo - enddo + end do + end do do d = lbound(FEM_quadrature_points,1), ubound(FEM_quadrature_points,1) do o = lbound(FEM_quadrature_points(d,:),1), ubound(FEM_quadrature_points(d,:),1) n = size(FEM_quadrature_points(d,o)%p,1)/d if (any(dNeq(sum(reshape(FEM_quadrature_points(d,o)%p,[d,n]),2),-real(n,pReal)/w(d),1.e-14_pReal))) & error stop 'quadrature points' - enddo - enddo + end do + end do end subroutine selfTest diff --git a/src/mesh/FEM_utilities.f90 b/src/mesh/FEM_utilities.f90 index c97c2bbe2..5307fcb85 100644 --- a/src/mesh/FEM_utilities.f90 +++ b/src/mesh/FEM_utilities.f90 @@ -93,7 +93,7 @@ contains subroutine FEM_utilities_init character(len=pStringLen) :: petsc_optionsOrder - class(tNode), pointer :: & + type(tDict), pointer :: & num_mesh, & debug_mesh ! pointer to mesh debug options integer :: & @@ -107,7 +107,7 @@ subroutine FEM_utilities_init print'(/,1x,a)', '<<<+- FEM_utilities init -+>>>' - num_mesh => config_numerics%get('mesh',defaultVal=emptyDict) + num_mesh => config_numerics%get_dict('mesh',defaultVal=emptyDict) p_s = num_mesh%get_asInt('p_s',defaultVal = 2) p_i = num_mesh%get_asInt('p_i',defaultVal = p_s) @@ -117,17 +117,17 @@ subroutine FEM_utilities_init if (p_i < max(1,p_s-1) .or. p_i > p_s) & call IO_error(821,ext_msg='integration order (p_i) out of bounds') - debug_mesh => config_debug%get('mesh',defaultVal=emptyList) - debugPETSc = debug_mesh%contains('PETSc') + debug_mesh => config_debug%get_dict('mesh',defaultVal=emptyDict) + debugPETSc = debug_mesh%contains('PETSc') - if(debugPETSc) print'(3(/,1x,a),/)', & + if (debugPETSc) print'(3(/,1x,a),/)', & 'Initializing PETSc with debug options: ', & trim(PETScDebug), & 'add more using the "PETSc_options" keyword in numerics.yaml' flush(IO_STDOUT) call PetscOptionsClear(PETSC_NULL_OPTIONS,err_PETSc) CHKERRQ(err_PETSc) - if(debugPETSc) call PetscOptionsInsertString(PETSC_NULL_OPTIONS,trim(PETSCDEBUG),err_PETSc) + if (debugPETSc) call PetscOptionsInsertString(PETSC_NULL_OPTIONS,trim(PETSCDEBUG),err_PETSc) CHKERRQ(err_PETSc) call PetscOptionsInsertString(PETSC_NULL_OPTIONS,'-mechanical_snes_type newtonls & &-mechanical_snes_linesearch_type cp -mechanical_snes_ksp_ew & @@ -182,8 +182,8 @@ subroutine utilities_projectBCValues(localVec,section,field,comp,bcPointsIS,BCVa PetscSection :: section IS :: bcPointsIS PetscInt, pointer :: bcPoints(:) - PetscScalar, pointer :: localArray(:) - PetscScalar :: BCValue,BCDotValue,timeinc + real(pReal), pointer :: localArray(:) + real(pReal) :: BCValue,BCDotValue,timeinc PetscErrorCode :: err_PETSc @@ -192,7 +192,8 @@ subroutine utilities_projectBCValues(localVec,section,field,comp,bcPointsIS,BCVa call ISGetSize(bcPointsIS,nBcPoints,err_PETSc) CHKERRQ(err_PETSc) if (nBcPoints > 0) call ISGetIndicesF90(bcPointsIS,bcPoints,err_PETSc) - call VecGetArrayF90(localVec,localArray,err_PETSc); CHKERRQ(err_PETSc) + call VecGetArrayF90(localVec,localArray,err_PETSc) + CHKERRQ(err_PETSc) do point = 1, nBcPoints call PetscSectionGetFieldDof(section,bcPoints(point),field,numDof,err_PETSc) CHKERRQ(err_PETSc) @@ -202,9 +203,12 @@ subroutine utilities_projectBCValues(localVec,section,field,comp,bcPointsIS,BCVa localArray(dof) = localArray(dof) + BCValue + BCDotValue*timeinc end do end do - call VecRestoreArrayF90(localVec,localArray,err_PETSc); CHKERRQ(err_PETSc) - call VecAssemblyBegin(localVec, err_PETSc); CHKERRQ(err_PETSc) - call VecAssemblyEnd (localVec, err_PETSc); CHKERRQ(err_PETSc) + call VecRestoreArrayF90(localVec,localArray,err_PETSc) + CHKERRQ(err_PETSc) + call VecAssemblyBegin(localVec, err_PETSc) + CHKERRQ(err_PETSc) + call VecAssemblyEnd (localVec, err_PETSc) + CHKERRQ(err_PETSc) if (nBcPoints > 0) call ISRestoreIndicesF90(bcPointsIS,bcPoints,err_PETSc) CHKERRQ(err_PETSc) diff --git a/src/mesh/discretization_mesh.f90 b/src/mesh/discretization_mesh.f90 index a53c50655..56c2eb8b5 100644 --- a/src/mesh/discretization_mesh.f90 +++ b/src/mesh/discretization_mesh.f90 @@ -20,7 +20,7 @@ module discretization_mesh use IO use config use discretization - use results + use result use FEM_quadrature use YAML_types use prec @@ -56,11 +56,10 @@ module discretization_mesh real(pReal), dimension(:,:,:), allocatable :: & mesh_ipCoordinates !< IP x,y,z coordinates (after deformation!) - external :: & #ifdef PETSC_USE_64BIT_INDICES - DMDestroy, & + external :: & + DMDestroy #endif - DMView ! ToDo: write interface public :: & discretization_mesh_init, & mesh_FEM_build_ipVolumes, & @@ -90,7 +89,7 @@ subroutine discretization_mesh_init(restart) integer(MPI_INTEGER_KIND) :: err_MPI PetscInt, dimension(:), allocatable :: & materialAt - class(tNode), pointer :: & + type(tDict), pointer :: & num_mesh integer :: p_i, dim !< integration order (quadrature rule) type(tvec) :: coords_node0 @@ -101,7 +100,7 @@ subroutine discretization_mesh_init(restart) !-------------------------------------------------------------------------------- ! read numerics parameter - num_mesh => config_numerics%get('mesh',defaultVal=emptyDict) + num_mesh => config_numerics%get_dict('mesh',defaultVal=emptyDict) p_i = num_mesh%get_asInt('p_i',defaultVal = 2) !--------------------------------------------------------------------------------- @@ -120,8 +119,6 @@ subroutine discretization_mesh_init(restart) call DMGetStratumSize(globalMesh,'depth',dimPlex,NelemsGlobal,err_PETSc) CHKERRQ(err_PETSc) mesh_NcpElemsGlobal = int(NelemsGlobal) - call DMView(globalMesh, PETSC_VIEWER_STDOUT_WORLD,err_PETSc) - CHKERRQ(err_PETSc) ! get number of IDs in face sets (for boundary conditions?) call DMGetLabelSize(globalMesh,'Face Sets',Nboundaries,err_PETSc) @@ -140,7 +137,7 @@ subroutine discretization_mesh_init(restart) call DMClone(globalMesh,geomMesh,err_PETSc) else call DMPlexDistribute(globalMesh,0_pPETSCINT,sf,geomMesh,err_PETSc) - endif + end if CHKERRQ(err_PETSc) allocate(mesh_boundaries(mesh_Nboundaries), source = 0_pPETSCINT) @@ -154,11 +151,12 @@ subroutine discretization_mesh_init(restart) mesh_boundaries(1:nFaceSets) = pFaceSets CHKERRQ(err_PETSc) call ISRestoreIndicesF90(faceSetIS,pFaceSets,err_PETSc) - endif + end if call MPI_Bcast(mesh_boundaries,mesh_Nboundaries,MPI_INTEGER,0_MPI_INTEGER_KIND,MPI_COMM_WORLD,err_MPI) if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' - call DMDestroy(globalMesh,err_PETSc); CHKERRQ(err_PETSc) + call DMDestroy(globalMesh,err_PETSc) + CHKERRQ(err_PETSc) call DMGetStratumSize(geomMesh,'depth',dimPlex,Nelems,err_PETSc) CHKERRQ(err_PETSc) @@ -181,7 +179,7 @@ subroutine discretization_mesh_init(restart) do j = 1, mesh_NcpElems call DMGetLabelValue(geomMesh,'Cell Sets',j-1,materialAt(j),err_PETSc) CHKERRQ(err_PETSc) - enddo + end do materialAt = materialAt + 1_pPETSCINT if (debug_element < 1 .or. debug_element > mesh_NcpElems) call IO_error(602,ext_msg='element') @@ -221,7 +219,7 @@ subroutine mesh_FEM_build_ipVolumes(dimPlex) call DMPlexComputeCellGeometryFVM(geomMesh,cell,vol,pCent,pNorm,err_PETSc) CHKERRQ(err_PETSc) mesh_ipVolume(:,cell+1) = vol/real(mesh_maxNips,pReal) - enddo + end do end subroutine mesh_FEM_build_ipVolumes @@ -257,11 +255,11 @@ subroutine mesh_FEM_build_ipCoordinates(dimPlex,qPoints) do dirJ = 1_pPETSCINT, dimPlex mesh_ipCoordinates(dirI,qPt,cell+1) = mesh_ipCoordinates(dirI,qPt,cell+1) + & pCellJ((dirI-1)*dimPlex+dirJ)*(qPoints(qOffset+dirJ) + 1.0_pReal) - enddo - enddo + end do + end do qOffset = qOffset + dimPlex - enddo - enddo + end do + end do end subroutine mesh_FEM_build_ipCoordinates @@ -274,16 +272,16 @@ subroutine writeGeometry(coordinates_points,coordinates_nodes) coordinates_nodes, & coordinates_points - call results_openJobFile - call results_closeGroup(results_addGroup('geometry')) + call result_openJobFile + call result_closeGroup(result_addGroup('geometry')) - call results_writeDataset(coordinates_nodes,'geometry','x_n', & - 'initial coordinates of the nodes','m') + call result_writeDataset(coordinates_nodes,'geometry','x_n', & + 'initial coordinates of the nodes','m') - call results_writeDataset(coordinates_points,'geometry','x_p', & - 'initial coordinates of the materialpoints (cell centers)','m') + call result_writeDataset(coordinates_points,'geometry','x_p', & + 'initial coordinates of the materialpoints (cell centers)','m') - call results_closeJobFile + call result_closeJobFile end subroutine writeGeometry diff --git a/src/mesh/mesh_mech_FEM.f90 b/src/mesh/mesh_mech_FEM.f90 index 3b162d97b..f612968fe 100644 --- a/src/mesh/mesh_mech_FEM.f90 +++ b/src/mesh/mesh_mech_FEM.f90 @@ -120,20 +120,20 @@ subroutine FEM_mechanical_init(fieldBC) PetscReal :: detJ PetscReal, allocatable, target :: cellJMat(:,:) - PetscScalar, pointer, dimension(:) :: px_scal - PetscScalar, allocatable, target, dimension(:) :: x_scal + real(pReal), pointer, dimension(:) :: px_scal + real(pReal), allocatable, target, dimension(:) :: x_scal character(len=*), parameter :: prefix = 'mechFE_' PetscErrorCode :: err_PETSc real(pReal), dimension(3,3) :: devNull - class(tNode), pointer :: & + type(tDict), pointer :: & num_mesh print'(/,1x,a)', '<<<+- FEM_mech init -+>>>'; flush(IO_STDOUT) !----------------------------------------------------------------------------- ! read numerical parametes and do sanity checks - num_mesh => config_numerics%get('mesh',defaultVal=emptyDict) + num_mesh => config_numerics%get_dict('mesh',defaultVal=emptyDict) num%p_i = int(num_mesh%get_asInt('p_i',defaultVal = 2),pPETSCINT) num%itmax = int(num_mesh%get_asInt('itmax',defaultVal=250),pPETSCINT) num%BBarStabilisation = num_mesh%get_asBool('bbarstabilisation',defaultVal = .false.) @@ -146,8 +146,10 @@ subroutine FEM_mechanical_init(fieldBC) !-------------------------------------------------------------------------------------------------- ! Setup FEM mech mesh - call DMClone(geomMesh,mechanical_mesh,err_PETSc); CHKERRQ(err_PETSc) - call DMGetDimension(mechanical_mesh,dimPlex,err_PETSc); CHKERRQ(err_PETSc) + call DMClone(geomMesh,mechanical_mesh,err_PETSc) + CHKERRQ(err_PETSc) + call DMGetDimension(mechanical_mesh,dimPlex,err_PETSc) + CHKERRQ(err_PETSc) !-------------------------------------------------------------------------------------------------- ! Setup FEM mech discretization @@ -162,24 +164,34 @@ subroutine FEM_mechanical_init(fieldBC) call PetscQuadratureSetData(mechQuad,dimPlex,nc,int(nQuadrature,pPETSCINT),qPointsP,qWeightsP,err_PETSc) CHKERRQ(err_PETSc) call PetscFECreateDefault(PETSC_COMM_SELF,dimPlex,nc,PETSC_TRUE,prefix, & - num%p_i,mechFE,err_PETSc); CHKERRQ(err_PETSc) - call PetscFESetQuadrature(mechFE,mechQuad,err_PETSc); CHKERRQ(err_PETSc) - call PetscFEGetDimension(mechFE,nBasis,err_PETSc); CHKERRQ(err_PETSc) + num%p_i,mechFE,err_PETSc) + CHKERRQ(err_PETSc) + call PetscFESetQuadrature(mechFE,mechQuad,err_PETSc) + CHKERRQ(err_PETSc) + call PetscFEGetDimension(mechFE,nBasis,err_PETSc) + CHKERRQ(err_PETSc) nBasis = nBasis/nc call DMAddField(mechanical_mesh,PETSC_NULL_DMLABEL,mechFE,err_PETSc) CHKERRQ(err_PETSc) - call DMCreateDS(mechanical_mesh,err_PETSc); CHKERRQ(err_PETSc) - call DMGetDS(mechanical_mesh,mechDS,err_PETSc); CHKERRQ(err_PETSc) - call PetscDSGetTotalDimension(mechDS,cellDof,err_PETSc); CHKERRQ(err_PETSc) - call PetscFEDestroy(mechFE,err_PETSc); CHKERRQ(err_PETSc) - call PetscQuadratureDestroy(mechQuad,err_PETSc); CHKERRQ(err_PETSc) + call DMCreateDS(mechanical_mesh,err_PETSc) + CHKERRQ(err_PETSc) + call DMGetDS(mechanical_mesh,mechDS,err_PETSc) + CHKERRQ(err_PETSc) + call PetscDSGetTotalDimension(mechDS,cellDof,err_PETSc) + CHKERRQ(err_PETSc) + call PetscFEDestroy(mechFE,err_PETSc) + CHKERRQ(err_PETSc) + call PetscQuadratureDestroy(mechQuad,err_PETSc) + CHKERRQ(err_PETSc) !-------------------------------------------------------------------------------------------------- ! Setup FEM mech boundary conditions call DMGetLabel(mechanical_mesh,'Face Sets',BCLabel,err_PETSc) CHKERRQ(err_PETSc) - call DMPlexLabelComplete(mechanical_mesh,BCLabel,err_PETSc); CHKERRQ(err_PETSc) - call DMGetLocalSection(mechanical_mesh,section,err_PETSc); CHKERRQ(err_PETSc) + call DMPlexLabelComplete(mechanical_mesh,BCLabel,err_PETSc) + CHKERRQ(err_PETSc) + call DMGetLocalSection(mechanical_mesh,section,err_PETSc) + CHKERRQ(err_PETSc) allocate(pnumComp(1), source=dimPlex) allocate(pnumDof(0:dimPlex), source = 0_pPETSCINT) do topologDim = 0, dimPlex @@ -187,11 +199,11 @@ subroutine FEM_mechanical_init(fieldBC) CHKERRQ(err_PETSc) call PetscSectionGetDof(section,cellStart,pnumDof(topologDim),err_PETSc) CHKERRQ(err_PETSc) - enddo + end do numBC = 0 do field = 1, dimPlex; do faceSet = 1, mesh_Nboundaries if (fieldBC%componentBC(field)%Mask(faceSet)) numBC = numBC + 1 - enddo; enddo + end do; end do allocate(pbcField(numBC), source=0_pPETSCINT) allocate(pbcComps(numBC)) allocate(pbcPoints(numBC)) @@ -206,28 +218,34 @@ subroutine FEM_mechanical_init(fieldBC) if (bcSize > 0) then call DMGetStratumIS(mechanical_mesh,'Face Sets',mesh_boundaries(faceSet),bcPoint,err_PETSc) CHKERRQ(err_PETSc) - call ISGetIndicesF90(bcPoint,pBcPoint,err_PETSc); CHKERRQ(err_PETSc) + call ISGetIndicesF90(bcPoint,pBcPoint,err_PETSc) + CHKERRQ(err_PETSc) call ISCreateGeneral(PETSC_COMM_WORLD,bcSize,pBcPoint,PETSC_COPY_VALUES,pbcPoints(numBC),err_PETSc) CHKERRQ(err_PETSc) - call ISRestoreIndicesF90(bcPoint,pBcPoint,err_PETSc); CHKERRQ(err_PETSc) - call ISDestroy(bcPoint,err_PETSc); CHKERRQ(err_PETSc) + call ISRestoreIndicesF90(bcPoint,pBcPoint,err_PETSc) + CHKERRQ(err_PETSc) + call ISDestroy(bcPoint,err_PETSc) + CHKERRQ(err_PETSc) else call ISCreateGeneral(PETSC_COMM_WORLD,0_pPETSCINT,[0_pPETSCINT],PETSC_COPY_VALUES,pbcPoints(numBC),err_PETSc) CHKERRQ(err_PETSc) - endif - endif - enddo; enddo + end if + end if + end do; end do call DMPlexCreateSection(mechanical_mesh,nolabel,pNumComp,pNumDof, & numBC,pBcField,pBcComps,pBcPoints,PETSC_NULL_IS,section,err_PETSc) CHKERRQ(err_PETSc) - call DMSetSection(mechanical_mesh,section,err_PETSc); CHKERRQ(err_PETSc) + call DMSetSection(mechanical_mesh,section,err_PETSc) + CHKERRQ(err_PETSc) do faceSet = 1, numBC - call ISDestroy(pbcPoints(faceSet),err_PETSc); CHKERRQ(err_PETSc) - enddo + call ISDestroy(pbcPoints(faceSet),err_PETSc) + CHKERRQ(err_PETSc) + end do !-------------------------------------------------------------------------------------------------- ! initialize solver specific parts of PETSc - call SNESCreate(PETSC_COMM_WORLD,mechanical_snes,err_PETSc);CHKERRQ(err_PETSc) + call SNESCreate(PETSC_COMM_WORLD,mechanical_snes,err_PETSc) + CHKERRQ(err_PETSc) call SNESSetOptionsPrefix(mechanical_snes,'mechanical_',err_PETSc) CHKERRQ(err_PETSc) call SNESSetDM(mechanical_snes,mechanical_mesh,err_PETSc) ! set the mesh for non-linear solver @@ -248,12 +266,15 @@ subroutine FEM_mechanical_init(fieldBC) CHKERRQ(err_PETSc) call SNESSetTolerances(mechanical_snes,1.0_pReal,0.0_pReal,0.0_pReal,num%itmax,num%itmax,err_PETSc) CHKERRQ(err_PETSc) - call SNESSetFromOptions(mechanical_snes,err_PETSc); CHKERRQ(err_PETSc) + call SNESSetFromOptions(mechanical_snes,err_PETSc) + CHKERRQ(err_PETSc) !-------------------------------------------------------------------------------------------------- ! init fields - call VecSet(solution ,0.0_pReal,err_PETSc); CHKERRQ(err_PETSc) - call VecSet(solution_rate,0.0_pReal,err_PETSc); CHKERRQ(err_PETSc) + call VecSet(solution ,0.0_pReal,err_PETSc) + CHKERRQ(err_PETSc) + call VecSet(solution_rate,0.0_pReal,err_PETSc) + CHKERRQ(err_PETSc) allocate(x_scal(cellDof)) allocate(nodalWeightsP(1)) allocate(nodalPointsP(dimPlex)) @@ -263,7 +284,8 @@ subroutine FEM_mechanical_init(fieldBC) allocate(cellJMat(dimPlex,dimPlex)) call PetscDSGetDiscretization(mechDS,0_pPETSCINT,mechFE,err_PETSc) CHKERRQ(err_PETSc) - call PetscFEGetDualSpace(mechFE,mechDualSpace,err_PETSc); CHKERRQ(err_PETSc) + call PetscFEGetDualSpace(mechFE,mechDualSpace,err_PETSc) + CHKERRQ(err_PETSc) call DMPlexGetHeightStratum(mechanical_mesh,0_pPETSCINT,cellStart,cellEnd,err_PETSc) CHKERRQ(err_PETSc) do cell = cellStart, cellEnd-1 !< loop over all elements @@ -277,11 +299,11 @@ subroutine FEM_mechanical_init(fieldBC) call PetscQuadratureGetData(functional,dimPlex,nc,nNodalPoints,nodalPointsP,nodalWeightsP,err_PETSc) CHKERRQ(err_PETSc) x_scal(basis+1:basis+dimPlex) = pV0 + matmul(transpose(cellJMat),nodalPointsP + 1.0_pReal) - enddo + end do px_scal => x_scal call DMPlexVecSetClosure(mechanical_mesh,section,solution_local,cell,px_scal,5,err_PETSc) CHKERRQ(err_PETSc) - enddo + end do call utilities_constitutiveResponse(0.0_pReal,devNull,.true.) end subroutine FEM_mechanical_init @@ -326,7 +348,7 @@ type(tSolutionState) function FEM_mechanical_solution( & FEM_mechanical_solution%converged = .true. call SNESGetIterationNumber(mechanical_snes,FEM_mechanical_solution%iterationsNeeded,err_PETSc) CHKERRQ(err_PETSc) - endif + end if print'(/,1x,a)', '===========================================================================' flush(IO_STDOUT) @@ -347,8 +369,8 @@ subroutine FEM_mechanical_formResidual(dm_local,xx_local,f_local,dummy,err_PETSc PetscDS :: prob Vec :: x_local, f_local, xx_local PetscSection :: section - PetscScalar, dimension(:), pointer :: x_scal, pf_scal - PetscScalar, dimension(cellDof), target :: f_scal + real(pReal), dimension(:), pointer :: x_scal, pf_scal + real(pReal), dimension(cellDof), target :: f_scal PetscReal :: IcellJMat(dimPlex,dimPlex) PetscReal, dimension(:),pointer :: pV0, pCellJ, pInvcellJ, basisField, basisFieldDer PetscInt :: cellStart, cellEnd, cell, field, face, & @@ -365,8 +387,10 @@ subroutine FEM_mechanical_formResidual(dm_local,xx_local,f_local,dummy,err_PETSc allocate(pinvcellJ(dimPlex**2)) allocate(x_scal(cellDof)) - call DMGetLocalSection(dm_local,section,err_PETSc); CHKERRQ(err_PETSc) - call DMGetDS(dm_local,prob,err_PETSc); CHKERRQ(err_PETSc) + call DMGetLocalSection(dm_local,section,err_PETSc) + CHKERRQ(err_PETSc) + call DMGetDS(dm_local,prob,err_PETSc) + CHKERRQ(err_PETSc) call PetscDSGetTabulation(prob,0_pPETSCINT,basisField,basisFieldDer,err_PETSc) CHKERRQ(err_PETSc) call DMPlexGetHeightStratum(dm_local,0_pPETSCINT,cellStart,cellEnd,err_PETSc) @@ -383,10 +407,11 @@ subroutine FEM_mechanical_formResidual(dm_local,xx_local,f_local,dummy,err_PETSc CHKERRQ(err_PETSc) call utilities_projectBCValues(x_local,section,0_pPETSCINT,field-1,bcPoints, & 0.0_pReal,params%fieldBC%componentBC(field)%Value(face),params%timeinc) - call ISDestroy(bcPoints,err_PETSc); CHKERRQ(err_PETSc) - endif - endif - enddo; enddo + call ISDestroy(bcPoints,err_PETSc) + CHKERRQ(err_PETSc) + end if + end if + end do; end do !-------------------------------------------------------------------------------------------------- ! evaluate field derivatives @@ -408,10 +433,10 @@ subroutine FEM_mechanical_formResidual(dm_local,xx_local,f_local,dummy,err_PETSc i = ((qPt*nBasis + basis)*dimPlex + comp)*dimPlex+comp BMat(comp*dimPlex+1_pPETSCINT:(comp+1_pPETSCINT)*dimPlex,basis*dimPlex+comp+1_pPETSCINT) = & matmul(IcellJMat,basisFieldDer(i*dimPlex+1_pPETSCINT:(i+1_pPETSCINT)*dimPlex)) - enddo - enddo + end do + end do homogenization_F(1:dimPlex,1:dimPlex,m) = reshape(matmul(BMat,x_scal),shape=[dimPlex,dimPlex], order=[2,1]) - enddo + end do if (num%BBarStabilisation) then detFAvg = math_det33(sum(homogenization_F(1:3,1:3,cell*nQuadrature+1:(cell+1)*nQuadrature),dim=3)/real(nQuadrature,pReal)) do qPt = 0, nQuadrature-1 @@ -419,11 +444,11 @@ subroutine FEM_mechanical_formResidual(dm_local,xx_local,f_local,dummy,err_PETSc homogenization_F(1:dimPlex,1:dimPlex,m) = homogenization_F(1:dimPlex,1:dimPlex,m) & * (detFAvg/math_det33(homogenization_F(1:3,1:3,m)))**(1.0_pReal/real(dimPlex,pReal)) - enddo - endif + end do + end if call DMPlexVecRestoreClosure(dm_local,section,x_local,cell,x_scal,err_PETSc) CHKERRQ(err_PETSc) - enddo + end do !-------------------------------------------------------------------------------------------------- ! evaluate constitutive response @@ -450,21 +475,22 @@ subroutine FEM_mechanical_formResidual(dm_local,xx_local,f_local,dummy,err_PETSc i = ((qPt*nBasis + basis)*dimPlex + comp)*dimPlex+comp BMat(comp*dimPlex+1_pPETSCINT:(comp+1_pPETSCINT)*dimPlex,basis*dimPlex+comp+1_pPETSCINT) = & matmul(IcellJMat,basisFieldDer(i*dimPlex+1_pPETSCINT:(i+1_pPETSCINT)*dimPlex)) - enddo - enddo + end do + end do f_scal = f_scal & + matmul(transpose(BMat), & reshape(transpose(homogenization_P(1:dimPlex,1:dimPlex,m)), & shape=[dimPlex*dimPlex]))*qWeights(qPt+1_pPETSCINT) - enddo + end do f_scal = f_scal*abs(detJ) pf_scal => f_scal call DMPlexVecSetClosure(dm_local,section,f_local,cell,pf_scal,ADD_VALUES,err_PETSc) CHKERRQ(err_PETSc) call DMPlexVecRestoreClosure(dm_local,section,x_local,cell,x_scal,err_PETSc) CHKERRQ(err_PETSc) - enddo - call DMRestoreLocalVector(dm_local,x_local,err_PETSc); CHKERRQ(err_PETSc) + end do + call DMRestoreLocalVector(dm_local,x_local,err_PETSc) + CHKERRQ(err_PETSc) end subroutine FEM_mechanical_formResidual @@ -491,10 +517,10 @@ subroutine FEM_mechanical_formJacobian(dm_local,xx_local,Jac_pre,Jac,dummy,err_P PetscReal, dimension(:), pointer :: basisField, basisFieldDer, & pV0, pCellJ, pInvcellJ - PetscScalar, dimension(:), pointer :: pK_e, x_scal + real(pReal), dimension(:), pointer :: pK_e, x_scal - PetscScalar,dimension(cellDOF,cellDOF), target :: K_e - PetscScalar,dimension(cellDOF,cellDOF) :: K_eA, K_eB + real(pReal),dimension(cellDOF,cellDOF), target :: K_e + real(pReal),dimension(cellDOF,cellDOF) :: K_eA, K_eB PetscInt :: cellStart, cellEnd, cell, field, face, & qPt, basis, comp, cidx,bcSize, m, i @@ -531,10 +557,11 @@ subroutine FEM_mechanical_formJacobian(dm_local,xx_local,Jac_pre,Jac,dummy,err_P CHKERRQ(err_PETSc) call utilities_projectBCValues(x_local,section,0_pPETSCINT,field-1,bcPoints, & 0.0_pReal,params%fieldBC%componentBC(field)%Value(face),params%timeinc) - call ISDestroy(bcPoints,err_PETSc); CHKERRQ(err_PETSc) - endif - endif - enddo; enddo + call ISDestroy(bcPoints,err_PETSc) + CHKERRQ(err_PETSc) + end if + end if + end do; end do call DMPlexGetHeightStratum(dm_local,0_pPETSCINT,cellStart,cellEnd,err_PETSc) CHKERRQ(err_PETSc) do cell = cellStart, cellEnd-1 !< loop over all elements @@ -556,8 +583,8 @@ subroutine FEM_mechanical_formJacobian(dm_local,xx_local,Jac_pre,Jac,dummy,err_P i = ((qPt*nBasis + basis)*dimPlex + comp)*dimPlex+comp BMat(comp*dimPlex+1_pPETSCINT:(comp+1_pPETSCINT)*dimPlex,basis*dimPlex+comp+1_pPETSCINT) = & matmul(reshape(pInvcellJ,[dimPlex,dimPlex]),basisFieldDer(i*dimPlex+1_pPETSCINT:(i+1_pPETSCINT)*dimPlex)) - enddo - enddo + end do + end do MatA = matmul(reshape(reshape(homogenization_dPdF(1:dimPlex,1:dimPlex,1:dimPlex,1:dimPlex,m), & shape=[dimPlex,dimPlex,dimPlex,dimPlex], order=[2,1,4,3]), & shape=[dimPlex*dimPlex,dimPlex*dimPlex]),BMat)*qWeights(qPt+1_pPETSCINT) @@ -575,8 +602,8 @@ subroutine FEM_mechanical_formJacobian(dm_local,xx_local,Jac_pre,Jac,dummy,err_P BMatAvg = BMatAvg + BMat else K_eA = K_eA + matmul(transpose(BMat),MatA) - endif - enddo + end if + end do if (num%BBarStabilisation) then FInv = math_inv33(FAvg) K_e = K_eA*math_det33(FAvg/real(nQuadrature,pReal))**(1.0_pReal/real(dimPlex,pReal)) + & @@ -585,7 +612,7 @@ subroutine FEM_mechanical_formJacobian(dm_local,xx_local,Jac_pre,Jac,dummy,err_P K_eB)/real(dimPlex,pReal) else K_e = K_eA - endif + end if K_e = (K_e + eps*math_eye(int(cellDof))) * abs(detJ) #ifndef __INTEL_COMPILER pK_e(1:cellDOF**2) => K_e @@ -597,24 +624,33 @@ subroutine FEM_mechanical_formJacobian(dm_local,xx_local,Jac_pre,Jac,dummy,err_P CHKERRQ(err_PETSc) call DMPlexVecRestoreClosure(dm_local,section,x_local,cell,x_scal,err_PETSc) CHKERRQ(err_PETSc) - enddo - call MatAssemblyBegin(Jac,MAT_FINAL_ASSEMBLY,err_PETSc); CHKERRQ(err_PETSc) - call MatAssemblyEnd(Jac,MAT_FINAL_ASSEMBLY,err_PETSc); CHKERRQ(err_PETSc) - call MatAssemblyBegin(Jac_pre,MAT_FINAL_ASSEMBLY,err_PETSc); CHKERRQ(err_PETSc) - call MatAssemblyEnd(Jac_pre,MAT_FINAL_ASSEMBLY,err_PETSc); CHKERRQ(err_PETSc) - call DMRestoreLocalVector(dm_local,x_local,err_PETSc); CHKERRQ(err_PETSc) + end do + call MatAssemblyBegin(Jac,MAT_FINAL_ASSEMBLY,err_PETSc) + CHKERRQ(err_PETSc) + call MatAssemblyEnd(Jac,MAT_FINAL_ASSEMBLY,err_PETSc) + CHKERRQ(err_PETSc) + call MatAssemblyBegin(Jac_pre,MAT_FINAL_ASSEMBLY,err_PETSc) + CHKERRQ(err_PETSc) + call MatAssemblyEnd(Jac_pre,MAT_FINAL_ASSEMBLY,err_PETSc) + CHKERRQ(err_PETSc) + call DMRestoreLocalVector(dm_local,x_local,err_PETSc) + CHKERRQ(err_PETSc) !-------------------------------------------------------------------------------------------------- ! apply boundary conditions #if (PETSC_VERSION_MINOR < 14) - call DMPlexCreateRigidBody(dm_local,matnull,err_PETSc); CHKERRQ(err_PETSc) + call DMPlexCreateRigidBody(dm_local,matnull,err_PETSc) + CHKERRQ(err_PETSc) #else call DMPlexCreateRigidBody(dm_local,0_pPETSCINT,matnull,err_PETSc) CHKERRQ(err_PETSc) #endif - call MatSetNullSpace(Jac,matnull,err_PETSc); CHKERRQ(err_PETSc) - call MatSetNearNullSpace(Jac,matnull,err_PETSc); CHKERRQ(err_PETSc) - call MatNullSpaceDestroy(matnull,err_PETSc); CHKERRQ(err_PETSc) + call MatSetNullSpace(Jac,matnull,err_PETSc) + CHKERRQ(err_PETSc) + call MatSetNearNullSpace(Jac,matnull,err_PETSc) + CHKERRQ(err_PETSc) + call MatNullSpaceDestroy(matnull,err_PETSc) + CHKERRQ(err_PETSc) end subroutine FEM_mechanical_formJacobian @@ -644,15 +680,20 @@ subroutine FEM_mechanical_forward(guess,timeinc,timeinc_old,fieldBC) if (guess .and. .not. cutBack) then ForwardData = .True. homogenization_F0 = homogenization_F - call SNESGetDM(mechanical_snes,dm_local,err_PETSc); CHKERRQ(err_PETSc) !< retrieve mesh info from mechanical_snes into dm_local - call DMGetSection(dm_local,section,err_PETSc); CHKERRQ(err_PETSc) - call DMGetLocalVector(dm_local,x_local,err_PETSc); CHKERRQ(err_PETSc) - call VecSet(x_local,0.0_pReal,err_PETSc); CHKERRQ(err_PETSc) + call SNESGetDM(mechanical_snes,dm_local,err_PETSc) !< retrieve mesh info from mechanical_snes into dm_local + CHKERRQ(err_PETSc) + call DMGetSection(dm_local,section,err_PETSc) + CHKERRQ(err_PETSc) + call DMGetLocalVector(dm_local,x_local,err_PETSc) + CHKERRQ(err_PETSc) + call VecSet(x_local,0.0_pReal,err_PETSc) + CHKERRQ(err_PETSc) call DMGlobalToLocalBegin(dm_local,solution,INSERT_VALUES,x_local,err_PETSc) !< retrieve my partition of global solution vector CHKERRQ(err_PETSc) call DMGlobalToLocalEnd(dm_local,solution,INSERT_VALUES,x_local,err_PETSc) CHKERRQ(err_PETSc) - call VecAXPY(solution_local,1.0_pReal,x_local,err_PETSc); CHKERRQ(err_PETSc) + call VecAXPY(solution_local,1.0_pReal,x_local,err_PETSc) + CHKERRQ(err_PETSc) do field = 1, dimPlex; do face = 1, mesh_Nboundaries if (fieldBC%componentBC(field)%Mask(face)) then call DMGetStratumSize(dm_local,'Face Sets',mesh_boundaries(face),bcSize,err_PETSc) @@ -661,19 +702,25 @@ subroutine FEM_mechanical_forward(guess,timeinc,timeinc_old,fieldBC) CHKERRQ(err_PETSc) call utilities_projectBCValues(solution_local,section,0_pPETSCINT,field-1,bcPoints, & 0.0_pReal,fieldBC%componentBC(field)%Value(face),timeinc_old) - call ISDestroy(bcPoints,err_PETSc); CHKERRQ(err_PETSc) - endif - endif - enddo; enddo - call DMRestoreLocalVector(dm_local,x_local,err_PETSc); CHKERRQ(err_PETSc) + call ISDestroy(bcPoints,err_PETSc) + CHKERRQ(err_PETSc) + end if + end if + end do; end do + call DMRestoreLocalVector(dm_local,x_local,err_PETSc) + CHKERRQ(err_PETSc) !-------------------------------------------------------------------------------------------------- ! update rate and forward last inc - call VecCopy(solution,solution_rate,err_PETSc); CHKERRQ(err_PETSc) - call VecScale(solution_rate,timeinc_old**(-1),err_PETSc); CHKERRQ(err_PETSc) - endif - call VecCopy(solution_rate,solution,err_PETSc); CHKERRQ(err_PETSc) - call VecScale(solution,timeinc,err_PETSc); CHKERRQ(err_PETSc) + call VecCopy(solution,solution_rate,err_PETSc) + CHKERRQ(err_PETSc) + call VecScale(solution_rate,timeinc_old**(-1),err_PETSc) + CHKERRQ(err_PETSc) + end if + call VecCopy(solution_rate,solution,err_PETSc) + CHKERRQ(err_PETSc) + call VecScale(solution,timeinc,err_PETSc) + CHKERRQ(err_PETSc) end subroutine FEM_mechanical_forward @@ -730,26 +777,34 @@ subroutine FEM_mechanical_updateCoords() PetscQuadrature :: mechQuad PetscReal, dimension(:), pointer :: basisField, basisFieldDer, & nodeCoords_linear !< nodal coordinates (dimPlex*Nnodes) - PetscScalar, dimension(:), pointer :: x_scal + real(pReal), dimension(:), pointer :: x_scal - call SNESGetDM(mechanical_snes,dm_local,err_PETSc); CHKERRQ(err_PETSc) - call DMGetDS(dm_local,mechQuad,err_PETSc); CHKERRQ(err_PETSc) - call DMGetLocalSection(dm_local,section,err_PETSc); CHKERRQ(err_PETSc) - call DMGetLocalVector(dm_local,x_local,err_PETSc); CHKERRQ(err_PETSc) - call DMGetDimension(dm_local,dimPlex,err_PETSc); CHKERRQ(err_PETSc) + call SNESGetDM(mechanical_snes,dm_local,err_PETSc) + CHKERRQ(err_PETSc) + call DMGetDS(dm_local,mechQuad,err_PETSc) + CHKERRQ(err_PETSc) + call DMGetLocalSection(dm_local,section,err_PETSc) + CHKERRQ(err_PETSc) + call DMGetLocalVector(dm_local,x_local,err_PETSc) + CHKERRQ(err_PETSc) + call DMGetDimension(dm_local,dimPlex,err_PETSc) + CHKERRQ(err_PETSc) ! write cell vertex displacements call DMPlexGetDepthStratum(dm_local,0_pPETSCINT,pStart,pEnd,err_PETSc) CHKERRQ(err_PETSc) allocate(nodeCoords(3,pStart:pEnd-1),source=0.0_pReal) - call VecGetArrayF90(x_local,nodeCoords_linear,err_PETSc); CHKERRQ(err_PETSc) + call VecGetArrayF90(x_local,nodeCoords_linear,err_PETSc) + CHKERRQ(err_PETSc) do p=pStart, pEnd-1 - call DMPlexGetPointLocal(dm_local, p, s, e, err_PETSc); CHKERRQ(err_PETSc) + call DMPlexGetPointLocal(dm_local, p, s, e, err_PETSc) + CHKERRQ(err_PETSc) nodeCoords(1:dimPlex,p)=nodeCoords_linear(s+1:e) - enddo + end do call discretization_setNodeCoords(nodeCoords) - call VecRestoreArrayF90(x_local,nodeCoords_linear,err_PETSc); CHKERRQ(err_PETSc) + call VecRestoreArrayF90(x_local,nodeCoords_linear,err_PETSc) + CHKERRQ(err_PETSc) ! write ip displacements call DMPlexGetHeightStratum(dm_local,0_pPETSCINT,cellStart,cellEnd,err_PETSc) @@ -772,14 +827,15 @@ subroutine FEM_mechanical_updateCoords() x_scal(nOffset+1:nOffset+dimPlex)) q = q+dimPlex nOffset = nOffset+dimPlex - enddo - enddo - enddo + end do + end do + end do call DMPlexVecRestoreClosure(dm_local,section,x_local,c,x_scal,err_PETSc) CHKERRQ(err_PETSc) end do call discretization_setIPcoords(reshape(ipCoords,[3,mesh_NcpElems*nQuadrature])) - call DMRestoreLocalVector(dm_local,x_local,err_PETSc); CHKERRQ(err_PETSc) + call DMRestoreLocalVector(dm_local,x_local,err_PETSc) + CHKERRQ(err_PETSc) end subroutine FEM_mechanical_updateCoords diff --git a/src/parallelization.f90 b/src/parallelization.f90 index fc328001a..3feea8cc3 100644 --- a/src/parallelization.f90 +++ b/src/parallelization.f90 @@ -27,15 +27,13 @@ module parallelization #ifndef PETSC integer, parameter, public :: & - MPI_INTEGER_KIND = pI64 + MPI_INTEGER_KIND = pI64 !< needed for MSC.Marc integer(MPI_INTEGER_KIND), parameter, public :: & - worldrank = 0_MPI_INTEGER_KIND, & !< MPI dummy worldrank - worldsize = 1_MPI_INTEGER_KIND !< MPI dummy worldsize #else integer(MPI_INTEGER_KIND), protected, public :: & +#endif worldrank = 0_MPI_INTEGER_KIND, & !< MPI worldrank (/=0 for MPI simulations only) worldsize = 1_MPI_INTEGER_KIND !< MPI worldsize (/=1 for MPI simulations only) -#endif #ifndef PETSC public :: parallelization_bcast_str @@ -55,7 +53,7 @@ contains !-------------------------------------------------------------------------------------------------- !> @brief Initialize shared memory (openMP) and distributed memory (MPI) parallelization. !-------------------------------------------------------------------------------------------------- -subroutine parallelization_init +subroutine parallelization_init() integer(MPI_INTEGER_KIND) :: err_MPI, typeSize, version, subversion, devNull character(len=4) :: rank_str @@ -140,7 +138,7 @@ subroutine parallelization_init error stop 'Mismatch between MPI_DOUBLE and DAMASK pReal' !$ call get_environment_variable(name='OMP_NUM_THREADS',value=NumThreadsString,STATUS=got_env) -!$ if(got_env /= 0) then +!$ if (got_env /= 0) then !$ print'(1x,a)', 'Could not get $OMP_NUM_THREADS, using default' !$ OMP_NUM_THREADS = 4_pI32 !$ else diff --git a/src/phase.f90 b/src/phase.f90 index f304707b9..4d4e30f45 100644 --- a/src/phase.f90 +++ b/src/phase.f90 @@ -9,10 +9,11 @@ module phase use math use rotations use polynomials + use tables use IO use config use material - use results + use result use lattice use discretization use parallelization @@ -96,31 +97,31 @@ module phase ! == cleaned:begin ================================================================================= module subroutine mechanical_init(phases) - class(tNode), pointer :: phases + type(tDict), pointer :: phases end subroutine mechanical_init module subroutine damage_init end subroutine damage_init module subroutine thermal_init(phases) - class(tNode), pointer :: phases + type(tDict), pointer :: phases end subroutine thermal_init - module subroutine mechanical_results(group,ph) + module subroutine mechanical_result(group,ph) character(len=*), intent(in) :: group integer, intent(in) :: ph - end subroutine mechanical_results + end subroutine mechanical_result - module subroutine damage_results(group,ph) + module subroutine damage_result(group,ph) character(len=*), intent(in) :: group integer, intent(in) :: ph - end subroutine damage_results + end subroutine damage_result - module subroutine thermal_results(group,ph) + module subroutine thermal_result(group,ph) character(len=*), intent(in) :: group integer, intent(in) :: ph - end subroutine thermal_results + end subroutine thermal_result module subroutine mechanical_forward() end subroutine mechanical_forward @@ -160,6 +161,11 @@ module phase integer, intent(in) :: ph end subroutine thermal_restartWrite + module subroutine damage_restartWrite(groupHandle,ph) + integer(HID_T), intent(in) :: groupHandle + integer, intent(in) :: ph + end subroutine damage_restartWrite + module subroutine mechanical_restartRead(groupHandle,ph) integer(HID_T), intent(in) :: groupHandle integer, intent(in) :: ph @@ -170,6 +176,11 @@ module phase integer, intent(in) :: ph end subroutine thermal_restartRead + module subroutine damage_restartRead(groupHandle,ph) + integer(HID_T), intent(in) :: groupHandle + integer, intent(in) :: ph + end subroutine damage_restartRead + module function mechanical_S(ph,en) result(S) integer, intent(in) :: ph,en real(pReal), dimension(3,3) :: S @@ -332,7 +343,7 @@ module phase IO, & config, & material, & - results, & + result, & lattice, & discretization, & HDF5_utilities @@ -347,7 +358,7 @@ module phase phase_K_T, & phase_mu_phi, & phase_mu_T, & - phase_results, & + phase_result, & phase_allocateState, & phase_forward, & phase_restore, & @@ -376,16 +387,16 @@ subroutine phase_init integer :: & ph, ce, co, ma - class (tNode), pointer :: & - debug_constitutive, & - materials, & + type(tDict), pointer :: & phases, & phase + type(tList), pointer :: & + debug_constitutive print'(/,1x,a)', '<<<+- phase init -+>>>'; flush(IO_STDOUT) - debug_constitutive => config_debug%get('phase', defaultVal=emptyList) + debug_constitutive => config_debug%get_list('phase', defaultVal=emptyList) debugConstitutive%basic = debug_constitutive%contains('basic') debugConstitutive%extensive = debug_constitutive%contains('extensive') debugConstitutive%selective = debug_constitutive%contains('selective') @@ -394,16 +405,14 @@ subroutine phase_init debugConstitutive%grain = config_debug%get_asInt('constituent', defaultVal = 1) - materials => config_material%get('material') - phases => config_material%get('phase') - + phases => config_material%get_dict('phase') allocate(phase_lattice(phases%length)) allocate(phase_cOverA(phases%length),source=-1.0_pReal) allocate(phase_rho(phases%length)) allocate(phase_O_0(phases%length)) do ph = 1,phases%length - phase => phases%get(ph) + phase => phases%get_dict(ph) phase_lattice(ph) = phase%get_asString('lattice') if (all(phase_lattice(ph) /= ['cF','cI','hP','tI'])) & call IO_error(130,ext_msg='phase_init: '//phase%get_asString('lattice')) @@ -503,26 +512,26 @@ end subroutine phase_forward !-------------------------------------------------------------------------------------------------- !> @brief writes constitutive results to HDF5 output file !-------------------------------------------------------------------------------------------------- -subroutine phase_results() +subroutine phase_result() integer :: ph character(len=:), allocatable :: group - call results_closeGroup(results_addGroup('/current/phase/')) + call result_closeGroup(result_addGroup('/current/phase/')) do ph = 1, size(material_name_phase) group = '/current/phase/'//trim(material_name_phase(ph))//'/' - call results_closeGroup(results_addGroup(group)) + call result_closeGroup(result_addGroup(group)) - call mechanical_results(group,ph) - call damage_results(group,ph) - call thermal_results(group,ph) + call mechanical_result(group,ph) + call damage_result(group,ph) + call thermal_result(group,ph) end do -end subroutine phase_results +end subroutine phase_result !-------------------------------------------------------------------------------------------------- @@ -536,13 +545,13 @@ subroutine crystallite_init() ip, & !< counter in integration point loop el, & !< counter in element loop en, ph - class(tNode), pointer :: & + type(tDict), pointer :: & num_crystallite, & phases - character(len=pStringLen) :: & - extmsg = '' + character(len=:), allocatable :: extmsg - num_crystallite => config_numerics%get('crystallite',defaultVal=emptyDict) + + num_crystallite => config_numerics%get_dict('crystallite',defaultVal=emptyDict) num%subStepMinCryst = num_crystallite%get_asFloat ('subStepMin', defaultVal=1.0e-3_pReal) num%subStepSizeCryst = num_crystallite%get_asFloat ('subStepSize', defaultVal=0.25_pReal) @@ -556,6 +565,7 @@ subroutine crystallite_init() num%nState = num_crystallite%get_asInt ('nState', defaultVal=20) num%nStress = num_crystallite%get_asInt ('nStress', defaultVal=40) + extmsg = '' if (num%subStepMinCryst <= 0.0_pReal) extmsg = trim(extmsg)//' subStepMinCryst' if (num%subStepSizeCryst <= 0.0_pReal) extmsg = trim(extmsg)//' subStepSizeCryst' if (num%stepIncreaseCryst <= 0.0_pReal) extmsg = trim(extmsg)//' stepIncreaseCryst' @@ -570,7 +580,7 @@ subroutine crystallite_init() if (extmsg /= '') call IO_error(301,ext_msg=trim(extmsg)) - phases => config_material%get('phase') + phases => config_material%get_dict('phase') !$OMP PARALLEL DO PRIVATE(ce,ph,en) do el = 1, discretization_Nelems @@ -675,6 +685,7 @@ subroutine phase_restartWrite(fileHandle) call mechanical_restartWrite(groupHandle(2),ph) call thermal_restartWrite(groupHandle(2),ph) + call damage_restartWrite(groupHandle(2),ph) call HDF5_closeGroup(groupHandle(2)) @@ -704,6 +715,7 @@ subroutine phase_restartRead(fileHandle) call mechanical_restartRead(groupHandle(2),ph) call thermal_restartRead(groupHandle(2),ph) + call damage_restartRead(groupHandle(2),ph) call HDF5_closeGroup(groupHandle(2)) diff --git a/src/phase_damage.f90 b/src/phase_damage.f90 index 7211f2db5..93c559ed5 100644 --- a/src/phase_damage.f90 +++ b/src/phase_damage.f90 @@ -1,6 +1,6 @@ -!---------------------------------------------------------------------------------------------------- +!-------------------------------------------------------------------------------------------------- !> @brief internal microstructure state for all damage sources and kinematics constitutive models -!---------------------------------------------------------------------------------------------------- +!-------------------------------------------------------------------------------------------------- submodule(phase) damage type :: tDamageParameters @@ -55,41 +55,42 @@ submodule(phase) damage S end subroutine anisobrittle_dotState - module subroutine anisobrittle_results(phase,group) - integer, intent(in) :: phase - character(len=*), intent(in) :: group - end subroutine anisobrittle_results - module subroutine isobrittle_results(phase,group) + module subroutine anisobrittle_result(phase,group) integer, intent(in) :: phase character(len=*), intent(in) :: group - end subroutine isobrittle_results + end subroutine anisobrittle_result + + module subroutine isobrittle_result(phase,group) + integer, intent(in) :: phase + character(len=*), intent(in) :: group + end subroutine isobrittle_result end interface contains !---------------------------------------------------------------------------------------------- -!< @brief initialize damage sources and kinematics mechanism +!< @brief Initialize damage mechanisms. !---------------------------------------------------------------------------------------------- -module subroutine damage_init +module subroutine damage_init() integer :: & ph, & Nmembers - class(tNode), pointer :: & + type(tDict), pointer :: & phases, & phase, & - sources, & source logical:: damage_active + print'(/,1x,a)', '<<<+- phase:damage init -+>>>' - phases => config_material%get('phase') + phases => config_material%get_dict('phase') allocate(current(phases%length)) - allocate(damageState (phases%length)) + allocate(damageState(phases%length)) allocate(param(phases%length)) damage_active = .false. @@ -99,12 +100,10 @@ module subroutine damage_init allocate(current(ph)%phi(Nmembers),source=1.0_pReal) - phase => phases%get(ph) - sources => phase%get('damage',defaultVal=emptyList) - if (sources%length > 1) error stop - if (sources%length == 1) then + phase => phases%get_dict(ph) + source => phase%get_dict('damage',defaultVal=emptyDict) + if (source%length > 0) then damage_active = .true. - source => sources%get(1) param(ph)%mu = source%get_asFloat('mu') param(ph)%l_c = source%get_asFloat('l_c') end if @@ -286,7 +285,7 @@ function integrateDamageState(Delta_t,ph,en) result(broken) contains !-------------------------------------------------------------------------------------------------- - !> @brief calculate the damping for correction of state and dot state + !> @brief Calculate the damping for correction of state and dot state. !-------------------------------------------------------------------------------------------------- real(pReal) pure function damper(omega_0,omega_1,omega_2) @@ -309,29 +308,58 @@ function integrateDamageState(Delta_t,ph,en) result(broken) end function integrateDamageState +module subroutine damage_restartWrite(groupHandle,ph) + + integer(HID_T), intent(in) :: groupHandle + integer, intent(in) :: ph + + + select case(phase_damage(ph)) + case(DAMAGE_ISOBRITTLE_ID,DAMAGE_ANISOBRITTLE_ID) + call HDF5_write(damageState(ph)%state,groupHandle,'omega_damage') + end select + +end subroutine damage_restartWrite + + +module subroutine damage_restartRead(groupHandle,ph) + + integer(HID_T), intent(in) :: groupHandle + integer, intent(in) :: ph + + + select case(phase_damage(ph)) + case(DAMAGE_ISOBRITTLE_ID,DAMAGE_ANISOBRITTLE_ID) + call HDF5_read(damageState(ph)%state0,groupHandle,'omega_damage') + end select + + +end subroutine damage_restartRead + + !---------------------------------------------------------------------------------------------- !< @brief writes damage sources results to HDF5 output file !---------------------------------------------------------------------------------------------- -module subroutine damage_results(group,ph) +module subroutine damage_result(group,ph) character(len=*), intent(in) :: group integer, intent(in) :: ph if (phase_damage(ph) /= DAMAGE_UNDEFINED_ID) & - call results_closeGroup(results_addGroup(group//'damage')) + call result_closeGroup(result_addGroup(group//'damage')) sourceType: select case (phase_damage(ph)) case (DAMAGE_ISOBRITTLE_ID) sourceType - call isobrittle_results(ph,group//'damage/') + call isobrittle_result(ph,group//'damage/') case (DAMAGE_ANISOBRITTLE_ID) sourceType - call anisobrittle_results(ph,group//'damage/') + call anisobrittle_result(ph,group//'damage/') end select sourceType -end subroutine damage_results +end subroutine damage_result !-------------------------------------------------------------------------------------------------- @@ -433,26 +461,27 @@ end function phase_damage_deltaState !-------------------------------------------------------------------------------------------------- -!> @brief checks if a source mechanism is active or not +!> @brief Check if a source mechanism is active or not. !-------------------------------------------------------------------------------------------------- function source_active(source_label) result(active_source) character(len=*), intent(in) :: source_label !< name of source mechanism logical, dimension(:), allocatable :: active_source - class(tNode), pointer :: & + type(tDict), pointer :: & phases, & phase, & - sources, & src + type(tList), pointer :: & + sources integer :: ph - phases => config_material%get('phase') + + phases => config_material%get_dict('phase') allocate(active_source(phases%length)) do ph = 1, phases%length - phase => phases%get(ph) - sources => phase%get('damage',defaultVal=emptyList) - src => sources%get(1) + phase => phases%get_dict(ph) + src => phase%get_dict('damage',defaultVal=emptyDict) active_source(ph) = src%get_asString('type',defaultVal = 'x') == source_label end do diff --git a/src/phase_damage_anisobrittle.f90 b/src/phase_damage_anisobrittle.f90 index 167d0829b..3c6880965 100644 --- a/src/phase_damage_anisobrittle.f90 +++ b/src/phase_damage_anisobrittle.f90 @@ -35,14 +35,13 @@ module function anisobrittle_init() result(mySources) logical, dimension(:), allocatable :: mySources - class(tNode), pointer :: & + type(tDict), pointer :: & phases, & phase, & - sources, & src integer :: Nmembers,ph integer, dimension(:), allocatable :: N_cl - character(len=pStringLen) :: extmsg = '' + character(len=:), allocatable :: extmsg mySources = source_active('anisobrittle') @@ -52,17 +51,16 @@ module function anisobrittle_init() result(mySources) print'(/,a,i0)', ' # phases: ',count(mySources); flush(IO_STDOUT) - phases => config_material%get('phase') + phases => config_material%get_dict('phase') allocate(param(phases%length)) - + extmsg = '' do ph = 1, phases%length if (mySources(ph)) then - phase => phases%get(ph) - sources => phase%get('damage') + phase => phases%get_dict(ph) + src => phase%get_dict('damage') associate(prm => param(ph)) - src => sources%get(1) N_cl = src%get_as1dInt('N_cl',defaultVal=emptyIntArray) prm%sum_N_cl = sum(abs(N_cl)) @@ -85,7 +83,7 @@ module function anisobrittle_init() result(mySources) prm%output = src%get_as1dString('output',defaultVal=emptyStringArray) #endif - ! sanity checks + ! sanity checks if (prm%q <= 0.0_pReal) extmsg = trim(extmsg)//' q' if (prm%dot_o <= 0.0_pReal) extmsg = trim(extmsg)//' dot_o' if (any(prm%g_crit < 0.0_pReal)) extmsg = trim(extmsg)//' g_crit' @@ -143,9 +141,9 @@ end subroutine anisobrittle_dotState !-------------------------------------------------------------------------------------------------- -!> @brief writes results to HDF5 output file +!> @brief Write results to HDF5 output file. !-------------------------------------------------------------------------------------------------- -module subroutine anisobrittle_results(phase,group) +module subroutine anisobrittle_result(phase,group) integer, intent(in) :: phase character(len=*), intent(in) :: group @@ -157,12 +155,12 @@ module subroutine anisobrittle_results(phase,group) outputsLoop: do o = 1,size(prm%output) select case(trim(prm%output(o))) case ('f_phi') - call results_writeDataset(stt,group,trim(prm%output(o)),'driving force','-') + call result_writeDataset(stt,group,trim(prm%output(o)),'driving force','-') end select end do outputsLoop end associate -end subroutine anisobrittle_results +end subroutine anisobrittle_result !-------------------------------------------------------------------------------------------------- diff --git a/src/phase_damage_isobrittle.f90 b/src/phase_damage_isobrittle.f90 index 76b382d62..73fa3f762 100644 --- a/src/phase_damage_isobrittle.f90 +++ b/src/phase_damage_isobrittle.f90 @@ -34,13 +34,12 @@ module function isobrittle_init() result(mySources) logical, dimension(:), allocatable :: mySources - class(tNode), pointer :: & + type(tDict), pointer :: & phases, & phase, & - sources, & src integer :: Nmembers,ph - character(len=pStringLen) :: extmsg = '' + character(len=:), allocatable :: extmsg mySources = source_active('isobrittle') @@ -50,18 +49,18 @@ module function isobrittle_init() result(mySources) print'(/,a,i0)', ' # phases: ',count(mySources); flush(IO_STDOUT) - phases => config_material%get('phase') + phases => config_material%get_dict('phase') allocate(param(phases%length)) allocate(state(phases%length)) allocate(deltaState(phases%length)) + extmsg = '' do ph = 1, phases%length if (mySources(ph)) then - phase => phases%get(ph) - sources => phase%get('damage') + phase => phases%get_dict(ph) + src => phase%get_dict('damage') associate(prm => param(ph), dlt => deltaState(ph), stt => state(ph)) - src => sources%get(1) prm%W_crit = src%get_asFloat('G_crit')/src%get_asFloat('l_c') @@ -95,7 +94,7 @@ end function isobrittle_init !-------------------------------------------------------------------------------------------------- -!> @brief calculates derived quantities from state +!> @brief !-------------------------------------------------------------------------------------------------- module subroutine isobrittle_deltaState(C, Fe, ph,en) @@ -111,11 +110,11 @@ module subroutine isobrittle_deltaState(C, Fe, ph,en) r_W - epsilon = math_33toVoigt6_strain(matmul(transpose(Fe),Fe)-math_I3) + epsilon = math_33toVoigt6_strain(0.5_pReal*(matmul(transpose(Fe),Fe)-math_I3)) associate(prm => param(ph), stt => state(ph), dlt => deltaState(ph)) - r_W = (0.5_pReal*dot_product(epsilon,matmul(C,epsilon)))/prm%W_crit + r_W = (2.0_pReal*dot_product(epsilon,matmul(C,epsilon)))/prm%W_crit dlt%r_W(en) = merge(r_W - stt%r_W(en), 0.0_pReal, r_W > stt%r_W(en)) end associate @@ -124,9 +123,9 @@ end subroutine isobrittle_deltaState !-------------------------------------------------------------------------------------------------- -!> @brief writes results to HDF5 output file +!> @brief Write results to HDF5 output file. !-------------------------------------------------------------------------------------------------- -module subroutine isobrittle_results(phase,group) +module subroutine isobrittle_result(phase,group) integer, intent(in) :: phase character(len=*), intent(in) :: group @@ -139,12 +138,12 @@ module subroutine isobrittle_results(phase,group) outputsLoop: do o = 1,size(prm%output) select case(trim(prm%output(o))) case ('f_phi') - call results_writeDataset(stt,group,trim(prm%output(o)),'driving force','-') + call result_writeDataset(stt,group,trim(prm%output(o)),'driving force','-') end select end do outputsLoop end associate -end subroutine isobrittle_results +end subroutine isobrittle_result end submodule isobrittle diff --git a/src/phase_mechanical.f90 b/src/phase_mechanical.f90 index 440e196bc..50a423caa 100644 --- a/src/phase_mechanical.f90 +++ b/src/phase_mechanical.f90 @@ -43,11 +43,11 @@ submodule(phase) mechanical interface module subroutine eigen_init(phases) - class(tNode), pointer :: phases + type(tDict), pointer :: phases end subroutine eigen_init module subroutine elastic_init(phases) - class(tNode), pointer :: phases + type(tDict), pointer :: phases end subroutine elastic_init module subroutine plastic_init @@ -129,35 +129,35 @@ submodule(phase) mechanical end subroutine plastic_LpAndItsTangents - module subroutine plastic_isotropic_results(ph,group) + module subroutine plastic_isotropic_result(ph,group) integer, intent(in) :: ph character(len=*), intent(in) :: group - end subroutine plastic_isotropic_results + end subroutine plastic_isotropic_result - module subroutine plastic_phenopowerlaw_results(ph,group) + module subroutine plastic_phenopowerlaw_result(ph,group) integer, intent(in) :: ph character(len=*), intent(in) :: group - end subroutine plastic_phenopowerlaw_results + end subroutine plastic_phenopowerlaw_result - module subroutine plastic_kinehardening_results(ph,group) + module subroutine plastic_kinehardening_result(ph,group) integer, intent(in) :: ph character(len=*), intent(in) :: group - end subroutine plastic_kinehardening_results + end subroutine plastic_kinehardening_result - module subroutine plastic_dislotwin_results(ph,group) + module subroutine plastic_dislotwin_result(ph,group) integer, intent(in) :: ph character(len=*), intent(in) :: group - end subroutine plastic_dislotwin_results + end subroutine plastic_dislotwin_result - module subroutine plastic_dislotungsten_results(ph,group) + module subroutine plastic_dislotungsten_result(ph,group) integer, intent(in) :: ph character(len=*), intent(in) :: group - end subroutine plastic_dislotungsten_results + end subroutine plastic_dislotungsten_result - module subroutine plastic_nonlocal_results(ph,group) + module subroutine plastic_nonlocal_result(ph,group) integer, intent(in) :: ph character(len=*), intent(in) :: group - end subroutine plastic_nonlocal_results + end subroutine plastic_nonlocal_result module function plastic_dislotwin_homogenizedC(ph,en) result(homogenizedC) real(pReal), dimension(6,6) :: homogenizedC @@ -169,14 +169,16 @@ submodule(phase) mechanical integer, intent(in) :: ph, en end function elastic_C66 - pure module function elastic_mu(ph,en) result(mu) + pure module function elastic_mu(ph,en,isotropic_bound) result(mu) real(pReal) :: mu integer, intent(in) :: ph, en + character(len=*), intent(in) :: isotropic_bound end function elastic_mu - pure module function elastic_nu(ph,en) result(nu) + pure module function elastic_nu(ph,en,isotropic_bound) result(nu) real(pReal) :: nu integer, intent(in) :: ph, en + character(len=*), intent(in) :: isotropic_bound end function elastic_nu end interface @@ -198,7 +200,7 @@ contains !-------------------------------------------------------------------------------------------------- module subroutine mechanical_init(phases) - class(tNode), pointer :: & + type(tDict), pointer :: & phases integer :: & @@ -208,11 +210,12 @@ module subroutine mechanical_init(phases) ph, & en, & Nmembers - class(tNode), pointer :: & + type(tDict), pointer :: & num_crystallite, & phase, & mech + print'(/,1x,a)', '<<<+- phase:mechanical init -+>>>' !------------------------------------------------------------------------------------------------- @@ -248,8 +251,8 @@ module subroutine mechanical_init(phases) allocate(phase_mechanical_P(ph)%data(3,3,Nmembers),source=0.0_pReal) allocate(phase_mechanical_S0(ph)%data(3,3,Nmembers),source=0.0_pReal) - phase => phases%get(ph) - mech => phase%get('mechanical') + phase => phases%get_dict(ph) + mech => phase%get_dict('mechanical') #if defined(__GFORTRAN__) output_mechanical(ph)%label = output_as1dString(mech) #else @@ -286,7 +289,7 @@ module subroutine mechanical_init(phases) plasticState(ph)%state0 = plasticState(ph)%state end do - num_crystallite => config_numerics%get('crystallite',defaultVal=emptyDict) + num_crystallite => config_numerics%get_dict('crystallite',defaultVal=emptyDict) select case(num_crystallite%get_asString('integrator',defaultVal='FPI')) @@ -316,7 +319,7 @@ module subroutine mechanical_init(phases) end subroutine mechanical_init -module subroutine mechanical_results(group,ph) +module subroutine mechanical_result(group,ph) character(len=*), intent(in) :: group integer, intent(in) :: ph @@ -327,27 +330,27 @@ module subroutine mechanical_results(group,ph) select case(phase_plasticity(ph)) case(PLASTIC_ISOTROPIC_ID) - call plastic_isotropic_results(ph,group//'mechanical/') + call plastic_isotropic_result(ph,group//'mechanical/') case(PLASTIC_PHENOPOWERLAW_ID) - call plastic_phenopowerlaw_results(ph,group//'mechanical/') + call plastic_phenopowerlaw_result(ph,group//'mechanical/') case(PLASTIC_KINEHARDENING_ID) - call plastic_kinehardening_results(ph,group//'mechanical/') + call plastic_kinehardening_result(ph,group//'mechanical/') case(PLASTIC_DISLOTWIN_ID) - call plastic_dislotwin_results(ph,group//'mechanical/') + call plastic_dislotwin_result(ph,group//'mechanical/') case(PLASTIC_DISLOTUNGSTEN_ID) - call plastic_dislotungsten_results(ph,group//'mechanical/') + call plastic_dislotungsten_result(ph,group//'mechanical/') case(PLASTIC_NONLOCAL_ID) - call plastic_nonlocal_results(ph,group//'mechanical/') + call plastic_nonlocal_result(ph,group//'mechanical/') end select -end subroutine mechanical_results +end subroutine mechanical_result !-------------------------------------------------------------------------------------------------- @@ -596,7 +599,7 @@ function integrateStateFPI(F_0,F,subFp0,subFi0,subState0,Delta_t,ph,en) result(b dotState_last(1:sizeDotState,1) = dotState broken = integrateStress(F,subFp0,subFi0,Delta_t,ph,en) - if(broken) exit iteration + if (broken) exit iteration dotState = plastic_dotState(Delta_t,ph,en) if (any(IEEE_is_NaN(dotState))) exit iteration @@ -677,7 +680,7 @@ function integrateStateEuler(F_0,F,subFp0,subFi0,subState0,Delta_t,ph,en) result #endif broken = plastic_deltaState(ph,en) - if(broken) return + if (broken) return broken = integrateStress(F,subFp0,subFi0,Delta_t,ph,en) @@ -720,10 +723,10 @@ function integrateStateAdaptiveEuler(F_0,F,subFp0,subFi0,subState0,Delta_t,ph,en #endif broken = plastic_deltaState(ph,en) - if(broken) return + if (broken) return broken = integrateStress(F,subFp0,subFi0,Delta_t,ph,en) - if(broken) return + if (broken) return dotState = plastic_dotState(Delta_t,ph,en) if (any(IEEE_is_NaN(dotState))) return @@ -852,13 +855,13 @@ function integrateStateRK(F_0,F,subFp0,subFi0,subState0,Delta_t,ph,en,A,B,C,DB) #endif broken = integrateStress(F_0+(F-F_0)*Delta_t*C(stage),subFp0,subFi0,Delta_t*C(stage), ph,en) - if(broken) exit + if (broken) exit dotState = plastic_dotState(Delta_t*C(stage), ph,en) if (any(IEEE_is_NaN(dotState))) exit end do - if(broken) return + if (broken) return plastic_RKdotState(1:sizeDotState,size(B)) = dotState @@ -869,15 +872,15 @@ function integrateStateRK(F_0,F,subFp0,subFi0,subState0,Delta_t,ph,en,A,B,C,DB) plasticState(ph)%state(1:sizeDotState,en) = IEEE_FMA(dotState,Delta_t,subState0) #endif - if(present(DB)) & + if (present(DB)) & broken = .not. converged(matmul(plastic_RKdotState(1:sizeDotState,1:size(DB)),DB) * Delta_t, & plasticState(ph)%state(1:sizeDotState,en), & plasticState(ph)%atol(1:sizeDotState)) - if(broken) return + if (broken) return broken = plastic_deltaState(ph,en) - if(broken) return + if (broken) return broken = integrateStress(F,subFp0,subFi0,Delta_t,ph,en) @@ -895,41 +898,41 @@ subroutine results(group,ph) integer :: ou - call results_closeGroup(results_addGroup(group//'/mechanical')) + call result_closeGroup(result_addGroup(group//'/mechanical')) do ou = 1, size(output_mechanical(ph)%label) select case (output_mechanical(ph)%label(ou)) case('F') - call results_writeDataset(phase_mechanical_F(ph)%data,group//'/mechanical/','F',& + call result_writeDataset(phase_mechanical_F(ph)%data,group//'/mechanical/','F',& 'deformation gradient','1') case('F_e') - call results_writeDataset(phase_mechanical_Fe(ph)%data,group//'/mechanical/','F_e',& + call result_writeDataset(phase_mechanical_Fe(ph)%data,group//'/mechanical/','F_e',& 'elastic deformation gradient','1') case('F_p') - call results_writeDataset(phase_mechanical_Fp(ph)%data,group//'/mechanical/','F_p', & + call result_writeDataset(phase_mechanical_Fp(ph)%data,group//'/mechanical/','F_p', & 'plastic deformation gradient','1') case('F_i') - call results_writeDataset(phase_mechanical_Fi(ph)%data,group//'/mechanical/','F_i', & + call result_writeDataset(phase_mechanical_Fi(ph)%data,group//'/mechanical/','F_i', & 'inelastic deformation gradient','1') case('L_p') - call results_writeDataset(phase_mechanical_Lp(ph)%data,group//'/mechanical/','L_p', & + call result_writeDataset(phase_mechanical_Lp(ph)%data,group//'/mechanical/','L_p', & 'plastic velocity gradient','1/s') case('L_i') - call results_writeDataset(phase_mechanical_Li(ph)%data,group//'/mechanical/','L_i', & + call result_writeDataset(phase_mechanical_Li(ph)%data,group//'/mechanical/','L_i', & 'inelastic velocity gradient','1/s') case('P') - call results_writeDataset(phase_mechanical_P(ph)%data,group//'/mechanical/','P', & + call result_writeDataset(phase_mechanical_P(ph)%data,group//'/mechanical/','P', & 'first Piola-Kirchhoff stress','Pa') case('S') - call results_writeDataset(phase_mechanical_S(ph)%data,group//'/mechanical/','S', & + call result_writeDataset(phase_mechanical_S(ph)%data,group//'/mechanical/','S', & 'second Piola-Kirchhoff stress','Pa') case('O') - call results_writeDataset(to_quaternion(phase_O(ph)%data),group//'/mechanical','O', & - 'crystal orientation as quaternion','q_0 (q_1 q_2 q_3)') - call results_addAttribute('lattice',phase_lattice(ph),group//'/mechanical/O') + call result_writeDataset(to_quaternion(phase_O(ph)%data),group//'/mechanical','O', & + 'crystal orientation as quaternion q_0 (q_1 q_2 q_3)','1') + call result_addAttribute('lattice',phase_lattice(ph),group//'/mechanical/O') if (any(phase_lattice(ph) == ['hP', 'tI'])) & - call results_addAttribute('c/a',phase_cOverA(ph),group//'/mechanical/O') + call result_addAttribute('c/a',phase_cOverA(ph),group//'/mechanical/O') end select end do @@ -1275,7 +1278,7 @@ end subroutine mechanical_restartRead !-------------------------------------------------------------------------------------------------- -!< @brief Get first Piola-Kichhoff stress (for use by non-mech physics). +!< @brief Get first Piola-Kirchhoff stress (for use by non-mech physics). !-------------------------------------------------------------------------------------------------- module function mechanical_S(ph,en) result(S) @@ -1317,7 +1320,7 @@ end function mechanical_F_e !-------------------------------------------------------------------------------------------------- -!< @brief Get second Piola-Kichhoff stress (for use by homogenization). +!< @brief Get second Piola-Kirchhoff stress (for use by homogenization). !-------------------------------------------------------------------------------------------------- module function phase_P(co,ce) result(P) diff --git a/src/phase_mechanical_eigen.f90 b/src/phase_mechanical_eigen.f90 index 4cd02d090..a0fad81c5 100644 --- a/src/phase_mechanical_eigen.f90 +++ b/src/phase_mechanical_eigen.f90 @@ -34,26 +34,29 @@ contains module subroutine eigen_init(phases) - class(tNode), pointer :: & + type(tDict), pointer :: & phases integer :: & ph - class(tNode), pointer :: & + type(tDict), pointer :: & phase, & - kinematics, & mechanics + type(tList), pointer :: & + kinematics + print'(/,1x,a)', '<<<+- phase:mechanical:eigen init -+>>>' + !-------------------------------------------------------------------------------------------------- ! explicit eigen mechanisms allocate(Nmodels(phases%length),source = 0) do ph = 1,phases%length - phase => phases%get(ph) - mechanics => phase%get('mechanical') - kinematics => mechanics%get('eigen',defaultVal=emptyList) + phase => phases%get_dict(ph) + mechanics => phase%get_dict('mechanical') + kinematics => mechanics%get_list('eigen',defaultVal=emptyList) Nmodels(ph) = kinematics%length end do @@ -72,7 +75,7 @@ end subroutine eigen_init !-------------------------------------------------------------------------------------------------- -!> @brief checks if a kinematic mechanism is active or not +!> @brief Check if an eigen kinematic mechanism is active. !-------------------------------------------------------------------------------------------------- function kinematics_active(kinematics_label,kinematics_length) result(active_kinematics) @@ -80,54 +83,54 @@ function kinematics_active(kinematics_label,kinematics_length) result(active_ki integer, intent(in) :: kinematics_length !< max. number of kinematics in system logical, dimension(:,:), allocatable :: active_kinematics - class(tNode), pointer :: & + type(tDict), pointer :: & phases, & phase, & - kinematics, & - kinematics_type, & - mechanics + mechanics, & + kinematic + type(tList), pointer :: & + kinematics integer :: ph,k - phases => config_material%get('phase') + + phases => config_material%get_dict('phase') allocate(active_kinematics(kinematics_length,phases%length), source = .false. ) do ph = 1, phases%length - phase => phases%get(ph) - mechanics => phase%get('mechanical') - kinematics => mechanics%get('eigen',defaultVal=emptyList) + phase => phases%get_dict(ph) + mechanics => phase%get_dict('mechanical') + kinematics => mechanics%get_list('eigen',defaultVal=emptyList) do k = 1, kinematics%length - kinematics_type => kinematics%get(k) - active_kinematics(k,ph) = kinematics_type%get_asString('type') == kinematics_label + kinematic => kinematics%get_dict(k) + active_kinematics(k,ph) = kinematic%get_asString('type') == kinematics_label end do end do - end function kinematics_active !-------------------------------------------------------------------------------------------------- -!> @brief checks if a kinematic mechanism is active or not +!> @brief Checks if a damage kinematic mechanism is active. !-------------------------------------------------------------------------------------------------- function kinematics_active2(kinematics_label) result(active_kinematics) character(len=*), intent(in) :: kinematics_label !< name of kinematic mechanism logical, dimension(:), allocatable :: active_kinematics - class(tNode), pointer :: & + type(tDict), pointer :: & phases, & phase, & - kinematics, & kinematics_type + type(tList), pointer :: & + kinematics integer :: ph - phases => config_material%get('phase') + + phases => config_material%get_dict('phase') allocate(active_kinematics(phases%length), source = .false.) do ph = 1, phases%length - phase => phases%get(ph) - kinematics => phase%get('damage',defaultVal=emptyList) - if (kinematics%length < 1) return - kinematics_type => kinematics%get(1) - if (.not. kinematics_type%contains('type')) continue + phase => phases%get_dict(ph) + kinematics_type => phase%get_dict('damage',defaultVal=emptyDict) active_kinematics(ph) = kinematics_type%get_asString('type',defaultVal='n/a') == kinematics_label end do diff --git a/src/phase_mechanical_eigen_cleavageopening.f90 b/src/phase_mechanical_eigen_cleavageopening.f90 index 1bf231c2c..780ed22b2 100644 --- a/src/phase_mechanical_eigen_cleavageopening.f90 +++ b/src/phase_mechanical_eigen_cleavageopening.f90 @@ -19,7 +19,7 @@ module function damage_anisobrittle_init() result(myKinematics) myKinematics = kinematics_active2('anisobrittle') - if(count(myKinematics) == 0) return + if (count(myKinematics) == 0) return print'(/,1x,a)', '<<<+- phase:mechanical:eigen:cleavageopening init -+>>>' print'(/,a,i2)', ' # phases: ',count(myKinematics); flush(IO_STDOUT) diff --git a/src/phase_mechanical_eigen_thermalexpansion.f90 b/src/phase_mechanical_eigen_thermalexpansion.f90 index 3c422616b..23c6b0aee 100644 --- a/src/phase_mechanical_eigen_thermalexpansion.f90 +++ b/src/phase_mechanical_eigen_thermalexpansion.f90 @@ -9,8 +9,8 @@ submodule(phase:eigen) thermalexpansion type :: tParameters type(tPolynomial) :: & - A_11, & - A_33 + Alpha_11, & + Alpha_33 end type tParameters type(tParameters), dimension(:), allocatable :: param @@ -28,40 +28,39 @@ module function thermalexpansion_init(kinematics_length) result(myKinematics) logical, dimension(:,:), allocatable :: myKinematics integer :: Ninstances, p, k - class(tNode), pointer :: & + type(tList), pointer :: & + kinematics + type(tDict), pointer :: & phases, & phase, & - mech, & - kinematics, & - myConfig + mech - print'(/,1x,a)', '<<<+- phase:mechanical:eigen:thermalexpansion init -+>>>' myKinematics = kinematics_active('thermalexpansion',kinematics_length) Ninstances = count(myKinematics) print'(/,a,i2)', ' # phases: ',Ninstances; flush(IO_STDOUT) if (Ninstances == 0) return - phases => config_material%get('phase') + print'(/,1x,a)', '<<<+- phase:mechanical:eigen:thermalexpansion init -+>>>' + + + phases => config_material%get_dict('phase') allocate(param(Ninstances)) allocate(kinematics_thermal_expansion_instance(phases%length), source=0) do p = 1, phases%length if (any(myKinematics(:,p))) kinematics_thermal_expansion_instance(p) = count(myKinematics(:,1:p)) - phase => phases%get(p) + phase => phases%get_dict(p) if (count(myKinematics(:,p)) == 0) cycle - mech => phase%get('mechanical') - kinematics => mech%get('eigen') + mech => phase%get_dict('mechanical') + kinematics => mech%get_list('eigen') do k = 1, kinematics%length if (myKinematics(k,p)) then associate(prm => param(kinematics_thermal_expansion_instance(p))) - myConfig => kinematics%get(k) - - prm%A_11 = polynomial(myConfig%asDict(),'A_11','T') + prm%Alpha_11 = polynomial(kinematics%get_dict(k),'Alpha_11','T') if (any(phase_lattice(p) == ['hP','tI'])) & - prm%A_33 = polynomial(myConfig%asDict(),'A_33','T') - + prm%Alpha_33 = polynomial(kinematics%get_dict(k),'Alpha_33','T') end associate end if end do @@ -82,7 +81,7 @@ module subroutine thermalexpansion_LiAndItsTangent(Li, dLi_dTstar, ph,me) dLi_dTstar !< derivative of Li with respect to Tstar (4th-order tensor defined to be zero) real(pReal) :: T, dot_T - real(pReal), dimension(3,3) :: A + real(pReal), dimension(3,3) :: Alpha T = thermal_T(ph,me) @@ -90,11 +89,11 @@ module subroutine thermalexpansion_LiAndItsTangent(Li, dLi_dTstar, ph,me) associate(prm => param(kinematics_thermal_expansion_instance(ph))) - A = 0.0_pReal - A(1,1) = prm%A_11%at(T) - if (any(phase_lattice(ph) == ['hP','tI'])) A(3,3) = prm%A_33%at(T) - A = lattice_symmetrize_33(A,phase_lattice(ph)) - Li = dot_T * A + Alpha = 0.0_pReal + Alpha(1,1) = prm%Alpha_11%at(T) + if (any(phase_lattice(ph) == ['hP','tI'])) Alpha(3,3) = prm%Alpha_33%at(T) + Alpha = lattice_symmetrize_33(Alpha,phase_lattice(ph)) + Li = dot_T * Alpha end associate dLi_dTstar = 0.0_pReal diff --git a/src/phase_mechanical_elastic.f90 b/src/phase_mechanical_elastic.f90 index 84ad7a20e..d5ad9f916 100644 --- a/src/phase_mechanical_elastic.f90 +++ b/src/phase_mechanical_elastic.f90 @@ -19,12 +19,12 @@ contains !-------------------------------------------------------------------------------------------------- module subroutine elastic_init(phases) - class(tNode), pointer :: & + type(tDict), pointer :: & phases integer :: & ph - class(tNode), pointer :: & + type(tDict), pointer :: & phase, & mech, & elastic @@ -35,27 +35,28 @@ module subroutine elastic_init(phases) print'(/,a,i0)', ' # phases: ',phases%length; flush(IO_STDOUT) + allocate(param(phases%length)) do ph = 1, phases%length - phase => phases%get(ph) - mech => phase%get('mechanical') - elastic => mech%get('elastic') + phase => phases%get_dict(ph) + mech => phase%get_dict('mechanical') + elastic => mech%get_dict('elastic') if (elastic%get_asString('type') /= 'Hooke') call IO_error(200,ext_msg=elastic%get_asString('type')) associate(prm => param(ph)) - prm%C_11 = polynomial(elastic%asDict(),'C_11','T') - prm%C_12 = polynomial(elastic%asDict(),'C_12','T') - prm%C_44 = polynomial(elastic%asDict(),'C_44','T') + prm%C_11 = polynomial(elastic,'C_11','T') + prm%C_12 = polynomial(elastic,'C_12','T') + prm%C_44 = polynomial(elastic,'C_44','T') if (any(phase_lattice(ph) == ['hP','tI'])) then - prm%C_13 = polynomial(elastic%asDict(),'C_13','T') - prm%C_33 = polynomial(elastic%asDict(),'C_33','T') + prm%C_13 = polynomial(elastic,'C_13','T') + prm%C_33 = polynomial(elastic,'C_33','T') end if if (phase_lattice(ph) == 'tI') & - prm%C_66 = polynomial(elastic%asDict(),'C_66','T') + prm%C_66 = polynomial(elastic,'C_66','T') end associate end do @@ -102,16 +103,21 @@ end function elastic_C66 !-------------------------------------------------------------------------------------------------- !> @brief return shear modulus !-------------------------------------------------------------------------------------------------- -pure module function elastic_mu(ph,en) result(mu) +pure module function elastic_mu(ph,en,isotropic_bound) result(mu) integer, intent(in) :: & ph, & en + character(len=*), intent(in) :: isotropic_bound real(pReal) :: & mu - mu = lattice_equivalent_mu(elastic_C66(ph,en),'voigt') + associate(prm => param(ph)) + + mu = lattice_isotropic_mu(elastic_C66(ph,en),isotropic_bound,phase_lattice(ph)) + + end associate end function elastic_mu @@ -119,16 +125,21 @@ end function elastic_mu !-------------------------------------------------------------------------------------------------- !> @brief return Poisson ratio !-------------------------------------------------------------------------------------------------- -pure module function elastic_nu(ph,en) result(nu) +pure module function elastic_nu(ph,en,isotropic_bound) result(nu) integer, intent(in) :: & ph, & en + character(len=*), intent(in) :: isotropic_bound real(pReal) :: & nu - nu = lattice_equivalent_nu(elastic_C66(ph,en),'voigt') + associate(prm => param(ph)) + + nu = lattice_isotropic_nu(elastic_C66(ph,en),isotropic_bound,phase_lattice(ph)) + + end associate end function elastic_nu diff --git a/src/phase_mechanical_plastic.f90 b/src/phase_mechanical_plastic.f90 index 6469c6e45..bff25895c 100644 --- a/src/phase_mechanical_plastic.f90 +++ b/src/phase_mechanical_plastic.f90 @@ -421,19 +421,19 @@ function plastic_active(plastic_label) result(active_plastic) character(len=*), intent(in) :: plastic_label !< type of plasticity model logical, dimension(:), allocatable :: active_plastic - class(tNode), pointer :: & + type(tDict), pointer :: & phases, & phase, & mech, & pl integer :: ph - phases => config_material%get('phase') + phases => config_material%get_dict('phase') allocate(active_plastic(phases%length), source = .false. ) do ph = 1, phases%length - phase => phases%get(ph) - mech => phase%get('mechanical') - pl => mech%get('plastic',defaultVal = emptyDict) + phase => phases%get_dict(ph) + mech => phase%get_dict('mechanical') + pl => mech%get_dict('plastic',defaultVal = emptyDict) active_plastic(ph) = pl%get_asString('type',defaultVal='none') == plastic_label end do diff --git a/src/phase_mechanical_plastic_dislotungsten.f90 b/src/phase_mechanical_plastic_dislotungsten.f90 index 9e72a1ebd..5ec974169 100644 --- a/src/phase_mechanical_plastic_dislotungsten.f90 +++ b/src/phase_mechanical_plastic_dislotungsten.f90 @@ -35,6 +35,8 @@ submodule(phase:plastic) dislotungsten P_nS_neg integer :: & sum_N_sl !< total number of active slip system + character(len=:), allocatable :: & + isotropic_bound character(len=pStringLen), allocatable, dimension(:) :: & output logical :: & @@ -91,9 +93,8 @@ module function plastic_dislotungsten_init() result(myPlasticity) rho_mob_0, & !< initial dislocation density rho_dip_0, & !< initial dipole density a !< non-Schmid coefficients - character(len=pStringLen) :: & - extmsg = '' - class(tNode), pointer :: & + character(len=:), allocatable :: extmsg + type(tDict), pointer :: & phases, & phase, & mech, & @@ -109,11 +110,13 @@ module function plastic_dislotungsten_init() result(myPlasticity) print'(/,1x,a)', 'D. Cereceda et al., International Journal of Plasticity 78:242–256, 2016' print'( 1x,a)', 'https://doi.org/10.1016/j.ijplas.2015.09.002' - phases => config_material%get('phase') + + phases => config_material%get_dict('phase') allocate(param(phases%length)) allocate(indexDotState(phases%length)) allocate(state(phases%length)) allocate(dependentState(phases%length)) + extmsg = '' do ph = 1, phases%length if (.not. myPlasticity(ph)) cycle @@ -121,9 +124,9 @@ module function plastic_dislotungsten_init() result(myPlasticity) associate(prm => param(ph), stt => state(ph), dst => dependentState(ph), & idx_dot => indexDotState(ph)) - phase => phases%get(ph) - mech => phase%get('mechanical') - pl => mech%get('plastic') + phase => phases%get_dict(ph) + mech => phase%get_dict('mechanical') + pl => mech%get_dict('plastic') #if defined (__GFORTRAN__) prm%output = output_as1dString(pl) @@ -131,6 +134,8 @@ module function plastic_dislotungsten_init() result(myPlasticity) prm%output = pl%get_as1dString('output',defaultVal=emptyStringArray) #endif + prm%isotropic_bound = pl%get_asString('isotropic_bound',defaultVal='isostrain') + !-------------------------------------------------------------------------------------------------- ! slip related parameters N_sl = pl%get_as1dInt('N_sl',defaultVal=emptyIntArray) @@ -333,7 +338,7 @@ module function dislotungsten_dotState(Mp,ph,en) result(dotState) dot_rho_dip => dotState(indexDotState(ph)%rho_dip(1):indexDotState(ph)%rho_dip(2)), & dot_gamma_sl => dotState(indexDotState(ph)%gamma_sl(1):indexDotState(ph)%gamma_sl(2))) - mu = elastic_mu(ph,en) + mu = elastic_mu(ph,en,prm%isotropic_bound) T = thermal_T(ph,en) call kinetics(Mp,T,ph,en,& @@ -384,7 +389,7 @@ module subroutine dislotungsten_dependentState(ph,en) associate(prm => param(ph), stt => state(ph), dst => dependentState(ph)) - dst%tau_pass(:,en) = elastic_mu(ph,en)*prm%b_sl & + dst%tau_pass(:,en) = elastic_mu(ph,en,prm%isotropic_bound)*prm%b_sl & * sqrt(matmul(prm%h_sl_sl,stt%rho_mob(:,en)+stt%rho_dip(:,en))) Lambda_sl_inv = 1.0_pReal/prm%D & @@ -399,7 +404,7 @@ end subroutine dislotungsten_dependentState !-------------------------------------------------------------------------------------------------- !> @brief Write results to HDF5 output file. !-------------------------------------------------------------------------------------------------- -module subroutine plastic_dislotungsten_results(ph,group) +module subroutine plastic_dislotungsten_result(ph,group) integer, intent(in) :: ph character(len=*), intent(in) :: group @@ -414,27 +419,27 @@ module subroutine plastic_dislotungsten_results(ph,group) select case(trim(prm%output(ou))) case('rho_mob') - call results_writeDataset(stt%rho_mob,group,trim(prm%output(ou)), & - 'mobile dislocation density','1/m²',prm%systems_sl) + call result_writeDataset(stt%rho_mob,group,trim(prm%output(ou)), & + 'mobile dislocation density','1/m²',prm%systems_sl) case('rho_dip') - call results_writeDataset(stt%rho_dip,group,trim(prm%output(ou)), & - 'dislocation dipole density','1/m²',prm%systems_sl) + call result_writeDataset(stt%rho_dip,group,trim(prm%output(ou)), & + 'dislocation dipole density','1/m²',prm%systems_sl) case('gamma_sl') - call results_writeDataset(stt%gamma_sl,group,trim(prm%output(ou)), & - 'plastic shear','1',prm%systems_sl) + call result_writeDataset(stt%gamma_sl,group,trim(prm%output(ou)), & + 'plastic shear','1',prm%systems_sl) case('Lambda_sl') - call results_writeDataset(dst%Lambda_sl,group,trim(prm%output(ou)), & - 'mean free path for slip','m',prm%systems_sl) + call result_writeDataset(dst%Lambda_sl,group,trim(prm%output(ou)), & + 'mean free path for slip','m',prm%systems_sl) case('tau_pass') - call results_writeDataset(dst%tau_pass,group,trim(prm%output(ou)), & - 'threshold stress for slip','Pa',prm%systems_sl) + call result_writeDataset(dst%tau_pass,group,trim(prm%output(ou)), & + 'threshold stress for slip','Pa',prm%systems_sl) end select end do end associate -end subroutine plastic_dislotungsten_results +end subroutine plastic_dislotungsten_result !-------------------------------------------------------------------------------------------------- diff --git a/src/phase_mechanical_plastic_dislotwin.f90 b/src/phase_mechanical_plastic_dislotwin.f90 index f01a7e95d..aa17b497c 100644 --- a/src/phase_mechanical_plastic_dislotwin.f90 +++ b/src/phase_mechanical_plastic_dislotwin.f90 @@ -27,7 +27,6 @@ submodule(phase:plastic) dislotwin gamma_0_sb = 1.0_pReal, & !< value for shearband velocity_0 E_sb = 1.0_pReal, & !< activation energy for shear bands h = 1.0_pReal, & !< stack height of hex nucleus - a_cF = 1.0_pReal, & cOverA_hP = 1.0_pReal, & V_mol = 1.0_pReal, & rho = 1.0_pReal @@ -55,8 +54,8 @@ submodule(phase:plastic) dislotwin real(pReal), allocatable, dimension(:,:) :: & h_sl_sl, & !< components of slip-slip interaction matrix h_sl_tw, & !< components of slip-twin interaction matrix - h_tw_tw, & !< components of twin-twin interaction matrix h_sl_tr, & !< components of slip-trans interaction matrix + h_tw_tw, & !< components of twin-twin interaction matrix h_tr_tr, & !< components of trans-trans interaction matrix n0_sl, & !< slip system normal forestProjection @@ -74,8 +73,9 @@ submodule(phase:plastic) dislotwin integer, allocatable, dimension(:,:) :: & fcc_twinNucleationSlipPair ! ToDo: Better name? Is also use for trans character(len=:), allocatable :: & - lattice_tr - character(len=pStringLen), allocatable, dimension(:) :: & + lattice_tr, & + isotropic_bound + character(len=pStringLen), allocatable, dimension(:) :: & output logical :: & extendedDislocations, & !< consider split into partials for climb calculation @@ -140,9 +140,8 @@ module function plastic_dislotwin_init() result(myPlasticity) real(pReal), allocatable, dimension(:) :: & rho_mob_0, & !< initial unipolar dislocation density per slip system rho_dip_0 !< initial dipole dislocation density per slip system - character(len=pStringLen) :: & - extmsg = '' - class(tNode), pointer :: & + character(len=:), allocatable :: extmsg + type(tDict), pointer :: & phases, & phase, & mech, & @@ -165,11 +164,12 @@ module function plastic_dislotwin_init() result(myPlasticity) print'( 1x,a)', 'https://doi.org/10.1016/j.actamat.2016.07.032' - phases => config_material%get('phase') + phases => config_material%get_dict('phase') allocate(param(phases%length)) allocate(indexDotState(phases%length)) allocate(state(phases%length)) allocate(dependentState(phases%length)) + extmsg = '' do ph = 1, phases%length if (.not. myPlasticity(ph)) cycle @@ -177,9 +177,9 @@ module function plastic_dislotwin_init() result(myPlasticity) associate(prm => param(ph), stt => state(ph), dst => dependentState(ph), & idx_dot => indexDotState(ph)) - phase => phases%get(ph) - mech => phase%get('mechanical') - pl => mech%get('plastic') + phase => phases%get_dict(ph) + mech => phase%get_dict('mechanical') + pl => mech%get_dict('plastic') #if defined (__GFORTRAN__) prm%output = output_as1dString(pl) @@ -187,6 +187,8 @@ module function plastic_dislotwin_init() result(myPlasticity) prm%output = pl%get_as1dString('output',defaultVal=emptyStringArray) #endif + prm%isotropic_bound = pl%get_asString('isotropic_bound',defaultVal='isostrain') + !-------------------------------------------------------------------------------------------------- ! slip related parameters N_sl = pl%get_as1dInt('N_sl',defaultVal=emptyIntArray) @@ -300,9 +302,9 @@ module function plastic_dislotwin_init() result(myPlasticity) prm%b_tr = math_expand(prm%b_tr,prm%N_tr) prm%i_tr = pl%get_asFloat('i_tr') - prm%Delta_G = polynomial(pl%asDict(),'Delta_G','T') + prm%Delta_G = polynomial(pl,'Delta_G','T') prm%L_tr = pl%get_asFloat('L_tr') - a_cF = pl%get_asFloat('a_cF') + a_cF = prm%b_tr(1)*sqrt(6.0_pReal) ! b_tr is Shockley partial prm%h = 5.0_pReal * a_cF/sqrt(3.0_pReal) prm%cOverA_hP = pl%get_asFloat('c/a_hP') prm%rho = 4.0_pReal/(sqrt(3.0_pReal)*a_cF**2)/N_A @@ -358,7 +360,7 @@ module function plastic_dislotwin_init() result(myPlasticity) end if if (prm%sum_N_tw + prm%sum_N_tr > 0 .or. prm%extendedDislocations) & - prm%Gamma_sf = polynomial(pl%asDict(),'Gamma_sf','T') + prm%Gamma_sf = polynomial(pl,'Gamma_sf','T') slipAndTwinActive: if (prm%sum_N_sl * prm%sum_N_tw > 0) then prm%h_sl_tw = lattice_interaction_SlipByTwin(N_sl,prm%N_tw,pl%get_as1dFloat('h_sl-tw'), & @@ -372,6 +374,10 @@ module function plastic_dislotwin_init() result(myPlasticity) if (prm%fccTwinTransNucleation .and. size(prm%N_tr) /= 1) extmsg = trim(extmsg)//' N_tr: nucleation' end if slipAndTransActive + twinAndTransActive: if (prm%sum_N_tw * prm%sum_N_tr > 0) then + if (dNeq(prm%b_tw(1),prm%b_tr(1))) extmsg = trim(extmsg)//' b_tw != b_tr' + end if twinAndTransActive + !-------------------------------------------------------------------------------------------------- ! allocate state arrays Nmembers = count(material_phaseID == ph) @@ -641,8 +647,8 @@ module function dislotwin_dotState(Mp,ph,en) result(dotState) dot_f_tw => dotState(indexDotState(ph)%f_tw(1):indexDotState(ph)%f_tw(2)), & dot_f_tr => dotState(indexDotState(ph)%f_tr(1):indexDotState(ph)%f_tr(2))) - mu = elastic_mu(ph,en) - nu = elastic_nu(ph,en) + mu = elastic_mu(ph,en,prm%isotropic_bound) + nu = elastic_nu(ph,en,prm%isotropic_bound) T = thermal_T(ph,en) f_matrix = 1.0_pReal & @@ -729,7 +735,7 @@ module subroutine dislotwin_dependentState(ph,en) associate(prm => param(ph), stt => state(ph), dst => dependentState(ph)) - mu = elastic_mu(ph,en) + mu = elastic_mu(ph,en,prm%isotropic_bound) sumf_tw = sum(stt%f_tw(1:prm%sum_N_tw,en)) sumf_tr = sum(stt%f_tr(1:prm%sum_N_tr,en)) @@ -762,7 +768,7 @@ end subroutine dislotwin_dependentState !-------------------------------------------------------------------------------------------------- !> @brief Write results to HDF5 output file. !-------------------------------------------------------------------------------------------------- -module subroutine plastic_dislotwin_results(ph,group) +module subroutine plastic_dislotwin_result(ph,group) integer, intent(in) :: ph character(len=*), intent(in) :: group @@ -777,30 +783,30 @@ module subroutine plastic_dislotwin_results(ph,group) select case(trim(prm%output(ou))) case('rho_mob') - call results_writeDataset(stt%rho_mob,group,trim(prm%output(ou)), & - 'mobile dislocation density','1/m²',prm%systems_sl) + call result_writeDataset(stt%rho_mob,group,trim(prm%output(ou)), & + 'mobile dislocation density','1/m²',prm%systems_sl) case('rho_dip') - call results_writeDataset(stt%rho_dip,group,trim(prm%output(ou)), & - 'dislocation dipole density','1/m²',prm%systems_sl) + call result_writeDataset(stt%rho_dip,group,trim(prm%output(ou)), & + 'dislocation dipole density','1/m²',prm%systems_sl) case('gamma_sl') - call results_writeDataset(stt%gamma_sl,group,trim(prm%output(ou)), & - 'plastic shear','1',prm%systems_sl) + call result_writeDataset(stt%gamma_sl,group,trim(prm%output(ou)), & + 'plastic shear','1',prm%systems_sl) case('Lambda_sl') - call results_writeDataset(dst%Lambda_sl,group,trim(prm%output(ou)), & - 'mean free path for slip','m',prm%systems_sl) + call result_writeDataset(dst%Lambda_sl,group,trim(prm%output(ou)), & + 'mean free path for slip','m',prm%systems_sl) case('tau_pass') - call results_writeDataset(dst%tau_pass,group,trim(prm%output(ou)), & - 'passing stress for slip','Pa',prm%systems_sl) + call result_writeDataset(dst%tau_pass,group,trim(prm%output(ou)), & + 'passing stress for slip','Pa',prm%systems_sl) case('f_tw') - call results_writeDataset(stt%f_tw,group,trim(prm%output(ou)), & - 'twinned volume fraction','m³/m³',prm%systems_tw) + call result_writeDataset(stt%f_tw,group,trim(prm%output(ou)), & + 'twinned volume fraction','m³/m³',prm%systems_tw) case('Lambda_tw') - call results_writeDataset(dst%Lambda_tw,group,trim(prm%output(ou)), & - 'mean free path for twinning','m',prm%systems_tw) + call result_writeDataset(dst%Lambda_tw,group,trim(prm%output(ou)), & + 'mean free path for twinning','m',prm%systems_tw) case('f_tr') - if (prm%sum_N_tr>0) call results_writeDataset(stt%f_tr,group,trim(prm%output(ou)), & + if (prm%sum_N_tr>0) call result_writeDataset(stt%f_tr,group,trim(prm%output(ou)), & 'martensite volume fraction','m³/m³') end select @@ -809,7 +815,7 @@ module subroutine plastic_dislotwin_results(ph,group) end associate -end subroutine plastic_dislotwin_results +end subroutine plastic_dislotwin_result !-------------------------------------------------------------------------------------------------- @@ -927,8 +933,8 @@ pure subroutine kinetics_tw(Mp,T,abs_dot_gamma_sl,ph,en,& associate(prm => param(ph), stt => state(ph), dst => dependentState(ph)) - mu = elastic_mu(ph,en) - nu = elastic_nu(ph,en) + mu = elastic_mu(ph,en,prm%isotropic_bound) + nu = elastic_nu(ph,en,prm%isotropic_bound) Gamma_sf = prm%Gamma_sf%at(T) tau_hat = 3.0_pReal*prm%b_tw(1)*mu/prm%L_tw & @@ -1003,8 +1009,8 @@ pure subroutine kinetics_tr(Mp,T,abs_dot_gamma_sl,ph,en,& associate(prm => param(ph), stt => state(ph), dst => dependentState(ph)) - mu = elastic_mu(ph,en) - nu = elastic_nu(ph,en) + mu = elastic_mu(ph,en,prm%isotropic_bound) + nu = elastic_nu(ph,en,prm%isotropic_bound) Gamma_sf = prm%Gamma_sf%at(T) tau_hat = 3.0_pReal*prm%b_tr(1)*mu/prm%L_tr & diff --git a/src/phase_mechanical_plastic_isotropic.f90 b/src/phase_mechanical_plastic_isotropic.f90 index c855f5c25..53303df33 100644 --- a/src/phase_mechanical_plastic_isotropic.f90 +++ b/src/phase_mechanical_plastic_isotropic.f90 @@ -54,9 +54,8 @@ module function plastic_isotropic_init() result(myPlasticity) sizeState, sizeDotState real(pReal) :: & xi_0 !< initial critical stress - character(len=pStringLen) :: & - extmsg = '' - class(tNode), pointer :: & + character(len=:), allocatable :: extmsg + type(tDict), pointer :: & phases, & phase, & mech, & @@ -64,7 +63,7 @@ module function plastic_isotropic_init() result(myPlasticity) myPlasticity = plastic_active('isotropic') - if(count(myPlasticity) == 0) return + if (count(myPlasticity) == 0) return print'(/,1x,a)', '<<<+- phase:mechanical:plastic:isotropic init -+>>>' print'(/,a,i0)', ' # phases: ',count(myPlasticity); flush(IO_STDOUT) @@ -72,18 +71,20 @@ module function plastic_isotropic_init() result(myPlasticity) print'(/,1x,a)', 'T. Maiti and P. Eisenlohr, Scripta Materialia 145:37–40, 2018' print'( 1x,a)', 'https://doi.org/10.1016/j.scriptamat.2017.09.047' - phases => config_material%get('phase') + + phases => config_material%get_dict('phase') allocate(param(phases%length)) allocate(state(phases%length)) + extmsg = '' do ph = 1, phases%length - if(.not. myPlasticity(ph)) cycle + if (.not. myPlasticity(ph)) cycle associate(prm => param(ph), stt => state(ph)) - phase => phases%get(ph) - mech => phase%get('mechanical') - pl => mech%get('plastic') + phase => phases%get_dict(ph) + mech => phase%get_dict('mechanical') + pl => mech%get_dict('plastic') #if defined (__GFORTRAN__) prm%output = output_as1dString(pl) @@ -285,7 +286,7 @@ end function isotropic_dotState !-------------------------------------------------------------------------------------------------- !> @brief Write results to HDF5 output file. !-------------------------------------------------------------------------------------------------- -module subroutine plastic_isotropic_results(ph,group) +module subroutine plastic_isotropic_result(ph,group) integer, intent(in) :: ph character(len=*), intent(in) :: group @@ -296,13 +297,13 @@ module subroutine plastic_isotropic_results(ph,group) outputsLoop: do o = 1,size(prm%output) select case(trim(prm%output(o))) case ('xi') - call results_writeDataset(stt%xi,group,trim(prm%output(o)), & - 'resistance against plastic flow','Pa') + call result_writeDataset(stt%xi,group,trim(prm%output(o)), & + 'resistance against plastic flow','Pa') end select end do outputsLoop end associate -end subroutine plastic_isotropic_results +end subroutine plastic_isotropic_result end submodule isotropic diff --git a/src/phase_mechanical_plastic_kinehardening.f90 b/src/phase_mechanical_plastic_kinehardening.f90 index bc8c7df4e..6d3f5d029 100644 --- a/src/phase_mechanical_plastic_kinehardening.f90 +++ b/src/phase_mechanical_plastic_kinehardening.f90 @@ -77,16 +77,15 @@ module function plastic_kinehardening_init() result(myPlasticity) real(pReal), dimension(:), allocatable :: & xi_0, & !< initial resistance against plastic flow a !< non-Schmid coefficients - character(len=pStringLen) :: & - extmsg = '' - class(tNode), pointer :: & + character(len=:), allocatable :: extmsg + type(tDict), pointer :: & phases, & phase, & mech, & pl myPlasticity = plastic_active('kinehardening') - if(count(myPlasticity) == 0) return + if (count(myPlasticity) == 0) return print'(/,1x,a)', '<<<+- phase:mechanical:plastic:kinehardening init -+>>>' print'(/,a,i0)', ' # phases: ',count(myPlasticity); flush(IO_STDOUT) @@ -94,12 +93,13 @@ module function plastic_kinehardening_init() result(myPlasticity) print'(/,1x,a)', 'J.A. Wollmershauser et al., International Journal of Fatigue 36:181–193, 2012' print'( 1x,a)', 'https://doi.org/10.1016/j.ijfatigue.2011.07.008' - phases => config_material%get('phase') + + phases => config_material%get_dict('phase') allocate(param(phases%length)) allocate(indexDotState(phases%length)) allocate(state(phases%length)) allocate(deltaState(phases%length)) - + extmsg = '' do ph = 1, phases%length if (.not. myPlasticity(ph)) cycle @@ -107,9 +107,9 @@ module function plastic_kinehardening_init() result(myPlasticity) associate(prm => param(ph), stt => state(ph), dlt => deltaState(ph), & idx_dot => indexDotState(ph)) - phase => phases%get(ph) - mech => phase%get('mechanical') - pl => mech%get('plastic') + phase => phases%get_dict(ph) + mech => phase%get_dict('mechanical') + pl => mech%get_dict('plastic') #if defined (__GFORTRAN__) prm%output = output_as1dString(pl) @@ -127,7 +127,7 @@ module function plastic_kinehardening_init() result(myPlasticity) if (phase_lattice(ph) == 'cI') then a = pl%get_as1dFloat('a_nonSchmid',defaultVal = emptyRealArray) - if(size(a) > 0) prm%nonSchmidActive = .true. + if (size(a) > 0) prm%nonSchmidActive = .true. prm%P_nS_pos = lattice_nonSchmidMatrix(N_sl,a,+1) prm%P_nS_neg = lattice_nonSchmidMatrix(N_sl,a,-1) else @@ -189,7 +189,7 @@ module function plastic_kinehardening_init() result(myPlasticity) stt%xi => plasticState(ph)%state(startIndex:endIndex,:) stt%xi = spread(xi_0, 2, Nmembers) plasticState(ph)%atol(startIndex:endIndex) = pl%get_asFloat('atol_xi',defaultVal=1.0_pReal) - if(any(plasticState(ph)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' atol_xi' + if (any(plasticState(ph)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' atol_xi' startIndex = endIndex + 1 endIndex = endIndex + prm%sum_N_sl @@ -202,7 +202,7 @@ module function plastic_kinehardening_init() result(myPlasticity) idx_dot%gamma = [startIndex,endIndex] stt%gamma => plasticState(ph)%state(startIndex:endIndex,:) plasticState(ph)%atol(startIndex:endIndex) = pl%get_asFloat('atol_gamma',defaultVal=1.0e-6_pReal) - if(any(plasticState(ph)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' atol_gamma' + if (any(plasticState(ph)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' atol_gamma' o = plasticState(ph)%offsetDeltaState startIndex = endIndex + 1 @@ -362,7 +362,7 @@ end subroutine plastic_kinehardening_deltaState !-------------------------------------------------------------------------------------------------- !> @brief Write results to HDF5 output file. !-------------------------------------------------------------------------------------------------- -module subroutine plastic_kinehardening_results(ph,group) +module subroutine plastic_kinehardening_result(ph,group) integer, intent(in) :: ph character(len=*), intent(in) :: group @@ -377,30 +377,30 @@ module subroutine plastic_kinehardening_results(ph,group) select case(trim(prm%output(ou))) case ('xi') - call results_writeDataset(stt%xi,group,trim(prm%output(ou)), & - 'resistance against plastic slip','Pa',prm%systems_sl) + call result_writeDataset(stt%xi,group,trim(prm%output(ou)), & + 'resistance against plastic slip','Pa',prm%systems_sl) case ('chi') - call results_writeDataset(stt%chi,group,trim(prm%output(ou)), & - 'back stress','Pa',prm%systems_sl) + call result_writeDataset(stt%chi,group,trim(prm%output(ou)), & + 'back stress','Pa',prm%systems_sl) case ('sgn(gamma)') - call results_writeDataset(int(stt%sgn_gamma),group,trim(prm%output(ou)), & - 'sense of shear','1',prm%systems_sl) + call result_writeDataset(int(stt%sgn_gamma),group,trim(prm%output(ou)), & + 'sense of shear','1',prm%systems_sl) case ('chi_0') - call results_writeDataset(stt%chi_0,group,trim(prm%output(ou)), & - 'back stress at last switch of stress sense','Pa',prm%systems_sl) + call result_writeDataset(stt%chi_0,group,trim(prm%output(ou)), & + 'back stress at last switch of stress sense','Pa',prm%systems_sl) case ('gamma_0') - call results_writeDataset(stt%gamma_0,group,trim(prm%output(ou)), & - 'plastic shear at last switch of stress sense','1',prm%systems_sl) + call result_writeDataset(stt%gamma_0,group,trim(prm%output(ou)), & + 'plastic shear at last switch of stress sense','1',prm%systems_sl) case ('gamma') - call results_writeDataset(stt%gamma,group,trim(prm%output(ou)), & - 'plastic shear','1',prm%systems_sl) + call result_writeDataset(stt%gamma,group,trim(prm%output(ou)), & + 'plastic shear','1',prm%systems_sl) end select end do end associate -end subroutine plastic_kinehardening_results +end subroutine plastic_kinehardening_result !-------------------------------------------------------------------------------------------------- diff --git a/src/phase_mechanical_plastic_none.f90 b/src/phase_mechanical_plastic_none.f90 index 50b4b4cbc..401b52102 100644 --- a/src/phase_mechanical_plastic_none.f90 +++ b/src/phase_mechanical_plastic_none.f90 @@ -17,7 +17,7 @@ module function plastic_none_init() result(myPlasticity) logical, dimension(:), allocatable :: myPlasticity integer :: & ph - class(tNode), pointer :: & + type(tDict), pointer :: & phases @@ -27,7 +27,8 @@ module function plastic_none_init() result(myPlasticity) print'(/,1x,a)', '<<<+- phase:mechanical:plastic:none init -+>>>' print'(/,a,i0)', ' # phases: ',count(myPlasticity); flush(IO_STDOUT) - phases => config_material%get('phase') + + phases => config_material%get_dict('phase') do ph = 1, phases%length if (.not. myPlasticity(ph)) cycle call phase_allocateState(plasticState(ph),count(material_phaseID == ph),0,0,0) diff --git a/src/phase_mechanical_plastic_nonlocal.f90 b/src/phase_mechanical_plastic_nonlocal.f90 index 4995f15d2..841e291e9 100644 --- a/src/phase_mechanical_plastic_nonlocal.f90 +++ b/src/phase_mechanical_plastic_nonlocal.f90 @@ -115,6 +115,8 @@ submodule(phase:plastic) nonlocal sum_N_sl = 0 integer, dimension(:), allocatable :: & colinearSystem !< colinear system to the active slip system (only valid for fcc!) + character(len=:), allocatable :: & + isotropic_bound character(len=pStringLen), dimension(:), allocatable :: & output logical :: & @@ -186,11 +188,10 @@ module function plastic_nonlocal_init() result(myPlasticity) s, t, l real(pReal), dimension(:), allocatable :: & a - character(len=pStringLen) :: & - extmsg = '' + character(len=:), allocatable :: extmsg type(tInitialParameters) :: & ini - class(tNode), pointer :: & + type(tDict), pointer :: & phases, & phase, & mech, & @@ -213,16 +214,15 @@ module function plastic_nonlocal_init() result(myPlasticity) print'( 1x,a)', 'http://publications.rwth-aachen.de/record/229993' - phases => config_material%get('phase') - + phases => config_material%get_dict('phase') allocate(geom(phases%length)) - allocate(param(phases%length)) allocate(state(phases%length)) allocate(state0(phases%length)) allocate(dotState(phases%length)) allocate(deltaState(phases%length)) allocate(dependentState(phases%length)) + extmsg = '' do ph = 1, phases%length if (.not. myPlasticity(ph)) cycle @@ -230,9 +230,9 @@ module function plastic_nonlocal_init() result(myPlasticity) associate(prm => param(ph), dot => dotState(ph), stt => state(ph), & st0 => state0(ph), del => deltaState(ph), dst => dependentState(ph)) - phase => phases%get(ph) - mech => phase%get('mechanical') - pl => mech%get('plastic') + phase => phases%get_dict(ph) + mech => phase%get_dict('mechanical') + pl => mech%get_dict('plastic') plasticState(ph)%nonlocal = pl%get_asBool('flux',defaultVal=.True.) #if defined (__GFORTRAN__) @@ -241,6 +241,7 @@ module function plastic_nonlocal_init() result(myPlasticity) prm%output = pl%get_as1dString('output',defaultVal=emptyStringArray) #endif + prm%isotropic_bound = pl%get_asString('isotropic_bound',defaultVal='isostrain') prm%atol_rho = pl%get_asFloat('atol_rho',defaultVal=1.0_pReal) ini%N_sl = pl%get_as1dInt('N_sl',defaultVal=emptyIntArray) @@ -251,7 +252,7 @@ module function plastic_nonlocal_init() result(myPlasticity) if (phase_lattice(ph) == 'cI') then a = pl%get_as1dFloat('a_nonSchmid',defaultVal = emptyRealArray) - if(size(a) > 0) prm%nonSchmidActive = .true. + if (size(a) > 0) prm%nonSchmidActive = .true. prm%P_nS_pos = lattice_nonSchmidMatrix(ini%N_sl,a,+1) prm%P_nS_neg = lattice_nonSchmidMatrix(ini%N_sl,a,-1) else @@ -416,7 +417,7 @@ module function plastic_nonlocal_init() result(myPlasticity) allocate(geom(ph)%IPcoordinates(3,Nmembers)) call storeGeometry(ph) - if(plasticState(ph)%nonlocal .and. .not. allocated(IPneighborhood)) & + if (plasticState(ph)%nonlocal .and. .not. allocated(IPneighborhood)) & call IO_error(212,ext_msg='IPneighborhood does not exist') st0%rho => plasticState(ph)%state0 (0*prm%sum_N_sl+1:10*prm%sum_N_sl,:) @@ -485,7 +486,7 @@ module function plastic_nonlocal_init() result(myPlasticity) dot%gamma => plasticState(ph)%dotState (10*prm%sum_N_sl + 1:11*prm%sum_N_sl,1:Nmembers) del%gamma => plasticState(ph)%deltaState (10*prm%sum_N_sl + 1:11*prm%sum_N_sl,1:Nmembers) plasticState(ph)%atol(10*prm%sum_N_sl+1:11*prm%sum_N_sl ) = pl%get_asFloat('atol_gamma', defaultVal = 1.0e-6_pReal) - if(any(plasticState(ph)%atol(10*prm%sum_N_sl+1:11*prm%sum_N_sl) < 0.0_pReal)) & + if (any(plasticState(ph)%atol(10*prm%sum_N_sl+1:11*prm%sum_N_sl) < 0.0_pReal)) & extmsg = trim(extmsg)//' atol_gamma' stt%rho_forest => plasticState(ph)%state (11*prm%sum_N_sl + 1:12*prm%sum_N_sl,1:Nmembers) @@ -518,9 +519,9 @@ module function plastic_nonlocal_init() result(myPlasticity) do ph = 1, phases%length - if(.not. myPlasticity(ph)) cycle + if (.not. myPlasticity(ph)) cycle - phase => phases%get(ph) + phase => phases%get_dict(ph) Nmembers = count(material_phaseID == ph) l = 0 do t = 1,4 @@ -609,8 +610,8 @@ module subroutine nonlocal_dependentState(ph, en) associate(prm => param(ph),dst => dependentState(ph), stt => state(ph)) - mu = elastic_mu(ph,en) - nu = elastic_nu(ph,en) + mu = elastic_mu(ph,en,prm%isotropic_bound) + nu = elastic_nu(ph,en,prm%isotropic_bound) rho = getRho(ph,en) stt%rho_forest(:,en) = matmul(prm%forestProjection_Edge, sum(abs(rho(:,edg)),2)) & @@ -880,8 +881,8 @@ module subroutine plastic_nonlocal_deltaState(Mp,ph,en) associate(prm => param(ph),dst => dependentState(ph),del => deltaState(ph)) - mu = elastic_mu(ph,en) - nu = elastic_nu(ph,en) + mu = elastic_mu(ph,en,prm%isotropic_bound) + nu = elastic_nu(ph,en,prm%isotropic_bound) !*** shortcut to state variables forall (s = 1:prm%sum_N_sl, t = 1:4) v(s,t) = plasticState(ph)%state(iV(s,t,ph),en) @@ -994,8 +995,8 @@ module subroutine nonlocal_dotState(Mp,timestep, & associate(prm => param(ph), dst => dependentState(ph), dot => dotState(ph), stt => state(ph)) - mu = elastic_mu(ph,en) - nu = elastic_nu(ph,en) + mu = elastic_mu(ph,en,prm%isotropic_bound) + nu = elastic_nu(ph,en,prm%isotropic_bound) Temperature = thermal_T(ph,en) tau = 0.0_pReal @@ -1476,7 +1477,7 @@ end subroutine plastic_nonlocal_updateCompatibility !-------------------------------------------------------------------------------------------------- !> @brief Write results to HDF5 output file. !-------------------------------------------------------------------------------------------------- -module subroutine plastic_nonlocal_results(ph,group) +module subroutine plastic_nonlocal_result(ph,group) integer, intent(in) :: ph character(len=*),intent(in) :: group @@ -1490,63 +1491,63 @@ module subroutine plastic_nonlocal_results(ph,group) select case(trim(prm%output(ou))) case('rho_u_ed_pos') - call results_writeDataset(stt%rho_sgl_mob_edg_pos,group,trim(prm%output(ou)), & - 'positive mobile edge density','1/m²', prm%systems_sl) + call result_writeDataset(stt%rho_sgl_mob_edg_pos,group,trim(prm%output(ou)), & + 'positive mobile edge density','1/m²', prm%systems_sl) case('rho_b_ed_pos') - call results_writeDataset(stt%rho_sgl_imm_edg_pos,group,trim(prm%output(ou)), & - 'positive immobile edge density','1/m²', prm%systems_sl) + call result_writeDataset(stt%rho_sgl_imm_edg_pos,group,trim(prm%output(ou)), & + 'positive immobile edge density','1/m²', prm%systems_sl) case('rho_u_ed_neg') - call results_writeDataset(stt%rho_sgl_mob_edg_neg,group,trim(prm%output(ou)), & - 'negative mobile edge density','1/m²', prm%systems_sl) + call result_writeDataset(stt%rho_sgl_mob_edg_neg,group,trim(prm%output(ou)), & + 'negative mobile edge density','1/m²', prm%systems_sl) case('rho_b_ed_neg') - call results_writeDataset(stt%rho_sgl_imm_edg_neg,group,trim(prm%output(ou)), & - 'negative immobile edge density','1/m²', prm%systems_sl) + call result_writeDataset(stt%rho_sgl_imm_edg_neg,group,trim(prm%output(ou)), & + 'negative immobile edge density','1/m²', prm%systems_sl) case('rho_d_ed') - call results_writeDataset(stt%rho_dip_edg,group,trim(prm%output(ou)), & - 'edge dipole density','1/m²', prm%systems_sl) + call result_writeDataset(stt%rho_dip_edg,group,trim(prm%output(ou)), & + 'edge dipole density','1/m²', prm%systems_sl) case('rho_u_sc_pos') - call results_writeDataset(stt%rho_sgl_mob_scr_pos,group,trim(prm%output(ou)), & - 'positive mobile screw density','1/m²', prm%systems_sl) + call result_writeDataset(stt%rho_sgl_mob_scr_pos,group,trim(prm%output(ou)), & + 'positive mobile screw density','1/m²', prm%systems_sl) case('rho_b_sc_pos') - call results_writeDataset(stt%rho_sgl_imm_scr_pos,group,trim(prm%output(ou)), & - 'positive immobile screw density','1/m²', prm%systems_sl) + call result_writeDataset(stt%rho_sgl_imm_scr_pos,group,trim(prm%output(ou)), & + 'positive immobile screw density','1/m²', prm%systems_sl) case('rho_u_sc_neg') - call results_writeDataset(stt%rho_sgl_mob_scr_neg,group,trim(prm%output(ou)), & - 'negative mobile screw density','1/m²', prm%systems_sl) + call result_writeDataset(stt%rho_sgl_mob_scr_neg,group,trim(prm%output(ou)), & + 'negative mobile screw density','1/m²', prm%systems_sl) case('rho_b_sc_neg') - call results_writeDataset(stt%rho_sgl_imm_scr_neg,group,trim(prm%output(ou)), & - 'negative immobile screw density','1/m²', prm%systems_sl) + call result_writeDataset(stt%rho_sgl_imm_scr_neg,group,trim(prm%output(ou)), & + 'negative immobile screw density','1/m²', prm%systems_sl) case('rho_d_sc') - call results_writeDataset(stt%rho_dip_scr,group,trim(prm%output(ou)), & - 'screw dipole density','1/m²', prm%systems_sl) + call result_writeDataset(stt%rho_dip_scr,group,trim(prm%output(ou)), & + 'screw dipole density','1/m²', prm%systems_sl) case('rho_f') - call results_writeDataset(stt%rho_forest,group,trim(prm%output(ou)), & - 'forest density','1/m²', prm%systems_sl) + call result_writeDataset(stt%rho_forest,group,trim(prm%output(ou)), & + 'forest density','1/m²', prm%systems_sl) case('v_ed_pos') - call results_writeDataset(stt%v_edg_pos,group,trim(prm%output(ou)), & - 'positive edge velocity','m/s', prm%systems_sl) + call result_writeDataset(stt%v_edg_pos,group,trim(prm%output(ou)), & + 'positive edge velocity','m/s', prm%systems_sl) case('v_ed_neg') - call results_writeDataset(stt%v_edg_neg,group,trim(prm%output(ou)), & - 'negative edge velocity','m/s', prm%systems_sl) + call result_writeDataset(stt%v_edg_neg,group,trim(prm%output(ou)), & + 'negative edge velocity','m/s', prm%systems_sl) case('v_sc_pos') - call results_writeDataset(stt%v_scr_pos,group,trim(prm%output(ou)), & - 'positive srew velocity','m/s', prm%systems_sl) + call result_writeDataset(stt%v_scr_pos,group,trim(prm%output(ou)), & + 'positive srew velocity','m/s', prm%systems_sl) case('v_sc_neg') - call results_writeDataset(stt%v_scr_neg,group,trim(prm%output(ou)), & - 'negative screw velocity','m/s', prm%systems_sl) + call result_writeDataset(stt%v_scr_neg,group,trim(prm%output(ou)), & + 'negative screw velocity','m/s', prm%systems_sl) case('gamma') - call results_writeDataset(stt%gamma,group,trim(prm%output(ou)), & - 'plastic shear','1', prm%systems_sl) + call result_writeDataset(stt%gamma,group,trim(prm%output(ou)), & + 'plastic shear','1', prm%systems_sl) case('tau_pass') - call results_writeDataset(dst%tau_pass,group,trim(prm%output(ou)), & - 'passing stress for slip','Pa', prm%systems_sl) + call result_writeDataset(dst%tau_pass,group,trim(prm%output(ou)), & + 'passing stress for slip','Pa', prm%systems_sl) end select end do end associate -end subroutine plastic_nonlocal_results +end subroutine plastic_nonlocal_result !-------------------------------------------------------------------------------------------------- @@ -1783,6 +1784,6 @@ subroutine storeGeometry(ph) end do end do -end subroutine +end subroutine storeGeometry end submodule nonlocal diff --git a/src/phase_mechanical_plastic_phenopowerlaw.f90 b/src/phase_mechanical_plastic_phenopowerlaw.f90 index f0dc04869..047aeed4c 100644 --- a/src/phase_mechanical_plastic_phenopowerlaw.f90 +++ b/src/phase_mechanical_plastic_phenopowerlaw.f90 @@ -90,9 +90,8 @@ module function plastic_phenopowerlaw_init() result(myPlasticity) xi_0_sl, & !< initial critical shear stress for slip xi_0_tw, & !< initial critical shear stress for twin a !< non-Schmid coefficients - character(len=pStringLen) :: & - extmsg = '' - class(tNode), pointer :: & + character(len=:), allocatable :: extmsg + type(tDict), pointer :: & phases, & phase, & mech, & @@ -100,16 +99,17 @@ module function plastic_phenopowerlaw_init() result(myPlasticity) myPlasticity = plastic_active('phenopowerlaw') - if(count(myPlasticity) == 0) return + if (count(myPlasticity) == 0) return print'(/,1x,a)', '<<<+- phase:mechanical:plastic:phenopowerlaw init -+>>>' print'(/,a,i0)', ' # phases: ',count(myPlasticity); flush(IO_STDOUT) - phases => config_material%get('phase') + phases => config_material%get_dict('phase') allocate(param(phases%length)) allocate(indexDotState(phases%length)) allocate(state(phases%length)) + extmsg = '' do ph = 1, phases%length if (.not. myPlasticity(ph)) cycle @@ -117,9 +117,9 @@ module function plastic_phenopowerlaw_init() result(myPlasticity) associate(prm => param(ph), stt => state(ph), & idx_dot => indexDotState(ph)) - phase => phases%get(ph) - mech => phase%get('mechanical') - pl => mech%get('plastic') + phase => phases%get_dict(ph) + mech => phase%get_dict('mechanical') + pl => mech%get_dict('plastic') !-------------------------------------------------------------------------------------------------- ! slip related parameters @@ -131,7 +131,7 @@ module function plastic_phenopowerlaw_init() result(myPlasticity) if (phase_lattice(ph) == 'cI') then a = pl%get_as1dFloat('a_nonSchmid',defaultVal=emptyRealArray) - if(size(a) > 0) prm%nonSchmidActive = .true. + if (size(a) > 0) prm%nonSchmidActive = .true. prm%P_nS_pos = lattice_nonSchmidMatrix(N_sl,a,+1) prm%P_nS_neg = lattice_nonSchmidMatrix(N_sl,a,-1) else @@ -243,7 +243,7 @@ module function plastic_phenopowerlaw_init() result(myPlasticity) stt%xi_sl => plasticState(ph)%state(startIndex:endIndex,:) stt%xi_sl = spread(xi_0_sl, 2, Nmembers) plasticState(ph)%atol(startIndex:endIndex) = pl%get_asFloat('atol_xi',defaultVal=1.0_pReal) - if(any(plasticState(ph)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' atol_xi' + if (any(plasticState(ph)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' atol_xi' startIndex = endIndex + 1 endIndex = endIndex + prm%sum_N_tw @@ -257,7 +257,7 @@ module function plastic_phenopowerlaw_init() result(myPlasticity) idx_dot%gamma_sl = [startIndex,endIndex] stt%gamma_sl => plasticState(ph)%state(startIndex:endIndex,:) plasticState(ph)%atol(startIndex:endIndex) = pl%get_asFloat('atol_gamma',defaultVal=1.0e-6_pReal) - if(any(plasticState(ph)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' atol_gamma' + if (any(plasticState(ph)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' atol_gamma' startIndex = endIndex + 1 endIndex = endIndex + prm%sum_N_tw @@ -347,8 +347,7 @@ module function phenopowerlaw_dotState(Mp,ph,en) result(dotState) sumF real(pReal), dimension(param(ph)%sum_N_sl) :: & dot_gamma_sl_pos,dot_gamma_sl_neg, & - right_SlipSlip - + left_SlipSlip associate(prm => param(ph), stt => state(ph), & dot_xi_sl => dotState(indexDotState(ph)%xi_sl(1):indexDotState(ph)%xi_sl(2)), & @@ -356,17 +355,17 @@ module function phenopowerlaw_dotState(Mp,ph,en) result(dotState) dot_gamma_sl => dotState(indexDotState(ph)%gamma_sl(1):indexDotState(ph)%gamma_sl(2)), & dot_gamma_tw => dotState(indexDotState(ph)%gamma_tw(1):indexDotState(ph)%gamma_tw(2))) - call kinetics_sl(Mp,ph,en,dot_gamma_sl_pos,dot_gamma_sl_neg) + call kinetics_sl(Mp,ph,en, dot_gamma_sl_pos,dot_gamma_sl_neg) dot_gamma_sl = abs(dot_gamma_sl_pos+dot_gamma_sl_neg) - call kinetics_tw(Mp,ph,en,dot_gamma_tw) - + call kinetics_tw(Mp,ph,en, dot_gamma_tw) sumF = sum(stt%gamma_tw(:,en)/prm%gamma_char) - xi_sl_sat_offset = prm%f_sat_sl_tw*sqrt(sumF) - right_SlipSlip = sign(abs(1.0_pReal-stt%xi_sl(:,en) / (prm%xi_inf_sl+xi_sl_sat_offset))**prm%a_sl, & - 1.0_pReal-stt%xi_sl(:,en) / (prm%xi_inf_sl+xi_sl_sat_offset)) - dot_xi_sl = prm%h_0_sl_sl * (1.0_pReal + prm%c_1*sumF** prm%c_2) * (1.0_pReal + prm%h_int) & - * matmul(prm%h_sl_sl,dot_gamma_sl*right_SlipSlip) & + xi_sl_sat_offset = prm%f_sat_sl_tw*sqrt(sumF) + left_SlipSlip = sign(abs(1.0_pReal-stt%xi_sl(:,en) / (prm%xi_inf_sl+xi_sl_sat_offset))**prm%a_sl, & + 1.0_pReal-stt%xi_sl(:,en) / (prm%xi_inf_sl+xi_sl_sat_offset)) + + dot_xi_sl = prm%h_0_sl_sl * (1.0_pReal + prm%c_1 * sumF**prm%c_2) * (1.0_pReal + prm%h_int) & + * left_SlipSlip * matmul(prm%h_sl_sl,dot_gamma_sl) & + matmul(prm%h_sl_tw,dot_gamma_tw) dot_xi_tw = prm%h_0_tw_sl * sum(stt%gamma_sl(:,en))**prm%c_3 & @@ -381,7 +380,7 @@ end function phenopowerlaw_dotState !-------------------------------------------------------------------------------------------------- !> @brief Write results to HDF5 output file. !-------------------------------------------------------------------------------------------------- -module subroutine plastic_phenopowerlaw_results(ph,group) +module subroutine plastic_phenopowerlaw_result(ph,group) integer, intent(in) :: ph character(len=*), intent(in) :: group @@ -396,18 +395,18 @@ module subroutine plastic_phenopowerlaw_results(ph,group) select case(trim(prm%output(ou))) case('xi_sl') - call results_writeDataset(stt%xi_sl,group,trim(prm%output(ou)), & - 'resistance against plastic slip','Pa',prm%systems_sl) + call result_writeDataset(stt%xi_sl,group,trim(prm%output(ou)), & + 'resistance against plastic slip','Pa',prm%systems_sl) case('gamma_sl') - call results_writeDataset(stt%gamma_sl,group,trim(prm%output(ou)), & - 'plastic shear','1',prm%systems_sl) + call result_writeDataset(stt%gamma_sl,group,trim(prm%output(ou)), & + 'plastic shear','1',prm%systems_sl) case('xi_tw') - call results_writeDataset(stt%xi_tw,group,trim(prm%output(ou)), & - 'resistance against twinning','Pa',prm%systems_tw) + call result_writeDataset(stt%xi_tw,group,trim(prm%output(ou)), & + 'resistance against twinning','Pa',prm%systems_tw) case('gamma_tw') - call results_writeDataset(stt%gamma_tw,group,trim(prm%output(ou)), & - 'twinning shear','1',prm%systems_tw) + call result_writeDataset(stt%gamma_tw,group,trim(prm%output(ou)), & + 'twinning shear','1',prm%systems_tw) end select @@ -415,7 +414,7 @@ module subroutine plastic_phenopowerlaw_results(ph,group) end associate -end subroutine plastic_phenopowerlaw_results +end subroutine plastic_phenopowerlaw_result !-------------------------------------------------------------------------------------------------- diff --git a/src/phase_thermal.f90 b/src/phase_thermal.f90 index ed374e142..3f99c84f9 100644 --- a/src/phase_thermal.f90 +++ b/src/phase_thermal.f90 @@ -76,11 +76,14 @@ contains !---------------------------------------------------------------------------------------------- module subroutine thermal_init(phases) - class(tNode), pointer :: & + type(tDict), pointer :: & phases - class(tNode), pointer :: & - phase, thermal, sources + type(tDict), pointer :: & + phase, & + thermal + type(tList), pointer :: & + sources integer :: & ph, so, & @@ -89,8 +92,8 @@ module subroutine thermal_init(phases) print'(/,1x,a)', '<<<+- phase:thermal init -+>>>' - allocate(current(phases%length)) + allocate(current(phases%length)) allocate(thermalState(phases%length)) allocate(thermal_Nsources(phases%length),source = 0) allocate(param(phases%length)) @@ -99,8 +102,8 @@ module subroutine thermal_init(phases) Nmembers = count(material_phaseID == ph) allocate(current(ph)%T(Nmembers),source=T_ROOM) allocate(current(ph)%dot_T(Nmembers),source=0.0_pReal) - phase => phases%get(ph) - thermal => phase%get('thermal',defaultVal=emptyDict) + phase => phases%get_dict(ph) + thermal => phase%get_dict('thermal',defaultVal=emptyDict) ! ToDo: temperature dependency of K and C_p if (thermal%length > 0) then @@ -114,7 +117,7 @@ module subroutine thermal_init(phases) #else param(ph)%output = thermal%get_as1dString('output',defaultVal=emptyStringArray) #endif - sources => thermal%get('source',defaultVal=emptyList) + sources => thermal%get_list('source',defaultVal=emptyList) thermal_Nsources(ph) = sources%length else thermal_Nsources(ph) = 0 @@ -365,21 +368,23 @@ function thermal_active(source_label,src_length) result(active_source) integer, intent(in) :: src_length !< max. number of sources in system logical, dimension(:,:), allocatable :: active_source - class(tNode), pointer :: & + type(tDict), pointer :: & phases, & phase, & - sources, thermal, & + thermal, & src + type(tList), pointer :: & + sources integer :: p,s - phases => config_material%get('phase') + phases => config_material%get_dict('phase') allocate(active_source(src_length,phases%length), source = .false. ) do p = 1, phases%length - phase => phases%get(p) - thermal => phase%get('thermal',defaultVal=emptyDict) - sources => thermal%get('source',defaultVal=emptyList) + phase => phases%get_dict(p) + thermal => phase%get_dict('thermal',defaultVal=emptyDict) + sources => thermal%get_list('source',defaultVal=emptyList) do s = 1, sources%length - src => sources%get(s) + src => sources%get_dict(s) active_source(s,p) = src%get_asString('type') == source_label end do end do @@ -389,9 +394,9 @@ end function thermal_active !---------------------------------------------------------------------------------------------- -!< @brief writes thermal sources results to HDF5 output file +!< @brief Write thermal sources results to HDF5 output file. !---------------------------------------------------------------------------------------------- -module subroutine thermal_results(group,ph) +module subroutine thermal_result(group,ph) character(len=*), intent(in) :: group integer, intent(in) :: ph @@ -401,20 +406,20 @@ module subroutine thermal_results(group,ph) if (.not. allocated(param(ph)%output)) return - call results_closeGroup(results_addGroup(group//'thermal')) + call result_closeGroup(result_addGroup(group//'thermal')) do ou = 1, size(param(ph)%output) select case(trim(param(ph)%output(ou))) case ('T') - call results_writeDataset(current(ph)%T,group//'thermal','T', 'temperature','K') + call result_writeDataset(current(ph)%T,group//'thermal','T', 'temperature','K') end select end do -end subroutine thermal_results +end subroutine thermal_result end submodule thermal diff --git a/src/phase_thermal_dissipation.f90 b/src/phase_thermal_dissipation.f90 index 898b32706..711d278de 100644 --- a/src/phase_thermal_dissipation.f90 +++ b/src/phase_thermal_dissipation.f90 @@ -26,32 +26,35 @@ module function dissipation_init(source_length) result(mySources) integer, intent(in) :: source_length logical, dimension(:,:), allocatable :: mySources - class(tNode), pointer :: & + type(tDict), pointer :: & phases, & phase, & - sources, thermal, & + thermal, & src + class(tList), pointer :: & + sources integer :: so,Nmembers,ph mySources = thermal_active('dissipation',source_length) - if(count(mySources) == 0) return + if (count(mySources) == 0) return + print'(/,1x,a)', '<<<+- phase:thermal:dissipation init -+>>>' print'(/,a,i2)', ' # phases: ',count(mySources); flush(IO_STDOUT) - phases => config_material%get('phase') + phases => config_material%get_dict('phase') allocate(param(phases%length)) do ph = 1, phases%length - phase => phases%get(ph) + phase => phases%get_dict(ph) if (count(mySources(:,ph)) == 0) cycle !ToDo: error if > 1 - thermal => phase%get('thermal') - sources => thermal%get('source') + thermal => phase%get_dict('thermal') + sources => thermal%get_list('source') do so = 1, sources%length if (mySources(so,ph)) then associate(prm => param(ph)) - src => sources%get(so) + src => sources%get_dict(so) prm%kappa = src%get_asFloat('kappa') Nmembers = count(material_phaseID == ph) diff --git a/src/phase_thermal_externalheat.f90 b/src/phase_thermal_externalheat.f90 index f7a8296a8..3dccc5791 100644 --- a/src/phase_thermal_externalheat.f90 +++ b/src/phase_thermal_externalheat.f90 @@ -11,11 +11,7 @@ submodule(phase:thermal) externalheat source_thermal_externalheat_offset !< which source is my current thermal dissipation mechanism? type :: tParameters !< container type for internal constitutive parameters - real(pReal), dimension(:), allocatable :: & - t_n, & - f_T - integer :: & - nIntervals + type(tTable) :: f end type tParameters type(tParameters), dimension(:), allocatable :: param !< containers of constitutive parameters (len Ninstances) @@ -33,39 +29,39 @@ module function externalheat_init(source_length) result(mySources) integer, intent(in) :: source_length logical, dimension(:,:), allocatable :: mySources - class(tNode), pointer :: & + type(tDict), pointer :: & phases, & phase, & - sources, thermal, & + thermal, & src + type(tList), pointer :: & + sources integer :: so,Nmembers,ph mySources = thermal_active('externalheat',source_length) - if(count(mySources) == 0) return + if (count(mySources) == 0) return + print'(/,1x,a)', '<<<+- phase:thermal:externalheat init -+>>>' print'(/,a,i2)', ' # phases: ',count(mySources); flush(IO_STDOUT) - phases => config_material%get('phase') + phases => config_material%get_dict('phase') allocate(param(phases%length)) allocate(source_thermal_externalheat_offset (phases%length), source=0) do ph = 1, phases%length - phase => phases%get(ph) + phase => phases%get_dict(ph) if (count(mySources(:,ph)) == 0) cycle - thermal => phase%get('thermal') - sources => thermal%get('source') + thermal => phase%get_dict('thermal') + sources => thermal%get_list('source') do so = 1, sources%length if (mySources(so,ph)) then source_thermal_externalheat_offset(ph) = so associate(prm => param(ph)) - src => sources%get(so) + src => sources%get_dict(so) - prm%t_n = src%get_as1dFloat('t_n') - prm%nIntervals = size(prm%t_n) - 1 - - prm%f_T = src%get_as1dFloat('f_T',requiredSize = size(prm%t_n)) + prm%f = table(src,'t','f') Nmembers = count(material_phaseID == ph) call phase_allocateState(thermalState(ph)%p(so),Nmembers,1,1,0) @@ -109,23 +105,13 @@ module function externalheat_f_T(ph,en) result(f_T) f_T integer :: & - so, interval - real(pReal) :: & - frac_time + so + so = source_thermal_externalheat_offset(ph) associate(prm => param(ph)) - do interval = 1, prm%nIntervals ! scan through all rate segments - frac_time = (thermalState(ph)%p(so)%state(1,en) - prm%t_n(interval)) & - / (prm%t_n(interval+1) - prm%t_n(interval)) ! fractional time within segment - if ( (frac_time < 0.0_pReal .and. interval == 1) & - .or. (frac_time >= 1.0_pReal .and. interval == prm%nIntervals) & - .or. (frac_time >= 0.0_pReal .and. frac_time < 1.0_pReal) ) & - f_T = prm%f_T(interval ) * (1.0_pReal - frac_time) + & - prm%f_T(interval+1) * frac_time ! interpolate heat rate between segment boundaries... - ! ...or extrapolate if outside of bounds - end do + f_T = prm%f%at(thermalState(ph)%p(so)%state(1,en)) end associate end function externalheat_f_T diff --git a/src/polynomials.f90 b/src/polynomials.f90 index eeb4152f2..2240616f7 100644 --- a/src/polynomials.f90 +++ b/src/polynomials.f90 @@ -1,6 +1,6 @@ !-------------------------------------------------------------------------------------------------- !> @author Martin Diehl, KU Leuven -!> @brief Polynomial representation for variable data +!> @brief Polynomial representation for variable data. !-------------------------------------------------------------------------------------------------- module polynomials use prec @@ -19,8 +19,8 @@ module polynomials end type tPolynomial interface polynomial - module procedure polynomial_from_dict module procedure polynomial_from_coef + module procedure polynomial_from_dict end interface polynomial public :: & @@ -43,7 +43,7 @@ end subroutine polynomials_init !-------------------------------------------------------------------------------------------------- -!> @brief Initialize a Polynomial from Coefficients. +!> @brief Initialize a polynomial from coefficients. !-------------------------------------------------------------------------------------------------- pure function polynomial_from_coef(coef,x_ref) result(p) @@ -59,7 +59,7 @@ end function polynomial_from_coef !-------------------------------------------------------------------------------------------------- -!> @brief Initialize a Polynomial from a Dictionary with Coefficients. +!> @brief Initialize a polynomial from a dictionary with coefficients. !-------------------------------------------------------------------------------------------------- function polynomial_from_dict(dict,y,x) result(p) @@ -93,7 +93,7 @@ end function polynomial_from_dict !-------------------------------------------------------------------------------------------------- -!> @brief Evaluate a Polynomial. +!> @brief Evaluate a polynomial. !> @details https://nvlpubs.nist.gov/nistpubs/jres/71b/jresv71bn1p11_a1b.pdf (eq. 1.2) !-------------------------------------------------------------------------------------------------- pure function eval(self,x) result(y) @@ -126,7 +126,7 @@ subroutine selfTest() real(pReal), dimension(5) :: coef integer :: i real(pReal) :: x_ref, x, y - class(tNode), pointer :: dict + type(tDict), pointer :: dict character(len=pStringLen), dimension(size(coef)) :: coef_s character(len=pStringLen) :: x_ref_s, x_s, YAML_s @@ -156,8 +156,8 @@ subroutine selfTest() 'C,T^3: '//trim(adjustl(coef_s(4)))//IO_EOL//& 'C,T^4: '//trim(adjustl(coef_s(5)))//IO_EOL//& 'T_ref: '//trim(adjustl(x_ref_s))//IO_EOL - Dict => YAML_parse_str(trim(YAML_s)) - p2 = polynomial(dict%asDict(),'C','T') + dict => YAML_parse_str_asDict(trim(YAML_s)) + p2 = polynomial(dict,'C','T') if (dNeq(p1%at(x),p2%at(x),1.0e-6_pReal)) error stop 'polynomials: init' y = coef(1)+coef(2)*(x-x_ref)+coef(3)*(x-x_ref)**2+coef(4)*(x-x_ref)**3+coef(5)*(x-x_ref)**4 if (dNeq(p1%at(x),y,1.0e-6_pReal)) error stop 'polynomials: eval(full)' @@ -165,29 +165,29 @@ subroutine selfTest() YAML_s = 'C: 0.0'//IO_EOL//& 'C,T: '//trim(adjustl(coef_s(2)))//IO_EOL//& 'T_ref: '//trim(adjustl(x_ref_s))//IO_EOL - Dict => YAML_parse_str(trim(YAML_s)) - p1 = polynomial(dict%asDict(),'C','T') + dict => YAML_parse_str_asDict(trim(YAML_s)) + p1 = polynomial(dict,'C','T') if (dNeq(p1%at(x_ref+x),-p1%at(x_ref-x),1.0e-10_pReal)) error stop 'polynomials: eval(linear)' YAML_s = 'C: 0.0'//IO_EOL//& 'C,T^2: '//trim(adjustl(coef_s(3)))//IO_EOL//& 'T_ref: '//trim(adjustl(x_ref_s))//IO_EOL - Dict => YAML_parse_str(trim(YAML_s)) - p1 = polynomial(dict%asDict(),'C','T') + dict => YAML_parse_str_asDict(trim(YAML_s)) + p1 = polynomial(dict,'C','T') if (dNeq(p1%at(x_ref+x),p1%at(x_ref-x),1e-10_pReal)) error stop 'polynomials: eval(quadratic)' YAML_s = 'Y: '//trim(adjustl(coef_s(1)))//IO_EOL//& 'Y,X^3: '//trim(adjustl(coef_s(2)))//IO_EOL//& 'X_ref: '//trim(adjustl(x_ref_s))//IO_EOL - Dict => YAML_parse_str(trim(YAML_s)) - p1 = polynomial(dict%asDict(),'Y','X') + dict => YAML_parse_str_asDict(trim(YAML_s)) + p1 = polynomial(dict,'Y','X') if (dNeq(p1%at(x_ref+x)-coef(1),-(p1%at(x_ref-x)-coef(1)),1.0e-8_pReal)) error stop 'polynomials: eval(cubic)' YAML_s = 'Y: '//trim(adjustl(coef_s(1)))//IO_EOL//& 'Y,X^4: '//trim(adjustl(coef_s(2)))//IO_EOL//& 'X_ref: '//trim(adjustl(x_ref_s))//IO_EOL - Dict => YAML_parse_str(trim(YAML_s)) - p1 = polynomial(dict%asDict(),'Y','X') + dict => YAML_parse_str_asDict(trim(YAML_s)) + p1 = polynomial(dict,'Y','X') if (dNeq(p1%at(x_ref+x),p1%at(x_ref-x),1.0e-6_pReal)) error stop 'polynomials: eval(quartic)' diff --git a/src/prec.f90 b/src/prec.f90 index 963391c39..1ae7ec62d 100644 --- a/src/prec.f90 +++ b/src/prec.f90 @@ -23,8 +23,10 @@ module prec integer, parameter :: pI32 = selected_int_kind(9) !< number with at least up to +-1e9 (typically 32 bit) integer, parameter :: pI64 = selected_int_kind(18) !< number with at least up to +-1e18 (typically 64 bit) #ifdef PETSC - PetscInt, private :: dummy - integer, parameter :: pPETSCINT = kind(dummy) + PetscInt, private :: dummy_int + integer, parameter :: pPETSCINT = kind(dummy_int) + PetscScalar, private :: dummy_scalar + real(pReal), parameter, private :: pPETSCSCALAR = kind(dummy_scalar) #endif integer, parameter :: pSTRINGLEN = 256 !< default string length integer, parameter :: pPATHLEN = 4096 !< maximum length of a path name on linux @@ -253,6 +255,9 @@ subroutine selfTest() real(pReal), dimension(2) :: r +#ifdef PETSC + if (pReal /= pPETSCSCALAR) error stop 'PETSc and DAMASK scalar datatypes do not match' +#endif realloc_lhs_test = [1,2] if (any(realloc_lhs_test/=[1,2])) error stop 'LHS allocation' diff --git a/src/results.f90 b/src/result.f90 similarity index 70% rename from src/results.f90 rename to src/result.f90 index 17efc87e3..6c4f7de82 100644 --- a/src/results.f90 +++ b/src/result.f90 @@ -4,7 +4,7 @@ !> @author Jennifer Nastola, Max-Planck-Institut für Eisenforschung GmbH !> @author Martin Diehl, Max-Planck-Institut für Eisenforschung GmbH !-------------------------------------------------------------------------------------------------- -module results +module result use prec use parallelization use IO @@ -28,46 +28,46 @@ module results #endif private - integer(HID_T) :: resultsFile + integer(HID_T) :: resultFile - interface results_writeDataset - module procedure results_writeTensorDataset_real - module procedure results_writeVectorDataset_real - module procedure results_writeScalarDataset_real + interface result_writeDataset + module procedure result_writeTensorDataset_real + module procedure result_writeVectorDataset_real + module procedure result_writeScalarDataset_real - module procedure results_writeTensorDataset_int - module procedure results_writeVectorDataset_int - end interface results_writeDataset + module procedure result_writeTensorDataset_int + module procedure result_writeVectorDataset_int + end interface result_writeDataset - interface results_addAttribute - module procedure results_addAttribute_str - module procedure results_addAttribute_int - module procedure results_addAttribute_real + interface result_addAttribute + module procedure result_addAttribute_str + module procedure result_addAttribute_int + module procedure result_addAttribute_real - module procedure results_addAttribute_str_array - module procedure results_addAttribute_int_array - module procedure results_addAttribute_real_array - end interface results_addAttribute + module procedure result_addAttribute_str_array + module procedure result_addAttribute_int_array + module procedure result_addAttribute_real_array + end interface result_addAttribute public :: & - results_init, & - results_openJobFile, & - results_closeJobFile, & - results_addIncrement, & - results_finalizeIncrement, & - results_addGroup, & - results_openGroup, & - results_closeGroup, & - results_writeDataset, & - results_writeDataset_str, & - results_setLink, & - results_addAttribute, & - results_removeLink, & - results_mapping_phase, & - results_mapping_homogenization + result_init, & + result_openJobFile, & + result_closeJobFile, & + result_addIncrement, & + result_finalizeIncrement, & + result_addGroup, & + result_openGroup, & + result_closeGroup, & + result_writeDataset, & + result_writeDataset_str, & + result_setLink, & + result_addAttribute, & + result_removeLink, & + result_mapping_phase, & + result_mapping_homogenization contains -subroutine results_init(restart) +subroutine result_init(restart) logical, intent(in) :: restart @@ -76,68 +76,68 @@ subroutine results_init(restart) character(len=:), allocatable :: date - print'(/,1x,a)', '<<<+- results init -+>>>'; flush(IO_STDOUT) + print'(/,1x,a)', '<<<+- result init -+>>>'; flush(IO_STDOUT) print'(/,1x,a)', 'M. Diehl et al., Integrating Materials and Manufacturing Innovation 6(1):83–91, 2017' print'( 1x,a)', 'https://doi.org/10.1007/s40192-017-0084-5' if (.not. restart) then - resultsFile = HDF5_openFile(getSolverJobName()//'.hdf5','w') - call results_addAttribute('DADF5_version_major',0) - call results_addAttribute('DADF5_version_minor',14) + resultFile = HDF5_openFile(getSolverJobName()//'.hdf5','w') + call result_addAttribute('DADF5_version_major',0) + call result_addAttribute('DADF5_version_minor',14) call get_command_argument(0,commandLine) - call results_addAttribute('creator',trim(commandLine)//' '//DAMASKVERSION) - call results_addAttribute('created',now()) + call result_addAttribute('creator',trim(commandLine)//' '//DAMASKVERSION) + call result_addAttribute('created',now()) call get_command(commandLine) - call results_addAttribute('call',trim(commandLine)) - call results_closeGroup(results_addGroup('cell_to')) - call results_addAttribute('description','mappings to place data in space','cell_to') - call results_closeGroup(results_addGroup('setup')) - call results_addAttribute('description','input data used to run the simulation','setup') + call result_addAttribute('call',trim(commandLine)) + call result_closeGroup(result_addGroup('cell_to')) + call result_addAttribute('description','mappings to place data in space','cell_to') + call result_closeGroup(result_addGroup('setup')) + call result_addAttribute('description','input data used to run the simulation','setup') else date = now() - call results_openJobFile + call result_openJobFile call get_command(commandLine) - call results_addAttribute('call (restart at '//date//')',trim(commandLine)) - call H5Gmove_f(resultsFile,'setup','tmp',hdferr) - call results_addAttribute('description','input data used to run the simulation up to restart at '//date,'tmp') - call results_closeGroup(results_addGroup('setup')) - call results_addAttribute('description','input data used to run the simulation','setup') - call H5Gmove_f(resultsFile,'tmp','setup/previous',hdferr) + call result_addAttribute('call (restart at '//date//')',trim(commandLine)) + call H5Gmove_f(resultFile,'setup','tmp',hdferr) + call result_addAttribute('description','input data used to run the simulation up to restart at '//date,'tmp') + call result_closeGroup(result_addGroup('setup')) + call result_addAttribute('description','input data used to run the simulation','setup') + call H5Gmove_f(resultFile,'tmp','setup/previous',hdferr) end if - call results_closeJobFile + call result_closeJobFile -end subroutine results_init +end subroutine result_init !-------------------------------------------------------------------------------------------------- -!> @brief opens the results file to append data +!> @brief opens the result file to append data !-------------------------------------------------------------------------------------------------- -subroutine results_openJobFile(parallel) +subroutine result_openJobFile(parallel) logical, intent(in), optional :: parallel - resultsFile = HDF5_openFile(getSolverJobName()//'.hdf5','a',parallel) + resultFile = HDF5_openFile(getSolverJobName()//'.hdf5','a',parallel) -end subroutine results_openJobFile +end subroutine result_openJobFile !-------------------------------------------------------------------------------------------------- -!> @brief closes the results file +!> @brief closes the result file !-------------------------------------------------------------------------------------------------- -subroutine results_closeJobFile +subroutine result_closeJobFile - call HDF5_closeFile(resultsFile) + call HDF5_closeFile(resultFile) -end subroutine results_closeJobFile +end subroutine result_closeJobFile !-------------------------------------------------------------------------------------------------- !> @brief creates the group of increment and adds time as attribute to the file !-------------------------------------------------------------------------------------------------- -subroutine results_addIncrement(inc,time) +subroutine result_addIncrement(inc,time) integer, intent(in) :: inc real(pReal), intent(in) :: time @@ -146,97 +146,97 @@ subroutine results_addIncrement(inc,time) write(incChar,'(i10)') inc - call results_closeGroup(results_addGroup(trim('increment_'//trim(adjustl(incChar))))) - call results_setLink(trim('increment_'//trim(adjustl(incChar))),'current') - call results_addAttribute('t/s',time,trim('increment_'//trim(adjustl(incChar)))) + call result_closeGroup(result_addGroup(trim('increment_'//trim(adjustl(incChar))))) + call result_setLink(trim('increment_'//trim(adjustl(incChar))),'current') + call result_addAttribute('t/s',time,trim('increment_'//trim(adjustl(incChar)))) -end subroutine results_addIncrement +end subroutine result_addIncrement !-------------------------------------------------------------------------------------------------- !> @brief finalize increment !> @details remove soft link !-------------------------------------------------------------------------------------------------- -subroutine results_finalizeIncrement +subroutine result_finalizeIncrement - call results_removeLink('current') + call result_removeLink('current') -end subroutine results_finalizeIncrement +end subroutine result_finalizeIncrement !-------------------------------------------------------------------------------------------------- -!> @brief open a group from the results file +!> @brief open a group from the result file !-------------------------------------------------------------------------------------------------- -integer(HID_T) function results_openGroup(groupName) +integer(HID_T) function result_openGroup(groupName) character(len=*), intent(in) :: groupName - results_openGroup = HDF5_openGroup(resultsFile,groupName) + result_openGroup = HDF5_openGroup(resultFile,groupName) -end function results_openGroup +end function result_openGroup !-------------------------------------------------------------------------------------------------- -!> @brief adds a new group to the results file +!> @brief adds a new group to the result file !-------------------------------------------------------------------------------------------------- -integer(HID_T) function results_addGroup(groupName) +integer(HID_T) function result_addGroup(groupName) character(len=*), intent(in) :: groupName - results_addGroup = HDF5_addGroup(resultsFile,groupName) + result_addGroup = HDF5_addGroup(resultFile,groupName) -end function results_addGroup +end function result_addGroup !-------------------------------------------------------------------------------------------------- !> @brief close a group !-------------------------------------------------------------------------------------------------- -subroutine results_closeGroup(group_id) +subroutine result_closeGroup(group_id) integer(HID_T), intent(in) :: group_id call HDF5_closeGroup(group_id) -end subroutine results_closeGroup +end subroutine result_closeGroup !-------------------------------------------------------------------------------------------------- -!> @brief set link to object in results file +!> @brief set link to object in result file !-------------------------------------------------------------------------------------------------- -subroutine results_setLink(path,link) +subroutine result_setLink(path,link) character(len=*), intent(in) :: path, link - call HDF5_setLink(resultsFile,path,link) + call HDF5_setLink(resultFile,path,link) -end subroutine results_setLink +end subroutine result_setLink !-------------------------------------------------------------------------------------------------- -!> @brief Add a string attribute to an object in the results file. +!> @brief Add a string attribute to an object in the result file. !-------------------------------------------------------------------------------------------------- -subroutine results_addAttribute_str(attrLabel,attrValue,path) +subroutine result_addAttribute_str(attrLabel,attrValue,path) character(len=*), intent(in) :: attrLabel, attrValue character(len=*), intent(in), optional :: path if (present(path)) then - call HDF5_addAttribute(resultsFile,attrLabel, attrValue, path) + call HDF5_addAttribute(resultFile,attrLabel, attrValue, path) else - call HDF5_addAttribute(resultsFile,attrLabel, attrValue) + call HDF5_addAttribute(resultFile,attrLabel, attrValue) end if -end subroutine results_addAttribute_str +end subroutine result_addAttribute_str !-------------------------------------------------------------------------------------------------- -!> @brief Add an integer attribute an object in the results file. +!> @brief Add an integer attribute an object in the result file. !-------------------------------------------------------------------------------------------------- -subroutine results_addAttribute_int(attrLabel,attrValue,path) +subroutine result_addAttribute_int(attrLabel,attrValue,path) character(len=*), intent(in) :: attrLabel integer, intent(in) :: attrValue @@ -244,18 +244,18 @@ subroutine results_addAttribute_int(attrLabel,attrValue,path) if (present(path)) then - call HDF5_addAttribute(resultsFile,attrLabel, attrValue, path) + call HDF5_addAttribute(resultFile,attrLabel, attrValue, path) else - call HDF5_addAttribute(resultsFile,attrLabel, attrValue) + call HDF5_addAttribute(resultFile,attrLabel, attrValue) end if -end subroutine results_addAttribute_int +end subroutine result_addAttribute_int !-------------------------------------------------------------------------------------------------- -!> @brief Add a real attribute an object in the results file. +!> @brief Add a real attribute an object in the result file. !-------------------------------------------------------------------------------------------------- -subroutine results_addAttribute_real(attrLabel,attrValue,path) +subroutine result_addAttribute_real(attrLabel,attrValue,path) character(len=*), intent(in) :: attrLabel real(pReal), intent(in) :: attrValue @@ -263,18 +263,18 @@ subroutine results_addAttribute_real(attrLabel,attrValue,path) if (present(path)) then - call HDF5_addAttribute(resultsFile,attrLabel, attrValue, path) + call HDF5_addAttribute(resultFile,attrLabel, attrValue, path) else - call HDF5_addAttribute(resultsFile,attrLabel, attrValue) + call HDF5_addAttribute(resultFile,attrLabel, attrValue) end if -end subroutine results_addAttribute_real +end subroutine result_addAttribute_real !-------------------------------------------------------------------------------------------------- -!> @brief Add a string array attribute an object in the results file. +!> @brief Add a string array attribute an object in the result file. !-------------------------------------------------------------------------------------------------- -subroutine results_addAttribute_str_array(attrLabel,attrValue,path) +subroutine result_addAttribute_str_array(attrLabel,attrValue,path) character(len=*), intent(in) :: attrLabel character(len=*), intent(in), dimension(:) :: attrValue @@ -282,18 +282,18 @@ subroutine results_addAttribute_str_array(attrLabel,attrValue,path) if (present(path)) then - call HDF5_addAttribute(resultsFile,attrLabel, attrValue, path) + call HDF5_addAttribute(resultFile,attrLabel, attrValue, path) else - call HDF5_addAttribute(resultsFile,attrLabel, attrValue) + call HDF5_addAttribute(resultFile,attrLabel, attrValue) end if -end subroutine results_addAttribute_str_array +end subroutine result_addAttribute_str_array !-------------------------------------------------------------------------------------------------- -!> @brief Add an integer array attribute an object in the results file. +!> @brief Add an integer array attribute an object in the result file. !-------------------------------------------------------------------------------------------------- -subroutine results_addAttribute_int_array(attrLabel,attrValue,path) +subroutine result_addAttribute_int_array(attrLabel,attrValue,path) character(len=*), intent(in) :: attrLabel integer, intent(in), dimension(:) :: attrValue @@ -301,18 +301,18 @@ subroutine results_addAttribute_int_array(attrLabel,attrValue,path) if (present(path)) then - call HDF5_addAttribute(resultsFile,attrLabel, attrValue, path) + call HDF5_addAttribute(resultFile,attrLabel, attrValue, path) else - call HDF5_addAttribute(resultsFile,attrLabel, attrValue) + call HDF5_addAttribute(resultFile,attrLabel, attrValue) end if -end subroutine results_addAttribute_int_array +end subroutine result_addAttribute_int_array !-------------------------------------------------------------------------------------------------- -!> @brief Add a real array attribute an object in the results file. +!> @brief Add a real array attribute an object in the result file. !-------------------------------------------------------------------------------------------------- -subroutine results_addAttribute_real_array(attrLabel,attrValue,path) +subroutine result_addAttribute_real_array(attrLabel,attrValue,path) character(len=*), intent(in) :: attrLabel real(pReal), intent(in), dimension(:) :: attrValue @@ -320,51 +320,51 @@ subroutine results_addAttribute_real_array(attrLabel,attrValue,path) if (present(path)) then - call HDF5_addAttribute(resultsFile,attrLabel, attrValue, path) + call HDF5_addAttribute(resultFile,attrLabel, attrValue, path) else - call HDF5_addAttribute(resultsFile,attrLabel, attrValue) + call HDF5_addAttribute(resultFile,attrLabel, attrValue) end if -end subroutine results_addAttribute_real_array +end subroutine result_addAttribute_real_array !-------------------------------------------------------------------------------------------------- !> @brief remove link to an object !-------------------------------------------------------------------------------------------------- -subroutine results_removeLink(link) +subroutine result_removeLink(link) character(len=*), intent(in) :: link integer :: hdferr - call H5Ldelete_f(resultsFile,link, hdferr) - if (hdferr < 0) call IO_error(1,ext_msg = 'results_removeLink: H5Ldelete_soft_f ('//trim(link)//')') + call H5Ldelete_f(resultFile,link, hdferr) + if (hdferr < 0) call IO_error(1,ext_msg = 'result_removeLink: H5Ldelete_soft_f ('//trim(link)//')') -end subroutine results_removeLink +end subroutine result_removeLink !-------------------------------------------------------------------------------------------------- !> @brief Store string dataset. !> @details Not collective, must be called by one process at at time. !-------------------------------------------------------------------------------------------------- -subroutine results_writeDataset_str(dataset,group,label,description) +subroutine result_writeDataset_str(dataset,group,label,description) character(len=*), intent(in) :: label,group,description,dataset integer(HID_T) :: groupHandle - groupHandle = results_openGroup(group) + groupHandle = result_openGroup(group) call HDF5_write_str(dataset,groupHandle,label) call executionStamp(group//'/'//label,description) call HDF5_closeGroup(groupHandle) -end subroutine results_writeDataset_str +end subroutine result_writeDataset_str !-------------------------------------------------------------------------------------------------- !> @brief Store real scalar dataset with associated metadata. !-------------------------------------------------------------------------------------------------- -subroutine results_writeScalarDataset_real(dataset,group,label,description,SIunit) +subroutine result_writeScalarDataset_real(dataset,group,label,description,SIunit) character(len=*), intent(in) :: label,group,description character(len=*), intent(in), optional :: SIunit @@ -373,18 +373,18 @@ subroutine results_writeScalarDataset_real(dataset,group,label,description,SIuni integer(HID_T) :: groupHandle - groupHandle = results_openGroup(group) + groupHandle = result_openGroup(group) call HDF5_write(dataset,groupHandle,label) call executionStamp(group//'/'//label,description,SIunit) call HDF5_closeGroup(groupHandle) -end subroutine results_writeScalarDataset_real +end subroutine result_writeScalarDataset_real !-------------------------------------------------------------------------------------------------- !> @brief Store real vector dataset with associated metadata. !-------------------------------------------------------------------------------------------------- -subroutine results_writeVectorDataset_real(dataset,group,label,description,SIunit,systems) +subroutine result_writeVectorDataset_real(dataset,group,label,description,SIunit,systems) character(len=*), intent(in) :: label,group,description character(len=*), intent(in), optional :: SIunit @@ -394,21 +394,21 @@ subroutine results_writeVectorDataset_real(dataset,group,label,description,SIuni integer(HID_T) :: groupHandle - groupHandle = results_openGroup(group) + groupHandle = result_openGroup(group) call HDF5_write(dataset,groupHandle,label) call executionStamp(group//'/'//label,description,SIunit) if (present(systems) .and. HDF5_objectExists(groupHandle,label)) & - call HDF5_addAttribute(resultsFile,'systems',systems,group//'/'//label) + call HDF5_addAttribute(resultFile,'systems',systems,group//'/'//label) call HDF5_closeGroup(groupHandle) -end subroutine results_writeVectorDataset_real +end subroutine result_writeVectorDataset_real !-------------------------------------------------------------------------------------------------- !> @brief Store real tensor dataset with associated metadata. !> @details Data is transposed to compenstate transposed storage order. !-------------------------------------------------------------------------------------------------- -subroutine results_writeTensorDataset_real(dataset,group,label,description,SIunit,transposed) +subroutine result_writeTensorDataset_real(dataset,group,label,description,SIunit,transposed) character(len=*), intent(in) :: label,group,description character(len=*), intent(in), optional :: SIunit @@ -421,15 +421,15 @@ subroutine results_writeTensorDataset_real(dataset,group,label,description,SIuni real(pReal), dimension(:,:,:), allocatable :: dataset_transposed - if(present(transposed)) then + if (present(transposed)) then transposed_ = transposed else transposed_ = .true. end if - groupHandle = results_openGroup(group) - if(transposed_) then - if(size(dataset,1) /= size(dataset,2)) error stop 'transpose non-symmetric tensor' + groupHandle = result_openGroup(group) + if (transposed_) then + if (size(dataset,1) /= size(dataset,2)) error stop 'transpose non-symmetric tensor' allocate(dataset_transposed,mold=dataset) do i=1,size(dataset_transposed,3) dataset_transposed(:,:,i) = transpose(dataset(:,:,i)) @@ -441,13 +441,13 @@ subroutine results_writeTensorDataset_real(dataset,group,label,description,SIuni call executionStamp(group//'/'//label,description,SIunit) call HDF5_closeGroup(groupHandle) -end subroutine results_writeTensorDataset_real +end subroutine result_writeTensorDataset_real !-------------------------------------------------------------------------------------------------- !> @brief Store integer vector dataset with associated metadata. !-------------------------------------------------------------------------------------------------- -subroutine results_writeVectorDataset_int(dataset,group,label,description,SIunit,systems) +subroutine result_writeVectorDataset_int(dataset,group,label,description,SIunit,systems) character(len=*), intent(in) :: label,group,description character(len=*), intent(in), optional :: SIunit @@ -457,20 +457,20 @@ subroutine results_writeVectorDataset_int(dataset,group,label,description,SIunit integer(HID_T) :: groupHandle - groupHandle = results_openGroup(group) + groupHandle = result_openGroup(group) call HDF5_write(dataset,groupHandle,label) call executionStamp(group//'/'//label,description,SIunit) if (present(systems) .and. HDF5_objectExists(groupHandle,label)) & - call HDF5_addAttribute(resultsFile,'systems',systems,group//'/'//label) + call HDF5_addAttribute(resultFile,'systems',systems,group//'/'//label) call HDF5_closeGroup(groupHandle) -end subroutine results_writeVectorDataset_int +end subroutine result_writeVectorDataset_int !-------------------------------------------------------------------------------------------------- !> @brief Store integer tensor dataset with associated metadata. !-------------------------------------------------------------------------------------------------- -subroutine results_writeTensorDataset_int(dataset,group,label,description,SIunit) +subroutine result_writeTensorDataset_int(dataset,group,label,description,SIunit) character(len=*), intent(in) :: label,group,description character(len=*), intent(in), optional :: SIunit @@ -479,19 +479,19 @@ subroutine results_writeTensorDataset_int(dataset,group,label,description,SIunit integer(HID_T) :: groupHandle - groupHandle = results_openGroup(group) + groupHandle = result_openGroup(group) call HDF5_write(dataset,groupHandle,label) call executionStamp(group//'/'//label,description,SIunit) call HDF5_closeGroup(groupHandle) -end subroutine results_writeTensorDataset_int +end subroutine result_writeTensorDataset_int !-------------------------------------------------------------------------------------------------- !> @brief adds the unique mapping from spatial position and constituent ID to results !-------------------------------------------------------------------------------------------------- -subroutine results_mapping_phase(ID,entry,label) +subroutine result_mapping_phase(ID,entry,label) integer, dimension(:,:), intent(in) :: ID !< phase ID at (co,ce) integer, dimension(:,:), intent(in) :: entry !< phase entry at (co,ce) @@ -527,7 +527,7 @@ subroutine results_mapping_phase(ID,entry,label) writeSize(worldrank) = size(entry(1,:)) ! total number of entries of this process call H5Pcreate_f(H5P_DATASET_XFER_F, plist_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' #ifndef PETSC entryGlobal = int(entry -1,pI64) ! 0-based @@ -535,10 +535,10 @@ subroutine results_mapping_phase(ID,entry,label) !-------------------------------------------------------------------------------------------------- ! MPI settings and communication call H5Pset_dxpl_mpio_f(plist_id, H5FD_MPIO_COLLECTIVE_F, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call MPI_Allreduce(MPI_IN_PLACE,writeSize,worldsize,MPI_INTEGER,MPI_SUM,MPI_COMM_WORLD,err_MPI) ! get output at each process - if(err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' + if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' entryOffset = 0_pI64 do co = 1, size(ID,1) @@ -547,7 +547,7 @@ subroutine results_mapping_phase(ID,entry,label) end do end do call MPI_Allreduce(MPI_IN_PLACE,entryOffset,size(entryOffset),MPI_INTEGER8,MPI_SUM,MPI_COMM_WORLD,err_MPI)! get offset at each process - if(err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' + if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' entryOffset(:,worldrank) = sum(entryOffset(:,0:worldrank-1),2) do co = 1, size(ID,1) do ce = 1, size(ID,2) @@ -563,91 +563,91 @@ subroutine results_mapping_phase(ID,entry,label) !--------------------------------------------------------------------------------------------------- ! compound type: label(ID) + entry call H5Tcopy_f(H5T_NATIVE_CHARACTER, dt_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Tset_size_f(dt_id, int(len(label(1)),SIZE_T), hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Tget_size_f(dt_id, type_size_string, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' pI64_t = h5kind_to_type(kind(entryGlobal),H5_INTEGER_KIND) call H5Tget_size_f(pI64_t, type_size_int, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Tcreate_f(H5T_COMPOUND_F, type_size_string + type_size_int, dtype_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Tinsert_f(dtype_id, 'label', 0_SIZE_T, dt_id,hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Tinsert_f(dtype_id, 'entry', type_size_string, pI64_t, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' !-------------------------------------------------------------------------------------------------- ! create memory types for each component of the compound type call H5Tcreate_f(H5T_COMPOUND_F, type_size_string, label_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Tinsert_f(label_id, 'label', 0_SIZE_T, dt_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Tcreate_f(H5T_COMPOUND_F, type_size_int, entry_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Tinsert_f(entry_id, 'entry', 0_SIZE_T, pI64_t, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Tclose_f(dt_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' !-------------------------------------------------------------------------------------------------- ! create dataspace in memory (local shape = hyperslab) and in file (global shape) call H5Screate_simple_f(2,myShape,memspace_id,hdferr,myShape) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Screate_simple_f(2,totalShape,filespace_id,hdferr,totalShape) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Sselect_hyperslab_f(filespace_id, H5S_SELECT_SET_F, myOffset, myShape, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' !-------------------------------------------------------------------------------------------------- ! write the components of the compound type individually call H5Pset_preserve_f(plist_id, .true., hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' - loc_id = results_openGroup('/cell_to') + loc_id = result_openGroup('/cell_to') call H5Dcreate_f(loc_id, 'phase', dtype_id, filespace_id, dset_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Dwrite_f(dset_id, label_id, reshape(label(pack(ID,.true.)),myShape), & myShape, hdferr, file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Dwrite_f(dset_id, entry_id, reshape(pack(entryGlobal,.true.),myShape), & myShape, hdferr, file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' !-------------------------------------------------------------------------------------------------- ! close all call HDF5_closeGroup(loc_id) call H5Pclose_f(plist_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Sclose_f(filespace_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Sclose_f(memspace_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Dclose_f(dset_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Tclose_f(dtype_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Tclose_f(label_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Tclose_f(entry_id, hdferr) call executionStamp('cell_to/phase','cell ID and constituent ID to phase results') -end subroutine results_mapping_phase +end subroutine result_mapping_phase !-------------------------------------------------------------------------------------------------- !> @brief adds the unique mapping from spatial position and constituent ID to results !-------------------------------------------------------------------------------------------------- -subroutine results_mapping_homogenization(ID,entry,label) +subroutine result_mapping_homogenization(ID,entry,label) integer, dimension(:), intent(in) :: ID !< homogenization ID at (ce) integer, dimension(:), intent(in) :: entry !< homogenization entry at (ce) @@ -683,7 +683,7 @@ subroutine results_mapping_homogenization(ID,entry,label) writeSize(worldrank) = size(entry) ! total number of entries of this process call H5Pcreate_f(H5P_DATASET_XFER_F, plist_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' #ifndef PETSC entryGlobal = int(entry -1,pI64) ! 0-based @@ -691,17 +691,17 @@ subroutine results_mapping_homogenization(ID,entry,label) !-------------------------------------------------------------------------------------------------- ! MPI settings and communication call H5Pset_dxpl_mpio_f(plist_id, H5FD_MPIO_COLLECTIVE_F, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call MPI_Allreduce(MPI_IN_PLACE,writeSize,worldsize,MPI_INTEGER,MPI_SUM,MPI_COMM_WORLD,err_MPI) ! get output at each process - if(err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' + if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' entryOffset = 0_pI64 do ce = 1, size(ID,1) entryOffset(ID(ce),worldrank) = entryOffset(ID(ce),worldrank) +1_pI64 end do call MPI_Allreduce(MPI_IN_PLACE,entryOffset,size(entryOffset),MPI_INTEGER8,MPI_SUM,MPI_COMM_WORLD,err_MPI)! get offset at each process - if(err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' + if (err_MPI /= 0_MPI_INTEGER_KIND) error stop 'MPI error' entryOffset(:,worldrank) = sum(entryOffset(:,0:worldrank-1),2) do ce = 1, size(ID,1) entryGlobal(ce) = int(entry(ce),pI64) -1_pI64 + entryOffset(ID(ce),worldrank) @@ -715,86 +715,86 @@ subroutine results_mapping_homogenization(ID,entry,label) !--------------------------------------------------------------------------------------------------- ! compound type: label(ID) + entry call H5Tcopy_f(H5T_NATIVE_CHARACTER, dt_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Tset_size_f(dt_id, int(len(label(1)),SIZE_T), hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Tget_size_f(dt_id, type_size_string, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' pI64_t = h5kind_to_type(kind(entryGlobal),H5_INTEGER_KIND) call H5Tget_size_f(pI64_t, type_size_int, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Tcreate_f(H5T_COMPOUND_F, type_size_string + type_size_int, dtype_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Tinsert_f(dtype_id, 'label', 0_SIZE_T, dt_id,hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Tinsert_f(dtype_id, 'entry', type_size_string, pI64_t, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' !-------------------------------------------------------------------------------------------------- ! create memory types for each component of the compound type call H5Tcreate_f(H5T_COMPOUND_F, type_size_string, label_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Tinsert_f(label_id, 'label', 0_SIZE_T, dt_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Tcreate_f(H5T_COMPOUND_F, type_size_int, entry_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Tinsert_f(entry_id, 'entry', 0_SIZE_T, pI64_t, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Tclose_f(dt_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' !-------------------------------------------------------------------------------------------------- ! create dataspace in memory (local shape = hyperslab) and in file (global shape) call H5Screate_simple_f(1,myShape,memspace_id,hdferr,myShape) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Screate_simple_f(1,totalShape,filespace_id,hdferr,totalShape) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Sselect_hyperslab_f(filespace_id, H5S_SELECT_SET_F, myOffset, myShape, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' !-------------------------------------------------------------------------------------------------- ! write the components of the compound type individually call H5Pset_preserve_f(plist_id, .true., hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' - loc_id = results_openGroup('/cell_to') + loc_id = result_openGroup('/cell_to') call H5Dcreate_f(loc_id, 'homogenization', dtype_id, filespace_id, dset_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Dwrite_f(dset_id, label_id, reshape(label(pack(ID,.true.)),myShape), & myShape, hdferr, file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Dwrite_f(dset_id, entry_id, reshape(pack(entryGlobal,.true.),myShape), & myShape, hdferr, file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' !-------------------------------------------------------------------------------------------------- ! close all call HDF5_closeGroup(loc_id) call H5Pclose_f(plist_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Sclose_f(filespace_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Sclose_f(memspace_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Dclose_f(dset_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Tclose_f(dtype_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Tclose_f(label_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call H5Tclose_f(entry_id, hdferr) - if(hdferr < 0) error stop 'HDF5 error' + if (hdferr < 0) error stop 'HDF5 error' call executionStamp('cell_to/homogenization','cell ID to homogenization results') -end subroutine results_mapping_homogenization +end subroutine result_mapping_homogenization !-------------------------------------------------------------------------------------------------- @@ -806,14 +806,14 @@ subroutine executionStamp(path,description,SIunit) character(len=*), intent(in), optional :: SIunit - if (HDF5_objectExists(resultsFile,path)) & - call HDF5_addAttribute(resultsFile,'creator','DAMASK '//DAMASKVERSION,path) - if (HDF5_objectExists(resultsFile,path)) & - call HDF5_addAttribute(resultsFile,'created',now(),path) - if (HDF5_objectExists(resultsFile,path)) & - call HDF5_addAttribute(resultsFile,'description',description,path) - if (HDF5_objectExists(resultsFile,path) .and. present(SIunit)) & - call HDF5_addAttribute(resultsFile,'unit',SIunit,path) + if (HDF5_objectExists(resultFile,path)) & + call HDF5_addAttribute(resultFile,'creator','DAMASK '//DAMASKVERSION,path) + if (HDF5_objectExists(resultFile,path)) & + call HDF5_addAttribute(resultFile,'created',now(),path) + if (HDF5_objectExists(resultFile,path)) & + call HDF5_addAttribute(resultFile,'description',description,path) + if (HDF5_objectExists(resultFile,path) .and. present(SIunit)) & + call HDF5_addAttribute(resultFile,'unit',SIunit,path) end subroutine executionStamp @@ -834,4 +834,4 @@ character(len=24) function now() end function now -end module results +end module result diff --git a/src/rotations.f90 b/src/rotations.f90 index 5c8677c81..657480ef4 100644 --- a/src/rotations.f90 +++ b/src/rotations.f90 @@ -212,10 +212,10 @@ subroutine fromAxisAngle(self,ax,degrees,P) axis = ax(1:3) else axis = ax(1:3) * merge(-1.0_pReal,1.0_pReal,P == 1) - if(abs(P) /= 1) call IO_error(402,ext_msg='fromAxisAngle (P)') + if (abs(P) /= 1) call IO_error(402,ext_msg='fromAxisAngle (P)') end if - if(dNeq(norm2(axis),1.0_pReal) .or. angle < 0.0_pReal .or. angle > PI) & + if (dNeq(norm2(axis),1.0_pReal) .or. angle < 0.0_pReal .or. angle > PI) & call IO_error(402,ext_msg='fromAxisAngle') self%q = ax2qu([axis,angle]) @@ -513,11 +513,11 @@ pure function om2qu(om) result(qu) trace = math_trace33(om) - if(trace > 0.0_pReal) then + if (trace > 0.0_pReal) then s = 0.5_pReal / sqrt(trace+1.0_pReal) qu = [0.25_pReal/s, (om(3,2)-om(2,3))*s,(om(1,3)-om(3,1))*s,(om(2,1)-om(1,2))*s] else - if( om(1,1) > om(2,2) .and. om(1,1) > om(3,3) ) then + if ( om(1,1) > om(2,2) .and. om(1,1) > om(3,3) ) then s = 2.0_pReal * sqrt( 1.0_pReal + om(1,1) - om(2,2) - om(3,3)) qu = [ (om(3,2) - om(2,3)) /s,0.25_pReal * s,(om(1,2) + om(2,1)) / s,(om(1,3) + om(3,1)) / s] elseif (om(2,2) > om(3,3)) then @@ -528,7 +528,7 @@ pure function om2qu(om) result(qu) qu = [ (om(2,1) - om(1,2)) /s,(om(1,3) + om(3,1)) / s,(om(2,3) + om(3,2)) / s,0.25_pReal * s] end if end if - if(sign(1.0_pReal,qu(1))<0.0_pReal) qu =-1.0_pReal * qu + if (sign(1.0_pReal,qu(1))<0.0_pReal) qu =-1.0_pReal * qu qu(2:4) = merge(qu(2:4),qu(2:4)*P,dEq0(qu(2:4))) qu = qu/norm2(qu) @@ -619,7 +619,7 @@ pure function eu2qu(eu) result(qu) -P*sPhi*cos(ee(1)-ee(3)), & -P*sPhi*sin(ee(1)-ee(3)), & -P*cPhi*sin(ee(1)+ee(3))] - if(sign(1.0_pReal,qu(1)) < 0.0_pReal) qu = qu * (-1.0_pReal) + if (sign(1.0_pReal,qu(1)) < 0.0_pReal) qu = qu * (-1.0_pReal) end function eu2qu @@ -807,15 +807,15 @@ subroutine selfTest() do i = 1, 20 - if(i==1) then + if (i==1) then qu = [1.0_pReal, 0.0_pReal, 0.0_pReal, 0.0_pReal] - elseif(i==2) then + elseif (i==2) then qu = [1.0_pReal,-0.0_pReal,-0.0_pReal,-0.0_pReal] - elseif(i==3) then + elseif (i==3) then qu = [0.0_pReal, 1.0_pReal, 0.0_pReal, 0.0_pReal] - elseif(i==4) then + elseif (i==4) then qu = [0.0_pReal,0.0_pReal,1.0_pReal,0.0_pReal] - elseif(i==5) then + elseif (i==5) then qu = [0.0_pReal, 0.0_pReal, 0.0_pReal, 1.0_pReal] else call random_number(x) @@ -825,20 +825,20 @@ subroutine selfTest() sin(TAU*x(2))*B,& cos(TAU*x(2))*B,& sin(TAU*x(1))*A] - if(qu(1)<0.0_pReal) qu = qu * (-1.0_pReal) + if (qu(1)<0.0_pReal) qu = qu * (-1.0_pReal) end if - if(.not. quaternion_equal(om2qu(qu2om(qu)),qu)) error stop 'om2qu2om' - if(.not. quaternion_equal(eu2qu(qu2eu(qu)),qu)) error stop 'eu2qu2eu' - if(.not. quaternion_equal(ax2qu(qu2ax(qu)),qu)) error stop 'ax2qu2ax' + if (.not. quaternion_equal(om2qu(qu2om(qu)),qu)) error stop 'om2qu2om' + if (.not. quaternion_equal(eu2qu(qu2eu(qu)),qu)) error stop 'eu2qu2eu' + if (.not. quaternion_equal(ax2qu(qu2ax(qu)),qu)) error stop 'ax2qu2ax' om = qu2om(qu) - if(.not. quaternion_equal(om2qu(eu2om(om2eu(om))),qu)) error stop 'eu2om2eu' - if(.not. quaternion_equal(om2qu(ax2om(om2ax(om))),qu)) error stop 'ax2om2ax' + if (.not. quaternion_equal(om2qu(eu2om(om2eu(om))),qu)) error stop 'eu2om2eu' + if (.not. quaternion_equal(om2qu(ax2om(om2ax(om))),qu)) error stop 'ax2om2ax' eu = qu2eu(qu) - if(.not. quaternion_equal(eu2qu(ax2eu(eu2ax(eu))),qu)) error stop 'ax2eu2ax' + if (.not. quaternion_equal(eu2qu(ax2eu(eu2ax(eu))),qu)) error stop 'ax2eu2ax' call R%fromMatrix(om) @@ -872,7 +872,7 @@ subroutine selfTest() logical :: ok ok = all(dEq(qu1,qu2,1.0e-7_pReal)) - if(dEq0(qu1(1),1.0e-12_pReal)) & + if (dEq0(qu1(1),1.0e-12_pReal)) & ok = ok .or. all(dEq(-1.0_pReal*qu1,qu2,1.0e-7_pReal)) end function quaternion_equal diff --git a/src/signals.f90 b/src/signal.f90 similarity index 61% rename from src/signals.f90 rename to src/signal.f90 index 3f0397d3d..43e823efa 100644 --- a/src/signals.f90 +++ b/src/signal.f90 @@ -2,7 +2,7 @@ !> @author Martin Diehl, Max-Planck-Institut für Eisenforschung GmbH !> @brief Handling of UNIX signals. !-------------------------------------------------------------------------------------------------- -module signals +module signal use prec use system_routines @@ -10,15 +10,15 @@ module signals private logical, volatile, public, protected :: & - signals_SIGINT = .false., & !< interrupt signal - signals_SIGUSR1 = .false., & !< 1. user-defined signal - signals_SIGUSR2 = .false. !< 2. user-defined signal + signal_SIGINT = .false., & !< interrupt signal + signal_SIGUSR1 = .false., & !< 1. user-defined signal + signal_SIGUSR2 = .false. !< 2. user-defined signal public :: & - signals_init, & - signals_setSIGINT, & - signals_setSIGUSR1, & - signals_setSIGUSR2 + signal_init, & + signal_setSIGINT, & + signal_setSIGUSR1, & + signal_setSIGUSR2 contains @@ -26,100 +26,100 @@ contains !-------------------------------------------------------------------------------------------------- !> @brief Register signal handlers. !-------------------------------------------------------------------------------------------------- -subroutine signals_init() +subroutine signal_init() call signalint_c(c_funloc(catchSIGINT)) call signalusr1_c(c_funloc(catchSIGUSR1)) call signalusr2_c(c_funloc(catchSIGUSR2)) -end subroutine signals_init +end subroutine signal_init !-------------------------------------------------------------------------------------------------- -!> @brief Set global variable signals_SIGINT to .true. +!> @brief Set global variable signal_SIGINT to .true. !> @details This function can be registered to catch signals send to the executable. !-------------------------------------------------------------------------------------------------- -subroutine catchSIGINT(signal) bind(C) +subroutine catchSIGINT(sig) bind(C) - integer(C_INT), value :: signal + integer(C_INT), value :: sig - print'(a,i0)', ' received signal ',signal - call signals_setSIGINT(.true.) + print'(a,i0)', ' received signal ',sig + call signal_setSIGINT(.true.) end subroutine catchSIGINT !-------------------------------------------------------------------------------------------------- -!> @brief Set global variable signals_SIGUSR1 to .true. +!> @brief Set global variable signal_SIGUSR1 to .true. !> @details This function can be registered to catch signals send to the executable. !-------------------------------------------------------------------------------------------------- -subroutine catchSIGUSR1(signal) bind(C) +subroutine catchSIGUSR1(sig) bind(C) - integer(C_INT), value :: signal + integer(C_INT), value :: sig - print'(a,i0)', ' received signal ',signal - call signals_setSIGUSR1(.true.) + print'(a,i0)', ' received signal ',sig + call signal_setSIGUSR1(.true.) end subroutine catchSIGUSR1 !-------------------------------------------------------------------------------------------------- -!> @brief Set global variable signals_SIGUSR2 to .true. +!> @brief Set global variable signal_SIGUSR2 to .true. !> @details This function can be registered to catch signals send to the executable. !-------------------------------------------------------------------------------------------------- -subroutine catchSIGUSR2(signal) bind(C) +subroutine catchSIGUSR2(sig) bind(C) - integer(C_INT), value :: signal + integer(C_INT), value :: sig - print'(a,i0,a)', ' received signal ',signal - call signals_setSIGUSR2(.true.) + print'(a,i0,a)', ' received signal ',sig + call signal_setSIGUSR2(.true.) end subroutine catchSIGUSR2 !-------------------------------------------------------------------------------------------------- -!> @brief Set global variable signals_SIGINT. +!> @brief Set global variable signal_SIGINT. !-------------------------------------------------------------------------------------------------- -subroutine signals_setSIGINT(state) +subroutine signal_setSIGINT(state) logical, intent(in) :: state - signals_SIGINT = state + signal_SIGINT = state print*, 'set SIGINT to',state -end subroutine signals_setSIGINT +end subroutine signal_setSIGINT !-------------------------------------------------------------------------------------------------- -!> @brief Set global variable signals_SIGUSR. +!> @brief Set global variable signal_SIGUSR. !-------------------------------------------------------------------------------------------------- -subroutine signals_setSIGUSR1(state) +subroutine signal_setSIGUSR1(state) logical, intent(in) :: state - signals_SIGUSR1 = state + signal_SIGUSR1 = state print*, 'set SIGUSR1 to',state -end subroutine signals_setSIGUSR1 +end subroutine signal_setSIGUSR1 !-------------------------------------------------------------------------------------------------- -!> @brief Set global variable signals_SIGUSR2. +!> @brief Set global variable signal_SIGUSR2. !-------------------------------------------------------------------------------------------------- -subroutine signals_setSIGUSR2(state) +subroutine signal_setSIGUSR2(state) logical, intent(in) :: state - signals_SIGUSR2 = state + signal_SIGUSR2 = state print*, 'set SIGUSR2 to',state -end subroutine signals_setSIGUSR2 +end subroutine signal_setSIGUSR2 -end module signals +end module signal diff --git a/src/system_routines.f90 b/src/system_routines.f90 index 3ce6ba6ce..74aa4685b 100644 --- a/src/system_routines.f90 +++ b/src/system_routines.f90 @@ -119,7 +119,7 @@ function getCWD() call getCWD_C(getCWD_Cstring,stat) - if(stat == 0) then + if (stat == 0) then getCWD = c_f_string(getCWD_Cstring) else error stop 'invalid working directory' @@ -141,7 +141,7 @@ function getHostName() call getHostName_C(getHostName_Cstring,stat) - if(stat == 0) then + if (stat == 0) then getHostName = c_f_string(getHostName_Cstring) else getHostName = 'n/a (Error!)' @@ -163,7 +163,7 @@ function getUserName() call getUserName_C(getUserName_Cstring,stat) - if(stat == 0) then + if (stat == 0) then getUserName = c_f_string(getUserName_Cstring) else getUserName = 'n/a (Error!)' diff --git a/src/tables.f90 b/src/tables.f90 new file mode 100644 index 000000000..c62082705 --- /dev/null +++ b/src/tables.f90 @@ -0,0 +1,145 @@ +!-------------------------------------------------------------------------------------------------- +!> @author Martin Diehl, KU Leuven +!> @author Philip Eisenlohr, Michigan State University +!> @brief Tabular representation of variable data. +!-------------------------------------------------------------------------------------------------- +module tables + use prec + use IO + use YAML_parse + use YAML_types + + implicit none(type,external) + private + + type, public :: tTable + real(pReal), dimension(:), allocatable :: x,y + contains + procedure, public :: at => eval + end type tTable + + interface table + module procedure table_from_values + module procedure table_from_dict + end interface table + + public :: & + table, & + tables_init + +contains + + +!-------------------------------------------------------------------------------------------------- +!> @brief Run self-test. +!-------------------------------------------------------------------------------------------------- +subroutine tables_init() + + print'(/,1x,a)', '<<<+- tables init -+>>>'; flush(IO_STDOUT) + + call selfTest() + +end subroutine tables_init + + +!-------------------------------------------------------------------------------------------------- +!> @brief Initialize a table from values. +!-------------------------------------------------------------------------------------------------- +function table_from_values(x,y) result(t) + + real(pReal), dimension(:), intent(in) :: x,y + type(tTable) :: t + + + if (size(x) < 1) call IO_error(603,ext_msg='missing tabulated x data') + if (size(y) < 1) call IO_error(603,ext_msg='missing tabulated y data') + if (size(x) /= size(y)) call IO_error(603,ext_msg='shape mismatch in tabulated data') + if (size(x) /= 1) then + if (any(x(2:size(x))-x(1:size(x)-1) <= 0.0_pReal)) & + call IO_error(603,ext_msg='ordinate data does not increase monotonically') + end if + + t%x = x + t%y = y + +end function table_from_values + + +!-------------------------------------------------------------------------------------------------- +!> @brief Initialize a table from a dictionary with values. +!-------------------------------------------------------------------------------------------------- +function table_from_dict(dict,x_label,y_label) result(t) + + type(tDict), intent(in) :: dict + character(len=*), intent(in) :: x_label, y_label + type(tTable) :: t + + + t = tTable(dict%get_as1dFloat(x_label),dict%get_as1dFloat(y_label)) + +end function table_from_dict + + +!-------------------------------------------------------------------------------------------------- +!> @brief Linearly interpolate/extrapolate tabular data. +!-------------------------------------------------------------------------------------------------- +pure function eval(self,x) result(y) + + class(tTable), intent(in) :: self + real(pReal), intent(in) :: x + real(pReal) :: y + + integer :: i + + + if (size(self%x) == 1) then + y = self%y(1) + else + i = max(1,min(findloc(self%x @brief Check correctness of table functionality. +!-------------------------------------------------------------------------------------------------- +subroutine selfTest() + + type(tTable) :: t + real(pReal), dimension(*), parameter :: & + x = real([ 1., 2., 3., 4.],pReal), & + y = real([ 1., 3., 2.,-2.],pReal), & + x_eval = real([ 0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0],pReal), & + y_true = real([-1.0, 0.0, 1.0, 2.0, 3.0, 2.5 ,2.0, 0.0,-2.0,-4.0,-6.0],pReal) + integer :: i + type(tDict), pointer :: dict + type(tList), pointer :: l_x, l_y + real(pReal) :: r + + + call random_number(r) + t = table(real([0.],pReal),real([r],pReal)) + if (dNeq(r,t%at(r),1.0e-9_pReal)) error stop 'table eval/mono' + + r = r-0.5_pReal + t = table(x+r,y) + do i = 1, size(x_eval) + if (dNeq(y_true(i),t%at(x_eval(i)+r),1.0e-9_pReal)) error stop 'table eval/values' + end do + + l_x => YAML_parse_str_asList('[1, 2, 3, 4]'//IO_EOL) + l_y => YAML_parse_str_asList('[1, 3, 2,-2]'//IO_EOL) + allocate(dict) + call dict%set('t',l_x) + call dict%set('T',l_y) + t = table(dict,'t','T') + do i = 1, size(x_eval) + if (dNeq(y_true(i),t%at(x_eval(i)))) error stop 'table eval/dict' + end do + +end subroutine selfTest + +end module tables