|
|
|
|
|
|
|
## Global view
|
|
|
|
|
|
|
|
The main purpose of a fargo3D simulation is to track the evolution of a planetary system embedded in a disk of gas. Those two entities will be represented by a **GasDisk** and **PlanetarySystem** class respectively. A single simulation will instantiate one object of each.
|
|
|
|
|
|
|
|
That simulation is driven by an instance of the **SimulationDriver** class (currently implementing a simple [Command pattern](https://en.wikipedia.org/wiki/Command_pattern), but might evolve into a [Template Method](https://en.wikipedia.org/wiki/Template_method_pattern). It behave like a function object with perform one step of the simulation at each call.
|
|
|
|
|
|
|
|
The simulation configuration is done through a property tree.
|
|
|
|
|
|
|
|
The main sequence diagram can be seen as follow:
|
|
|
|
|
|
|
|
```plantuml
|
|
|
|
participant main
|
|
|
|
participant driver
|
|
|
|
participant gasDisk
|
|
|
|
participant planets
|
|
|
|
database storage
|
|
|
|
main -> gasDisk : load initial state
|
|
|
|
main -> driver : create
|
|
|
|
loop monitor
|
|
|
|
loop time steps
|
|
|
|
main -> driver : next step
|
|
|
|
driver -> gasDisk : sub step 1
|
|
|
|
driver -> gasDisk : sub step <N>
|
|
|
|
gasDisk -> planets : rotate
|
|
|
|
driver -> main : done
|
|
|
|
end
|
|
|
|
main -> gasDisk : write state
|
|
|
|
gasDisk -> storage : dump fields
|
|
|
|
main -> planets : monitor
|
|
|
|
planets -> storage : write position and masses
|
|
|
|
main -> storage : write disk info
|
|
|
|
end
|
|
|
|
```
|
|
|
|
|
|
|
|
The (incomplete) class diagram[^1] could be summarized as:
|
|
|
|
|
|
|
|
```plantuml
|
|
|
|
namespace fargOCA {
|
|
|
|
class SystemPhysic <<(S,#FF7700)>> {
|
|
|
|
}
|
|
|
|
class DiskDesc << (S,#FF7700) >> {
|
|
|
|
}
|
|
|
|
class DiskPhysic <<S,#FF7700)>> {
|
|
|
|
}
|
|
|
|
|
|
|
|
class DiskGrid << (S,#FF7700) >> {
|
|
|
|
int nbRadius, nbLayer, nbSector
|
|
|
|
real minRadius, maxRadius
|
|
|
|
mpi::communicator comm
|
|
|
|
|
|
|
|
}
|
|
|
|
class PolarGrid {
|
|
|
|
string name
|
|
|
|
real[] field
|
|
|
|
}
|
|
|
|
class Planet {
|
|
|
|
sting name
|
|
|
|
real mass
|
|
|
|
real x,y,z
|
|
|
|
real vx,vy,vz
|
|
|
|
}
|
|
|
|
class PlanetarySystem {
|
|
|
|
void rotate(real dt)
|
|
|
|
void monitor(fileName)
|
|
|
|
}
|
|
|
|
class GasDisk {
|
|
|
|
void applyBoundariesConditions()
|
|
|
|
void setGhosts()
|
|
|
|
void read(fileName)
|
|
|
|
void write(fileName)
|
|
|
|
void monitor(fileName)
|
|
|
|
}
|
|
|
|
class GasDisk::Velocity {
|
|
|
|
}
|
|
|
|
class SimuProgress {
|
|
|
|
real physicalTime
|
|
|
|
real step
|
|
|
|
void isOutputStep()
|
|
|
|
}
|
|
|
|
class BoundariesHandler {
|
|
|
|
string name
|
|
|
|
void operator()(GarsDisk& gas, real step);
|
|
|
|
}
|
|
|
|
class FctBoundariesHandler {
|
|
|
|
void operator()(GarsDisk& gas, real step);
|
|
|
|
}
|
|
|
|
FctBoundariesHandler --|> BoundariesHandler
|
|
|
|
GasDisk o--> "many" BoundariesHandler
|
|
|
|
}
|
|
|
|
namespace D3 {
|
|
|
|
class SimulationDriver {
|
|
|
|
void operator()(flow, torque)
|
|
|
|
-- private sub steps ---
|
|
|
|
void subStep1(..)
|
|
|
|
void subStep<N>(..)
|
|
|
|
-- private util. --
|
|
|
|
myRadiationManager
|
|
|
|
myTransport
|
|
|
|
}
|
|
|
|
}
|
|
|
|
note top of fargOCA.DiskPhysic
|
|
|
|
Configuration of the disk
|
|
|
|
physical properties
|
|
|
|
and behavior
|
|
|
|
end note
|
|
|
|
note left of fargOCA.SystemPhysic
|
|
|
|
Configuration of the
|
|
|
|
planetary system
|
|
|
|
physical properties
|
|
|
|
and behavior
|
|
|
|
end note
|
|
|
|
D3.SimulationDriver o--> fargOCA.GasDisk
|
|
|
|
D3.SimulationDriver o--> fargOCA.SimuProgress
|
|
|
|
fargOCA.PlanetarySystem "1"*-->"many" fargOCA.Planet
|
|
|
|
fargOCA.PlanetarySystem o--> fargOCA.SystemPhysic
|
|
|
|
fargOCA.DiskDesc "1"*-->"1" fargOCA.DiskGrid
|
|
|
|
fargOCA.DiskDesc "1"*-->"1" fargOCA.DiskPhysic
|
|
|
|
fargOCA.PolarGrid o-->"1" fargOCA.DiskGrid
|
|
|
|
fargOCA.GasDisk o-->"1" fargOCA.DiskDesc
|
|
|
|
fargOCA.GasDisk o-->"1" fargOCA.PlanetarySystem
|
|
|
|
fargOCA.GasDisk *--> fargOCA.PolarGrid: pressure\n soundSpeed\n density\n viscosity
|
|
|
|
fargOCA.GasDisk "1"*-->"1" fargOCA.GasDisk::Velocity
|
|
|
|
fargOCA.GasDisk::Velocity *--> fargOCA.PolarGrid: radial\n phi\n theta
|
|
|
|
```
|
|
|
|
## The polar grid object.
|
|
|
|
|
|
|
|
The most part of the program is spent manipulating **PolarGrid**[^2] instances. A polar grid is basically a 3D field of continuous floating point data organized on a grid with as `[nr radial][ni layer][ns sector]` if we use $`nr*ni*ns`$ grids.
|
|
|
|
|
|
|
|
This object only store the data as a [std::valarray<double>](http://www.cplusplus.com/reference/valarray/)[^4] object field, but also export it as an old fashioned C pointer[^3].
|
|
|
|
|
|
|
|
## The disk description
|
|
|
|
|
|
|
|
The disk geometry and physic configuration are described through a set of classes that are almost (almost) a [Singleton](https://en.wikipedia.org/wiki/Singleton_pattern) (because we do not need many of them). All object that need to have access to those information do so by referencing the appropriate instances.
|
|
|
|
|
|
|
|
The "almost" is important, as in the short term, it will allow close to trivial implementation of multi-grid decomposition by providing one instance by sub-domain.
|
|
|
|
|
|
|
|
* **DiskPhysic** provide the physical parameter of the disk. It is close to a direct mapping of the user provided property tree.
|
|
|
|
* **SystemPhysic** paly a similar role for the planetary system.
|
|
|
|
* **DiskGrid** is . It describe discretization of the (possibly flat) cylinder containing the gas. That include the grid points, aperture, etc.. and some usefull pre computed values. More than one **DiskGrid** object exist when the grid resolution is modified and a polar grid need to be re-mapped.
|
|
|
|
|
|
|
|
## Boundaries Conditions
|
|
|
|
|
|
|
|
Boundaries condition are implemented through **BoundariesHandler** [function objects](https://en.wikipedia.org/wiki/Command_pattern)[^5].
|
|
|
|
* All available handlers are registered by name in the application (user can add their own).
|
|
|
|
* In the configuration file, the user indicate the names of the requested handler.
|
|
|
|
* The application then bind those handler to the **GasDisk** object.
|
|
|
|
* The **SimulationDriver** object will then trigger them when required.
|
|
|
|
|
|
|
|
-------
|
|
|
|
[^1]: In particular, the diagram does not detail the configuration aspects in details.
|
|
|
|
[^2]: Not a very smart name, but **Field** was already used at the time. It might change in the future.
|
|
|
|
[^3]: Mostly for backward compatibility/laziness/lack of time.
|
|
|
|
[^4]: Intel has [special optimizations](https://software.intel.com/en-us/articles/using-improved-stdvalarray-with-intelr-c-compiler) for `std::valarray`, has not been tested yet.
|
|
|
|
[^5] Also called "callback". |
|
|
|
\ No newline at end of file |