GCC Code Coverage Report


Directory: ./
File: Solver/linearProblemNSHeat.cpp
Date: 2024-04-14 07:32:34
Exec Total Coverage
Lines: 0 83 0.0%
Branches: 0 94 0.0%

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