CppNoddy  0.92
Loading...
Searching...
No Matches
OneD_TVDLF_Elt.cpp
Go to the documentation of this file.
1/// \file OneD_TVDLF_Elt.cpp
2/// Implementation of a one dimensional linear element for
3/// use in a TVD Lax-Friedrichs scheme.
4
5#include <list>
6
8#include <OneD_TVDLF_Elt.h>
9#include <Types.h>
10
11namespace CppNoddy {
12
15 bool flag, int index) {
16#ifdef DEBUG
17 std::cout << "DEBUG: Constructing a OneD_TVDLF_Elt object between "
18 << a << " and " << b << "\n";
19#endif
20 system_ptr = ptr;
21 LEFT = a;
22 RIGHT = b;
23 EXTERNAL = flag;
24 EXTERNAL_FACE_I = index;
25 SLOPE = DenseVector<double>(system_ptr -> get_order(), 0.0);
26 Q = DenseVector<double>(system_ptr -> get_order(), 0.0);
27 }
28
30 {}
31
33 contribution cont;
34 cont.elt_ptr = ptr;
35 cont.s = s_range;
36 cont.face_index = index;
37 // push the contribution data into a list
38 CONT_LIST.push_back(cont);
39 }
40
42 std::list< contribution >::iterator c = CONT_LIST.begin();
43 // start with zero
44 DenseVector<double> sum(system_ptr -> get_order(), 0.0);
45 // loop over contributions
46 while(c != CONT_LIST.end()) {
47 // get integral of each
48 sum += c -> elt_ptr -> get_int_Q(c -> s[0], c -> s[1]);
49 ++c;
50 }
51 return sum;
52 }
53
54 void OneD_TVDLF_Elt::contributed_flux_in_left(const double &dt, DenseVector<double> &flux_in_left, const double &current_time) {
55 std::list< contribution >::iterator c = CONT_LIST.begin();
56 // loop over all contributing elements
57 while(c != CONT_LIST.end()) {
58 // find contributions to the left face
59 if(c -> face_index == -1) {
60 // which local coord in the contributing elt?
61 const double s = c -> s[ 0 ];
62 DenseVector<double> q_half_step(c -> elt_ptr -> get_Q(s));
63 // add half step correction
64 q_half_step += (c -> elt_ptr -> get_source_fn(s)
65 - c -> elt_ptr -> get_Jac_flux_fn(s).multiply(c -> elt_ptr -> SLOPE))
66 * 0.5 * dt;
67 //DenseVector<double> x( 1, 0.0 ); x[ 0 ] = c -> elt_ptr -> get_x( s );
68 double x(c -> elt_ptr -> get_x(s));
69 // evaluate the flux at this Q value
70 c -> elt_ptr -> system_ptr -> flux_fn(x, q_half_step, flux_in_left);
71 }
72 ++c;
73 }
74 // treat the user specified external faces separately
75 if(EXTERNAL) {
76 // we are in an external elt
77 c = CONT_LIST.begin();
78 while(c != CONT_LIST.end()) {
79 // external faces are external for the current elt *and* its contributions
80 if(c -> elt_ptr -> get_external_flag()) {
81 if(EXTERNAL_FACE_I < 0) {
82 // LH boundary
83 DenseVector<double> q_left(c -> elt_ptr -> get_Q(-1.0));
84 // convert x at boundary to a vector
85 //DenseVector<double> x_left( 1, 0.0 ); x_left[ 0 ] = c -> elt_ptr -> get_x( -1.0 );
86 double x_left(c -> elt_ptr -> get_x(-1.0));
87 DenseVector<double> q_left_half_step(q_left);
88 //compute flux at the half time step
89 q_left_half_step += (c -> elt_ptr -> get_source_fn(-1.0)
90 - c -> elt_ptr -> get_Jac_flux_fn(-1.0).multiply(c -> elt_ptr -> SLOPE))
91 * 0.5 * dt;
92 // get the edge values
93 system_ptr -> edge_values(-1, x_left, q_left_half_step, current_time + 0.5*dt);
94 // get the flux
95 system_ptr -> flux_fn(x_left, q_left_half_step, flux_in_left);
96 }
97 }
98 ++c;
99 }
100 }
101 }
102
103 void OneD_TVDLF_Elt::contributed_flux_out_right(const double &dt, DenseVector<double> &flux_out_right, const double &current_time) {
104 std::list< contribution >::iterator c = CONT_LIST.begin();
105 // loop over all contributing elements
106 while(c != CONT_LIST.end()) {
107 // find contributions to the right face
108 if(c -> face_index == 1) {
109 // which local coord in the contributing elt?
110 const double s = c -> s[ 1 ];
111 DenseVector<double> q_half_step(c -> elt_ptr -> get_Q(s));
112 // add half step correction
113 q_half_step += (c -> elt_ptr -> get_source_fn(s)
114 - c -> elt_ptr -> get_Jac_flux_fn(s).multiply(c -> elt_ptr -> SLOPE))
115 * 0.5 * dt;
116 //DenseVector<double> x( 1, 0.0 ); x[ 0 ] = c -> elt_ptr -> get_x( s );
117 double x(c -> elt_ptr -> get_x(s));
118 // evaluate the flux at this Q value
119 c -> elt_ptr -> system_ptr -> flux_fn(x, q_half_step, flux_out_right);
120 }
121 ++c;
122 }
123 // treat the user specified external faces separately
124 if(EXTERNAL) {
125 // we are in an external elt
126 c = CONT_LIST.begin();
127 while(c != CONT_LIST.end()) {
128 // external faces are external for the current elt *and* its contributions
129 if(c -> elt_ptr -> get_external_flag()) {
130 if(EXTERNAL_FACE_I > 0) {
131 // RH boundary
132 DenseVector<double> q_right(c -> elt_ptr -> get_Q(1.0));
133 // convert x at boundary to a vector
134 //DenseVector<double> x_right( 1, 0.0 ); x_right[ 0 ] = c -> elt_ptr -> get_x( 1.0 );
135 double x_right(c -> elt_ptr -> get_x(1.0));
136 DenseVector<double> q_right_half_step(q_right);
137 // compute flux at the half time step
138 q_right_half_step += (c -> elt_ptr -> get_source_fn(1.0)
139 - c -> elt_ptr -> get_Jac_flux_fn(1.0).multiply(c -> elt_ptr -> SLOPE))
140 * 0.5 * dt;
141 // get the edge values
142 system_ptr -> edge_values(1, x_right, q_right_half_step, current_time + 0.5*dt);
143 // get the flux
144 system_ptr -> flux_fn(x_right, q_right_half_step, flux_out_right);
145 }
146 }
147 ++c;
148 }
149 }
150 }
151
153 DenseVector<double> f(system_ptr -> get_order(), 0.0);
154 double x(get_x(s));
155 system_ptr -> flux_fn(x, get_Q(s), f);
156 return f;
157 }
158
160 DenseMatrix<double> J(system_ptr -> get_order(), system_ptr -> get_order(), 0.0);
161 double x(get_x(s));
162 system_ptr -> Jac_flux_fn(x, get_Q(s), J);
163 return J;
164 }
165
167 DenseVector<double> r(system_ptr -> get_order(), 0.0);
168 double x(get_x(s));
169 system_ptr -> source_fn(x, get_Q(s), get_slope(), r);
170 return r;
171 }
172
174 // left face & right face speeds
175 return get_dx() / std::max(std::abs(system_ptr -> max_charac_speed(get_Q(-1.0))),
176 std::abs(system_ptr -> max_charac_speed(get_Q(1.0))));
177 }
178
179} // CppNoddy namespace
@ f
Definition: BVPBerman.cpp:15
Specification of a one dimensional linear element for use in a TVD Lax-Friedrichs scheme.
A matrix class that constructs a DENSE matrix as a row major std::vector of DenseVectors.
Definition: DenseMatrix.h:25
DenseVector< _Type > multiply(const DenseVector< _Type > &x) const
Right multiply the matrix by a DENSE vector.
An DenseVector class – a dense vector object.
Definition: DenseVector.h:34
A class to represent a one dimensional hyperbolic system of equations.
A Linear Element class.
void add_contribution(OneD_TVDLF_Elt *ptr, const DenseVector< double > &s_range, int index)
Allow the connection of this element to another element.
OneD_Hyperbolic_System * system_ptr
double get_x(double s) const
Get the global position of the local coordinate.
DenseVector< double > contributed_Q()
Find the integral contributions to this black/red element from the contributed red/black element.
void contributed_flux_in_left(const double &dt, DenseVector< double > &flux_in_left, const double &current_time)
Compute the flux into this element through the left face over a given time step.
~OneD_TVDLF_Elt()
An empty destructor.
DenseVector< double > get_Q(double s) const
Get the value of the 'concentration' stored in this element.
double get_dx() const
Get the size of the element.
DenseMatrix< double > get_Jac_flux_fn(const double s) const
Get the Jacobian of the flux function evaluated for the concentration value stored in this elt.
OneD_TVDLF_Elt(double a, double b, OneD_Hyperbolic_System *ptr, bool flag=false, int index=0)
Construct a linear element.
DenseVector< double > get_source_fn(const double s) const
Get the value of the source function term in this element at a given local coordinate.
DenseVector< double > get_slope() const
The concentration is approximated by a linear function in each element.
bool get_external_flag() const
Get the external flag.
DenseVector< double > get_flux_fn(const double s) const
Get the flux function evaluated for the concentration value stored in this elt.
void contributed_flux_out_right(const double &dt, DenseVector< double > &flux_out_right, const double &current_time)
Compute the flux out of this element through the right face over a given time step.
DenseVector< double > get_int_Q(const double s0, const double s1)
Get the integral of Q over a sub-element.
double get_max_dt() const
Get the maximum allowable time step for this element by using information about the size of the eleme...
A collection of OO numerical routines aimed at simple (typical) applied problems in continuum mechani...

© 2012

R.E. Hewitt