Line data Source code
1 : /*
2 : * SPDX-FileCopyrightText: Copyright (c) 2014-2025: G-CSC, Goethe University Frankfurt
3 : * SPDX-License-Identifier: LicenseRef-UG4-LGPL-3.0
4 : *
5 : * Author: Arne Naegel, Andreas Kreienbuehl
6 : *
7 : * This file is part of UG4.
8 : *
9 : * UG4 is free software: you can redistribute it and/or modify it under the
10 : * terms of the GNU Lesser General Public License version 3 (as published by the
11 : * Free Software Foundation) with the following additional attribution
12 : * requirements (according to LGPL/GPL v3 §7):
13 : *
14 : * (1) The following notice must be displayed in the Appropriate Legal Notices
15 : * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
16 : *
17 : * (2) The following notice must be displayed at a prominent place in the
18 : * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
19 : *
20 : * (3) The following bibliography is recommended for citation and must be
21 : * preserved in all covered files:
22 : * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
23 : * parallel geometric multigrid solver on hierarchically distributed grids.
24 : * Computing and visualization in science 16, 4 (2013), 151-164"
25 : * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
26 : * flexible software system for simulating pde based models on high performance
27 : * computers. Computing and visualization in science 16, 4 (2013), 165-179"
28 : *
29 : * This program is distributed in the hope that it will be useful,
30 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
31 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 : * GNU Lesser General Public License for more details.
33 : */
34 :
35 : #ifndef __H__LIMEX__DATA_OUTPUT_OBSERVER_HPP__
36 : #define __H__LIMEX__DATA_OUTPUT_OBSERVER_HPP__
37 :
38 : #include <string>
39 : #include <vector>
40 :
41 : #include "lib_disc/time_disc/time_integrator_observers/time_integrator_observer_interface.h"
42 : #include "lib_disc/io/vtkoutput.h"
43 :
44 : namespace ug {
45 :
46 : /// Class for integration observer: Output to VTK
47 : template<class TDomain, class TAlgebra>
48 : class VTKOutputObserver
49 : : public ITimeIntegratorObserver<TDomain, TAlgebra>,
50 : public ITimeIntegratorStageObserver_start<TDomain, TAlgebra>,
51 : public ITimeIntegratorStageObserver_finalize<TDomain, TAlgebra>,
52 : public ITimeIntegratorStageObserver_end<TDomain, TAlgebra>
53 : {
54 : public:
55 : typedef ITimeIntegratorObserver<TDomain, TAlgebra> base_type;
56 : typedef GridFunction<TDomain, TAlgebra> grid_function_type;
57 : typedef VTKOutput<TDomain::dim> vtk_type;
58 :
59 : VTKOutputObserver()
60 : : m_sp_vtk(SPNULL), m_filename("0000"), m_startTime(0.0), m_plotStep(0.0) {}
61 :
62 0 : VTKOutputObserver(const char *filename, SmartPtr<vtk_type> vtk)
63 0 : : m_sp_vtk(vtk), m_filename(filename), m_startTime(0.0), m_plotStep(0.0) {}
64 :
65 0 : VTKOutputObserver(const char *filename, SmartPtr<vtk_type> vtk, number plotStep)
66 0 : : m_sp_vtk(vtk), m_filename(filename), m_startTime(0.0), m_plotStep(plotStep) {}
67 :
68 0 : virtual ~VTKOutputObserver()
69 0 : { m_sp_vtk = SPNULL; }
70 :
71 :
72 0 : void set_output_scales(const std::vector<number>& vScales)
73 : {
74 0 : m_vOutputScales = vScales;
75 0 : }
76 :
77 :
78 0 : bool step_process(SmartPtr<grid_function_type> uNew, int step, number time, number dt) OVERRIDE
79 : {
80 0 : return true;
81 : }
82 :
83 :
84 0 : bool start_action(SmartPtr<grid_function_type> u, int step, number time, number dt) OVERRIDE
85 : {
86 0 : if (!m_sp_vtk.valid())
87 : return false;
88 :
89 0 : writeToFile(u, step, time);
90 :
91 0 : m_startTime = time;
92 0 : m_uOld = u->clone();
93 :
94 0 : return true;
95 : }
96 :
97 :
98 0 : bool finalize_action(SmartPtr<grid_function_type> uNew, int step, number time, number dt) OVERRIDE
99 : {
100 0 : if (!m_sp_vtk.valid())
101 : return false;
102 :
103 0 : if (m_plotStep == 0.0)
104 : {
105 0 : writeToFile(uNew, step, time);
106 0 : return true;
107 : }
108 :
109 : // otherwise, only plot data at multiples of given time step (interpolate if necessary)
110 0 : number rem = fmod(time - dt - m_startTime, m_plotStep);
111 0 : number nextPlotTimePt = time - dt - rem + m_plotStep;
112 0 : int nextStep = (int) ((nextPlotTimePt - m_startTime + 0.5 * m_plotStep) / m_plotStep);
113 :
114 0 : if (nextPlotTimePt > time)
115 : {
116 0 : m_uOld = uNew->clone();
117 0 : return true;
118 : }
119 :
120 0 : SmartPtr<grid_function_type> uCur = uNew->clone_without_values();
121 0 : while (nextPlotTimePt <= time)
122 : {
123 0 : number alpha = (time - nextPlotTimePt) / dt;
124 0 : VecScaleAdd(static_cast<typename TAlgebra::vector_type&>(*uCur),
125 : alpha, static_cast<typename TAlgebra::vector_type&>(*m_uOld),
126 : 1.0 - alpha, static_cast<typename TAlgebra::vector_type&>(*uNew));
127 :
128 0 : writeToFile(uCur, nextStep, nextPlotTimePt);
129 :
130 0 : nextPlotTimePt = (++nextStep) * m_plotStep;
131 : }
132 :
133 0 : m_uOld = uNew->clone();
134 : return true;
135 : }
136 :
137 :
138 0 : bool end_action(SmartPtr<grid_function_type> u, int step, number time, number dt) OVERRIDE
139 : {
140 0 : if (!m_sp_vtk.valid())
141 : return false;
142 :
143 0 : m_sp_vtk->write_time_pvd(m_filename.c_str(), *u);
144 0 : return true;
145 : }
146 :
147 :
148 : private:
149 0 : void writeToFile(SmartPtr<grid_function_type> u, int step, number time)
150 : {
151 0 : if (m_vOutputScales.size())
152 : {
153 0 : SmartPtr<grid_function_type> uTmp = u->clone_without_values();
154 0 : ScaleGF<grid_function_type>(uTmp, u, m_vOutputScales);
155 : m_sp_vtk->print(m_filename.c_str(), *uTmp, step, time);
156 : }
157 : else
158 : m_sp_vtk->print(m_filename.c_str(), *u, step, time);
159 0 : }
160 :
161 : protected:
162 : SmartPtr<vtk_type> m_sp_vtk;
163 : SmartPtr<grid_function_type> m_uOld;
164 : std::string m_filename;
165 : number m_startTime;
166 : number m_plotStep;
167 : std::vector<number> m_vOutputScales;
168 : };
169 :
170 : /// Class for integration observer: Output to ConnectionViewer
171 : template<class TDomain, class TAlgebra>
172 : class ConnectionViewerOutputObserver
173 : : public ITimeIntegratorObserver<TDomain, TAlgebra>
174 : {
175 : public:
176 : typedef ITimeIntegratorObserver<TDomain, TAlgebra> base_type;
177 : typedef GridFunction<TDomain, TAlgebra> grid_function_type;
178 :
179 0 : ConnectionViewerOutputObserver(const char *filename)
180 0 : : m_filename(filename), m_outputTime(-1.0) {}
181 :
182 0 : ConnectionViewerOutputObserver(const char *filename, number t_out)
183 0 : : m_filename(filename), m_outputTime(t_out) {}
184 :
185 0 : virtual ~ConnectionViewerOutputObserver()
186 0 : {}
187 :
188 0 : bool step_process(SmartPtr<grid_function_type> uNew, /*SmartPtr<grid_function_type> uOld, */int step, number time, number dt) OVERRIDE
189 : {
190 : // quit, if time does not match
191 0 : if (m_outputTime >=0.0 && time != m_outputTime) return true;
192 :
193 : SaveVectorForConnectionViewer<grid_function_type>(*uNew, m_filename.c_str());
194 0 : return true;
195 : }
196 :
197 : protected:
198 : std::string m_filename;
199 : number m_outputTime;
200 :
201 : };
202 :
203 : } // namespace ug
204 :
205 : #endif /* __H__LIMEX__DATA_OUTPUT_OBSERVER_HPP__ */
|