Go to the documentation of this file.00001 #ifndef OPENTISSUE_DYNAMICS_SWE_SWE_DAMPED_WAVE_EQUATIONS_H
00002 #define OPENTISSUE_DYNAMICS_SWE_SWE_DAMPED_WAVE_EQUATIONS_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/utility/utility_empty_traits.h>
00013
00014 #include <cassert>
00015 #include <vector>
00016
00017
00018 namespace OpenTissue
00019 {
00020 namespace swe
00021 {
00022
00034 template <typename math_types_, typename dwe_particle_traits = OpenTissue::utility::EmptyTraits >
00035 class DampedWaveEquations
00036 {
00037 public:
00038
00039 typedef math_types_ math_types;
00040 typedef typename math_types::real_type real_type;
00041 typedef typename math_types::index_type index_type;
00042 typedef typename math_types::vector3_type vector3_type;
00043
00044 public:
00045
00046 class DWEParticle : public dwe_particle_traits
00047 {
00048 public:
00049
00050 typedef typename math_types::real_type real_type;
00051
00052 public:
00053 DWEParticle()
00054 : m_Hold(0)
00055 , m_Hcur(0)
00056 , m_Hnew(0)
00057 , m_fixed(false)
00058 {}
00059 virtual ~DWEParticle()
00060 {}
00061
00062 public:
00063 real_type const& height() const {return m_Hcur;}
00064 real_type& height() {return m_Hcur;}
00065 bool const& fixed() const {return m_fixed;}
00066 bool& fixed() {return m_fixed;}
00067
00068 protected:
00069 friend class DampedWaveEquations;
00070 real_type m_Hold, m_Hcur, m_Hnew;
00071 bool m_fixed;
00072
00073 };
00074
00075 typedef DWEParticle dwe_particle;
00076 typedef std::vector<dwe_particle> particle_container;
00077 typedef typename particle_container::iterator particle_iterator;
00078 typedef typename particle_container::const_iterator particle_const_iterator;
00079
00080 public:
00081 DampedWaveEquations()
00082 : m_I(0)
00083 , m_J(0)
00084 , m_k(0.5)
00085 , m_c(50)
00086 , m_D(5)
00087 , m_smooth(true)
00088 {}
00089 virtual ~DampedWaveEquations()
00090 {}
00091
00092 public:
00101 bool init(index_type columns, index_type rows, real_type const& default_height = 0)
00102 {
00103 if (columns < 1 || rows < 1)
00104 return false;
00105 m_pars.clear();
00106 m_pars.resize((m_I=columns)*(m_J=rows));
00107 particle_iterator end = m_pars.end();
00108 for (particle_iterator p = m_pars.begin(); p != end; ++p)
00109 p->m_Hold = p->m_Hcur = p->m_Hnew = default_height;
00110 return true;
00111 }
00112
00118 void simulate(real_type const& dt)
00119 {
00120 const real_type damping = 1-m_k*dt;
00121 const real_type advection = (dt*dt*m_c*m_c)/(m_D*m_D);
00122 for (int j = 0; j < int(m_J); ++j) for (int i = 0; i < int(m_I); ++i) {
00123 dwe_particle& par = particle(i,j);
00124 if (par.m_fixed) {
00125 par.m_Hcur = par.m_Hnew;
00126 continue;
00127 }
00128 const real_type fdm = m_smooth
00129 ? -6*par.m_Hcur+get(i+1,j).m_Hcur+get(i-1,j).m_Hcur+get(i,j+1).m_Hcur+get(i,j-1).m_Hcur
00130 +0.5*(get(i+1,j+1).m_Hcur+get(i+1,j-1).m_Hcur+get(i-1,j+1).m_Hcur+get(i-1,j-1).m_Hcur)
00131 : get(i+1,j).m_Hcur+get(i-1,j).m_Hcur+get(i,j+1).m_Hcur+get(i,j-1).m_Hcur-4*par.m_Hcur;
00132 par.m_Hnew = par.m_Hcur + damping*(par.m_Hcur-par.m_Hold) + advection*fdm;
00133 }
00134 particle_iterator end = m_pars.end();
00135 for (particle_iterator p = m_pars.begin(); p != end; ++p) {
00136 dwe_particle& par = *p;
00137 par.m_Hold = par.m_Hcur;
00138 par.m_Hcur = par.m_Hnew;
00139 }
00140 }
00141
00142 public:
00143 real_type& damping() {return m_k;}
00144 real_type const& damping() const {return m_k;}
00145 real_type& speed() {return m_c;}
00146 real_type const& speed() const {return m_c;}
00147 real_type& spacing() {return m_D;}
00148 real_type const& spacing() const {return m_D;}
00149 bool& smooth() {return m_smooth;}
00150 bool const& smooth() const {return m_smooth;}
00151
00152 index_type const& columns() const {return m_I;}
00153 index_type const& rows() const {return m_J;}
00154 index_type size() const {return m_pars.size();}
00155 dwe_particle const& particle(index_type n) const
00156 {
00157 assert(n < m_pars.size());
00158 return m_pars[n];
00159 }
00160 dwe_particle& particle(index_type n)
00161 {
00162 assert(n < m_pars.size());
00163 return m_pars[n];
00164 }
00165 dwe_particle const& particle(index_type i, index_type j) const
00166 {
00167 assert(i < m_I && j < m_J);
00168 return m_pars[j*m_I+i];
00169 }
00170 dwe_particle& particle(index_type i, index_type j)
00171 {
00172 assert(i < m_I && j < m_J);
00173 return m_pars[j*m_I+i];
00174 }
00175
00176 vector3_type normal(index_type i, index_type j) const
00177 {
00178 assert(i < m_I && j < m_J);
00179 const index_type i0 = m_I==i+1?i:i+1;
00180 const index_type i1 = 0==i?i:i-1;
00181 const index_type j0 = m_J==j+1?j:j+1;
00182 const index_type j1 = 0==j?j:j-1;
00183 const real_type nx = -m_D*(particle(i0, j).m_Hcur - particle(i1, j).m_Hcur);
00184 const real_type ny = 1;
00185 const real_type nz = -m_D*(particle(i, j0).m_Hcur - particle(i, j1).m_Hcur);
00186
00187
00188
00189 return unit(vector3_type(nx, ny, nz));
00190 }
00191
00192 protected:
00193 dwe_particle const& get(int i, int j) const
00194 {
00195 using std::max;
00196 using std::min;
00197 i = max(0, min(int(m_I)-1, i));
00198 j = max(0, min(int(m_J)-1, j));
00199 return m_pars[j*m_I+i];
00200 }
00201
00202 protected:
00203 index_type m_I;
00204 index_type m_J;
00205 real_type m_k;
00206 real_type m_c;
00207 real_type m_D;
00208 bool m_smooth;
00209 particle_container m_pars;
00210
00211 };
00212
00213 }
00214 }
00215
00216
00217 #endif