Directory: | ./ |
---|---|
File: | Solver/linearProblemLinearElasticity.cpp |
Date: | 2024-04-14 07:32:34 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 91 | 509 | 17.9% |
Branches: | 135 | 1495 | 9.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/linearProblemLinearElasticity.hpp" | ||
21 | #include "DegreeOfFreedom/boundaryCondition.hpp" | ||
22 | #include "Core/felisceTransient.hpp" | ||
23 | |||
24 | namespace felisce { | ||
25 | 4 | LinearProblemLinearElasticity::LinearProblemLinearElasticity(): | |
26 |
11/22✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
✓ Branch 11 taken 4 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 4 times.
✗ Branch 15 not taken.
✓ Branch 21 taken 4 times.
✗ Branch 22 not taken.
✓ Branch 24 taken 4 times.
✗ Branch 25 not taken.
✓ Branch 30 taken 4 times.
✗ Branch 31 not taken.
✓ Branch 33 taken 4 times.
✗ Branch 34 not taken.
✓ Branch 36 taken 4 times.
✗ Branch 37 not taken.
✓ Branch 39 taken 4 times.
✗ Branch 40 not taken.
✓ Branch 42 taken 4 times.
✗ Branch 43 not taken.
|
4 | LinearProblem("Linear Elasticity",/*numberOfMatrices*/2),m_coupled(false) { |
27 | |||
28 | |||
29 | 4 | std::vector<std::string> listPara; //list | |
30 | |||
31 | // The petsc vectors normalField and measStar are necessary for the computation | ||
32 | // of the P1-normal field. | ||
33 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | listPara.emplace_back("normalField"); |
34 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | listPara.emplace_back("measStar"); |
35 | // Old quantities | ||
36 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | listPara.emplace_back("displacementOld"); |
37 |
2/4✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
|
4 | if (FelisceParam::instance().timeScheme == 0 ) { |
38 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | listPara.emplace_back("displacementOlder"); |
39 | } else { | ||
40 | ✗ | listPara.emplace_back("accelerationCurrent"); | |
41 | ✗ | listPara.emplace_back("accelerationOld"); | |
42 | ✗ | listPara.emplace_back("velocityCurrent"); | |
43 | ✗ | listPara.emplace_back("velocityOld"); | |
44 | } | ||
45 | |||
46 | // Stress coming from external problem | ||
47 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | listPara.emplace_back("externalStress"); |
48 | |||
49 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | std::vector<std::string> listSeq(listPara); |
50 | |||
51 |
2/2✓ Branch 1 taken 20 times.
✓ Branch 2 taken 4 times.
|
24 | for( std::size_t k(0); k<listPara.size();++k) { |
52 |
2/4✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 20 times.
✗ Branch 6 not taken.
|
20 | m_vecs.Init(listPara[k]); |
53 | } | ||
54 |
2/2✓ Branch 1 taken 20 times.
✓ Branch 2 taken 4 times.
|
24 | for( std::size_t k(0); k<listSeq.size();++k) { |
55 |
2/4✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 20 times.
✗ Branch 6 not taken.
|
20 | m_seqVecs.Init(listSeq[k]); |
56 | } | ||
57 | |||
58 |
2/4✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
|
4 | if ( FelisceParam::instance().withCVG ) { |
59 | #ifdef FELISCE_WITH_CVGRAPH | ||
60 | ✗ | m_cvgDirichletVariable = "cvgraphDisplacement"; | |
61 | #endif | ||
62 | ✗ | m_seqVecs.Init("cvgraphDisplacementOld"); | |
63 | ✗ | m_seqVecs.Init("cvgraphDisplacement"); | |
64 | ✗ | m_seqVecs.Init("externalVelocity"); | |
65 | ✗ | m_seqVecs.Init("cvgraphSTRESS"); | |
66 | ✗ | m_seqVecs.Init("currentVelocity"); | |
67 | } | ||
68 |
2/4✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
|
4 | m_interfaceLabels=FelisceParam::instance().fsiInterfaceLabel; |
69 | 4 | } | |
70 | |||
71 | ✗ | void LinearProblemLinearElasticity::initPetscVecsForCoupling() { | |
72 | ✗ | m_seqVecs.Init("previousFixedPointVelocity"); | |
73 | ✗ | m_vecs.Init("velocityCurrent"); | |
74 | ✗ | m_seqVecs.Init("velocityCurrent"); | |
75 | ✗ | this->initFixedPointAcceleration(); | |
76 | } | ||
77 | |||
78 | void | ||
79 | ✗ | LinearProblemLinearElasticity::initializeDofBoundaryAndBD2VolMaps() { | |
80 | /// this function builds all the mappings | ||
81 | /// to deal with petsc objects defined at the interface | ||
82 | ✗ | m_dofBD[0/*iBD*/].initialize(this); | |
83 | ✗ | std::vector<int> components(3); | |
84 | ✗ | for ( std::size_t icomp(0); icomp<(std::size_t)this->dimension(); icomp++) { | |
85 | ✗ | this->dofBD(/*iBD*/0).buildListOfBoundaryPetscDofs(this, m_interfaceLabels, /*iunknown*/ 0 , icomp); | |
86 | ✗ | components[icomp]=icomp; | |
87 | } | ||
88 | ✗ | m_dofBD[0/*iBD*/].buildBoundaryVolumeMapping(/*iunknown*/0, components); | |
89 | } | ||
90 | 4 | void LinearProblemLinearElasticity::initialize(std::vector<GeometricMeshRegion::Pointer>& mesh, FelisceTransient::Pointer fstransient, MPI_Comm& comm, bool doUseSNES) { | |
91 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | LinearProblem::initialize(mesh,comm,doUseSNES); |
92 | |||
93 | 4 | m_fstransient = fstransient; | |
94 | // you can either specify the lame coefficients or young and poisson, by default I assume to use ( E, \nu) | ||
95 |
5/10✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 4 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 4 times.
|
4 | if ( FelisceParam::instance().young < 0 || FelisceParam::instance().poisson < 0 ) { |
96 | ✗ | m_mu = FelisceParam::instance().mu_lame; | |
97 | ✗ | m_lambda = FelisceParam::instance().lambda_lame; | |
98 | } else { | ||
99 |
2/4✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
|
4 | m_mu = FelisceParam::instance().young/2/(1+FelisceParam::instance().poisson); |
100 |
4/8✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 4 times.
✗ Branch 11 not taken.
|
4 | m_lambda = FelisceParam::instance().young*FelisceParam::instance().poisson/(1.+FelisceParam::instance().poisson)/(1.-2.*FelisceParam::instance().poisson); |
101 | } | ||
102 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | m_deltaT = FelisceParam::instance().timeStep; |
103 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | m_density = FelisceParam::instance().densitySolid; |
104 | |||
105 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | m_betaNM = FelisceParam::instance().gammaNM; |
106 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | m_gammaNM = FelisceParam::instance().betaNM; |
107 | |||
108 |
4/8✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 4 times.
✗ Branch 11 not taken.
|
4 | std::cout<<"E: " << FelisceParam::instance().young << std::endl; |
109 |
4/8✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 4 times.
✗ Branch 11 not taken.
|
4 | std::cout<<"nu: "<< FelisceParam::instance().poisson << std::endl; |
110 |
3/6✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
|
4 | std::cout<<"mu: "<< m_mu << std::endl; |
111 |
3/6✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
|
4 | std::cout<<"lambda: "<< m_lambda << std::endl; |
112 |
3/6✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
|
4 | std::cout<<"deltaT: "<< m_deltaT << std::endl; |
113 |
3/6✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
|
4 | std::cout<<"density: "<< m_density << std::endl; |
114 | |||
115 | 4 | std::vector<PhysicalVariable> listVariable; | |
116 | 4 | std::vector<std::size_t> listNumComp; | |
117 | |||
118 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | listVariable.push_back(displacement); |
119 |
1/2✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
|
4 | listNumComp.push_back(this->dimension()); |
120 | |||
121 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | userAddOtherVariables(listVariable,listNumComp); |
122 | |||
123 | //define unknowns of the linear system. | ||
124 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | m_listUnknown.push_back(displacement); |
125 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | this->definePhysicalVariable(listVariable,listNumComp); |
126 |
1/2✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
|
4 | m_iDisplacement = this->listVariable().getVariableIdList(displacement); |
127 | 4 | } | |
128 | |||
129 | 124 | void LinearProblemLinearElasticity::initPerElementType(ElementType eltType, FlagMatrixRHS flagMatrixRHS) { | |
130 | (void) eltType; | ||
131 | (void) flagMatrixRHS; | ||
132 | 124 | m_fe = m_listCurrentFiniteElement[m_iDisplacement]; | |
133 | |||
134 |
3/6✓ Branch 2 taken 124 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 124 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 124 times.
✗ Branch 10 not taken.
|
124 | m_elemFields["displacementOld"].initialize(DOF_FIELD,*m_fe,this->dimension()); |
135 |
1/2✓ Branch 1 taken 124 times.
✗ Branch 2 not taken.
|
124 | if (FelisceParam::instance().timeScheme == 0) { |
136 |
3/6✓ Branch 2 taken 124 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 124 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 124 times.
✗ Branch 10 not taken.
|
124 | m_elemFields["displacementOlder"].initialize(DOF_FIELD,*m_fe,this->dimension()); |
137 | } else { | ||
138 | ✗ | m_elemFields["velocityOld"].initialize(DOF_FIELD,*m_fe,this->dimension()); | |
139 | ✗ | m_elemFields["accelerationOld"].initialize(DOF_FIELD,*m_fe,this->dimension()); | |
140 | } | ||
141 | |||
142 | |||
143 | 124 | } | |
144 | 120 | void LinearProblemLinearElasticity::initPerElementTypeBoundaryCondition(ElementType& eltType, FlagMatrixRHS flagMatrixRHS) { | |
145 | IGNORE_UNUSED_FLAG_MATRIX_RHS; | ||
146 | IGNORE_UNUSED_ELT_TYPE; | ||
147 | |||
148 | 120 | m_curvFe = m_listCurvilinearFiniteElement[m_iDisplacement]; | |
149 | #ifdef FELISCE_WITH_CVGRAPH | ||
150 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 120 times.
|
120 | if (FelisceParam::instance().withCVG ) { |
151 | ✗ | if ( slave()->thereIsAtLeastOneRobinCondition() ){ | |
152 | ✗ | m_robinAux.initialize( DOF_FIELD, *m_curvFe, this->dimension() ); | |
153 | } | ||
154 | } | ||
155 | #endif | ||
156 | 120 | } | |
157 | |||
158 | 35640 | void LinearProblemLinearElasticity::computeElementArrayBoundaryCondition(const std::vector<Point*>& elemPoint, const std::vector<felInt>& /*elemIdPoint*/, felInt& iel, FlagMatrixRHS /*flagMatrixRHS*/) { | |
159 | |||
160 | (void)iel; | ||
161 | |||
162 | 35640 | m_curvFe->updateMeas(0,elemPoint); | |
163 | #ifdef FELISCE_WITH_CVGRAPH | ||
164 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 35640 times.
|
35640 | if (FelisceParam::instance().withCVG ) { |
165 | ✗ | this->cvgraphNaturalBC(iel); | |
166 | } | ||
167 | #endif | ||
168 | 35640 | } | |
169 | |||
170 | 155403 | void LinearProblemLinearElasticity::computeElementArray(const std::vector<Point*>& elemPoint, const std::vector<felInt>& elemIdPoint, felInt& iel, FlagMatrixRHS flagMatrixRHS) { | |
171 | (void) elemIdPoint; | ||
172 | (void) elemPoint; | ||
173 | |||
174 | 155403 | m_fe->updateFirstDeriv(0, elemPoint); | |
175 | |||
176 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 155403 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
155403 | if ( flagMatrixRHS == FlagMatrixRHS::matrix_and_rhs || flagMatrixRHS == FlagMatrixRHS::only_matrix ) { |
177 |
2/2✓ Branch 1 taken 5013 times.
✓ Branch 2 taken 150390 times.
|
155403 | if ( m_fstransient->iteration == 0 ) { |
178 | //! Divergence of the stress-tensor | ||
179 | 5013 | m_elementMat[1]->eps_phi_i_eps_phi_j( 2*m_mu, *m_fe, 0, 0, this->dimension()); | |
180 | 5013 | m_elementMat[1]->div_phi_j_div_phi_i( m_lambda, *m_fe, 0, 0, this->dimension()); | |
181 | |||
182 | //! Mass term for the time scheme | ||
183 |
1/2✓ Branch 1 taken 5013 times.
✗ Branch 2 not taken.
|
5013 | if (FelisceParam::instance().timeScheme == 0 ) { |
184 | 5013 | m_elementMat[1]->phi_i_phi_j(m_density/(m_deltaT*m_deltaT),*m_fe,0,0,this->dimension()); | |
185 | } else { | ||
186 | ✗ | m_elementMat[1]->phi_i_phi_j(m_density/(m_deltaT*m_deltaT*m_betaNM),*m_fe,0,0,this->dimension()); | |
187 | } | ||
188 | } | ||
189 | } | ||
190 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 155403 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
155403 | if ( (flagMatrixRHS == FlagMatrixRHS::matrix_and_rhs) || (flagMatrixRHS == FlagMatrixRHS::only_rhs)) { |
191 | 155403 | this->computeRHS(iel); | |
192 | } | ||
193 | 155403 | } | |
194 | |||
195 | 155403 | void LinearProblemLinearElasticity::computeRHS(felInt iel) { | |
196 |
1/2✓ Branch 1 taken 155403 times.
✗ Branch 2 not taken.
|
155403 | if (FelisceParam::instance().timeScheme == 0 ) { |
197 | //! We read the values we need | ||
198 |
5/10✓ Branch 2 taken 155403 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 155403 times.
✗ Branch 6 not taken.
✓ Branch 10 taken 155403 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 155403 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 155403 times.
✗ Branch 17 not taken.
|
155403 | m_elemFields.Get("displacementOld") .setValue(m_seqVecs.Get("displacementOld") ,*m_fe,iel,m_iDisplacement,m_ao,dof()); |
199 |
5/10✓ Branch 2 taken 155403 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 155403 times.
✗ Branch 6 not taken.
✓ Branch 10 taken 155403 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 155403 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 155403 times.
✗ Branch 17 not taken.
|
155403 | m_elemFields.Get("displacementOlder") .setValue(m_seqVecs.Get("displacementOlder") ,*m_fe,iel,m_iDisplacement,m_ao,dof()); |
200 | |||
201 | //! We scale the values with the correct coefficients and we sum them into the first elementField | ||
202 |
3/6✓ Branch 2 taken 155403 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 155403 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 155403 times.
✗ Branch 9 not taken.
|
155403 | m_elemFields.Get("displacementOld") .val *= 2./m_deltaT/m_deltaT; |
203 |
3/6✓ Branch 2 taken 155403 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 155403 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 155403 times.
✗ Branch 9 not taken.
|
155403 | m_elemFields.Get("displacementOlder") .val *= -1./m_deltaT/m_deltaT; |
204 |
5/10✓ Branch 2 taken 155403 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 155403 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 155403 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 155403 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 155403 times.
✗ Branch 16 not taken.
|
155403 | m_elemFields.Get("displacementOld") .val += m_elemFields.Get("displacementOlder").val; |
205 | |||
206 | //! Everything is considered as a source term | ||
207 |
3/6✓ Branch 5 taken 155403 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 155403 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 155403 times.
✗ Branch 12 not taken.
|
155403 | m_elementVector[0]->source(m_density, *m_fe, m_elemFields.Get("displacementOld"), /*iblock*/0,/*numComp*/this->dimension()); |
208 | |||
209 | } else { | ||
210 | //! We read the values we need | ||
211 | ✗ | m_elemFields.Get("displacementOld") .setValue(m_seqVecs.Get("displacementOld"), *m_fe,iel,m_iDisplacement,m_ao,dof()); | |
212 | ✗ | m_elemFields.Get("velocityOld") .setValue(m_seqVecs.Get("velocityOld"), *m_fe,iel,m_iDisplacement,m_ao,dof()); | |
213 | ✗ | m_elemFields.Get("accelerationOld") .setValue(m_seqVecs.Get("accelerationOld"), *m_fe,iel,m_iDisplacement,m_ao,dof()); | |
214 | |||
215 | //! We scale the values with the correct coefficients and we sum them into the first elementField | ||
216 | ✗ | m_elemFields.Get("displacementOld").val += m_deltaT*m_elemFields.Get("velocityOld").val; | |
217 | ✗ | m_elemFields.Get("displacementOld").val += (m_deltaT*m_deltaT*(1-2*m_betaNM)/2)*m_elemFields.Get("accelerationOld").val; | |
218 | |||
219 | //! Everything is considered as a source term | ||
220 | ✗ | m_elementVector[0]->source(m_density/(m_betaNM*m_deltaT*m_deltaT), *m_fe, m_elemFields.Get("displacementOld"), /*iblock*/0,/*numComp*/this->dimension()); | |
221 | } | ||
222 | 155403 | } | |
223 | |||
224 | 120 | void LinearProblemLinearElasticity::updateCurrentVelocity() { | |
225 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 120 times.
|
120 | if ( FelisceParam::instance().timeScheme == 1) { |
226 | ✗ | if ( m_coupled ) { | |
227 | ✗ | m_seqVecs.Get("previousFixedPointVelocity").copyFrom(m_seqVecs.Get("velocityCurrent")); | |
228 | } | ||
229 | // The current acceleration: | ||
230 | ✗ | m_vecs.Get("accelerationCurrent").copyFrom(m_vecs.Get("accelerationOld")); | |
231 | ✗ | m_vecs.Get("accelerationCurrent").axpbypcz(/*a*/1, /*b*/m_deltaT,/*c*/m_deltaT*m_deltaT/2*(1-2*m_betaNM), /*x*/m_vecs.Get("displacementOld"), /*y*/m_vecs.Get("velocityOld")); | |
232 | ✗ | m_vecs.Get("accelerationCurrent").axpby(/*a*/1./m_betaNM/m_deltaT/m_deltaT, /*b*/ -1./m_betaNM/m_deltaT/m_deltaT, /*x*/this->solution()); | |
233 | ✗ | this->gatherVector(m_vecs.Get("accelerationCurrent"),m_seqVecs.Get("accelerationCurrent")); | |
234 | |||
235 | ✗ | m_vecs.Get("velocityCurrent").copyFrom(m_vecs.Get("velocityOld")); | |
236 | ✗ | m_vecs.Get("velocityCurrent").axpbypcz(m_deltaT*(1-m_gammaNM), m_deltaT*m_gammaNM,/*c*/1, m_vecs.Get("accelerationOld"),m_vecs.Get("accelerationCurrent")); | |
237 | ✗ | this->gatherVector(m_vecs.Get("velocityCurrent"),m_seqVecs.Get("velocityCurrent")); | |
238 | } else { | ||
239 | // The current displacement is the solution... | ||
240 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 120 times.
|
120 | if ( m_coupled ) { |
241 | ✗ | m_seqVecs.Get("previousFixedPointVelocity").copyFrom(m_seqVecs.Get("velocityCurrent")); | |
242 | // The current velocity: | ||
243 | ✗ | m_vecs.Get("velocityCurrent").copyFrom(this->solution());// currentVelocity = currentDisplacement | |
244 | ✗ | m_vecs.Get("velocityCurrent").axpby(-1./m_deltaT, 1./m_deltaT, m_vecs.Get("displacementOld")); // currentVelocity = (currentDisplacent - oldDisplacement)/delta T | |
245 | ✗ | this->gatherVector(m_vecs.Get("velocityCurrent"),m_seqVecs.Get("velocityCurrent")); | |
246 | } | ||
247 | } | ||
248 | |||
249 | |||
250 | |||
251 | 120 | } | |
252 | |||
253 | 120 | void LinearProblemLinearElasticity::updateOldDisplacement() { | |
254 |
1/2✓ Branch 1 taken 120 times.
✗ Branch 2 not taken.
|
120 | if ( FelisceParam::instance().timeScheme == 0 ) { |
255 | |||
256 |
5/10✓ Branch 2 taken 120 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 120 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 120 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 120 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 120 times.
✗ Branch 16 not taken.
|
120 | m_vecs.Get("displacementOlder").copyFrom(m_vecs.Get("displacementOld")); |
257 |
5/10✓ Branch 2 taken 120 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 120 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 120 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 120 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 120 times.
✗ Branch 16 not taken.
|
120 | this->gatherVector(m_vecs.Get("displacementOlder"),m_seqVecs.Get("displacementOlder")); |
258 | |||
259 | } else { | ||
260 | |||
261 | ✗ | m_vecs.Get("velocityOld").copyFrom(m_vecs.Get("velocityCurrent")); | |
262 | ✗ | m_vecs.Get("accelerationOld").copyFrom(m_vecs.Get("accelerationCurrent")); | |
263 | |||
264 | ✗ | this->gatherVector(m_vecs.Get("velocityOld"),m_seqVecs.Get("velocityOld")); | |
265 | ✗ | this->gatherVector(m_vecs.Get("accelerationOld"),m_seqVecs.Get("accelerationOld")); | |
266 | |||
267 | } | ||
268 |
3/6✓ Branch 2 taken 120 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 120 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 120 times.
✗ Branch 10 not taken.
|
120 | m_vecs.Get("displacementOld").copyFrom(this->solution()); |
269 |
5/10✓ Branch 2 taken 120 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 120 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 120 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 120 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 120 times.
✗ Branch 16 not taken.
|
120 | this->gatherVector(m_vecs.Get("displacementOld"),m_seqVecs.Get("displacementOld")); |
270 | #ifdef FELISCE_WITH_CVGRAPH | ||
271 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 120 times.
|
120 | if( FelisceParam::instance().withCVG ) { //&& m_readVariable == "VELOCITY" |
272 | ✗ | this->gatherSolution(); | |
273 | ✗ | m_seqVecs.Get("cvgraphDisplacementOld").copyFrom(this->sequentialSolution()); | |
274 | } | ||
275 | #endif | ||
276 | 120 | } | |
277 | |||
278 | void | ||
279 | ✗ | LinearProblemLinearElasticity::readStressInterface(std::map<int, std::map<int,std::map<int,int> > > externalMap, const PetscVector& externalSeqStress, felInt iUC0) { | |
280 | ✗ | if ( FelisceParam::verbose() > 0 ) { | |
281 | ✗ | std::stringstream out; | |
282 | ✗ | out<<"reading data at the interface..."; | |
283 | ✗ | PetscPrintf(MpiInfo::petscComm(), "%s",out.str().c_str()); | |
284 | } | ||
285 | ✗ | felInt iDofGlobScalarPressure(0); | |
286 | ✗ | felInt iDofGlobScalarIOP(0); | |
287 | ✗ | felInt iDofGlobScalarPressureAus(0); | |
288 | ✗ | double valueAus(0.0); | |
289 | ✗ | std::vector<felInt> labels = FelisceParam::instance().fsiInterfaceLabel; | |
290 | ✗ | for ( std::size_t iComp(0); iComp< (std::size_t) this->dimension(); ++iComp, ++iUC0) { | |
291 | ✗ | for ( std::size_t iLab(0); iLab < m_interfaceLabels.size(); ++iLab) { | |
292 | //Contrary to the application PerfectFluid we assume the labels are the same, therefore we do not need a mapBetweenLabels | ||
293 | ✗ | for(auto it_suppDofIop = externalMap.at(iUC0)[m_interfaceLabels[iLab]].begin(); it_suppDofIop != externalMap.at(iUC0)[m_interfaceLabels[iLab]].end(); it_suppDofIop++) { | |
294 | ✗ | iDofGlobScalarIOP = it_suppDofIop->second; | |
295 | ✗ | iDofGlobScalarPressure = m_dofBD[0/*iBD*/].getPetscDofs( this->dof().getNumGlobComp(m_iDisplacement,iComp), m_interfaceLabels[iLab], it_suppDofIop->first ); | |
296 | ✗ | iDofGlobScalarPressureAus = iDofGlobScalarPressure; | |
297 | ✗ | AOPetscToApplication(m_ao,/*counter*/1,&iDofGlobScalarPressureAus); | |
298 | ✗ | if ( m_dofPart[iDofGlobScalarPressureAus] == MpiInfo::rankProc() ) { | |
299 | ✗ | externalSeqStress.getValues(1,&iDofGlobScalarIOP, &valueAus); | |
300 | ✗ | m_vecs.Get("externalStress").setValue(iDofGlobScalarPressure, valueAus, INSERT_VALUES); | |
301 | } | ||
302 | } | ||
303 | } | ||
304 | } | ||
305 | ✗ | m_vecs.Get("externalStress").assembly(); | |
306 | ✗ | gatherVector(m_vecs.Get("externalStress"), m_seqVecs.Get("externalStress")); | |
307 | |||
308 | ✗ | if ( FelisceParam::verbose() > 0 ) { | |
309 | ✗ | std::stringstream out; | |
310 | ✗ | out<<"done"<<std::endl; | |
311 | ✗ | PetscPrintf(MpiInfo::petscComm(), "%s",out.str().c_str()); | |
312 | } | ||
313 | } | ||
314 | ✗ | double LinearProblemLinearElasticity::computeL2ScalarProduct(std::string l, std::string r) { | |
315 | ✗ | m_auxiliaryStrings.clear(); | |
316 | ✗ | m_auxiliaryStrings.push_back(l); | |
317 | ✗ | m_auxiliaryStrings.push_back(r); | |
318 | |||
319 | ✗ | m_auxiliaryDoubles.clear(); | |
320 | ✗ | m_auxiliaryDoubles.push_back(0.0); | |
321 | ✗ | assemblyLoopBoundaryGeneral(&LinearProblemLinearElasticity::scalarProductComputer, | |
322 | ✗ | m_interfaceLabels, | |
323 | &LinearProblemLinearElasticity::initPerET, | ||
324 | &LinearProblemLinearElasticity::updateFe); | ||
325 | ✗ | double result(0); | |
326 | ✗ | MPI_Allreduce(&m_auxiliaryDoubles[0],&result,1,MPI_DOUBLE,MPI_SUM,MpiInfo::petscComm()); | |
327 | ✗ | return result; | |
328 | } | ||
329 | ✗ | void LinearProblemLinearElasticity::scalarProductComputer(felInt ielSupportDof) { | |
330 | double l,r; | ||
331 | ✗ | for ( std::size_t iComp(0); iComp < (std::size_t) this->dimension(); ++iComp ) { | |
332 | ✗ | for ( std::size_t iSurfDof(0); iSurfDof < ( std::size_t ) m_curvFe->numDof(); iSurfDof++) { | |
333 | felInt iDofGlobScalar; | ||
334 | ✗ | dof().loc2glob( ielSupportDof, iSurfDof, m_iDisplacement, iComp, iDofGlobScalar); | |
335 | ✗ | AOApplicationToPetsc(m_ao,1,&iDofGlobScalar); | |
336 | ✗ | m_seqVecs.Get( m_auxiliaryStrings[0] ).getValues(1,&iDofGlobScalar, &r); | |
337 | ✗ | for ( std::size_t jSurfDof(0); jSurfDof < ( std::size_t ) m_curvFe->numDof(); jSurfDof++) { | |
338 | felInt jDofGlobScalar; | ||
339 | ✗ | dof().loc2glob( ielSupportDof, jSurfDof, m_iDisplacement, iComp, jDofGlobScalar); | |
340 | ✗ | AOApplicationToPetsc(m_ao,1,&jDofGlobScalar); | |
341 | ✗ | m_seqVecs.Get( m_auxiliaryStrings[1] ).getValues(1,&iDofGlobScalar, &l); | |
342 | ✗ | for(int ig=0; ig < m_curvFe->numQuadraturePoint(); ig++) { | |
343 | ✗ | m_auxiliaryDoubles[0] += l*r * m_curvFe->phi[ig](iSurfDof) * m_curvFe->phi[ig](jSurfDof) * m_curvFe->weightMeas(ig); | |
344 | } | ||
345 | } | ||
346 | } | ||
347 | } | ||
348 | } | ||
349 | |||
350 | std::pair<double,double> | ||
351 | ✗ | LinearProblemLinearElasticity::computeTestQuantities() { | |
352 | ✗ | std::pair<double,double> pairOfTestQuantities; | |
353 | ✗ | m_auxiliaryDoubles.clear(); | |
354 | ✗ | m_auxiliaryDoubles.resize(4,0.0); | |
355 | ✗ | assemblyLoopBoundaryGeneral( &LinearProblemLinearElasticity::testQuantitiesComputer, | |
356 | ✗ | m_interfaceLabels, | |
357 | &LinearProblemLinearElasticity::initPerET, | ||
358 | &LinearProblemLinearElasticity::updateFe); | ||
359 | ✗ | std::vector<double> result(4,0.0); | |
360 | ✗ | MPI_Allreduce(m_auxiliaryDoubles.data(),result.data(),4,MPI_DOUBLE,MPI_SUM,MpiInfo::petscComm()); | |
361 | using std::sqrt; | ||
362 | ✗ | pairOfTestQuantities.first = std::sqrt(result[0])/( std::sqrt(result[1]) + 1e-12); | |
363 | ✗ | pairOfTestQuantities.second = std::sqrt(result[2])/( std::sqrt(result[3]) + 1e-12); | |
364 | ✗ | return pairOfTestQuantities; | |
365 | } | ||
366 | ✗ | void LinearProblemLinearElasticity::initPerET() { | |
367 | ✗ | m_curvFe = m_listCurvilinearFiniteElement[m_iDisplacement]; | |
368 | } | ||
369 | ✗ | void LinearProblemLinearElasticity::updateFe(const std::vector<Point*>& elemPoint,const std::vector<int>& /*elemIdPoint*/) { | |
370 | ✗ | m_curvFe ->updateMeasNormal(0, elemPoint); | |
371 | } | ||
372 | |||
373 | void | ||
374 | ✗ | LinearProblemLinearElasticity::testQuantitiesComputer(felInt ielSupportDof) { | |
375 | |||
376 | double uni,unoldi,ciopi,x1i; | ||
377 | double value0i,value1i,value2i,value3i; | ||
378 | |||
379 | double unj,unoldj,ciopj,x1j; | ||
380 | double value0j,value1j,value2j,value3j; | ||
381 | |||
382 | felInt iDofGlobScalar; | ||
383 | |||
384 | ✗ | for ( std::size_t iComp(0); iComp < ( std::size_t )this->dimension(); iComp++) { | |
385 | ✗ | for ( std::size_t iSurfDof(0); iSurfDof < ( std::size_t ) m_curvFe->numDof(); iSurfDof++) { | |
386 | |||
387 | ✗ | dof().loc2glob( ielSupportDof, iSurfDof, m_iDisplacement, iComp, iDofGlobScalar); | |
388 | ✗ | AOApplicationToPetsc(m_ao,1,&iDofGlobScalar); | |
389 | |||
390 | ✗ | m_seqVecs.Get( "velocityCurrent" ).getValues(1,&iDofGlobScalar, &uni); | |
391 | ✗ | m_seqVecs.Get( "previousFixedPointVelocity" ).getValues(1,&iDofGlobScalar, &unoldi); | |
392 | ✗ | m_seqVecs.Get( "externalStress" ).getValues(1,&iDofGlobScalar, &ciopi); | |
393 | ✗ | m_seqVecs.Get( "x1" ).getValues(1,&iDofGlobScalar, &x1i); | |
394 | |||
395 | ✗ | value0i = uni-unoldi; | |
396 | ✗ | value1i = uni; | |
397 | ✗ | value2i = ciopi-x1i; | |
398 | ✗ | value3i = ciopi; | |
399 | |||
400 | |||
401 | ✗ | for ( std::size_t jSurfDof(0); jSurfDof < ( std::size_t ) m_curvFe->numDof(); jSurfDof++) { | |
402 | felInt jDofGlobScalar; | ||
403 | ✗ | dof().loc2glob( ielSupportDof, jSurfDof, m_iDisplacement, iComp, jDofGlobScalar); | |
404 | ✗ | AOApplicationToPetsc(m_ao,1,&jDofGlobScalar); | |
405 | |||
406 | ✗ | m_seqVecs.Get( "velocityCurrent" ).getValues(1,&jDofGlobScalar, &unj); | |
407 | ✗ | m_seqVecs.Get( "previousFixedPointVelocity" ).getValues(1,&jDofGlobScalar, &unoldj); | |
408 | ✗ | m_seqVecs.Get( "externalStress" ).getValues(1,&jDofGlobScalar, &ciopj); | |
409 | ✗ | m_seqVecs.Get( "x1" ).getValues(1,&jDofGlobScalar, &x1j); | |
410 | |||
411 | ✗ | value0j = unj-unoldj; | |
412 | ✗ | value1j = unj; | |
413 | ✗ | value2j = ciopj-x1j; | |
414 | ✗ | value3j = ciopj; | |
415 | |||
416 | ✗ | for(int ig=0; ig < m_curvFe->numQuadraturePoint(); ig++) { | |
417 | ✗ | double w = m_curvFe->phi[ig](iSurfDof) * m_curvFe->phi[ig](jSurfDof) * m_curvFe->weightMeas(ig); | |
418 | ✗ | m_auxiliaryDoubles[0] += value0i*value0j * w; | |
419 | ✗ | m_auxiliaryDoubles[1] += value1i*value1j * w; | |
420 | ✗ | m_auxiliaryDoubles[2] += value2i*value2j * w; | |
421 | ✗ | m_auxiliaryDoubles[3] += value3i*value3j * w; | |
422 | } | ||
423 | } | ||
424 | } | ||
425 | } | ||
426 | } | ||
427 | |||
428 | 120 | void LinearProblemLinearElasticity::applyEssentialBoundaryConditionDerivedProblem(int rank, FlagMatrixRHS flagMatrixRHS) { | |
429 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 120 times.
|
120 | if( FelisceParam::instance().useEssDerivedBoundaryCondition ) { |
430 | ✗ | if ( FelisceParam::verbose() > 2 ) | |
431 | ✗ | std::cout<<"["<<rank<<"]--Applying zero-Dirichlet BCs on the velocity at the interface between inlet outlet and surface."<<std::endl; | |
432 | ✗ | getRings(); | |
433 | ✗ | double bigValue=1.e20; | |
434 | |||
435 | ✗ | for(auto itDofBC = m_idDofRings.begin(); itDofBC != m_idDofRings.end(); ++itDofBC) { | |
436 | ✗ | if( (flagMatrixRHS == FlagMatrixRHS::matrix_and_rhs) || (flagMatrixRHS == FlagMatrixRHS::only_matrix)) | |
437 | ✗ | matrix(0).setValue(*itDofBC, *itDofBC, bigValue, INSERT_VALUES); | |
438 | ✗ | if( (flagMatrixRHS == FlagMatrixRHS::matrix_and_rhs) || (flagMatrixRHS == FlagMatrixRHS::only_rhs)) | |
439 | ✗ | vector().setValue(*itDofBC,0.0, INSERT_VALUES); | |
440 | } | ||
441 | } | ||
442 | 120 | } | |
443 | |||
444 | #ifdef FELISCE_WITH_CVGRAPH | ||
445 | ✗ | void LinearProblemLinearElasticity::readData() { | |
446 | ✗ | bool dispUpdateNeeded(false); | |
447 | ✗ | bool dispDirectly(false); | |
448 | ✗ | for ( std::size_t iConn(0); iConn<this->slave()->numConnections(); ++iConn ) { | |
449 | ✗ | std::vector<PetscVector> vecs; | |
450 | ✗ | for ( std::size_t cVar(0); cVar<this->slave()->numVarToRead(iConn); ++cVar) { | |
451 | ✗ | std::string varToRead = this->slave()->readVariable(iConn,cVar); | |
452 | ✗ | if ( varToRead == "STRESS" ) { | |
453 | ✗ | vecs.push_back(m_seqVecs.Get("cvgraphSTRESS")); | |
454 | ✗ | } else if ( varToRead == "VELOCITY" ) { | |
455 | ✗ | dispUpdateNeeded = true; | |
456 | ✗ | vecs.push_back(m_seqVecs.Get("externalVelocity")); | |
457 | ✗ | } else if ( varToRead == "DISPLACEMENT" ) { | |
458 | ✗ | dispDirectly = true; | |
459 | ✗ | vecs.push_back(m_seqVecs.Get("cvgraphDisplacement")); | |
460 | } else { | ||
461 | ✗ | std::cout<<"Connection: "<<iConn<<"--variable to read: "<<varToRead<<std::endl; | |
462 | ✗ | FEL_ERROR("Error in variable to read"); | |
463 | } | ||
464 | } | ||
465 | ✗ | this->slave()->receiveData(vecs,iConn); | |
466 | } | ||
467 | ✗ | if ( dispUpdateNeeded && dispDirectly ) { | |
468 | ✗ | FEL_ERROR("TODO: implement a better readData function"); | |
469 | } | ||
470 | ✗ | if ( dispUpdateNeeded ) { | |
471 | ✗ | waxpy(m_seqVecs.Get("cvgraphDisplacement"), m_deltaT, m_seqVecs.Get("externalVelocity"),m_seqVecs.Get("cvgraphDisplacementOld")); | |
472 | } | ||
473 | } | ||
474 | |||
475 | ✗ | void LinearProblemLinearElasticity::sendData() { | |
476 | ✗ | this->gatherSolution(); | |
477 | |||
478 | ✗ | m_seqVecs.Get("currentVelocity").copyFrom(this->sequentialSolution());// currentVelocity = currentDisplacement | |
479 | ✗ | m_seqVecs.Get("currentVelocity").axpby(-1./m_deltaT, 1./m_deltaT, m_seqVecs.Get("displacementOld")); // currentVelocity = (currentDisplacent - oldDisplacement)/delta T | |
480 | |||
481 | ✗ | for ( std::size_t iConn(0); iConn<this->slave()->numConnections(); ++iConn ) { | |
482 | ✗ | std::vector<PetscVector> vecs; | |
483 | ✗ | for ( std::size_t cVar(0); cVar<this->slave()->numVarToSend(iConn); ++cVar) { | |
484 | ✗ | std::string varToSend = this->slave()->sendVariable(iConn, cVar); | |
485 | ✗ | if ( varToSend == "STRESS" ) { | |
486 | ✗ | this->prepareResidual(iConn); | |
487 | ✗ | vecs.push_back(m_seqStressOut); | |
488 | ✗ | } else if ( varToSend == "DISPLACEMENT" ) { | |
489 | ✗ | vecs.push_back(this->sequentialSolution()); | |
490 | ✗ | } else if ( varToSend == "VELOCITY" ) { | |
491 | ✗ | vecs.push_back(m_seqVecs.Get("currentVelocity")); | |
492 | } else { | ||
493 | ✗ | std::cout<<"Connection: "<<iConn<<"--variable to send: "<<varToSend<<std::endl; | |
494 | ✗ | FEL_ERROR("Error in variable to send"); | |
495 | } | ||
496 | } | ||
497 | ✗ | this->slave()->sendData(vecs,iConn); | |
498 | } | ||
499 | } | ||
500 | ✗ | void LinearProblemLinearElasticity::assembleMassBoundaryAndInitKSP( std::size_t iConn ) { | |
501 | ✗ | LinearProblem::assembleMassBoundaryAndInitKSP(&LinearProblemLinearElasticity::massMatrixComputer, | |
502 | ✗ | this->slave()->interfaceLabels(iConn), | |
503 | &LinearProblemLinearElasticity::initPerETMass, | ||
504 | &LinearProblemLinearElasticity::updateFE, | ||
505 | iConn); | ||
506 | } | ||
507 | |||
508 | /*! \brief Function to assemble the mass matrix | ||
509 | * Function to be called in the assemblyLoopBoundaryGeneral | ||
510 | */ | ||
511 | ✗ | void LinearProblemLinearElasticity::massMatrixComputer(felInt ielSupportDof) { | |
512 | ✗ | this->m_elementMatBD[0]->zero(); | |
513 | ✗ | this->m_elementMatBD[0]->phi_i_phi_j(/*coef*/1.,*m_curvFe,/*iblock*/0,/*iblock*/0,this->dimension()); | |
514 | ✗ | this->setValueMatrixBD(ielSupportDof); | |
515 | } | ||
516 | |||
517 | void | ||
518 | ✗ | LinearProblemLinearElasticity::initPerETMass() { | |
519 | ✗ | felInt numDofTotal = 0; | |
520 | //pay attention this numDofTotal is bigger than expected since it counts for all the VARIABLES | ||
521 | ✗ | for (std::size_t iFe = 0; iFe < this->m_listCurvilinearFiniteElement.size(); iFe++) {//this loop is on variables while it should be on unknown | |
522 | ✗ | numDofTotal += this->m_listCurvilinearFiniteElement[iFe]->numDof()*this->m_listVariable[iFe].numComponent(); | |
523 | } | ||
524 | ✗ | m_globPosColumn.resize(numDofTotal); m_globPosRow.resize(numDofTotal); m_matrixValues.resize(numDofTotal*numDofTotal); | |
525 | |||
526 | ✗ | m_curvFe = this->m_listCurvilinearFiniteElement[ m_iDisplacement ]; | |
527 | } | ||
528 | |||
529 | void | ||
530 | ✗ | LinearProblemLinearElasticity::updateFE(const std::vector<Point*>& elemPoint, const std::vector<int>&) { | |
531 | ✗ | m_curvFe->updateMeasNormal(0, elemPoint); | |
532 | } | ||
533 | #endif | ||
534 | |||
535 | ✗ | void LinearProblemLinearElasticity::computeBoundaryStress(const std::vector<int>& labels) { | |
536 | ✗ | if ( m_computedStress.isNull() ) | |
537 | ✗ | m_computedStress.duplicateFrom(this->solution()); | |
538 | ✗ | if ( m_seqComputedStress.isNull() ) | |
539 | ✗ | m_seqComputedStress.duplicateFrom(this->sequentialSolution()); | |
540 | ✗ | m_computedStress.zeroEntries(); | |
541 | ✗ | this->gatherSolution(); | |
542 | ✗ | m_grad.resize(this->dimension(),this->dimension()); | |
543 | ✗ | m_stress.resize(this->dimension()); | |
544 | ✗ | m_previousVolEltType=GeometricMeshRegion::Nod; | |
545 | ✗ | if(m_mesh[m_currentMesh]->statusFaces() == false) { | |
546 | ✗ | m_mesh[m_currentMesh]->buildFaces(); | |
547 | } | ||
548 | ✗ | assemblyLoopBoundaryGeneral(&LinearProblemLinearElasticity::boundaryStressComputer, | |
549 | labels, | ||
550 | &LinearProblemLinearElasticity::initPerETBoundaryStress, | ||
551 | &LinearProblemLinearElasticity::updateFEBoundaryStress); | ||
552 | ✗ | this->desallocateArrayForAssembleMatrixRHS(FlagMatrixRHS::only_rhs); | |
553 | ✗ | m_computedStress.assembly(); | |
554 | ✗ | this->gatherVector(m_computedStress,m_seqComputedStress); | |
555 | } | ||
556 | |||
557 | /*! \brief Function to compute boundary stress | ||
558 | * Function to be called in the assemblyLoopBoundaryGeneral | ||
559 | */ | ||
560 | ✗ | void LinearProblemLinearElasticity::boundaryStressComputer(felInt ielSupportDof) { | |
561 | ✗ | std::vector<felInt> bd2vol; | |
562 | ✗ | m_fe->identifyLocBDDof(*m_curvFe,bd2vol); | |
563 | ✗ | m_elemFieldStress.val*=0.0; | |
564 | ✗ | for (int hbdDof(0); hbdDof<m_curvFe->numDof(); hbdDof++) { | |
565 | ✗ | m_grad = prod(m_fe->dPhiOnDofs[bd2vol.at(hbdDof)],trans(m_elemFieldDisplacementVolumeDofs.val)); | |
566 | ✗ | m_stress = m_mu*( prod(m_grad,m_curvFe->normal[0]) + prod(trans(m_grad),m_curvFe->normal[0]) ) + m_lambda*Tools::trace(m_grad)*m_curvFe->normal[0]; | |
567 | ✗ | for (int jcomp(0); jcomp<this->dimension(); jcomp++) { | |
568 | ✗ | m_elemFieldStress.val(jcomp,hbdDof) = m_stress(jcomp); | |
569 | } | ||
570 | } | ||
571 | ✗ | m_elementVectorBD[0]->zero(); | |
572 | ✗ | m_elementVectorBD[0]->source(-1.0, *m_curvFe, m_elemFieldStress, 0, this->dimension()); | |
573 | ✗ | this->setValueCustomVectorBD(ielSupportDof, ADD_VALUES, m_computedStress ); | |
574 | } | ||
575 | void | ||
576 | ✗ | LinearProblemLinearElasticity::initPerETBoundaryStress() { | |
577 | ✗ | this->desallocateArrayForAssembleMatrixRHS(FlagMatrixRHS::only_rhs); | |
578 | ✗ | this->allocateArrayForAssembleMatrixRHSBD(FlagMatrixRHS::only_rhs); | |
579 | ✗ | m_curvFe = m_listCurvilinearFiniteElement[m_iDisplacement]; | |
580 | ✗ | m_elemFieldStress.initialize(DOF_FIELD, *m_curvFe,this->dimension()); | |
581 | } | ||
582 | void | ||
583 | ✗ | LinearProblemLinearElasticity::updateFEBoundaryStress(const std::vector<Point*>& elemPoint, const std::vector<int>& elemIdPoint) { | |
584 | ✗ | std::vector<Point*> elemPointVol; | |
585 | ✗ | std::vector<felInt> elemIdPointVol; | |
586 | ✗ | int idLocFace = -1; | |
587 | ✗ | felInt idElemVol = -1; | |
588 | ✗ | m_mesh[m_currentMesh]->getElementFromBdElem(elemIdPoint,elemIdPointVol,elemPointVol,idLocFace,idElemVol); | |
589 | int dummy; | ||
590 | ✗ | m_mesh[m_currentMesh]->getTypeElemFromIdElem(idElemVol, m_volEltType, dummy); | |
591 | ✗ | if (m_volEltType != m_previousVolEltType ) { | |
592 | ✗ | this->defineFiniteElement(m_volEltType); | |
593 | ✗ | this->initElementArray(); | |
594 | ✗ | m_previousVolEltType=m_volEltType; | |
595 | ✗ | m_fe = m_listCurrentFiniteElement[m_iDisplacement]; | |
596 | ✗ | m_elemFieldDisplacementVolumeDofs.initialize(DOF_FIELD, *m_fe,this->dimension()); | |
597 | ✗ | m_fe->allocateOnDofsDataStructures(); | |
598 | } | ||
599 | ✗ | m_fe->updateFirstDerivOnDofs(0, elemPointVol); | |
600 | ✗ | m_curvFe->updateMeasNormal(0,elemPoint); | |
601 | ✗ | m_elemFieldDisplacementVolumeDofs.setValue(this->sequentialSolution(),*m_fe,idElemVol,m_iDisplacement,m_ao,dof()); | |
602 | } | ||
603 | |||
604 | /***********************************************************************************/ | ||
605 | /***********************************************************************************/ | ||
606 | |||
607 | ✗ | void LinearProblemLinearElasticity::computeNormalField(const std::vector<int> & labels, felInt idVecVariable) | |
608 | { | ||
609 | ✗ | m_auxiliaryInts.resize(1); | |
610 | ✗ | m_auxiliaryInts[0]=idVecVariable;//for instance m_iVelocity; | |
611 | /*! | ||
612 | For each dof d of the surface the sum: \f$\sum_{K} m(K)\vec n(K)\f$ is computed. | ||
613 | - K are all the boundary elements that share the dof d. | ||
614 | - m(K) is the measure of the element | ||
615 | - n(K) is the P0 normal defined on the element | ||
616 | */ | ||
617 | ✗ | this->assemblyLoopBoundaryGeneral(&LinearProblemLinearElasticity::normalFieldComputer,labels,&LinearProblemLinearElasticity::initPerETNormVel,&LinearProblemLinearElasticity::updateFeNormVel); | |
618 | |||
619 | ✗ | m_vecs.Get("normalField").assembly(); | |
620 | ✗ | m_vecs.Get("measStar").assembly(); | |
621 | |||
622 | /// Than the vector is divided by \f$\sum_{K} m(K)\f$ to obtain the P1 field. | ||
623 | ✗ | pointwiseDivide(m_vecs.Get("normalField"), m_vecs.Get("normalField"), m_vecs.Get("measStar")); | |
624 | ✗ | gatherVector( m_vecs.Get("normalField"), m_seqVecs.Get("normalField") ); | |
625 | |||
626 | /// using normalizeComputer we normalize the result. | ||
627 | ✗ | this->assemblyLoopBoundaryGeneral(&LinearProblemLinearElasticity::normalizeComputer,labels,&LinearProblemLinearElasticity::initPerETNormVel,&LinearProblemLinearElasticity::updateFeNormVel); | |
628 | |||
629 | ✗ | m_vecs.Get("normalField").assembly(); | |
630 | ✗ | gatherVector( m_vecs.Get("normalField"), m_seqVecs.Get("normalField") ); | |
631 | } | ||
632 | |||
633 | /***********************************************************************************/ | ||
634 | /***********************************************************************************/ | ||
635 | |||
636 | ✗ | void LinearProblemLinearElasticity::normalFieldComputer(felInt ielSupportDof) | |
637 | { | ||
638 | double value; | ||
639 | ✗ | for ( std::size_t iSurfDof(0); iSurfDof < ( std::size_t ) m_listCurvilinearFiniteElement[m_auxiliaryInts[0]]->numDof(); iSurfDof++) { | |
640 | ✗ | double feMeas(m_listCurvilinearFiniteElement[m_auxiliaryInts[0]]->measure()); | |
641 | ✗ | for ( std::size_t iCoor(0); iCoor < ( std::size_t ) m_listCurvilinearFiniteElement[m_auxiliaryInts[0]]->numCoor(); iCoor++) { | |
642 | felInt iDofGlob; | ||
643 | ✗ | dof().loc2glob( ielSupportDof, iSurfDof, m_auxiliaryInts[0], iCoor, iDofGlob); | |
644 | ✗ | AOApplicationToPetsc(m_ao,1,&iDofGlob); | |
645 | ✗ | value=0.0; | |
646 | ✗ | for ( std::size_t iQuadBd(0.0) ; iQuadBd < ( std::size_t )m_listCurvilinearFiniteElement[m_auxiliaryInts[0]]->numQuadraturePoint(); iQuadBd++) { | |
647 | ✗ | value += m_listCurvilinearFiniteElement[m_auxiliaryInts[0]]->weightMeas( iQuadBd ) * m_listCurvilinearFiniteElement[m_auxiliaryInts[0]]->normal[iQuadBd](iCoor); | |
648 | } | ||
649 | ✗ | m_vecs.Get("normalField").setValue(iDofGlob, value, ADD_VALUES); | |
650 | ✗ | m_vecs.Get("measStar").setValue(iDofGlob, feMeas, ADD_VALUES); | |
651 | } | ||
652 | } | ||
653 | } | ||
654 | |||
655 | /***********************************************************************************/ | ||
656 | /***********************************************************************************/ | ||
657 | |||
658 | ✗ | void LinearProblemLinearElasticity::updateFeNormVel(const std::vector<Point*>& elemPoint,const std::vector<int>& /*elemIdPoint*/) | |
659 | { | ||
660 | ✗ | m_listCurvilinearFiniteElement[m_auxiliaryInts[0]]->updateMeasNormal(0,elemPoint); | |
661 | } | ||
662 | |||
663 | /***********************************************************************************/ | ||
664 | /***********************************************************************************/ | ||
665 | |||
666 | ✗ | void LinearProblemLinearElasticity::normalizeComputer(felInt ielSupportDof) | |
667 | { | ||
668 | ✗ | const int numComp = m_listCurvilinearFiniteElement[m_auxiliaryInts[0]]->numCoor( ); | |
669 | ✗ | const int numDof = m_listCurvilinearFiniteElement[m_auxiliaryInts[0]]->numDof( ); | |
670 | |||
671 | ✗ | std::vector< double > norm(numDof,0.0); | |
672 | ✗ | std::vector< std::vector< double > > NN(numDof, std::vector< double >(numComp, 0.0)); | |
673 | ✗ | for ( int idof = 0; idof < numDof; idof++ ) { | |
674 | ✗ | for ( int icomp = 0; icomp < numComp; icomp++ ) { | |
675 | int iDofGlob; | ||
676 | double value; | ||
677 | ✗ | dof().loc2glob( ielSupportDof, idof, m_auxiliaryInts[0], icomp, iDofGlob); | |
678 | ✗ | AOApplicationToPetsc(m_ao, 1, &iDofGlob); | |
679 | ✗ | m_seqVecs.Get("normalField").getValues(1, &iDofGlob, &value); | |
680 | ✗ | norm[idof] += value*value; | |
681 | ✗ | NN[idof][icomp] = value; | |
682 | } | ||
683 | ✗ | norm[idof] = std::sqrt( norm[idof] ); | |
684 | ✗ | for ( int icomp = 0; icomp < numComp; icomp++ ) | |
685 | ✗ | NN[idof][icomp] = NN[idof][icomp]/norm[idof]; | |
686 | } | ||
687 | ✗ | for ( int idof = 0; idof < numDof; idof++ ) { | |
688 | ✗ | for ( int icomp = 0; icomp < numComp; icomp++ ) { | |
689 | int iDofGlob; | ||
690 | ✗ | dof().loc2glob( ielSupportDof, idof, m_auxiliaryInts[0], icomp, iDofGlob); | |
691 | ✗ | AOApplicationToPetsc(m_ao, 1, &iDofGlob); | |
692 | ✗ | m_vecs.Get("normalField").setValue(iDofGlob, NN[idof][icomp], INSERT_VALUES); | |
693 | } | ||
694 | } | ||
695 | } | ||
696 | |||
697 | /***********************************************************************************/ | ||
698 | /***********************************************************************************/ | ||
699 | |||
700 | ✗ | void LinearProblemLinearElasticity::initFixedPointAcceleration() | |
701 | { | ||
702 | ✗ | m_accMethod = accelerationType(FelisceParam::instance(this->instanceIndex()).accelerationMethod); | |
703 | ✗ | m_omegaAcceleration = FelisceParam::instance(this->instanceIndex()).omegaAcceleration; | |
704 | ✗ | m_seqVecs.Init("x1"); | |
705 | ✗ | switch ( m_accMethod ) { | |
706 | ✗ | case FixedPoint: | |
707 | case Relaxation: | ||
708 | ✗ | break; | |
709 | ✗ | case Aitken: | |
710 | case IronsTuck: | ||
711 | ✗ | m_seqVecs.Init("x0"); | |
712 | ✗ | m_seqVecs.Init("fx0"); | |
713 | ✗ | m_seqVecs.Init("fx1"); | |
714 | ✗ | break; | |
715 | } | ||
716 | } | ||
717 | |||
718 | /***********************************************************************************/ | ||
719 | /***********************************************************************************/ | ||
720 | |||
721 | ✗ | void LinearProblemLinearElasticity::accelerationPreStep(PetscVector& seqCurrentInput) | |
722 | { | ||
723 | // pre and post with respect to reading the data at the interface | ||
724 | |||
725 | // method explanation in accelerationPostStep | ||
726 | ✗ | switch(m_accMethod) { | |
727 | ✗ | case FixedPoint: | |
728 | case Relaxation: | ||
729 | ✗ | break; | |
730 | ✗ | case Aitken: | |
731 | case IronsTuck: | ||
732 | // in these two cases we have to move forward x0 and x1 | ||
733 | ✗ | m_seqVecs.Get("x0" ).copyFrom(m_seqVecs.Get("x1" )); | |
734 | ✗ | m_seqVecs.Get("fx0").copyFrom(m_seqVecs.Get("fx1")); | |
735 | ✗ | break; | |
736 | } | ||
737 | // in any case we need to the save the current value of iop which was the last point | ||
738 | // where we have have evaluated the functional F. | ||
739 | ✗ | m_seqVecs.Get("x1").copyFrom(seqCurrentInput); | |
740 | // The following evaluation of the system will | ||
741 | // be saved in fx1 in the function acceleration | ||
742 | } | ||
743 | |||
744 | /***********************************************************************************/ | ||
745 | /***********************************************************************************/ | ||
746 | |||
747 | ✗ | void LinearProblemLinearElasticity::accelerationPostStep( PetscVector& seqCurrentInput, int nbOfCurrentIteration ) | |
748 | { | ||
749 | // We are solving a fixed point problem. | ||
750 | |||
751 | // here an example for IOPcouplModel: | ||
752 | // the input to the coupled system is currentiop | ||
753 | // then you solve NS you compute the displacement | ||
754 | // than you solve PF given the displacement and the current iop | ||
755 | // the solution of PF at the boarder is the outcome of function. | ||
756 | // P_interface = F ( currentIop ) | ||
757 | // an evaluation of F implies the solution of a NS pb + a PF pb. | ||
758 | // P_interface will be modified by this function and reused for a new iteration. | ||
759 | |||
760 | // Four (4) different methods: | ||
761 | // 0. fixed point iterations | ||
762 | // default method: we simly iterate F over the same value. | ||
763 | // new x1=fx1; | ||
764 | // 1. relaxation: | ||
765 | // new x1= w * fx1 + (1 - w) x1 | ||
766 | // w=1 ==> back to fixed point iterations | ||
767 | // 2. Aitken acceleration | ||
768 | // new x1= w * fx1 + (1 - w) x1, but w is a funcion of ( x0, fx0, x1, fx1 ) | ||
769 | // 3. Irons-Tuck: the same as Aitken, should be more "stable" | ||
770 | ✗ | switch(m_accMethod) { | |
771 | ✗ | case FixedPoint: | |
772 | case Relaxation: | ||
773 | // there is no need to save explicitly fx1 as done in aitken and irons tuck | ||
774 | // since it is stored in currentIop and it will be overridden with the correct value. | ||
775 | ✗ | break; | |
776 | ✗ | case Aitken: | |
777 | { | ||
778 | // at this point we just read the results from the PF problem | ||
779 | // this has been stored in the petscvec currentIop, since in a | ||
780 | // fixed point approach it is already the new input (new x1 = currentIop = fx1). | ||
781 | // in all the other approaches this is just the lates outcome | ||
782 | // of the F. | ||
783 | ✗ | m_seqVecs.Get("fx1").copyFrom( seqCurrentInput ); | |
784 | |||
785 | ✗ | if ( nbOfCurrentIteration == 1 /*first iteration: w=1*/ ) { | |
786 | ✗ | m_omegaAcceleration = 1; | |
787 | } else { | ||
788 | // we compute the value for the omega parameter | ||
789 | ✗ | m_seqVecs.Init("dx"); // map element initialization | |
790 | ✗ | m_seqVecs.Get("dx").duplicateFrom(m_seqVecs.Get("x1")); // structure of dx copied from x1 | |
791 | ✗ | m_seqVecs.Get("dx").copyFrom(m_seqVecs.Get("x1")); // dx = x1 | |
792 | ✗ | m_seqVecs.Get("dx").axpy(-1.,m_seqVecs.Get("x0")); // dx = x1 - x0 | |
793 | |||
794 | ✗ | m_seqVecs.Init("tmp"); // map element initialization | |
795 | ✗ | m_seqVecs.Get("tmp").duplicateFrom(m_seqVecs.Get("fx0")); // structure of tmp copied from fx0 | |
796 | ✗ | m_seqVecs.Get("tmp").copyFrom(m_seqVecs.Get("fx0")); // tmp = fx0 | |
797 | ✗ | m_seqVecs.Get("tmp").axpy(-1.,m_seqVecs.Get("fx1")); // tmp = fx0 - fx1 | |
798 | ✗ | m_seqVecs.Get("tmp").axpy(1.,m_seqVecs.Get("dx")); // tmp = fx0 - fx1 + x1 - x0 | |
799 | |||
800 | ✗ | const double omega = computeL2ScalarProduct("dx" ,"tmp"); | |
801 | ✗ | const double xxnorm = computeL2ScalarProduct("tmp","tmp"); | |
802 | ✗ | if ( Tools::equal( xxnorm, 0.0 ) ) | |
803 | ✗ | m_omegaAcceleration = 1; | |
804 | else | ||
805 | ✗ | m_omegaAcceleration = omega / xxnorm; | |
806 | |||
807 | // we destroy those auxiliary vectors | ||
808 | ✗ | m_seqVecs.Get("tmp").destroy(); | |
809 | ✗ | m_seqVecs.erase("tmp"); | |
810 | ✗ | m_seqVecs.Get("dx").destroy(); | |
811 | ✗ | m_seqVecs.erase("dx"); | |
812 | |||
813 | } | ||
814 | } | ||
815 | ✗ | break; | |
816 | ✗ | case IronsTuck: | |
817 | { | ||
818 | ✗ | m_seqVecs.Get("fx1").copyFrom(seqCurrentInput); | |
819 | |||
820 | ✗ | if ( nbOfCurrentIteration == 1 /*first iteration: w=1*/ ) { | |
821 | ✗ | m_omegaAcceleration = 1; | |
822 | } else { | ||
823 | |||
824 | // we compute the value for the omega parameter | ||
825 | ✗ | m_seqVecs.Init("d1"); // map element initialization | |
826 | ✗ | m_seqVecs.Get("d1").duplicateFrom(m_seqVecs.Get("x1")); // structure of d1 copied from x1 | |
827 | ✗ | m_seqVecs.Get("d1").copyFrom(m_seqVecs.Get("x1")); // d1 = x1 | |
828 | ✗ | m_seqVecs.Get("d1").axpy(-1.,m_seqVecs.Get("fx1")); // d1 = x1 - fx1 | |
829 | |||
830 | ✗ | m_seqVecs.Init("tmp"); // map element initialization | |
831 | ✗ | m_seqVecs.Get("tmp").duplicateFrom(m_seqVecs.Get("x0")); // structure of tmp copied from x0 | |
832 | ✗ | m_seqVecs.Get("tmp").copyFrom(m_seqVecs.Get("x0")); // tmp = x0 | |
833 | ✗ | m_seqVecs.Get("tmp").axpy(-1.,m_seqVecs.Get("fx0")); // tmp = x0 - fx0 | |
834 | ✗ | m_seqVecs.Get("tmp").axpy(-1.,m_seqVecs.Get("d1")); // tmp = x0 - fx0 - (x1 - fx1 ) | |
835 | |||
836 | ✗ | const double xxnorm ( computeL2ScalarProduct("tmp","tmp") ); | |
837 | ✗ | const double omega ( computeL2ScalarProduct("d1","tmp") ); | |
838 | ✗ | if ( Tools::equal( xxnorm, 0.0 ) ) { | |
839 | ✗ | m_omegaAcceleration = 1; | |
840 | } else { | ||
841 | ✗ | m_omegaAcceleration = ( 1 + omega / xxnorm ) * m_omegaAcceleration; | |
842 | } | ||
843 | |||
844 | // we destroy those auxiliary vectors | ||
845 | ✗ | m_seqVecs.Get("tmp").destroy(); | |
846 | ✗ | m_seqVecs.Get("d1").destroy(); | |
847 | ✗ | m_seqVecs.erase("d1"); | |
848 | ✗ | m_seqVecs.erase("tmp"); | |
849 | } | ||
850 | } | ||
851 | ✗ | break; | |
852 | } | ||
853 | |||
854 | ✗ | if ( FelisceParam::verbose() > 1 ) { | |
855 | ✗ | std::stringstream msg; | |
856 | ✗ | msg<<"----> using omega = "<<m_omegaAcceleration<<std::endl; | |
857 | ✗ | PetscPrintf(MpiInfo::petscComm(),"%s",msg.str().c_str()); | |
858 | } | ||
859 | |||
860 | //for the fixed point this step is not needed | ||
861 | ✗ | if ( m_accMethod != FixedPoint ) { | |
862 | ✗ | std::stringstream msg; | |
863 | ✗ | msg<<" updating fixed point input "<<std::endl; | |
864 | ✗ | PetscPrintf(MpiInfo::petscComm(),"%s",msg.str().c_str()); | |
865 | // update of currentIop, i.e. the new x1, the input for the next evaluation of F | ||
866 | ✗ | seqCurrentInput.axpby( 1. - m_omegaAcceleration, m_omegaAcceleration, m_seqVecs.Get("x1") ); | |
867 | } | ||
868 | } | ||
869 | |||
870 | /***********************************************************************************/ | ||
871 | /***********************************************************************************/ | ||
872 | |||
873 | ✗ | void LinearProblemLinearElasticity::sumOnBoundary(PetscVector& v, PetscVector& b, const DofBoundary& dofBD) | |
874 | { | ||
875 | ✗ | felInt numLocalDofInterface = dofBD.numLocalDofInterface(); | |
876 | ✗ | std::vector<double> tmp(numLocalDofInterface); | |
877 | ✗ | b.getValues(numLocalDofInterface, dofBD.loc2PetscVolPtr(), tmp.data() ); | |
878 | ✗ | v.setValues(numLocalDofInterface, dofBD.loc2PetscVolPtr(), tmp.data(),ADD_VALUES); | |
879 | ✗ | v.assembly(); | |
880 | } | ||
881 | |||
882 | /***********************************************************************************/ | ||
883 | /***********************************************************************************/ | ||
884 | |||
885 | #ifdef FELISCE_WITH_CVGRAPH | ||
886 | void | ||
887 | ✗ | LinearProblemLinearElasticity::cvgraphNaturalBC(felInt iel) { | |
888 | BoundaryCondition* BC; | ||
889 | // Loop over the cvgraph connections | ||
890 | ✗ | for ( std::size_t iConn(0); iConn<this->slave()->numConnections(); ++iConn ) { | |
891 | // Extract the labels of the current connection | ||
892 | ✗ | std::vector<int> labels = this->slave()->interfaceLabels(iConn); | |
893 | // Verify if the current label is part of the interface of this connection | ||
894 | ✗ | if ( std::find( labels.begin(), labels.end(), m_currentLabel ) != labels.end() ) { | |
895 | ✗ | switch ( this->slave()->numVarToRead(iConn) ) { | |
896 | ✗ | case 1: // only one var to read: neumann interface BC | |
897 | // Verify that we have to apply the stress in its strong form. | ||
898 | ✗ | if ( this->slave()->readVariable(iConn,/*cVar*/0) == "STRESS" && this->slave()->residualInterpolationType(iConn) == 0 ) { | |
899 | // Look through the different neumann conditions to find the correct one. | ||
900 | ✗ | for (std::size_t iNeumann=0; iNeumann<m_boundaryConditionList.numNeumannBoundaryCondition(); iNeumann++ ) { | |
901 | ✗ | BC = m_boundaryConditionList.Neumann(iNeumann);//get the the BC | |
902 | ✗ | if ( std::find( BC->listLabel().begin(), BC->listLabel().end(),m_currentLabel) != BC->listLabel().end() ) { | |
903 | //compute the force term. | ||
904 | ✗ | m_elemFieldNeumann[iNeumann].setValue( m_seqVecs.Get("cvgraphSTRESS"), *m_curvFe, iel, m_iDisplacement, m_ao, dof()); | |
905 | } | ||
906 | } | ||
907 | } | ||
908 | ✗ | break; | |
909 | ✗ | case 2: //two variables to read: robin interface BC | |
910 | // Look through the different robin conditions to find the correct one. | ||
911 | ✗ | for (std::size_t iRobin=0; iRobin<m_boundaryConditionList.numRobinBoundaryCondition(); iRobin++ ) { | |
912 | ✗ | BC = m_boundaryConditionList.Robin(iRobin); | |
913 | ✗ | if ( std::find( BC->listLabel().begin(), BC->listLabel().end(),m_currentLabel ) != BC->listLabel().end() ) { | |
914 | ✗ | if ( this->slave()->residualInterpolationType(iConn) == 0 ) { | |
915 | ✗ | m_elemFieldRobin[iRobin].setValue( m_seqVecs.Get("cvgraphSTRESS"), *m_curvFe , iel, m_iDisplacement, m_ao, dof()); | |
916 | } else { | ||
917 | ✗ | m_elemFieldRobin[iRobin].val *=0 ; | |
918 | } | ||
919 | ✗ | m_robinAux.setValue(m_seqVecs.Get("cvgraphDisplacement"),*m_curvFe, iel, m_iDisplacement, m_ao, dof()); | |
920 | ✗ | m_elemFieldRobin[iRobin].val += FelisceParam::instance().alphaRobin[iRobin]*m_robinAux.val; | |
921 | } | ||
922 | } | ||
923 | ✗ | break; | |
924 | ✗ | default: | |
925 | ✗ | FEL_ERROR("Three variables to read not yet implemented for this linear problem.") | |
926 | ✗ | break; | |
927 | } | ||
928 | } | ||
929 | } | ||
930 | } | ||
931 | #endif | ||
932 | } | ||
933 |