DiffusionForce.cpp

00001 /*
00002 
00003 Copyright (c) 2005-2015, University of Oxford.
00004 All rights reserved.
00005 
00006 University of Oxford means the Chancellor, Masters and Scholars of the
00007 University of Oxford, having an administrative office at Wellington
00008 Square, Oxford OX1 2JD, UK.
00009 
00010 This file is part of Chaste.
00011 
00012 Redistribution and use in source and binary forms, with or without
00013 modification, are permitted provided that the following conditions are met:
00014  * Redistributions of source code must retain the above copyright notice,
00015    this list of conditions and the following disclaimer.
00016  * Redistributions in binary form must reproduce the above copyright notice,
00017    this list of conditions and the following disclaimer in the documentation
00018    and/or other materials provided with the distribution.
00019  * Neither the name of the University of Oxford nor the names of its
00020    contributors may be used to endorse or promote products derived from this
00021    software without specific prior written permission.
00022 
00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00024 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00025 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00026 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00027 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00028 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
00029 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00030 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00032 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033 
00034 */
00035 
00036 #include "DiffusionForce.hpp"
00037 #include "NodeBasedCellPopulation.hpp"
00038 
00039 //Static constant is instantiated here.
00040 template<unsigned DIM>
00041 const double DiffusionForce<DIM>::msBoltzmannConstant = 1.3806488e-23;
00042 
00043 template<unsigned DIM>
00044 DiffusionForce<DIM>::DiffusionForce()
00045     : AbstractForce<DIM>(),
00046       mDiffusionConstant(0.01),
00047       mAbsoluteTemperature(296.0), // default to room temperature
00048       mViscosity(3.204e-6), // default to viscosity of water at room temperature in (using microns and hours)
00049       mMechanicsCutOffLength(10.0)
00050 {
00051 }
00052 
00053 template<unsigned DIM>
00054 DiffusionForce<DIM>::~DiffusionForce()
00055 {
00056 }
00057 
00058 template<unsigned DIM>
00059 void DiffusionForce<DIM>::SetCutOffLength(double cutOffLength)
00060 {
00061     assert(cutOffLength > 0.0);
00062     mMechanicsCutOffLength=cutOffLength;
00063 }
00064 
00065 template<unsigned DIM>
00066 double DiffusionForce<DIM>::GetCutOffLength()
00067 {
00068     return mMechanicsCutOffLength;
00069 }
00070 
00071 template<unsigned DIM>
00072 void DiffusionForce<DIM>::SetDiffusionConstant(double diffusionConstant)
00073 {
00074     assert(diffusionConstant > 0.0);
00075     mDiffusionConstant = diffusionConstant;
00076 }
00077 
00078 template<unsigned DIM>
00079 double DiffusionForce<DIM>::GetDiffusionConstant()
00080 {
00081     return mDiffusionConstant;
00082 }
00083 
00084 template<unsigned DIM>
00085 void DiffusionForce<DIM>::SetAbsoluteTemperature(double newValue)
00086 {
00087     assert(newValue > 0.0);
00088     mAbsoluteTemperature = newValue;
00089 }
00090 
00091 template<unsigned DIM>
00092 double DiffusionForce<DIM>::GetAbsoluteTemperature()
00093 {
00094     return mAbsoluteTemperature;
00095 }
00096 
00097 template<unsigned DIM>
00098 void DiffusionForce<DIM>::SetViscosity(double newValue)
00099 {
00100     assert(newValue > 0.0);
00101     mViscosity = newValue;
00102 }
00103 
00104 template<unsigned DIM>
00105 double DiffusionForce<DIM>::GetViscosity()
00106 {
00107     return mViscosity;
00108 }
00109 
00110 template<unsigned DIM>
00111 double DiffusionForce<DIM>::GetDiffusionScalingConstant()
00112 {
00113     return msBoltzmannConstant*mAbsoluteTemperature/(6.0*mViscosity*M_PI);
00114 }
00115 
00116 template<unsigned DIM>
00117 void DiffusionForce<DIM>::AddForceContribution(AbstractCellPopulation<DIM>& rCellPopulation)
00118 {
00119     double dt = SimulationTime::Instance()->GetTimeStep();
00120 
00121     // Loop over the cells
00122     for (typename AbstractCellPopulation<DIM>::Iterator cell_iter = rCellPopulation.Begin();
00123          cell_iter != rCellPopulation.End();
00124          ++cell_iter)
00125     {
00126         // Get the radius, damping constant and node index associated with this cell
00127         unsigned node_index = rCellPopulation.GetLocationIndexUsingCell(*cell_iter);
00128         Node<DIM>* p_node = rCellPopulation.GetNode(node_index);
00129 
00130         double nu = dynamic_cast<AbstractOffLatticeCellPopulation<DIM>*>(&rCellPopulation)->GetDampingConstant(node_index);
00131         double cell_radius = p_node->GetRadius();
00132 
00133         /*
00134          * Compute the diffusion coefficient D as D = k*T/(6*pi*eta*r), where
00135          *
00136          * k = Boltzmann's constant,
00137          * T = absolute temperature,
00138          * eta = dynamic viscosity,
00139          * r = cell radius.
00140          */
00141         double diffusion_const_scaling = GetDiffusionScalingConstant();
00142         double diffusion_constant = diffusion_const_scaling/cell_radius;
00143 
00144         c_vector<double, DIM> force_contribution;
00145         for (unsigned i=0; i<DIM; i++)
00146         {
00147             /*
00148              * The force on this cell is scaled with the timestep such that when it is
00149              * used in the discretised equation of motion for the cell, we obtain the
00150              * correct formula
00151              *
00152              * x_new = x_old + sqrt(2*D*dt)*W
00153              *
00154              * where W is a standard normal random variable.
00155              */
00156             double xi = RandomNumberGenerator::Instance()->StandardNormalRandomDeviate();
00157 
00158             force_contribution[i] = (nu*sqrt(2.0*diffusion_constant*dt)/dt)*xi;
00159         }
00160         p_node->AddAppliedForceContribution(force_contribution);
00161     }
00162 }
00163 
00164 template<unsigned DIM>
00165 void DiffusionForce<DIM>::OutputForceParameters(out_stream& rParamsFile)
00166 {
00167     *rParamsFile << "\t\t\t<DiffusionConstant>" << mDiffusionConstant << "</DiffusionConstant> \n";
00168     *rParamsFile << "\t\t\t<MechanicsCutOffLength>" << mMechanicsCutOffLength << "</MechanicsCutOffLength> \n";
00169 
00170     // Call direct parent class
00171     AbstractForce<DIM>::OutputForceParameters(rParamsFile);
00172 }
00173 
00175 // Explicit instantiation
00177 
00178 template class DiffusionForce<1>;
00179 template class DiffusionForce<2>;
00180 template class DiffusionForce<3>;
00181 
00182 // Serialization for Boost >= 1.36
00183 #include "SerializationExportWrapperForCpp.hpp"
00184 EXPORT_TEMPLATE_CLASS_SAME_DIMS(DiffusionForce)

Generated by  doxygen 1.6.2