]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Function Parser Interface.
authorLuca Heltai <luca.heltai@sissa.it>
Mon, 7 Mar 2005 15:51:05 +0000 (15:51 +0000)
committerLuca Heltai <luca.heltai@sissa.it>
Mon, 7 Mar 2005 15:51:05 +0000 (15:51 +0000)
git-svn-id: https://svn.dealii.org/trunk@10029 0785d39b-7218-0410-832d-ea1e28bc413d

deal.II/base/source/function_parser.cc [new file with mode: 0644]

diff --git a/deal.II/base/source/function_parser.cc b/deal.II/base/source/function_parser.cc
new file mode 100644 (file)
index 0000000..b0488b3
--- /dev/null
@@ -0,0 +1,157 @@
+//----------------------------  function_parser.cc ---------------------
+//    $Id$
+//    Version: $Name$
+//
+//    Copyright (C) 2005 by the deal.II authors
+//
+//    This file is subject to QPL and may not be  distributed
+//    without copyright and license information. Please refer
+//    to the file deal.II/doc/license.html for the  text  and
+//    further information on this license.
+//
+//----------------------------  function_parser.cc ---------------------
+
+#include <base/function_parser.h>
+#include <base/point.h>
+#include <lac/vector.h>
+
+template <int dim>
+FunctionParser<dim>::FunctionParser(const unsigned int n_components,
+                                   const double       initial_time)
+  : Function<dim>(n_components, initial_time)
+{ 
+  fp = new fparser::FunctionParser[n_components];
+}
+
+template <int dim>
+FunctionParser<dim>::~FunctionParser() {
+  delete fp;
+}
+
+
+
+template <int dim>
+void FunctionParser<dim>::initialize(const std::string variables,
+                                    const std::vector<std::string> expressions,
+                                    std::map<std::string, double> constants,
+                                    bool time_dependent,
+                                    bool use_degrees)
+{
+  // We distinguish between two cases: Time dependent problems, and
+  // not time dependent problems. In the first case the number of
+  // variables is given by the number of components plus one. In the
+  // other case, the number of variables is equal to the number of
+  // components. If none of this is the case, then an exception is
+  // thrown.
+  if (time_dependent) 
+    n_vars = this->n_components+1;
+  else 
+    n_vars = this->n_components;
+
+  AssertThrow(this->n_components == expressions.size(),
+             ExcInvalidExpressionSize(this->n_components,
+                                      expressions.size()) );
+
+  for (unsigned int i=0; i<this->n_components; ++i) {
+    // Add the variuous constants to the parser.
+    ConstMapIterator
+      constant = constants.begin(),
+      endc  = constants.end();
+    for(;constant != endc; ++constant) {
+      AssertThrow( fp[i].AddConstant(constant->first, constant->second),
+             ExcMessage("Invalid Constant Name"));
+    }
+
+
+    int ret_value = fp[i].Parse(expressions[i], 
+                               variables, 
+                               use_degrees);
+    AssertThrow(ret_value == -1, 
+               ExcParseError(ret_value, fp[i].ErrorMsg()));
+    
+    // The fact that the parser did not throw an error does not mean
+    // that everything went ok... we can still have problems with the
+    // number of variables...
+
+  } 
+  
+  // Let's check if the number of variables is correct...
+  AssertThrow(n_vars == fp[0].NVars(), 
+             ExcDimensionMismatch(n_vars,fp[0].NVars()));
+    
+  // Now set the initialization bit.
+  initialized = true;
+}
+template <int dim>
+void FunctionParser<dim>::initialize(const std::string variables,
+                                    const std::string expression,
+                                    std::map<std::string, double> constants,
+                                    bool time_dependent,
+                                    bool use_degrees)
+{
+  std::vector<std::string> expressions(1,expression);
+  initialize(variables, expressions, constants, time_dependent, use_degrees); 
+}
+
+template <int dim>
+inline
+double FunctionParser<dim>::value (const Point<dim> &p,
+                                  unsigned int component) const 
+{
+  AssertThrow(initialized==true, ExcNotInitialized());
+  AssertThrow(component < this->n_components,
+             ExcIndexRange(component, 0, this->n_components));
+  // Statically allocates dim+1 double variables.
+  double vars[dim+1];
+  
+  for(unsigned int i=0; i<dim; ++i)
+    vars[i] = p(i);
+  
+  // We need the time variable only if the number of variables is
+  // different from the dimension. In this case it can only be dim+1,
+  // otherwise an exception would have already been thrown
+  if(dim != n_vars)
+    vars[dim] = this->get_time();
+  
+  double my_value = fp[component].Eval(vars);
+  
+  AssertThrow(fp[component].EvalError() == 0,
+             ExcMessage(fp[component].ErrorMsg()));
+  
+  return my_value;
+}
+
+
+template <int dim>
+inline
+void FunctionParser<dim>::vector_value (const Point<dim> &p,
+                                          Vector<double>   &values) const 
+{
+  AssertThrow(initialized==true, ExcNotInitialized());
+  AssertThrow(values.size() == this->n_components,
+             ExcDimensionMismatch (values.size(), this->n_components));
+  // Statically allocates dim+1 double variables.
+  double vars[dim+1];
+  
+  for(unsigned int i=0; i<dim; ++i)
+    vars[i] = p(i);
+  
+  // We need the time variable only if the number of variables is
+  // different from the dimension. In this case it can only be dim+1,
+  // otherwise an exception would have already been thrown
+  if(dim != n_vars)
+    vars[dim] = this->get_time();
+  
+  for(unsigned int component = 0; component < this->n_components;
+      ++component) {
+    values(component) = fp[component].Eval(vars);
+    Assert(fp[component].EvalError() == 0,
+          ExcMessage(fp[component].ErrorMsg()));
+  }
+}
+
+// Explicit Instantiations.
+
+template class FunctionParser<1>;
+template class FunctionParser<2>;
+template class FunctionParser<3>;

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.