Flow123d  3.9.0-f06eab6ff
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"
26 #include "fields/field_model.hh"
27 #include "fields/field_coords.hh"
28 
29 
30 /*******************************************************************************
31  * Functors of FieldModels
32  */
33 using Sclr = double;
34 using Vect = arma::vec3;
35 
36 // Functor computing piezo_head_p0
38  inline Sclr operator() (Vect gravity, Vect coords, Sclr pressure) {
39  return arma::dot(gravity, coords) + pressure;
40  }
41 };
42 
43 
44 /**
45  * Factory class (descendant of @p Field<...>::FactoryBase) that is necessary
46  * for setting pressure values are piezometric head values.
47  */
48 template <int spacedim, class Value> // <3, FieldValue<3>::Scalar>
49 class AddPotentialFactory : public Field<spacedim, Value>::FactoryBase {
50 public:
51  /// Constructor.
53  : gravity_(gravity),
54  coords_(coords),
55  inner_field_(inner_field),
56  field_name_(inner_field.input_name())
57  {}
58 
60  Input::AbstractRecord field_a_rec;
61  if (rec.opt_val(field_name_, field_a_rec)) {
63 
64  } else {
65  return typename Field<spacedim,Value>::FieldBasePtr();
66  }
67  }
68 
69  bool is_active_field_descriptor(const Input::Record &in_rec, FMT_UNUSED const std::string &input_name) override {
70  return in_rec.find<Input::AbstractRecord>(field_name_);
71  }
72 
76  std::string field_name_;
77 };
78 
79 
80 /**
81  * This field is meant to be used to implement two possibilities for initialization of pressure fields in
82  * Darcy flows. You can either use pressure of piezo-metric head which are related by adding gravity potential.
83  * For various reasons we use pressure as the primary variable, so if the user enters piezo-head we need to add the potential to
84  * the field he/she has provided. This is done by this class. Unfortunately it introduce one more level of indirection,
85  * namely one more virtual call for getting the field value.
86  *
87  * - The field can not be initialized form the input.
88  * - We allow only Scalar Value with element_type double.
89  */
90 template <int spacedim, class Value>
91 class FieldAddPotential : public FieldAlgorithmBase<spacedim, Value> {
92 public:
94  typedef typename Space<spacedim>::Point Point;
95  /**
96  *
97  */
98  FieldAddPotential( const arma::vec::fixed<spacedim+1> &potential_grad, const Input::AbstractRecord &rec, unsigned int n_comp=0);
99 
100  /**
101  * Constructor allows to set existing Field as inner_field_
102  */
103  FieldAddPotential( const arma::vec::fixed<spacedim+1> &potential_grad, std::shared_ptr< FieldAlgorithmBase<spacedim, Value> > inner_field,
104  unsigned int n_comp=0);
105 
106 
107  /**
108  * Factory class (descendant of @p Field<...>::FactoryBase) that is necessary
109  * for setting pressure values are piezometric head values.
110  */
111  class FieldFactory : public FactoryBaseType {
112  public:
113  /// Constructor.
114  FieldFactory(arma::vec::fixed<spacedim+1> potential, std::string field_name)
115  : potential_(potential),
116  field_name_(field_name)
117  {}
118 
120  Input::AbstractRecord field_a_rec;
121  if (rec.opt_val(field_name_, field_a_rec)) {
122  return std::make_shared< FieldAddPotential<3, FieldValue<3>::Scalar > >( potential_, field_a_rec);
123  } else {
124  return typename Field<spacedim,Value>::FieldBasePtr();
125  }
126  }
127 
128  bool is_active_field_descriptor(const Input::Record &in_rec, FMT_UNUSED const std::string &input_name) override {
129  return in_rec.find<Input::AbstractRecord>(field_name_);
130  }
131 
132  arma::vec::fixed<spacedim+1> potential_;
133  std::string field_name_;
134  };
135 
136 
137  /**
138  * Returns one value in one given point. ResultType can be used to avoid some costly calculation if the result is trivial.
139  */
140  virtual typename Value::return_type const &value(const Point &p, const ElementAccessor<spacedim> &elm);
141 
142  /**
143  * Returns std::vector of scalar values in several points at once.
144  */
145  virtual void value_list (const Armor::array &point_list, const ElementAccessor<spacedim> &elm,
147 
148 
149  /**
150  * Update time and possibly update data.
151  */
152  bool set_time(const TimeStep &time) override;
153 
154  /// Implements @p FieldAlgirithmBase::set_mesh.
155  void set_mesh(const Mesh *mesh, bool boundary_domain) override;
156 
157  virtual ~FieldAddPotential();
158 
159 private:
160  /// Field to which we add linear potential.
161  std::shared_ptr< FieldAlgorithmBase<spacedim, Value> > inner_field_;
162  /// Potential gradient.
163  arma::vec::fixed<spacedim> grad_;
164  /// Potential constant term.
165  double zero_level_;
166 };
167 
168 
169 #endif /* FIELD_ADD_POTENTIAL_HH_ */
Space::Point
Armor::ArmaVec< double, spacedim > Point
Definition: point.hh:42
AddPotentialFactory::field_name_
std::string field_name_
Definition: field_add_potential.hh:76
FieldAddPotential::value
virtual const Value::return_type & value(const Point &p, const ElementAccessor< spacedim > &elm)
Definition: field_add_potential.impl.hh:51
FieldCoords
Definition: field_coords.hh:36
AddPotentialFactory::inner_field_
Field< 3, FieldValue< 3 >::Scalar > & inner_field_
Definition: field_add_potential.hh:75
FieldAddPotential::set_mesh
void set_mesh(const Mesh *mesh, bool boundary_domain) override
Implements FieldAlgirithmBase::set_mesh.
Definition: field_add_potential.impl.hh:94
fn_add_potential
Definition: field_add_potential.hh:37
FieldAlgorithmBase::n_comp
unsigned int n_comp() const
Definition: field_algo_base.impl.hh:133
field_algo_base.hh
FieldAddPotential::set_time
bool set_time(const TimeStep &time) override
Definition: field_add_potential.impl.hh:86
FieldAddPotential::FieldFactory::create_field
Field< spacedim, Value >::FieldBasePtr create_field(Input::Record rec, const FieldCommon &) override
Definition: field_add_potential.hh:119
AddPotentialFactory::create_field
Field< spacedim, Value >::FieldBasePtr create_field(Input::Record rec, const FieldCommon &) override
Definition: field_add_potential.hh:59
FieldAddPotential::grad_
arma::vec::fixed< spacedim > grad_
Potential gradient.
Definition: field_add_potential.hh:163
std::vector
Definition: doxy_dummy_defs.hh:7
ElementAccessor
Definition: dh_cell_accessor.hh:32
arma::vec3
Definition: doxy_dummy_defs.hh:17
fn_add_potential::operator()
Sclr operator()(Vect gravity, Vect coords, Sclr pressure)
Definition: field_add_potential.hh:38
FieldAddPotential
Definition: field_add_potential.hh:91
Field::FactoryBase
Definition: field.hh:121
FieldAddPotential::FieldFactory::FieldFactory
FieldFactory(arma::vec::fixed< spacedim+1 > potential, std::string field_name)
Constructor.
Definition: field_add_potential.hh:114
FieldAddPotential::FieldAddPotential
FieldAddPotential(const arma::vec::fixed< spacedim+1 > &potential_grad, const Input::AbstractRecord &rec, unsigned int n_comp=0)
Definition: field_add_potential.impl.hh:25
AddPotentialFactory::gravity_
Field< 3, FieldValue< 3 >::VectorFixed > & gravity_
Definition: field_add_potential.hh:73
AddPotentialFactory
Definition: field_add_potential.hh:49
AddPotentialFactory::is_active_field_descriptor
bool is_active_field_descriptor(const Input::Record &in_rec, FMT_UNUSED const std::string &input_name) override
Definition: field_add_potential.hh:69
Input::Record
Accessor to the data with type Type::Record.
Definition: accessors.hh:291
field_model.hh
FieldAddPotential::zero_level_
double zero_level_
Potential constant term.
Definition: field_add_potential.hh:165
TimeStep
Representation of one time step..
Definition: time_governor.hh:123
Input::AbstractRecord
Accessor to the polymorphic input data of a type given by an AbstracRecord object.
Definition: accessors.hh:458
FieldCommon
Common abstract parent of all Field<...> classes.
Definition: field_common.hh:76
Input::Record::opt_val
bool opt_val(const string &key, Ret &value) const
Definition: accessors_impl.hh:107
FieldAddPotential::FieldFactory::is_active_field_descriptor
bool is_active_field_descriptor(const Input::Record &in_rec, FMT_UNUSED const std::string &input_name) override
Definition: field_add_potential.hh:128
FieldAddPotential::FieldFactory::potential_
arma::vec::fixed< spacedim+1 > potential_
Definition: field_add_potential.hh:132
FieldAddPotential::~FieldAddPotential
virtual ~FieldAddPotential()
Definition: field_add_potential.impl.hh:102
Input::Record::find
Iterator< Ret > find(const string &key) const
Definition: accessors_impl.hh:91
Sclr
double Sclr
Definition: field_add_potential.hh:33
Field::FieldBasePtr
std::shared_ptr< FieldBaseType > FieldBasePtr
Definition: field.hh:95
FieldAddPotential::FactoryBaseType
Field< spacedim, Value >::FactoryBase FactoryBaseType
Definition: field_add_potential.hh:93
Mesh
Definition: mesh.h:361
FieldAddPotential::value_list
virtual void value_list(const Armor::array &point_list, const ElementAccessor< spacedim > &elm, std::vector< typename Value::return_type > &value_list)
Definition: field_add_potential.impl.hh:69
FieldAlgorithmBase
Definition: field_algo_base.hh:112
Model
Definition: field_model.hh:338
FieldAddPotential::FieldFactory::field_name_
std::string field_name_
Definition: field_add_potential.hh:133
Armor::Array< double >
FieldAddPotential::FieldFactory
Definition: field_add_potential.hh:111
AddPotentialFactory::coords_
FieldCoords & coords_
Definition: field_add_potential.hh:74
Field
Class template representing a field with values dependent on: point, element, and region.
Definition: field.hh:91
FieldAddPotential::Point
Space< spacedim >::Point Point
Definition: field_add_potential.hh:94
FieldAddPotential::inner_field_
std::shared_ptr< FieldAlgorithmBase< spacedim, Value > > inner_field_
Field to which we add linear potential.
Definition: field_add_potential.hh:161
field.hh
field_coords.hh
AddPotentialFactory::AddPotentialFactory
AddPotentialFactory(Field< 3, FieldValue< 3 >::VectorFixed > &gravity, FieldCoords &coords, Field< 3, FieldValue< 3 >::Scalar > &inner_field)
Constructor.
Definition: field_add_potential.hh:52
FieldValue
Definition: field_values.hh:645
FMT_UNUSED
#define FMT_UNUSED
Definition: posix.h:75