diff --git a/changelog-entries/544.md b/changelog-entries/544.md new file mode 100644 index 000000000..a5cee276e --- /dev/null +++ b/changelog-entries/544.md @@ -0,0 +1 @@ +- Fixed the [volume-coupled flow tutorial](https://precice.org/tutorials-volume-coupled-flow.html) to correctly assign all components of the read velocity field. diff --git a/changelog-entries/545.md b/changelog-entries/545.md new file mode 100644 index 000000000..6f365fe3f --- /dev/null +++ b/changelog-entries/545.md @@ -0,0 +1 @@ +- Updated the default suggested OpenFOAM version to v2406 [#545](https://github.com/precice/tutorials/pull/545). diff --git a/changelog-entries/554.md b/changelog-entries/554.md new file mode 100644 index 000000000..0896242d2 --- /dev/null +++ b/changelog-entries/554.md @@ -0,0 +1 @@ +- Use `assign` function instead of directly accessing vectors in perpendicular-flap/solid-fenics. Fixes problem with checkpointing. diff --git a/channel-transport/fluid-nutils/requirements.txt b/channel-transport/fluid-nutils/requirements.txt index cfd521c81..fddef32ad 100644 --- a/channel-transport/fluid-nutils/requirements.txt +++ b/channel-transport/fluid-nutils/requirements.txt @@ -1,2 +1,3 @@ nutils==7 -pyprecice==3 +numpy >1, <2 +pyprecice~=3.0 diff --git a/channel-transport/transport-nutils/requirements.txt b/channel-transport/transport-nutils/requirements.txt index cfd521c81..fddef32ad 100644 --- a/channel-transport/transport-nutils/requirements.txt +++ b/channel-transport/transport-nutils/requirements.txt @@ -1,2 +1,3 @@ nutils==7 -pyprecice==3 +numpy >1, <2 +pyprecice~=3.0 diff --git a/flow-over-heated-plate/solid-dunefem/requirements.txt b/flow-over-heated-plate/solid-dunefem/requirements.txt index b0b7bdf42..9eebb23ea 100644 --- a/flow-over-heated-plate/solid-dunefem/requirements.txt +++ b/flow-over-heated-plate/solid-dunefem/requirements.txt @@ -1,2 +1,2 @@ dune-fem>=2.8 -pyprecice==3 +pyprecice~=3.0 diff --git a/flow-over-heated-plate/solid-nutils/requirements.txt b/flow-over-heated-plate/solid-nutils/requirements.txt index cfd521c81..fddef32ad 100644 --- a/flow-over-heated-plate/solid-nutils/requirements.txt +++ b/flow-over-heated-plate/solid-nutils/requirements.txt @@ -1,2 +1,3 @@ nutils==7 -pyprecice==3 +numpy >1, <2 +pyprecice~=3.0 diff --git a/partitioned-heat-conduction-direct/dirichlet-nutils/requirements.txt b/partitioned-heat-conduction-direct/dirichlet-nutils/requirements.txt index cfd521c81..fddef32ad 100644 --- a/partitioned-heat-conduction-direct/dirichlet-nutils/requirements.txt +++ b/partitioned-heat-conduction-direct/dirichlet-nutils/requirements.txt @@ -1,2 +1,3 @@ nutils==7 -pyprecice==3 +numpy >1, <2 +pyprecice~=3.0 diff --git a/partitioned-heat-conduction-direct/neumann-nutils/requirements.txt b/partitioned-heat-conduction-direct/neumann-nutils/requirements.txt index cfd521c81..fddef32ad 100644 --- a/partitioned-heat-conduction-direct/neumann-nutils/requirements.txt +++ b/partitioned-heat-conduction-direct/neumann-nutils/requirements.txt @@ -1,2 +1,3 @@ nutils==7 -pyprecice==3 +numpy >1, <2 +pyprecice~=3.0 diff --git a/partitioned-heat-conduction/dirichlet-nutils/requirements.txt b/partitioned-heat-conduction/dirichlet-nutils/requirements.txt index cfd521c81..fddef32ad 100644 --- a/partitioned-heat-conduction/dirichlet-nutils/requirements.txt +++ b/partitioned-heat-conduction/dirichlet-nutils/requirements.txt @@ -1,2 +1,3 @@ nutils==7 -pyprecice==3 +numpy >1, <2 +pyprecice~=3.0 diff --git a/partitioned-heat-conduction/neumann-nutils/requirements.txt b/partitioned-heat-conduction/neumann-nutils/requirements.txt index cfd521c81..fddef32ad 100644 --- a/partitioned-heat-conduction/neumann-nutils/requirements.txt +++ b/partitioned-heat-conduction/neumann-nutils/requirements.txt @@ -1,2 +1,3 @@ nutils==7 -pyprecice==3 +numpy >1, <2 +pyprecice~=3.0 diff --git a/perpendicular-flap/README.md b/perpendicular-flap/README.md index 9a6ae600b..c48a78fb9 100644 --- a/perpendicular-flap/README.md +++ b/perpendicular-flap/README.md @@ -51,6 +51,8 @@ Solid participant: * OpenFOAM (solidDisplacementFoam). For more information, have a look at the [OpenFOAM plateHole tutorial](https://www.openfoam.com/documentation/tutorial-guide/5-stress-analysis/5.1-stress-analysis-of-a-plate-with-a-hole). The solidDisplacementFoam solver only supports linear geometry and this case is only provided for quick testing purposes, leading to outlier results. For general solid mechanics procedures in OpenFOAM, see solids4foam. +* Fake. A simple Python script that acts as a fake solver and provides an arbitrary time-dependent flap displacement in the x-direction, i.e., it performs a shear mapping on the resting flap. This solver can be used for debugging of the fluid participant and its adapter. It also technically works with implicit coupling, thus no changes to the preCICE configuration are necessary. Note that [ASTE's replay mode](https://precice.org/tooling-aste.html#replay-mode) has a similar use case and could also feed artificial or previously recorded real data, replacing an actual solver. + ## Running the Simulation All listed solvers can be used in order to run the simulation. OpenFOAM can be executed in parallel using `run.sh -parallel`. The default setting uses 4 MPI ranks. Open two separate terminals and start the desired fluid and solid participant by calling the respective run script `run.sh` located in the participant directory. For example: diff --git a/perpendicular-flap/fluid-fake/requirements.txt b/perpendicular-flap/fluid-fake/requirements.txt index 3f8163356..dbffa144f 100644 --- a/perpendicular-flap/fluid-fake/requirements.txt +++ b/perpendicular-flap/fluid-fake/requirements.txt @@ -1,2 +1,2 @@ -numpy -pyprecice==3 +numpy >1, <2 +pyprecice~=3.0 diff --git a/perpendicular-flap/fluid-nutils/requirements.txt b/perpendicular-flap/fluid-nutils/requirements.txt index 9e344b1e3..fd576feac 100644 --- a/perpendicular-flap/fluid-nutils/requirements.txt +++ b/perpendicular-flap/fluid-nutils/requirements.txt @@ -1,2 +1,3 @@ nutils==6 -pyprecice==3 +numpy >1, <2 +pyprecice~=3.0 diff --git a/perpendicular-flap/solid-fake/fake.py b/perpendicular-flap/solid-fake/fake.py new file mode 100644 index 000000000..fd5581292 --- /dev/null +++ b/perpendicular-flap/solid-fake/fake.py @@ -0,0 +1,92 @@ +from __future__ import division + +import numpy as np +import precice + + +def displace_flap(x, y, t, flap_tip_y): + x_displ = np.zeros_like(x) + y_displ = np.zeros_like(y) + # get displacement independent of x, only dependent on y and t + max_x_displ = 0.5 + period_fac = 3 * np.pi + damping_fac = 8 # damps the amplitude of the sine + # defines how much the sine is shifted in y-direction + shift = 0.95 + # wiggles the flap periodically. + # the arcsin(-shift) in the sine evaluation is necessary to start at a flap displacement of 0 at t=0 + # (i.e. sin(arcsin(-shift))+shift = 0) + x_displ = np.minimum(((np.sin(period_fac * t + np.arcsin(-shift)) + shift) / + damping_fac), max_x_displ) * y / flap_tip_y + + dimensions = 2 + displ = np.zeros((len(x), dimensions)) + displ[:, 0] = x_displ + displ[:, 1] = y_displ + + return displ + + +configuration_file_name = "../precice-config.xml" +participant_name = "Solid" +mesh_name = "Solid-Mesh" +write_data_name = 'Displacement' + +solver_process_index = 0 +solver_process_size = 1 + +# define mesh +H = 1 +W = 0.1 + +interface = precice.Participant(participant_name, configuration_file_name, solver_process_index, solver_process_size) +dimensions = interface.get_mesh_dimensions(mesh_name) +assert (dimensions == 2) + +x_left = 0.0 - 0.5 * W # left boundary of the flap +x_right = 0.5 * W # right boundary of the flap +y_bottom = 0.0 # bottom of the flap +y_top = y_bottom + H # top of the flap + +n = 24 # Number of vertices per side +t = 0 + +vertices = np.zeros((2 * n, dimensions)) +# define vertices of flap's left side +vertices[:n, 1] = np.linspace(y_bottom, y_top, n) +vertices[:n, 0] = x_left +# define vertices of flap's right side +vertices[n:, 1] = np.linspace(y_bottom, y_top, n) +vertices[n:, 0] = x_right + +vertex_ids = interface.set_mesh_vertices(mesh_name, vertices) + +if interface.requires_initial_data(): + # initially, there should be no displacement + interface.write_data(np.zeros_like(vertices)) + +interface.initialize() +# change if necessary +solver_dt = np.inf +# for checkpointing +t_cp = 0 + +while interface.is_coupling_ongoing(): + if interface.requires_writing_checkpoint(): + t_cp = t + + precice_dt = interface.get_max_time_step_size() + dt = min([solver_dt, precice_dt]) + # wiggle the flap + write_data = displace_flap(vertices[:, 0], vertices[:, 1], t, H) + + interface.write_data(mesh_name, write_data_name, vertex_ids, write_data) + interface.advance(dt) + + if interface.requires_reading_checkpoint(): + t = t_cp + else: + # update t + t += dt + +interface.finalize() diff --git a/perpendicular-flap/solid-fake/requirements.txt b/perpendicular-flap/solid-fake/requirements.txt new file mode 100644 index 000000000..dbffa144f --- /dev/null +++ b/perpendicular-flap/solid-fake/requirements.txt @@ -0,0 +1,2 @@ +numpy >1, <2 +pyprecice~=3.0 diff --git a/perpendicular-flap/solid-fake/run.sh b/perpendicular-flap/solid-fake/run.sh new file mode 100755 index 000000000..487ea548d --- /dev/null +++ b/perpendicular-flap/solid-fake/run.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env sh +set -e -u + +python3 -m venv .venv +. .venv/bin/activate +pip install -r requirements.txt +python3 fake.py diff --git a/perpendicular-flap/solid-fenics/solid.py b/perpendicular-flap/solid-fenics/solid.py index dc07af7cc..20d3e1f07 100644 --- a/perpendicular-flap/solid-fenics/solid.py +++ b/perpendicular-flap/solid-fenics/solid.py @@ -158,16 +158,14 @@ def update_v(a, u_old, v_old, a_old, ufl=True): def update_fields(u, u_old, v_old, a_old): """Update all fields at the end of a timestep.""" - u_vec, u0_vec = u.vector(), u_old.vector() - v0_vec, a0_vec = v_old.vector(), a_old.vector() - # call update functions - a_vec = update_a(u_vec, u0_vec, v0_vec, a0_vec, ufl=False) - v_vec = update_v(a_vec, u0_vec, v0_vec, a0_vec, ufl=False) + a_new = update_a(u, u_old, v_old, a_old) + v_new = update_v(u, u_old, v_old, a_old) - # assign u->u_old - v_old.vector()[:], a_old.vector()[:] = v_vec, a_vec - u_old.vector()[:] = u.vector() + # update values + a_old.assign(project(a_new, V)) + v_old.assign(project(v_new, V)) + u_old.assign(u) def avg(x_old, x_new, alpha): @@ -238,7 +236,6 @@ def avg(x_old, x_new, alpha): n = n_cp else: update_fields(u_np1, u_n, v_n, a_n) - u_n.assign(u_np1) t += float(dt) n += 1 diff --git a/perpendicular-flap/solid-nutils/requirements.txt b/perpendicular-flap/solid-nutils/requirements.txt index 5b0938a20..00638bb7c 100644 --- a/perpendicular-flap/solid-nutils/requirements.txt +++ b/perpendicular-flap/solid-nutils/requirements.txt @@ -1,2 +1,3 @@ nutils>=8.5 -pyprecice==3 +numpy >1, <2 +pyprecice~=3.0 diff --git a/quickstart/README.md b/quickstart/README.md index 8a532accd..9809f9759 100644 --- a/quickstart/README.md +++ b/quickstart/README.md @@ -39,10 +39,10 @@ To get a feeling what preCICE does, watch a [short presentation](https://www.you ```bash # Add the signing key, add the repository, update (check this): wget -q -O - https://dl.openfoam.com/add-debian-repo.sh | sudo bash - # Install OpenFOAM v2312: - sudo apt install openfoam2312-dev + # Install OpenFOAM v2406: + sudo apt install openfoam2406-dev # Enable OpenFOAM by default in your system and apply now: - echo "source /usr/lib/openfoam/openfoam2312/etc/bashrc" >> ~/.bashrc + echo "source /usr/lib/openfoam/openfoam2406/etc/bashrc" >> ~/.bashrc source ~/.bashrc ``` @@ -55,9 +55,9 @@ To get a feeling what preCICE does, watch a [short presentation](https://www.you 4. Download and install the [OpenFOAM-preCICE adapter](https://precice.org/adapter-openfoam-get.html): ```bash - wget https://github.com/precice/openfoam-adapter/archive/refs/tags/v1.3.0.tar.gz - tar -xzf v1.3.0.tar.gz - cd openfoam-adapter-1.3.0/ + wget https://github.com/precice/openfoam-adapter/archive/refs/tags/v1.3.1.tar.gz + tar -xzf v1.3.1.tar.gz + cd openfoam-adapter-1.3.1/ ./Allwmake cd .. ``` diff --git a/resonant-circuit/README.md b/resonant-circuit/README.md index 5a421e809..79032a1aa 100644 --- a/resonant-circuit/README.md +++ b/resonant-circuit/README.md @@ -7,7 +7,7 @@ summary: We simulate a two-element LC circuit (one inductor and one capacitor). ## Setup -The purpose of this tutorial is to illustrate the usage of preCICE to couple MATLAB code. Two different MATLAB solvers will be coupled to simulate a two-element LC circuit. This type of circuit consists on a very simple system with one inductor and one capacitor: +The purpose of this tutorial is to illustrate the usage of preCICE to couple MATLAB code. Two different MATLAB solvers will be coupled to simulate a two-element LC circuit. This type of circuit consists of a very simple system with one inductor and one capacitor: ![LC circuit diagram [1]](images/tutorials-resonant-circuit-diagram.svg) @@ -17,9 +17,9 @@ $U(t) = L \frac{\text{d}I}{\text{d}t}$ $I(t) = -C \frac{\text{d}U}{\text{d}t}$ -where $I$ is the current and $U$ the voltage of the cirucit. +where $I$ is the current and $U$ the voltage of the circuit. -Each of these equations is going to be solved by a different MATLAB solver. Note that as only one scalar is solved per equation, this is a 0+1 dimensional problem. +Each of these equations is going to be solved by a different MATLAB solver. Note that, as only one scalar is solved per equation, this is a 0+1 dimensional problem. ## Configuration @@ -37,23 +37,23 @@ preCICE configuration (image generated using the [precice-config-visualizer](htt ### MATLAB -For running this example, first get into one of folders with the solvers and open a MATLAB instance. +For running this example, first get into one of the solver folders and open a MATLAB instance. Afterward, do the same for the second solver. After adding the MATLAB bindings to the MATLAB path (in both instances), run the following commands: -In the first MATLAB instance one can run the solver for the current: +In the first MATLAB instance, one can run the solver for the current: ```MATLAB coil ``` -And in the second MATLAB instance the solver for the voltage: +And in the second MATLAB instance, the solver for the voltage: ```MATLAB capacitor ``` -The preCICE configuration file is available as `precice-config.xml`, and it is called directly in the solvers. +The preCICE configuration file is hard-coded as `precice-config.xml` in the solvers. #### Running from terminal @@ -68,7 +68,7 @@ The MATLAB participant for the current also records the current and voltage thro After successfully running the coupling, one can find the curves in the folder `capacitor-matlab` as `Curves.png`. -The `Curves.png` plot could exemplarily look like the following: +Example of a `Curves.png` plot: ![Voltage and current plot of the resonant circuit](images/tutorials-resonant-circuit-curves.png) ## References diff --git a/tools/tests/components.yaml b/tools/tests/components.yaml index acbd55eb6..3ca370bd7 100644 --- a/tools/tests/components.yaml +++ b/tools/tests/components.yaml @@ -101,10 +101,10 @@ calculix-adapter: TUTORIALS_REF: description: Tutorial git reference to use default: "master" - CALULIX_VERSION: + CALCULIX_VERSION: description: Version of Calculix to use default: "2.20" - CALULIX_ADAPTER_REF: + CALCULIX_ADAPTER_REF: description: Version of Calculix-Adapter to use default: "master" diff --git a/two-scale-heat-conduction/macro-nutils/requirements.txt b/two-scale-heat-conduction/macro-nutils/requirements.txt index cfd521c81..fddef32ad 100644 --- a/two-scale-heat-conduction/macro-nutils/requirements.txt +++ b/two-scale-heat-conduction/macro-nutils/requirements.txt @@ -1,2 +1,3 @@ nutils==7 -pyprecice==3 +numpy >1, <2 +pyprecice~=3.0 diff --git a/two-scale-heat-conduction/micro-dumux/micro-manager-config.json b/two-scale-heat-conduction/micro-dumux/micro-manager-config.json index 1626ea671..ccf833a9c 100644 --- a/two-scale-heat-conduction/micro-dumux/micro-manager-config.json +++ b/two-scale-heat-conduction/micro-dumux/micro-manager-config.json @@ -8,6 +8,7 @@ "read_data_names": {"concentration": "scalar"} }, "simulation_params": { + "micro_dt": 0.01, "macro_domain_bounds": [0.0, 1.0, 0.0, 0.5], "decomposition": [2, 1], "adaptivity": "True", diff --git a/two-scale-heat-conduction/micro-nutils/micro-manager-config.json b/two-scale-heat-conduction/micro-nutils/micro-manager-config.json index 7bbee2baf..79db88b4a 100644 --- a/two-scale-heat-conduction/micro-nutils/micro-manager-config.json +++ b/two-scale-heat-conduction/micro-nutils/micro-manager-config.json @@ -8,6 +8,7 @@ "read_data_names": {"concentration": "scalar"} }, "simulation_params": { + "micro_dt": 0.01, "macro_domain_bounds": [0.0, 1.0, 0.0, 0.5], "decomposition": [2, 1], "adaptivity": "True", diff --git a/two-scale-heat-conduction/micro-nutils/requirements.txt b/two-scale-heat-conduction/micro-nutils/requirements.txt index 7e22175a7..e1caaea3c 100644 --- a/two-scale-heat-conduction/micro-nutils/requirements.txt +++ b/two-scale-heat-conduction/micro-nutils/requirements.txt @@ -1,3 +1,4 @@ nutils==7 -pyprecice==3 +numpy >1, <2 +pyprecice~=3.0 micro-manager-precice==0.4.0 diff --git a/volume-coupled-flow/fluid-openfoam/constant/fvOptions b/volume-coupled-flow/fluid-openfoam/constant/fvOptions index d43c960da..0614532e3 100644 --- a/volume-coupled-flow/fluid-openfoam/constant/fvOptions +++ b/volume-coupled-flow/fluid-openfoam/constant/fvOptions @@ -27,6 +27,8 @@ codedSource for(auto cell : cells) { fld[cell].x() = U_vol[cell].x(); + fld[cell].y() = U_vol[cell].y(); + fld[cell].z() = U_vol[cell].z(); } #}; @@ -39,4 +41,4 @@ codedSource #{ return; #}; -} \ No newline at end of file +} diff --git a/volume-coupled-flow/images/tutorials-volume-coupled-flow-Ux.png b/volume-coupled-flow/images/tutorials-volume-coupled-flow-Ux.png index 26a5edeaa..d574cd1c7 100644 Binary files a/volume-coupled-flow/images/tutorials-volume-coupled-flow-Ux.png and b/volume-coupled-flow/images/tutorials-volume-coupled-flow-Ux.png differ