ViennaLS
Loading...
Searching...
No Matches
lsAdvectIntegrationSchemes.hpp
Go to the documentation of this file.
1#pragma once
2
4#include <lsDomain.hpp>
5
6namespace viennals {
7
23
24// Legacy naming (deprecated, will be removed in future versions)
25using IntegrationSchemeEnum [[deprecated("Use SpatialSchemeEnum instead")]] =
27
35
36// Forward declaration
37template <class T, int D> class Advect;
38} // namespace viennals
39
40namespace lsInternal {
41
42template <class T, int D> struct AdvectTimeIntegration {
44
45 static double evolveForwardEuler(AdvectType &kernel, double maxTimeStep) {
46 if (kernel.currentTimeStep < 0. || kernel.storedRates.empty())
47 kernel.computeRates(maxTimeStep);
48
49 kernel.updateLevelSet(kernel.currentTimeStep);
50
51 kernel.rebuildLS();
52
53 kernel.adjustLowerLayers();
54
55 return kernel.currentTimeStep;
56 }
57
58 static double evolveRungeKutta2(AdvectType &kernel, double maxTimeStep) {
59 // TVD Runge-Kutta 2nd Order (Heun's Method)
60 // 1. Determine time step
61 kernel.computeRates(maxTimeStep);
62 const double dt = kernel.getCurrentTimeStep();
63
64 // 2. Save u^n
65 if (kernel.originalLevelSet == nullptr) {
66 kernel.originalLevelSet =
67 viennals::Domain<T, D>::New(kernel.levelSets.back()->getGrid());
68 }
69 kernel.originalLevelSet->deepCopy(kernel.levelSets.back());
70
71 if (dt <= 0)
72 return 0.;
73
74 // Stage 1: u^(1) = u^n + dt * L(u^n)
75 kernel.updateLevelSet(dt);
76
77 // Stage 2: u^(n+1) = 1/2 u^n + 1/2 (u^(1) + dt * L(u^(1)))
78 // Current level set is u^(1). Compute L(u^(1)).
79 kernel.computeRates(dt);
80 // Update to u* = u^(1) + dt * L(u^(1))
81 kernel.updateLevelSet(dt);
82 // Combine: u^(n+1) = 0.5 * u^n + 0.5 * u*
83 kernel.combineLevelSets(0.5, 0.5);
84
85 // Finalize
86 kernel.rebuildLS();
87
88 kernel.adjustLowerLayers();
89
90 return dt;
91 }
92
93 static double evolveRungeKutta3(AdvectType &kernel, double maxTimeStep) {
94 // 1. Determine the single time step 'dt' for all stages.
95 kernel.computeRates(maxTimeStep);
96 const double dt = kernel.getCurrentTimeStep();
97
98 // 2. Save u^n (Deep copy to preserve topology)
99 if (kernel.originalLevelSet == nullptr) {
100 kernel.originalLevelSet =
101 viennals::Domain<T, D>::New(kernel.levelSets.back()->getGrid());
102 }
103 kernel.originalLevelSet->deepCopy(kernel.levelSets.back());
104
105 // If dt is 0 or negative, no advection is possible or needed.
106 if (dt <= 0)
107 return 0.;
108
109 // Stage 1: u^(1) = u^n + dt * L(u^n)
110 kernel.updateLevelSet(dt);
111
112 // Stage 2: u^(2) = 3/4 u^n + 1/4 (u^(1) + dt * L(u^(1)))
113 kernel.computeRates(dt);
114 kernel.updateLevelSet(dt);
115 // Combine to get u^(2) = 0.75 * u^n + 0.25 * u*.
116 kernel.combineLevelSets(0.75, 0.25);
117
118 // Stage 3: u^(n+1) = 1/3 u^n + 2/3 (u^(2) + dt * L(u^(2)))
119 kernel.computeRates(dt);
120 kernel.updateLevelSet(dt);
121 // Combine to get u^(n+1) = 1/3 * u^n + 2/3 * u**.
122 kernel.combineLevelSets(1.0 / 3.0, 2.0 / 3.0);
123
124 // Finalize: Re-segment and renormalize the final result.
125 kernel.rebuildLS();
126
127 kernel.adjustLowerLayers();
128
129 return dt;
130 }
131};
132
133} // namespace lsInternal
This class is used to advance level sets over time. Level sets are passed to the constructor in a std...
Definition lsAdvect.hpp:53
double getCurrentTimeStep() const
Return the last applied time step.
Definition lsAdvect.hpp:913
static auto New(Args &&...args)
Definition lsDomain.hpp:111
Definition lsAdvectIntegrationSchemes.hpp:40
Definition lsAdvect.hpp:40
SpatialSchemeEnum
Enumeration for the different spatial discretization schemes used by the advection kernel.
Definition lsAdvectIntegrationSchemes.hpp:10
@ LOCAL_LOCAL_LAX_FRIEDRICHS_2ND_ORDER
Definition lsAdvectIntegrationSchemes.hpp:17
@ STENCIL_LOCAL_LAX_FRIEDRICHS_1ST_ORDER
Definition lsAdvectIntegrationSchemes.hpp:20
@ LOCAL_LOCAL_LAX_FRIEDRICHS_1ST_ORDER
Definition lsAdvectIntegrationSchemes.hpp:16
@ LAX_FRIEDRICHS_2ND_ORDER
Definition lsAdvectIntegrationSchemes.hpp:14
@ LOCAL_LAX_FRIEDRICHS_1ST_ORDER
Definition lsAdvectIntegrationSchemes.hpp:18
@ ENGQUIST_OSHER_2ND_ORDER
Definition lsAdvectIntegrationSchemes.hpp:12
@ LAX_FRIEDRICHS_1ST_ORDER
Definition lsAdvectIntegrationSchemes.hpp:13
@ LOCAL_LAX_FRIEDRICHS_2ND_ORDER
Definition lsAdvectIntegrationSchemes.hpp:19
@ ENGQUIST_OSHER_1ST_ORDER
Definition lsAdvectIntegrationSchemes.hpp:11
@ LOCAL_LAX_FRIEDRICHS_ANALYTICAL_1ST_ORDER
Definition lsAdvectIntegrationSchemes.hpp:15
@ WENO_5TH_ORDER
Definition lsAdvectIntegrationSchemes.hpp:21
TemporalSchemeEnum
Enumeration for the different time integration schemes used to select the advection kernel.
Definition lsAdvectIntegrationSchemes.hpp:30
@ RUNGE_KUTTA_2ND_ORDER
Definition lsAdvectIntegrationSchemes.hpp:32
@ RUNGE_KUTTA_3RD_ORDER
Definition lsAdvectIntegrationSchemes.hpp:33
@ FORWARD_EULER
Definition lsAdvectIntegrationSchemes.hpp:31
Definition lsAdvectIntegrationSchemes.hpp:42
viennals::Advect< T, D > AdvectType
Definition lsAdvectIntegrationSchemes.hpp:43
static double evolveRungeKutta3(AdvectType &kernel, double maxTimeStep)
Definition lsAdvectIntegrationSchemes.hpp:93
static double evolveForwardEuler(AdvectType &kernel, double maxTimeStep)
Definition lsAdvectIntegrationSchemes.hpp:45
static double evolveRungeKutta2(AdvectType &kernel, double maxTimeStep)
Definition lsAdvectIntegrationSchemes.hpp:58