Skip to content

Commit 37ed8da

Browse files
committed
Initial pass at using linearly interpolated areas within the solver using the spatial characteristics. This is failing system tests so clearly there are issues. I have a few notes on things to check but mostly I just need to go back and verify all the locations where we're using the new data. If that isn't sufficient I might need to do some spot checks by outputing what the solver is seeing for those values.
1 parent 9d94aea commit 37ed8da

12 files changed

Lines changed: 231 additions & 159 deletions

Code/Source/cvOneDBFSolver.cxx

Lines changed: 47 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,15 @@ double cvOneDBFSolver::convCriteria = 0;
9595
BoundCondType cvOneDBFSolver::inletBCtype;
9696
int cvOneDBFSolver::ASCII = 1;
9797

98+
99+
namespace{
100+
101+
double linearInterpolate(double x, double x1, double y1, double x2, double y2) {
102+
return y1 + (x - x1) * (y2 - y1) / (x2 - x1);
103+
}
104+
105+
} // namespace
106+
98107
// SET MODE PTR
99108
void cvOneDBFSolver::SetModelPtr(cvOneDModel *mdl){
100109
model = mdl;
@@ -424,7 +433,6 @@ void cvOneDBFSolver::postprocess_VTK_XML3D_ONEFILE(){
424433
cvDoubleVec tmp;
425434
cvDoubleMat segNodeList;
426435
double lengthByNodes = 0.0;
427-
double lengthBySegment = 0.0;
428436
int startOut = 0;
429437
int finishOut = 0;
430438
double segLength = 0.0;
@@ -470,7 +478,6 @@ void cvOneDBFSolver::postprocess_VTK_XML3D_ONEFILE(){
470478
segVers[2][0] /= mod;
471479

472480
lengthByNodes = mod;
473-
lengthBySegment = currSeg->getSegmentLength();
474481

475482
// Compute Segment Local axis system
476483
evalSegmentLocalAxis(segVers);
@@ -484,8 +491,12 @@ void cvOneDBFSolver::postprocess_VTK_XML3D_ONEFILE(){
484491
currCentre[2] = nodeList[inletSegJoint][2] + loopEl*lengthByNodes/double(currSeg->getNumElements())*segVers[2][0];
485492

486493
// Get initial radius at current location
487-
currIniArea = currSeg->getInitInletS() + (loopEl/double(currSeg->getNumElements()))*(currSeg->getInitOutletS() - currSeg->getInitInletS());
488-
currIniRad = sqrt(currIniArea/M_PI);
494+
495+
// TODO: verify this is the correct "z" location we want
496+
// to interpolate at. These loops and myriad variables make
497+
// something super simple super confusing.
498+
double const zAxial = linearInterpolate(loopEl, 0, currSeg->getInletZ(), currSeg->getNumElements(), currSeg->getOutletZ());
499+
currIniRad = currSeg->getInitialRadius(zAxial);
489500

490501
// Loop on the subdivisions
491502
for(int loopSubdiv=0;loopSubdiv<circSubdiv;loopSubdiv++){
@@ -559,7 +570,14 @@ void cvOneDBFSolver::postprocess_VTK_XML3D_ONEFILE(){
559570
for(int j=startOut;j<finishOut;j+=2){
560571

561572
// Evaluate Initial Area at current location
562-
iniArea = currSeg->getInitInletS() + (((j-startOut)/2)/double(currSeg->getNumElements()))*(currSeg->getInitOutletS() - currSeg->getInitInletS());
573+
574+
// TODO: verify this is the correct "z" location we want
575+
// to interpolate at. These loops and myriad variables make
576+
// something super simple super confusing.
577+
double const zAxial = linearInterpolate((j-startOut)/2.0,
578+
startOut, currSeg->getInletZ(), finishOut, currSeg->getOutletZ());
579+
iniArea = currSeg->getInitialArea(zAxial);
580+
563581
// Eval Current Area at current location
564582
newArea = TotalSolution[loopTime][j];
565583
// Evaluate Radial displacement
@@ -738,7 +756,6 @@ void cvOneDBFSolver::postprocess_VTK_XML3D_MULTIPLEFILES(){
738756
cvDoubleVec tmp;
739757
cvDoubleMat segNodeList;
740758
double lengthByNodes = 0.0;
741-
double lengthBySegment = 0.0;
742759
int startOut = 0;
743760
int finishOut = 0;
744761
double segLength = 0.0;
@@ -812,7 +829,6 @@ void cvOneDBFSolver::postprocess_VTK_XML3D_MULTIPLEFILES(){
812829
segVers[2][0] /= mod;
813830

814831
lengthByNodes = mod;
815-
lengthBySegment = currSeg->getSegmentLength();
816832

817833
// Compute Segment Local axis system
818834
evalSegmentLocalAxis(segVers);
@@ -826,9 +842,13 @@ void cvOneDBFSolver::postprocess_VTK_XML3D_MULTIPLEFILES(){
826842
currCentre[2] = nodeList[inletSegJoint][2] + loopEl*lengthByNodes/double(currSeg->getNumElements())*segVers[2][0];
827843

828844
// Get initial radius at current location
829-
currIniArea = currSeg->getInitInletS() + (loopEl/double(currSeg->getNumElements()))*(currSeg->getInitOutletS() - currSeg->getInitInletS());
830-
currIniRad = sqrt(currIniArea/M_PI);
831-
845+
846+
// TODO: verify this is the correct "z" location we want
847+
// to interpolate at. These loops and myriad variables make
848+
// something super simple super confusing.
849+
double const zAxial = linearInterpolate(loopEl, 0, currSeg->getInletZ(), currSeg->getNumElements(), currSeg->getOutletZ());
850+
currIniRad = currSeg->getInitialRadius(zAxial);
851+
832852
// Loop on the subdivisions
833853
for(int loopSubdiv=0;loopSubdiv<circSubdiv;loopSubdiv++){
834854
currTheta = loopSubdiv*2*M_PI/double(circSubdiv);
@@ -899,7 +919,14 @@ void cvOneDBFSolver::postprocess_VTK_XML3D_MULTIPLEFILES(){
899919
for(int j=startOut;j<finishOut;j+=2){
900920

901921
// Evaluate Initial Area at current location
902-
iniArea = currSeg->getInitInletS() + (((j-startOut)/2)/double(currSeg->getNumElements()))*(currSeg->getInitOutletS() - currSeg->getInitInletS());
922+
923+
// TODO: verify this is the correct "z" location we want
924+
// to interpolate at. These loops and myriad variables make
925+
// something super simple super confusing.
926+
double const zAxial = linearInterpolate((j-startOut)/2.0,
927+
startOut, currSeg->getInletZ(), finishOut, currSeg->getOutletZ());
928+
iniArea = currSeg->getInitialArea(zAxial);
929+
903930
// Eval Current Area at current location
904931
newArea = TotalSolution[loopTime][j];
905932
// Evaluate Radial displacement
@@ -1124,19 +1151,15 @@ void cvOneDBFSolver::QuerryModelInformation(void)
11241151
for (i=0; i<is; i++){
11251152
cvOneDSegment* seg = model->getSegment(i);
11261153
long nels = seg->getNumElements();
1127-
double segLen = seg->getSegmentLength();
11281154
int matID = seg->getMaterialID();
11291155
MeshType mType = seg->getMeshType();
1130-
double zin = seg->getInletZ();
1131-
double zout = seg->getOutletZ();
11321156

11331157
cvOneDSubdomain* subdomain = new cvOneDSubdomain;
11341158
assert(subdomain != 0);
11351159
subdomain -> SetNumberOfNodes(nels+1);
11361160
subdomain -> SetNumberOfElements(nels);
11371161
subdomain -> SetMeshType(mType);
1138-
subdomain -> Init(zin, zout);
1139-
1162+
subdomain -> Init(seg->getSpatialCharacteristics());
11401163

11411164
// Get the Initial Properties of the subdomain...
11421165
double Qo = 0.0;
@@ -1147,17 +1170,13 @@ void cvOneDBFSolver::QuerryModelInformation(void)
11471170
P0 = seg->getInitialPressure();
11481171
dQ0_dT = 0.0;
11491172
}
1150-
double So = seg->getInitInletS();
1151-
double Sn = seg->getInitOutletS();
11521173
BoundCondType boundT = seg -> getBoundCondition();
11531174
double boundV= seg -> getBoundValue();
11541175

11551176
// Set these in the subdomain.
11561177
subdomain->SetInitialFlow(Qo);
11571178
subdomain->SetInitialdFlowdT(dQ0_dT);
1158-
subdomain->SetInitInletS(So);
11591179
subdomain->SetInitialPressure(P0);
1160-
subdomain->SetInitOutletS(Sn);
11611180
subdomain->SetGlobal1stNodeID(temp);
11621181
subdomain->SetBoundCondition(boundT);
11631182
if(!seg->IsOutlet){
@@ -1324,22 +1343,21 @@ void cvOneDBFSolver::CreateGlobalArrays(void){
13241343

13251344
// Initialize the solution, that is, area as area input and flow rate as 0 except the inlet
13261345
void cvOneDBFSolver::CalcInitProps(long ID){
1327-
double segLen = subdomainList[ID] -> GetLength();
13281346
double Qo, dQ0dT;
1329-
Qo = subdomainList[ID] -> GetInitialFlow();
1347+
auto const& subdomain = subdomainList[ID];
1348+
Qo = subdomain -> GetInitialFlow();
13301349
dQ0dT=0;
13311350

1332-
double So = subdomainList[ID] -> GetInitInletS();
1333-
double Sn = subdomainList[ID] -> GetInitOutletS();
1334-
for( long node = 0; node < subdomainList[ID]->GetNumberOfNodes(); node++){
1335-
double zn = subdomainList[ID]->GetNodalCoordinate( node);
1351+
for( long node = 0; node < subdomain->GetNumberOfNodes(); node++){
1352+
double zn = subdomain->GetNodalCoordinate( node);
13361353
long eqNumbers[2];
13371354
mathModels[0]->GetNodalEquationNumbers(node, eqNumbers, ID);
13381355

13391356
// Linear Interpolation
1340-
double zi = (zn - segLen)/(0.0-segLen);
1341-
double Si = (zi*(So - Sn)) + Sn;
1342-
(*previousSolution)[eqNumbers[0]] = Si;
1357+
// This is "Si"
1358+
// TODO: verify this calcluation makes sense
1359+
double initialAreaAtZn = getInterpolatedArea(zn, subdomain->getSpatialCharacteristics());
1360+
(*previousSolution)[eqNumbers[0]] = initialAreaAtZn;
13431361

13441362
if(node == 0){
13451363
(*previousSolution)[eqNumbers[1]] = Qo;

Code/Source/cvOneDMaterial.h

Lines changed: 52 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,34 @@
1-
/* Copyright (c) Stanford University, The Regents of the University of
2-
* California, and others.
3-
*
4-
* All Rights Reserved.
5-
*
6-
* See Copyright-SimVascular.txt for additional details.
7-
*
8-
* Permission is hereby granted, free of charge, to any person obtaining
9-
* a copy of this software and associated documentation files (the
10-
* "Software"), to deal in the Software without restriction, including
11-
* without limitation the rights to use, copy, modify, merge, publish,
12-
* distribute, sublicense, and/or sell copies of the Software, and to
13-
* permit persons to whom the Software is furnished to do so, subject
14-
* to the following conditions:
15-
*
16-
* The above copyright notice and this permission notice shall be included
17-
* in all copies or substantial portions of the Software.
18-
*
19-
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20-
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21-
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
22-
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
23-
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24-
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25-
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26-
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27-
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28-
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29-
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30-
*/
31-
1+
/* Copyright (c) Stanford University, The Regents of the University of
2+
* California, and others.
3+
*
4+
* All Rights Reserved.
5+
*
6+
* See Copyright-SimVascular.txt for additional details.
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining
9+
* a copy of this software and associated documentation files (the
10+
* "Software"), to deal in the Software without restriction, including
11+
* without limitation the rights to use, copy, modify, merge, publish,
12+
* distribute, sublicense, and/or sell copies of the Software, and to
13+
* permit persons to whom the Software is furnished to do so, subject
14+
* to the following conditions:
15+
*
16+
* The above copyright notice and this permission notice shall be included
17+
* in all copies or substantial portions of the Software.
18+
*
19+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20+
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21+
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
22+
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
23+
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24+
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25+
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26+
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27+
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28+
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30+
*/
31+
3232
#ifndef CVONEDMATERIAL_H
3333
#define CVONEDMATERIAL_H
3434

@@ -38,8 +38,10 @@
3838
// This class maintains Material Properties of the subdomain.
3939
//
4040

41-
# include "cvOneDEnums.h"
42-
# include <math.h>
41+
#include "cvOneDEnums.h"
42+
#include "cvOneDSegmentSpatialCharacteristics.h"
43+
44+
#include <math.h>
4345

4446
class cvOneDMaterial{
4547

@@ -82,16 +84,27 @@ class cvOneDMaterial{
8284
virtual double GetProperty(char* what) const = 0;
8385
virtual double GetIntegralpS (double area, double z) const = 0;
8486

85-
86-
virtual double GetN(double S) const = 0;//not really dependent on S actually IV 080703
87+
88+
virtual double GetN(double S) const = 0;//not really dependent on S actually IV 080703
8789
virtual double GetEHR(double z) const = 0;
88-
90+
8991
virtual double GetOutflowFunction(double pressure, double z) const = 0;
9092
virtual double GetDpDz(double area, double z) const = 0;
9193
virtual double GetDOutflowDp(double pressure, double z) const = 0;
9294
virtual double GetIntegralpD2S (double area, double z) const = 0;
9395
virtual void SetPeriod(double period) = 0;
94-
virtual void SetAreas_and_length(double S_top, double S_bottom, double z) = 0;
96+
97+
// Technically speaking, this doesnt at all belong in "material"...
98+
// but for now, we'll keep it here, since there was already
99+
// an odd coupling to the spatial characteristics.
100+
void SetSpatialCharacteristics(cvOneD::SegmentSpatialCharacteristics const& in){ spatialCharacteristics = in; };
101+
102+
// Computes the initial radius at the z location based on the spatial
103+
// characteristics. Again, doesn't really belong here...
104+
double Getr1(double z) const{
105+
// linearly interpolated r
106+
return cvOneD::getInterpolatedRadius(z, spatialCharacteristics);
107+
}
95108

96109
double GetProfileExponent() const {return profile_exponent;}
97110
double GetDensity() const {return density;}
@@ -112,6 +125,8 @@ class cvOneDMaterial{
112125

113126
protected:
114127

128+
cvOneD::SegmentSpatialCharacteristics spatialCharacteristics;
129+
115130
double density;
116131
double dynamicViscosity;
117132
double kinematicViscosity;

Code/Source/cvOneDMaterialLinear.cxx

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -115,27 +115,12 @@ double cvOneDMaterialLinear::GetEHR(double z)const{
115115
return ehr;
116116
}
117117

118-
void cvOneDMaterialLinear::SetAreas_and_length(double S_top,double S_bottom,double z){
119-
Stop = S_top;//inlet
120-
Sbot = S_bottom;//outlet
121-
len = z;
122-
}
123-
124118
double cvOneDMaterialLinear::GetS1(double z)const{
125119
double r = Getr1(z);
126120
double area = r*r*M_PI;
127121
return area;
128122
}
129123

130-
double cvOneDMaterialLinear::Getr1(double z)const{
131-
// Linearly interpolated r
132-
double r_top = sqrt(Stop/M_PI);
133-
double r_bot = sqrt(Sbot/M_PI);
134-
double r = ((z-len)/(-len))*(r_top - r_bot) + r_bot;
135-
136-
return r;
137-
}
138-
139124
double cvOneDMaterialLinear::GetDS1Dz(double z)const{
140125
// Since vessel geometry will always be linear in
141126
// space, this is just a constant

Code/Source/cvOneDMaterialLinear.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ class cvOneDMaterialLinear:public cvOneDMaterial{
8585
double PP1_;
8686

8787
double GetS1( double z) const;
88-
double Getr1( double z) const;
8988
double GetDS1Dz( double z) const;
9089
double GetDr1Dz(double z) const;
9190
};

Code/Source/cvOneDMaterialOlufsen.cxx

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -151,16 +151,6 @@ double cvOneDMaterialOlufsen::GetS1(double z)const{
151151
return area; // slightly increased pressure/decreased area
152152
}
153153

154-
double cvOneDMaterialOlufsen::Getr1(double z)const{
155-
// linearly interpolated r
156-
double r_top=sqrt(Stop/PI);
157-
double r_bot=sqrt(Sbot/PI);
158-
double r=((z-len)/(-len))*(r_top - r_bot) + r_bot;
159-
160-
161-
return r;
162-
}
163-
164154
double cvOneDMaterialOlufsen::GetDS1Dz(double z)const{
165155
double drdz=GetDr1Dz(z) ;
166156
double dsdr= 2.0*PI*Getr1(z);

0 commit comments

Comments
 (0)