OGS
HeatTransportBHELocalAssemblerSoil-impl.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
4#pragma once
5
6#include <vector>
7
18#include "SecondaryData.h"
19
20namespace ProcessLib
21{
22namespace HeatTransportBHE
23{
24template <typename ShapeFunction>
27 MeshLib::Element const& e,
28 NumLib::GenericIntegrationMethod const& integration_method,
29 bool const is_axially_symmetric,
30 HeatTransportBHEProcessData& process_data,
31 BHEMeshData const& /*bhe_mesh_data*/)
32 : _process_data(process_data),
33 _integration_method(integration_method),
34 _element(e)
35{
36 unsigned const n_integration_points =
37 _integration_method.getNumberOfPoints();
38
39 _ip_data.reserve(n_integration_points);
40 _secondary_data.N.resize(n_integration_points);
41
44 3 /* GlobalDim */>(e, is_axially_symmetric,
46
47 // ip data initialization
48 for (unsigned ip = 0; ip < n_integration_points; ip++)
49 {
50 // create the class IntegrationPointDataBHE in place
51 auto const& sm = _shape_matrices[ip];
52 double const w = _integration_method.getWeightedPoint(ip).getWeight() *
53 sm.integralMeasure * sm.detJ;
54 _ip_data.push_back({sm.N, sm.dNdx, w});
55
56 _secondary_data.N[ip] = sm.N;
57 }
58}
59
60template <typename ShapeFunction>
62 double const t, double const dt, std::vector<double> const& local_x,
63 std::vector<double> const& /*local_x_prev*/,
64 std::vector<double>& local_M_data, std::vector<double>& local_K_data,
65 std::vector<double>& /*local_b_data*/)
66{
67 assert(local_x.size() == ShapeFunction::NPOINTS);
68 (void)local_x; // Avoid unused arg warning.
69
71 local_M_data, ShapeFunction::NPOINTS, ShapeFunction::NPOINTS);
73 local_K_data, ShapeFunction::NPOINTS, ShapeFunction::NPOINTS);
74
75 auto const& medium = *_process_data.media_map.getMedium(_element.getID());
76 auto const& solid_phase =
78 auto const& liquid_phase =
80
82
83 unsigned const n_integration_points =
84 _integration_method.getNumberOfPoints();
85
86 for (unsigned ip = 0; ip < n_integration_points; ip++)
87 {
88 auto& ip_data = _ip_data[ip];
89 auto const& N = ip_data.N;
90 auto const& dNdx = ip_data.dNdx;
91 auto const& w = ip_data.integration_weight;
92
94 std::nullopt, _element.getID(),
97 _element, N))};
98
99 double T_int_pt = 0.0;
100 NumLib::shapeFunctionInterpolate(local_x, N, T_int_pt);
101
102 vars.temperature = T_int_pt;
103
104 // for now only using the solid and liquid phase parameters
105 auto const density_s =
107 .template value<double>(vars, pos, t, dt);
108
109 auto const heat_capacity_s =
110 solid_phase
111 .property(
113 .template value<double>(vars, pos, t, dt);
114
115 auto const density_f =
116 liquid_phase.property(MaterialPropertyLib::PropertyType::density)
117 .template value<double>(vars, pos, t, dt);
118
119 auto const heat_capacity_f =
120 liquid_phase
121 .property(
123 .template value<double>(vars, pos, t, dt);
124
125 auto const porosity =
127 .template value<double>(vars, pos, t, dt);
128
129 auto const velocity =
130 liquid_phase
132 .template value<Eigen::Vector3d>(vars, pos, t, dt);
133
134 // calculate the hydrodynamic thermodispersion tensor
135 auto const thermal_conductivity =
137 medium
138 .property(
140 .value(vars, pos, t, dt));
141
142 auto thermal_conductivity_dispersivity = thermal_conductivity;
143
144 double const velocity_magnitude = velocity.norm();
145
146 if (velocity_magnitude >= std::numeric_limits<double>::epsilon())
147 {
148 auto const thermal_dispersivity_longitudinal =
149 medium
151 thermal_longitudinal_dispersivity)
152 .template value<double>();
153 auto const thermal_dispersivity_transversal =
154 medium
156 thermal_transversal_dispersivity)
157 .template value<double>();
158
159 auto const thermal_dispersivity =
160 density_f * heat_capacity_f *
161 (thermal_dispersivity_transversal * velocity_magnitude *
162 Eigen::Matrix3d::Identity() +
163 (thermal_dispersivity_longitudinal -
164 thermal_dispersivity_transversal) /
165 velocity_magnitude * velocity * velocity.transpose());
166 thermal_conductivity_dispersivity += thermal_dispersivity;
167 }
168
169 // assemble Conductance matrix
170 local_K.noalias() +=
171 (dNdx.transpose() * thermal_conductivity_dispersivity * dNdx +
172 N.transpose() * velocity.transpose() * dNdx * density_f *
173 heat_capacity_f) *
174 w;
175
176 // assemble Mass matrix
177 local_M.noalias() += N.transpose() * N * w *
178 (density_s * heat_capacity_s * (1 - porosity) +
179 density_f * heat_capacity_f * porosity);
180 }
181
182 if (_process_data._mass_lumping)
183 {
184 // only mass lumping at the BHE connected soil elements
185 if (_process_data.mass_lumping_soil_elements[_element.getID()])
186 {
187 local_M = local_M.colwise().sum().eval().asDiagonal();
188 }
189 }
190
191 // debugging
192 // std::string sep = "\n----------------------------------------\n";
193 // Eigen::IOFormat CleanFmt(4, 0, ", ", "\n", "[", "]");
194 // std::cout << local_K.format(CleanFmt) << sep;
195 // std::cout << local_M.format(CleanFmt) << sep;
196}
197
198template <typename ShapeFunction>
200 double const t, double const dt, std::vector<double> const& local_x,
201 std::vector<double> const& local_x_prev,
202 std::vector<double>& local_rhs_data, std::vector<double>& local_Jac_data)
203{
204 assert(local_x.size() == ShapeFunction::NPOINTS);
205 auto const local_matrix_size = local_x.size();
206 // initialize x and x_prev
207 auto x =
208 Eigen::Map<NodalVectorType const>(local_x.data(), local_matrix_size);
209 auto x_prev = Eigen::Map<NodalVectorType const>(local_x_prev.data(),
210 local_matrix_size);
211 // initialize local_Jac and local_rhs
213 local_Jac_data, local_matrix_size, local_matrix_size);
215 local_rhs_data, local_matrix_size);
216
217 std::vector<double> local_M_data;
218 std::vector<double> local_K_data;
219 assemble(t, dt, local_x, local_x_prev, local_M_data, local_K_data,
220 local_rhs_data /*not going to be used*/);
221
222 // convert to matrix
224 local_M_data, local_matrix_size, local_matrix_size);
226 local_K_data, local_matrix_size, local_matrix_size);
227
228 // Jac matrix and rhs vector operation
229 local_Jac.noalias() += local_K + local_M / dt;
230 local_rhs.noalias() -= local_K * x + local_M * (x - x_prev) / dt;
231
232 local_M.setZero();
233 local_K.setZero();
234}
235
236} // namespace HeatTransportBHE
237} // namespace ProcessLib
std::vector< ShapeMatrices, Eigen::aligned_allocator< ShapeMatrices > > _shape_matrices
void assemble(double const, double const, std::vector< double > const &, std::vector< double > const &, std::vector< double > &, std::vector< double > &, std::vector< double > &) override
void assembleWithJacobian(double const t, double const dt, std::vector< double > const &local_x, std::vector< double > const &local_x_prev, std::vector< double > &local_rhs_data, std::vector< double > &local_Jac_data) override
std::vector< IntegrationPointDataSoil< NodalRowVectorType, GlobalDimNodalMatrixType >, Eigen::aligned_allocator< IntegrationPointDataSoil< NodalRowVectorType, GlobalDimNodalMatrixType > > > _ip_data
HeatTransportBHELocalAssemblerSoil(HeatTransportBHELocalAssemblerSoil const &)=delete
template Eigen::Matrix< double, 3, 3 > formEigenTensor< 3 >(MaterialPropertyLib::PropertyDataType const &values)
Eigen::Map< Vector > createZeroedVector(std::vector< double > &data, Eigen::VectorXd::Index size)
Eigen::Map< Matrix > createZeroedMatrix(std::vector< double > &data, Eigen::MatrixXd::Index rows, Eigen::MatrixXd::Index cols)
Eigen::Map< const Matrix > toMatrix(std::vector< double > const &data, Eigen::MatrixXd::Index rows, Eigen::MatrixXd::Index cols)
void shapeFunctionInterpolate(const NodalValues &, const ShapeMatrix &)
std::vector< typename ShapeMatricesType::ShapeMatrices, Eigen::aligned_allocator< typename ShapeMatricesType::ShapeMatrices > > initShapeMatrices(MeshLib::Element const &e, bool const is_axially_symmetric, IntegrationMethod const &integration_method)
std::array< double, 3 > interpolateCoordinates(MeshLib::Element const &e, typename ShapeMatricesType::ShapeMatrices::ShapeType const &N)