File: Scene.hpp

package info (click to toggle)
yade 2026.1.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 34,448 kB
  • sloc: cpp: 97,645; python: 52,173; sh: 677; makefile: 162
file content (141 lines) | stat: -rw-r--r-- 7,098 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/*************************************************************************
*  Copyright (C) 2004 by Olivier Galizzi                                 *
*  olivier.galizzi@imag.fr                                               *
*  Copyright (C) 2004 by Janek Kozicki                                   *
*  cosurgi@berlios.de                                                    *
*                                                                        *
*  This program is free software; it is licensed under the terms of the  *
*  GNU General Public License v2 or later. See file LICENSE for details. *
*************************************************************************/

#pragma once

#include <core/Body.hpp>
#include <core/BodyContainer.hpp>
#include <core/Cell.hpp>
#include <core/DisplayParameters.hpp>
#include <core/EnergyTracker.hpp>
#include <core/Engine.hpp>
#include <core/ForceContainer.hpp>
#include <core/InteractionContainer.hpp>
#include <core/Material.hpp>
#ifdef YADE_MPI
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpragmas"
#pragma GCC diagnostic ignored "-Wsuggest-override"
#pragma GCC diagnostic ignored "-Wcast-function-type"
#include <mpi.h>
#pragma GCC diagnostic pop
#endif

#ifdef YADE_OPENMP
#include <omp.h>
#endif


namespace yade { // Cannot have #include directive inside.
class Shape;
class Bound;
#ifdef YADE_OPENGL
class OpenGLRenderer;
#endif

class Scene : public Serializable {
	const unsigned int hostNameMax = 255;

public:
	//! Adds material to Scene::materials. It also sets id of the material accordingly and returns it.
	int addMaterial(shared_ptr<Material> m)
	{
		materials.push_back(m);
		m->id = (int)materials.size() - 1;
		return m->id;
	}
	//! Checks that type of Body::state satisfies Material::stateTypeOk. Throws runtime_error if not. (Is called from BoundDispatcher the first time it runs)
	void checkStateTypes();
	//! update our bound; used directly instead of a BoundFunctor, since we don't derive from Body anymore
	void updateBound();

	// neither serialized, nor accessible from python (at least not directly)
	ForceContainer forces;

	// initialize tags (author, date, time)
	void fillDefaultTags();
	// advance by one iteration by running all engines
	void moveToNextTimeStep();

	/* Functions operating on TimeStepper; they all throw exception if there is more than 1 */
	// return whether a TimeStepper is present
	bool timeStepperPresent();
	// true if TimeStepper is present and active, false otherwise
	bool timeStepperActive();
	// (de)activate TimeStepper; returns whether the operation was successful (i.e. whether a TimeStepper was found)
	bool                               timeStepperActivate(bool activate);
	static const int                   nSpeedIter = 10; //Number of iterations, which are taking into account for speed calculation
	Eigen::Matrix<Real, nSpeedIter, 1> SpeedElements;   //Array for saving speed-values for last "nSpeedIter"-iterations

	shared_ptr<Engine> engineByName(const string& s);

#ifdef YADE_LIQMIGRATION
	OpenMPVector<Interaction*>          addIntrs; //Array of added interactions, needed for liquid migration.
	OpenMPVector<std::pair<id_t, Real>> delIntrs; //Array of deleted interactions, needed for liquid migration.
#endif

#ifdef YADE_OPENGL
	shared_ptr<OpenGLRenderer> renderer;
#endif

#ifdef YADE_MPI
	MPI_Comm getComm();
#endif

	void postLoad(Scene&);

	boost::posix_time::ptime prevTime; //Time value on the previous step

	// clang-format off
	YADE_CLASS_BASE_DOC_ATTRS_CTOR_PY(Scene,Serializable,"Object comprising a stand-alone simulation.",
		((Real,dt,1e-8,,"Current timestep for integration."))
		((long,iter,0,Attr::readonly,"Current iteration (computational step) number"))
		((bool,subStepping,false,,"Whether we currently advance by one engine in every step (rather than by single run through all engines)."))
		((int,subStep,-1,Attr::readonly,"Number of sub-step; not to be changed directly. -1 means to run loop prologue (cell integration), 0…n-1 runs respective engines (n is number of engines), n runs epilogue (increment step number and time."))
		((Real,time,0,Attr::readonly,"Simulation time (virtual time) [s]"))
		((Real,speed,0,Attr::readonly,"Current calculation speed [iter/s]"))
		((long,stopAtIter,0,,"Iteration after which to stop the simulation."))
		((Real,stopAtTime,0,,"Time after which to stop the simulation"))
		((bool,isPeriodic,false,Attr::readonly,"Whether periodic boundary conditions are active."))
		((bool,trackEnergy,false,Attr::readonly,"Whether energies are being traced."))
		((bool,doSort,false,Attr::readonly,"Used, when new body is added to the scene."))
		((bool,runInternalConsistencyChecks,true,Attr::hidden,"Run internal consistency check, right before the very first simulation step."))
		((Body::id_t,selectedBody,-1,,"Id of body that is selected by the user"))
	#ifdef YADE_MPI
		((int,subdomain,0,,"the subdomain this scene is assigned in MPI/domain decomposition."))
		((shared_ptr<Shape>,subD,boost::make_shared<Shape>(),,"subdomain (shape) attached to this proc."))
	#endif
		((vector<string>,tags,,,"Arbitrary key=value associations (tags like mp3 tags: author, date, version, description etc.)"))
		((vector<shared_ptr<Engine> >,engines,,Attr::hidden,"Engines sequence in the simulation."))
		((vector<shared_ptr<Engine> >,_nextEngines,,Attr::hidden,"Engines to be used from the next step on; is returned transparently by O.engines if in the middle of the loop (controlled by subStep>=0)."))
		// NOTE: bodies must come before interactions, since InteractionContainer is initialized with a reference to BodyContainer::body
		((shared_ptr<BodyContainer>,bodies,new BodyContainer,Attr::hidden,"Bodies contained in the scene."))
		((shared_ptr<InteractionContainer>,interactions,new InteractionContainer,Attr::hidden,"All interactions between bodies."))
		((shared_ptr<EnergyTracker>,energy,new EnergyTracker,Attr::hidden,"Energy values, if energy tracking is enabled."))
		((vector<shared_ptr<Material> >,materials,,Attr::hidden,"Container of shared materials. Add elements using Scene::addMaterial, not directly. Do NOT remove elements from here unless you know what you are doing!"))
		((shared_ptr<Bound>,bound,,Attr::hidden,"Bounding box of the scene (only used for rendering and initialized if needed)."))

		((shared_ptr<Cell>,cell,new Cell,Attr::hidden,"Information on periodicity; only should be used if Scene::isPeriodic."))
		((vector<shared_ptr<Serializable> >,miscParams,,Attr::hidden,"Store for arbitrary Serializable objects; will set static parameters during deserialization (primarily for GLDraw functors which otherwise have no attribute access)"))
		((vector<shared_ptr<DisplayParameters> >,dispParams,,Attr::hidden,"'hash maps' of display parameters (since yade::serialization had no support for maps, emulate it via vector of strings in format key=value)"))
		,
		/*ctor*/
			fillDefaultTags();
			interactions->postLoad__calledFromScene(bodies);
			SpeedElements.Zero();
		,
		/* py */
	);
	// clang-format on
	DECLARE_LOGGER;
};
REGISTER_SERIALIZABLE(Scene);

} // namespace yade