Difference between revisions of "Contrib/multiSolver"

From OpenFOAMWiki
m (Wyldckat moved page Contrib multiSolver to Contrib/multiSolver: Consolidate all contributions into the same naming style.)
 
(36 intermediate revisions by 2 users not shown)
Line 1: Line 1:
<small>Subpages<BR>
+
This project has migrated over to '''github'''.
> [[multiSolver/glossary|glossary]]<BR>
+
> [[multiSolver/multiControlDict|multiControlDict]]<BR></small>
+
'''multiSolver''' allows you to create a [[multiSolver/glossary#superSolver|superSolver]] composed of multiple solvers within a [[multiSolver/glossary#superLoop|superLoop]].  All solvers operate on the same dataset in sequence. For example:
+
  
# <tt>icoFoam</tt> - runs to completion;
+
'''''[http://github.com/Marupio/multiSolver/wiki Click here for the new website.]'''''
# data is handed over to <tt>scalarTransportFoam</tt>;
+
# <tt>scalarTransportFoam</tt> - runs to completion;
+
# data is handed back to <tt>icoFoam</tt>, and the [[multiSolver/glossary#superLoop|superLoop]] repeats.
+
  
The settings for each solver are all stored within a single case directory using a [[multiSolver/glossary#multiDict|multiDict]] format.  All the data output is sorted into subdirectories corresponding to the solver, and can be retrieved for easy data management.  This kind of behaviour is very useful for:
+
http://github.com/Marupio/multiSolver/wiki
 
+
* multi-step processes to be modelled within a single application, e.g. fluid injection, followed by settling;
+
* modelling of a flow problem characterized by two different timescales, e.g. stirring with biochemical reactions; and
+
* changing boundary conditions mid-run.
+
 
+
It turns out this type of behaviour is difficult, if not impossible, to implement in OpenFOAM without '''multiSolver'''.
+
 
+
== Why is it needed? ==
+
A fundamental assumption in the design of OpenFOAM is the existence of a universal time.  Therefore the time object is the top-level [[objectRegistry|object registry]], which means it controls the database for every solver.  This design works for nearly all simulations imaginable, except for multi-step simulations.
+
 
+
:'''''Multi-step simulation'''''
+
:Here, a multi-step simulation is a simulation where:
+
 
+
:# one solver is run to completion;
+
:# the dataset is handed over to another solver;
+
:# this solver is run to completion; and
+
:# repeat from step #2 as many times as necessary for as many different solvers as necessary.
+
 
+
Trying to accomplish this within the existing '''runTime''' framework is problematic.  '''multiSolver''' achieves this behaviour neatly.
+
 
+
== When do you need it? ==
+
The '''runTime''' framework can handle nearly every simulation imaginable, but there are situations where '''multiSolver''' will make things much easier.  For example:
+
 
+
* If you are modelling a multi-step process, with clearly defined changes in boundary-conditions over time; or
+
* If you are modelling a single problem with internal processes characterized by vastly different timescales.
+
 
+
Basically, if you find yourself:
+
 
+
* frequently copying data between case directories; or
+
* frequently stopping and changing the simulation details, then restarting,
+
 
+
then '''multiSolver''' might help you.
+
 
+
=== Parallel runs and mesh motion not fully supported yet ===
+
'''NOTE:''' At this time, '''multiSolver''' does not support parallel runs at all; and mesh motion is allowed, provided the mesh returns to its original position between solvers.  This functionality is planned for the future.
+
 
+
== How do you program applications with it? ==
+
 
+
Here's a quick overview of how to program applications with multiSolver.
+
 
+
# Download it;
+
# Compile it;
+
# Write (or choose from existing) solvers that your [[multiSolver/glossary#superSolver|superSolver]] will use;
+
# Set up the createFields for each solver;
+
# Add <tt>#include "multiSolver.H"</tt> to the top;
+
# Between <tt>#include "setRootCase.H"</tt> and <tt>#include "createTime.H"</tt> add:
+
#  include "createMultiRun.H"
+
    solverDomain = "nameOfFirstSolver";
+
#  include "setSolverDomain.H"
+
7. Between each solver, add the lines:
+
    solverDomain = "nameOfNextSolver";
+
#  include "setSolverDomain.H"
+
:where <tt>nameOfNextSovler</tt> is a [[multiSolver/glossary#solverDomainName|solverDomainName]]<BR>
+
8. From each solver, include everything from <tt>#include "createTime.H"</tt> to just before <tt>return 0;</tt><BR>
+
9. At the end, add:
+
#  include "endMultiSolver.H"
+
return 0;
+
 
+
<!--=== dummyControlDict ===
+
In order to allow ''runTimeModification'' of '''multiSolver''''s [[multiSolver/glossary#multiDict|multiDicts]], '''multiSolver''' required its own [[objectRegistry]].  Therefore <tt>multiDictRegistry_</tt> is a <tt>Time</tt> object.  <tt>Time</tt> was never intended to be a member variable, therefore its constructors do not allow initialization without a <tt>controlDict</tt>.  The object <tt>dummyControlDict</tt> was introduced as a self-initializing, minimal <tt>controlDict</tt>.  Ultimately it was necessary for global ''runTimeModification''.
+
-->
+
== How do you run simulations with it? ==
+
Here is a brief overview of how to work with a '''multiSolver'''-enabled application.
+
 
+
=== MultiControlDict ===
+
The [[multiSolver/multiControlDict|multiControlDict]][[multiSolver/glossary#multiControlDict|(glossary)]] is the '''multiSolver''' analogue of the <tt>controlDict</tt>.  The <tt>controlDict</tt> is auto-generated based on the content of this file.  The [[multiSolver/multiControlDict|multiControlDict]] is the main control dictionary and therefore it does not conform to the format of a regular [[#multiDicts|multiDict]][[multiSolver/glossary#multiDict|(glossary)]].  For the full break-down of all settings and options available in the multiControlDict, see [[multiSolver/multiControlDict|multiControlDict]].
+
 
+
=== MultiDicts ===
+
A regular solver reads information from various dictionary files, and these affect its behaviour.  When using '''multiSolver''', there will be dictionaries whose values need to be ''different'' for each [[multiSolver/glossary#solverDomain|solverDomain]].  To specify this behaviour, a [[multiSolver/glossary#multiDict|multiDict]] is used.
+
 
+
A [[multiSolver/glossary#multiDict|multiDict]] has the following structure:
+
dictionaryName  fvSchemes;
+
+
multiSolver
+
{
+
    sovlerDomainName1 // this is the [[multiSolver/glossary#solverDomain|solverDomain]] name
+
    {
+
          // settings for the first solver go here
+
    }
+
    solverDomainName2 // another [[multiSolver/glossary#solverDomain|solverDomain]] name
+
    {
+
        // settings for the second solver go here
+
    }
+
    default // optional
+
    {
+
        // default settings go here
+
        // these are loaded first, then overwritten by solverName (above)
+
        // solvers whose names are not listed above inherit only these settings, or none at all if default is absent
+
    }
+
}
+
 
+
=== Boundary conditions and initial values ===
+
The boundary conditions and initial values are located in:
+
 
+
:<tt>case/multiSolver/<nowiki>[</nowiki>[[multiSolver/glossary#solverDomainName|solverDomainName]]<nowiki>]</nowiki>/0/0</tt>
+
 
+
This is the analogue of the <tt>case/0</tt> directory, except there is one for every [[multiSolver/glossary#solverDomain|solverDomain]].  Unlike in a regular simulation, '''multiSolver''' will ''always'' refer to the boundary conditions located in <tt>0/0</tt>.
+
 
+
'''multiSolver''' allows the boundary conditions to change between [[multiSolver/glossary#solverDomain|solverDomains]].  To accomplish this, '''multiSolver''' will use the ''boundaryField'' specified in <tt><nowiki>[</nowiki>[[multiSolver/glossary#solverDomainName|solverDomainName]]<nowiki>]</nowiki>/0/0</tt> and copy over the latest ''internalField'' (from the previous [[multiSolver/glossary#solverDomain|solverDomain]]).
+
 
+
=== Output Data ===
+
The data is sorted into [[multiSolver/glossary#superLoop|superLoop]] subdirectories within subdirectories named after the [[multiSolver/glossary#solverDomain|solverDomain]]:
+
 
+
:<tt>case/multiSolver/<nowiki>[</nowiki>[[multiSolver/glossary#solverDomainName|solverDomainName]]<nowiki>]</nowiki>/<nowiki>[</nowiki>[[multiSolver/glossary#superLoopIndex|superLoopIndex]]<nowiki>]</nowiki>/[timeValue]</tt>
+
 
+
The standard location of <tt>case/[timeValue]</tt> is used as a temporary loading area, mostly for post-processing.
+
 
+
=== Post-processing ===
+
OpenFOAM is hard-coded to look for data in the <tt>case/[time]</tt> directories.  In order to post-process (including sampling, and data conversion) the data needs to be there.  To accomplish this,
+
 
+
=== Runtime Modification ===
+
There are two levels of runtime modification: within a [[multiSolver/glossary#solverDomain|solverDomain]], and globally.
+
 
+
* Editting a standard dictionary (e.g. <tt>controlDict</tt>, or <tt>transportProperties</tt> applies to a [[multiSolver/glossary#solverDomain|solverDomain]].  Its effect depends on whether that solver has <tt>runTimeModifiable</tt> enabled.  This happens at the end of a solver iteration.  However, these changes will be lost in the next [[multiSolver/glossary#superLoop|superLoop]] when the same [[multiSolver/glossary#solverDomain|solverDomain]] is initialized.
+
 
+
* Editting a [[multiSolver/glossary#multiDict|multiDict]] dictionary applies globally.  This is goverend by <tt>multiDictsRunTimeModifiable</tt> setting in the [[multSolver/multiControlDict|multiControlDict]], but these modifications do not take place until the next [[multiSolver/glossary#solverDomain|solverDomain]] is initialized.  However, these changes are permanent.
+
 
+
== How does it work? ==
+
OpenFOAM is incredibly flexible, and easily extensible, but implementing a change of this kind challenged its founding assumptions.  Therefore, the flexibility was not there on level it needed to be, leaving little option but to use an ''interface-wrapper'' implementation.
+
 
+
:An ''interface-wrapper'' is using an interface for purposes that it was not intended.  For example, I read an old ad for a home security system that called the monitoring company by using a robotic arm to lift the phone receiver and physically dial the numbers.  Why they didn't simply plug the phone line directly into the security system, I have no idea... but this is good example of an ''interface-wrapper''.
+
 
+
'''multiSolver''' works by ''mutating'' the case directory into what each solver requires.  A transient solver will see the correct <tt>ddtSchemes</tt> setting in <tt>fvSchemes</tt>; likewise a steady state solver will see <tt>steadyState</tt> for <tt>ddtSchemes</tt>.  This is the purpose of the [[#multiDicts|multiDict]][[multiSolver/glossary#multiDict|(glossary)]] dictionary format.
+
 
+
The data output and input are hard-coded to the <tt>case/[timeValue]</tt> directory.  Therefore, when '''multiSolver''' initializes the next [[multiSolver/glossary#solverDomain|solverDomain]], it archives the existing output into the correct directory at <tt>case/multiSolver/<nowiki>[</nowiki>[[multiSolver/glossary#solverDomainName|solverDomainName]]<nowiki>]</nowiki>/<nowiki>[</nowiki>[[multiSolver/glossary#superLoopIndex|superLoopIndex]]<nowiki>]</nowiki>/[timeValue]
+
[[Category:Contribution]]
+

Latest revision as of 11:49, 24 November 2013

This project has migrated over to github.

Click here for the new website.

http://github.com/Marupio/multiSolver/wiki