diff --git a/.compileOF2412.sh b/.compileOF2412.sh
new file mode 100755
index 000000000..eae639057
--- /dev/null
+++ b/.compileOF2412.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+docker pull ithacafv/openfoam2412-muq2-pytorch
+docker run -ti -d --name foam2412 -v "${PWD}":/home/ofuser/app:rw ithacafv/openfoam2412-muq2-pytorch /bin/bash
+docker exec foam2412 /bin/bash -c "source /usr/lib/openfoam/openfoam2412/etc/bashrc; cd /home/ofuser/app; git config --global --add safe.directory /home/ofuser/app; source etc/bashrc; git submodule update --init; ./Allwclean; ./Allwmake -taumq"
diff --git a/.compileOF2506.sh b/.compileOF2506.sh
new file mode 100755
index 000000000..f8d282320
--- /dev/null
+++ b/.compileOF2506.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+docker pull ithacafv/openfoam2506-muq2-pytorch
+docker run -ti -d --name foam2506 -v "${PWD}":/home/ofuser/app:rw ithacafv/openfoam2506-muq2-pytorch /bin/bash
+docker exec foam2506 /bin/bash -c "source /usr/lib/openfoam/openfoam2506/etc/bashrc; cd /home/ofuser/app; git config --global --add safe.directory /home/ofuser/app; source etc/bashrc; git submodule update --init; ./Allwclean; ./Allwmake -taumq"
diff --git a/.github/workflows/docker-dependencies.yml b/.github/workflows/docker-dependencies.yml
new file mode 100644
index 000000000..e86d331c7
--- /dev/null
+++ b/.github/workflows/docker-dependencies.yml
@@ -0,0 +1,69 @@
+name: Build Dependencies Docker Images
+
+on:
+ workflow_dispatch:
+
+env:
+ REGISTRY: docker.io
+ IMAGE_NAME: ithacafv/ithacafv-dependencies
+
+jobs:
+ build-amd64-deps:
+ runs-on: ubuntu-latest
+ outputs:
+ digest: ${{ steps.build.outputs.digest }}
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v3
+
+ - name: Log into registry ${{ env.REGISTRY }}
+ uses: docker/login-action@v3
+ with:
+ registry: ${{ env.REGISTRY }}
+ username: ${{ secrets.DOCKER_USERNAME }}
+ password: ${{ secrets.DOCKER_PASSWORD }}
+
+ - name: Build and push AMD64 dependencies
+ id: build
+ uses: docker/build-push-action@v5
+ with:
+ context: ./dockerfiles/OF2506/amd64-deps
+ platforms: linux/amd64
+ push: true
+ tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:amd64
+ cache-from: type=gha
+ cache-to: type=gha,mode=max
+
+ build-arm64-deps:
+ runs-on: ubuntu-24.04-arm
+ outputs:
+ digest: ${{ steps.build.outputs.digest }}
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v3
+
+ - name: Log into registry ${{ env.REGISTRY }}
+ uses: docker/login-action@v3
+ with:
+ registry: ${{ env.REGISTRY }}
+ username: ${{ secrets.DOCKER_USERNAME }}
+ password: ${{ secrets.DOCKER_PASSWORD }}
+
+ - name: Build and push ARM64 dependencies
+ id: build
+ uses: docker/build-push-action@v5
+ with:
+ context: ./dockerfiles/OF2506/arm64-deps
+ platforms: linux/arm64
+ push: true
+ tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:arm64
+ cache-from: type=gha
+ cache-to: type=gha,mode=max
diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml
new file mode 100644
index 000000000..0dc3aedf1
--- /dev/null
+++ b/.github/workflows/docker-publish.yml
@@ -0,0 +1,129 @@
+name: Build and Push Multi-Arch Docker Images
+
+on:
+ release:
+ types: [published]
+ workflow_dispatch:
+
+env:
+ REGISTRY: docker.io
+ IMAGE_NAME: ithacafv/ithacafv
+
+jobs:
+ build-amd64:
+ runs-on: ubuntu-latest
+ outputs:
+ digest: ${{ steps.build.outputs.digest }}
+ metadata: ${{ steps.meta.outputs.json }}
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v3
+
+ - name: Log into registry ${{ env.REGISTRY }}
+ if: github.event_name != 'pull_request'
+ uses: docker/login-action@v3
+ with:
+ registry: ${{ env.REGISTRY }}
+ username: ${{ secrets.DOCKER_USERNAME }}
+ password: ${{ secrets.DOCKER_PASSWORD }}
+
+ - name: Extract metadata for ITHACA-FV image
+ id: meta
+ uses: docker/metadata-action@v5
+ with:
+ images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
+ tags: |
+ type=semver,pattern={{version}}
+ type=raw,value=latest
+
+ - name: Build and push AMD64 image
+ id: build
+ uses: docker/build-push-action@v5
+ with:
+ context: ./dockerfiles
+ file: ./dockerfiles/Dockerfile
+ platforms: linux/amd64
+ labels: ${{ steps.meta.outputs.labels }}
+ cache-from: type=gha
+ cache-to: type=gha,mode=max
+ outputs: type=image,name=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=true
+
+ build-arm64:
+ runs-on: ubuntu-24.04-arm
+ outputs:
+ digest: ${{ steps.build.outputs.digest }}
+ metadata: ${{ steps.meta.outputs.json }}
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v3
+
+ - name: Log into registry ${{ env.REGISTRY }}
+ if: github.event_name != 'pull_request'
+ uses: docker/login-action@v3
+ with:
+ registry: ${{ env.REGISTRY }}
+ username: ${{ secrets.DOCKER_USERNAME }}
+ password: ${{ secrets.DOCKER_PASSWORD }}
+
+ - name: Extract metadata for ITHACA-FV image
+ id: meta
+ uses: docker/metadata-action@v5
+ with:
+ images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
+ tags: |
+ type=semver,pattern={{version}}
+ type=raw,value=latest
+
+ - name: Build and push ARM64 image
+ id: build
+ uses: docker/build-push-action@v5
+ with:
+ context: ./dockerfiles
+ file: ./dockerfiles/Dockerfile
+ platforms: linux/arm64
+ labels: ${{ steps.meta.outputs.labels }}
+ cache-from: type=gha
+ cache-to: type=gha,mode=max
+ outputs: type=image,name=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=true
+
+ merge:
+ runs-on: ubuntu-latest
+ needs:
+ - build-amd64
+ - build-arm64
+ steps:
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v3
+
+ - name: Log into registry ${{ env.REGISTRY }}
+ uses: docker/login-action@v3
+ with:
+ registry: ${{ env.REGISTRY }}
+ username: ${{ secrets.DOCKER_USERNAME }}
+ password: ${{ secrets.DOCKER_PASSWORD }}
+
+ - name: Extract metadata for ITHACA-FV image
+ id: meta
+ uses: docker/metadata-action@v5
+ with:
+ images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
+ tags: |
+ type=semver,pattern={{version}}
+ type=raw,value=latest
+
+ - name: Create and push manifest list
+ working-directory: /tmp
+ run: |
+ docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
+ ${{ needs.build-amd64.outputs.digest }} \
+ ${{ needs.build-arm64.outputs.digest }}
+ env:
+ DOCKER_METADATA_OUTPUT_JSON: ${{ steps.meta.outputs.json }}
\ No newline at end of file
diff --git a/.github/workflows/docker_ithaca.yml b/.github/workflows/docker_ithaca.yml
deleted file mode 100755
index c6a71da4f..000000000
--- a/.github/workflows/docker_ithaca.yml
+++ /dev/null
@@ -1,91 +0,0 @@
-name: Docker
-
-on:
- push:
- # Pattern matched against refs/tags
- tags:
- - '*' # Push events to every tag not containing /
-
-jobs:
- docker-arm64:
- runs-on: ubuntu-latest
- steps:
-
- - name: Checkout
- uses: actions/checkout@v2
-
- - name: Set up QEMU
- uses: docker/setup-qemu-action@v1
-
- - name: Set up Docker Buildx
- uses: docker/setup-buildx-action@v1
-
- - name: Login to DockerHub
- uses: docker/login-action@v1
- with:
- username: ${{ secrets.DOCKER_USERNAME }}
- password: ${{ secrets.DOCKER_PASSWORD }}
-
- - name: Build and push
- uses: docker/build-push-action@v2
- with:
- context: ./dockerfiles/arm64
- platforms: linux/arm64
- push: true
- tags: ithacafv/ithacafv:manifest-arm64
-
- docker-amd64:
- runs-on: ubuntu-latest
- steps:
-
- - name: Checkout
- uses: actions/checkout@v2
-
- - name: Set up QEMU
- uses: docker/setup-qemu-action@v1
-
- - name: Set up Docker Buildx
- uses: docker/setup-buildx-action@v1
-
- - name: Login to DockerHub
- uses: docker/login-action@v1
- with:
- username: ${{ secrets.DOCKER_USERNAME }}
- password: ${{ secrets.DOCKER_PASSWORD }}
-
- - name: Build and push
- uses: docker/build-push-action@v2
- with:
- context: ./dockerfiles/amd64
- platforms: linux/amd64
- push: true
- tags: ithacafv/ithacafv:manifest-amd64
-
-
-
- #build-manifest:
- #needs: [docker-amd64, docker-arm64]
-
- #runs-on: ubuntu-latest
- #steps:
-
- #- name: Checkout
- #uses: actions/checkout@v2
-
- #- name: Set up QEMU
- #uses: docker/setup-qemu-action@v1
-
- #- name: Set up Docker Buildx
- #uses: docker/setup-buildx-action@v1
-
- #- name: Login to DockerHub
- #uses: docker/login-action@v1
- #with:
- #username: ${{ secrets.DOCKER_USERNAME }}
- #password: ${{ secrets.DOCKER_PASSWORD }}
-
- #- name: manifest creation
- #run: docker manifest create ithacafv/ithacafv:manifest-latest --amend ithacafv/ithacafv:manifest-amd64 --amend ithacafv/ithacafv:manifest-arm64
-
- #- name: push manifest
- #run: docker manifest push ithacafv/ithacafv:manifest-latest
diff --git a/.github/workflows/of2412.yml b/.github/workflows/of2412.yml
new file mode 100755
index 000000000..625661c2f
--- /dev/null
+++ b/.github/workflows/of2412.yml
@@ -0,0 +1,27 @@
+name: OF2412
+
+on:
+ push:
+ branches: [ master ]
+ pull_request:
+ branches: [ master ]
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+
+ strategy:
+ matrix:
+ include:
+ - name: "OpenFOAM 2412"
+ install: "cd ."
+ compile: ./.compileOF2412.sh
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v1
+ - name: install OF
+ run: ${{ matrix.install}}
+ - name: make
+ run: ${{ matrix.compile}}
diff --git a/.github/workflows/of2512.yml b/.github/workflows/of2512.yml
new file mode 100755
index 000000000..0ba698a27
--- /dev/null
+++ b/.github/workflows/of2512.yml
@@ -0,0 +1,27 @@
+name: OF2506
+
+on:
+ push:
+ branches: [ master ]
+ pull_request:
+ branches: [ master ]
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+
+ strategy:
+ matrix:
+ include:
+ - name: "OpenFOAM 2506"
+ install: "cd ."
+ compile: ./.compileOF2506.sh
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v1
+ - name: install OF
+ run: ${{ matrix.install}}
+ - name: make
+ run: ${{ matrix.compile}}
diff --git a/.gitmodules b/.gitmodules
index c8272cfbf..d47a82246 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -5,3 +5,9 @@
[submodule "src/thirdparty/Eigen"]
path = src/thirdparty/Eigen
url = https://gitlab.com/libeigen/eigen.git
+[submodule "src/thirdparty/spectra"]
+ path = src/thirdparty/spectra
+ url = https://github.com/yixuan/spectra.git
+[submodule "src/thirdparty/OptimLib"]
+ path = src/thirdparty/OptimLib
+ url = https://github.com/kthohr/optim.git
diff --git a/README.md b/README.md
index ee04cd07c..dd51b816c 100644
--- a/README.md
+++ b/README.md
@@ -14,18 +14,15 @@
-
-
-
### 0. Introduction
**ITHACA-FV** is an implementation in **OpenFOAM** of several reduced order modelling techniques. **ITHACA-FV** is designed for [**OpenFOAM v2412**](https://www.openfoam.com/news/main-news/openfoam-v2412/) but it can be easily adapted also to other versions of OpenFOAM.
**ITHACA-FV** can also be used as a basis for more advanced projects that would like to assess the capability of reduced order models in their existing **OpenFOAM**-based software, thanks to the availability of several reduced order methods and algorithms.
-Linear and non-linear algebra operations which are not already implemented in OpenFOAM are performed with the external library [**Eigen**](http://eigen.tuxfamily.org/index.php?title=Main_Page). The source code of Eigen 3.3.7 is provided together with ITHACA-FV and is located in the [src/thirdyparty/Eigen](./src/thirdparty/Eigen) folder. For the EigenValue decomposition it is also possible to rely on the [**Spectra-0.7.0**](https://spectralib.org/) library and the source code is provided in the [src/thirdyparty/spectra](./src//thirdparty/spectra) folder. Numerical optimization can be performed using the external library [**OptimLib**](https://www.kthohr.com/optimlib.html) and the header based source code is provided in the [src/thirdyparty/OptimLib](./src/thirdparty/OptimLib) folder.
+Linear and non-linear algebra operations which are not already implemented in OpenFOAM are performed with the external library [**Eigen**](http://eigen.tuxfamily.org/index.php?title=Main_Page). Eigen 3.4 is provided as a git submodule together with ITHACA-FV and is located in the [src/thirdyparty/Eigen](./src/thirdparty/Eigen) folder. For the EigenValue decomposition it is also possible to rely on the [**Spectra-1.2.0**](https://spectralib.org/) library and the source code, as a git submodule, is provided in the [src/thirdyparty/spectra](./src//thirdparty/spectra) folder. Numerical optimization can be performed using the external library [**OptimLib**](https://www.kthohr.com/optimlib.html) and the header based source code, as a git submodule, is provided in the [src/thirdyparty/OptimLib](./src/thirdparty/OptimLib) folder.
-**ITHACA-FV** has been tested on ubuntu 16.04, CentOS 7, ArchLinux but can be easily compiled on any linux distribution with a compiled version of OpenFOAM 2106, OpenFOAM 2212, OpenFOAM 2306, OpenFOAM 2312, OpenFOAM 2406, and OpenFOAM 2412.
+**ITHACA-FV** has been tested on several versions of ubuntu, CentOS 7, ArchLinux but can be easily compiled on any linux distribution with a compiled version of OpenFOAM 2106, OpenFOAM 2212, OpenFOAM 2306, OpenFOAM 2312, OpenFOAM 2406, OpenFOAM 2412 and OpenFOAM 2506.
### 1. Prerequisites
**ITHACA-FV** requires
@@ -35,12 +32,13 @@ Linear and non-linear algebra operations which are not already implemented in Op
* [**OpenFOAM 2312**](https://www.openfoam.com/news/main-news/openfoam-v2312) or
* [**OpenFOAM 2406**](https://www.openfoam.com/news/main-news/openfoam-v2406) or
* [**OpenFOAM 2412**](https://www.openfoam.com/news/main-news/openfoam-v2412) or
+* [**OpenFOAM 2506**](https://www.openfoam.com/news/main-news/openfoam-v2506)
### 2. Installation and usage
First of all you need to source the bashrc file of your installation **OpenFOAM**. This is of course depending on the location of your OpenFOAM installation and of your particular version of OpenFOAM
```
-source $HOME/OpenFOAM/OpenFOAM-v2106/etc/bashrc
+source $HOME/OpenFOAM/OpenFOAM-v2506/etc/bashrc
```
Then navigate to the folder where you want to install ITHACA-FV such as, for example, your HOME folder
```
@@ -75,8 +73,9 @@ source etc/bashrc
In the near future the ITHACA-FV will also be linked with the pytorch package for machine learning. Some basic functions are already available. In order to compile these additional functionalities one will need to have torch installed and compile the library with the `-m` options. Moreover one will need to install a version of libtorch with ABI enabled. The one available at the following link for example has it:
```
- curl https://download.pytorch.org/libtorch/cpu/libtorch-cxx11-abi-shared-with-deps-1.4.0%2Bcpu.zip > libtorch.zip && \
- unzip libtorch.zip -d opt/ && \
+ wget https://download.pytorch.org/libtorch/cpu/libtorch-cxx11-abi-shared-with-deps-2.7.1%2Bcpu.zip > libtorch.zip && \
+ unzip libtorch.zip && \
+ export TORCH_LIBRARIES=libtorch
```
For a brief description of the classes and methods, you can check the official ITHACA-FV doxygen [documentation](https://ithaca-fv.github.io/ITHACA-FV).
@@ -89,13 +88,13 @@ These images are based **OpenFOAM-v2106**, and provided an isolated environment,
In order to pull the image, run the following command:
```
-docker pull ithacafv/ithacafv:manifest-latest
+docker pull ithacafv/ithacafv:latest
```
Once the image is downloaded, you can start the container and mount the $HOME directory by executing:
```
-docker run -ti --rm -v "${HOME}:/home/ithacafv/${USER}" ithacafv/ithacafv:manifest-latest
+docker run -ti --rm -v "${HOME}:/home/ithacafv/${USER}" ithacafv/ithacafv:latest
```
### 4. Singularity
@@ -115,7 +114,7 @@ export SINGULARITY_CACHEDIR=$HOME/mycontainter
Buidling singularity image file `.sif` from the docker image, which is build and stored in `$HOME/mycontainter`, The below image used is based **OpenFOAM-v2106**, and where you can find a compiled version of the master branch of **ITHACA-FV**.
```
-singularity build ithacafv.sif docker://ithacafv/ithacafv:manifest-latest
+singularity build ithacafv.sif docker://ithacafv/ithacafv:latest
```
To view / list all the images/cache,
diff --git a/applications/POD/Make/options b/applications/POD/Make/options
index 421af160b..9144064b7 100644
--- a/applications/POD/Make/options
+++ b/applications/POD/Make/options
@@ -34,7 +34,7 @@ EXE_INC = \
-I$(LIB_ITHACA_SRC)/thirdparty/spectra/include \
-Wno-comment \
-w \
- -std=c++14
+ -std=c++17
EXE_LIBS = \
-lturbulenceModels \
diff --git a/applications/POD/perform_POD.C b/applications/POD/perform_POD.C
index 4ddd3bbd6..86ebba8dc 100755
--- a/applications/POD/perform_POD.C
+++ b/applications/POD/perform_POD.C
@@ -84,10 +84,7 @@ int main(int argc, char *argv[])
{
pod_exist = false;
Info << "POD don't exist, performing a POD decomposition" << endl;
- mkDir("./ITHACAoutput/POD");
- system("ln -s ../../constant ./ITHACAoutput/POD/constant");
- system("ln -s ../../0 ./ITHACAoutput/POD/0");
- system("ln -s ../../system ./ITHACAoutput/POD/system");
+ ITHACAutilities::createSymLink("./ITHACAoutput/POD");
}
if(pod_exist == 1)
{
diff --git a/applications/extract_time_evolution/Make/options b/applications/extract_time_evolution/Make/options
index c047e7cda..1d2854cba 100644
--- a/applications/extract_time_evolution/Make/options
+++ b/applications/extract_time_evolution/Make/options
@@ -25,7 +25,7 @@ EXE_INC = \
-I$(LIB_SRC)/turbulenceModels/compressible/turbulenceModel \
-I$(LIB_SRC)/functionObjects/forces/lnInclude \
-w \
- -std=c++14
+ -std=c++17
EXE_LIBS = \
-lturbulenceModels \
diff --git a/dockerfiles/Dockerfile b/dockerfiles/Dockerfile
new file mode 100644
index 000000000..a80764a21
--- /dev/null
+++ b/dockerfiles/Dockerfile
@@ -0,0 +1,47 @@
+# Multi-architecture Dockerfile for ITHACA-FV
+# Automatically selects the correct base image based on target platform
+ARG TARGETARCH
+FROM ithacafv/ithacafv-dependencies:${TARGETARCH} AS base
+
+LABEL maintainer="giovannistabile@santannapisa.it"
+
+# Install additional packages
+RUN apt-get update && \
+ apt-get install -y \
+ git \
+ vim \
+ ssh \
+ sudo \
+ wget \
+ software-properties-common && \
+ rm -rf /var/lib/apt/lists/*
+
+# Set working directory and clone ITHACA-FV
+WORKDIR /usr/dir
+RUN git clone https://github.com/ITHACA-FV/ITHACA-FV.git
+
+# Environment variables for bashrc
+ARG of_var="source \$FOAM_ETC/bashrc"
+ARG ithaca_var="source /opt/ITHACA-FV/etc/bashrc"
+
+# Update bashrc with OpenFOAM and ITHACA-FV sources
+RUN echo $of_var >> /etc/bash.bashrc && \
+ echo $ithaca_var >> /etc/bash.bashrc
+
+# Update bashrc with OpenFOAM and ITHACA-FV sources
+RUN echo $of_var >> /etc/bash.bashrc && \
+ echo $ithaca_var >> /etc/bash.bashrc
+
+
+RUN /bin/bash -c "source \$FOAM_ETC/bashrc && \
+ cd ITHACA-FV && git submodule update --init && source etc/bashrc && \
+ if [ \"$TARGETARCH\" = \"amd64\" ]; then \
+ ./Allwmake -taumq -j 4; \
+ else \
+ ./Allwmake -au -j 4; \
+ fi"
+
+
+# Source bashrc on container start
+RUN /bin/bash -c "source /etc/bash.bashrc"
+ENTRYPOINT ["/bin/bash"]
diff --git a/dockerfiles/OF2412/Dockerfile b/dockerfiles/OF2412/Dockerfile
new file mode 100644
index 000000000..a849e580d
--- /dev/null
+++ b/dockerfiles/OF2412/Dockerfile
@@ -0,0 +1,75 @@
+# Multi-architecture Dockerfile for ITHACA-FV
+# Automatically selects the correct base image based on target platform
+ARG TARGETARCH
+FROM ithacafv/openfoam2412-muq2-pytorch:${TARGETARCH} AS base
+
+LABEL maintainer="giovannistabile@santannapisa.it"
+
+USER root
+
+# Install additional packages
+RUN apt-get update && \
+ apt-get install -y \
+ git \
+ vim \
+ ssh \
+ sudo \
+ wget \
+ software-properties-common && \
+ rm -rf /var/lib/apt/lists/*
+
+# Create ithacafv user and group
+ARG USER=ithacafv
+RUN if id -u 1000 >/dev/null 2>&1; then \
+ userdel $(id -nu 1000) || true; \
+ fi && \
+ if getent group 1000 >/dev/null 2>&1; then \
+ groupdel $(getent group 1000 | cut -d: -f1) || true; \
+ fi && \
+ adduser --disabled-password --gecos '' --uid 1000 $USER && \
+ adduser $USER sudo && \
+ echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
+
+# Set environment variables
+ENV HOME=/home/$USER
+ENV USER=$USER
+
+# Set working directory and clone ITHACA-FV
+WORKDIR /opt
+RUN git clone https://github.com/mathLab/ITHACA-FV.git && \
+ chown -R $USER:$USER ITHACA-FV && \
+ chown -R $USER:$USER /home/$USER
+
+# Environment variables for bashrc
+ARG of_var="source /usr/lib/openfoam/openfoam2412/etc/bashrc"
+ARG ithaca_var="source /opt/ITHACA-FV/etc/bashrc"
+
+# Update bashrc with OpenFOAM and ITHACA-FV sources
+RUN echo $of_var >> /etc/bash.bashrc && \
+ echo $ithaca_var >> /etc/bash.bashrc
+
+# Switch to ithacafv user
+USER $USER
+
+# Build ITHACA-FV
+RUN /bin/bash -c "source /usr/lib/openfoam/openfoam2412/etc/bashrc && \
+ cd ITHACA-FV && \
+ git submodule update --init && \
+ source etc/bashrc && \
+ ./Allwmake -au -j 4"
+
+# Copy binaries and libraries to system paths (as root)
+USER root
+RUN if [ -d "/home/$USER/OpenFOAM/$USER-openfoam2412/platforms/linux64GccDPInt32Opt/bin" ]; then \
+ cp -r /home/$USER/OpenFOAM/$USER-openfoam2412/platforms/linux64GccDPInt32Opt/bin/* /usr/local/bin/ || true; \
+ cp -r /home/$USER/OpenFOAM/$USER-openfoam2412/platforms/linux64GccDPInt32Opt/lib/* /usr/local/lib/ || true; \
+ fi
+
+# Final setup
+USER $USER
+WORKDIR $HOME
+
+# Source bashrc on container start
+RUN /bin/bash -c "source /etc/bash.bashrc"
+
+ENTRYPOINT ["/bin/bash"]
diff --git a/dockerfiles/OF2412/amd64-deps/Dockerfile b/dockerfiles/OF2412/amd64-deps/Dockerfile
new file mode 100644
index 000000000..2e5533ceb
--- /dev/null
+++ b/dockerfiles/OF2412/amd64-deps/Dockerfile
@@ -0,0 +1,41 @@
+# Start from the ubuntu Openfoam 2106 image
+FROM opencfd/openfoam-dev:2412
+USER root
+ARG PYTHON_VERSION=3.7
+ENV PATH="/root/miniconda3/bin:${PATH}"
+
+RUN rm /etc/apt/sources.list.d/openfoam.list && \
+ cp /etc/apt/sources.list /etc/apt/sources.list.backup && \
+ grep -v -e "openfoam" /etc/apt/sources.list.backup > /etc/apt/sources.list && \
+ echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections && \
+ apt-get update && \
+ apt-get install -yy -q pwgen npm nodejs cmake git wget bzip2 unzip && \
+ apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
+
+# Anaconda installing
+RUN wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh && \
+bash Miniconda3-latest-Linux-x86_64.sh -b && \
+rm Miniconda3-latest-Linux-x86_64.sh && \
+. /root/miniconda3/etc/profile.d/conda.sh && \
+export PATH=/root/miniconda3/bin:$PATH && \
+wget https://download.pytorch.org/libtorch/cpu/libtorch-cxx11-abi-shared-with-deps-2.7.1%2Bcpu.zip && \
+unzip libtorch-cxx11-abi-shared-with-deps-2.7.1+cpu.zip && \
+rm libtorch-cxx11-abi-shared-with-deps-2.7.1+cpu.zip && \
+conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/main && \
+conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/r && \
+conda install -y -c conda-forge muq cmake pybind11 && \
+conda clean -y --all
+ENV TORCH_LIBRARIES=/libtorch
+ENV MUQ_LIBRARIES=/root/miniconda3
+
+# Export OpenFOAM environment variables for use in subsequent builds
+RUN /bin/bash -c "source /usr/lib/openfoam/openfoam2412/etc/bashrc && \
+ echo 'export FOAM_ETC=${FOAM_ETC}' >> /etc/environment && \
+ echo 'export FOAM_APP=${FOAM_APP}' >> /etc/environment && \
+ echo 'export FOAM_APPBIN=${FOAM_APPBIN}' >> /etc/environment && \
+ echo 'export FOAM_LIBBIN=${FOAM_LIBBIN}' >> /etc/environment && \
+ echo 'export FOAM_SRC=${FOAM_SRC}' >> /etc/environment && \
+ echo 'export WM_PROJECT_DIR=${WM_PROJECT_DIR}' >> /etc/environment"
+
+ENV FOAM_ETC=/usr/lib/openfoam/openfoam2412/etc
+RUN echo 'source /usr/lib/openfoam/openfoam2412/etc/bashrc' >> ~/.bashrc
\ No newline at end of file
diff --git a/dockerfiles/OF2412/arm64-deps/Dockerfile b/dockerfiles/OF2412/arm64-deps/Dockerfile
new file mode 100644
index 000000000..5d419c583
--- /dev/null
+++ b/dockerfiles/OF2412/arm64-deps/Dockerfile
@@ -0,0 +1,43 @@
+# Start from the ubuntu Openfoam 2106 image
+FROM opencfd/openfoam-dev:2412
+USER root
+ARG PYTHON_VERSION=3.7
+ENV PATH="/root/miniconda3/bin:${PATH}"
+
+RUN rm /etc/apt/sources.list.d/openfoam.list && \
+ cp /etc/apt/sources.list /etc/apt/sources.list.backup && \
+ grep -v -e "openfoam" /etc/apt/sources.list.backup > /etc/apt/sources.list && \
+ echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections && \
+ apt-get update && \
+ apt-get install -yy -q pwgen npm nodejs cmake git wget bzip2 unzip libc6-dev && \
+ apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
+
+# Anaconda installing
+RUN wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-aarch64.sh && \
+bash Miniconda3-latest-Linux-aarch64.sh -b && \
+rm Miniconda3-latest-Linux-aarch64.sh && \
+. /root/miniconda3/etc/profile.d/conda.sh && \
+export PATH=/root/miniconda3/bin:$PATH && \
+conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/main && \
+conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/r && \
+conda install -y -c conda-forge cmake pybind11 eigen hdf5 nlopt && \
+git clone https://bitbucket.org/mituq/muq2.git /tmp/muq2 && \
+cd /tmp/muq2 && rm -rf build && mkdir build && cd build && \
+cmake -DCMAKE_INSTALL_PREFIX=/root/miniconda3 -DMUQ_USE_PYTHON=ON .. && \
+make -j4 && make install && \
+cd / && rm -rf /tmp/muq2 && \
+conda clean -y --all
+ENV MUQ_LIBRARIES=/root/miniconda3
+
+# Export OpenFOAM environment variables for use in subsequent builds
+RUN /bin/bash -c "source /usr/lib/openfoam/openfoam2412/etc/bashrc && \
+ echo 'export FOAM_ETC=${FOAM_ETC}' >> /etc/environment && \
+ echo 'export FOAM_APP=${FOAM_APP}' >> /etc/environment && \
+ echo 'export FOAM_APPBIN=${FOAM_APPBIN}' >> /etc/environment && \
+ echo 'export FOAM_LIBBIN=${FOAM_LIBBIN}' >> /etc/environment && \
+ echo 'export FOAM_SRC=${FOAM_SRC}' >> /etc/environment && \
+ echo 'export WM_PROJECT_DIR=${WM_PROJECT_DIR}' >> /etc/environment"
+
+ENV FOAM_ETC=/usr/lib/openfoam/openfoam2412/etc
+RUN echo 'source /usr/lib/openfoam/openfoam2412/etc/bashrc' >> ~/.bashrc
+
diff --git a/dockerfiles/OF2506/Dockerfile b/dockerfiles/OF2506/Dockerfile
new file mode 100644
index 000000000..d37e2ca71
--- /dev/null
+++ b/dockerfiles/OF2506/Dockerfile
@@ -0,0 +1,75 @@
+# Multi-architecture Dockerfile for ITHACA-FV
+# Automatically selects the correct base image based on target platform
+ARG TARGETARCH
+FROM ithacafv/openfoam2506-muq2-pytorch:${TARGETARCH} AS base
+
+LABEL maintainer="giovannistabile@santannapisa.it"
+
+USER root
+
+# Install additional packages
+RUN apt-get update && \
+ apt-get install -y \
+ git \
+ vim \
+ ssh \
+ sudo \
+ wget \
+ software-properties-common && \
+ rm -rf /var/lib/apt/lists/*
+
+# Create ithacafv user and group
+ARG USER=ithacafv
+RUN if id -u 1000 >/dev/null 2>&1; then \
+ userdel $(id -nu 1000) || true; \
+ fi && \
+ if getent group 1000 >/dev/null 2>&1; then \
+ groupdel $(getent group 1000 | cut -d: -f1) || true; \
+ fi && \
+ adduser --disabled-password --gecos '' --uid 1000 $USER && \
+ adduser $USER sudo && \
+ echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
+
+# Set environment variables
+ENV HOME=/home/$USER
+ENV USER=$USER
+
+# Set working directory and clone ITHACA-FV
+WORKDIR /opt
+RUN git clone https://github.com/mathLab/ITHACA-FV.git && \
+ chown -R $USER:$USER ITHACA-FV && \
+ chown -R $USER:$USER /home/$USER
+
+# Environment variables for bashrc
+ARG of_var="source /usr/lib/openfoam/openfoam2412/etc/bashrc"
+ARG ithaca_var="source /opt/ITHACA-FV/etc/bashrc"
+
+# Update bashrc with OpenFOAM and ITHACA-FV sources
+RUN echo $of_var >> /etc/bash.bashrc && \
+ echo $ithaca_var >> /etc/bash.bashrc
+
+# Switch to ithacafv user
+USER $USER
+
+# Build ITHACA-FV
+RUN /bin/bash -c "source /usr/lib/openfoam/openfoam2412/etc/bashrc && \
+ cd ITHACA-FV && \
+ git submodule update --init && \
+ source etc/bashrc && \
+ ./Allwmake -au -j 4"
+
+# Copy binaries and libraries to system paths (as root)
+USER root
+RUN if [ -d "/home/$USER/OpenFOAM/$USER-openfoam2412/platforms/linux64GccDPInt32Opt/bin" ]; then \
+ cp -r /home/$USER/OpenFOAM/$USER-openfoam2412/platforms/linux64GccDPInt32Opt/bin/* /usr/local/bin/ || true; \
+ cp -r /home/$USER/OpenFOAM/$USER-openfoam2412/platforms/linux64GccDPInt32Opt/lib/* /usr/local/lib/ || true; \
+ fi
+
+# Final setup
+USER $USER
+WORKDIR $HOME
+
+# Source bashrc on container start
+RUN /bin/bash -c "source /etc/bash.bashrc"
+
+ENTRYPOINT ["/bin/bash"]
diff --git a/dockerfiles/OF2506/amd64-deps/Dockerfile b/dockerfiles/OF2506/amd64-deps/Dockerfile
new file mode 100644
index 000000000..5efe51943
--- /dev/null
+++ b/dockerfiles/OF2506/amd64-deps/Dockerfile
@@ -0,0 +1,41 @@
+# Start from the ubuntu Openfoam 2106 image
+FROM opencfd/openfoam-dev:2506
+USER root
+ARG PYTHON_VERSION=3.7
+ENV PATH="/root/miniconda3/bin:${PATH}"
+
+RUN rm /etc/apt/sources.list.d/openfoam.list && \
+ cp /etc/apt/sources.list /etc/apt/sources.list.backup && \
+ grep -v -e "openfoam" /etc/apt/sources.list.backup > /etc/apt/sources.list && \
+ echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections && \
+ apt-get update && \
+ apt-get install -yy -q pwgen npm nodejs cmake git wget bzip2 unzip && \
+ apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
+
+# Anaconda installing
+RUN wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh && \
+bash Miniconda3-latest-Linux-x86_64.sh -b && \
+rm Miniconda3-latest-Linux-x86_64.sh && \
+. /root/miniconda3/etc/profile.d/conda.sh && \
+export PATH=/root/miniconda3/bin:$PATH && \
+wget https://download.pytorch.org/libtorch/cpu/libtorch-cxx11-abi-shared-with-deps-2.7.1%2Bcpu.zip && \
+unzip libtorch-cxx11-abi-shared-with-deps-2.7.1+cpu.zip && \
+rm libtorch-cxx11-abi-shared-with-deps-2.7.1+cpu.zip && \
+conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/main && \
+conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/r && \
+conda install -y -c conda-forge muq cmake pybind11 && \
+conda clean -y --all
+ENV TORCH_LIBRARIES=/libtorch
+ENV MUQ_LIBRARIES=/root/miniconda3
+
+# Export OpenFOAM environment variables for use in subsequent builds
+RUN /bin/bash -c "source /usr/lib/openfoam/openfoam2506/etc/bashrc && \
+ echo 'export FOAM_ETC=${FOAM_ETC}' >> /etc/environment && \
+ echo 'export FOAM_APP=${FOAM_APP}' >> /etc/environment && \
+ echo 'export FOAM_APPBIN=${FOAM_APPBIN}' >> /etc/environment && \
+ echo 'export FOAM_LIBBIN=${FOAM_LIBBIN}' >> /etc/environment && \
+ echo 'export FOAM_SRC=${FOAM_SRC}' >> /etc/environment && \
+ echo 'export WM_PROJECT_DIR=${WM_PROJECT_DIR}' >> /etc/environment"
+
+ENV FOAM_ETC=/usr/lib/openfoam/openfoam2506/etc
+RUN echo 'source /usr/lib/openfoam/openfoam2506/etc/bashrc' >> ~/.bashrc
diff --git a/dockerfiles/OF2506/arm64-deps/Dockerfile b/dockerfiles/OF2506/arm64-deps/Dockerfile
new file mode 100644
index 000000000..6d7ea6012
--- /dev/null
+++ b/dockerfiles/OF2506/arm64-deps/Dockerfile
@@ -0,0 +1,43 @@
+# Start from the ubuntu Openfoam 2106 image
+FROM opencfd/openfoam-dev:2506
+USER root
+ARG PYTHON_VERSION=3.7
+ENV PATH="/root/miniconda3/bin:${PATH}"
+
+RUN rm /etc/apt/sources.list.d/openfoam.list && \
+ cp /etc/apt/sources.list /etc/apt/sources.list.backup && \
+ grep -v -e "openfoam" /etc/apt/sources.list.backup > /etc/apt/sources.list && \
+ echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections && \
+ apt-get update && \
+ apt-get install -yy -q pwgen npm nodejs cmake git wget bzip2 unzip libc6-dev && \
+ apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
+
+# Anaconda installing
+RUN wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-aarch64.sh && \
+bash Miniconda3-latest-Linux-aarch64.sh -b && \
+rm Miniconda3-latest-Linux-aarch64.sh && \
+. /root/miniconda3/etc/profile.d/conda.sh && \
+export PATH=/root/miniconda3/bin:$PATH && \
+conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/main && \
+conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/r && \
+conda install -y -c conda-forge cmake pybind11 eigen hdf5 nlopt && \
+git clone https://bitbucket.org/mituq/muq2.git /tmp/muq2 && \
+cd /tmp/muq2 && rm -rf build && mkdir build && cd build && \
+cmake -DCMAKE_INSTALL_PREFIX=/root/miniconda3 -DMUQ_USE_PYTHON=ON .. && \
+make -j4 && make install && \
+cd / && rm -rf /tmp/muq2 && \
+conda clean -y --all
+ENV MUQ_LIBRARIES=/root/miniconda3
+
+# Export OpenFOAM environment variables for use in subsequent builds
+RUN /bin/bash -c "source /usr/lib/openfoam/openfoam2506/etc/bashrc && \
+ echo 'export FOAM_ETC=${FOAM_ETC}' >> /etc/environment && \
+ echo 'export FOAM_APP=${FOAM_APP}' >> /etc/environment && \
+ echo 'export FOAM_APPBIN=${FOAM_APPBIN}' >> /etc/environment && \
+ echo 'export FOAM_LIBBIN=${FOAM_LIBBIN}' >> /etc/environment && \
+ echo 'export FOAM_SRC=${FOAM_SRC}' >> /etc/environment && \
+ echo 'export WM_PROJECT_DIR=${WM_PROJECT_DIR}' >> /etc/environment"
+
+ENV FOAM_ETC=/usr/lib/openfoam/openfoam2506/etc
+RUN echo 'source /usr/lib/openfoam/openfoam2506/etc/bashrc' >> ~/.bashrc
+
diff --git a/dockerfiles/amd64/Dockerfile b/dockerfiles/amd64/Dockerfile
index a4e21aa0e..cbb2a37d7 100644
--- a/dockerfiles/amd64/Dockerfile
+++ b/dockerfiles/amd64/Dockerfile
@@ -1,21 +1,20 @@
-FROM opencfd/openfoam2106-dev
-LABEL maintainer="moaadkhamlich@gmail.com"
+FROM ithacafv/openfoam2506-muq2-pytorch
+LABEL maintainer="giovannistabile@santannapisa.it"
# add enviromental variables and enable the default user
ARG USER=ithacafv
-ARG of_var="source /usr/lib/openfoam/openfoam2106/etc/bashrc"
+ARG of_var="source /usr/lib/openfoam/openfoam2506/etc/bashrc"
ARG ithaca_var="source /usr/lib/ITHACA-FV/etc/bashrc"
-ENV USER $USER
+# ENV USER=$USER
-# Create the user
+# # Create the user
RUN adduser --disabled-password --gecos '' $USER && \
adduser $USER sudo; echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers && \
usermod -a -G $USER $USER && \
- userdel sudofoam && \
- usermod -u 1000 ithacafv && \
- groupmod -g 1000 ithacafv
-#make sure everything is in place
+ usermod -u 9999 ithacafv && \
+ groupmod -g 9999 ithacafv
+# #make sure everything is in place
ENV HOME /home/$USER
RUN chown -R $USER:$USER /home/$USER
RUN chown -R $USER:$USER /home/openfoam && rm -r /home/openfoam && \
@@ -33,24 +32,25 @@ RUN apt-get update &&\
sudo rm -rf /var/lib/apt/lists/*
WORKDIR /usr/lib
-RUN git clone https://github.com/mathLab/ITHACA-FV.git
+RUN git clone https://github.com/ITHACA-FV/ITHACA-FV.git
RUN chown -R $USER:$USER openfoam ITHACA-FV
RUN chown -R $USER:$USER /home/$USER
+RUN chown -R $USER:$USER /root/miniconda3/include
USER $USER
-RUN /bin/bash -c "source /usr/lib/openfoam/openfoam2106/etc/bashrc && \
- cd ITHACA-FV && git submodule update --init && source /etc/bash.bashrc && \
- ./Allwmake -tau -j 4";
+RUN /bin/bash -c "source /usr/lib/openfoam/openfoam2506/etc/bashrc && \
+ cd ITHACA-FV && git submodule update --init && source etc/bashrc && \
+ ./Allwmake -taumq -j 4";
USER root
-RUN cp -r /home/ithacafv/OpenFOAM/ithacafv-v2106/platforms/linux64GccDPInt32Opt/bin/* /bin/
-RUN cp -r /home/ithacafv/OpenFOAM/ithacafv-v2106/platforms/linux64GccDPInt32Opt/lib/* /lib/
+RUN cp -r /home/ithacafv/OpenFOAM/ithacafv-v2506/platforms/linux64GccDPInt32Opt/bin/* /bin/
+RUN cp -r /home/ithacafv/OpenFOAM/ithacafv-v2506/platforms/linux64GccDPInt32Opt/lib/* /lib/
#Update bashrc
RUN echo $of_var >> /etc/bash.bashrc
-RUN echo $ithaca_var >> /etc/bash.bashrc
+RUN echo $ithaca_var >> /root/.bashrc
-#Source bashrc
+# #Source bashrc
USER $USER
RUN /bin/bash -c "source /etc/bash.bashrc"
diff --git a/gtest/Make/options b/gtest/Make/options
index 12747fdf6..b3fad9d66 100755
--- a/gtest/Make/options
+++ b/gtest/Make/options
@@ -13,7 +13,7 @@ EXE_INC = \
-I$(LIB_ITHACA_SRC)/thirdparty/splinter/include \
-w \
-DOFVER=$${WM_PROJECT_VERSION%.*} \
- -std=c++14
+ -std=c++17
EXE_LIBS = \
-lturbulenceModels \
diff --git a/src/ITHACA_CORE/Containers/Modes.C b/src/ITHACA_CORE/Containers/Modes.C
index 4a0414107..4b1dda32e 100644
--- a/src/ITHACA_CORE/Containers/Modes.C
+++ b/src/ITHACA_CORE/Containers/Modes.C
@@ -491,3 +491,4 @@ void Modes::operator=(const
template class Modes;
template class Modes;
template class Modes;
+template class Modes;
\ No newline at end of file
diff --git a/src/ITHACA_CORE/Containers/Modes.H b/src/ITHACA_CORE/Containers/Modes.H
index e41f33c70..82273615d 100644
--- a/src/ITHACA_CORE/Containers/Modes.H
+++ b/src/ITHACA_CORE/Containers/Modes.H
@@ -255,6 +255,7 @@ class Modes : public PtrList>
typedef Modes volScalarModes;
typedef Modes volVectorModes;
typedef Modes surfaceScalarModes;
+typedef Modes pointVectorModes;
#endif
diff --git a/src/ITHACA_CORE/EigenFunctions/EigenFunctions.H b/src/ITHACA_CORE/EigenFunctions/EigenFunctions.H
index 9c9b0742b..40e3d30ab 100644
--- a/src/ITHACA_CORE/EigenFunctions/EigenFunctions.H
+++ b/src/ITHACA_CORE/EigenFunctions/EigenFunctions.H
@@ -466,7 +466,7 @@ bool saveMarketVector (const VectorType & vec, const std::string & filename,
for (label i = 0; i < vec.size(); i++)
{
- internal::putVectorElt(vec(i), out);
+ internal::putDenseElt(vec(i), out);
}
out.close();
return true;
diff --git a/src/ITHACA_CORE/Foam2Eigen/Foam2Eigen.C b/src/ITHACA_CORE/Foam2Eigen/Foam2Eigen.C
index 4dbe2f5d4..eada5b62c 100644
--- a/src/ITHACA_CORE/Foam2Eigen/Foam2Eigen.C
+++ b/src/ITHACA_CORE/Foam2Eigen/Foam2Eigen.C
@@ -220,16 +220,34 @@ List Foam2Eigen::field2EigenBC(
label size = field.boundaryField().size();
Out.resize(size);
- for (label i = 0; i < size; i++)
- {
- label sizei = field.boundaryField()[i].size();
- Out[i].resize(sizei * 3);
+ constexpr bool check_vol = std::is_same::value || std::is_same::value;
+ if constexpr(check_vol){
+ for (label i = 0; i < size; i++ )
+ {
+ label sizei = field.boundaryField()[i].size();
+ Out[i].resize(sizei * 3);
- for (label k = 0; k < sizei; k++)
+ for (label k = 0; k < sizei ; k++)
+ {
+ Out[i](k) = field.boundaryField()[i][k][0];
+ Out[i](k + sizei) = field.boundaryField()[i][k][1];
+ Out[i](k + 2 * sizei) = field.boundaryField()[i][k][2];
+ }
+ }
+ }
+
+ else if constexpr(std::is_same::value)
+ {
+ for (label i = 0; i < size; i++ )
{
- for (label j = 0; j < 3; j++)
+ label sizei = field.boundaryField()[i].size();
+ Out[i].resize(sizei * 3);
+
+ for (label k = 0; k < sizei ; k++)
{
- Out[i](k + j * sizei) = field.boundaryField()[i][k][j];
+ Out[i](k) = field.boundaryField()[i].patchInternalField()()[k][0];
+ Out[i](k + sizei) = field.boundaryField()[i].patchInternalField()()[k][1];
+ Out[i](k + 2 * sizei) = field.boundaryField()[i].patchInternalField()()[k][2];
}
}
}
@@ -355,6 +373,8 @@ List Foam2Eigen::PtrList2EigenBC(
template List Foam2Eigen::PtrList2EigenBC(
PtrList& fields, label Nfields);
+template List Foam2Eigen::PtrList2EigenBC(
+PtrList& fields, label Nfields);
template class PatchField, class GeoMesh>
List Foam2Eigen::PtrList2EigenBC(
@@ -509,6 +529,8 @@ GeometricField Foam2Eigen::Eigen2field(
template volVectorField Foam2Eigen::Eigen2field(
volVectorField& field_in, Eigen::VectorXd& eigen_vector, bool correctBC);
+template pointVectorField Foam2Eigen::Eigen2field(
+ pointVectorField& field_in, Eigen::VectorXd& eigen_vector, bool correctBC);
template class PatchField, class GeoMesh>
GeometricField Foam2Eigen::Eigen2field(
@@ -679,16 +701,20 @@ template Eigen::MatrixXd Foam2Eigen::PtrList2Eigen(PtrList&
fields,
label Nfields);
template Eigen::MatrixXd
-Foam2Eigen::PtrList2Eigen
-(PtrList&
- fields,
- label Nfields);
+Foam2Eigen::PtrList2Eigen(PtrList&
+ fields,
+ label Nfields);
+template Eigen::MatrixXd
+Foam2Eigen::PtrList2Eigen(PtrList&
+ fields, label Nfields);
+
template Eigen::MatrixXd
Foam2Eigen::PtrList2Eigen
(PtrList&
fields,
label Nfields);
+
template <>
void Foam2Eigen::fvMatrix2Eigen(fvMatrix foam_matrix,
Eigen::MatrixXd& A,
@@ -774,6 +800,137 @@ void Foam2Eigen::fvMatrix2Eigen(fvMatrix foam_matrix,
}
}
+
+template
+void Foam2Eigen::fvMat2Eigen(fvMatrix foam_matrix,
+ SparseMatType& A,
+ VecType& b)
+{
+ //using Trip = Eigen::Triplet;
+ label sizeA = foam_matrix.diag().size();
+ label nel = foam_matrix.diag().size() + foam_matrix.upper().size() +
+ foam_matrix.lower().size();
+ A.resize(sizeA, sizeA);
+ b.resize(sizeA);
+ A.reserve(nel);
+ typedef Eigen::Triplet Trip;
+ std::vector tripletList;
+ tripletList.reserve(nel);
+
+ for (label i = 0; i < sizeA; ++i)
+ {
+ tripletList.emplace_back(i, i, foam_matrix.diag()[i]);
+ b(i) = foam_matrix.source()[i];
+ }
+
+ const lduAddressing& addr = foam_matrix.lduAddr();
+ const labelList& lowerAddr = addr.lowerAddr();
+ const labelList& upperAddr = addr.upperAddr();
+ forAll(lowerAddr, i)
+ {
+ tripletList.emplace_back(lowerAddr[i], upperAddr[i], foam_matrix.upper()[i]);
+ tripletList.emplace_back(upperAddr[i], lowerAddr[i], foam_matrix.lower()[i]);
+ }
+
+ forAll(foam_matrix.psi().boundaryField(), I)
+ {
+ const fvPatch& ptch = foam_matrix.psi().boundaryField()[I].patch();
+ forAll(ptch, J)
+ {
+ label w = ptch.faceCells()[J];
+ tripletList.emplace_back(w, w, foam_matrix.internalCoeffs()[I][J]);
+ b(w) += foam_matrix.boundaryCoeffs()[I][J];
+ }
+ }
+
+ A.setFromTriplets(tripletList.begin(), tripletList.end());
+}
+
+// Explicit instantiations
+template void Foam2Eigen::fvMat2Eigen, Eigen::VectorXd>(
+ fvMatrix foam_matrix,
+ Eigen::SparseMatrix& A,
+ Eigen::VectorXd& b);
+template void Foam2Eigen::fvMat2Eigen, Eigen::VectorXd>(
+ fvMatrix foam_matrix,
+ Eigen::SparseMatrix& A,
+ Eigen::VectorXd& b);
+
+
+template
+void Foam2Eigen::fvMat2Eigen(fvMatrix foam_matrix,
+ SparseMatType& A,
+ VecType& b)
+{
+ label sizeA = foam_matrix.diag().size();
+ label nel = foam_matrix.diag().size() + foam_matrix.upper().size() +
+ foam_matrix.lower().size();
+ A.resize(sizeA * 3, sizeA * 3);
+ A.reserve(nel * 3);
+ b.resize(sizeA * 3);
+ typedef Eigen::Triplet Trip;
+ std::vector tripletList;
+ tripletList.reserve(nel * 3);
+
+ for (auto i = 0; i < sizeA; i++)
+ {
+ tripletList.push_back(Trip(i, i, foam_matrix.diag()[i]));
+ tripletList.push_back(Trip(sizeA + i, sizeA + i, foam_matrix.diag()[i]));
+ tripletList.push_back(Trip(2 * sizeA + i, 2 * sizeA + i,
+ foam_matrix.diag()[i]));
+ b(i) = foam_matrix.source()[i][0];
+ b(sizeA + i) = foam_matrix.source()[i][1];
+ b(2 * sizeA + i) = foam_matrix.source()[i][2];
+ }
+
+ const lduAddressing& addr = foam_matrix.lduAddr();
+ const labelList& lowerAddr = addr.lowerAddr();
+ const labelList& upperAddr = addr.upperAddr();
+ forAll(lowerAddr, i)
+ {
+ tripletList.push_back(Trip(lowerAddr[i], upperAddr[i], foam_matrix.upper()[i]));
+ tripletList.push_back(Trip(lowerAddr[i] + sizeA, upperAddr[i] + sizeA,
+ foam_matrix.upper()[i]));
+ tripletList.push_back(Trip(lowerAddr[i] + sizeA * 2, upperAddr[i] + sizeA * 2,
+ foam_matrix.upper()[i]));
+ tripletList.push_back(Trip(upperAddr[i], lowerAddr[i], foam_matrix.lower()[i]));
+ tripletList.push_back(Trip(upperAddr[i] + sizeA, lowerAddr[i] + sizeA,
+ foam_matrix.lower()[i]));
+ tripletList.push_back(Trip(upperAddr[i] + sizeA * 2, lowerAddr[i] + sizeA * 2,
+ foam_matrix.lower()[i]));
+ }
+
+ forAll(foam_matrix.psi().boundaryField(), I)
+ {
+ const fvPatch& ptch = foam_matrix.psi().boundaryField()[I].patch();
+ forAll(ptch, J)
+ {
+ label w = ptch.faceCells()[J];
+ tripletList.push_back(Trip(w, w, foam_matrix.internalCoeffs()[I][J][0]));
+ tripletList.push_back(Trip(w + sizeA, w + sizeA,
+ foam_matrix.internalCoeffs()[I][J][1]));
+ tripletList.push_back(Trip(w + sizeA * 2, w + sizeA * 2,
+ foam_matrix.internalCoeffs()[I][J][2]));
+ b(w) += foam_matrix.boundaryCoeffs()[I][J][0];
+ b(w + sizeA) += foam_matrix.boundaryCoeffs()[I][J][1];
+ b(w + sizeA * 2) += foam_matrix.boundaryCoeffs()[I][J][2];
+ }
+ }
+
+ A.setFromTriplets(tripletList.begin(), tripletList.end());
+}
+
+template void Foam2Eigen::fvMat2Eigen, Eigen::VectorXd>(
+ fvMatrix foam_matrix,
+ Eigen::SparseMatrix& A,
+ Eigen::VectorXd& b);
+
+template void Foam2Eigen::fvMat2Eigen, Eigen::VectorXd>(
+ fvMatrix foam_matrix,
+ Eigen::SparseMatrix& A,
+ Eigen::VectorXd& b);
+
+/////////////////////////////////////////////////////////////////////////////////////////////
template <>
void Foam2Eigen::fvMatrix2Eigen(fvMatrix foam_matrix,
Eigen::SparseMatrix& A, Eigen::VectorXd& b)
diff --git a/src/ITHACA_CORE/Foam2Eigen/Foam2Eigen.H b/src/ITHACA_CORE/Foam2Eigen/Foam2Eigen.H
index 9829d9f0b..a09628422 100644
--- a/src/ITHACA_CORE/Foam2Eigen/Foam2Eigen.H
+++ b/src/ITHACA_CORE/Foam2Eigen/Foam2Eigen.H
@@ -39,6 +39,8 @@
#include "fvCFD.H"
#include "IOmanip.H"
+#include "pointMesh.H"
+#include "pointPatchField.H"
#include "ITHACAassert.H"
#include "ITHACAutilities.H"
#include
@@ -46,6 +48,7 @@
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wold-style-cast"
#include
+#include
#pragma GCC diagnostic pop
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -86,6 +89,20 @@ class Foam2Eigen
template
static void fvMatrix2Eigen(fvMatrix foam_matrix, type_A& A,
type_B& b);
+ /*
+ template
+ static void fvMat2Eigen(fvMatrix foam_matrix,
+ SparseMatType& A,
+ VecType& b);*/
+ template
+ static void fvMat2Eigen(Foam::fvMatrix foam_matrix,
+ SparseMatType& A,
+ VecType& b);
+
+ template
+ static void fvMat2Eigen(Foam::fvMatrix foam_matrix,
+ SparseMatType& A,
+ VecType& b);
//----------------------------------------------------------------------
/// @brief Convert a ldu OpenFOAM matrix into a Eigen Matrix A
diff --git a/src/ITHACA_CORE/ITHACAPOD/ITHACAPOD.C b/src/ITHACA_CORE/ITHACAPOD/ITHACAPOD.C
index e88f42213..7fa6d4224 100644
--- a/src/ITHACA_CORE/ITHACAPOD/ITHACAPOD.C
+++ b/src/ITHACA_CORE/ITHACAPOD/ITHACAPOD.C
@@ -94,6 +94,7 @@ void getModes(
bool correctBC)
{
ITHACAparameters* para(ITHACAparameters::getInstance());
+ constexpr bool check_vol = std::is_same::value || std::is_same::value;
word PODkey = "POD_" + fieldName;
word PODnorm = para->ITHACAdict->lookupOrDefault(PODkey, "L2");
M_Assert(PODnorm == "L2" ||
@@ -154,12 +155,11 @@ void getModes(
if (para->eigensolver == "spectra")
{
- Spectra::SymEigsSolver>
- es(& op, nmodes, ncv);
+ Spectra::SymEigsSolver> es(op, nmodes, ncv);
std::cout << "Using Spectra EigenSolver " << std::endl;
es.init();
- es.compute(1000, 1e-10, Spectra::LARGEST_ALGE);
- M_Assert(es.info() == Spectra::SUCCESSFUL,
+ es.compute(Spectra::SortRule::LargestAlge);
+ M_Assert(es.info() == Spectra::CompInfo::Successful,
"The Eigenvalue Decomposition did not succeed");
eigenVectoreig = es.eigenvectors().real();
eigenValueseig = es.eigenvalues().real();
@@ -198,6 +198,15 @@ void getModes(
{
normFact(i, 0) = std::sqrt((modesEig.col(i).transpose() * V.asDiagonal() *
modesEig.col(i))(0, 0));
+ if constexpr(check_vol){
+ normFact(i, 0) = std::sqrt((modesEig.col(i).transpose() * V.asDiagonal() *
+ modesEig.col(i))(0, 0));
+ }
+
+ else if constexpr(std::is_same::value){
+ normFact(i, 0) = std::sqrt((modesEig.col(i).transpose() * modesEig.col(i))(0, 0));
+ }
+
if (Pstream::parRun())
{
normFact(i, 0) = (modesEig.col(i).transpose() * V.asDiagonal() *
@@ -313,6 +322,10 @@ template void getModes(
PtrList& snapshots, PtrList& modes,
word fieldName, bool podex, bool supex, bool sup, label nmodes,
bool correctBC);
+template void getModes(
+ PtrList& snapshots, PtrList& modes,
+ word fieldName, bool podex, bool supex, bool sup, label nmodes,
+ bool correctBC);
template class PatchField, class GeoMesh>
void getModesMemoryEfficient(
@@ -458,12 +471,11 @@ void getModesMemoryEfficient(
// Use Spectra solver for large eigenvalue problems
std::cout << "Using Spectra EigenSolver " << std::endl;
Spectra::DenseSymMatProd op(_corMatrix);
- Spectra::SymEigsSolver>
- solver(&op, nmodes, nSnaps);
+ Spectra::SymEigsSolver>
+ solver(op, nmodes, nSnaps);
solver.init();
- solver.compute(1000, 1e-10, Spectra::LARGEST_ALGE);
- M_Assert(solver.info() == Spectra::SUCCESSFUL,
+ solver.compute(Spectra::SortRule::LargestAlge);
+ M_Assert(solver.info() == Spectra::CompInfo::Successful,
"Eigenvalue decomposition failed");
eigenVectors = solver.eigenvectors().real();
eigenValues = solver.eigenvalues().real();
@@ -716,14 +728,14 @@ void getWeightedModes(
label ncv = snapshots.size();
Spectra::DenseSymMatProd op(_corMatrix);
Eigen::SelfAdjointEigenSolver esEg;
- Spectra::SymEigsSolver>
- es(& op, nmodes, ncv);
+ Spectra::SymEigsSolver>
+ es(op, nmodes, ncv);
if (para->eigensolver == "spectra")
{
std::cout << "Using Spectra EigenSolver " << std::endl;
es.init();
- es.compute(1000, 1e-10, Spectra::LARGEST_ALGE);
- M_Assert(es.info() == Spectra::SUCCESSFUL,
+ es.compute(Spectra::SortRule::LargestAlge);
+ M_Assert(es.info() == Spectra::CompInfo::Successful,
"The Eigenvalue Decomposition did not succeed");
eigenVectoreig = es.eigenvectors().real();
eigenValueseig = es.eigenvalues().real();
@@ -1176,14 +1188,14 @@ DEIMmodes(List> & A,
Info << "####### Performing the POD for the Matrix List #######" << endl;
Spectra::DenseSymMatProd opA(corMatrixA);
Spectra::DenseSymMatProd opB(corMatrixB);
- Spectra::SymEigsSolver>
- esA(& opA, nmodesA, nmodesA + 10);
- Spectra::SymEigsSolver>
+ esA(opA, nmodesA, nmodesA + 10);
+ Spectra::SymEigsSolver>
- esB(& opB, nmodesB, nmodesB + 10);
+ esB(opB, nmodesB, nmodesB + 10);
esA.init();
esB.init();
- esA.compute();
+ esA.compute(Spectra::SortRule::LargestAlge);
if (nmodesB != 1)
{
@@ -1195,12 +1207,12 @@ DEIMmodes(List> & A,
Eigen::VectorXd eigenValueseigB;
Eigen::MatrixXd eigenVectorseigB;
- if (esA.info() == Spectra::SUCCESSFUL)
+ if (esA.info() == Spectra::CompInfo::Successful)
{
eigenValueseigA = esA.eigenvalues().real();
eigenVectorseigA = esA.eigenvectors().real();
- if (esB.info() == Spectra::SUCCESSFUL && nmodesB != 1)
+ if (esB.info() == Spectra::CompInfo::Successful && nmodesB != 1)
{
eigenValueseigB = esB.eigenvalues().real();
eigenVectorseigB = esB.eigenvectors().real();
@@ -1410,12 +1422,12 @@ void getModes(
if (para->eigensolver == "spectra")
{
- Spectra::SymEigsSolver>
- es(& op, nmodes, ncv);
+ Spectra::SymEigsSolver< Spectra::DenseSymMatProd>
+ es(op, nmodes, ncv);
std::cout << "Using Spectra EigenSolver " << std::endl;
es.init();
- es.compute(1000, 1e-10, Spectra::LARGEST_ALGE);
- M_Assert(es.info() == Spectra::SUCCESSFUL,
+ es.compute(Spectra::SortRule::LargestAlge);
+ M_Assert(es.info() == Spectra::CompInfo::Successful,
"The Eigenvalue Decomposition did not succeed");
eigenVectoreig = es.eigenvectors().real();
eigenValueseig = es.eigenvalues().real();
@@ -1534,21 +1546,21 @@ DEIMmodes(PtrList & MatrixList, label nmodesA, label nmodesB,
Spectra::DenseSymMatProd opB(corMatrixB);
label ncvA = MatrixList.size();
label ncvB = MatrixList.size();
- Spectra::SymEigsSolver>
- esA(& opA, nmodesA, ncvA);
- Spectra::SymEigsSolver>
+ esA(opA, nmodesA, ncvA);
+ Spectra::SymEigsSolver>
- esB(& opB, nmodesB, ncvB);
+ esB(opB, nmodesB, ncvB);
esA.init();
esB.init();
- esA.compute(1000, 1e-10, Spectra::LARGEST_ALGE);
- M_Assert(esA.info() == Spectra::SUCCESSFUL,
+ esA.compute(Spectra::SortRule::LargestAlge);
+ M_Assert(esA.info() == Spectra::CompInfo::Successful,
"The Eigenvalue Decomposition did not succeed");
if (nmodesB != 1)
{
- esB.compute(1000, 1e-10, Spectra::LARGEST_ALGE);
- M_Assert(esB.info() == Spectra::SUCCESSFUL,
+ esB.compute(Spectra::SortRule::LargestAlge);
+ M_Assert(esB.info() == Spectra::CompInfo::Successful,
"The Eigenvalue Decomposition did not succeed");
}
Info << "####### End of the POD decomposition for the Matrix List #######" <<
@@ -1741,12 +1753,12 @@ PtrList> DEIMmodes(
if (para->eigensolver == "spectra")
{
- Spectra::SymEigsSolver>
- es(& op, nmodes, ncv);
+ Spectra::SymEigsSolver< Spectra::DenseSymMatProd>
+ es(op, nmodes, ncv);
std::cout << "Using Spectra EigenSolver " << std::endl;
es.init();
- es.compute(1000, 1e-10, Spectra::LARGEST_ALGE);
- M_Assert(es.info() == Spectra::SUCCESSFUL,
+ es.compute(Spectra::SortRule::LargestAlge);
+ M_Assert(es.info() == Spectra::CompInfo::Successful,
"The Eigenvalue Decomposition did not succeed");
eigenVectoreig = es.eigenvectors().real();
eigenValueseig = es.eigenvalues().real();
@@ -1924,12 +1936,12 @@ void getModes(
if (para->eigensolver == "spectra")
{
- Spectra::SymEigsSolver>
- es(& op, nmodes, ncv);
+ Spectra::SymEigsSolver>
+ es(op, nmodes, ncv);
std::cout << "Using Spectra EigenSolver " << std::endl;
es.init();
- es.compute(1000, 1e-10, Spectra::LARGEST_ALGE);
- M_Assert(es.info() == Spectra::SUCCESSFUL,
+ es.compute(Spectra::SortRule::LargestAlge);
+ M_Assert(es.info() == Spectra::CompInfo::Successful,
"The Eigenvalue Decomposition did not succeed");
eigenVectoreig = es.eigenvectors().real();
eigenValueseig = es.eigenvalues().real();
diff --git a/src/ITHACA_CORE/ITHACAstream/ITHACAstream.C b/src/ITHACA_CORE/ITHACAstream/ITHACAstream.C
index 025c87864..f1f525320 100644
--- a/src/ITHACA_CORE/ITHACAstream/ITHACAstream.C
+++ b/src/ITHACA_CORE/ITHACAstream/ITHACAstream.C
@@ -474,7 +474,7 @@ GeometricField readFieldByIndex(
IOobject
(
field.name(),
- casename + runTime2.times()[index + 2].name(),
+ casename + "/" + runTime2.times()[index + 2].name(),
field.mesh(),
IOobject::MUST_READ
),
@@ -486,9 +486,9 @@ GeometricField readFieldByIndex(
word timename(field.mesh().time().rootPath() + "/" +
field.mesh().time().caseName());
timename = timename.substr(0, timename.find_last_of("\\/"));
- timename = timename + "/" + casename + "processor" + name(Pstream::myProcNo());
+ timename = timename + "/" + casename + "/" + "processor" + name(Pstream::myProcNo());
int last_s = numberOfFiles(casename,
- "processor" + name(Pstream::myProcNo()) + "/");
+ "processor" + name(Pstream::myProcNo()));
if (index >= last_s - 1)
{
@@ -519,6 +519,8 @@ void read_fields(
{
ITHACAparameters* para(ITHACAparameters::getInstance());
fvMesh& mesh = para->mesh;
+ const pointMesh& pMesh = pointMesh::New(mesh);
+ constexpr bool check_vol = std::is_same::value || std::is_same::value;
if (!Pstream::parRun())
{
Info << "######### Reading the Data for " << Name << " #########" << endl;
@@ -540,21 +542,43 @@ void read_fields(
{
last_s = min(runTime2.times().size(), n_snap + 2);
}
- for (int i = 2 + first_snap; i < last_s + first_snap; i++)
+ if constexpr(check_vol)
{
- GeometricField tmp_field(
- IOobject
- (
- Name,
- casename + runTime2.times()[i].name(),
- mesh,
- IOobject::MUST_READ
- ),
- mesh
- );
- Lfield.append(tmp_field.clone());
- printProgress(double(i + 1) / (last_s + first_snap));
- }
+ for (int i = 2 + first_snap; i < last_s + first_snap; i++)
+ {
+ GeometricField tmp_field(
+ IOobject
+ (
+ Name,
+ casename + runTime2.times()[i].name(),
+ mesh,
+ IOobject::MUST_READ
+ ),
+ mesh
+ );
+ Lfield.append(tmp_field.clone());
+ printProgress(double(i + 1) / (last_s + first_snap));
+ }
+ }
+
+ else if constexpr(std::is_same::value)
+ {
+ for (int i = 2 + first_snap; i < last_s + first_snap; i++)
+ {
+ GeometricField tmp_field(
+ IOobject
+ (
+ Name,
+ casename + runTime2.times()[i].name(),
+ mesh,
+ IOobject::MUST_READ
+ ),
+ pMesh
+ );
+ Lfield.append(tmp_field.clone());
+ printProgress(double(i + 1) / (last_s + first_snap));
+ }
+ }
std::cout << std::endl;
}
else
@@ -564,7 +588,7 @@ void read_fields(
word timename(mesh.time().rootPath() + "/" +
mesh.time().caseName() );
timename = timename.substr(0, timename.find_last_of("\\/"));
- timename = timename + "/" + casename + "processor" + name(Pstream::myProcNo());
+ timename = timename + "/" + casename + "/" + "processor" + name(Pstream::myProcNo());
int last_s = numberOfFiles(casename,
"processor" + name(Pstream::myProcNo()) + "/");
@@ -582,22 +606,41 @@ void read_fields(
{
last_s = min(last_s, n_snap + 2);
}
-
- for (int i = 1 + first_snap; i < last_s + first_snap; i++)
- {
- GeometricField tmp_field(
- IOobject
- (
- Name,
- timename + "/" + name(i),
- mesh,
- IOobject::MUST_READ
- ),
- mesh
- );
- Lfield.append(tmp_field.clone());
- printProgress(double(i + 1) / (last_s + first_snap));
+ if constexpr(check_vol){
+ for (int i = 1 + first_snap; i < last_s + first_snap; i++)
+ {
+ GeometricField tmp_field(
+ IOobject
+ (
+ Name,
+ timename + "/" + name(i),
+ mesh,
+ IOobject::MUST_READ
+ ),
+ mesh
+ );
+ Lfield.append(tmp_field.clone());
+ printProgress(double(i + 1) / (last_s + first_snap));
+ }
}
+
+ else if constexpr(std::is_same::value){
+ for (int i = 1 + first_snap; i < last_s + first_snap; i++)
+ {
+ GeometricField tmp_field(
+ IOobject
+ (
+ Name,
+ timename + "/" + name(i),
+ mesh,
+ IOobject::MUST_READ
+ ),
+ pMesh
+ );
+ Lfield.append(tmp_field.clone());
+ printProgress(double(i + 1) / (last_s + first_snap));
+ }
+ }
Info << endl;
}
@@ -609,6 +652,10 @@ void read_fields(
GeometricField& field,
fileName casename, int first_snap, int n_snap)
{
+ ITHACAparameters* para(ITHACAparameters::getInstance());
+ fvMesh& mesh = para->mesh;
+ const pointMesh& pMesh = pointMesh::New(mesh );
+ constexpr bool check_vol = std::is_same::value || std::is_same::value;
if (!Pstream::parRun())
{
Info << "######### Reading the Data for " << field.name() << " #########" <<
@@ -632,22 +679,43 @@ void read_fields(
{
last_s = min(runTime2.times().size(), n_snap + 2);
}
-
- for (int i = 2 + first_snap; i < last_s + first_snap; i++)
+ if constexpr(check_vol)
{
- GeometricField tmp_field(
- IOobject
- (
- field.name(),
- casename + runTime2.times()[i].name(),
- field.mesh(),
- IOobject::MUST_READ
- ),
- field.mesh()
- );
- Lfield.append(tmp_field.clone());
- printProgress(double(i + 1) / (last_s + first_snap));
+ for (int i = 2 + first_snap; i < last_s + first_snap; i++)
+ {
+ GeometricField tmp_field(
+ IOobject
+ (
+ field.name(),
+ casename + runTime2.times()[i].name(),
+ field.mesh(),
+ IOobject::MUST_READ
+ ),
+ field.mesh()
+ );
+ Lfield.append(tmp_field.clone());
+ printProgress(double(i + 1) / (last_s + first_snap));
+ }
}
+
+ else if constexpr(std::is_same::value)
+ {
+ for (int i = 2 + first_snap; i < last_s + first_snap; i++)
+ {
+ GeometricField tmp_field(
+ IOobject
+ (
+ field.name(),
+ casename + runTime2.times()[i].name(),
+ field.mesh().thisDb(),
+ IOobject::MUST_READ
+ ),
+ pMesh
+ );
+ Lfield.append(tmp_field.clone());
+ printProgress(double(i + 1) / (last_s + first_snap));
+ }
+ }
std::cout << std::endl;
}
@@ -658,7 +726,7 @@ void read_fields(
word timename(field.mesh().time().rootPath() + "/" +
field.mesh().time().caseName() );
timename = timename.substr(0, timename.find_last_of("\\/"));
- timename = timename + "/" + casename + "processor" + name(Pstream::myProcNo());
+ timename = timename + "/" + casename + "/" + "processor" + name(Pstream::myProcNo());
int last_s = numberOfFiles(casename,
"processor" + name(Pstream::myProcNo()) + "/");
@@ -676,21 +744,22 @@ void read_fields(
{
last_s = min(last_s, n_snap + 2);
}
-
- for (int i = 1 + first_snap; i < last_s + first_snap; i++)
- {
- GeometricField tmp_field(
- IOobject
- (
- field.name(),
- timename + "/" + name(i),
- field.mesh(),
- IOobject::MUST_READ
- ),
- field.mesh()
- );
- Lfield.append(tmp_field.clone());
- printProgress(double(i + 1) / (last_s + first_snap));
+ if constexpr(check_vol){
+ for (int i = 1 + first_snap; i < last_s + first_snap; i++)
+ {
+ GeometricField tmp_field(
+ IOobject
+ (
+ field.name(),
+ timename + "/" + name(i),
+ field.mesh(),
+ IOobject::MUST_READ
+ ),
+ field.mesh()
+ );
+ Lfield.append(tmp_field.clone());
+ printProgress(double(i + 1) / (last_s + first_snap));
+ }
}
Info << endl;
@@ -703,12 +772,12 @@ void readMiddleFields(
GeometricField& field, fileName casename)
{
int par = 1;
- M_Assert(ITHACAutilities::check_folder(casename + name(par)) != 0,
+ M_Assert(ITHACAutilities::check_folder(casename + "/" + name(par)) != 0,
"No parameter dependent solutions stored into Offline folder");
- while (ITHACAutilities::check_folder(casename + name(par)))
+ while (ITHACAutilities::check_folder(casename + "/" + name(par)))
{
- read_fields(Lfield, field, casename + name(par) + "/");
+ read_fields(Lfield, field, casename + "/" + name(par));
par++;
}
}
@@ -720,16 +789,16 @@ void readConvergedFields(
fileName casename)
{
int par = 1;
- M_Assert(ITHACAutilities::check_folder(casename + name(par)) != 0,
+ M_Assert(ITHACAutilities::check_folder(casename + "/" + name(par)) != 0,
"No parameter dependent solutions stored into Offline folder");
std::cout << "######### Reading the Data for " << field.name() << " #########"
<< std::endl;
- while (ITHACAutilities::check_folder(casename + name(par)))
+ while (ITHACAutilities::check_folder(casename + "/" + name(par)))
{
int last = 1;
- while (ITHACAutilities::check_folder(casename + name(par) + "/" + name(last)))
+ while (ITHACAutilities::check_folder(casename + "/" + name(par) + "/" + name(last)))
{
last++;
}
@@ -738,7 +807,7 @@ void readConvergedFields(
IOobject
(
field.name(),
- casename + name(par) + "/" + name(last - 1),
+ casename + "/" + name(par) + "/" + name(last - 1),
field.mesh(),
IOobject::MUST_READ
),
@@ -768,7 +837,7 @@ void read_last_fields(
IOobject
(
field.name(),
- casename + runTime2.times()[last_s - 1].name(),
+ casename + "/" + runTime2.times()[last_s - 1].name(),
field.mesh(),
IOobject::MUST_READ
),
@@ -781,7 +850,7 @@ void read_last_fields(
IOobject
(
field.name(),
- casename + runTime2.times()[last_s - 1].name(),
+ casename + "/" + runTime2.times()[last_s - 1].name(),
field.mesh(),
IOobject::MUST_READ
),
@@ -799,9 +868,9 @@ void read_last_fields(
word timename(field.mesh().time().rootPath() + "/" +
field.mesh().time().caseName() );
timename = timename.substr(0, timename.find_last_of("\\/"));
- timename = timename + "/" + casename + "processor" + name(Pstream::myProcNo());
+ timename = timename + "/" + casename + "/" + "processor" + name(Pstream::myProcNo());
int last_s = numberOfFiles(casename,
- "processor" + name(Pstream::myProcNo()) + "/");
+ "processor" + name(Pstream::myProcNo()));
#if defined(OFVER) && (OFVER >= 2212)
Lfield.emplace_back
(
@@ -840,12 +909,12 @@ void readLastFields(
const fileName casename)
{
int par = 1;
- M_Assert(ITHACAutilities::check_folder(casename + name(par)) != 0,
+ M_Assert(ITHACAutilities::check_folder(casename + "/" + name(par)) != 0,
"No parameter dependent solutions stored into Offline folder");
- while (ITHACAutilities::check_folder(casename + name(par)))
+ while (ITHACAutilities::check_folder(casename + "/" + name(par)))
{
- read_last_fields(Lfield, field, casename + name(par) + "/");
+ read_last_fields(Lfield, field, casename + "/" + name(par));
par++;
}
}
@@ -899,6 +968,9 @@ template void exportFields(
template void exportFields(
PtrList> & field,
word folder, word fieldname);
+template void exportFields(
+ PtrList>& field,
+ word folder, word fieldname);
template class PatchField, class GeoMesh >
void exportSolution(GeometricField& s,
@@ -945,6 +1017,10 @@ template void exportSolution(
GeometricField& s,
fileName subfolder, fileName folder,
word fieldName);
+template void exportSolution(
+ GeometricField & s,
+ fileName subfolder, fileName folder,
+ word fieldName);
template class PatchField, class GeoMesh>
void exportSolution(GeometricField& s,
@@ -984,6 +1060,10 @@ template void exportSolution(
GeometricField& s,
fileName subfolder, fileName folder);
+template void exportSolution(
+ GeometricField & s,
+ fileName subfolder, fileName folder);
+
template void exportSolution(
GeometricField& s,
fileName subfolder, fileName folder);
@@ -1062,6 +1142,10 @@ void load(List> & MatrixList, word folder,
MatrixList.append(A);
}
}
+template void read_fields(PtrList& Lfield,word Name,
+ fileName casename, int first_snap, int n_snap);
+template void read_fields(PtrList& Lfield,pointVectorField& field,
+fileName casename, int first_snap, int n_snap);
template void read_fields(PtrList& Lfield,
word Name,
@@ -1090,6 +1174,9 @@ template void read_fields(PtrList& Lfield,
surfaceVectorField& field, fileName casename, int first_snap, int n_snap);
template void readMiddleFields(PtrList& Lfield,
volScalarField& field, fileName casename);
+
+template void readMiddleFields(PtrList & Lfield,
+ pointVectorField& field, fileName casename);
template void readMiddleFields(PtrList& Lfield,
volVectorField& field, fileName casename);
template void readMiddleFields(PtrList& Lfield,
@@ -1129,12 +1216,14 @@ template void readLastFields(PtrList&
Lfield, const surfaceScalarField& field, const fileName casename);
template void readLastFields(PtrList&
Lfield, const surfaceVectorField& field, const fileName casename);
+// template void readLastFields(PtrList &
+// Lfield, const pointVectorField& field, const fileName casename);
template
void exportList(T& list, word folder, word filename)
{
mkDir(folder);
- word fieldname = folder + filename;
+ word fieldname = folder + "/" + filename;
OFstream os(fieldname);
for (int i = 0; i < list.size(); i++)
diff --git a/src/ITHACA_CORE/ITHACAstream/cnpy.C b/src/ITHACA_CORE/ITHACAstream/cnpy.C
index 98135a4bc..f36b8476e 100644
--- a/src/ITHACA_CORE/ITHACAstream/cnpy.C
+++ b/src/ITHACA_CORE/ITHACAstream/cnpy.C
@@ -525,16 +525,14 @@ void cnpy::save(const Eigen::Tensor&
template
Eigen::Matrix cnpy::load(
Eigen::Matrix& mat,
- const std::string fname, std::string order)
+ const std::string fname)
{
- M_Assert(order == "rowMajor" ||
- order == "colMajor", "Order can be only rowMajor or colMajor");
NpyArray arr = npy_load(fname);
assert(arr.shape.size() == 2);
mat.resize(arr.shape[0], arr.shape[1]);
std::vector data = arr.as_vec();
- if (order == "rowMajor")
+ if (!arr.fortran_order)
{
for (size_t i = 0; i < arr.shape[0]; ++i)
{
@@ -544,13 +542,13 @@ Eigen::Matrix cnpy::load(
}
}
}
- else if (order == "colMajor")
+ else
{
for (size_t i = 0; i < arr.shape[0]; ++i)
{
for (size_t j = 0; j < arr.shape[1]; ++j)
{
- data[arr.shape[0] * j + i];
+ mat(i, j) = data[arr.shape[0] * j + i];
}
}
}
@@ -561,17 +559,15 @@ Eigen::Matrix cnpy::load(
template
Eigen::Tensor cnpy::load(Eigen::Tensor& tens,
- const std::string fname, std::string order)
+ const std::string fname)
{
- M_Assert(order == "rowMajor" ||
- order == "colMajor", "Order can be only rowMajor or colMajor");
NpyArray arr = npy_load(fname);
assert(arr.shape.size() == 3);
tens.resize(static_cast(arr.shape[0]), static_cast(arr.shape[1]),
static_cast(arr.shape[2]));
std::vector data = arr.as_vec();
- if (order == "rowMajor")
+ if (!arr.fortran_order)
{
for (size_t i = 0; i < arr.shape[0]; ++i)
{
@@ -585,7 +581,7 @@ Eigen::Tensor cnpy::load(Eigen::Tensor& tens,
}
}
}
- else if (order == "colMajor")
+ else
{
for (size_t i = 0; i < arr.shape[0]; ++i)
{
@@ -660,28 +656,28 @@ void cnpy::save(const Eigen::SparseMatrix& mat, const std::string fname)
template void cnpy::save(const Eigen::MatrixXi& mat, const std::string fname);
template Eigen::MatrixXi cnpy::load(Eigen::MatrixXi& mat,
- const std::string fname, std::string order);
+ const std::string fname);
template void cnpy::save(const Eigen::MatrixXd& mat, const std::string fname);
template Eigen::MatrixXd cnpy::load(Eigen::MatrixXd& mat,
- const std::string fname, std::string order);
+ const std::string fname);
template void cnpy::save(const Eigen::MatrixXf& mat, const std::string fname);
template Eigen::MatrixXf cnpy::load(Eigen::MatrixXf& mat,
- const std::string fname, std::string order);
+ const std::string fname);
template void cnpy::save(const Eigen::MatrixXcd& mat, const std::string fname);
template Eigen::MatrixXcd cnpy::load(Eigen::MatrixXcd& mat,
- const std::string fname, std::string order);
+ const std::string fname);
template void cnpy::save(const Eigen::VectorXi& mat, const std::string fname);
template Eigen::VectorXi cnpy::load(Eigen::VectorXi& mat,
- const std::string fname, std::string order);
+ const std::string fname);
template void cnpy::save(const Eigen::VectorXd& mat, const std::string fname);
template Eigen::VectorXd cnpy::load(Eigen::VectorXd& mat,
- const std::string fname, std::string order);
+ const std::string fname);
template void cnpy::save(const Eigen::VectorXf& mat, const std::string fname);
template Eigen::VectorXf cnpy::load(Eigen::VectorXf& mat,
- const std::string fname, std::string order);
+ const std::string fname);
template void cnpy::save(const Eigen::VectorXcd& mat, const std::string fname);
template Eigen::VectorXcd cnpy::load(Eigen::VectorXcd& mat,
- const std::string fname, std::string order);
+ const std::string fname);
template void cnpy::save(const Eigen::SparseMatrix& mat,
const std::string fname);
template Eigen::SparseMatrix cnpy::load(Eigen::SparseMatrix&
@@ -690,18 +686,18 @@ template Eigen::SparseMatrix cnpy::load(Eigen::SparseMatrix&
template void cnpy::save(const Eigen::Tensor& mat,
const std::string fname);
template Eigen::Tensor cnpy::load(Eigen::Tensor& tens,
- const std::string fname, std::string order);
+ const std::string fname);
template void cnpy::save(const Eigen::Tensor& mat,
const std::string fname);
template Eigen::Tensor cnpy::load(Eigen::Tensor& tens,
- const std::string fname, std::string order);
+ const std::string fname);
template void cnpy::save(const Eigen::Tensor& mat,
const std::string fname);
template Eigen::Tensor cnpy::load(Eigen::Tensor& tens,
- const std::string fname, std::string order);
+ const std::string fname);
template void cnpy::save(const Eigen::Tensor, 3>& mat,
const std::string fname);
template Eigen::Tensor, 3> cnpy::load(
Eigen::Tensor, 3>& tens,
- const std::string fname, std::string order);
+ const std::string fname);
#pragma GCC diagnostic pop
diff --git a/src/ITHACA_CORE/ITHACAstream/cnpy.H b/src/ITHACA_CORE/ITHACAstream/cnpy.H
index 578243b9b..8f7fa8298 100644
--- a/src/ITHACA_CORE/ITHACAstream/cnpy.H
+++ b/src/ITHACA_CORE/ITHACAstream/cnpy.H
@@ -410,7 +410,7 @@ template std::vector create_npy_header(
template
Eigen::Matrix < T, -1, dim > load(Eigen::Matrix < T, -1, dim > & mat,
- const std::string fname, std::string order = "rowMajor");
+ const std::string fname);
template
Eigen::SparseMatrix load(Eigen::SparseMatrix& mat,
@@ -418,7 +418,7 @@ Eigen::SparseMatrix load(Eigen::SparseMatrix& mat,
template
Eigen::Tensor load(Eigen::Tensor& tens,
- const std::string fname, std::string order = "rowMajor");
+ const std::string fname);
template
void save(const Eigen::Matrix < T, -1, dim > & mat, const std::string fname);
diff --git a/src/ITHACA_CORE/ITHACAutilities/ITHACAassign.C b/src/ITHACA_CORE/ITHACAutilities/ITHACAassign.C
index ef6716683..93cb7f4b5 100644
--- a/src/ITHACA_CORE/ITHACAutilities/ITHACAassign.C
+++ b/src/ITHACA_CORE/ITHACAutilities/ITHACAassign.C
@@ -311,6 +311,36 @@ void assignBC(GeometricField& s, label BC_ind,
assignBC(s, BC_ind, valueList);
}
+void assignBC(GeometricField& s, label BC_ind,
+ Eigen::MatrixXd valueVec)
+{
+ label sizeBC = s.boundaryField()[BC_ind].size();
+ M_Assert(sizeBC * 3 == valueVec.size(),
+ "The size of the given values matrix has to be equal to 3 times the dimension of the boundaryField");
+ List valueList(sizeBC);
+
+ for (label i = 0; i < sizeBC; i++)
+ {
+ valueList[i].component(0) = valueVec(i);
+ valueList[i].component(1) = valueVec(i + sizeBC);
+ valueList[i].component(2) = valueVec(i + sizeBC * 2);
+ }
+
+ assignBC(s, BC_ind, valueList);
+}
+
+void assignBC(GeometricField& s, label BC_ind,
+ double value)
+{
+ label sizeBC = s.boundaryField()[BC_ind].size();
+ List valueList(sizeBC);
+ for (label i = 0; i < sizeBC; i++)
+ {
+ valueList[i] = value;
+ }
+
+ assignBC(s, BC_ind, valueList);
+}
void assignBC(GeometricField& s,
label BC_ind, Eigen::MatrixXd valueVec)
@@ -409,7 +439,48 @@ void assignBC(GeometricField& s, label BC_ind,
}
}
+// Assign a BC for a point patch field
+void assignBC(GeometricField& s, label BC_ind,
+ List valueList)
+{
+ word typeBC = s.boundaryField()[BC_ind].type();
+ label sizeBC = s.boundaryField()[BC_ind].size();
+ M_Assert(sizeBC == valueList.size(),
+ "The size of the given values list has to be equal to the dimension of the boundaryField");
+ if (s.boundaryField()[BC_ind].type() == "fixedGradient")
+ {
+ Info << "This Feature is not implemented for this boundary condition" << endl;
+ exit(0);
+ }
+ else if (s.boundaryField()[BC_ind].type() == "empty"
+ || s.boundaryField()[BC_ind].type() == "zeroGradient")
+ {}
+ else
+ {
+ try
+ {
+ if (typeBC != "fixedGradient" && typeBC != "freestream" && typeBC != "empty"
+ && typeBC != "zeroGradient" && typeBC != "fixedValue" && typeBC != "calculated"
+ && typeBC != "processor")
+ {
+ word message = "Pay attention, your typeBC " + typeBC + " for " + s.name() +
+ " is not included into the developed ones. Your BC will be treated as a classical fixedValue.";
+ throw (message);
+ }
+ }
+ catch (const word message)
+ {
+ cerr << "WARNING: " << message << endl;
+ }
+
+ for (label i = 0; i < sizeBC; i++)
+ {
+ s.boundaryFieldRef()[BC_ind].patchInternalField()()[i] == valueList[i];
+
+ }
+ }
+}
// Assign a BC for a tensor field
void assignBC(GeometricField& s, label BC_ind,
List valueList)
@@ -474,6 +545,65 @@ void assignBC(GeometricField& s, label BC_ind,
}
+void assignBC(GeometricField& s,
+ label BC_ind, vector value)
+{
+ M_Assert(value.size() == 3, "The size of the given vector has to be equal to 3 for the 3 components");
+ label sizeBC = s.boundaryField()[BC_ind].size();
+ List valueList(sizeBC);
+
+ for (label i = 0; i < sizeBC; i++)
+ {
+ valueList[i] = value;
+ }
+
+ assignBC(s, BC_ind, valueList);
+}
+
+void assignBC(GeometricField& s, label BC_ind,
+ List valueList)
+{
+ word typeBC = s.boundaryField()[BC_ind].type();
+ label sizeBC = s.boundaryField()[BC_ind].size();
+ M_Assert(sizeBC == valueList.size(),
+ "The size of the given values list has to be equal to the dimension of the boundaryField");
+ ITHACAparameters* para(ITHACAparameters::getInstance());
+ if (s.boundaryField()[BC_ind].type() == "fixedGradient")
+ {
+ Info << "This Feature is not implemented for this boundary condition" << endl;
+ exit(0);
+ }
+ else if (typeBC == "empty")
+ {}
+ else
+ {
+ try
+ {
+ if (typeBC != "fixedGradient" && typeBC != "freestream" && typeBC != "empty"
+ && typeBC != "zeroGradient" && typeBC != "fixedValue" && typeBC != "calculated"
+ && typeBC != "processor")
+ {
+ word message = "Pay attention, your typeBC " + typeBC + " for " + s.name() +
+ " is not included into the developed ones. Your BC will be treated as a classical fixedValue.";
+ throw (message);
+ }
+ }
+ catch (const word message)
+ {
+ cerr << "WARNING: " << message << endl;
+ }
+
+ for (label i = 0; i < sizeBC; i++)
+ {
+ double value = valueList[i];
+
+ //s.boundaryFieldRef()[BC_ind].patchInternalField()()[i] == valueList[i];
+ s.primitiveFieldRef()[BC_ind][i] = value;
+ }
+ }
+}
+
+
template
void assignBC(GeometricField& s,
label BC_ind,
diff --git a/src/ITHACA_CORE/ITHACAutilities/ITHACAassign.H b/src/ITHACA_CORE/ITHACAutilities/ITHACAassign.H
index 6f970d0a0..4a544c937 100644
--- a/src/ITHACA_CORE/ITHACAutilities/ITHACAassign.H
+++ b/src/ITHACA_CORE/ITHACAutilities/ITHACAassign.H
@@ -166,6 +166,16 @@ void assignBC(GeometricField& s, label BC_ind,
///
void assignBC(GeometricField& s, label BC_ind,
List valueList);
+//--------------------------------------------------------------------------
+/// Assign Boundary Condition to a pointVectorField
+///
+/// @param[in] s field where you want to assign the BC.
+/// @param[in] BC_ind The BC index.
+/// @param[in] valueList The value you want to assign (it must be a list of doubles).
+///
+
+void assignBC(GeometricField& s, label BC_ind,
+ List valueList);
//--------------------------------------------------------------------------
/// Assign Boundary Condition to a volVectorField
@@ -176,6 +186,16 @@ void assignBC(GeometricField& s, label BC_ind,
///
void assignBC(GeometricField& s, label BC_ind,
vector value);
+
+//--------------------------------------------------------------------------
+/// Assign Boundary Condition to a pointVectorField
+///
+/// @param[in] s field where you want to assign the BC.
+/// @param[in] BC_ind The BC index.
+/// @param[in] value The value you want to assign (it must be an OpenFOAM vector).
+///
+void assignBC(GeometricField& s, label BC_ind,
+ vector value);
//--------------------------------------------------------------------------
/// Assign Boundary Condition to a volTensorField
@@ -206,6 +226,16 @@ void assignBC(GeometricField& s, label BC_ind,
///
void assignBC(GeometricField& s, label BC_ind,
Eigen::MatrixXd valueVec);
+
+//--------------------------------------------------------------------------
+/// Assign Boundary Condition to a pointVectorField
+///
+/// @param[in] s field where you want to assign the BC.
+/// @param[in] BC_ind The BC index.
+/// @param[in] valueVec The value you want to assign (it must be an Eigen MatrixXd).
+///
+void assignBC(GeometricField& s, label BC_ind,
+ Eigen::MatrixXd valueVec);
//--------------------------------------------------------------------------
/// Assign Boundary Condition to a volVectorField
@@ -216,6 +246,16 @@ void assignBC(GeometricField& s, label BC_ind,
///
void assignBC(GeometricField& s, label BC_ind,
List valueList);
+
+//--------------------------------------------------------------------------
+/// Assign Boundary Condition to a pointVectorField
+///
+/// @param[in] s field where you want to assign the BC.
+/// @param[in] BC_ind The BC index.
+/// @param[in] valueList The value you want to assign (it must be a list of doubles).
+///
+void assignBC(GeometricField& s, label BC_ind,
+ List valueList);
//--------------------------------------------------------------------------
/// Assign Boundary Condition to a volTensorField
diff --git a/src/ITHACA_CORE/ITHACAutilities/ITHACAcoeffsMass.C b/src/ITHACA_CORE/ITHACAutilities/ITHACAcoeffsMass.C
index f70058884..57c442309 100644
--- a/src/ITHACA_CORE/ITHACAutilities/ITHACAcoeffsMass.C
+++ b/src/ITHACA_CORE/ITHACAutilities/ITHACAcoeffsMass.C
@@ -84,7 +84,8 @@ Eigen::MatrixXd getMassMatrix(
Eigen::MatrixXd F = Foam2Eigen::PtrList2Eigen(modes);
Eigen::MatrixXd M = Eigen::MatrixXd::Zero(Msize, Msize);
- if (consider_volumes)
+ constexpr bool check_vol = std::is_same::value || std::is_same::value;
+ if constexpr(check_vol)
{
Eigen::VectorXd V = getMassMatrixFV(modes[0]);
@@ -101,7 +102,7 @@ Eigen::MatrixXd getMassMatrix(
M = F.transpose().topRows(Msize) * V.asDiagonal() * F.leftCols(Msize);
}
}
- else
+ else if constexpr(std::is_same::value)
{
M = F.transpose().topRows(Msize) * F.leftCols(Msize);
}
@@ -210,6 +211,9 @@ template Eigen::MatrixXd getMassMatrix(
PtrList>& modes2, label Nmodes,
bool consider_volumes);
+template Eigen::MatrixXd getMassMatrix(
+ PtrList>& modes, label Nmodes,
+ bool consider_volumes);
template class PatchField, class GeoMesh>
Eigen::MatrixXd getMassMatrix(
@@ -302,22 +306,37 @@ template Eigen::MatrixXd getMassMatrix(
label Nmodes = 0,
bool consider_volumes);
-
template class PatchField, class GeoMesh>
Eigen::VectorXd getMassMatrixFV(
GeometricField& snapshot)
{
- Eigen::MatrixXd snapEigen = Foam2Eigen::field2Eigen(snapshot);
- label dim = std::nearbyint(snapEigen.rows() / (snapshot.mesh().V()).size());
- Eigen::VectorXd volumes = Foam2Eigen::field2Eigen(snapshot.mesh().V());
- Eigen::VectorXd vol3 = volumes.replicate(dim, 1);
- return vol3;
+ constexpr bool check_vol = std::is_same::value || std::is_same::value;
+
+ if constexpr(check_vol){
+
+ Eigen::MatrixXd snapEigen = Foam2Eigen::field2Eigen(snapshot);
+ label dim = std::nearbyint(snapEigen.rows() / (snapshot.mesh().V()).size());
+ Eigen::VectorXd volumes = Foam2Eigen::field2Eigen(snapshot.mesh().V());
+ Eigen::VectorXd vol3 = volumes.replicate(dim, 1);
+ return vol3;
+ }
+ else if constexpr(std::is_same::value) {
+
+ Eigen::MatrixXd snapEigen = Foam2Eigen::field2Eigen(snapshot);
+ label dim = std::nearbyint(snapEigen.rows() / (snapshot.mesh()().points()).size());
+ Eigen::VectorXd pointsdata = Foam2Eigen::field2Eigen(snapshot);
+ Eigen::VectorXd points3 = pointsdata.replicate(dim, 1);
+ return points3;
+ }
}
template Eigen::VectorXd getMassMatrixFV(
GeometricField& snapshot);
template Eigen::VectorXd getMassMatrixFV(
GeometricField& snapshot);
+template Eigen::VectorXd getMassMatrixFV(
+ GeometricField& snapshot);
+
template Eigen::VectorXd getMassMatrixFV(
GeometricField& snapshot);
@@ -345,12 +364,14 @@ Eigen::VectorXd getCoeffs(GeometricField&
Eigen::VectorXd a(Msize);
Eigen::VectorXd b(Msize);
- if (consider_volumes)
+ constexpr bool check_vol = std::is_same::value || std::is_same::value;
+
+ if constexpr(check_vol)
{
Eigen::VectorXd V = getMassMatrixFV(modes[0]);
b = F.transpose().topRows(Msize) * V.asDiagonal() * snapEigen;
}
- else
+ else if constexpr(std::is_same::value)
{
b = F.transpose().topRows(Msize) * snapEigen;
}
@@ -381,6 +402,11 @@ template Eigen::VectorXd getCoeffs(
snapshot, PtrList