Directory: | ./ |
---|---|
File: | Solver/linearProblemHeat.cpp |
Date: | 2024-04-14 07:32:34 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 46 | 126 | 36.5% |
Branches: | 35 | 207 | 16.9% |
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: J. Foulon & J-F. Gerbeau & V. Martin | ||
13 | // | ||
14 | |||
15 | /*! | ||
16 | \file linearProblemHeat.cpp | ||
17 | \authors J. Foulon & J-F. Gerbeau & V. Martin | ||
18 | \date 05/01/2011 | ||
19 | \brief File where is implemented laplacian class. | ||
20 | */ | ||
21 | |||
22 | // System includes | ||
23 | |||
24 | // External includes | ||
25 | |||
26 | // Project includes | ||
27 | #include "Solver/linearProblemHeat.hpp" | ||
28 | #include "Core/felisceTransient.hpp" | ||
29 | #include "FiniteElement/elementVector.hpp" | ||
30 | #include "FiniteElement/elementMatrix.hpp" | ||
31 | #include "InputOutput/io.hpp" | ||
32 | #include "DegreeOfFreedom/boundaryCondition.hpp" | ||
33 | |||
34 | |||
35 | namespace felisce { | ||
36 | 76 | LinearProblemHeat::LinearProblemHeat(): | |
37 | LinearProblem("Heat equation",/*numberOfMatrices*/2), | ||
38 |
5/10✓ Branch 2 taken 76 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 76 times.
✗ Branch 6 not taken.
✓ Branch 10 taken 76 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 76 times.
✗ Branch 14 not taken.
✓ Branch 17 taken 76 times.
✗ Branch 18 not taken.
|
76 | m_sourceTermDynamicValue(nullptr) |
39 | { | ||
40 |
2/4✓ Branch 2 taken 76 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 76 times.
✗ Branch 6 not taken.
|
76 | m_seqVecs.Init("oldTemperature"); |
41 | // When using cvgraph, the following vectors are needed. | ||
42 | // If we use a D2N or a N2D some of them may be unused | ||
43 | #ifdef FELISCE_WITH_CVGRAPH | ||
44 |
2/4✓ Branch 1 taken 76 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 76 times.
|
76 | if ( FelisceParam::instance().withCVG ) { |
45 | ✗ | m_cvgDirichletVariable = "cvgraphTEMPERATURE"; | |
46 | ✗ | m_seqVecs.Init("cvgraphFLOWOFHEAT"); | |
47 | ✗ | m_seqVecs.Init("cvgraphTEMPERATURE"); | |
48 | } | ||
49 | #endif | ||
50 | 76 | } | |
51 | 2896 | void LinearProblemHeat::updateOldQuantities() { | |
52 |
3/6✓ Branch 2 taken 2896 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2896 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 2896 times.
✗ Branch 10 not taken.
|
2896 | m_seqVecs.Get("oldTemperature").copyFrom(sequentialSolution()); |
53 | 2896 | } | |
54 | ✗ | void LinearProblemHeat::readDataDisplacement(std::vector<IO::Pointer>& io, double iteration) { | |
55 | // Read displacement file (*.00000.vct) | ||
56 | ✗ | const int iMesh = m_listVariable[0].idMesh(); | |
57 | ✗ | m_vectorDisp.resize(m_mesh[iMesh]->numPoints()*3,0.); | |
58 | ✗ | io[iMesh]->readVariable(0, iteration,&m_vectorDisp[0], m_vectorDisp.size()); | |
59 | } | ||
60 | |||
61 | 76 | void LinearProblemHeat::initialize(std::vector<GeometricMeshRegion::Pointer>& mesh, FelisceTransient::Pointer fstransient, MPI_Comm& comm, bool doUseSNES) { | |
62 |
1/2✓ Branch 1 taken 76 times.
✗ Branch 2 not taken.
|
76 | LinearProblem::initialize(mesh,comm, doUseSNES); |
63 | 76 | m_fstransient = fstransient; | |
64 |
1/2✓ Branch 2 taken 76 times.
✗ Branch 3 not taken.
|
76 | std::vector<PhysicalVariable> listVariable(1); |
65 |
1/2✓ Branch 2 taken 76 times.
✗ Branch 3 not taken.
|
76 | std::vector<std::size_t> listNumComp(1); |
66 | 76 | listVariable[0] = temperature; | |
67 | 76 | listNumComp[0] = 1; | |
68 | //define unknown of the linear system. | ||
69 |
1/2✓ Branch 1 taken 76 times.
✗ Branch 2 not taken.
|
76 | m_listUnknown.push_back(temperature); |
70 |
1/2✓ Branch 1 taken 76 times.
✗ Branch 2 not taken.
|
76 | definePhysicalVariable(listVariable,listNumComp); |
71 | |||
72 |
1/2✓ Branch 1 taken 76 times.
✗ Branch 2 not taken.
|
76 | m_iTemperature = m_listVariable.getVariableIdList(temperature); |
73 |
2/4✓ Branch 1 taken 76 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 76 times.
✗ Branch 5 not taken.
|
76 | m_sourceTermDynamicValue = FelisceParam::instance().elementFieldDynamicValue("heatSourceTerm"); |
74 | 76 | } | |
75 | |||
76 | 2246 | void LinearProblemHeat::initPerElementType(ElementType /*eltType*/, FlagMatrixRHS /*flagMatrixRHS*/) { | |
77 | 2246 | m_feTemp = m_listCurrentFiniteElement[m_iTemperature]; | |
78 | |||
79 | // define elemField to put term u_n_1.phi_j in RHS. | ||
80 | // m_elemField contains u_n_1 values. | ||
81 | 2246 | m_elemField.initialize(DOF_FIELD,*m_feTemp); | |
82 | 2246 | } | |
83 | |||
84 | 2168 | void LinearProblemHeat::initPerElementTypeBoundaryCondition(ElementType& /*eltType*/, FlagMatrixRHS /*flagMatrixRHS*/) { | |
85 | #ifdef FELISCE_WITH_CVGRAPH | ||
86 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2168 times.
|
2168 | if (FelisceParam::instance().withCVG ) { |
87 | ✗ | m_curvFeTemp = m_listCurvilinearFiniteElement[m_iTemperature]; | |
88 | ✗ | if ( slave()->thereIsAtLeastOneRobinCondition() ){ | |
89 | ✗ | m_robinAux.initialize( DOF_FIELD, *m_curvFeTemp, this->dimension() ); | |
90 | } | ||
91 | } | ||
92 | #endif | ||
93 | 2168 | } | |
94 | 645100 | void LinearProblemHeat::computeElementArray(const std::vector<Point*>& elemPoint, const std::vector<felInt>& /*elemIdPoint*/, felInt& iel, FlagMatrixRHS flagMatrixRHS) { | |
95 | 645100 | const double coef = 1./m_fstransient->timeStep; | |
96 | |||
97 | 645100 | m_feTemp->updateFirstDeriv(0, elemPoint); | |
98 | |||
99 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 645100 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
645100 | if (flagMatrixRHS == FlagMatrixRHS::matrix_and_rhs || flagMatrixRHS == FlagMatrixRHS::only_matrix) { |
100 |
2/2✓ Branch 1 taken 75212 times.
✓ Branch 2 taken 569888 times.
|
645100 | if ( m_fstransient->iteration == 0 ) { |
101 | 75212 | m_elementMat[1]->grad_phi_i_grad_phi_j(1.,*m_feTemp,0,0,1); | |
102 | 75212 | m_elementMat[1]->phi_i_phi_j(coef,*m_feTemp,0,0,1); | |
103 | } | ||
104 | } | ||
105 | |||
106 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 645100 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
645100 | if (flagMatrixRHS == FlagMatrixRHS::matrix_and_rhs || flagMatrixRHS == FlagMatrixRHS::only_rhs) { |
107 |
2/2✓ Branch 1 taken 569888 times.
✓ Branch 2 taken 75212 times.
|
645100 | if ( m_fstransient->iteration > 0 ) { |
108 | // vector operators. | ||
109 |
3/6✓ Branch 3 taken 569888 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 569888 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 569888 times.
✗ Branch 10 not taken.
|
569888 | m_elemField.setValue(m_seqVecs.Get("oldTemperature"), *m_feTemp, iel, m_iTemperature, m_ao, dof()); |
110 | 569888 | m_elementVector[0]->source(coef,*m_feTemp,m_elemField,0,1); | |
111 | |||
112 |
2/2✓ Branch 0 taken 8192 times.
✓ Branch 1 taken 561696 times.
|
569888 | if (m_sourceTermDynamicValue != nullptr) { |
113 |
1/2✓ Branch 3 taken 8192 times.
✗ Branch 4 not taken.
|
8192 | m_sourceTerm.setValue(*m_feTemp, *m_sourceTermDynamicValue, m_fstransient->time); |
114 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 8192 times.
|
8192 | assert(!m_elementVector.empty()); |
115 | 8192 | m_elementVector[0]->source(1.,*m_feTemp,m_sourceTerm,0,1); | |
116 | } | ||
117 | } | ||
118 | } | ||
119 | 645100 | } | |
120 | |||
121 | 70592 | void LinearProblemHeat::computeElementArrayBoundaryCondition(const std::vector<Point*>& elemPoint, const std::vector<felInt>& /*elemIdPoint*/, felInt& iel, FlagMatrixRHS /*flagMatrixRHS*/) { | |
122 | (void) iel; | ||
123 | (void) elemPoint; | ||
124 | #ifdef FELISCE_WITH_CVGRAPH | ||
125 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 70592 times.
|
70592 | if (FelisceParam::instance().withCVG ) { |
126 | ✗ | m_curvFeTemp->updateMeasNormal(0, elemPoint); | |
127 | ✗ | cvgraphNaturalBC(iel); | |
128 | } | ||
129 | #endif | ||
130 | 70592 | } | |
131 | #ifdef FELISCE_WITH_CVGRAPH | ||
132 | ✗ | void LinearProblemHeat::sendData() { | |
133 | ✗ | gatherSolution(); | |
134 | ✗ | for ( std::size_t iConn(0); iConn<slave()->numConnections(); ++iConn ) { | |
135 | ✗ | std::vector<PetscVector> vecs; | |
136 | ✗ | for (std::size_t cVar(0); cVar<slave()->numVarToSend(iConn); ++cVar) { | |
137 | ✗ | std::string varToSend=slave()->sendVariable(iConn,cVar); | |
138 | ✗ | if (varToSend=="FLOWOFHEAT") { | |
139 | ✗ | prepareResidual(iConn); | |
140 | ✗ | vecs.push_back(m_seqStressOut); | |
141 | ✗ | } else if(varToSend =="TEMPERATURE") { | |
142 | ✗ | vecs.push_back(this->sequentialSolution()); | |
143 | } else { | ||
144 | ✗ | std::cout<<"variable to send: "<<varToSend<<std::endl; | |
145 | ✗ | FEL_ERROR("Error in variable to read"); | |
146 | } | ||
147 | } | ||
148 | ✗ | slave()->sendData(vecs,iConn); | |
149 | } | ||
150 | } | ||
151 | ✗ | void LinearProblemHeat::readData() { | |
152 | ✗ | for ( std::size_t iConn(0); iConn<slave()->numConnections(); ++iConn ) { | |
153 | ✗ | std::vector<PetscVector> vecs; | |
154 | ✗ | for (std::size_t cVar(0); cVar<slave()->numVarToRead(iConn); ++cVar) { | |
155 | ✗ | std::string varToRead=slave()->readVariable(iConn,cVar); | |
156 | ✗ | if ( varToRead == "FLOWOFHEAT" ) { | |
157 | ✗ | vecs.push_back(m_seqVecs.Get("cvgraphFLOWOFHEAT")); | |
158 | ✗ | } else if ( varToRead == "TEMPERATURE" ) { | |
159 | ✗ | vecs.push_back(m_seqVecs.Get("cvgraphTEMPERATURE")); | |
160 | } else { | ||
161 | ✗ | std::cout<<"Connection: "<<iConn<<"variable to read: "<<varToRead<<std::endl; | |
162 | ✗ | FEL_ERROR("Error in variable to read"); | |
163 | } | ||
164 | } | ||
165 | ✗ | slave()->receiveData(vecs,iConn); | |
166 | } | ||
167 | } | ||
168 | /*! \brief Function to assemble the mass matrix | ||
169 | * Function to be called in the assemblyLoopBoundaryGeneral | ||
170 | */ | ||
171 | void | ||
172 | ✗ | LinearProblemHeat::initPerETMass() { | |
173 | ✗ | felInt numDofTotal = 0; | |
174 | //pay attention this numDofTotal is bigger than expected since it counts for all the VARIABLES | ||
175 | ✗ | for (std::size_t iFe = 0; iFe < this->m_listCurvilinearFiniteElement.size(); iFe++) {//this loop is on variables while it should be on unknown | |
176 | ✗ | numDofTotal += this->m_listCurvilinearFiniteElement[iFe]->numDof()*this->m_listVariable[iFe].numComponent(); | |
177 | } | ||
178 | ✗ | m_globPosColumn.resize(numDofTotal); m_globPosRow.resize(numDofTotal); m_matrixValues.resize(numDofTotal*numDofTotal); | |
179 | ✗ | m_curvFeTemp = this->m_listCurvilinearFiniteElement[ m_iTemperature ]; | |
180 | } | ||
181 | |||
182 | ✗ | void LinearProblemHeat::massMatrixComputer(felInt ielSupportDof) { | |
183 | ✗ | m_elementMatBD[0]->zero(); | |
184 | ✗ | m_elementMatBD[0]->phi_i_phi_j(/*coef*/1.,*m_curvFeTemp,/*iblock*/0,/*iblock*/0,1/*dim*/); | |
185 | ✗ | setValueMatrixBD(ielSupportDof); | |
186 | } | ||
187 | |||
188 | ✗ | void LinearProblemHeat::updateFE(const std::vector<Point*>& elemPoint, const std::vector<int>&) { | |
189 | ✗ | m_curvFeTemp->updateMeasNormal(0, elemPoint); | |
190 | } | ||
191 | |||
192 | ✗ | void LinearProblemHeat::cvgraphNaturalBC(felInt iel) { | |
193 | BoundaryCondition* BC; | ||
194 | // Loop over the cvgraph connections | ||
195 | ✗ | for ( std::size_t iConn(0); iConn<slave()->numConnections(); ++iConn ) { | |
196 | // Extract the labels of the current connection | ||
197 | ✗ | std::vector<int> labels = slave()->interfaceLabels(iConn); | |
198 | // Verify if the current label is part of the interface of this connection | ||
199 | ✗ | if ( std::find( labels.begin(), labels.end(), m_currentLabel ) != labels.end() ) { | |
200 | ✗ | switch ( slave()->numVarToRead(iConn) ) { | |
201 | ✗ | case 1: // only one var to read: neumann interface BC | |
202 | // Verify that we have to apply the stress in its strong form. | ||
203 | ✗ | if ( slave()->readVariable(iConn,/*cVar*/0) == "FLOWOFHEAT" && slave()->residualInterpolationType(iConn) == 0 ) { | |
204 | // Look through the different neumann conditions to find the correct one. | ||
205 | ✗ | for (std::size_t iNeumann=0; iNeumann<m_boundaryConditionList.numNeumannBoundaryCondition(); iNeumann++ ) { | |
206 | ✗ | BC = m_boundaryConditionList.Neumann(iNeumann);//get the the BC | |
207 | ✗ | const auto& list_bc = BC->listLabel(); | |
208 | ✗ | if ( list_bc.find(m_currentLabel) != list_bc.end()) { | |
209 | //compute the force term. | ||
210 | ✗ | m_elemFieldNeumann[iNeumann].setValue( m_seqVecs.Get("cvgraphFLOWOFHEAT"), *m_curvFeTemp , iel, m_iTemperature, m_ao, dof()); | |
211 | } | ||
212 | } | ||
213 | } | ||
214 | ✗ | break; | |
215 | ✗ | case 2: //two variables to read: robin interface BC | |
216 | // Look through the different robin conditions to find the correct one. | ||
217 | ✗ | for (std::size_t iRobin=0; iRobin<m_boundaryConditionList.numRobinBoundaryCondition(); iRobin++ ) { | |
218 | ✗ | BC = m_boundaryConditionList.Robin(iRobin); | |
219 | ✗ | const auto& list_bc = BC->listLabel(); | |
220 | ✗ | if ( list_bc.find(m_currentLabel) != list_bc.end()) { | |
221 | ✗ | if ( slave()->residualInterpolationType(iConn) == 0 ) { | |
222 | ✗ | m_elemFieldRobin[iRobin].setValue( m_seqVecs.Get("cvgraphFLOWOFHEAT"), *m_curvFeTemp , iel, m_iTemperature, m_ao, dof()); | |
223 | } else { | ||
224 | ✗ | m_elemFieldRobin[iRobin].val *=0 ; | |
225 | } | ||
226 | ✗ | m_robinAux.setValue(m_seqVecs.Get("cvgraphTEMPERATURE"),*m_curvFeTemp , iel, m_iTemperature, m_ao, dof()); | |
227 | ✗ | m_elemFieldRobin[iRobin].val += FelisceParam::instance().alphaRobin[iRobin]*m_robinAux.val; | |
228 | } | ||
229 | } | ||
230 | ✗ | break; | |
231 | ✗ | default: | |
232 | ✗ | FEL_ERROR("Three variables to read not yet implemented for this linear problem."); | |
233 | ✗ | break; | |
234 | } | ||
235 | } | ||
236 | } | ||
237 | } | ||
238 | ✗ | void LinearProblemHeat::assembleMassBoundaryAndInitKSP( std::size_t iConn ) { | |
239 | ✗ | LinearProblem::assembleMassBoundaryAndInitKSP(&LinearProblemHeat::massMatrixComputer, | |
240 | ✗ | this->slave()->interfaceLabels(iConn), | |
241 | &LinearProblemHeat::initPerETMass, | ||
242 | &LinearProblemHeat::updateFE, | ||
243 | iConn); | ||
244 | } | ||
245 | #endif | ||
246 | } | ||
247 |