1#ifndef _RHEOLEF_FORM_EXPR_VARIATIONAL_H
2#define _RHEOLEF_FORM_EXPR_VARIATIONAL_H
48#include "rheolef/field_expr_variational.h"
69template<
class UnaryFunction,
class Expr>
79 typename Expr::value_type
115 _expr.initialize (pops, iopt);
118 _expr.initialize (
gh, pops, iopt);
120 template<
class Result>
124 Eigen::Tensor<Result,3>& value)
const
128 _expr.evaluate (omega_K, K, value);
129 for (
size_type i = 0, ni = value.dimension(0); i < ni; ++i) {
130 for (
size_type j = 0, nj = value.dimension(1); j < nj; ++j) {
131 for (
size_type k = 0, nk = value.dimension(2); k < nk; ++k) {
132 value(i,j,k) =
_f (value(i,j,k));
135 template<
class Result>
153#define _RHEOLEF_make_form_expr_v2_variational_unary(FUNCTION,FUNCTOR) \
154template<class Expr> \
158 details::is_form_expr_v2_variational_arg<Expr>::value \
159 ,details::form_expr_v2_variational_unary< \
164FUNCTION (const Expr& expr) \
166 return details::form_expr_v2_variational_unary <FUNCTOR,Expr> (FUNCTOR(), expr); \
171#undef _RHEOLEF_make_form_expr_v2_variational_unary
183template<
class BinaryFunction,
class Expr1,
class Expr2>
192 typename Expr1::value_type
195 typename Expr1::value_type
196 ,
typename Expr2::value_type
202 typename Expr1::vf_tag_type,
208 typename Expr2::dual_self_type>
210 typedef typename and_type<
typename Expr1::maybe_symmetric::type,
211 typename Expr2::maybe_symmetric::type>::type
240 _expr1.initialize (pops, iopt);
241 _expr2.initialize (pops, iopt);
248 template<
class Result>
252 Eigen::Tensor<Result,3>& value)
const
258 Eigen::Tensor<float_type,3> value1;
_expr1.evaluate (omega_K, K, value1);
259 Eigen::Tensor<float_type,3> value2;
_expr2.evaluate (omega_K, K, value2);
260 value.resize (value1.dimension(0), value1.dimension(1), value1.dimension(2));
261 check_macro (value1.dimension(0) == value2.dimension(0) &&
262 value1.dimension(1) == value2.dimension(1) &&
263 value1.dimension(2) == value2.dimension(2),
264 "invalid sizes value1("
265 << value1.dimension(0) <<
","<< value1.dimension(1) <<
","<< value1.dimension(2) <<
") and value2("
266 << value2.dimension(0) <<
","<< value2.dimension(1) <<
","<< value2.dimension(2) <<
")");
267 for (
size_type i = 0, ni = value.dimension(0); i < ni; ++i) {
268 for (
size_type j = 0, nj = value.dimension(1); j < nj; ++j) {
269 for (
size_type k = 0, nk = value.dimension(2); k < nk; ++k) {
270 value(i,j,k) =
_f (value1(i,j,k), value2(i,j,k));
273 template<
class Result>
278 Eigen::Tensor<Result,3>& value)
const
284 Eigen::Tensor<float_type,3> value1;
_expr1.evaluate_on_side (omega_K, K, sid, value1);
285 Eigen::Tensor<float_type,3> value2;
_expr2.evaluate_on_side (omega_K, K, sid, value2);
286 value.resize (value1.dimension(0), value1.dimension(1), value1.dimension(2));
287 check_macro (value1.dimension(0) == value2.dimension(0) &&
288 value1.dimension(1) == value2.dimension(1) &&
289 value1.dimension(2) == value2.dimension(2),
290 "invalid sizes value1("
291 << value1.dimension(0) <<
","<< value1.dimension(1) <<
","<< value1.dimension(2) <<
") and value2("
292 << value2.dimension(0) <<
","<< value2.dimension(1) <<
","<< value2.dimension(2) <<
")");
293 for (
size_type i = 0, ni = value.dimension(0); i < ni; ++i) {
294 for (
size_type j = 0, nj = value.dimension(1); j < nj; ++j) {
295 for (
size_type k = 0, nk = value.dimension(2); k < nk; ++k) {
296 value(i,j,k) =
_f (value1(i,j,k), value2(i,j,k));
299 template<
class Result>
322#define _RHEOLEF_form_expr_v2_variational_binary(FUNCTION,FUNCTOR) \
323template <class Expr1, class Expr2> \
327 details::is_form_expr_v2_variational_arg <Expr1>::value \
328 && details::is_form_expr_v2_variational_arg <Expr2>::value \
329 ,details::form_expr_v2_variational_binary< \
335FUNCTION (const Expr1& expr1, const Expr2& expr2) \
337 return details::form_expr_v2_variational_binary \
338 <FUNCTOR, Expr1, Expr2> \
339 (FUNCTOR(), expr1, expr2); \
345#undef _RHEOLEF_form_expr_v2_variational_binary
355template<
class BinaryFunction,
class Expr1,
class Expr2>
364 typename Expr1::value_type
367 typename Expr1::value_type
368 ,
typename Expr2::value_type
374 typename Expr1::vf_tag_type,
384 typename Expr2::dual_self_type>::type>::type
418 _expr1.initialize (pops, iopt);
419 _expr2.initialize (pops, iopt);
430 template<
class ValueType,
class Arg1,
class Arg2>
434 Eigen::Tensor<ValueType,3>& value)
const
436 typedef long int eig_idx_t;
439 Eigen::Matrix<Arg2,Eigen::Dynamic,Eigen::Dynamic> v_test;
_expr2.evaluate (omega_K, K, v_test);
440 Eigen::Matrix<Arg1,Eigen::Dynamic,Eigen::Dynamic> u_trial;
_expr1.evaluate (omega_K, K, u_trial);
441 check_macro(u_trial.rows() == v_test.rows(),
"mult: invalid sizes u_trial("
442 <<u_trial.rows()<<
","<<u_trial.cols() <<
") and v_test("
443 <<v_test.rows() <<
","<<v_test.cols()<<
")");
444 eig_idx_t nq = u_trial.rows();
445 eig_idx_t ni = v_test.cols();
446 eig_idx_t nj = u_trial.cols();
447 value.resize(nq,ni,nj);
448 for (eig_idx_t q = 0; q < nq; ++q) {
449 for (eig_idx_t i = 0; i < ni; ++i) {
450 for (eig_idx_t j = 0; j < nj; ++j) {
451 value(q,i,j) =
_f (u_trial(q,j), v_test(q,i));
455 Eigen::Matrix<Arg2,Eigen::Dynamic,Eigen::Dynamic> v_test;
_expr1.evaluate (omega_K, K, v_test);
456 Eigen::Matrix<Arg1,Eigen::Dynamic,Eigen::Dynamic> u_trial;
_expr2.evaluate (omega_K, K, u_trial);
457 check_macro(u_trial.rows() == v_test.rows(),
"binary: invalid sizes");
458 eig_idx_t nq = u_trial.rows();
459 eig_idx_t ni = v_test.cols();
460 eig_idx_t nj = u_trial.cols();
461 value.resize(nq,ni,nj);
462 for (eig_idx_t q = 0; q < nq; ++q) {
463 for (eig_idx_t i = 0; i < ni; ++i) {
464 for (eig_idx_t j = 0; j < nj; ++j) {
465 value(q,i,j) =
_f (u_trial(q,j), v_test(q,i));
469 template<
class ValueType,
class Arg1,
class Arg2>
474 Eigen::Tensor<ValueType,3>& value)
const
476 typedef long int eig_idx_t;
477 bool do_local_component_assembly =
true;
480 Eigen::Matrix<Arg2,Eigen::Dynamic,Eigen::Dynamic> v_test;
_expr2.evaluate_on_side (omega_K, K, sid, v_test, do_local_component_assembly);
481 Eigen::Matrix<Arg1,Eigen::Dynamic,Eigen::Dynamic> u_trial;
_expr1.evaluate_on_side (omega_K, K, sid, u_trial, do_local_component_assembly);
482 check_macro(u_trial.rows() == v_test.rows(),
"invalid sizes u_trial("
483 <<u_trial.rows()<<
","<<u_trial.cols() <<
") and v_test("
484 <<v_test.rows() <<
","<<v_test.cols()<<
")");
485 eig_idx_t nq = u_trial.rows();
486 eig_idx_t ni = v_test.cols();
487 eig_idx_t nj = u_trial.cols();
488 value.resize(nq,ni,nj);
489 for (eig_idx_t q = 0; q < nq; ++q) {
490 for (eig_idx_t i = 0; i < ni; ++i) {
491 for (eig_idx_t j = 0; j < nj; ++j) {
492 value(q,i,j) =
_f (u_trial(q,j), v_test(q,i));
496 Eigen::Matrix<Arg2,Eigen::Dynamic,Eigen::Dynamic> v_test;
_expr1.evaluate_on_side (omega_K, K, sid, v_test, do_local_component_assembly);
497 Eigen::Matrix<Arg1,Eigen::Dynamic,Eigen::Dynamic> u_trial;
_expr2.evaluate_on_side (omega_K, K, sid, u_trial, do_local_component_assembly);
498 check_macro(u_trial.rows() == v_test.rows(),
"binary: invalid sizes");
499 eig_idx_t nq = u_trial.rows();
500 eig_idx_t ni = v_test.cols();
501 eig_idx_t nj = u_trial.cols();
502 value.resize(nq,ni,nj);
503 for (eig_idx_t q = 0; q < nq; ++q) {
504 for (eig_idx_t i = 0; i < ni; ++i) {
505 for (eig_idx_t j = 0; j < nj; ++j) {
506 value(q,i,j) =
_f (u_trial(q,j), v_test(q,i));
511 template<
class This,
class ValueType,
521 Eigen::Tensor<ValueType,3>& value)
const
523 obj.template evaluate_internal<ValueType, Arg1, Arg2> (omega_K, K, value);
530 Eigen::Tensor<ValueType,3>& value)
const
532 obj.template evaluate_on_side_internal<ValueType, Arg1, Arg2> (omega_K, K, sid, value);
535 template<
class ValueType>
539 Eigen::Tensor<ValueType,3>& value)
const
542 typename Expr1::value_type
543 ,
typename Expr2::value_type
544 ,ValueType>::first_argument_type first_argument_type;
546 typename Expr1::value_type
547 ,
typename Expr2::value_type
548 ,ValueType>::second_argument_type second_argument_type;
552 first_argument_type, first_argument_tag,
553 second_argument_type, second_argument_tag> eval;
554 eval (*
this, omega_K, K, value);
556 template<
class ValueType>
561 Eigen::Tensor<ValueType,3>& value)
const
564 typename Expr1::value_type
565 ,
typename Expr2::value_type
566 ,ValueType>::first_argument_type first_argument_type;
568 typename Expr1::value_type
569 ,
typename Expr2::value_type
570 ,ValueType>::second_argument_type second_argument_type;
574 first_argument_type, first_argument_tag,
575 second_argument_type, second_argument_tag> eval;
576 eval (*
this, omega_K, K, sid, value);
578 template<
class ValueType>
581 typename Expr1::value_type
582 ,
typename Expr2::value_type
583 ,ValueType>::first_argument_type A1;
585 typename Expr1::value_type
586 ,
typename Expr2::value_type
587 ,ValueType>::second_argument_type A2;
606template<
class Expr1,
class Expr2,
class Sfinae =
void>
609template <
class Expr1,
class Expr2>
615 is_field_expr_v2_variational_arg<Expr1>::value
616 && is_field_expr_v2_variational_arg<Expr2>::value
620 is_field_expr_v2_variational_arg<Expr1>
621 ,is_field_expr_v2_variational_arg<Expr2>
623 typename Expr1::vf_tag_type
624 ,typename dual_vf_tag<typename Expr2::vf_tag_type>::type
631#define _RHEOLEF_form_expr_v2_variational_binary_field(FUNCTION,FUNCTOR) \
632template <class Expr1, class Expr2> \
636 details::is_form_expr_v2_variational_binary_field <Expr1,Expr2>::value \
637 ,details::form_expr_v2_variational_binary_field< \
643FUNCTION (const Expr1& expr1, const Expr2& expr2) \
645 return details::form_expr_v2_variational_binary_field \
646 <FUNCTOR, Expr1, Expr2> \
647 (FUNCTOR(), expr1, expr2); \
655#undef _RHEOLEF_form_expr_v2_variational_binary_field
666template<
class BinaryFunction,
class NLExpr,
class VFExpr>
675 typename NLExpr::value_type
678 typename NLExpr::value_type
679 ,
typename VFExpr::value_type
689 typedef form_expr_v2_variational_binary_binded <BinaryFunction,NLExpr,VFExpr>
self_type;
690 typedef form_expr_v2_variational_binary_binded <BinaryFunction,NLExpr,typename VFExpr::dual_self_type>
702 const NLExpr& nl_expr,
703 const VFExpr& vf_expr)
728 template<
class Result>
732 Eigen::Tensor<Result,3>& value)
const
736 Eigen::Matrix<Arg1,Eigen::Dynamic,1> value1;
_nl_expr.evaluate (omega_K, K, value1);
737 Eigen::Tensor<float_type,3> value2;
_vf_expr.evaluate (omega_K, K, value2);
738 check_macro (value1.size() == value2.dimension(0),
"invalid sizes");
739 size_type loc_nnod = value2.dimension(0);
740 size_type loc_ndof1 = value2.dimension(1);
741 size_type loc_ndof2 = value2.dimension(2);
742 value.resize(loc_nnod,loc_ndof1,loc_ndof2);
743 for (
size_type loc_inod = 0; loc_inod < loc_nnod; ++loc_inod) {
744 for (
size_type loc_jdof = 0; loc_jdof < loc_ndof1; ++loc_jdof) {
745 for (
size_type loc_kdof = 0; loc_kdof < loc_ndof2; ++loc_kdof) {
746 value(loc_inod,loc_jdof,loc_kdof)
747 =
_f (value1(loc_inod,loc_jdof), value2(loc_inod,loc_jdof,loc_kdof));
750 template<
class Result>
774template<
class Expr1,
class Expr2,
class Sfinae =
void>
777template<
class Expr1,
class Expr2>
783 is_field_expr_v2_nonlinear_arg <Expr1>::value
784 && ! is_rheolef_arithmetic <Expr1>::value
785 && is_form_expr_v2_variational_arg<Expr2>::value
791template<
class Expr1,
class Expr2>
797#define _RHEOLEF_make_form_expr_v2_variational_binary_operator_multiplies_divides_left(FUNCTION,FUNCTOR) \
798template<class Expr1, class Expr2> \
802 details::is_form_expr_v2_variational_binary_multiplies_divides_left <Expr1,Expr2>::value \
803 ,details::form_expr_v2_variational_binary_binded< \
805 ,typename details::field_expr_v2_nonlinear_terminal_wrapper_traits<Expr1>::type \
809FUNCTION (const Expr1& expr1, const Expr2& expr2) \
811 typedef typename details::field_expr_v2_nonlinear_terminal_wrapper_traits<Expr1>::type wrap1_t; \
812 return details::form_expr_v2_variational_binary_binded \
813 <FUNCTOR, wrap1_t, Expr2> \
814 (FUNCTOR(), wrap1_t(expr1), expr2); \
817#define _RHEOLEF_make_form_expr_v2_variational_binary_operator_multiplies_divides_right(FUNCTION,FUNCTOR) \
818template<class Expr1, class Expr2> \
822 details::is_form_expr_v2_variational_binary_multiplies_divides_right <Expr1,Expr2>::value \
823 ,details::form_expr_v2_variational_binary_binded< \
824 details::swapper<FUNCTOR> \
825 , typename details::field_expr_v2_nonlinear_terminal_wrapper_traits<Expr2>::type \
829FUNCTION (const Expr1& expr1, const Expr2& expr2) \
831 typedef typename details::field_expr_v2_nonlinear_terminal_wrapper_traits<Expr2>::type wrap2_t; \
832 return details::form_expr_v2_variational_binary_binded \
833 <details::swapper<FUNCTOR>, wrap2_t, Expr1> \
834 (details::swapper<FUNCTOR>(FUNCTOR()), wrap2_t(expr2), expr1); \
836#define _RHEOLEF_make_form_expr_v2_variational_binary_operator_multiplies_divides(FUNCTION,FUNCTOR) \
837 _RHEOLEF_make_form_expr_v2_variational_binary_operator_multiplies_divides_left (FUNCTION,FUNCTOR) \
838 _RHEOLEF_make_form_expr_v2_variational_binary_operator_multiplies_divides_right (FUNCTION,FUNCTOR)
845#undef _RHEOLEF_make_form_expr_v2_variational_binary_operator_multiplies_divides_left
846#undef _RHEOLEF_make_form_expr_v2_variational_binary_operator_multiplies_divides_right
847#undef _RHEOLEF_make_form_expr_v2_variational_binary_operator_multiplies_divides
854template<
class Expr1,
class Expr2,
class Sfinae =
void>
855struct is_form_expr_v2_variational_binary_multiplies_divides_constant_left : std::false_type {};
857template<
class Expr1,
class Expr2>
858struct is_form_expr_v2_variational_binary_multiplies_divides_constant_left <
863 is_rheolef_arithmetic <Expr1>::value
864 && is_form_expr_v2_variational_arg<Expr2>::value
870template<
class Expr1,
class Expr2>
871struct is_form_expr_v2_variational_binary_multiplies_divides_constant_right
872: is_form_expr_v2_variational_binary_multiplies_divides_constant_left <Expr2,Expr1> {};
876#define _RHEOLEF_make_form_expr_v2_variational_binary_operator_multiplies_divides_constant_left(FUNCTION,FUNCTOR) \
877template<class Expr1, class Expr2> \
881 details::is_form_expr_v2_variational_binary_multiplies_divides_constant_left <Expr1,Expr2>::value \
882 ,details::form_expr_v2_variational_unary< \
883 details::binder_first <FUNCTOR, Expr1> \
887FUNCTION (const Expr1& expr1, const Expr2& expr2) \
889 return details::form_expr_v2_variational_unary \
890 <details::binder_first <FUNCTOR,Expr1>, Expr2> \
891 (details::binder_first <FUNCTOR,Expr1> (FUNCTOR(), expr1), expr2); \
894#define _RHEOLEF_make_form_expr_v2_variational_binary_operator_multiplies_divides_constant_right(FUNCTION,FUNCTOR) \
895template<class Expr1, class Expr2> \
899 details::is_form_expr_v2_variational_binary_multiplies_divides_constant_right <Expr1,Expr2>::value \
900 ,details::form_expr_v2_variational_unary< \
901 details::binder_second <FUNCTOR, Expr2> \
905FUNCTION (const Expr1& expr1, const Expr2& expr2) \
907 return details::form_expr_v2_variational_unary \
908 <details::binder_second <FUNCTOR,Expr2>, Expr1> \
909 (details::binder_second <FUNCTOR,Expr2> (FUNCTOR(), expr2), expr1); \
912#define _RHEOLEF_make_form_expr_v2_variational_binary_operator_multiplies_divides_constant(FUNCTION,FUNCTOR) \
913 _RHEOLEF_make_form_expr_v2_variational_binary_operator_multiplies_divides_constant_left (FUNCTION,FUNCTOR) \
914 _RHEOLEF_make_form_expr_v2_variational_binary_operator_multiplies_divides_constant_right (FUNCTION,FUNCTOR)
923#undef _RHEOLEF_make_form_expr_v2_variational_binary_operator_multiplies_divides_constant_right
924#undef _RHEOLEF_make_form_expr_v2_variational_binary_operator_multiplies_divides_constant_left
925#undef _RHEOLEF_make_form_expr_v2_variational_binary_operator_multiplies_divides_constant
field gh(Float epsilon, Float t, const field &uh, const test &v)
generic mesh with rerefence counting
see the geo_element page for the full documentation
reference_element::size_type size_type
see the integrate_option page for the full documentation
check_macro(expr1.have_homogeneous_space(Xh1), "dual(expr1,expr2); expr1 should have homogeneous space. HINT: use dual(interpolate(Xh, expr1),expr2)")
std::pair< std::false_type, std::false_type > vf_tag_00
This file is part of Rheolef.
T ddot(const tensor_basic< T > &a, const tensor_basic< T > &b)
ddot(x,y): see the expression page for the full documentation
T dddot(const tensor3_basic< T > &a, const tensor3_basic< T > &b)
rheolef::std enable_if ::type dot const Expr1 expr1, const Expr2 expr2 dot(const Expr1 &expr1, const Expr2 &expr2)