SundanceSymbPreprocessor.cpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 // 
00004 //                             Sundance
00005 //                 Copyright 2011 Sandia Corporation
00006 // 
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00008 // the U.S. Government retains certain rights in this software.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Kevin Long (kevin.long@ttu.edu)
00038 // 
00039 
00040 /* @HEADER@ */
00041 
00042 #include "SundanceSymbPreprocessor.hpp"
00043 #include "SundanceEvaluatorFactory.hpp"
00044 #include "SundanceEvaluator.hpp"
00045 #include "SundanceEvalManager.hpp"
00046 #include "SundanceExpr.hpp"
00047 #include "PlayaTabs.hpp"
00048 #include "SundanceZeroExpr.hpp"
00049 #include "SundanceDiscreteFuncElement.hpp"
00050 #include "SundanceDiscreteFunctionStub.hpp"
00051 #include "SundanceTestFuncElement.hpp"
00052 #include "SundanceUnknownFuncElement.hpp"
00053 #include "SundanceUnknownParameterElement.hpp"
00054 #include "SundanceUnknownFunctionStub.hpp"
00055 #include "SundanceTestFunctionStub.hpp"
00056 
00057 #include "SundanceOut.hpp"
00058 #include "Teuchos_Utils.hpp"
00059 
00060 using namespace Sundance;
00061 using namespace Sundance;
00062 using namespace Teuchos;
00063 
00064 
00065 
00066 
00067 
00068 DerivSet SymbPreprocessor::setupFwdProblem(const Expr& expr, 
00069   const Expr& tests,
00070   const Expr& unks,
00071   const Expr& unkEvalPts, 
00072   const Expr& unkParams,
00073   const Expr& unkParamEvalPts,
00074   const Expr& fixedParams,
00075   const Expr& fixedParamEvalPts,
00076   const Expr& fixedFields,
00077   const Expr& fixedFieldEvalPts,
00078   const EvalContext& context,
00079   const ComputationType& compType)
00080 {
00081   Expr zero;
00082   Expr v = tests.flatten();
00083   Array<Expr> z(v.size());
00084   for (int i=0; i<v.size(); i++) z[i] = new ZeroExpr();
00085   zero = new ListExpr(z);
00086 
00087   return setupVariations(expr, 
00088     tests, zero,
00089     unks, unkEvalPts,
00090     unkParams, unkParamEvalPts,
00091     fixedFields, fixedFieldEvalPts,
00092     fixedParams, fixedParamEvalPts,
00093     context, compType);
00094 }
00095 
00096 
00097 
00098 
00099 DerivSet SymbPreprocessor::setupSensitivities(const Expr& expr, 
00100   const Expr& tests,
00101   const Expr& unks,
00102   const Expr& unkEvalPts, 
00103   const Expr& unkParams,
00104   const Expr& unkParamEvalPts,
00105   const Expr& fixedParams,
00106   const Expr& fixedParamEvalPts,
00107   const Expr& fixedFields,
00108   const Expr& fixedFieldEvalPts,
00109   const EvalContext& context,
00110   const ComputationType& compType)
00111 {
00112   Expr zero;
00113   Expr v = tests.flatten();
00114   Array<Expr> z(v.size());
00115   for (int i=0; i<v.size(); i++) z[i] = new ZeroExpr();
00116   zero = new ListExpr(z);
00117 
00118   return setupVariations(expr, 
00119     tests, zero,
00120     unks, unkEvalPts,
00121     unkParams, unkParamEvalPts,
00122     fixedFields, fixedFieldEvalPts,
00123     fixedParams, fixedParamEvalPts,
00124     context, compType);
00125 }
00126 
00127 
00128 DerivSet SymbPreprocessor::setupFunctional(const Expr& expr, 
00129   const Expr& fixedParams,
00130   const Expr& fixedParamEvalPts,
00131   const Expr& fixedFields,
00132   const Expr& fixedFieldEvalPts,
00133   const EvalContext& context,
00134   const ComputationType& compType)
00135 {
00136   Expr vars;
00137   Expr varEvalPts;
00138   Expr unks;
00139   Expr unkEvalPts;
00140   Expr unkParams;
00141   Expr unkParamEvalPts;
00142 
00143   return setupVariations(expr, 
00144     vars, varEvalPts,
00145     unks, unkEvalPts,
00146     unkParams, unkParamEvalPts,
00147     fixedFields, fixedFieldEvalPts,
00148     fixedParams, fixedParamEvalPts,
00149     context,compType);
00150 }
00151 
00152 
00153 
00154 
00155 
00156 DerivSet SymbPreprocessor::setupGradient(const Expr& expr, 
00157   const Expr& vars,
00158   const Expr& varEvalPts,
00159   const Expr& fixedParams,
00160   const Expr& fixedParamEvalPts,
00161   const Expr& fixedFields,
00162   const Expr& fixedFieldEvalPts, 
00163   const EvalContext& context,
00164   const ComputationType& compType)
00165 {
00166   Expr unks;
00167   Expr unkEvalPts;
00168   Expr unkParams;
00169   Expr unkParamEvalPts;
00170 
00171   return setupVariations(expr, 
00172     vars, varEvalPts,
00173     unks, unkEvalPts,
00174     unkParams, unkParamEvalPts,
00175     fixedFields, fixedFieldEvalPts,
00176     fixedParams, fixedParamEvalPts,
00177     context, compType);
00178 }
00179 
00180 
00181 
00182 
00183 DerivSet SymbPreprocessor::setupVariations(const Expr& expr, 
00184   const Expr& vars,
00185   const Expr& varEvalPts,
00186   const Expr& unks,
00187   const Expr& unkEvalPts,
00188   const Expr& unkParams,
00189   const Expr& unkParamEvalPts,
00190   const Expr& fixedFields,
00191   const Expr& fixedFieldEvalPts, 
00192   const Expr& fixedParams,
00193   const Expr& fixedParamEvalPts, 
00194   const EvalContext& context,
00195   const ComputationType& compType)
00196 {
00197   TimeMonitor t(preprocTimer());
00198   Tabs tab;
00199 
00200   const EvaluatableExpr* e 
00201     = dynamic_cast<const EvaluatableExpr*>(expr.ptr().get());
00202 
00203   Array<Set<MultiSet<int> > > funcDerivs(3);
00204   Array<Set<MultiIndex> > spatialDerivs(3);
00205 
00206   int verb=context.setupVerbosity();
00207   SUNDANCE_BANNER1(verb, tab, "in setupVariations()");
00208   verbosity<EvaluatableExpr>() = verb;
00209   SUNDANCE_MSG1(verb,
00210     tab << "************ setting up variations of expr: " 
00211     << expr 
00212     << std::endl << tab << "context is " << context 
00213     << std::endl << tab << "conp type is " << compType
00214     << std::endl << tab << "vars are " << vars
00215     << std::endl << tab << "unks are " << unks
00216     << std::endl << tab << "unk parameters " << unkParams
00217     << std::endl << tab << "fixed parameters " << fixedParams
00218     << std::endl << tab << "the eval points for the vars are " 
00219     << varEvalPts
00220     << std::endl << tab << "the eval points for the unks are " 
00221     << unkEvalPts
00222     << std::endl << tab 
00223     << "the eval points for the unknown parameters are " 
00224     << unkParamEvalPts 
00225     << std::endl << tab 
00226     << "the eval points for the fixed parameters are " 
00227     << fixedParamEvalPts 
00228     << tab << std::endl);
00229 
00230   TEUCHOS_TEST_FOR_EXCEPTION(e==0, std::logic_error,
00231     "Non-evaluatable expr " << expr.toString()
00232     << " given to SymbPreprocessor::setupExpr()");
00233 
00234   /* make flat lists of variations, unknowns, parameters, and fixed fields */
00235   Expr v = vars.flatten();
00236   Expr v0 = varEvalPts.flatten();
00237   Expr u = unks.flatten();
00238   Expr u0 = unkEvalPts.flatten();
00239   Expr alpha = unkParams.flatten();
00240   Expr alpha0 = unkParamEvalPts.flatten();
00241   Expr beta = fixedParams.flatten();
00242   Expr beta0 = fixedParamEvalPts.flatten();
00243   Expr f = fixedFields.flatten();
00244   Expr f0 = fixedFieldEvalPts.flatten();
00245   
00246 
00247 
00248   Set<int> varID = processInputFuncs<SymbolicFuncElement>(v, v0);
00249 
00250   Set<int> unkID = processInputFuncs<UnknownFuncElement>(u, u0);
00251 
00252   Set<int> fixedID = processInputFuncs<UnknownFuncElement>(f, f0);
00253 
00254   Set<int> unkParamID 
00255     = processInputParams<UnknownParameterElement>(alpha, alpha0);
00256 
00257   Set<int> fixedParamID 
00258     = processInputParams<UnknownParameterElement>(beta, beta0);
00259 
00260 
00261   
00262 
00263   /* put together the set of functions that are active differentiation
00264    * variables */
00265 
00266   SUNDANCE_MSG2(verb, tab << "forming active set");
00267   Array<Sundance::Set<MultiSet<int> > > activeFuncIDs(3);
00268   if (context.needsDerivOrder(0)) activeFuncIDs[0].put(MultiSet<int>());
00269   if (context.topLevelDiffOrder() >= 1)
00270   {
00271     for (Set<int>::const_iterator i=varID.begin(); i != varID.end(); i++)
00272     {
00273       if (context.needsDerivOrder(1)) activeFuncIDs[1].put(makeMultiSet<int>(*i));
00274       if (context.topLevelDiffOrder()==2)
00275       {
00276         for (Set<int>::const_iterator j=unkID.begin(); j != unkID.end(); j++)
00277         {
00278           activeFuncIDs[2].put(makeMultiSet<int>(*i, *j));
00279         }
00280         if (compType==MatrixAndVector)
00281         {
00282           for (Set<int>::const_iterator 
00283                  j=unkParamID.begin(); j != unkParamID.end(); j++)
00284           {
00285             activeFuncIDs[2].put(makeMultiSet<int>(*i, *j));
00286           }
00287         }
00288         else if (compType==Sensitivities)
00289         {
00290           for (Set<int>::const_iterator 
00291                  j=fixedParamID.begin(); j != fixedParamID.end(); j++)
00292           {
00293             activeFuncIDs[2].put(makeMultiSet<int>(*i, *j));
00294           }
00295         }
00296       }
00297     }
00298   }
00299   SUNDANCE_MSG1(verb, tab << std::endl << tab 
00300     << " ************* Finding nonzeros for expr " << std::endl << tab);
00301   for (int i=0; i<=context.topLevelDiffOrder(); i++)
00302   {
00303     Tabs tab2;
00304     SUNDANCE_MSG4(verb, tab2 << "diff order=" << i << ", active funcs="
00305       << activeFuncIDs[i]);
00306   }
00307 
00308   Set<MultiIndex> miSet;
00309   miSet.put(MultiIndex());
00310   e->registerSpatialDerivs(context, miSet);
00311   
00312   SUNDANCE_MSG2(verb,
00313     tab << std::endl << tab 
00314     << " ************* finding required functions" << std::endl << tab);
00315   SUNDANCE_MSG2(verb,
00316     tab << "activeFuncIDs are = " << activeFuncIDs);
00317   SUNDANCE_MSG2(verb,
00318     tab << "spatial derivs are = " << spatialDerivs);
00319   Array<Set<MultipleDeriv> > RInput 
00320     = e->computeInputR(context, activeFuncIDs, spatialDerivs);
00321 
00322   SUNDANCE_MSG3(verb,
00323     tab << std::endl << tab 
00324     << " ************* Top-level required funcs are " << RInput << std::endl << tab);
00325 
00326 
00327   SUNDANCE_MSG2(verb,
00328     tab << std::endl << tab 
00329     << " ************* Calling determineR()" << std::endl << tab);
00330   
00331   e->determineR(context, RInput);
00332 
00333   
00334   SUNDANCE_MSG1(verb,
00335     tab << std::endl << tab 
00336     << " ************* Finding sparsity structure " << std::endl << tab);
00337   DerivSet derivs = e->sparsitySuperset(context)->derivSet();
00338   SUNDANCE_MSG1(verb,
00339     tab << std::endl << tab 
00340     << "Nonzero deriv set = " << derivs);
00341 
00342   SUNDANCE_MSG1(verb,
00343     tab << std::endl << tab 
00344     << " ************* Setting up evaluators for expr " << std::endl << tab);
00345 
00346   int saveVerb = context.setupVerbosity();
00347   context.setSetupVerbosity(0);
00348   e->setupEval(context);
00349 
00350   if (verb>1)
00351   { 
00352     SUNDANCE_MSG1(verb,
00353       tab << std::endl << tab 
00354       << " ************* Nonzeros are:");
00355     e->displayNonzeros(Out::os(), context);
00356 
00357   }
00358 
00359 
00360   context.setSetupVerbosity(saveVerb);
00361   return derivs;
00362 }
00363 
00364 
00365 namespace Sundance
00366 {
00367 Expr makeZeros(const Expr& v)
00368 {
00369   Array<Expr> z(v.size());
00370   for (int i=0; i<v.size(); i++) 
00371   {
00372     if (v[i].size()==1) z[i] = new ZeroExpr();
00373     else z[i] = makeZeros(v[i]);
00374   }
00375   return new ListExpr(z);
00376 }
00377 }

Site Contact