LIMEX plugin
All Classes Functions Variables Typedefs Modules
data_output_observer.hpp
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
44namespace ug {
45
47template<class TDomain, class TAlgebra>
48class 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{
54public:
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 VTKOutputObserver(const char *filename, SmartPtr<vtk_type> vtk)
63 : m_sp_vtk(vtk), m_filename(filename), m_startTime(0.0), m_plotStep(0.0) {}
64
65 VTKOutputObserver(const char *filename, SmartPtr<vtk_type> vtk, number plotStep)
66 : m_sp_vtk(vtk), m_filename(filename), m_startTime(0.0), m_plotStep(plotStep) {}
67
68 virtual ~VTKOutputObserver()
69 { m_sp_vtk = SPNULL; }
70
71
72 void set_output_scales(const std::vector<number>& vScales)
73 {
74 m_vOutputScales = vScales;
75 }
76
77
78 bool step_process(SmartPtr<grid_function_type> uNew, int step, number time, number dt) OVERRIDE
79 {
80 return true;
81 }
82
83
84 bool start_action(SmartPtr<grid_function_type> u, int step, number time, number dt) OVERRIDE
85 {
86 if (!m_sp_vtk.valid())
87 return false;
88
89 writeToFile(u, step, time);
90
91 m_startTime = time;
92 m_uOld = u->clone();
93
94 return true;
95 }
96
97
98 bool finalize_action(SmartPtr<grid_function_type> uNew, int step, number time, number dt) OVERRIDE
99 {
100 if (!m_sp_vtk.valid())
101 return false;
102
103 if (m_plotStep == 0.0)
104 {
105 writeToFile(uNew, step, time);
106 return true;
107 }
108
109 // otherwise, only plot data at multiples of given time step (interpolate if necessary)
110 number rem = fmod(time - dt - m_startTime, m_plotStep);
111 number nextPlotTimePt = time - dt - rem + m_plotStep;
112 int nextStep = (int) ((nextPlotTimePt - m_startTime + 0.5 * m_plotStep) / m_plotStep);
113
114 if (nextPlotTimePt > time)
115 {
116 m_uOld = uNew->clone();
117 return true;
118 }
119
120 SmartPtr<grid_function_type> uCur = uNew->clone_without_values();
121 while (nextPlotTimePt <= time)
122 {
123 number alpha = (time - nextPlotTimePt) / dt;
124 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 writeToFile(uCur, nextStep, nextPlotTimePt);
129
130 nextPlotTimePt = (++nextStep) * m_plotStep;
131 }
132
133 m_uOld = uNew->clone();
134 return true;
135 }
136
137
138 bool end_action(SmartPtr<grid_function_type> u, int step, number time, number dt) OVERRIDE
139 {
140 if (!m_sp_vtk.valid())
141 return false;
142
143 m_sp_vtk->write_time_pvd(m_filename.c_str(), *u);
144 return true;
145 }
146
147
148private:
149 void writeToFile(SmartPtr<grid_function_type> u, int step, number time)
150 {
151 if (m_vOutputScales.size())
152 {
153 SmartPtr<grid_function_type> uTmp = u->clone_without_values();
154 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 }
160
161protected:
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
171template<class TDomain, class TAlgebra>
172class ConnectionViewerOutputObserver
173: public ITimeIntegratorObserver<TDomain, TAlgebra>
174{
175public:
176 typedef ITimeIntegratorObserver<TDomain, TAlgebra> base_type;
177 typedef GridFunction<TDomain, TAlgebra> grid_function_type;
178
179 ConnectionViewerOutputObserver(const char *filename)
180 : m_filename(filename), m_outputTime(-1.0) {}
181
182 ConnectionViewerOutputObserver(const char *filename, number t_out)
183 : m_filename(filename), m_outputTime(t_out) {}
184
185 virtual ~ConnectionViewerOutputObserver()
186 {}
187
188 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 if (m_outputTime >=0.0 && time != m_outputTime) return true;
192
193 SaveVectorForConnectionViewer<grid_function_type>(*uNew, m_filename.c_str());
194 return true;
195 }
196
197protected:
198 std::string m_filename;
199 number m_outputTime;
200
201};
202
203} // namespace ug
204
205#endif /* __H__LIMEX__DATA_OUTPUT_OBSERVER_HPP__ */