Line |
Branch |
Exec |
Source |
1 |
|
|
// ______ ______ _ _ _____ ______ |
2 |
|
|
// | ____| ____| | (_)/ ____| | ____| |
3 |
|
|
// | |__ | |__ | | _| (___ ___| |__ |
4 |
|
|
// | __| | __| | | | |\___ \ / __| __| |
5 |
|
|
// | | | |____| |____| |____) | (__| |____ |
6 |
|
|
// |_| |______|______|_|_____/ \___|______| |
7 |
|
|
// Finite Elements for Life Sciences and Engineering |
8 |
|
|
// |
9 |
|
|
// License: LGL2.1 License |
10 |
|
|
// FELiScE default license: LICENSE in root folder |
11 |
|
|
// |
12 |
|
|
// Main authors: |
13 |
|
|
// |
14 |
|
|
|
15 |
|
|
// System includes |
16 |
|
|
|
17 |
|
|
// External includes |
18 |
|
|
|
19 |
|
|
// Project includes |
20 |
|
|
#include "Solver/linearProblemNSHeat.hpp" |
21 |
|
|
#include "FiniteElement/elementMatrix.hpp" |
22 |
|
|
#include "FiniteElement/elementVector.hpp" |
23 |
|
|
#include "DegreeOfFreedom/boundaryConditionList.hpp" |
24 |
|
|
#include "DegreeOfFreedom/boundaryCondition.hpp" |
25 |
|
|
|
26 |
|
|
namespace felisce{ |
27 |
|
✗ |
LinearProblemNSHeat::LinearProblemNSHeat():LinearProblemNS() { |
28 |
|
✗ |
if (FelisceParam::instance().exportP1Normal ) { |
29 |
|
✗ |
m_vecs.Init("measStar"); |
30 |
|
✗ |
m_seqVecs.Init("measStar"); |
31 |
|
|
|
32 |
|
✗ |
m_vecs.Init("normalField"); |
33 |
|
✗ |
m_seqVecs.Init("normalField"); |
34 |
|
|
} |
35 |
|
|
} |
36 |
|
✗ |
void LinearProblemNSHeat::initialize(std::vector<GeometricMeshRegion::Pointer>& mesh, FelisceTransient::Pointer fstransient, MPI_Comm& comm, bool doUseSNES) { |
37 |
|
✗ |
LinearProblemNS::initialize(mesh,fstransient,comm,doUseSNES); |
38 |
|
✗ |
m_iTemp = m_listVariable.getVariableIdList(temperature); |
39 |
|
✗ |
m_iUnknownTemp = m_listUnknown.getUnknownIdList(temperature); |
40 |
|
✗ |
m_gravity = FelisceParam::instance().gravity; |
41 |
|
✗ |
m_referenceTemperature = FelisceParam::instance().referenceTemperature; |
42 |
|
✗ |
m_t0 = FelisceParam::instance().initialTemperature; |
43 |
|
✗ |
m_coeffOfThermalExpansion = FelisceParam::instance().coeffOfThermalExpansion; |
44 |
|
✗ |
m_thermalDiffusion = FelisceParam::instance().thermalDiffusion; |
45 |
|
|
} |
46 |
|
✗ |
void LinearProblemNSHeat::userAddOtherUnknowns(std::vector<PhysicalVariable>& listVariable, std::vector<std::size_t>& listNumComp) { |
47 |
|
✗ |
m_listUnknown.push_back(temperature); |
48 |
|
✗ |
listVariable.push_back(temperature); |
49 |
|
✗ |
listNumComp.push_back(1); |
50 |
|
|
} |
51 |
|
✗ |
void LinearProblemNSHeat::initPerElementType(ElementType eltType, FlagMatrixRHS flagMatrixRHS) { |
52 |
|
✗ |
LinearProblemNS::initPerElementType(eltType,flagMatrixRHS); |
53 |
|
|
|
54 |
|
✗ |
m_feTemp = m_listCurrentFiniteElement[m_iTemp]; |
55 |
|
✗ |
m_elemFieldOldTemp.initialize(DOF_FIELD,*m_feTemp,1); |
56 |
|
✗ |
m_elemFieldAdvection.initialize(DOF_FIELD,*m_feVel,m_velocity->numComponent()); |
57 |
|
|
|
58 |
|
✗ |
FEL_ASSERT(m_gravity.size() == m_velocity->numComponent()); |
59 |
|
|
} |
60 |
|
✗ |
void LinearProblemNSHeat::userElementInit() { |
61 |
|
|
//By using m_elemFieldRHS, we automatically include this part in the SUPG stabilization |
62 |
|
✗ |
for (int i(0); i<this->dimension();++i) { |
63 |
|
✗ |
m_elemFieldRHS.setValue( m_density*(1 + m_coeffOfThermalExpansion*m_referenceTemperature)*m_gravity[i] , i ); |
64 |
|
|
} |
65 |
|
|
} |
66 |
|
✗ |
void LinearProblemNSHeat::userElementInitNaturalBoundaryCondition() { |
67 |
|
✗ |
m_curvFeVel=m_listCurvilinearFiniteElement[m_iVelocity]; |
68 |
|
✗ |
m_stevino.initialize(DOF_FIELD,*m_curvFeVel,1); |
69 |
|
|
} |
70 |
|
|
|
71 |
|
✗ |
void LinearProblemNSHeat::computeElementArray(const std::vector<Point*>& elemPoint, const std::vector<felInt>& elemIdPoint, felInt& iel, FlagMatrixRHS flagMatrixRHS) { |
72 |
|
✗ |
LinearProblemNS::computeElementArray(elemPoint,elemIdPoint,iel,flagMatrixRHS); |
73 |
|
✗ |
m_feTemp->updateFirstDeriv(0, elemPoint); |
74 |
|
|
|
75 |
|
✗ |
std::size_t temperatureBlock = m_velocity->numComponent() + 1; |
76 |
|
✗ |
std::size_t timeCoeff = 1./m_fstransient->timeStep; |
77 |
|
|
|
78 |
|
✗ |
if ( flagMatrixRHS == FlagMatrixRHS::matrix_and_rhs || flagMatrixRHS == FlagMatrixRHS::only_matrix ) { |
79 |
|
✗ |
if (m_fstransient->iteration == 0) { |
80 |
|
✗ |
std::size_t idMatrix = 1; |
81 |
|
|
//mass |
82 |
|
✗ |
m_elementMat[idMatrix]->phi_i_phi_j(timeCoeff, *m_feTemp, temperatureBlock, temperatureBlock, 1); |
83 |
|
|
//Diffusion |
84 |
|
✗ |
m_elementMat[idMatrix]->grad_phi_i_grad_phi_j(m_thermalDiffusion, *m_feTemp, temperatureBlock, temperatureBlock, 1); |
85 |
|
|
|
86 |
|
|
//Gravity term |
87 |
|
|
//We assume that we use the same finite element for velocity and temperature. |
88 |
|
|
//If it is not the case, we have to add another function to elementMatrix |
89 |
|
✗ |
for (int i(0); i<this->dimension();++i) { |
90 |
|
|
// +\rho_0*\alpha*\vec g T |
91 |
|
✗ |
m_elementMat[idMatrix]->phi_i_phi_j(m_density*m_coeffOfThermalExpansion*m_gravity[i],*m_feVel, i, m_velocity->numComponent()+1,1); |
92 |
|
|
} |
93 |
|
|
} |
94 |
|
|
|
95 |
|
|
//Advection |
96 |
|
✗ |
m_elemFieldAdvection.setValue(m_solExtrapol, *m_feVel, iel, m_iVelocity, m_ao, dof()); |
97 |
|
✗ |
m_elementMat[0]->u_grad_phi_j_phi_i(1.,m_elemFieldAdvection,*m_feTemp, temperatureBlock, temperatureBlock, 1); |
98 |
|
|
|
99 |
|
|
//SUPG stabilization extra terms, the extra terms due to the non-zero rhs are correctly handled in linearProblemNS::computeElementArray() |
100 |
|
✗ |
if ( m_velocity->finiteElementType() == m_pressure->finiteElementType()) { |
101 |
|
✗ |
m_elementMat[0]->stab_supgNSHeat(m_fstransient->timeStep,FelisceParam::instance().stabSUPG,m_coeffOfThermalExpansion,m_density,m_viscosity, |
102 |
|
✗ |
*m_feVel, m_elemFieldAdvection, FelisceParam::instance().typeSUPG, m_gravity); |
103 |
|
|
|
104 |
|
|
} |
105 |
|
✗ |
if ( flagMatrixRHS == FlagMatrixRHS::matrix_and_rhs || flagMatrixRHS == FlagMatrixRHS::only_rhs ) { |
106 |
|
|
// Advancing in time |
107 |
|
✗ |
if ( m_fstransient->iteration == 1 ) { |
108 |
|
✗ |
m_elemFieldOldTemp.setValue(m_t0,0); |
109 |
|
|
} |
110 |
|
|
else { |
111 |
|
✗ |
m_elemFieldOldTemp.setValue(this->sequentialSolution(),*m_feTemp, iel, m_iTemp, m_ao, dof());//TODO in case of fix point iterations this has to be modified |
112 |
|
|
} |
113 |
|
✗ |
m_elementVector[0]->source(timeCoeff,*m_feTemp,m_elemFieldOldTemp,m_velocity->numComponent()+1,1); |
114 |
|
|
|
115 |
|
|
// Velocity force term |
116 |
|
|
// +\rho_0*\vec g(1-\alpha*TRef) |
117 |
|
✗ |
m_elementVector[0]->source(1., *m_feVel, m_elemFieldRHS,0,m_velocity->numComponent()); |
118 |
|
|
} |
119 |
|
|
} |
120 |
|
|
} |
121 |
|
✗ |
void LinearProblemNSHeat::userElementComputeNaturalBoundaryCondition(const std::vector<Point*>& elemPoint, const std::vector<felInt>& /*elemIdPoint*/,felInt& /*ielSupportDof*/, int /*label*/) { |
122 |
|
|
// Check we are in the labels where the addition of the hydrostatic pressure (Stevino Pressure) is required. |
123 |
|
✗ |
if ( std::find( FelisceParam::instance().stevinoLabels.begin(), FelisceParam::instance().stevinoLabels.end(), m_currentLabel) != FelisceParam::instance().stevinoLabels.end() ) { |
124 |
|
|
|
125 |
|
|
|
126 |
|
|
// We assume that, on this label, constant in time and space Dirichlet boundary condition is imposed on the Temperature. |
127 |
|
|
// We need this value to correctly compute the Stevino pressure. |
128 |
|
|
// |
129 |
|
|
// We loop over the boundary conditions to check the assumptions and to get the value |
130 |
|
✗ |
BoundaryCondition* bc = nullptr; |
131 |
|
✗ |
double value(0); |
132 |
|
✗ |
bool foundACorrectBC = false; |
133 |
|
|
|
134 |
|
✗ |
for ( int iDirBC(0); (std::size_t)iDirBC<m_boundaryConditionList.numDirichletBoundaryCondition(); ++iDirBC) { |
135 |
|
|
// Get the current Dirichlet boundary condition. |
136 |
|
✗ |
bc=m_boundaryConditionList.Dirichlet(iDirBC); |
137 |
|
|
// Check that it is about the temperature |
138 |
|
✗ |
if ( (std::size_t)bc->getUnknown() == m_iUnknownTemp ) { |
139 |
|
|
// Get the labels and check that this bc actually concerns the currentLabel |
140 |
|
✗ |
const auto& lab = bc->listLabel(); |
141 |
|
✗ |
if ( std::find( lab.begin(), lab.end(), m_currentLabel) != lab.end() ) { |
142 |
|
|
// Check the type of BC is constant |
143 |
|
✗ |
if ( bc->typeValueBC() != Constant ) { |
144 |
|
✗ |
FEL_ERROR("Hydrostatic (Stevino) pressure is not yet available for non-constant Dirichlet boundary condition for the temperature"); |
145 |
|
|
} else { |
146 |
|
|
// We can take the value |
147 |
|
✗ |
value = bc->ValueBCInSupportDof()[0]; |
148 |
|
✗ |
foundACorrectBC = true; |
149 |
|
|
} |
150 |
|
|
} |
151 |
|
|
} |
152 |
|
|
} |
153 |
|
✗ |
if ( ! foundACorrectBC ) { |
154 |
|
✗ |
std::stringstream msg; |
155 |
|
✗ |
msg<<"For some reasons, it was impossible to apply the Stevino pressure on label: "<<m_currentLabel<<std::endl; |
156 |
|
✗ |
FEL_ERROR(msg.str().c_str()); |
157 |
|
|
} |
158 |
|
|
|
159 |
|
|
// Filling of the elementField |
160 |
|
✗ |
for ( int idof(0); idof<m_curvFeVel->numDof(); idof++) { |
161 |
|
✗ |
if ( (std::size_t)idof < elemPoint.size() ) { |
162 |
|
✗ |
m_stevino.val(0,idof)=0; |
163 |
|
✗ |
for ( int icoor(0); icoor<this->dimension(); ++icoor ) { |
164 |
|
✗ |
m_stevino.val(0,idof) += ( elemPoint[idof]->coor(icoor) - m_zedZeroStevino[icoor] )*m_gravity[icoor]; |
165 |
|
|
} |
166 |
|
|
} else { |
167 |
|
✗ |
if ( this->dimension() == 2 ) { |
168 |
|
|
// We are dealing with an edge is 1D, and we are using P2 finite-elements. idof must be equal to 2 |
169 |
|
✗ |
FEL_ASSERT(idof==2); |
170 |
|
|
// We don't have a point for this dof, but it simply the middle point |
171 |
|
✗ |
m_stevino.val(0,idof) = ( 0.5 * elemPoint[0]->x() + 0.5 * elemPoint[1]->x() - m_zedZeroStevino[0] )*m_gravity[0] |
172 |
|
✗ |
+( 0.5 * elemPoint[0]->y() + 0.5 * elemPoint[1]->y() - m_zedZeroStevino[1] )*m_gravity[1]; |
173 |
|
|
} else { |
174 |
|
✗ |
FEL_ERROR("Hydrostatic (Stevino) pressure not yet available for 3D-P2 finite-elements."); |
175 |
|
|
} |
176 |
|
|
} |
177 |
|
|
} |
178 |
|
|
// Adding it as a force term |
179 |
|
✗ |
m_elementVectorBD[0]->f_phi_i_scalar_n( - m_density * ( 1. - m_coeffOfThermalExpansion * ( value - m_referenceTemperature ) ),*m_curvFeVel,m_stevino,0/*iblockVel*/); |
180 |
|
|
} |
181 |
|
|
} |
182 |
|
|
} |
183 |
|
|
|