10#ifndef THYRA_DEFAULT_MULTI_PERIOD_MODEL_EVALUATOR_HPP 
   11#define THYRA_DEFAULT_MULTI_PERIOD_MODEL_EVALUATOR_HPP 
   14#include "Thyra_ModelEvaluatorDefaultBase.hpp" 
   15#include "Thyra_DefaultProductVectorSpace.hpp" 
   16#include "Thyra_DefaultBlockedTriangularLinearOpWithSolveFactory.hpp"  
   17#include "Thyra_DefaultBlockedLinearOp.hpp" 
   18#include "Thyra_ModelEvaluatorDelegatorBase.hpp" 
   19#include "Thyra_ProductVectorBase.hpp" 
   20#include "Teuchos_implicit_cast.hpp" 
   21#include "Teuchos_AbstractFactory.hpp"  
   22#include "Teuchos_AbstractFactoryStd.hpp"  
  303  void set_z_indexes_and_create_period_l_map( 
const Array<int> &z_indexes );
 
  305  void wrapNominalValuesAndBounds();
 
  315  int period_l(
const int l)
 const 
  318      return period_l_map_[l];
 
  321  int numPeriodZs()
 const { 
return z_indexes_.
size(); }
 
  323  int N()
 const { 
return x_bar_space_->numBlocks(); }
 
 
  335template<
class Scalar>
 
  337  :g_index_(-1), Np_(-1), Ng_(-1)
 
 
  341template<
class Scalar>
 
  353  :g_index_(-1), Np_(-1), Ng_(-1)
 
  356    N, periodModels, z_indexes, z, g_index, g_weights,
 
  357    x_bar_space, f_bar_space, W_bar_factory
 
 
  362template<
class Scalar>
 
  382  MEB::InArgs<Scalar> periodInArgs = periodModels[0]->createInArgs();
 
  383  MEB::OutArgs<Scalar> periodOutArgs = periodModels[0]->createOutArgs();
 
  384  for ( 
int k = 0; k < implicit_cast<int>(z_indexes.
size()); ++k ) {
 
  392  Np_ = periodInArgs.Np() - z_indexes.
size();
 
  396  set_z_indexes_and_create_period_l_map(z_indexes);
 
  398  periodModel_ = periodModels[0]; 
 
  400  periodModels_ = periodModels;
 
  406  g_weights_ = g_weights;
 
  408  if ( periodInArgs.supports(MEB::IN_ARG_x) ) {
 
  409    if( !is_null(x_bar_space) ) {
 
  412      x_bar_space_ = x_bar_space;
 
  415      x_bar_space_ = productVectorSpace(periodModel_->get_x_space(),N);
 
  420  if ( periodOutArgs.supports(MEB::OUT_ARG_f) ) {
 
  421    if( !is_null(f_bar_space) ) {
 
  424      f_bar_space_ = f_bar_space;
 
  427      f_bar_space_ = productVectorSpace(periodModel_->get_f_space(),N);
 
  432  if ( periodOutArgs.supports(MEB::OUT_ARG_W) ) {
 
  433    if ( !is_null(W_bar_factory) ) {
 
  435      W_bar_factory_ = W_bar_factory;
 
  439        defaultBlockedTriangularLinearOpWithSolveFactory<Scalar>(
 
  440          periodModel_->get_W_factory() );
 
  444  wrapNominalValuesAndBounds();
 
 
  449template<
class Scalar>
 
  457  const int N = z_.size();
 
  464  for( 
int i = 0; i < N; ++i ) {
 
 
  478template<
class Scalar>
 
  485template<
class Scalar>
 
  492template<
class Scalar>
 
  500template<
class Scalar>
 
  508template<
class Scalar>
 
  512  return  periodModel_->get_p_space(period_l(l));
 
 
  516template<
class Scalar>
 
  520  return  periodModel_->get_p_names(period_l(l));
 
 
  524template<
class Scalar>
 
  529  return periodModel_->get_g_space(g_index_);
 
 
  533template<
class Scalar>
 
  537  return  periodModel_->get_g_names(j);
 
 
  541template<
class Scalar>
 
  545  return nominalValues_;
 
 
  549template<
class Scalar>
 
  557template<
class Scalar>
 
  565template<
class Scalar>
 
  571    W_op_bar = defaultBlockedLinearOp<Scalar>();
 
  572  W_op_bar->beginBlockFill(f_bar_space_,x_bar_space_);
 
  573  const int N = x_bar_space_->numBlocks();
 
  574  for ( 
int i = 0; i < N; ++i ) {
 
  575    W_op_bar->setNonconstBlock( i, i, periodModel_->create_W_op() );
 
  577  W_op_bar->endBlockFill();
 
 
  582template<
class Scalar>
 
  590template<
class Scalar>
 
  594  return W_bar_factory_;
 
 
  598template<
class Scalar>
 
  603  MEB::InArgs<Scalar> periodInArgs = periodModel_->createInArgs();
 
  604  MEB::InArgsSetup<Scalar> inArgs;
 
  605  inArgs.setModelEvalDescription(this->description());
 
  607  inArgs.setSupports( MEB::IN_ARG_x, periodInArgs.supports(MEB::IN_ARG_x) );
 
 
  612template<
class Scalar>
 
  615  ,
const bool                                   wasSolved
 
 
  630template<
class Scalar>
 
  639template<
class Scalar>
 
  640RCP<LinearOpBase<Scalar> >
 
  641DefaultMultiPeriodModelEvaluator<Scalar>::create_DgDx_dot_op_impl(
int j)
 const 
  648template<
class Scalar>
 
  649RCP<LinearOpBase<Scalar> >
 
  650DefaultMultiPeriodModelEvaluator<Scalar>::create_DgDx_op_impl(
int j)
 const 
  657template<
class Scalar>
 
  658RCP<LinearOpBase<Scalar> >
 
  659DefaultMultiPeriodModelEvaluator<Scalar>::create_DgDp_op_impl(
int j, 
int l)
 const 
  666template<
class Scalar>
 
  667ModelEvaluatorBase::OutArgs<Scalar>
 
  668DefaultMultiPeriodModelEvaluator<Scalar>::createOutArgsImpl()
 const 
  671  typedef ModelEvaluatorBase MEB;
 
  673  MEB::OutArgs<Scalar> periodOutArgs = periodModel_->createOutArgs();
 
  674  MEB::OutArgsSetup<Scalar> outArgs;
 
  676  outArgs.setModelEvalDescription(this->description());
 
  678  outArgs.set_Np_Ng(Np_,Ng_);
 
  681  if (periodOutArgs.supports(MEB::OUT_ARG_f) ) {
 
  682    outArgs.setSupports(MEB::OUT_ARG_f);
 
  686  if (periodOutArgs.supports(MEB::OUT_ARG_W_op) ) {
 
  687    outArgs.setSupports(MEB::OUT_ARG_W_op);
 
  688    outArgs.set_W_properties(periodOutArgs.get_W_properties());
 
  694  for ( 
int l = 0; l < Np_; ++l ) {
 
  695    const int period_l = this->period_l(l);
 
  696    const MEB::DerivativeSupport period_DfDp_l_support
 
  697      = periodOutArgs.supports(MEB::OUT_ARG_DfDp,period_l);
 
  698    if (!period_DfDp_l_support.none()) {
 
  699      outArgs.setSupports( MEB::OUT_ARG_DfDp, l, period_DfDp_l_support );
 
  700      outArgs.set_DfDp_properties(
 
  701        l, periodOutArgs.get_DfDp_properties(period_l) );
 
  706  const MEB::DerivativeSupport
 
  707    period_DgDx_dot_support = periodOutArgs.supports(MEB::OUT_ARG_DgDx_dot,g_index_);
 
  708  if (!period_DgDx_dot_support.none()) {
 
  709    outArgs.setSupports( MEB::OUT_ARG_DgDx_dot, 0, period_DgDx_dot_support );
 
  710    outArgs.set_DgDx_dot_properties(
 
  711      0, periodOutArgs.get_DgDx_dot_properties(g_index_) );
 
  715  const MEB::DerivativeSupport
 
  716    period_DgDx_support = periodOutArgs.supports(MEB::OUT_ARG_DgDx,g_index_);
 
  717  if (!period_DgDx_support.none()) {
 
  718    outArgs.setSupports( MEB::OUT_ARG_DgDx, 0, period_DgDx_support );
 
  719    outArgs.set_DgDx_properties(
 
  720      0, periodOutArgs.get_DgDx_properties(g_index_) );
 
  724  for ( 
int l = 0; l < Np_; ++l ) {
 
  725    const int period_l = this->period_l(l);
 
  726    const MEB::DerivativeSupport period_DgDp_l_support
 
  727      = periodOutArgs.supports(MEB::OUT_ARG_DgDp, g_index_, period_l);
 
  728    if (!period_DgDp_l_support.none()) {
 
  729      outArgs.setSupports( MEB::OUT_ARG_DgDp, 0, l, period_DgDp_l_support );
 
  730      outArgs.set_DgDp_properties(
 
  731        0, l, periodOutArgs.get_DgDp_properties(g_index_,period_l) );
 
  740template<
class Scalar>
 
  741void DefaultMultiPeriodModelEvaluator<Scalar>::evalModelImpl(
 
  742  const ModelEvaluatorBase::InArgs<Scalar> &inArgs,
 
  743  const ModelEvaluatorBase::OutArgs<Scalar> &outArgs
 
  747  using Teuchos::rcp_dynamic_cast;
 
  749  typedef ModelEvaluatorBase MEB;
 
  752  THYRA_MODEL_EVALUATOR_DECORATOR_EVAL_MODEL_GEN_BEGIN(
 
  753    "DefaultMultiPeriodModelEvaluator",inArgs,outArgs,periodModel_ );
 
  757  const int N = x_bar_space_->numBlocks();
 
  758  const int Np = this->Np_;
 
  765  RCP<const ProductVectorBase<Scalar> > x_bar;
 
  766  if (inArgs.supports(MEB::IN_ARG_x)) {
 
  767    x_bar = rcp_dynamic_cast<const ProductVectorBase<Scalar> >(
 
  768      inArgs.get_x(), true );
 
  770      is_null(x_bar), std::logic_error,
 
  771      "Error, if x is supported, it must be set!" 
  779  RCP<ProductVectorBase<Scalar> > f_bar;
 
  780  if (outArgs.supports(MEB::OUT_ARG_f)) {
 
  781    f_bar = rcp_dynamic_cast<ProductVectorBase<Scalar> >(
 
  782      outArgs.get_f(), true );
 
  785  Array<MEB::Derivative<Scalar> > DfDp_bar(Np);
 
  786  Array<RCP<ProductMultiVectorBase<Scalar> > > DfDp_bar_mv(Np);
 
  787  for ( 
int l = 0; l < Np; ++l ) {
 
  788    if (!outArgs.supports(MEB::OUT_ARG_DfDp,l).none()) {
 
  789      MEB::Derivative<Scalar>
 
  790        DfDp_bar_l = outArgs.get_DfDp(l);
 
  791      DfDp_bar[l] = DfDp_bar_l;
 
  792      DfDp_bar_mv[l] = rcp_dynamic_cast<ProductMultiVectorBase<Scalar> >(
 
  793        DfDp_bar_l.getMultiVector(), true );
 
  796          !DfDp_bar_l.isEmpty()
 
  801            DfDp_bar_l.getMultiVectorOrientation() != MEB::DERIV_MV_BY_COL
 
  805        "Error, we currently can only handle DfDp as an column-based multi-vector!" 
  810  RCP<BlockedLinearOpBase<Scalar> > W_op_bar;
 
  811  if (outArgs.supports(MEB::OUT_ARG_W_op)) {
 
  812    W_op_bar = rcp_dynamic_cast<BlockedLinearOpBase<Scalar> >(
 
  813      outArgs.get_W_op(), true
 
  817  RCP<VectorBase<Scalar> >
 
  818    g_bar = outArgs.get_g(0);
 
  820  MEB::Derivative<Scalar> DgDx_dot_bar;
 
  821  RCP<ProductMultiVectorBase<Scalar> > DgDx_dot_bar_mv;
 
  822  if (!outArgs.supports(MEB::OUT_ARG_DgDx_dot,0).none()) {
 
  823    DgDx_dot_bar = outArgs.get_DgDx_dot(0);
 
  824    DgDx_dot_bar_mv = rcp_dynamic_cast<ProductMultiVectorBase<Scalar> >(
 
  825      DgDx_dot_bar.getMultiVector(), true );
 
  828        !DgDx_dot_bar.isEmpty()
 
  833          DgDx_dot_bar.getMultiVectorOrientation() != MEB::DERIV_TRANS_MV_BY_ROW
 
  837      "Error, we currently can only handle DgDx_dot as an row-based multi-vector!" 
  841  MEB::Derivative<Scalar> DgDx_bar;
 
  842  RCP<ProductMultiVectorBase<Scalar> > DgDx_bar_mv;
 
  843  if (!outArgs.supports(MEB::OUT_ARG_DgDx,0).none()) {
 
  844    DgDx_bar = outArgs.get_DgDx(0);
 
  845    DgDx_bar_mv = rcp_dynamic_cast<ProductMultiVectorBase<Scalar> >(
 
  846      DgDx_bar.getMultiVector(), true );
 
  854          DgDx_bar.getMultiVectorOrientation() != MEB::DERIV_TRANS_MV_BY_ROW
 
  858      "Error, we currently can only handle DgDx as an row-based multi-vector!" 
  862  Array<MEB::Derivative<Scalar> > DgDp_bar(Np);
 
  863  Array<RCP<MultiVectorBase<Scalar> > > DgDp_bar_mv(Np);
 
  864  for ( 
int l = 0; l < Np; ++l ) {
 
  865    if (!outArgs.supports(MEB::OUT_ARG_DgDp,0,l).none()) {
 
  866      MEB::Derivative<Scalar>
 
  867        DgDp_bar_l = outArgs.get_DgDp(0,l);
 
  868      DgDp_bar[l] = DgDp_bar_l;
 
  869      DgDp_bar_mv[l] = DgDp_bar_l.getMultiVector();
 
  871        !DgDp_bar_l.isEmpty() && 
is_null(DgDp_bar_mv[l]),
 
  873        "Error, we currently can only handle DgDp as some type of multi-vector!" 
  885    periodInArgs = periodModel_->createInArgs();
 
  890  for ( 
int l = 0; l < Np; ++l )
 
  891    periodInArgs.set_p( period_l(l), inArgs.get_p(l) ); 
 
  894    periodOutArgs = periodModel_->createOutArgs();
 
  900    g_index_, createMember<Scalar>( periodModel_->get_g_space(g_index_) ) );
 
  904    assign( g_bar.ptr(), ST::zero() );
 
  908  for ( 
int l = 0; l < Np; ++l ) {
 
  909    if ( !
is_null(DgDp_bar_mv[l]) ) {
 
  910      assign(DgDp_bar_mv[l].ptr(), ST::zero());
 
  911      periodOutArgs.set_DgDp(
 
  912        g_index_, period_l(l),
 
  914          *periodModel_, g_index_, period_l(l),
 
  915          DgDp_bar[l].getMultiVectorOrientation()
 
  923  for ( 
int i = 0; i < N; ++i ) {
 
  925    VOTSME thyraModel_outputTempState(periodModels_[i],out,verbLevel);
 
  929    for ( 
int k = 0; k < numPeriodZs(); ++k )
 
  930      periodInArgs.set_p( z_indexes_[k], z_[i][k] );
 
  933      periodInArgs.set_x(x_bar->getVectorBlock(i));
 
  936      periodOutArgs.set_f(f_bar->getNonconstVectorBlock(i)); 
 
  939      periodOutArgs.set_W_op(W_op_bar->getNonconstBlock(i,i));
 
  941    for ( 
int l = 0; l < Np; ++l ) {
 
  942      if ( !
is_null(DfDp_bar_mv[l]) ) {
 
  943        periodOutArgs.set_DfDp(
 
  945          MEB::Derivative<Scalar>(
 
  946            DfDp_bar_mv[l]->getNonconstMultiVectorBlock(i),
 
  953    if ( !
is_null(DgDx_dot_bar_mv) ) {
 
  954      periodOutArgs.set_DgDx_dot(
 
  956        MEB::Derivative<Scalar>(
 
  957          DgDx_dot_bar_mv->getNonconstMultiVectorBlock(i),
 
  958          MEB::DERIV_TRANS_MV_BY_ROW
 
  964      periodOutArgs.set_DgDx(
 
  966        MEB::Derivative<Scalar>(
 
  967          DgDx_bar_mv->getNonconstMultiVectorBlock(i),
 
  968          MEB::DERIV_TRANS_MV_BY_ROW
 
  975    periodModels_[i]->evalModel( periodInArgs, periodOutArgs );
 
  981      Vp_StV( g_bar.ptr(), g_weights_[i], *periodOutArgs.get_g(g_index_) );
 
  985    for ( 
int l = 0; l < Np; ++l ) {
 
  986      if ( !
is_null(DgDp_bar_mv[l]) ) {
 
  989          *periodOutArgs.get_DgDp(g_index_,period_l(l)).getMultiVector(),
 
  996    if ( !
is_null(DgDx_dot_bar_mv) ) {
 
  997      scale( g_weights_[i],
 
  998        DgDx_dot_bar_mv->getNonconstMultiVectorBlock(i).ptr() );
 
 1002    if ( !
is_null(DgDx_bar_mv) ) {
 
 1003      scale( g_weights_[i],
 
 1004        DgDx_bar_mv->getNonconstMultiVectorBlock(i).ptr() );
 
 1016  THYRA_MODEL_EVALUATOR_DECORATOR_EVAL_MODEL_END();
 
 1024template<
class Scalar>
 
 1025void DefaultMultiPeriodModelEvaluator<Scalar>::set_z_indexes_and_create_period_l_map(
 
 1026  const Array<int> &z_indexes
 
 1032  z_indexes_ = z_indexes;
 
 1033  period_l_map_.resize(0);
 
 1034  const int numTotalParams = Np_ + z_indexes_.size();
 
 1035  Array<int>::const_iterator
 
 1036    z_indexes_itr = z_indexes_.begin(),
 
 1037    z_indexes_end = z_indexes_.end();
 
 1038  int last_z_index = -1;
 
 1039  for ( 
int k = 0; k < numTotalParams; ++k ) {
 
 1040    if ( z_indexes_itr == z_indexes_end || k < *z_indexes_itr ) {
 
 1042      period_l_map_.push_back(k);
 
 1050      const int tmp_last_z_index = *z_indexes_itr;
 
 1052      if ( z_indexes_itr != z_indexes_end ) {
 
 1054        if ( last_z_index >= 0 ) {
 
 1056            *z_indexes_itr <= last_z_index, std::logic_error,
 
 1057            "Error, the z_indexes array = " << 
toString(z_indexes_)
 
 1058            << 
" is not sorted or contains duplicate entries!" 
 1062        last_z_index = tmp_last_z_index;
 
 1069template<
class Scalar>
 
 1070void DefaultMultiPeriodModelEvaluator<Scalar>::wrapNominalValuesAndBounds()
 
 1073  using Teuchos::rcp_dynamic_cast;
 
 1074  typedef ModelEvaluatorBase MEB;
 
 1076  nominalValues_ = this->createInArgs();
 
 1077  lowerBounds_ = this->createInArgs();
 
 1078  upperBounds_ = this->createInArgs();
 
 1080  const MEB::InArgs<Scalar>
 
 1081    periodNominalValues = periodModel_->getNominalValues(),
 
 1082    periodLowerBounds = periodModel_->getLowerBounds(),
 
 1083    periodUpperBounds = periodModel_->getUpperBounds();
 
 1085  if (periodNominalValues.supports(MEB::IN_ARG_x)) {
 
 1087    if( !
is_null(periodNominalValues.get_x()) ) {
 
 1090      RCP<Thyra::ProductVectorBase<Scalar> >
 
 1091        x_bar_init = createProductVector(x_bar_space_);
 
 1092      const int N = this->N();
 
 1093      for ( 
int i = 0; i < N; ++i ) {
 
 1095          x_bar_init->getNonconstVectorBlock(i).ptr(),
 
 1096          *periodModels_[i]->getNominalValues().get_x()
 
 1099      nominalValues_.set_x(x_bar_init);
 
 1102    if( !
is_null(periodLowerBounds.get_x()) ) {
 
 1105      RCP<Thyra::ProductVectorBase<Scalar> >
 
 1106        x_bar_l = createProductVector(x_bar_space_);
 
 1107      const int N = this->N();
 
 1108      for ( 
int i = 0; i < N; ++i ) {
 
 1110          x_bar_l->getNonconstVectorBlock(i).ptr(),
 
 1111          *periodModels_[i]->getLowerBounds().get_x()
 
 1114      lowerBounds_.set_x(x_bar_l);
 
 1117    if( !
is_null(periodUpperBounds.get_x()) ) {
 
 1120      RCP<Thyra::ProductVectorBase<Scalar> >
 
 1121        x_bar_u = createProductVector(x_bar_space_);
 
 1122      const int N = this->N();
 
 1123      for ( 
int i = 0; i < N; ++i ) {
 
 1125          x_bar_u->getNonconstVectorBlock(i).ptr(),
 
 1126          *periodModels_[i]->getUpperBounds().get_x()
 
 1129      upperBounds_.set_x(x_bar_u);
 
 1136  for ( 
int l = 0; l < Np_; ++l ) {
 
 1137    const int period_l = this->period_l(l);
 
 1138    nominalValues_.set_p(l,periodNominalValues.get_p(period_l));
 
 1139    lowerBounds_.set_p(l,periodLowerBounds.get_p(period_l));
 
 1140    upperBounds_.set_p(l,periodUpperBounds.get_p(period_l));
 
 1146template<
class Scalar>
 
 1147RCP<ProductVectorBase<Scalar> >
 
 1148DefaultMultiPeriodModelEvaluator<Scalar>::createProductVector(
 
 1149  const RCP<
const ProductVectorSpaceBase<Scalar> > &prodVecSpc
 
 1153    Thyra::createMember<Scalar>(prodVecSpc), true );
 
Composite subclass that takes a single ModelEvaluator object and represents it as a single aggregate ...
 
ArrayView< const std::string > get_g_names(int j) const
 
RCP< const VectorSpaceBase< Scalar > > get_x_space() const
 
DefaultMultiPeriodModelEvaluator()
 
ModelEvaluatorBase::InArgs< Scalar > getUpperBounds() const
 
RCP< const VectorSpaceBase< Scalar > > get_g_space(int j) const
 
RCP< PreconditionerBase< Scalar > > create_W_prec() const
 
ModelEvaluatorBase::InArgs< Scalar > getLowerBounds() const
 
RCP< const VectorSpaceBase< Scalar > > get_p_space(int l) const
 
RCP< const LinearOpWithSolveFactoryBase< Scalar > > get_W_factory() const
 
ModelEvaluatorBase::InArgs< Scalar > createInArgs() const
 
RCP< LinearOpBase< Scalar > > create_W_op() const
 
RCP< const Array< std::string > > get_p_names(int l) const
 
void reset_z(const Array< Array< RCP< const VectorBase< Scalar > > > > &z)
Reset z.
 
RCP< const VectorSpaceBase< Scalar > > get_f_space() const
 
void reportFinalPoint(const ModelEvaluatorBase::InArgs< Scalar > &finalPoint, const bool wasSolved)
Ignores the final point.
 
void initialize(const int N, const Array< RCP< ModelEvaluator< Scalar > > > &periodModels, const Array< int > &z_indexes, const Array< Array< RCP< const VectorBase< Scalar > > > > &z, const int g_index, const Array< Scalar > g_weights, const RCP< const ProductVectorSpaceBase< Scalar > > &x_bar_space=Teuchos::null, const RCP< const ProductVectorSpaceBase< Scalar > > &f_bar_space=Teuchos::null, const RCP< LinearOpWithSolveFactoryBase< Scalar > > &W_bar_factory=Teuchos::null)
Initialize.
 
ModelEvaluatorBase::InArgs< Scalar > getNominalValues() const
 
Factory interface for creating LinearOpWithSolveBase objects from compatible LinearOpBase objects.
 
Concrete aggregate class for all input arguments computable by a ModelEvaluator subclass object.
 
Concrete aggregate class for all output arguments computable by a ModelEvaluator subclass object.
 
Base subclass for ModelEvaluator that defines some basic types.
 
Default base class for concrete model evaluators.
 
Pure abstract base interface for evaluating a stateless "model" that can be mapped into a number of d...
 
Abstract interface for finite-dimensional dense vectors.
 
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
 
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
 
bool is_null(const std::shared_ptr< T > &p)
 
const char * toString(EConj conj)
Return a string name for a EOpTransp value. `*.
 
TypeTo implicit_cast(const TypeFrom &t)
 
T_To & dyn_cast(T_From &from)