GCC Code Coverage Report


Directory: ./
File: Solver/linearProblemBidomainTransMemb.cpp
Date: 2024-04-14 07:32:34
Exec Total Coverage
Lines: 0 97 0.0%
Branches: 0 146 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: E. Schenone C. Corrado
13 //
14
15 // System includes
16
17 // External includes
18
19 // Project includes
20 #include "Solver/linearProblemBidomainTransMemb.hpp"
21 #include "InputOutput/io.hpp"
22 #include "FiniteElement/elementMatrix.hpp"
23
24 namespace felisce {
25 LinearProblemBidomainTransMemb::LinearProblemBidomainTransMemb():
26 LinearProblem("Problem cardiac Bidomain first equation",3),
27 m_fePotTransMemb(nullptr),
28 m_fePotTransMembCurv(nullptr),
29 m_bdf(nullptr),
30 m_fiber(nullptr),
31 m_angleFiber(nullptr),
32 m_endocardiumDistance(nullptr) {
33 if(FelisceParam::instance().monodomain)
34 this->setNumberOfMatrix(2);
35
36 }
37
38 LinearProblemBidomainTransMemb::~LinearProblemBidomainTransMemb() {
39 m_fstransient = nullptr;
40 m_fePotTransMemb = nullptr;
41 m_fePotTransMembCurv = nullptr;
42 m_bdf = nullptr;
43 if (m_fiber)
44 delete [] m_fiber;
45 if (m_angleFiber)
46 delete [] m_angleFiber;
47 if (m_endocardiumDistance)
48 delete [] m_endocardiumDistance;
49 }
50
51 void LinearProblemBidomainTransMemb::initialize(std::vector<GeometricMeshRegion::Pointer>& mesh, FelisceTransient::Pointer fstransient, MPI_Comm& comm, bool doUseSNES) {
52 LinearProblem::initialize(mesh,comm, doUseSNES);
53 m_fstransient = fstransient;
54 std::vector<PhysicalVariable> listVariable(1);
55 std::vector<std::size_t> listNumComp(1);
56
57 listVariable[0] = potTransMemb;
58 listNumComp[0] = 1;
59
60 //define unknown of the linear system.
61 m_listUnknown.push_back(potTransMemb);
62
63 definePhysicalVariable(listVariable,listNumComp);
64 }
65
66 void LinearProblemBidomainTransMemb::readData(IO& io) {
67 // Read fibers file (*.00000.vct)
68 m_fiber = new double[m_mesh[m_currentMesh]->numPoints()*3];
69 io.readVariable(0, 0.,m_fiber, m_mesh[m_currentMesh]->numPoints()*3);
70 if (FelisceParam::instance().hasCoupledAtriaVent) {
71 m_angleFiber = new double[m_numDof];
72 io.readVariable(2, 0.,m_angleFiber, m_numDof);
73 }
74 // Read distance from endocardium file for Zygote geometry (*.00000.scl)
75 if ( (FelisceParam::instance().typeOfAppliedCurrent == "zygote") || (FelisceParam::instance().typeOfAppliedCurrent == "zygoteImproved") || (FelisceParam::instance().typeOfAppliedCurrent == "heart") || (FelisceParam::instance().typeOfAppliedCurrent == "ellipseheart") ) {
76 m_endocardiumDistance = new double[m_numDof];
77 io.readVariable(1, 0.,m_endocardiumDistance, m_numDof);
78 }
79 }
80 void LinearProblemBidomainTransMemb::getFiberDirection(felInt iel, int iUnknown, std::vector<double>& elemFiber) {
81 int numSupport = static_cast<int>(supportDofUnknown(iUnknown).iEle()[iel+1] - supportDofUnknown(iUnknown).iEle()[iel]);
82 elemFiber.resize( numSupport*3,0.);
83 for (int i = 0; i < numSupport; i++) {
84 elemFiber[i*3] = m_fiber[3*(supportDofUnknown(iUnknown).iSupportDof()[supportDofUnknown(iUnknown).iEle()[iel]+i])];
85 elemFiber[i*3+1] = m_fiber[3*(supportDofUnknown(iUnknown).iSupportDof()[supportDofUnknown(iUnknown).iEle()[iel]+i])+1];
86 elemFiber[i*3+2] = m_fiber[3*(supportDofUnknown(iUnknown).iSupportDof()[supportDofUnknown(iUnknown).iEle()[iel]+i])+2];
87 }
88 }
89
90 void LinearProblemBidomainTransMemb::getAngleFiber(felInt iel, int iUnknown, std::vector<double>& elemAngle) {
91 int numSupport = static_cast<int>(supportDofUnknown(iUnknown).iEle()[iel+1] - supportDofUnknown(iUnknown).iEle()[iel]);
92 elemAngle.resize(numSupport,0.);
93 for (int i = 0; i < numSupport; i++) {
94 elemAngle[i] = m_angleFiber[(supportDofUnknown(iUnknown).iSupportDof()[supportDofUnknown(iUnknown).iEle()[iel]+i])];
95 }
96 }
97
98 void LinearProblemBidomainTransMemb::initPerElementType(ElementType eltType, FlagMatrixRHS flagMatrixRHS) {
99 IGNORE_UNUSED_ELT_TYPE;
100 IGNORE_UNUSED_FLAG_MATRIX_RHS;
101 //Init pointer on Finite Element, Variable or idVariable
102 m_ipotTransMemb = m_listVariable.getVariableIdList(potTransMemb);
103 m_fePotTransMemb = m_listCurrentFiniteElement[m_ipotTransMemb];
104 }
105
106 void LinearProblemBidomainTransMemb::computeElementArray(const std::vector<Point*>& elemPoint, const std::vector<felInt>& elemIdPoint, felInt& iel, FlagMatrixRHS flagMatrixRHS) {
107 IGNORE_UNUSED_FLAG_MATRIX_RHS;
108 IGNORE_UNUSED_ELEM_ID_POINT;
109 m_fePotTransMemb->updateMeasQuadPt(0, elemPoint);
110 m_fePotTransMemb->updateFirstDeriv(0, elemPoint);
111 std::vector<double> elemFiber;
112 getFiberDirection(iel,m_ipotTransMemb, elemFiber);
113
114 //Bdf coeff not initialized at iteration 0, so need to be added to matrix(at)first iteration.
115 double coefTime = 1./m_fstransient->timeStep;
116 double coefAm = FelisceParam::instance().Am;
117 double coefCm = FelisceParam::instance().Cm;
118 double coef = m_bdf->coeffDeriv0()*coefTime*coefAm*coefCm;
119 //1st equation : Am*C*/dT V_m
120 m_elementMat[0]->phi_i_phi_j(coef,*m_fePotTransMemb,0,0,1);
121
122 //1st equation : \sigma_i^t \grad V_m
123 m_elementMat[0]->grad_phi_i_grad_phi_j(FelisceParam::instance().intraTransvTensor,*m_fePotTransMemb,0,0,1);
124
125 //1st equation : (\sigma_i^l-\sigma_i^t) a vec a \grad V_m
126 m_elementMat[0]->tau_grad_phi_i_tau_grad_phi_j(FelisceParam::instance().intraFiberTensor-FelisceParam::instance().intraTransvTensor,elemFiber,*m_fePotTransMemb,0,0,1);
127
128 //1st equation RHS1 : mass RHS
129 m_elementMat[1]->phi_i_phi_j(1.,*m_fePotTransMemb,0,0,1);
130
131 if(!FelisceParam::instance().monodomain) {
132 //1st equation RHS2 : - \sigma_i^t \grad u_e
133 m_elementMat[2]->grad_phi_i_grad_phi_j(-1.*(FelisceParam::instance().intraTransvTensor),*m_fePotTransMemb,0,0,1);
134
135 //1st equation RHS2 : - (\sigma_i^l-\sigma_i^t) a vec a \grad u_e
136 m_elementMat[2]->tau_grad_phi_i_tau_grad_phi_j(-1.*(FelisceParam::instance().intraFiberTensor-FelisceParam::instance().intraTransvTensor),elemFiber,*m_fePotTransMemb,0,0,1);
137 }
138
139 }
140
141
142 void LinearProblemBidomainTransMemb::computeElementArrayBoundaryCondition(const std::vector<Point*>& elemPoint, const std::vector<felInt>& elemIdPoint, felInt& iel, FlagMatrixRHS flagMatrixRHS) {
143 IGNORE_UNUSED_FLAG_MATRIX_RHS;
144 IGNORE_UNUSED_ELEM_ID_POINT;;
145 m_ipotTransMemb = m_listVariable.getVariableIdList(potTransMemb);
146 m_fePotTransMembCurv = m_listCurvilinearFiniteElement[m_ipotTransMemb];
147
148 m_fePotTransMembCurv->updateMeasNormalContra(0, elemPoint);
149
150
151 if ((m_currentLabel >= 30) && (m_currentLabel <= 40)) {
152 std::vector<double> elemAngle;
153 getAngleFiber(iel,m_ipotTransMemb,elemAngle);
154
155 std::vector<double> elemFiber;
156 getFiberDirection(iel,m_ipotTransMemb,elemFiber);
157
158 // Constant angle
159 //double angle = acos(0.0)/2.0;
160
161 // Assembling matrix(0)
162 double coefTime = 1./m_fstransient->timeStep;
163 double coefAm = FelisceParam::instance().Am;
164 double coefCm = FelisceParam::instance().Cm;
165 double coef = m_bdf->coeffDeriv0()*coefTime*coefAm*coefCm;
166
167 //1st equation : Am*Cm/dt V_m
168 m_elementMatBD[0]->phi_i_phi_j(coef,*m_fePotTransMembCurv,0,0,1);
169
170 //1st equation : \sigma_i^t \grad V_m
171 if (m_currentLabel < 40) { // regular atrial myocardium
172 m_elementMatBD[0]->grad_phi_i_grad_phi_j(FelisceParam::instance().intraTransvTensorAtria,*m_fePotTransMembCurv,0,0,1);
173 m_elementMatBD[0]->tau_orthotau_grad_phi_i_grad_phi_j((FelisceParam::instance().intraFiberTensorAtria - FelisceParam::instance().intraTransvTensorAtria),elemFiber,elemAngle,*m_fePotTransMembCurv,0,0,1);
174 }
175
176
177 //Assembling matrix(1) = mass (only first quadrant if hasAppliedExteriorCurrent = false)
178 //1st equation RHS1 : mass RHS
179 m_elementMatBD[1]->phi_i_phi_j(1.,*m_fePotTransMembCurv,0,0,1);
180
181 if(!FelisceParam::instance().monodomain) {
182 //1st equation RHS2 : - \sigma_i^t \grad u_e
183 if (m_currentLabel < 40) { // regular atrial myocardium
184 m_elementMatBD[2]->grad_phi_i_grad_phi_j(-1.0*(FelisceParam::instance().intraTransvTensorAtria),*m_fePotTransMembCurv,0,0,1);
185 m_elementMatBD[2]->tau_orthotau_grad_phi_i_grad_phi_j(-1.0*(FelisceParam::instance().intraFiberTensorAtria - FelisceParam::instance().intraTransvTensorAtria),elemFiber,elemAngle,*m_fePotTransMembCurv,0,0,1);
186 }
187 }
188 }
189 }
190
191 void LinearProblemBidomainTransMemb::addMatrixRHS() {
192 // _RHS = m_mass * m_massRHS
193 mult(matrix(1),m_massRHS,vector());
194
195 if(!FelisceParam::instance().monodomain) {
196 // _RHS = _RHS + _Ksigmai * _KsigmaiRHS
197 multAdd(matrix(2),_KsigmaiRHS,vector(),vector());
198 }
199
200 m_massRHS.zeroEntries();
201 _KsigmaiRHS.zeroEntries();
202 }
203
204 }
205