root/src/secOrd_op_initData_impl.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. clone
  2. clone
  3. clone
  4. evaluate
  5. evaluate

   1 /*! \file secOrd_op_initData_impl.h
   2     \brief Implementation details for `secOrd_op_initData.cpp`
   3 
   4      Revision history
   5      --------------------------------------------------
   6 
   7           Revised by Christian Power June 2016
   8           Revised by Christian Power April 2016
   9           Originally written by Christian Power
  10                (power22c@gmail.com) February 2016
  11 
  12      Idea
  13      --------------------------------------------------
  14 
  15      Actual implementation of Initial data.
  16 
  17      \author Christian Power 
  18      \date 15. June 2016
  19      \copyright Copyright (c) 2016 Christian Power.  All rights reserved.
  20  */
  21 
  22 #ifndef SECORD_OP_INITDATA_IMPL_H
  23 #define SECORD_OP_INITDATA_IMPL_H 
  24 
  25 #include <random>
  26 #include <functional>
  27 #include <string>
  28 #include <config.h>
  29 #include <dune/fem/operator/lagrangeinterpolation.hh>
  30 #include "secOrd_op_initData.h"
  31 #include "grid.h"
  32 
  33 namespace Esfem{
  34   namespace Impl{
  35     //! Initial data is given via an analytic formula
  36     class Explicit_initial_data
  37       : public Dune::Fem::Function<Esfem::Grid::Grid_and_time::Function_space,
  38                                    Explicit_initial_data>
  39     {
  40     public:
  41       //! \f$ f\colon\R^3\to \R\f$
  42       using Fun_space = Esfem::Grid::Grid_and_time::Function_space;
  43       //! \f$ \R^3\f$
  44       using Domain = Fun_space::DomainType;
  45       //! \f$ \R\f$
  46       using Range = Fun_space::RangeType;
  47 
  48       static_assert(Domain::dimension == 3, "Bad Domain dimension");
  49       static_assert(Range::dimension == 1, "Bad Range dimension");
  50     
  51       //! Time provider and determine if we want initial data for \f$ u\f$ or \f$ w\f$
  52       /*! \post Input Grid_and_time must outlive this object!
  53         \todo We have hard coded the parameter into the function.  Change
  54         the constructor so that it reads the parameter.
  55       */
  56       Explicit_initial_data(const Esfem::Grid::Grid_and_time&,
  57                             const Esfem::Growth);
  58       //! No copy constructor
  59       Explicit_initial_data(const Explicit_initial_data&) = delete;
  60       //! No copy assignment 
  61       Explicit_initial_data& operator=(const Explicit_initial_data&) = delete;
  62 
  63       //! Required for the dune Lagrange interpolation class
  64       void evaluate(const Domain&, Range&) const;
  65     private:
  66       //! Current time 
  67       const Dune::Fem::TimeProviderBase& tp;
  68       //! Initial data function for \f$ u\f$ or \f$ w\f$
  69       std::function<void(const Domain&,Range&)> fun_impl;
  70     };
  71 
  72     //! Random perturbation around an equilibrium point
  73     class Random_initial_data
  74       : public Dune::Fem::Function<Esfem::Grid::Grid_and_time::Function_space,
  75                                    Random_initial_data>
  76     {
  77     public:
  78       //! \copybrief Explicit_initial_data::Fun_space
  79       using Fun_space = Esfem::Grid::Grid_and_time::Function_space;
  80       //! \copybrief Explicit_initial_data::Domain
  81       using Domain = typename Fun_space::DomainType;
  82       //! \copybrief Explicit_initial_data::Range
  83       using Range = typename Fun_space::RangeType;
  84 
  85       static_assert(Domain::dimension == 3, "Bad Domain dimension");
  86       static_assert(Range::dimension == 1, "Bad Range dimension");
  87     
  88       //! \copybrief Explicit_initial_data()
  89       Random_initial_data(const Esfem::Io::Parameter&,
  90                           const Esfem::Growth);
  91     
  92       //! \copybrief Explicit_initial_data::evaluate()
  93       void evaluate(const Domain&, Range&) const;
  94     private:
  95       //! Random distribution
  96       using Random_dist = std::uniform_real_distribution<>;
  97       //! Seed 
  98       using Random_engine = std::default_random_engine;
  99     
 100       //! Random function for evaluate()
 101       std::function<double()> random_fun;
 102 
 103       //! Constructs `random_fun`
 104       Random_initial_data(const double hom_value, const double pertubation);
 105     };
 106 
 107     //! First eigen function of the sphere
 108     /*! \f$xye^{-6t}\f$*/
 109     struct sphere_1EF
 110       : Dune::Fem::Function<Esfem::Grid::Grid_and_time::Function_space,
 111                             sphere_1EF>,
 112         SecOrd_op::sIdata{
 113       //! \f$f\colon \R^3\to\R^1\f$
 114       using fspace = Esfem::Grid::Grid_and_time::Function_space;
 115       //! \f$ \R^3\f$
 116       using domain = typename fspace::DomainType;
 117       //! \f$\R^1\f$
 118       using range = typename fspace::RangeType;
 119       static_assert(domain::dimension == 3, "Bad Domain dimension");
 120       static_assert(range::dimension == 1, "Bad Range dimension");
 121       //! Get time provider
 122       sphere_1EF(const Grid::Grid_and_time&);
 123       sphere_1EF* clone() override;
 124       void interpolate(Grid::Scal_FEfun&) const override; 
 125       //! \copybrief Explicit_initial_data::evaluate()
 126       void evaluate(const domain&, range&) const;
 127     private:
 128       //! Current time
 129       const Dune::Fem::TimeProviderBase& tp;      
 130     };
 131     //! Second eigen function of the sphere
 132     /*! \f$yze^{-6t}\f$*/
 133     struct sphere_2EF
 134       : Dune::Fem::Function<Esfem::Grid::Grid_and_time::Function_space,
 135                             sphere_2EF>,
 136         SecOrd_op::sIdata{
 137       //! \f$f\colon \R^3\to\R^1\f$
 138       using fspace = Esfem::Grid::Grid_and_time::Function_space;
 139       //! \f$ \R^3\f$
 140       using domain = typename fspace::DomainType;
 141       //! \f$\R^1\f$
 142       using range = typename fspace::RangeType;
 143       static_assert(domain::dimension == 3, "Bad Domain dimension");
 144       static_assert(range::dimension == 1, "Bad Range dimension");
 145       //! Get time provider
 146       sphere_2EF(const Grid::Grid_and_time&);
 147       sphere_2EF* clone() override;
 148       void interpolate(Grid::Scal_FEfun&) const override; 
 149       //! \copybrief Explicit_initial_data::evaluate()
 150       void evaluate(const domain&, range&) const;
 151     private:
 152       //! Current time
 153       const Dune::Fem::TimeProviderBase& tp;      
 154     };
 155     //! Thrid eigen function of the sphere
 156     /*! \f$xze^{-6t}\f$*/
 157     struct sphere_3EF
 158       : Dune::Fem::Function<Esfem::Grid::Grid_and_time::Function_space,
 159                             sphere_3EF>,
 160         SecOrd_op::sIdata{
 161       //! \f$f\colon \R^3\to\R^1\f$
 162       using fspace = Esfem::Grid::Grid_and_time::Function_space;
 163       //! \f$ \R^3\f$
 164       using domain = typename fspace::DomainType;
 165       //! \f$\R^1\f$
 166       using range = typename fspace::RangeType;
 167       static_assert(domain::dimension == 3, "Bad Domain dimension");
 168       static_assert(range::dimension == 1, "Bad Range dimension");
 169       //! Get time provider
 170       sphere_3EF(const Grid::Grid_and_time&);
 171       sphere_3EF* clone() override;
 172       void interpolate(Grid::Scal_FEfun&) const override; 
 173       //! \copybrief Explicit_initial_data::evaluate()
 174       void evaluate(const domain&, range&) const;
 175     private:
 176       //! Current time
 177       const Dune::Fem::TimeProviderBase& tp;      
 178     };
 179 
 180 
 181     //! Implementation of SecOrd_op::vIdata::ssef()
 182     struct sphere_eigenFun
 183       : Dune::Fem::Function<Esfem::Grid::Grid_and_time::Vec_Function_space,
 184                             sphere_eigenFun>,
 185         SecOrd_op::vIdata{
 186       //! \f$f\colon \R^3\to\R^3\f$
 187       using Fun_space = Esfem::Grid::Grid_and_time::Vec_Function_space;
 188       //! \f$\R^3\f$
 189       using Domain = typename Fun_space::DomainType;
 190       //! \f$\R^3\f$
 191       using Range = typename Fun_space::RangeType;
 192 
 193       static_assert(Domain::dimension == 3, "Bad Domain dimension");
 194       static_assert(Range::dimension == 3, "Bad Range dimension");
 195       //! Get time provider
 196       sphere_eigenFun(const Grid::Grid_and_time&);
 197       sphere_eigenFun* clone() override;
 198       void interpolate(Grid::Vec_FEfun&) const override; 
 199       //! \copybrief Explicit_initial_data::evaluate()
 200       void evaluate(const Domain&, Range&) const;
 201     private:
 202       //! Current time
 203       const Dune::Fem::TimeProviderBase& tp;
 204     };
 205 
 206     //! Implementation of SecOrd_op::vIdata::ssef()
 207     /*! \pre The initial sphere is the unit sphere \f$S^2\f$.  */
 208     struct sphere_mcf_sol
 209       : Dune::Fem::Function<Esfem::Grid::Grid_and_time::Vec_Function_space,
 210                             sphere_mcf_sol>,
 211         SecOrd_op::vIdata{
 212       //! \f$f\colon \R^3\to\R^3\f$
 213       using Fun_space = Esfem::Grid::Grid_and_time::Vec_Function_space;
 214       //! \f$\R^3\f$
 215       using Domain = typename Fun_space::DomainType;
 216       //! \f$\R^3\f$
 217       using Range = typename Fun_space::RangeType;
 218 
 219       static_assert(Domain::dimension == 3, "Bad Domain dimension");
 220       static_assert(Range::dimension == 3, "Bad Range dimension");
 221       //! Get time provider
 222       sphere_mcf_sol(const Grid::Grid_and_time&);
 223       sphere_mcf_sol* clone() override;
 224       void interpolate(Grid::Vec_FEfun&) const override; 
 225       //! \copybrief Explicit_initial_data::evaluate()
 226       void evaluate(const Domain&, Range&) const;
 227     private:
 228       //! Current time
 229       const Dune::Fem::TimeProviderBase& tp;
 230     };    
 231 
 232     //! Sphere growing via a logistic growth function
 233     /*! \pre I assume that I am on the exact surface, which is a sphere.
 234       \sa Esfem::Brusselator_scheme::eoc_sls() */
 235     struct sls_iData
 236       : Dune::Fem::Function<Esfem::Grid::Grid_and_time::Vec_Function_space,
 237                             sls_iData>,
 238         SecOrd_op::vIdata{
 239       //! \f$f\colon \R^3\to\R^3\f$
 240       using Fun_space = Esfem::Grid::Grid_and_time::Vec_Function_space;
 241       //! \f$\R^3\f$
 242       using Domain = typename Fun_space::DomainType;
 243       //! \f$\R^3\f$
 244       using Range = typename Fun_space::RangeType;
 245 
 246       static_assert(Domain::dimension == 3, "Bad Domain dimension");
 247       static_assert(Range::dimension == 3, "Bad Range dimension");
 248       //! Get time provider and logistic growth parameter
 249       sls_iData(const Grid::Grid_and_time&);
 250       sls_iData* clone() override{ return new sls_iData {*this}; }
 251       void interpolate(Grid::Vec_FEfun&) const override; 
 252       //! \copybrief Explicit_initial_data::evaluate()
 253       void evaluate(const Domain&, Range&) const;
 254     private:
 255       //! Current time
 256       const Dune::Fem::TimeProviderBase& tp;
 257       //! Initial radius
 258       double rA;
 259       //! End radius or carrying capcity
 260       double rE;
 261       //! Growth rate
 262       double k;
 263     };
 264 
 265     //! Velocity of a sphere growing via a logistic growth function
 266     /*! \sa Esfem::Brusselator_scheme::eoc_sls() */
 267     struct sls_v_iData
 268       : Dune::Fem::Function<Esfem::Grid::Grid_and_time::Vec_Function_space,
 269                             sls_v_iData>,
 270         SecOrd_op::vIdata{
 271       //! \f$f\colon \R^3\to\R^3\f$
 272       using Fun_space = Esfem::Grid::Grid_and_time::Vec_Function_space;
 273       //! \f$\R^3\f$
 274       using Domain = typename Fun_space::DomainType;
 275       //! \f$\R^3\f$
 276       using Range = typename Fun_space::RangeType;
 277 
 278       static_assert(Domain::dimension == 3, "Bad Domain dimension");
 279       static_assert(Range::dimension == 3, "Bad Range dimension");
 280       //! Get time provider and logistic growth parameter
 281       sls_v_iData(const Grid::Grid_and_time&);
 282       sls_v_iData* clone() override{ return new sls_v_iData {*this}; }
 283       void interpolate(Grid::Vec_FEfun&) const override; 
 284       //! \copybrief Explicit_initial_data::evaluate()
 285       void evaluate(const Domain&, Range&) const;
 286     private:
 287       //! Current time
 288       const Dune::Fem::TimeProviderBase& tp;
 289       //! Initial radius
 290       double rA;
 291       //! End radius or carrying capcity
 292       double rE;
 293       //! Growth rate
 294       double k;
 295     };
 296     
 297     //! Sphere growing via na logistic growth function
 298     /*! \pre I assume that I am on the exact surface, which is a sphere.
 299       \sa Esfem::Brusselator_scheme::eoc_sd() */
 300     struct sd_iData
 301       : Dune::Fem::Function<Esfem::Grid::Grid_and_time::Vec_Function_space,
 302                             sd_iData>,
 303         SecOrd_op::vIdata{
 304       //! \f$f\colon \R^3\to\R^3\f$
 305       using Fun_space = Esfem::Grid::Grid_and_time::Vec_Function_space;
 306       //! \f$\R^3\f$
 307       using Domain = typename Fun_space::DomainType;
 308       //! \f$\R^3\f$
 309       using Range = typename Fun_space::RangeType;
 310 
 311       static_assert(Domain::dimension == 3, "Bad Domain dimension");
 312       static_assert(Range::dimension == 3, "Bad Range dimension");
 313 
 314       //! Get time provider 
 315       sd_iData(const Grid::Grid_and_time&);
 316       sd_iData* clone() override{ return new sd_iData {*this}; }
 317       void interpolate(Grid::Vec_FEfun&) const override; 
 318       //! \copybrief Explicit_initial_data::evaluate()
 319       void evaluate(const Domain&, Range&) const;
 320     private:
 321       //! Current time
 322       const Dune::Fem::TimeProviderBase& tp;
 323     };
 324     
 325     //! The actual implementation of the velocity
 326     class Analytic_velocity
 327       : public Dune::Fem::Function<Esfem::Grid::Grid_and_time::Vec_Function_space,
 328                                    Analytic_velocity>
 329     {
 330     public:
 331       //! \f$f\colon \R^3\to\R^3\f$
 332       using Fun_space = Esfem::Grid::Grid_and_time::Vec_Function_space;
 333       //! \f$\R^3\f$
 334       using Domain = typename Fun_space::DomainType;
 335       //! \f$\R^3\f$
 336       using Range = typename Fun_space::RangeType;
 337 
 338       static_assert(Domain::dimension == 3, "Bad Domain dimension");
 339       static_assert(Range::dimension == 3, "Bad Range dimension");
 340 
 341       //! Get time provider
 342       Analytic_velocity(const Esfem::Grid::Grid_and_time&);
 343       //! No copy constructor
 344       Analytic_velocity(const Analytic_velocity&) = delete;
 345       //! No copy assignment 
 346       Analytic_velocity& operator=(const Analytic_velocity&) = delete;
 347 
 348       //! \copybrief Explicit_initial_data::evaluate()
 349       void evaluate(const Domain&, Range&) const;
 350     private:
 351       //! Current time
 352       const Dune::Fem::TimeProviderBase& tp;
 353     };
 354 
 355     // ----------------------------------------------------------------------
 356     // helper functions 
 357 
 358     // ------------------------------------------------------------
 359     // Random_init_data helper
 360     double hom_value(const Esfem::Io::Parameter&, const Esfem::Growth);
 361     double pertubation(const Esfem::Io::Parameter&, const Esfem::Growth);
 362     std::string print_configuration(const Esfem::Io::Parameter&, const Esfem::Growth);
 363 
 364     // ------------------------------------------------------------
 365     // Init_data::Data helper
 366     std::string dof_filename(const Io::Parameter&, const Growth);
 367   } // namespace Impl
 368 
 369   //! %Data members of Init_data
 370   /*! \note If we want to get rid of the unique pointer, we may use inheritance. */
 371   struct SecOrd_op::Init_data::Data{
 372     //! Name for a log file 
 373     const std::string dof_io_filename {};
 374     //! Analytically given function.
 375     std::unique_ptr<Impl::Explicit_initial_data> eid_ptr;
 376     //! Function with random distributed coefficients.
 377     std::unique_ptr<Impl::Random_initial_data> rid_ptr;
 378     
 379     //! `eid_ptr` constructor
 380     /*! \post Grid_and_time must outlive this object. */
 381     Data(const Grid::Grid_and_time&, const Growth);
 382     //! `rid_ptr` constructor
 383     Data(const Io::Parameter&, const Growth);
 384   };
 385 
 386   //! %Data members of Exact_velocity
 387   struct SecOrd_op::Exact_velocity::Data{
 388     //! Functor of the analytic function
 389     Impl::Analytic_velocity v_fun;
 390     
 391     //! Get time provider
 392     Data(const Grid::Grid_and_time&);
 393   };
 394 } // namespace Esfem
 395 
 396 // ----------------------------------------------------------------------
 397 // Inline implementation
 398 
 399 inline void Esfem::Impl::Explicit_initial_data::
 400 evaluate(const Domain& d, Range& r) const{
 401   fun_impl(d,r);
 402 }    
 403 inline void Esfem::Impl::Random_initial_data::
 404 evaluate(const Domain&, Range& q) const{
 405   q = random_fun(); 
 406 }  
 407 
 408 #endif // SECORD_OP_INITDATA_IMPL_H

/* [<][>][^][v][top][bottom][index][help] */