Chaste  Build::
MicrovesselSolver.cpp
1 /*
2 
3 Copyright (c) 2005-2016, University of Oxford.
4  All rights reserved.
5 
6  University of Oxford means the Chancellor, Masters and Scholars of the
7  University of Oxford, having an administrative office at Wellington
8  Square, Oxford OX1 2JD, UK.
9 
10  This file is part of Chaste.
11 
12  Redistribution and use in source and binary forms, with or without
13  modification, are permitted provided that the following conditions are met:
14  * Redistributions of source code must retain the above copyright notice,
15  this list of conditions and the following disclaimer.
16  * Redistributions in binary form must reproduce the above copyright notice,
17  this list of conditions and the following disclaimer in the documentation
18  and/or other materials provided with the distribution.
19  * Neither the name of the University of Oxford nor the names of its
20  contributors may be used to endorse or promote products derived from this
21  software without specific prior written permission.
22 
23  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 
34  */
35 
36 #include <boost/lexical_cast.hpp>
37 #include "UblasIncludes.hpp"
38 #include "VesselSegment.hpp"
39 #include "VesselNode.hpp"
40 #include "MicrovesselSolver.hpp"
41 #include "VesselNetworkWriter.hpp"
42 #include "SolutionDependentDiscreteSource.hpp"
43 
44 template<unsigned DIM>
46  mpNetwork(),
47  mOutputFrequency(1),
48  mpOutputFileHandler(),
49  mDiscreteContinuumSolvers(),
50  mpStructuralAdaptationSolver(),
51  mpAngiogenesisSolver(),
52  mpRegressionSolver(),
53  mDiscreteContinuumSolversHaveCompatibleGridIndexing(false),
54  mUpdatePdeEachSolve(true)
55 {
56 
57 }
58 
59 template<unsigned DIM>
61 {
62 
63 }
64 
65 template<unsigned DIM>
66 boost::shared_ptr<MicrovesselSolver<DIM> > MicrovesselSolver<DIM>::Create()
67 {
68  MAKE_PTR(MicrovesselSolver<DIM>, pSelf);
69  return pSelf;
70 }
71 
72 template<unsigned DIM>
74 {
75  mpNetwork = pNetwork;
76 }
77 
78 template<unsigned DIM>
80 {
81  mUpdatePdeEachSolve = doUpdate;
82 }
83 
84 template<unsigned DIM>
86 {
87  mDiscreteContinuumSolvers.push_back(pDiscreteContinuumSolver);
88 }
89 
90 template<unsigned DIM>
91 std::vector<boost::shared_ptr<AbstractDiscreteContinuumSolver<DIM> > > MicrovesselSolver<DIM>::GetDiscreteContinuumSolvers()
92 {
94 }
95 template<unsigned DIM>
97 {
98  unsigned num_steps = SimulationTime::Instance()->GetTimeStepsElapsed();
99 
100  // If there is a structural adaptation or flow problem solve it
101  std::cout << "ADAPT_IN****" << std::endl;
103  {
104  mpStructuralAdaptationSolver->UpdateFlowSolver(true);
106  }
107  std::cout << "ADAPT_OUT****" << std::endl;
108 
109  // If there are PDEs solve them
110  if(mDiscreteContinuumSolvers.size()>0)
111  {
112  for(unsigned idx=0; idx<mDiscreteContinuumSolvers.size(); idx++)
113  {
114  if(num_steps>0 and !mUpdatePdeEachSolve)
115  {
116  break;
117  }
118 
119  mDiscreteContinuumSolvers[idx]->Update();
120  mDiscreteContinuumSolvers[idx]->SetFileName("/" + mDiscreteContinuumSolvers[idx]->GetLabel() +"_solution_" + boost::lexical_cast<std::string>(num_steps));
121 
122  // Transfer PDE solutions for coupled problems
123  if(idx>0 and mDiscreteContinuumSolvers[idx]->GetPde())
124  {
125  for(unsigned jdx=0; jdx<mDiscreteContinuumSolvers[idx]->GetPde()->GetDiscreteSources().size(); jdx++)
126  {
127  boost::shared_ptr<SolutionDependentDiscreteSource<DIM> > p_solution_dep_source =
128  boost::dynamic_pointer_cast<SolutionDependentDiscreteSource<DIM> >(mDiscreteContinuumSolvers[idx]->GetPde()->GetDiscreteSources()[jdx]);
129  if(p_solution_dep_source)
130  {
132  {
133  p_solution_dep_source->SetSolution(mDiscreteContinuumSolvers[idx-1]->GetConcentrations());
134  }
135  else
136  {
137  EXCEPTION("Solution dependent PDEs only work with compatible grids at the moment.");
138  }
139  }
140  }
141  }
142 
143  if(mOutputFrequency > 0 && num_steps % mOutputFrequency == 0)
144  {
145  mDiscreteContinuumSolvers[idx]->SetWriteSolution(true);
146  }
147  else
148  {
149  mDiscreteContinuumSolvers[idx]->SetWriteSolution(false);
150  }
151  mDiscreteContinuumSolvers[idx]->Solve();
152  }
153  }
154 
155  // Do angiogenesis if the is a network and solver
156  if(this->mpNetwork && mpAngiogenesisSolver)
157  {
158  mpAngiogenesisSolver->Increment();
159  }
160 
161  // Do regression if the is a network and solver
162  if(this->mpNetwork && mpRegressionSolver)
163  {
164  mpRegressionSolver->Increment();
165  }
166 
167  // Manage vessel network output
168  if (this->mpNetwork)
169  {
170  mpNetwork->UpdateAll();
171  if (mOutputFrequency > 0 && num_steps % mOutputFrequency == 0)
172  {
173  boost::shared_ptr<VesselNetworkWriter<DIM> > p_network_writer = VesselNetworkWriter<DIM>::Create();
174  p_network_writer->SetVesselNetwork(mpNetwork);
175  p_network_writer->SetFileName(
176  mpOutputFileHandler->GetOutputDirectoryFullPath() + "/VesselNetwork_inc_"
177  + boost::lexical_cast<std::string>(num_steps + 1) + ".vtp");
178  p_network_writer->Write();
179  }
180  }
181 }
182 
183 template<unsigned DIM>
185 {
186  if (this->mpNetwork)
187  {
188  boost::shared_ptr<VesselNetworkWriter<DIM> > p_network_writer = VesselNetworkWriter<DIM>::Create();
189  mpNetwork->UpdateAll(true);
190  p_network_writer->SetVesselNetwork(mpNetwork);
191  p_network_writer->SetFileName(mpOutputFileHandler->GetOutputDirectoryFullPath() + "/VesselNetwork_inc_0.vtp");
192  p_network_writer->Write();
193  }
194 
195  Setup();
196 
197  while (!SimulationTime::Instance()->IsFinished())
198  {
199  Increment();
200  SimulationTime::Instance()->IncrementTimeOneStep();
201  }
202 }
203 
204 template<unsigned DIM>
205 void MicrovesselSolver<DIM>::SetAngiogenesisSolver(boost::shared_ptr<AngiogenesisSolver<DIM> > pAngiogenesisSolver)
206 {
207  mpAngiogenesisSolver = pAngiogenesisSolver;
208 }
209 
210 template<unsigned DIM>
211 void MicrovesselSolver<DIM>::SetOutputFileHandler(boost::shared_ptr<OutputFileHandler> pFileHandler)
212 {
213  mpOutputFileHandler = pFileHandler;
214 }
215 
216 template<unsigned DIM>
218 {
219  mOutputFrequency = frequency;
220 }
221 
222 template<unsigned DIM>
223 void MicrovesselSolver<DIM>::SetupFromModifier(AbstractCellPopulation<DIM,DIM>& rCellPopulation,
224  units::quantity<unit::length> cellReferenceLength,
225  units::quantity<unit::concentration> cellReferenceConcentration,
226  const std::string& rDirectory)
227 {
228  // Set up an output file handler
229  mpOutputFileHandler = boost::shared_ptr<OutputFileHandler>(new OutputFileHandler(rDirectory, false));
230 
231  // Set up all the DiscreteContinuum solvers
232  for(unsigned idx=0; idx<mDiscreteContinuumSolvers.size(); idx++)
233  {
234  mDiscreteContinuumSolvers[idx]->SetCellPopulation(rCellPopulation, cellReferenceLength, cellReferenceConcentration);
235  mDiscreteContinuumSolvers[idx]->SetFileHandler(mpOutputFileHandler);
236  if(mpNetwork)
237  {
238  mDiscreteContinuumSolvers[idx]->SetVesselNetwork(mpNetwork);
239  }
240  mDiscreteContinuumSolvers[idx]->Setup();
241  }
242 
243  Setup();
244 }
245 
246 template<unsigned DIM>
248 {
250 }
251 
252 template<unsigned DIM>
254 {
255  // Set up all the DiscreteContinuum solvers
256  for(unsigned idx=0; idx<mDiscreteContinuumSolvers.size(); idx++)
257  {
258  mDiscreteContinuumSolvers[idx]->SetFileHandler(mpOutputFileHandler);
259  if(mpNetwork)
260  {
261  mDiscreteContinuumSolvers[idx]->SetVesselNetwork(mpNetwork);
262  }
263  mDiscreteContinuumSolvers[idx]->Setup();
264  }
265 
266  // Set up the flow and structural adaptation solvers
268  {
269  mpStructuralAdaptationSolver->SetVesselNetwork(mpNetwork);
270  }
271 
273  {
274  mpRegressionSolver->SetVesselNetwork(mpNetwork);
275  }
276 }
277 
278 template<unsigned DIM>
280 {
281  mpStructuralAdaptationSolver = pStructuralAdaptationSolver;
282 }
283 
284 template<unsigned DIM>
285 void MicrovesselSolver<DIM>::UpdateCellData(std::vector<std::string> labels)
286 {
287  if(labels.size()==0)
288  {
289  //update everything
290  for(unsigned jdx=0; jdx<mDiscreteContinuumSolvers.size(); jdx++)
291  {
292  mDiscreteContinuumSolvers[jdx]->UpdateCellData();
293  }
294  }
295 
296  for(unsigned idx=0; idx<labels.size(); idx++)
297  {
298  for(unsigned jdx=0; jdx<mDiscreteContinuumSolvers.size(); jdx++)
299  {
300  if(labels[idx]==mDiscreteContinuumSolvers[idx]->GetLabel())
301  {
302  mDiscreteContinuumSolvers[jdx]->UpdateCellData();
303  }
304  }
305  }
306 }
307 
308 template<unsigned DIM>
309 void MicrovesselSolver<DIM>::SetRegressionSolver(boost::shared_ptr<RegressionSolver<DIM> > pRegressionSolver)
310 {
311  mpRegressionSolver = pRegressionSolver;
312 }
313 
314 // Explicit instantiation
315 template class MicrovesselSolver<2> ;
316 template class MicrovesselSolver<3> ;
void SetVesselNetwork(boost::shared_ptr< VesselNetwork< DIM > > pNetwork)
void SetUpdatePdeEachSolve(bool doUpdate)
boost::shared_ptr< OutputFileHandler > mpOutputFileHandler
void SetAngiogenesisSolver(boost::shared_ptr< AngiogenesisSolver< DIM > > pAngiogenesisSolver)
void SetOutputFileHandler(boost::shared_ptr< OutputFileHandler > pFileHandler)
static boost::shared_ptr< VesselNetworkWriter< DIM > > Create()
void SetSolution(std::vector< units::quantity< unit::concentration > > solution)
boost::shared_ptr< AngiogenesisSolver< DIM > > mpAngiogenesisSolver
void AddDiscreteContinuumSolver(boost::shared_ptr< AbstractDiscreteContinuumSolver< DIM > > pDiscreteContinuumSolver)
void SetStructuralAdaptationSolver(boost::shared_ptr< StructuralAdaptationSolver< DIM > > pStructuralAdaptationSolver)
void SetRegressionSolver(boost::shared_ptr< RegressionSolver< DIM > > pRegressionSolver)
std::vector< boost::shared_ptr< AbstractDiscreteContinuumSolver< DIM > > > GetDiscreteContinuumSolvers()
boost::shared_ptr< StructuralAdaptationSolver< DIM > > mpStructuralAdaptationSolver
void SetDiscreteContinuumSolversHaveCompatibleGridIndexing(bool compatibleIndexing)
static boost::shared_ptr< MicrovesselSolver > Create()
bool mDiscreteContinuumSolversHaveCompatibleGridIndexing
void SetupFromModifier(AbstractCellPopulation< DIM, DIM > &rCellPopulation, units::quantity< unit::length > cellReferenceLength, units::quantity< unit::concentration > cellReferenceConcentration, const std::string &rDirectory)
void UpdateCellData(std::vector< std::string > labels)
std::vector< boost::shared_ptr< AbstractDiscreteContinuumSolver< DIM > > > mDiscreteContinuumSolvers
boost::shared_ptr< RegressionSolver< DIM > > mpRegressionSolver
void SetOutputFrequency(unsigned frequency)
boost::shared_ptr< VesselNetwork< DIM > > mpNetwork