======================================== Preparation of Fluid solver and Coupling ======================================== We want to couple problems where one solver solves the Navier-Stokes equations with heat transport and a solver that just solves the heat equation without flow (:math:`u\equiv0` and :math:`v\equiv0`). The flow solver has been implemented in the previous exercise and just needs to be extended. The solid solver will be derived from your solver. Conjugate heat transfer ======================= On Worksheet 3, we have already considered heat transfer in fluids. Now, we want to simulate heat transfer for scenarios with fluids (:math:`\mathrm{F}`) and solids (:math:`\mathrm{S}`). The additional equation for heat transfer in solids and the following two coupling conditions at the interface between solid and fluid should have already been introduced in the lecture: .. math:: T_{\mathrm{F}} &= T_{\mathrm{S}} \\ q_{\mathrm{F}} = - \kappa_{\mathrm{F}} \frac{\partial T_{\mathrm{F}}}{\partial n} &= \kappa_{\mathrm{S}} \frac{\partial T_{\mathrm{S}}}{\partial n} = q_{\mathrm{S}} Here :math:`n` is the normal vector pointing from the solid into the fluid domain. We realize these coupling conditions by a partitioned Neumann-Dirichlet coupling approach: In the fluid equations, the solid heat flux :math:`q_{\mathrm{S}}` is prescribed as a Neumann boundary condition at the coupling interface, whereas in the solid equations, the fluid temperature :math:`T_{\mathrm{F}}` is prescribed as a Dirichlet boundary condition at the coupling interface. There are other variants, such as Dirichlet-Neumann or Robin-Robin, but these are out of scope for this worksheet. Extending your code =================== After you have gotten familiar with preCICE, check Section :ref:`ex4-precice`, it is time to prepare your code for the iterative coupling. Adapt the CMake file (if not done yet) to include preCICE and check if your code still compiles. We will introduce two additional boundary types for the temperature: - ``TPD``: Temperature preCICE Dirichlet. Sets a temperature Dirichlet boundary condition. The temperature :math:`T` is read from preCICE. - ``TPN``: Temperature preCICE Neumann. Sets a Neumann boundary condition to enforce a certain heat flux :math:`q`. We guarantee that these boundary conditions will usualy appear in conjunction with no-slip wall boundary conditions (``NSW``). In the verification test case it appears also with inflow boundary conditions (``IN``). In general, there is no restriction on mixing velocity boundary conditions and preCICE boundaries for heat. In this exercise we only plan to use the preCICE temperature boundary conditions only with the two velocity boundary conditions stated above. For the last test case we allow that such boundary conditions can appear inside the domain (for the step). Adapt your code such that it can handle this case. The geometry file needs two new parameters to ``xOrigin`` and ``yOrigin`` that defined the origin for the geometry (left-bottom corner of geometry). Make sure that the ``VTKWriter`` uses these origin coordinates! Follow the adapter example to extend your code for the coupling. Your solver has to announce itself to preCICE and give a ``participantName`` when preCICE has to be first initialized, see: .. code-block:: c++ SolverInterface (const std::string &participantName, int solverProcessIndex, int solverProcessSize) Your solver ``numsim`` should be renamed to ``numsim_fluid``. The ``participantName`` is set to the name given in the solver input file. It is crucial that you stick to the name such that the submission system works. Moreover, data should be written to the directory ``out_${participantName}/``, i.e. if ``participantName=FluidSolver`` the output goes into the directory ``out_FluidSolver``. The name of the output files does not need to be changed. The name of the mesh used will be ``NumSimMesh``. The names of the datasets exchanged will usually be ``Temperature`` and ``Heat-Flux``. The names should be given in the input file as ``readDataName`` and ``writeDataName``. In the configure step .. code-block:: c++ configure (const std::string &configurationFileName) one has to provide a preCICE-configuration file. The filename should be defined in the problem input file where you also define the test case settings as the ``endTime`` and so on. Extend the settings-parser such that the input file can have a parameter ``preciceConfigFile`` that refers to the filename of the preCICE-configuration file. Also add a parameter ``meshName`` to the input file that specifies the name of the mesh that is used in your solver. You have to announce the name when calling .. code-block:: c++ int getMeshID (const std::string &meshName) const Implicit coupling schemes require that your solver can save its state (save a checkpoint) and restore it. Implement functions for that. We need to interpolate data onto the interface and determine the heat flux. Assume that we are on the left hand boundary then we can interpolate the temperature on the domain boundary via averaging (assuming an equidistant mesh) .. math:: T_{\frac{1}{2},j} = \frac{1}{2} (T_{0,j} + T_{1,j}) For the heat flux we need the conductivity :math:`\kappa` and the temperature gradient. In the **flow** solver the conductivity is given as .. math:: \kappa = \frac{1}{\textrm{Re}\textrm{Pr}} due to the nondimensional form of the equations. The temperature gradient on the left hand boundary would be approximated by .. math:: \left[ \frac{\partial T}{\partial x} \right]_{\frac{1}{2},j} = -\kappa \frac{T_{1,j}-T_{0,j}}{dx} Make sure that you use the correct signs for the heat flux (heat leaving one domain enters the other domain) and to set the boundary condition properly. The terms have to be evaluated accordingly at top, bottom and right boundaries. .. warning:: Make sure that you update the boundary conditions after solving before you write data to preCICE! Otherwise your evaluated temperature and heat flux on the boundaries are not meaningful. The **flow solver** will **usually** read heat fluxes from another solver and writes temperatures to the other solver. The only exception is the optional test case. If you want to run the optional test case, the flow solver has to support the other direction of data exchange as well. The **solid solver** (more about it below) will **always** read temperatures from another solver and writes the heat fluxes to the other solver. You will **not** need the announce the connectivity of your mesh to preCICE. You are still allowed to do so. Suggested approach ------------------ This describes a potential workflow for extending your solver: - Write a preCICE adapter for your flow solver that supports explicit coupling. - Make sure that you announce the correct points (centers of cell faces/edges) for the coupling. - Test it a bit with the verification setup provided below, if necessary. - Implement functions to store and restore the state of your solver. - Extend your adapter to be suitable for implicit coupling schemes as well. - Proceed to the more complicated test cases. .. _ex4-coupling-verification: Verification and testing ------------------------ We will provide some file for debugging and basic verification of your implementation soon. Lid-driven cavity with heated lid (optional) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We have set up a small solver for testing. We have written a dummy solid solver such that you can test your flow solver after you have written ther preCICE adapter. The idea of the test case is that it reproduces the lid-driven cavity with heated lid test case from the previous exercise. The dummy solver will receive a temperature from the flow solver and compuate compute a heat flux such that the effective temperature on the boundary should always be :math:`T_{BC}=1`. You should get nearly identical results as for the When I compare solutions generated with the sample code from the previous exercise with the solver from the current exercise I get extremly small (and expected) differences. The output of ``compare_solution`` looks like this for me: .. code-block:: none 20 files with 441 entries each. average 2-norm error per velocity vector: 1.84425e-16 average 2-norm error per temperature: 2.55577e-17 Biggest difference uv: File 16 at point 44, |u-u_ref|+|v-v_ref|: 1.19826e-15 Biggest difference T: File 3 at point 429, |T-T_ref|: 4.44089e-16 The test case should help you to verify that you - evaluate the boundary values correctly, - initialize data correctly in preCICE - have implemented the new boundary conditions (at least for the heat flux) - have implemented new parameters You can download the files here: :download:`Download files `. .. warning:: Depending on the definition of the normal vector that you choose you might have to change the sign of the computed heat flux in the dummy solver. .. note:: The ``SolidSolverDummy`` is really simple. It does not read any ``.input``-file nor any geometry file. The geometry is hard coded. It can be given a preCICE-configuration. This means you can start it as .. code-block:: bash ./SolidSolverDummy my-precice-config.xml By default dummy solver will try to open a file called ``precice-config.xml``. Tasks ======== - Change the name of the executable to ``numsim_fluid``. - Extend your code to account for the new boundary condition types for temperature. - Extend your code such that it can be coupled with preCICE, i.e. write an adapter for your code. - Write a solid solver that only solves for heat conduction and verify that it is correct. - Extend your code such that it can have boundary conditions inside the domain.