Flow123d  JS_before_hm-979-g397e552
field_add_potential.hh
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2015 Technical University of Liberec. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License version 3 as published by the
7  * Free Software Foundation. (http://www.gnu.org/licenses/gpl-3.0.en.html)
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12  *
13  *
14  * @file field_add_potential.hh
15  * @brief
16  */
17 
18 #ifndef FIELD_ADD_POTENTIAL_HH_
19 #define FIELD_ADD_POTENTIAL_HH_
20 
21 #include <armadillo>
22 #include <memory>
23 
24 #include "fields/field.hh"
25 
26 
27 /**
28  * This field is meant to be used to implement two possibilities for initialization of pressure fields in
29  * Darcy flows. You can either use pressure of piezo-metric head which are related by adding gravity potential.
30  * For various reasons we use pressure as the primary variable, so if the user enters piezo-head we need to add the potential to
31  * the field he/she has provided. This is done by this class. Unfortunately it introduce one more level of indirection,
32  * namely one more virtual call for getting the field value.
33  *
34  * - The field can not be initialized form the input.
35  * - We allow only Scalar Value with element_type double.
36  */
37 template <int spacedim, class Value>
38 class FieldAddPotential : public FieldAlgorithmBase<spacedim, Value> {
39 public:
41  typedef typename Space<spacedim>::Point Point;
42  /**
43  *
44  */
45  FieldAddPotential( const arma::vec::fixed<spacedim+1> &potential_grad, const Input::AbstractRecord &rec, unsigned int n_comp=0);
46 
47  /**
48  * Constructor allows to set existing Field as inner_field_
49  */
50  FieldAddPotential( const arma::vec::fixed<spacedim+1> &potential_grad, std::shared_ptr< FieldAlgorithmBase<spacedim, Value> > inner_field,
51  unsigned int n_comp=0);
52 
53 
54  /**
55  * Factory class (descendant of @p Field<...>::FactoryBase) that is necessary
56  * for setting pressure values are piezometric head values.
57  */
58  class FieldFactory : public FactoryBaseType {
59  public:
60  /// Constructor.
61  FieldFactory(arma::vec::fixed<spacedim+1> potential, std::string field_name)
62  : potential_(potential),
63  field_name_(field_name)
64  {}
65 
67  Input::AbstractRecord field_a_rec;
68  if (rec.opt_val(field_name_, field_a_rec)) {
69  return std::make_shared< FieldAddPotential<3, FieldValue<3>::Scalar > >( potential_, field_a_rec);
70  } else {
71  return typename Field<spacedim,Value>::FieldBasePtr();
72  }
73  }
74 
75  bool is_active_field_descriptor(const Input::Record &in_rec, FMT_UNUSED const std::string &input_name) override {
76  return in_rec.find<Input::AbstractRecord>(field_name_);
77  }
78 
79  arma::vec::fixed<spacedim+1> potential_;
80  std::string field_name_;
81  };
82 
83 
84  /**
85  * Returns one value in one given point. ResultType can be used to avoid some costly calculation if the result is trivial.
86  */
87  virtual typename Value::return_type const &value(const Point &p, const ElementAccessor<spacedim> &elm);
88 
89  /**
90  * Returns std::vector of scalar values in several points at once.
91  */
92  virtual void value_list (const Armor::array &point_list, const ElementAccessor<spacedim> &elm,
94 
95 
96  /**
97  * Update time and possibly update data.
98  */
99  bool set_time(const TimeStep &time) override;
100 
101  /// Implements @p FieldAlgirithmBase::set_mesh.
102  void set_mesh(const Mesh *mesh, bool boundary_domain) override;
103 
104  virtual ~FieldAddPotential();
105 
106 private:
107  /// Field to which we add linear potential.
108  std::shared_ptr< FieldAlgorithmBase<spacedim, Value> > inner_field_;
109  /// Potential gradient.
110  arma::vec::fixed<spacedim> grad_;
111  /// Potential constant term.
112  double zero_level_;
113 };
114 
115 
116 #endif /* FIELD_ADD_POTENTIAL_HH_ */
Common abstract parent of all Field<...> classes.
Definition: field_common.hh:73
void set_mesh(const Mesh *mesh, bool boundary_domain) override
Implements FieldAlgirithmBase::set_mesh.
Armor::ArmaVec< double, spacedim > Point
Definition: point.hh:42
bool set_time(const TimeStep &time) override
arma::vec::fixed< spacedim > grad_
Potential gradient.
Definition: mesh.h:78
Iterator< Ret > find(const string &key) const
FieldAddPotential(const arma::vec::fixed< spacedim+1 > &potential_grad, const Input::AbstractRecord &rec, unsigned int n_comp=0)
bool opt_val(const string &key, Ret &value) const
bool is_active_field_descriptor(const Input::Record &in_rec, FMT_UNUSED const std::string &input_name) override
#define FMT_UNUSED
Definition: posix.h:75
FieldFactory(arma::vec::fixed< spacedim+1 > potential, std::string field_name)
Constructor.
double zero_level_
Potential constant term.
Accessor to the data with type Type::Record.
Definition: accessors.hh:291
Accessor to the polymorphic input data of a type given by an AbstracRecord object.
Definition: accessors.hh:458
std::shared_ptr< FieldBaseType > FieldBasePtr
Definition: field.hh:96
Field< spacedim, Value >::FactoryBase FactoryBaseType
virtual void value_list(const Armor::array &point_list, const ElementAccessor< spacedim > &elm, std::vector< typename Value::return_type > &value_list)
Field< spacedim, Value >::FieldBasePtr create_field(Input::Record rec, const FieldCommon &) override
arma::vec::fixed< spacedim+1 > potential_
std::shared_ptr< FieldAlgorithmBase< spacedim, Value > > inner_field_
Field to which we add linear potential.
virtual Value::return_type const & value(const Point &p, const ElementAccessor< spacedim > &elm)
Representation of one time step..
Space< spacedim >::Point Point
unsigned int n_comp() const