This file is indexed.

/usr/include/trilinos/Thyra_ModelEvaluator.hpp is in libtrilinos-thyra-dev 12.10.1-3.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

   1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
// @HEADER
// ***********************************************************************
// 
//    Thyra: Interfaces and Support for Abstract Numerical Algorithms
//                 Copyright (2004) Sandia Corporation
// 
// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
// license for use of this work by or on behalf of the U.S. Government.
// 
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the Corporation nor the names of the
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Questions? Contact Roscoe A. Bartlett (bartlettra@ornl.gov) 
// 
// ***********************************************************************
// @HEADER


#ifndef THYRA_MODEL_EVALUATOR_HPP
#define THYRA_MODEL_EVALUATOR_HPP


#include "Thyra_ModelEvaluatorBase.hpp"
#include "Thyra_LinearOpWithSolveFactoryBase.hpp"


namespace Thyra {


/** \brief Pure abstract base interface for evaluating a stateless "model"
 * that can be mapped into a number of different types of problems.
 *
 * \section Thyra_ME_outline_sec Outline
 *
 * <ul>
 * <li>\ref Thyra_ME_intro_sec
 * <li>\ref Thyra_ME_problem_types_sec
 *     <ul>
 *     <li>\ref Thyra_ME_nonlinear_equations_sec
 *     <li>\ref Thyra_ME_explicit_ode_sec
 *     <li>\ref Thyra_ME_implicit_dae_sec
 *     <li>\ref Thyra_ME_unconstrained_optimization_sec
 *     <li>\ref Thyra_ME_equality_constrained_optimization_sec
 *     </ul>
 * <li>\ref Thyra_ME_derivatives_sec
 * <li>\ref Thyra_ME_nominal_values_sec
 * <li>\ref Thyra_ME_bounds_sec
 * <li>\ref Thyra_ME_checking_sec
 * <li>\ref Thyra_ME_dev_notes_sec
 * </ul>
 *
 * \section Thyra_ME_intro_sec Introduction
 *
 * This interface defines a very loosely mathematically typed interface to a
 * very wide variety of simulation-based models that can support a very wide
 * range of simulation-based numerical algorithms.
 *
 * For the most part, a model represented by this interface is composed:
 *
 * <ul>
 *
 * <li><b>State vector function:</b>
 *
 * <tt>(x_dot,x,{p(l)},t,...}) -> f <: f_space</tt>
 *
 * <li><b>Auxiliary response vector functions:</b>
 *
 * <tt>(x_dot,x,{p(l)},t,...}) -> g(j) <: g_space(j)</tt>, for <tt>j=0...Ng-1</tt>
 *
 * <li><b>Other outputs:</b>
 *
 * A model can compute other objects as well (see derivatives below).
 *
 * </ul>
 *
 * given the general input variables/parameters:
 *
 * <ul>
 *
 * <li><b>State variables vector:</b>
 *
 * <tt>x <: x_space</tt>
 *
 * <li><b>State variables derivative w.r.t. <tt>t</tt> vector:</b>
 *
 * <tt>x_dot <: x_space</tt>
 *
 * <li><b>Auxiliary parameter vectors:</b>
 *
 * <tt>p(l) <: p_space(l)</tt>, for <tt>l=0...Np-1</tt>
 *
 * <li><b>Time point (or some other independent variable):</b>
 *
 * <tt>t <: Scalar</tt>
 *
 * <li><b>Other inputs:</b>
 *
 * A model can accept additional input objects as well (see below).
 *
 * </ul>
 *
 * where <tt>x_space <: RE^n_x</tt>, <tt>f_space <: RE^n_x</tt>,
 * <tt>p_space(l) <: RE^n_p_l</tt> (for <tt>l=0...Np-1</tt>), and
 * <tt>g_space(j) <: RE^n_g_j</tt> (for <tt>j=0...Ng-1</tt>) are
 * <tt>%Thyra</tt> vector spaces of the given dimensions.
 *
 * Above, the notation <tt>{p(l)}</tt> is shorthand for the set of parameter
 * vectors <tt>{ p(0), p(1), ..., p(Np-1) }</tt>.
 *
 * All of the above variables/parameters and functions are represented as
 * abstract <tt>Thyra::VectorBase</tt> objects.  The vector spaces associated
 * with these vector quantities are returned by <tt>get_x_space()</tt>,
 * <tt>get_p_space()</tt>, <tt>get_f_space()</tt>, and
 * <tt>get_g_space()</tt>.
 *
 * All of the input variables/parameters are specified as a
 * <tt>ModelEvaluatorBase::InArgs</tt> object, all functions to be computed
 * are specified as a <tt>ModelEvaluatorBase::OutArgs</tt> object, and
 * evaluations of all function at a single set of variable values is performed in a single
 * call to <tt>evalModel()</tt>.
 *
 * A particular <tt>%ModelEvaluator</tt> subclass object can support any
 * subset of these inputs and outputs and it is up to the client to map these
 * variables/parameters and functions into abstract mathematical problems.
 * Some of the different types of abstract mathematical problems that can be
 * represented through this interface are given in the next section.
 *
 * This interface can also support the computation of various derivatives of
 * these functions w.r.t. the input arguments (see the section \ref
 * Thyra_ME_derivatives_sec below).
 *
 * \section Thyra_ME_problem_types_sec Examples of Abstract Problem Types
 *
 * There are a number of different types of mathematical problems that can be
 * formulated using this interface.  In the following subsections, a few
 * different examples of specific abstract problems types are given.
 *
 * \subsection Thyra_ME_nonlinear_equations_sec Nonlinear Equations
 *
 
 \verbatim
    f(x) = 0
 \endverbatim 

 * Here it is assumed that <tt>D(f)/D(x)</tt> is nonsingular in general but
 * this is not strictly required.  If <tt>W=D(f)/D(x)</tt> is supported, the
 * nature of <tt>D(f)/D(x)</tt> may be given by
 * <tt>this->createOutArgs().get_W_properties()</tt>.
 
 * \subsection Thyra_ME_explicit_ode_sec Explicit ODEs
 *
 
 \verbatim
    x_dot = f(x,t)
 \endverbatim 

 * Here it is assumed that <tt>D(f)/D(x)</tt> is nonsingular in general but
 * this is not strictly required.  If <tt>W=D(f)/D(x)</tt> is supported, the
 * nature of <tt>D(f)/D(x)</tt> may be given by
 * <tt>this->createOutArgs().get_W_properties()</tt>.

 * Above, the argument <tt>t</tt> may or may not be accepted by the model
 * (i.e. <tt>createInArgs().supports(IN_ARG_t)</tt> may return
 * <tt>false</tt>).
 *
 * \subsection Thyra_ME_implicit_dae_sec Implicit ODEs or DAEs
 
 \verbatim
    f(x_dot,x,t) = 0
 \endverbatim

 * Here it is assumed that <tt>D(f)/D(x)</tt> is nonsingular in general but
 * this is not strictly required.
 *
 * The problem is either an implicit ODE or DAE depending on the nature of the
 * derivative matrix <tt>D(f)/D(x_dot)</tt>:
 *
 * <ul>
 * <li> ODE: <tt>D(f)/D(x_dot)</tt> is full rank
 * <li> DAE: <tt>D(f)/D(x_dot)</tt> is <em>not</em> full rank
 * </ul>
 *
 * If supported, the nature of <tt>W=alpha*D(f)/D(x_dot)+beta*D(f)/D(x)</tt>
 * may be given by <tt>this->createOutArgs().get_W_properties()</tt>.
 *
 * Here the argument <tt>t</tt> may or may not be accepted by <tt>*this</tt>.
 *
 * \subsection Thyra_ME_unconstrained_optimization_sec Unconstrained optimization
 
 \verbatim
    min g(x,{p(l)})
 \endverbatim

 * where the objective function <tt>g(x,{p(l)})</tt> is some aggregated
 * function built from some subset of the the auxiliary response functions
 * <tt>g(j)(x,{p(l)})</tt>, for <tt>j=1...Ng</tt>.
 *
 * In general, it would be assumed that the Hessian <tt>D^2(g)/D(x^2)</tt> is
 * symmetric semidefinite but this is not strictly required.
 *
 * \subsection Thyra_ME_equality_constrained_optimization_sec Equality constrained optimization
 
 \verbatim
    min g(x,{p(l)})

    s.t. f(x,{p(l)}) = 0
 \endverbatim 

 * where the objective function <tt>g(x,{p(l)})</tt> is some aggregated
 * function built from some subset of the the auxiliary response functions
 * <tt>g(j)(x,{p(l)})</tt>, for <tt>j=0...Ng-1</tt>.
 *
 * Here it is assumed that <tt>D(f)/D(x)</tt> is nonsingular in general but
 * this is not strictly required.  If <tt>W=D(f)/D(x)</tt> is supported, the
 * nature of <tt>D(f)/D(x)</tt> may be given by
 * <tt>this->createOutArgs().get_W_properties()</tt>.
 *
 * \subsection Thyra_ME_general_constrained_optimization_sec General constrained optimization
 
 \verbatim
    min g(x,{p(l)})

    s.t. f(x,{p(l)}) = 0
         r(x,{p(l)}) = 0
         hL <= h(x,{p(l)}) <= hU
         xL <= x <= xU
         pL(l) <= p(l) <= pU(l)
 \endverbatim 

 * where the objective function <tt>g(x,{p(l)})</tt> and the auxiliary
 * equality <tt>r(x,{p(l)})</tt> and inequality <tt>h(x,{p(l)})</tt>
 * constraint functions are aggregated functions built from some subset of the
 * the auxiliary response functions <tt>g(j)(x,{p(l)})</tt>, for
 * <tt>j=0...Ng-1</tt>.  The auxiliary response functions for a particular
 * model can be interpreted in a wide variety of ways and can be mapped into a
 * number of different optimization problems.
 *
 * Here it is assumed that <tt>D(f)/D(x)</tt> is nonsingular in general but
 * this is not strictly required.  If <tt>W=D(f)/D(x)</tt> is supported, the
 * nature of <tt>D(f)/D(x)</tt> may be given by
 * <tt>this->createOutArgs().get_W_properties()</tt>.
 *
 * \section Thyra_ME_derivatives_sec Function derivatives and sensitivities
 *
 * A model can also optionally support the computation of various derivatives
 * of the underlying model functions.  The primary use for these derivatives
 * is in the computation of various types of sensitivities.  Specifically,
 * direct and adjoint sensitivities will be considered.
 *
 * To illustrate the issues involved, consider a single auxiliary parameter
 * <tt>p</tt> and a single auxiliary response function <tt>g</tt> of the form
 * <tt>(x,p) => g</tt>.  Assuming that <tt>(x,p) ==> f</tt> defines the state
 * equation <tt>f(x,p)=0</tt> and that <tt>D(f)/D(x)</tt> is full rank, then
 * <tt>f(x,p)=0</tt> defines the implicit function <tt>p ==> x(p)</tt>.  Given
 * this implicit function, the reduced auxiliary function is
 
 \verbatim
    g_hat(p) = g(x(p),p)
 \endverbatim
 
 * The reduced derivative <tt>D(g_hat)/D(p)</tt> is given as:
 
 \verbatim
    D(g_hat)/D(p) = D(g)/D(x) * D(x)/D(p) + D(g)/D(p)
 \endverbatim
 
 * where

 \verbatim
    D(x)/D(p) = - [D(f)/D(x)]^{-1} * [D(f)/D(p)]
 \endverbatim
 
 * Restated, the reduced derivative <tt>D(g_hat)/D(p)</tt> is given as:
 
 \verbatim
    D(g_hat)/D(p) = - [D(g)/D(x)] * [D(f)/D(x)]^{-1} * [D(f)/D(p)] + D(g)/D(p)
 \endverbatim
 
 * The reduced derivative <tt>D(g_hat)/D(p)</tt> can be computed using the
 * direct or the adjoint approaches.
 *
 * The <b>direct sensitivity approach</b> first solves for

 \verbatim
    D(x)/D(p) = - [D(f)/D(x)]^{-1} * [D(f)/D(p)]
 \endverbatim

 * explicitly, then computes

 \verbatim
    D(g_hat)/D(p) = D(g)/D(x) * D(x)/D(p) + D(g)/D(p).
 \endverbatim

 * In this case, <tt>D(f)/D(p)</tt> is needed as a multivector since it forms
 * the RHS for a set of linear equations.  However, only the action of
 * <tt>D(g)/D(x)</tt> on the multivector <tt>D(x)/D(p)</tt> is needed and
 * therefore <tt>D(g)/D(x)</tt> can be returned as only a linear operator
 * (i.e. a <tt>LinearOpBase</tt> object).  Note that in Thyra a multivector
 * <em>is a</em> linear operator and therefore every derivative object
 * returned as a multivector automatically implements the forward and adjoint
 * linear operators for the derivative operator.
 *
 * The final derivative <tt>D(g)/D(p)</tt> should be returned as a multivector
 * that can be added to the multivector <tt>D(g)/D(x)*D(x)/D(p)</tt>.
 *
 * The <b>adjoint sensitivity approach</b> computes

 \verbatim
    D(g_hat)/D(p)^T =  [D(f)/D(p)]^T * ( - [D(f)/D(x)]^{-T} * [D(g)/D(x)]^T ) + [D(g)/D(p)]^T
 \endverbatim

 * by first solving the adjoint system 

 \verbatim
    Lambda = - [D(f)/D(x)]^{-T} * [D(g)/D(x)]^T
 \endverbatim

 * for the multivector <tt>Lambda</tt> and then computes

 \verbatim
    D(g_hat)/D(p)^T =  [D(f)/D(p)]^T * Lambda + [D(g)/D(p)]^T.
 \endverbatim

 * In this case, <tt>[D(g)/D(x)]^T</tt> is needed as an explicit multivector
 * since it forms the RHS for the linear adjoint equations.  Also, only the
 * adjoint operator application[D(f)/D(p)]^T is needed.  And in this case, the
 * multivector form of the adjoint <tt>[D(g)/D(p)]^T</tt> is required.
 *
 * As demonstrated above, general derivative objects (e.g. <tt>D(f)/D(p)</tt>,
 * <tt>D(g)/D(x)</tt>, and <tt>D(g)/D(p)</tt>) may be needed as either only a
 * linear operator (where it's forward or adjoint application is required) or
 * as a multivector for its forward or adjoint forms.  A derivative
 * <tt>D(h)/D(z)</tt> for some function <tt>h(z)</tt> can be supported in any
 * of the following forms:
 *
 * <ul>
 *
 * <li> <tt><b>D(h)/D(z)</b></tt> as a <tt>LinearOpBase</tt> object where the
 * forward and/or adjoint operator applications are supported
 *
 * <li> <tt><b>D(h)/D(z)</b></tt> as a <tt>MultiVectorBase</tt> object where
 * each column in the multivector <tt>i</tt> represents <tt>D(h)/D(z(i))</tt>,
 * the derivatives for all of the functions <tt>h</tt> for the single variable
 * <tt>z(i)</tt>
 *
 * <li> <tt><b>[D(h)/D(z)]^T</b></tt> as a <tt>MultiVectorBase</tt> object
 * where each column in the multivector <tt>k</tt> represents
 * <tt>[D(h(k))/D(z)]^T</tt>, the derivatives for the function <tt>h(k)</tt>
 * for all of the variables <tt>z</tt>
 *
 * </ul>
 *
 * A model can sign up to compute any, or all, or none of these forms of a
 * derivative and this information is returned from
 * <tt>this->createOutArgs().supports(OUT_ARG_blah,...)</tt> as a
 * <tt>ModelEvaluatorBase::DerivativeSupport</tt> object, where <tt>blah</tt>
 * is either <tt>DfDp</tt>, <tt>DgDx_dot</tt>,  <tt>DgDx</tt>, or <tt>DgDp</tt>.  The
 * <tt>LinearOpBase</tt> form of a derivative is supported if
 * <tt>this->createOutArgs().supports(OUT_ARG_blah,...).supports(DERIV_LINEAR_OP)==true</tt>.
 * The forward <tt>MultiVectorBase</tt> form of the derivative is supported if
 * <tt>this->createOutArgs().supports(OUT_ARG_blah,...).supports(DERIV_MV_BY_COL)==true</tt>
 * while the adjoint form of the derivative is supported if
 * <tt>this->createOutArgs().supports(OUT_ARG_blah,...).supports(DERIV_TRANS_MV_BY_ROW)==true</tt>.
 * 
 * In order to accommodate these different forms of a derivative, the simple
 * class <tt>ModelEvaluatorBase::Derivative</tt> is defined that can store
 * either a <tt>LinearOpBase</tt> or one of two <tt>MultiVectorBase</tt> forms
 * (i.e. forward or adjoint) of the derivative.  A
 * <tt>%ModelEvaluatorBase::%Derivative</tt> object can only store one (or
 * zero) forms of a derivative object at one time.
 *
 * We now describe each of these derivative objects in more detail:
 *
 * <ul>
 *
 * <li><b>State function <tt>f(x_dot,x,{p(l)},t,...)</tt> derivatives</b>
 *
 *     <ul>
 *     
 *     <li><b>State variable derivatives</b>

       \verbatim
       W = alpha*D(f)/D(x_dot) + beta*D(f)/D(x)
       \endverbatim

 *     This derivative operator is a special object that is derived from the
 *     <tt>LinearOpWithSolveBase</tt> interface and therefore supports linear
 *     solves.  Objects of this type are created with the function
 *     <tt>create_W()</tt> and set on the <tt>InArgs</tt> object before they
 *     are computed in <tt>evalModel()</tt>.  Note that if the model does not
 *     define or support an <tt>x_dot</tt> vector then the scalars
 *     <tt>alpha</tt> and <tt>beta</tt> need not be supported.
 *
 *     The <tt>LinearOpWithSolveBase</tt> form of this derivative is supported
 *     if <tt>this->createOutArgs().supports(OUT_ARG_W)==true</tt>.  The
 *     <tt>LinearOpBase</tt>-only form (i.e. no solve operation is given) of
 *     this derivative is supported if
 *     <tt>this->createOutArgs().supports(OUT_ARG_W_op)==true</tt>.  The
 *     <tt>W_op</tt> form of <tt>W</tt> is to be preferred when no linear solve
 *     with <tt>W</tt> will ever be needed.  A valid implementation may
 *     support none, both, or either of these forms <tt>LOWSB</tt> and/or
 *     <tt>LOB</tt> of <tt>W</tt>.
 *
 *     Also note that an underlying model may only support a single copy of
 *     <tt>W</tt> or <tt>W_op</tt> at one time.  This is required to
 *     accommodate some types of underlying applications that are less flexible
 *     in how they maintain their memory and how they deal with their objects.
 *     Therefore, to accommodate these types of less ideal application
 *     implementations, if a client tries to create and maintain more than one
 *     <tt>W</tt> and/or <tt>W_op</tt> object at one time, then
 *     <tt>create_W()</tt> and <tt>create_W_op()</tt> may return <tt>null</tt>
 *     (or may throw an undetermined exception).  However, every "good"
 *     implementation of this interface should support the creation and
 *     maintenance of as many <tt>W</tt> and/or <tt>W_op</tt> objects at one
 *     time as will fit into memory.
 *
 *     <li><b>State variable Taylor coefficients</b>
 *
 *     <tt>x_poly =</tt> \f$\sum_{i=0}^d x_i t^i\f$,
 *
 *     <tt>x_dot_poly =</tt> \f$\sum_{i=0}^d-1 (i+1)x_{i+1} t^i\f$,
 *
 *     <tt>f_poly =</tt> \f$\sum_{i=0}^{d-1} f_i t^i\f$.
 *
 *     If <tt>x_poly</tt> is a given polynomial of degree \f$d\f$ and
 *     <tt>x_dot_poly =</tt> \f$d(\f$<tt>x_poly</tt>\f$)/dt\f$, then <tt>f_poly
 *     = f(x_poly, x_dot_poly, t) +</tt> \f$O(t^{d})\f$ where \f$f_i =
 *     \frac{1}{k!} \frac{d^k}{dt^k} f(dx/dt ,x(t),t), i=0,\ldots,d-1\f$ are
 *     the Taylor series coefficient of \f$f\f$.  The polynomials
 *     <tt>x_poly</tt>, <tt>x_dot_poly</tt>, and <tt>f_poly</tt> are
 *     represented by <tt>Teuchos::Polynomial</tt> objects where each
 *     coefficient is a <tt>Thyra::VectorBase</tt> object.  The Taylor series
 *     coefficients of \f$f\f$ can easily be computed using automatic
 *     differentiation, but this is generally the only means of doing so.
 *     
 *     <li><b>Auxiliary parameter derivatives</b>

       \verbatim
       DfDp(l) = D(f)/D(p(l))
       \endverbatim

 *     for <tt>l=0...Np-1</tt>.

 *     These are derivative objects that represent the derivative of the state
 *     function <tt>f</tt> with respect to the auxiliary parameters
 *     <tt>p(l)</tt>.  This derivative is manipulated as a
 *     <tt>ModelEvaluatorBase::Derivative</tt> object.
 *
 *     </ul>
 *
 * <li><b>Auxiliary response function <tt>g(j)(x,{p(l)},t,...)</tt> derivatives</b>
 *
 *     <ul>
 *     
 *     <li><b>State variable derivatives</b>
 
       \verbatim
       DgDx_dot(j) = D(g(j))/D(x_dot)
       \endverbatim
 
 *     for <tt>j=0...Ng-1</tt>.
 *
 *     These are derivative objects that represent the derivative of the
 *     axillary function <tt>g(j)</tt> with respect to the state variables
 *     derivative <tt>x_dot</tt>.  This derivative is manipulated as a
 *     <tt>ModelEvaluatorBase::Derivative</tt> object.
 
       \verbatim
       DgDx(j) = D(g(j))/D(x)
       \endverbatim
 
 *     for <tt>j=0...Ng-1</tt>.
 *
 *     These are derivative objects that represent the derivative of the
 *     axillary function <tt>g(j)</tt> with respect to the state variables
 *     <tt>x</tt>.  This derivative is manipulated as a
 *     <tt>ModelEvaluatorBase::Derivative</tt> object.
 *     
 *     <li><b>Auxiliary parameter derivatives</b>
 *
       \verbatim
       DgDp(j,l) = D(g(j))/D(p(l))
       \endverbatim

 *     for <tt>j=0...Ng-1</tt>, <tt>l=0...Np-1</tt>.
 *
 *     These are derivative objects that represent the derivative of the
 *     axillary function <tt>g(j)</tt> with respect to the auxiliary
 *     parameters <tt>p(l)</tt>.  This derivative is manipulated as a
 *     <tt>ModelEvaluatorBase::Derivative</tt> object.
 *
 *     </ul>
 *
 * </ul>
 *
 * \section Thyra_ME_nominal_values_sec Nominal values
 *
 * A model can optionally define a nominal value for any of the input
 * arguments and these are returned from the <tt>getNominalValues()</tt>
 * function as a <tt>const ModelEvaluatorBase::InArgs</tt> object.  These
 * nominal values can be used as initial guesses, as typical values (e.g. for
 * scaling), or for other purposes.  See <tt>evalModel()</tt> a discussion of
 * how nonminal values are treated in an evaluation where the client does not
 * pass in the values explicitly.
 *
 * \section Thyra_ME_bounds_sec Variable and Function Bounds
 *
 * A model can optionally define a set of upper and/or lower bounds for each
 * of the input variables/parameters.  These bounds are returned as
 * <tt>const</tt> <tt>ModelEvaluatorBase::InArgs</tt> objects from the
 * functions <tt>getLowerBounds()</tt> and <tt>getUpperBounds()</tt>.  These
 * bounds are typically used to define regions in space where the model
 * functions are well defined.  A client algorithm is free to ignore these
 * bounds if they can not handle these types of constraints.
 *
 * That fact that a model can defined reasonable bounds but most numerical
 * algorithms can not handle bounds is no reason to leave bounds out of this
 * interface.  Again, if the client algorithm can not handle bounds then then
 * can be simply ignored and there is not harm done (except the client
 * algorithm might run into lots of trouble computing functions with undefined
 * values)..
 *
 * \section Thyra_ME_param_subvectors_sec Significance of Parameter Subvectors
 *
 * The parameters for any particular model are partitioned into different
 * subvectors <tt>p(l)</tt> for several different reasons:
 *
 * <ul>
 *
 * <li>Parameters are grouped together into a subvectors <tt>p(l)</tt> to
 * allow an ANA to manipulate an entire set at a time for different purposes.
 * It is up to someone to select which parameters from a model will be exposed
 * in a parameter subvector and how they are partitioned into subvectors.  For
 * example, one parameter subvector may be used a design parameters, while
 * another subvector may be used for uncertain parameters, while still another
 * may be used as continuation parameters.
 *
 * <li>Parameters are grouped together into subvectors <tt>p(l)</tt> implies
 * that certain derivatives will be supplied for all the parameters in the
 * subvector or none.  If an ANA wants to flexibility to get the derivative
 * for any individual scalar parameter by itself, then the paramters must
 * be segregated into different parameter subvectors <tt>p(l)</tt> with
 * one component each (e.g. <tt>get_p_space(l)->dim()==1</tt>).
 *
 * </ul>
 *
 * \section Thyra_ME_failed_evals_sec Failed evaluations
 *
 * The way for a ModelEvalutor object to return a failed evaluation is to set
 * NaN in one or more of the output objects.  If an algebraic model executes
 * and happens to pass a negative number to a squareroot or something, then a
 * NaN is what will get created anyway (even if the ModelEvaluator object does
 * not detect this).  Therefore, clients of the ME interface really need to be
 * searching for a NaN to see if an evaluation has faield.  Also, a ME object
 * can set the isFailed flag on the outArgs object on the return from the
 * <tt>evalModel()</tt> function if it knows that the evaluation has failed
 * for some reason.
 *
 * \section Thyra_ME_inexact_evals_sec Inexact function evaluations
 *
 * The <tt>%ModelEvaluator</tt> interface supports inexact function
 * evaluations for <tt>f</tt> and <tt>g(j)</tt>.  This is supported through
 * the use of the type <tt>ModelEvaluatorBase::Evaluation</tt> which
 * associates an enum <tt>ModelEvaluatorBase::EEvalType</tt> with each
 * <tt>VectorBase</tt> object.  By default, the evaluation type is
 * <tt>ModelEvaluatorBase::EVAL_TYPE_EXACT</tt>.  However, a client ANA can
 * request or allow more inexact (and faster) evaluations for different
 * purposes.  For example,
 * </tt>ModelEvaluatorBase::EVAL_TYPE_APPROX_DERIV</tt> would be used for
 * finite difference approximations to the Jacobian-vector products and
 * </tt>ModelEvaluatorBase::EVAL_TYPE_VERA_APPROX_DERIV</tt> would be used for
 * finite difference Jacobian preconditioner approximations.
 *
 * The type <tt>ModelEvaluatorBase::Evaluation</tt> is designed so that it can
 * be seamlessly copied to and from a <tt>Teuchos::RCP</tt> object storing the
 * <tt>VectorBase</tt> object.  That means that if a client ANA requests an
 * evaluation and just assumes an exact evaluation it can just set an
 * <tt>RCP<VectorBase></tt> object and ignore the presences of the evaluation
 * type.  Likewise, if a <tt>%ModelEvaluator</tt> subclass does not support
 * inexact evaluations, it can simply grab the vector object out of the
 * OutArgs object as an <tt>RCP<VectorBase></tt> object and ignore the
 * evaluation type.  However, any generic software (e.g. DECORATORS and
 * COMPOSITES) must handle these objects as <tt>%Evaluation</tt> objects and
 * not <tt>RCP</tt> objects or the eval type info will be lost (see below).
 *
 * If some bit of software converts from an <tt>Evaluation</tt> object to an
 * <tt>RCP</tt> and then coverts back to an <tt>Evaluation</tt> object
 * (perhaps by accident), this will slice off the evaluation type enum value
 * and the resulting eval type will be the default <tt>EVAL_TYPE_EXACT</tt>.
 * The worse thing that will likely happen in this case is that a more
 * expensive evaluation will occur.  Again, general software should avoid
 * this.
 *
 * Design Consideration: By putting the evaluation type into the OutArg output
 * object itself instead of using a different data object, we avoid the risk
 * of having some bit of software setting the evaluation type enum as inexact
 * for one part of the computation (e.g. a finite difference Jacobian mat-vec)
 * and then another bit of software reusing the OutArgs object and be
 * computing inexact evaluation when they really wanted an exact evaluation
 * (e.g. a line search algorithm).  That could be a very difficult defect to
 * track down in the ANA.  For example, this could cause a line search method
 * to fail due to an inexact evaluation.  Therefore, the current design has
 * the advantage of being biased toward exact evaluations and allowing clients
 * and subclasses to ignore inexactness but has the disadvantage of allowing
 * general code to slice off the evaluation type enum without even as much as
 * a compile-time or any other type of warning.
 *
 * \section Thyra_ME_checking_sec Compile-Time and Run-Time Safety and Checking
 *
 * The <tt>%ModelEvaluator</tt> interface is designed to allow for great
 * flexibility in how models are defined.  The idea is that, at runtime, a
 * model can decide what input and output arguments it will support and client
 * algorithms must decide how to interpret what the model provides in order to
 * form an abstract problem to solve.  As a result, the
 * <tt>%ModelEvaluator</tt> interface is weakly typed mathematically.
 * However, the interface is strongly typed in terms of the types of objects
 * involved.  For example, while a single <tt>%ModelEvaluator</tt> object can
 * represent anything and everything from a set of nonlinear equations to a
 * full-blown constrained transient optimization problem, if the state vector
 * <tt>x</tt> is supported, it must be manipulated as a <tt>VectorBase</tt>
 * object, and this is checked at comple time.
 *
 * In order for highly dynamically configurable software to be safe and
 * usable, a great deal of runtime checking and good error reporting is
 * required.  Practically all of the runtime checking and error reporting work
 * associated with a <tt>%ModelEvaluator</tt> object is handled by the
 * concrete <tt>ModelEvaluatorBase::InArgs</tt> and
 * <tt>ModelEvaluatorBase::OutArgs</tt> classes.  Once a concrete
 * <tt>%ModelEvaluator</tt> object has setup what input and output arguments
 * the model supports, as returned by the <tt>createInArgs()</tt> and
 * <tt>createOutArgs()</tt> functions, all runtime checking for the proper
 * setting of input and output arguments and error reporting is automatically
 * handled.
 *
 * \section Thyra_ME_dev_notes_sec Notes to subclass developers
 *
 * Nearly every subclass should directly or indirectly derive from the node
 * subclass <tt>ModelEvaluatorDefaultBase</tt> since provides checking for
 * correct specification of a model evaluator subclass and provides default
 * implementations for various features.
 *
 * Subclass developers should consider deriving from one (but not more than
 * one) of the following subclasses rather than directly deriving from
 * <tt>ModelEvaluatorDefaultBase</tt>:
 *
 * <ul>
 *
 * <li><tt>StateFuncModelEvaluatorBase</tt> makes it easy to create models that
 * start with the state function evaluation <tt>x -> f(x)</tt>.
 *
 * <li><tt>ResponseOnlyModelEvaluatorBase</tt> makes it easy to create models
 * that start with the non-state response evaluation <tt>p -> g(p)</tt>.
 *
 * <li><tt>ModelEvaluatorDelegatorBase</tt> makes it easy to develop and
 * maintain different types of decorator subclasses.
 *
 * </ul>
 *
 * When deriving from any of the above intermediate base classes, the subclass
 * can override any of virtual functions in any way that it would like.
 * Therefore these subclasses just make the job of creating concrete
 * subclasses easier without removing any of the flexibility of creating a
 * subclass.
 *
 * ToDo: Finish Documentation!
 *
 * \ingroup Thyra_Nonlinear_model_evaluator_interfaces_code_grp
 */
template<class Scalar>
class ModelEvaluator : public ModelEvaluatorBase {
public:

  /** \brief . */
  typedef typename Teuchos::ScalarTraits<Scalar>::magnitudeType ScalarMag;

  /** \name Basic information */
  //@{

  /** \brief Return the number of sets of auxiliary parameters.
   *
   * If this function returns 0, then there are no auxiliary parameters.
   */
  virtual int Np() const = 0;

  /** \brief Return the number of sets of auxiliary response functions.
   *
   * If this function returns 0, then there are no auxiliary response
   * functions.
   */
  virtual int Ng() const = 0;

  //@}

  /** \name Vector spaces */
  //@{

  /** \brief Return the vector space for the state variables <tt>x <: RE^n_x</tt>. */
  virtual RCP<const VectorSpaceBase<Scalar> > get_x_space() const = 0;

  /** \brief Return the vector space for the state function <tt>f(...) <: RE^n_x</tt>. */
  virtual RCP<const VectorSpaceBase<Scalar> > get_f_space() const = 0;

  /** \brief Return the vector space for the auxiliary parameters
   * <tt>p(l) <: RE^n_p_l</tt>.
   *
   * <b>Preconditions:</b><ul>
   * <li><tt>this->Np() > 0</tt>
   * <li><tt>0 <= l < this->Np()</tt>
   * </ul>
   *
   * <b>Postconditions:</b><ul>
   * <li> <tt>return.get()!=NULL</tt>
   * </ul>
   */
  virtual RCP<const VectorSpaceBase<Scalar> > get_p_space(int l) const = 0;

  /** \brief Get the names of the parameters associated with parameter
   * subvector l if available.
   *
   * \return Returns an RCP to a Teuchos::Array<std::string> object that
   * contains the names of the parameters.   If returnVal == Teuchos::null,
   * then there are no names available for the parameter subvector p(l).
   * If returnVal->size() == 1, then a single name is given to the entire
   * parameter subvector.  If returnVal->size() == get_p_space(l)->dim(),
   * then a name is given to every parameter scalar entry.
   *
   * The default implementation return returnVal==Teuchos::null which means
   * by default, parameters have no names associated with them.
   */
  virtual RCP<const Teuchos::Array<std::string> > get_p_names(int l) const = 0;

  /** \brief Return the vector space for the auxiliary response functions
   * <tt>g(j) <: RE^n_g_j</tt>.
   *
   * <b>Preconditions:</b><ul>
   * <li><tt>this->Ng() > 0</tt>
   * <li><tt>0 <= j < this->Ng()</tt>
   * </ul>
   *
   * <b>Postconditions:</b><ul>
   * <li> <tt>return.get()!=NULL</tt>
   * </ul>
   */
  virtual RCP<const VectorSpaceBase<Scalar> > get_g_space(int j) const = 0;

  /** \brief Get the names of the response functions associated with
   * subvector j if available.
   *
   * \return Returns a Teuchos::Array<cosnt std::string> object that
   * contains the names of the responses.   If returnVal.size() == 0,
   * then there are no names available for the response subvector g(j).
   * If returnVal.size() == 1, then a single name is given to the entire
   * response subvector.  If returnVal.size() == get_g_space(l)->dim(),
   * then a name is given to every parameter scalar entry.
   *
   * The default implementation return returnVal.size() == 0 which means
   * by default, responses have no names associated with them.
   */
  virtual Teuchos::ArrayView<const std::string> get_g_names(int j) const = 0;

  //@}

  /** \name Initial guess and upper and lower bounds */
  //@{
  
  /** \brief Return the set of nominal values or initial guesses for the
   * supported the input arguments.
   *
   * In most cases, when a supported input argument is not specified in an
   * <tt>InArgs</tt> object passed to <tt>evalModel()</tt>, the nominal value
   * is assumed (see <tt>evalModel()</tt> for more details).
   *
   * A model does not have to return nominal values for every supported input
   * argument.  Therefore, just because
   * <tt>returnVal.supports(IN_ARG_blah)==true</tt>, the client should not
   * assume that <tt>returnVal.get_blah()!=null</tt>.
   *
   * <b>Warning!</b> Clients should not try to modify the state of the
   * contained objects.  Doing so might invalidate the state of <tt>*this</tt>
   * model or of other clients.  This is a hole in the const support and the
   * use of InArgs.  If a client wants to modify a value, then a clone of that
   * value should be created and reset on the returned InArgs object.  Do
   * *not* modify the values in place!
   */
  virtual ModelEvaluatorBase::InArgs<Scalar> getNominalValues() const = 0;
  
  /** \brief Return the set of lower bounds for the input arguments.
   *
   * It is not required for the client to supply lower bounds for every input
   * argument.  If a lower bound object for an input argument is null, then
   * the bounds of negative infinity should be assumed by the client.
   *
   * <b>Warning!</b> Clients should not try to modify the state of the
   * contained objects.  Doing so might invalidate the state of <tt>*this</tt>
   * model or of other clients.  This is a hole in the const support and the
   * use of InArgs.  If a client wants to modify a value, then a clone of that
   * value should be created and reset on the returned InArgs object.  Do
   * *not* modify the values in place!
   */
  virtual ModelEvaluatorBase::InArgs<Scalar> getLowerBounds() const = 0;
  
  /** \brief Return the set of upper bounds for the input arguments.
   *
   * It is not required for the client to supply upper bounds for every input
   * argument.  If an upper bound object for an input argument is null, then
   * the bounds of positive infinity should be assumed by the client.
   *
   * <b>Warning!</b> Clients should not try to modify the state of the
   * contained objects.  Doing so might invalidate the state of <tt>*this</tt>
   * model or of other clients.  This is a hole in the const support and the
   * use of InArgs.  If a client wants to modify a value, then a clone of that
   * value should be created and reset on the returned InArgs object.  Do
   * *not* modify the values in place!
   */
  virtual ModelEvaluatorBase::InArgs<Scalar> getUpperBounds() const = 0;

  //@}

  /** \name Factory functions for creating derivative objects */
  //@{

  /** \brief If supported, create a <tt>LinearOpWithSolveBase</tt> object for
   * <tt>W</tt> to be evaluated.
   *
   * <b>Preconditions:</b><ul>
   * <li><tt>this->createOutArgs().supports(OUT_ARG_W)==true</tt>
   * </ul>
   *
   * <b>Postconditions:</b><ul>
   * <li><tt>!is_null(returnVal)</tt>
   * </ul>
   *
   * Note that a model is only required to support a single <tt>W</tt>
   * object if the precondition below is satisfied and if the client asks for
   * more than one <tt>W</tt> object, the response should be to return
   * <tt>null</tt> from this function.
   */
  virtual RCP<LinearOpWithSolveBase<Scalar> > create_W() const = 0;

  /** \brief If supported, create a <tt>LinearOpBase</tt> object for
   * <tt>W</tt> to be evaluated.
   *
   * <b>Preconditions:</b><ul>
   * <li><tt>this->createOutArgs().supports(OUT_ARG_W_op)==true</tt>
   * </ul>
   *
   * <b>Postconditions:</b><ul>
   * <li><tt>!is_null(returnVal)</tt>
   * <li><tt>isPartiallyInitialized(*returnVal) || isFullyInitialized(*returnVal)</tt>
   * </ul>
   *
   * Note that a model is only required to support a single <tt>W_op</tt>
   * object if the precondition below is satisfied and if the client asks for
   * more than one <tt>W_op</tt> object, the response should be to return
   * <tt>null</tt> from this function.
   *
   * Also note the above post-condition that requires that a created
   * <tt>W_op</tt> object also needs to be at least partially initialized.
   * This means that its range and domain spaces must be fully formed and
   * accessible.  This greatly simplifies the creation of composite structures
   * and simplifies the implementation of certain types of implicit
   * ModelEvaluator subclasses.
   */
  virtual RCP<LinearOpBase<Scalar> > create_W_op() const = 0;

  /** \brief If supported, create a <tt>PreconditionerBase</tt> object for
   * <tt>W_prec</tt> to be evaluated.
   *
   * <b>Preconditions:</b><ul>
   * <li><tt>this->createOutArgs().supports(OUT_ARG_W_prec)==true</tt>
   * </ul>
   *
   * <b>Postconditions:</b><ul>
   * <li><tt>!is_null(returnVal)</tt>
   * <li><tt>isPartiallyInitialized(*returnVal-.someOp())
   *  || isFullyInitialized(*returnVal->someOp())</tt>
   * </ul>
   *
   * Note that a model is only required to support a single <tt>W_prec</tt>
   * object if the precondition below is satisfied and if the client asks for
   * more than one <tt>W_prec</tt> object, the response should be to return
   * <tt>null</tt> from this function.
   *
   * Also note the above post-condition requires that the embedded
   * preconditioner linear operators (signified by <tt>*W_prec->someOp()</tt>)
   * needs to be at least partially initialized.  This means that its range
   * and domain spaces must be fully formed and accessible.  This greatly
   * simplifies the creation of composite structures and simplifies the
   * implementation of certain types of implicit ModelEvaluator subclasses.
   */
  virtual RCP<PreconditionerBase<Scalar> > create_W_prec() const = 0;

  /** \brief If supported, create a linear operator derivative object for
   * <tt>D(f)/D(p(l))</tt>.
   *
   * <b>Preconditions:</b><ul>
   * <li><tt>this->Np() > 0</tt>
   * <li><tt>0 <= l < this->Np()</tt>
   * <li><tt>outArgs.supports_DfDp(l).supports(DERIV_LINEAR_OP)==true</tt>,
   *     where <tt>outArgs = this->createOutArgs()</tt>
   * </ul>
   */
  virtual RCP<LinearOpBase<Scalar> > create_DfDp_op(int l) const = 0;

  /** \brief If supported, create a linear operator derivative object for
   * <tt>D(g(j))/D(x_dot)</tt>.
   *
   * <b>Preconditions:</b><ul>
   * <li><tt>this->Ng() > 0</tt>
   * <li><tt>0 <= j < this->Ng()</tt>
   * <li><tt>outArgs.supports_DgDx_dot(j).supports(DERIV_LINEAR_OP)==true</tt>,
   *     where <tt>outArgs = this->createOutArgs()</tt>
   * </ul>
   */
  virtual RCP<LinearOpBase<Scalar> > create_DgDx_dot_op(int j) const = 0;

  /** \brief If supported, create a linear operator derivative object for
   * <tt>D(g(j))/D(x)</tt>.
   *
   * <b>Preconditions:</b><ul>
   * <li><tt>this->Ng() > 0</tt>
   * <li><tt>0 <= j < this->Ng()</tt>
   * <li><tt>outArgs.supports_DgDx(j).supports(DERIV_LINEAR_OP)==true</tt>,
   *     where <tt>outArgs = this->createOutArgs()</tt>
   * </ul>
   */
  virtual RCP<LinearOpBase<Scalar> > create_DgDx_op(int j) const = 0;

  /** \brief If supported, create a linear operator derivative object for
   * <tt>D(g(j))/D(p(l))</tt>.
   *
   * <b>Preconditions:</b><ul>
   * <li><tt>this->Ng() > 0</tt>
   * <li><tt>this->Np() > 0</tt>
   * <li><tt>0 <= j < this->Ng()</tt>
   * <li><tt>0 <= l < this->Np()</tt>
   * <li><tt>outArgs.supports_DgDp(j,l).supports(DERIV_LINEAR_OP)==true</tt>,
   *     where <tt>outArgs = this->createOutArgs()</tt>
   * </ul>
   */
  virtual RCP<LinearOpBase<Scalar> > create_DgDp_op( int j, int l ) const = 0;
  
  //@}

  /** \name Linear solver factory for W */
  //@{

  /** \brief If supported, return a <tt>LinearOpWithSolveFactoryBase</tt>
   * object that can be used to initialize a <tt>LOWSB</tt> object for
   * <tt>W</tt> given a <tt>LOB</tt> object for <tt>W_op</tt>.
   *
   * <b>Preconditions:</b><ul>
   * <li><tt>this->createOutArgs().supports(OUT_ARG_W) ||
   *     this->createOutArgs().supports(OUT_ARG_W_op)</tt>
   * </ul>
   *
   * By returning this factory object, a model evaluator allows a client to
   * compute the <tt>LOB</tt>-only version <tt>W_op</tt> and then allow client
   * to create a linear solver associated through the <tt>LOWSB</tt> interface
   * at any time.  Note that this allow allows access to the underlying
   * precondioner factory object
   * (i.e. <tt>this->get_W_factory()->getPreconditionerFactory()</tt.) if such
   * a factory object is supported.
   *
   * This function will return <tt>retalVal==Teuchos::null</tt> if no such
   * factory object is supported.
   */
  virtual RCP<const LinearOpWithSolveFactoryBase<Scalar> > get_W_factory() const = 0;

  //@}

  /** \name Computational functions */
  //@{

  /** \brief Create an empty input arguments object that can be set up and
   * passed to <tt>evalModel()</tt>.
   *
   * <b>Postconditions:</b><ul>
   * <li><tt>returnVal.supports(IN_ARG_blah)</tt> gives the variables that are
   * supported or not supported by the underlying model.
   * <li><tt>returnVal.get_blah(...)==null</tt> for all variables/parameters
   * that are supported.
   * </ul>
   * 
   */
  virtual ModelEvaluatorBase::InArgs<Scalar> createInArgs() const = 0;

  /** \brief Create an empty output functions/derivatives object that can be
   * set up and passed to <tt>evalModel()</tt>.
   *
   * <b>Postconditions:</b><ul>
   * <li><tt>returnVal.supports(OUT_ARG_blah...)</tt> gives the functions/derivatives that
   * are supported or not supported by the underlying model.
   * <li><tt>returnVal.get_blah(...) == null</tt> for all functions/derivatives
   * that are supported.
   * </ul>
   *
   */
  virtual ModelEvaluatorBase::OutArgs<Scalar> createOutArgs() const = 0;

  /** \brief Compute all of the requested functions/derivatives at the given
   * point.
   *
   * \param inArgs [in] Gives the values of the input variables and parameters
   * that are supported by the model.  This object must have been initially
   * created by <tt>this->createInArgs()</tt> before being set up by the
   * client.  All supported variables/parameters that are not set by the
   * client (i.e. <tt>inArgs.get_blah(...)==null</tt>) are assumed to be at
   * the nominal value.  If a particular input variable/parameter is not set
   * and does not have a nominal value
   * (i.e. <tt>this->getNominalValues().get_blah(...)==null</tt>, then the
   * evaluation is undefined and an exception should be thrown by a good
   * implementation.  The one exception this rule is support for
   * <tt>x_dot</tt>.  If <tt>x_dot</tt> is supported but not specified in
   * <tt>inArgs</tt>, then it is implicitly assumed to be zero.
   *
   * \param outArgs [out] Gives the objects for the supported functions and
   * derivatives that are to be computed at the given point.  This object must
   * have been created by <tt>this->createOutArgs()</tt> before being set up
   * by the client.  Only functions and derivatives that are set will be
   * computed.  The client should check for NaN in any of objects computed to
   * see if the evaluation failed.  Also, if the underlying object knows that
   * the evaluation failed, then <tt>outArgs.isFailed()</tt> will be
   * <tt>true</tt> on output.  The client needs to check for both NaN and
   * <tt>outArgs.isFailed()</tt> to be sure.
   *
   * <b>Preconditions:</b><ul>
   * <li><tt>this->createInArgs().isCompatible(inArgs)==true</tt>
   * <li><tt>this->creatOutnArgs().isCompatible(outArgs)==true</tt>
   * <li>[<tt>inArgs.supports(IN_ARG_blah)==true</tt>] <tt>inArgs.get_blah(...)!=null
   * || this->getNominalValues().get_blah(...)!=null</tt>.
   * <li><tt>inArgs.get_p(l)!=null ||
   * this->getNominalValues().get_pl(l)!=null</tt>, for
   * <tt>l=0...inArgs.Np()-1</tt>.
   * </ul>
   *
   * This function is the real meat of the <tt>%ModelEvaluator</tt> interface.
   * A whole set of supported functions and/or their various supported
   * derivatives are computed all in one shot at a given point (i.e. set of
   * values for input variables and parameters).  This allows a model to be
   * stateless in the sense that, in general, a model's behavior is assumed to
   * be unaffected by evaluations at previous points.  This greatly simplifies
   * software maintenance and makes data dependences explicit.
   *
   * <b>WARNING:</b> The implementation of this function must not create any
   * persisting associations involving any of the input or output objects
   * (even though these are returned through RCP objects).  This includes not
   * embedding any of the input objects in the created output objects.  One
   * reason for this requirement is that the RCP objects may not be strong
   * owning RCPs in which case the objects may not stay around.  This will
   * likely result in a dangling reference exception in a debug-mode bulid (or
   * a segfault in a non-debug build).  Also, even if the objects do stay
   * around, the implementation of <tt>evalModel(...)</tt> can not assume that
   * the objects will not be further modified by the client after
   * <tt>evalModel(...)</tt> is called.  For example, the value of the vector
   * returned from <tt>*inArgs.get_x()</tt> may changed by the client just
   * after this function finishes which would invalidate any objects that
   * might have expected it to not change.
   *
   * TODO: Define behavior for state-full models!
   */
  virtual void evalModel(
    const ModelEvaluatorBase::InArgs<Scalar> &inArgs,
    const ModelEvaluatorBase::OutArgs<Scalar> &outArgs
    ) const = 0;

  //@}

  /** \name Reporting functions */
  //@{

  /** \brief Report the final point and whether the problem was considered
   * solved or not.
   *
   * ToDo: Add a PL to InArgs to allow extra data like Lagrange multipliers to
   * be passed back as well?
   */
  virtual void reportFinalPoint(
    const ModelEvaluatorBase::InArgs<Scalar> &finalPoint,
    const bool wasSolved
    ) = 0;

  //@}

private:
  
  // Not defined and not to be called
  ModelEvaluator<Scalar>&
  operator=(const ModelEvaluator<Scalar>&);

};

} // namespace Thyra


#endif // THYRA_MODEL_EVALUATOR_HPP