2 #ifndef INMOST_AUTODIFF_ETVAR_H_INCLUDED
3 #define INMOST_AUTODIFF_ETVAR_H_INCLUDED
4 #include "inmost_common.h"
5 #include "inmost_expression.h"
6 #include "inmost_mesh.h"
7 #include "inmost_autodiff.h"
8 #include "inmost_solver.h"
12 #if defined(USE_AUTODIFF) && defined(USE_MESH)
27 #pragma warning(disable : 4503)
35 template<
class Op,
class A>
41 unary_pool & operator = (
unary_pool const & other) {arg = other.arg; operand.assign(other.operand,arg);
return *
this;}
43 unary_pool(
const A & parg) : arg(parg), operand(arg) {}
44 unary_pool(
const A & parg, INMOST_DATA_REAL_TYPE pmult) : arg(parg), operand(arg,pmult) {}
48 Op & get_op() {
return operand;}
49 const Op & get_op()
const {
return operand;}
54 template<
class Op,
class A,
class B>
62 binary_pool & operator = (
binary_pool const & other) {left = other.left; right = other.right; operand.assign(other.operand,left,right);
return *
this;}
64 binary_pool(
const A & pleft,
const B & pright) : left(pleft), right(pright), operand(left,right) {}
65 binary_pool(
const binary_pool & other) : left(other.left), right(other.right), operand(other.operand,left,right) {}
69 Op & get_op() {
return operand;}
70 const Op & get_op()
const {
return operand;}
74 template<
class Op,
class A,
class B,
class C>
82 ternary_pool & operator =(
ternary_pool const & other) {cond = other.cond; left = other.left; right = other.right; operand.assign(other.operand,cond,left,right);
return *
this;}
84 ternary_pool(
const A & pcond,
const B & pleft,
const C & pright) : cond(pcond), left(pleft), right(pright), operand(cond,left,right) {}
85 ternary_pool(
const ternary_pool & other) : cond(other.cond), left(other.left), right(other.right), operand(other.operand,cond,left,right) {}
90 Op & get_op() {
return operand;}
91 const Op & get_op()
const {
return operand;}
95 template<
class A,
class ArgA>
103 __INLINE INMOST_DATA_REAL_TYPE GetValue()
const {
return pool.get_op().GetValue(); }
104 __INLINE
void GetJacobian(INMOST_DATA_REAL_TYPE mult,
Sparse::RowMerger & r)
const {pool.get_op().GetJacobian(mult,r);}
105 __INLINE
void GetJacobian(INMOST_DATA_REAL_TYPE mult,
Sparse::Row & r)
const {pool.get_op().GetJacobian(mult,r);}
106 __INLINE
void GetHessian(INMOST_DATA_REAL_TYPE multJ,
Sparse::Row & J, INMOST_DATA_REAL_TYPE multH,
Sparse::HessianRow & H)
const {pool.get_op().GetHessian(multJ,J,multH,H);}
107 __INLINE
void GetInterval(INMOST_DATA_ENUM_TYPE& beg, INMOST_DATA_ENUM_TYPE& end, INMOST_DATA_ENUM_TYPE& cnt)
const {
return pool.get_op().GetInterval(beg, end, cnt); }
111 template<
class A,
class ArgA,
class ArgB>
119 __INLINE INMOST_DATA_REAL_TYPE GetValue()
const {
return pool.get_op().GetValue(); }
120 __INLINE
void GetJacobian(INMOST_DATA_REAL_TYPE mult,
Sparse::RowMerger & r)
const {pool.get_op().GetJacobian(mult,r);}
121 __INLINE
void GetJacobian(INMOST_DATA_REAL_TYPE mult,
Sparse::Row & r)
const {pool.get_op().GetJacobian(mult,r);}
122 __INLINE
void GetHessian(INMOST_DATA_REAL_TYPE multJ,
Sparse::Row & J, INMOST_DATA_REAL_TYPE multH,
Sparse::HessianRow & H)
const {pool.get_op().GetHessian(multJ,J,multH,H);}
123 __INLINE
void GetInterval(INMOST_DATA_ENUM_TYPE& beg, INMOST_DATA_ENUM_TYPE& end, INMOST_DATA_ENUM_TYPE& cnt)
const {
return pool.get_op().GetInterval(beg, end, cnt); }
126 template<
class A,
class ArgA,
class ArgB,
class ArgC>
134 __INLINE INMOST_DATA_REAL_TYPE GetValue()
const {
return pool.get_op().GetValue(); }
135 __INLINE
void GetJacobian(INMOST_DATA_REAL_TYPE mult,
Sparse::RowMerger & r)
const {pool.get_op().GetJacobian(mult,r);}
136 __INLINE
void GetJacobian(INMOST_DATA_REAL_TYPE mult,
Sparse::Row & r)
const {pool.get_op().GetJacobian(mult,r);}
137 __INLINE
void GetHessian(INMOST_DATA_REAL_TYPE multJ,
Sparse::Row & J, INMOST_DATA_REAL_TYPE multH,
Sparse::HessianRow & H)
const {pool.get_op().GetHessian(multJ,J,multH,H);}
138 __INLINE
void GetInterval(INMOST_DATA_ENUM_TYPE& beg, INMOST_DATA_ENUM_TYPE& end, INMOST_DATA_ENUM_TYPE& cnt)
const {
return pool.get_op().GetInterval(beg, end, cnt); }
144 virtual INMOST_DATA_REAL_TYPE Value (
const Storage & e)
const = 0;
152 template<
typename RetType>
156 virtual RetType operator()(
const Storage & e)
const = 0;
174 typedef INMOST_DATA_REAL_TYPE type;
176 INMOST_DATA_REAL_TYPE operator()(
const Storage & e)
const {
return var.Value(e);}
183 template<
class VariableType>
187 typedef VariableType Var;
188 virtual INMOST_DATA_REAL_TYPE Value(
const Storage & e)
const = 0;
190 virtual VariableType operator[](
const Storage & e)
const = 0;
197 template<
class VariableType,
class Derived>
201 typedef VariableType Var;
202 virtual INMOST_DATA_REAL_TYPE Value(
const Storage & e)
const {
return static_cast<const Derived *
>(
this)->Value(e);}
204 virtual VariableType operator[](
const Storage & e)
const {
return (*
static_cast<const Derived *
>(
this))[e];}
205 virtual void GetVariation(
const Storage & e,
Sparse::Row & r)
const {
static_cast<const Derived *
>(
this)->GetVariation(e,r);}
206 virtual void GetVariation(
const Storage & e,
Sparse::RowMerger & r)
const {
static_cast<const Derived *
>(
this)->GetVariation(e,r);}
207 operator Derived & () {
return *
static_cast<Derived *
>(
this);}
208 operator const Derived & ()
const {
return *
static_cast<const Derived *
>(
this);}
222 INMOST_DATA_REAL_TYPE Value(
const Storage & e)
const {
return var->Value(e);}
225 void GetVariation(
const Storage & e,
Sparse::Row & r)
const { (*this)[e].GetJacobian(1.0,r); }
240 INMOST_DATA_ENUM_TYPE comp;
252 INMOST_DATA_REAL_TYPE Value(
const Storage & e)
const {
return entry->
Value(e,comp);}
253 INMOST_DATA_ENUM_TYPE Index(
const Storage & e)
const {
return entry->
isValid(e) ? entry->
Index(e,comp):ENUMUNDEF;}
259 return entry->
Value(e,comp);
262 void GetVariation(
const Storage & e,
Sparse::Row & r)
const { (*this)[e].GetJacobian(1.0,r); }
264 bool isUnknown(
const Storage & e)
const {
return entry->
isValid(e)?
true:
false;}
271 INMOST_DATA_REAL_TYPE value;
280 INMOST_DATA_REAL_TYPE Value(
const Storage & e)
const {(void)e;
return value;}
287 void GetVariation(
const Storage & e,
Sparse::Row & r)
const { (*this)[e].GetJacobian(1.0,r); }
295 const INMOST_DATA_REAL_TYPE * value;
304 INMOST_DATA_REAL_TYPE Value(
const Storage & e)
const {(void)e;
return *value;}
311 void GetVariation(
const Storage & e,
Sparse::Row & r)
const { (*this)[e].GetJacobian(1.0,r); }
320 INMOST_DATA_ENUM_TYPE comp;
322 static_variable(
Tag t, INMOST_DATA_ENUM_TYPE pcomp = 0) : value_tag(t), comp(pcomp) {}
326 value_tag = other.value_tag;
330 INMOST_DATA_REAL_TYPE Value(
const Storage & e)
const {
return e->
RealArray(value_tag)[comp];}
336 Tag ValueTag() {
return value_tag;}
337 void GetVariation(
const Storage & e,
Sparse::Row & r)
const { (*this)[e].GetJacobian(1.0,r); }
339 bool isUnknown(
const Storage & e)
const {(void)e;
return false;}
347 INMOST_DATA_ENUM_TYPE comp;
350 stored_variable(
Tag t, INMOST_DATA_ENUM_TYPE pcomp = 0) : variable_tag(t), comp(pcomp)
352 assert(t.GetDataType() == DATA_REAL || t.GetDataType() == DATA_VARIABLE);
357 variable_tag = other.variable_tag;
361 INMOST_DATA_REAL_TYPE Value(
const Storage & e)
const
363 if( variable_tag.GetDataType() == DATA_VARIABLE )
365 else if( variable_tag.GetDataType() == DATA_REAL )
367 else throw NotImplemented;
371 if( variable_tag.GetDataType() == DATA_VARIABLE )
373 else if( variable_tag.GetDataType() == DATA_REAL )
375 else throw NotImplemented;
379 if( variable_tag.GetDataType() == DATA_VARIABLE )
381 else if( variable_tag.GetDataType() == DATA_REAL )
383 else throw NotImplemented;
385 Tag VariableTag() {
return variable_tag;}
386 void GetVariation(
const Storage & e,
Sparse::Row & r)
const { (*this)[e].GetJacobian(1.0,r); }
388 bool isUnknown(
const Storage & e)
const {(void)e;
return false;}
398 typedef std::vector< argument > container;
401 INMOST_DATA_REAL_TYPE value;
406 for(
typename container::iterator it = arg.begin(); it != arg.end(); ++it)
407 value += it->GetValue();
410 __INLINE INMOST_DATA_REAL_TYPE GetValue()
const {
return value; }
411 __INLINE
void GetJacobian(INMOST_DATA_REAL_TYPE mult,
Sparse::RowMerger & r)
const
413 for(
typename container::iterator it = arg.begin(); it != arg.end(); ++it)
414 it->GetJacobian(mult,r);
416 __INLINE
void GetJacobian(INMOST_DATA_REAL_TYPE mult,
Sparse::Row & r)
const
418 for(
typename container::iterator it = arg.begin(); it != arg.end(); ++it)
419 it->GetJacobian(mult,r);
425 for(
typename container::iterator it = arg.begin(); it != arg.end(); ++it)
429 it->GetHessian(multJ,curJ,multH,curH);
449 INMOST_DATA_REAL_TYPE Value(
const Storage & e)
const {
return (*
this)[e].GetValue();}
457 typename stencil_expression<typename A::Var>::container tmp;
460 assert(coefs.size() == elems.size());
461 tmp.resize(elems.size());
462 for(INMOST_DATA_ENUM_TYPE k = 0; k < elems.size(); ++k)
470 void GetVariation(
const Storage & e,
Sparse::Row & r)
const { (*this)[e].GetJacobian(1.0,r); }
484 INMOST_DATA_REAL_TYPE Value(
const Storage & e)
const {
return (*
this)[e].GetValue();}
492 typename A::Var arg = Arg[e];
494 std::pair<INMOST_DATA_REAL_TYPE, INMOST_DATA_REAL_TYPE> both = Table.GetBoth(arg.GetValue());
495 pool.get_op().SetFunctionValue(both.first);
496 pool.get_op().SetFunctionDerivative(both.second);
499 void GetVariation(
const Storage & e,
Sparse::Row & r)
const { (*this)[e].GetJacobian(1.0,r); }
506 template<
class A,
class B>
512 ElementType types_true;
515 etype_branch_variable(ElementType _types_true,
const A & _ArgA,
const B & _ArgB) : types_true(_types_true), ArgA(_ArgA), ArgB(_ArgB) {}
521 types_true = other.types_true;
527 INMOST_DATA_REAL_TYPE
Value(
const Storage & e)
const {
return (*
this)[e].GetValue();}
534 if( e->GetElementType() & types_true )
549 template<
class A,
class B>
558 marker_branch_variable(MarkerType _marker,
const A & _ArgA,
const B & _ArgB) : marker(_marker), ArgA(_ArgA), ArgB(_ArgB) {}
564 marker = other.marker;
570 INMOST_DATA_REAL_TYPE
Value(
const Storage & e)
const {
return (*
this)[e].GetValue();}
577 if( isPrivate(marker) ? e->GetPrivateMarker(marker) : e->GetMarker(marker) )
591 template<
class Expr,
class A>
600 INMOST_DATA_REAL_TYPE Value(
const Storage & e)
const {
return (*
this)[e].GetValue();}
611 void GetVariation(
const Storage & e,
Sparse::Row & r)
const { (*this)[e].GetJacobian(1.0,r); }
616 template<
class Expr,
class A>
621 INMOST_DATA_REAL_TYPE Right;
624 : Left(pleft), Right(pright) {}
627 INMOST_DATA_REAL_TYPE Value(
const Storage & e)
const {
return (*
this)[e].GetValue();}
638 void GetVariation(
const Storage & e,
Sparse::Row & r)
const { (*this)[e].GetJacobian(1.0,r); }
643 template<
class Expr,
class A,
class B>
651 : Left(pleft), Right(pright) {}
654 INMOST_DATA_REAL_TYPE Value(
const Storage & e)
const {
return (*
this)[e].GetValue();}
665 void GetVariation(
const Storage & e,
Sparse::Row & r)
const { (*this)[e].GetJacobian(1.0,r); }
670 template<
class Expr,
class A,
class B,
class C>
679 : Cond(pcond), Left(pleft), Right(pright) {}
682 INMOST_DATA_REAL_TYPE Value(
const Storage & e)
const {
return (*
this)[e].GetValue();}
693 void GetVariation(
const Storage & e,
Sparse::Row & r)
const { (*this)[e].GetJacobian(1.0,r); }
700 template<
class A,
class B,
class C>
702 INMOST::ternary_custom_variable<INMOST::condition_expression<typename A::Var, typename B::Var, typename C::Var>,A,B,C> condition(
INMOST::shell_dynamic_variable<typename A::Var, A> const & control,
INMOST::shell_dynamic_variable<typename B::Var, B> const & if_ge_zero,
INMOST::shell_dynamic_variable<typename C::Var, C> const & if_lt_zero) {
return INMOST::ternary_custom_variable<INMOST::condition_expression<typename A::Var, typename B::Var, typename C::Var>,A,B,C>(control,if_ge_zero,if_lt_zero); }
712 template<
class A,
class B> __INLINE
INMOST::binary_custom_variable<INMOST::addition_expression<typename A::Var,typename B::Var>,A, B> operator+(
INMOST::shell_dynamic_variable<typename A::Var,A> const & Left,
INMOST::shell_dynamic_variable<typename B::Var,B> const & Right) {
return INMOST::binary_custom_variable<INMOST::addition_expression<typename A::Var,typename B::Var>,A, B> (Left, Right); }
713 template<
class A,
class B> __INLINE
INMOST::binary_custom_variable<INMOST::subtraction_expression<typename A::Var,typename B::Var>,A, B> operator-(
INMOST::shell_dynamic_variable<typename A::Var,A> const & Left,
INMOST::shell_dynamic_variable<typename B::Var,B> const & Right) {
return INMOST::binary_custom_variable<INMOST::subtraction_expression<typename A::Var,typename B::Var>, A, B> (Left, Right); }
714 template<
class A,
class B> __INLINE
INMOST::binary_custom_variable<INMOST::multiplication_expression<typename A::Var,typename B::Var>,A, B> operator*(
INMOST::shell_dynamic_variable<typename A::Var,A> const & Left,
INMOST::shell_dynamic_variable<typename B::Var,B> const & Right) {
return INMOST::binary_custom_variable<INMOST::multiplication_expression<typename A::Var,typename B::Var>, A, B> (Left, Right); }
715 template<
class A,
class B> __INLINE
INMOST::binary_custom_variable<INMOST::division_expression<typename A::Var,typename B::Var>,A, B> operator/(
INMOST::shell_dynamic_variable<typename A::Var,A> const & Left,
INMOST::shell_dynamic_variable<typename B::Var,B> const & Right) {
return INMOST::binary_custom_variable<INMOST::division_expression<typename A::Var,typename B::Var>, A, B> (Left, Right); }
716 template<
class A,
class B> __INLINE
INMOST::binary_custom_variable<INMOST::pow_expression<typename A::Var,typename B::Var>,A, B> pow(
INMOST::shell_dynamic_variable<typename A::Var,A> const & Left,
INMOST::shell_dynamic_variable<typename B::Var,B> const & Right) {
return INMOST::binary_custom_variable<INMOST::pow_expression<typename A::Var,typename B::Var>,A, B>(Left, Right); }
731 std::vector< INMOST::const_multiplication_expression<typename A::Var> > tmp;
732 for( INMOST_DATA_ENUM_TYPE k = 0; k < num; ++k)
if( elems[k] != 0 )
This class is used to organize unknowns in abstract way, it should be registered with and managed by ...
virtual unknown Unknown(const Storage &e, INMOST_DATA_ENUM_TYPE pos) const =0
Return unknown in vector of variables of the block at certain position.
virtual INMOST_DATA_REAL_TYPE Value(const Storage &e, INMOST_DATA_ENUM_TYPE pos) const =0
Return value in vector of unknowns of the block at certain position.
bool isValid(const Storage &e) const
Check that the block is valid on given element.
virtual INMOST_DATA_ENUM_TYPE Index(const Storage &e, INMOST_DATA_ENUM_TYPE pos) const =0
Return index in vector of indices of the block at certain position.
The Automatizator class helps in defining primary unknowns of the model and enhances user experience ...
AbstractEntry & GetEntry(INMOST_DATA_ENUM_TYPE ind)
Retrieve the block from automatizator by index.
Class to store the compressed symmetric matrix of a hessian row.
void Clear()
Clear all data of the current row.
static void MergeSortedRows(INMOST_DATA_REAL_TYPE alpha, const HessianRow &left, INMOST_DATA_REAL_TYPE beta, const HessianRow &right, HessianRow &output)
output = alpha * left + beta *right
This class may be used to sum multiple sparse rows.
Class to store the sparse matrix row.
void Swap(Row &other)
Exchange all the data with another row.
void Clear()
Clear all data of the current row.
static void MergeSortedRows(INMOST_DATA_REAL_TYPE alpha, const Row &left, INMOST_DATA_REAL_TYPE beta, const Row &right, Row &output)
Add up two rows.
Storage type for representing arrays of Element references.
Base class for Mesh, Element, and ElementSet classes.
__INLINE var_array VariableArray(const Tag &tag) const
Retrieve array of variables associated with Tag.
__INLINE real_array RealArray(const Tag &tag) const
Retrieve array of real values associated with Tag.
This class provides the access to the individual mesh datum and general information about it.
This class makes possible to evaluate different expressions on different element types.
etype_branch_variable(ElementType _types_true, const A &_ArgA, const B &_ArgB)
Constructor. Used by etype_branch function.
void GetVariation(const Storage &e, Sparse::RowMerger &r) const
Retrieve first derivatives of variable expression on provided element e, with supplimentary structure...
multivar_expression Variable(const Storage &e) const
Get value with derivatives of variable expression on provided element e.
etype_branch_variable & operator=(etype_branch_variable const &other)
Assignment operator.
abstract_dynamic_variable * Copy() const
Make a copy of this class, used to reproduce and store a tree of variable expressions.
INMOST_DATA_REAL_TYPE Value(const Storage &e) const
Get value of variable expression on provided element e.
etype_branch_variable(const etype_branch_variable &other)
Copy constructor.
multivar_expression operator[](const Storage &e) const
Build an expression associated with variable expression on provided element e.
void GetVariation(const Storage &e, Sparse::Row &r) const
Retrieve first derivatives of variable expression on provided element e, default approach.
This class makes possible to evaluate different expressions depending on the markers.
abstract_dynamic_variable * Copy() const
Make a copy of this class, used to reproduce and store a tree of variable expressions.
void GetVariation(const Storage &e, Sparse::RowMerger &r) const
Retrieve first derivatives of variable expression on provided element e, with supplimentary structure...
multivar_expression operator[](const Storage &e) const
Build an expression associated with variable expression on provided element e.
marker_branch_variable & operator=(marker_branch_variable const &other)
Assignment operator.
void GetVariation(const Storage &e, Sparse::Row &r) const
Retrieve first derivatives of variable expression on provided element e, default approach.
marker_branch_variable(const marker_branch_variable &other)
Copy constructor.
multivar_expression Variable(const Storage &e) const
Get value with derivatives of variable expression on provided element e.
marker_branch_variable(MarkerType _marker, const A &_ArgA, const B &_ArgB)
Constructor. Used by marker_branch function.
INMOST_DATA_REAL_TYPE Value(const Storage &e) const
Get value of variable expression on provided element e.
A class that represents a variable with multiple first order variations.