libmesh解析
本工作只是尝试解析原libmesh的代码,供学习使用
 全部  命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 
parsed_function.h
浏览该文件的文档.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2023 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 #ifndef LIBMESH_PARSED_FUNCTION_H
19 #define LIBMESH_PARSED_FUNCTION_H
20 
21 #include "libmesh/libmesh_config.h"
22 #include "libmesh/function_base.h"
23 
24 #ifdef LIBMESH_HAVE_FPARSER
25 
26 // Local includes
27 #include "libmesh/dense_vector.h"
28 #include "libmesh/int_range.h"
29 #include "libmesh/vector_value.h"
30 #include "libmesh/point.h"
31 
32 // FParser includes
33 #include "libmesh/fparser_ad.hh"
34 
35 // C++ includes
36 #include <algorithm> // std::find
37 #include <cmath>
38 #include <cmath>
39 #include <cstddef>
40 #include <iomanip>
41 #include <limits>
42 #include <memory>
43 #include <sstream>
44 #include <string>
45 #include <vector>
46 
47 namespace libMesh
48 {
49 
57 template <typename Output=Number, typename OutputGradient=Gradient>
58 class ParsedFunction : public FunctionBase<Output>
59 {
60 public:
68  explicit
69  ParsedFunction (std::string expression,
70  const std::vector<std::string> * additional_vars=nullptr,
71  const std::vector<Output> * initial_vals=nullptr);
72 
73 
76 
77  ParsedFunction (ParsedFunction &&) = default;
79  virtual ~ParsedFunction () = default;
80 
86  void reparse (std::string expression);
87 
95  virtual Output operator() (const Point & p,
96  const Real time = 0) override;
97 
103  virtual bool has_derivatives() { return _valid_derivatives; }
104 
112  virtual Output dot(const Point & p,
113  const Real time = 0);
114 
122  virtual OutputGradient gradient(const Point & p,
123  const Real time = 0);
124 
132  virtual void operator() (const Point & p,
133  const Real time,
134  DenseVector<Output> & output) override;
135 
144  virtual Output component (unsigned int i,
145  const Point & p,
146  Real time) override;
147 
153  const std::string & expression() { return _expression; }
154 
161  virtual Output & getVarAddress(std::string_view variable_name);
162 
168  virtual std::unique_ptr<FunctionBase<Output>> clone() const override;
169 
181  Output get_inline_value(std::string_view inline_var_name) const;
182 
196  void set_inline_value(std::string_view inline_var_name,
197  Output newval);
198 
199 protected:
205  void partial_reparse (std::string expression);
206 
214  std::size_t find_name (std::string_view varname,
215  std::string_view expr) const;
216 
223  bool expression_is_time_dependent( std::string_view expression ) const;
224 
225 private:
232  void set_spacetime(const Point & p,
233  const Real time = 0);
234 
243  inline Output eval(FunctionParserADBase<Output> & parser,
244  std::string_view libmesh_dbg_var(function_name),
245  unsigned int libmesh_dbg_var(component_idx)) const;
246 
250  std::string _expression;
251 
255  std::vector<std::string> _subexpressions;
256 
260  std::vector<std::unique_ptr<FunctionParserADBase<Output>>> parsers;
261 
265  std::vector<Output> _spacetime;
266 
270  std::vector<std::unique_ptr<FunctionParserADBase<Output>>> dx_parsers;
271 
272  #if LIBMESH_DIM > 1
273 
276  std::vector<std::unique_ptr<FunctionParserADBase<Output>>> dy_parsers;
277  #endif
278 
279  #if LIBMESH_DIM > 2
280 
283  std::vector<std::unique_ptr<FunctionParserADBase<Output>>> dz_parsers;
284  #endif
285 
289  std::vector<std::unique_ptr<FunctionParserADBase<Output>>> dt_parsers;
290 
295 
299  std::string variables;
300 
304  std::vector<std::string> _additional_vars;
305 
309  std::vector<Output> _initial_vals;
310 };
311 
312 
313 /*----------------------- Inline functions ----------------------------------*/
314 
315 template <typename Output, typename OutputGradient>
316 inline
318  const std::vector<std::string> * additional_vars,
319  const std::vector<Output> * initial_vals) :
320  _expression (), // overridden by parse()
321  // 调整时空向量的大小,以考虑空间、时间和传递的任何其他变量
322  _spacetime (LIBMESH_DIM+1 + (additional_vars ? additional_vars->size() : 0)),
323  _valid_derivatives (true),
324  _additional_vars (additional_vars ? *additional_vars : std::vector<std::string>()),
325  _initial_vals (initial_vals ? *initial_vals : std::vector<Output>())
326 {
327  // time-dependence established in reparse function
328  this->reparse(std::move(expression));
329  this->_initialized = true;
330 }
331 
332 
333 template <typename Output, typename OutputGradient>
334 inline
336  FunctionBase<Output>(other),
337  _expression(other._expression),
338  _subexpressions(other._subexpressions),
339  _spacetime(other._spacetime),
340  _valid_derivatives(other._valid_derivatives),
341  variables(other.variables),
342  _additional_vars(other._additional_vars),
343  _initial_vals(other._initial_vals)
344 {
345  // 可以通过重新解析表达式从头生成解析器
346  this->reparse(this->_expression);
347  this->_initialized = true;
348 }
349 
350 
351 
352 template <typename Output, typename OutputGradient>
353 inline
356 {
357  // Use copy-and-swap idiom
359  std::swap(tmp, *this);
360  return *this;
361 }
362 
363 
364 template <typename Output, typename OutputGradient>
365 inline
366 void
368 {
369  variables = "x";
370 #if LIBMESH_DIM > 1
371  variables += ",y";
372 #endif
373 #if LIBMESH_DIM > 2
374  variables += ",z";
375 #endif
376  variables += ",t";
377 
378  // 如果传递了额外的变量,将它们附加到我们发送给函数解析器的字符串中。也把它们加到时空向量的末尾
379  for (auto i : index_range(_additional_vars))
380  {
381  variables += "," + _additional_vars[i];
382  // 将额外变量初始化为传入或zeroNote的向量:initial_vals向量可以比additional_vars向量短
383  _spacetime[LIBMESH_DIM+1 + i] =
384  (i < _initial_vals.size()) ? _initial_vals[i] : 0;
385  }
386 
387  this->_is_time_dependent = this->expression_is_time_dependent(expression);
388 
389  this->partial_reparse(std::move(expression));
390 }
391 
392 template <typename Output, typename OutputGradient>
393 inline
394 Output
396 {
397  set_spacetime(p, time);
398  return eval(*parsers[0], "f", 0);
399 }
400 
401 template <typename Output, typename OutputGradient>
402 inline
403 Output
405 {
406  set_spacetime(p, time);
407  return eval(*dt_parsers[0], "df/dt", 0);
408 }
409 
410 template <typename Output, typename OutputGradient>
411 inline
412 OutputGradient
414 {
415  OutputGradient grad;
416  set_spacetime(p, time);
417 
418  grad(0) = eval(*dx_parsers[0], "df/dx", 0);
419 #if LIBMESH_DIM > 1
420  grad(1) = eval(*dy_parsers[0], "df/dy", 0);
421 #endif
422 #if LIBMESH_DIM > 2
423  grad(2) = eval(*dz_parsers[0], "df/dz", 0);
424 #endif
425 
426  return grad;
427 }
428 
429 template <typename Output, typename OutputGradient>
430 inline
431 void
433  (const Point & p,
434  const Real time,
435  DenseVector<Output> & output)
436 {
437  set_spacetime(p, time);
438 
439  unsigned int size = output.size();
440 
441  libmesh_assert_equal_to (size, parsers.size());
442 
443  // 剩余的时空位置目前是固定的,但有可能是动态的
444  for (unsigned int i=0; i != size; ++i)
445  output(i) = eval(*parsers[i], "f", i);
446 }
447 
452 template <typename Output, typename OutputGradient>
453 inline
454 Output
456  const Point & p,
457  Real time)
458 {
459  set_spacetime(p, time);
460  libmesh_assert_less (i, parsers.size());
461 
462  // _spacetime中的其余位置目前在构建时是固定的,但可能会被动态化
463  libmesh_assert_less(i, parsers.size());
464  return eval(*parsers[i], "f", i);
465 }
466 
470 template <typename Output, typename OutputGradient>
471 inline
472 Output &
474 {
475  const std::vector<std::string>::iterator it =
476  std::find(_additional_vars.begin(), _additional_vars.end(), variable_name);
477 
478  libmesh_error_msg_if(it == _additional_vars.end(),
479  "ERROR: Requested variable not found in parsed function");
480 
481  // 迭代器算术(我们的目标地址离数组末尾有多远?)
482  return _spacetime[_spacetime.size() - (_additional_vars.end() - it)];
483 }
484 
485 
486 template <typename Output, typename OutputGradient>
487 inline
488 std::unique_ptr<FunctionBase<Output>>
490 {
491  return std::make_unique<ParsedFunction>(_expression,
492  &_additional_vars,
493  &_initial_vals);
494 }
495 
496 template <typename Output, typename OutputGradient>
497 inline
498 Output
499 ParsedFunction<Output,OutputGradient>::get_inline_value (std::string_view inline_var_name) const
500 {
501  libmesh_assert_greater (_subexpressions.size(), 0);
502 
503 #ifndef NDEBUG
504  bool found_var_name = false;
505 #endif
506  Output old_var_value(0.);
507 
508  for (const auto & subexpression : _subexpressions)
509  {
510  const std::size_t varname_i =
511  find_name(inline_var_name, subexpression);
512  if (varname_i == std::string::npos)
513  continue;
514 
515  const std::size_t assignment_i =
516  subexpression.find(":", varname_i+1);
517 
518  libmesh_assert_not_equal_to(assignment_i, std::string::npos);
519 
520  libmesh_assert_equal_to(subexpression[assignment_i+1], '=');
521  for (std::size_t i = varname_i+1; i != assignment_i; ++i)
522  libmesh_assert_equal_to(subexpression[i], ' ');
523 
524  std::size_t end_assignment_i =
525  subexpression.find(";", assignment_i+1);
526 
527  libmesh_assert_not_equal_to(end_assignment_i, std::string::npos);
528 
529  std::string new_subexpression =
530  subexpression.substr(0, end_assignment_i+1).append(inline_var_name);
531 
532 #ifdef LIBMESH_HAVE_FPARSER
533  // Parse and evaluate the new subexpression.
534  // Add the same constants as we used originally.
535  FunctionParserADBase<Output> fp;
536  fp.AddConstant("NaN", std::numeric_limits<Real>::quiet_NaN());
537  fp.AddConstant("pi", std::acos(Real(-1)));
538  fp.AddConstant("e", std::exp(Real(1)));
539  libmesh_error_msg_if
540  (fp.Parse(new_subexpression, variables) != -1, // -1 for success
541  "ERROR: FunctionParser is unable to parse modified expression: "
542  << new_subexpression << '\n' << fp.ErrorMsg());
543 
544  Output new_var_value = this->eval(fp, new_subexpression, 0);
545 #ifdef NDEBUG
546  return new_var_value;
547 #else
548  if (found_var_name)
549  {
550  libmesh_assert_equal_to(old_var_value, new_var_value);
551  }
552  else
553  {
554  old_var_value = new_var_value;
555  found_var_name = true;
556  }
557 #endif
558 
559 #else
560  libmesh_error_msg("ERROR: This functionality requires fparser!");
561 #endif
562  }
563 
564  libmesh_assert(found_var_name);
565  return old_var_value;
566 }
567 
568 
569 template <typename Output, typename OutputGradient>
570 inline
571 void
573  Output newval)
574 {
575  libmesh_assert_greater (_subexpressions.size(), 0);
576 
577 #ifndef NDEBUG
578  bool found_var_name = false;
579 #endif
580  for (auto & subexpression : _subexpressions)
581  {
582  const std::size_t varname_i =
583  find_name(inline_var_name, subexpression);
584  if (varname_i == std::string::npos)
585  continue;
586 
587 #ifndef NDEBUG
588  found_var_name = true;
589 #endif
590  const std::size_t assignment_i =
591  subexpression.find(":", varname_i+1);
592 
593  libmesh_assert_not_equal_to(assignment_i, std::string::npos);
594 
595  libmesh_assert_equal_to(subexpression[assignment_i+1], '=');
596  for (std::size_t i = varname_i+1; i != assignment_i; ++i)
597  libmesh_assert_equal_to(subexpression[i], ' ');
598 
599  std::size_t end_assignment_i =
600  subexpression.find(";", assignment_i+1);
601 
602  libmesh_assert_not_equal_to(end_assignment_i, std::string::npos);
603 
604  std::ostringstream new_subexpression;
605  new_subexpression << subexpression.substr(0, assignment_i+2)
606  << std::setprecision(std::numeric_limits<Output>::digits10+2)
607 #ifdef LIBMESH_USE_COMPLEX_NUMBERS
608  << '(' << newval.real() << '+'
609  << newval.imag() << 'i' << ')'
610 #else
611  << newval
612 #endif
613  << subexpression.substr(end_assignment_i,
614  std::string::npos);
615  subexpression = new_subexpression.str();
616  }
617 
618  libmesh_assert(found_var_name);
619 
620  std::string new_expression;
621 
622  for (const auto & subexpression : _subexpressions)
623  {
624  new_expression += '{';
625  new_expression += subexpression;
626  new_expression += '}';
627  }
628 
629  this->partial_reparse(new_expression);
630 }
631 
632 
633 template <typename Output, typename OutputGradient>
634 inline
635 void
637 {
638  _expression = std::move(expression);
639  _subexpressions.clear();
640  parsers.clear();
641 
642  size_t nextstart = 0, end = 0;
643 
644  while (end != std::string::npos)
645  {
646  // 如果超出了字符串的末尾,就不能再创建子解析器了
647  if (nextstart >= _expression.size())
648  break;
649 
650  // 如果在一个用大括号分隔的section的开头,那么只解析该section:
651  if (_expression[nextstart] == '{')
652  {
653  nextstart++;
654  end = _expression.find('}', nextstart);
655  }
656  // 否则解析整个东西
657  else
658  end = std::string::npos;
659 
660  // 我们要么需要整个字符串的末尾(end == npos),要么需要中间的子字符串。
661  _subexpressions.push_back
662  (_expression.substr(nextstart, (end == std::string::npos) ?
663  std::string::npos : end - nextstart));
664 
665  // Fparser可能会在空表达式上崩溃
666  libmesh_error_msg_if(_subexpressions.back().empty(),
667  "ERROR: FunctionParser is unable to parse empty expression.\n");
668 
669  // 解析(并尽可能优化)子表达式。添加一些基本常量,以达到真正的精度。
670  auto fp = std::make_unique<FunctionParserADBase<Output>>();
671  fp->AddConstant("NaN", std::numeric_limits<Real>::quiet_NaN());
672  fp->AddConstant("pi", std::acos(Real(-1)));
673  fp->AddConstant("e", std::exp(Real(1)));
674  libmesh_error_msg_if
675  (fp->Parse(_subexpressions.back(), variables) != -1, // -1 for success
676  "ERROR: FunctionParser is unable to parse expression: "
677  << _subexpressions.back() << '\n' << fp->ErrorMsg());
678 
679  // use of derivatives is optional. suppress error output on the console
680  // use the has_derivatives() method to check if AutoDiff was successful.
681  // also enable immediate optimization
682  fp->SetADFlags(FunctionParserADBase<Output>::ADSilenceErrors |
683  FunctionParserADBase<Output>::ADAutoOptimize);
684 
685  // 优化原始函数
686  fp->Optimize();
687 
688  // 通过自动微分生成导数
689  auto dx_fp = std::make_unique<FunctionParserADBase<Output>>(*fp);
690  if (dx_fp->AutoDiff("x") != -1) // -1 for success
691  _valid_derivatives = false;
692  dx_parsers.push_back(std::move(dx_fp));
693 #if LIBMESH_DIM > 1
694  auto dy_fp = std::make_unique<FunctionParserADBase<Output>>(*fp);
695  if (dy_fp->AutoDiff("y") != -1) // -1 for success
696  _valid_derivatives = false;
697  dy_parsers.push_back(std::move(dy_fp));
698 #endif
699 #if LIBMESH_DIM > 2
700  auto dz_fp = std::make_unique<FunctionParserADBase<Output>>(*fp);
701  if (dz_fp->AutoDiff("z") != -1) // -1 for success
702  _valid_derivatives = false;
703  dz_parsers.push_back(std::move(dz_fp));
704 #endif
705  auto dt_fp = std::make_unique<FunctionParserADBase<Output>>(*fp);
706  if (dt_fp->AutoDiff("t") != -1) // -1 for success
707  _valid_derivatives = false;
708  dt_parsers.push_back(std::move(dt_fp));
709 
710  // 如果在末尾,使用nextstart=maxSize。否则从下一个字符开始。
711  nextstart = (end == std::string::npos) ?
712  std::string::npos : end + 1;
713 
714  // Store fp for later use
715  parsers.push_back(std::move(fp));
716  }
717 }
718 
719 
720 template <typename Output, typename OutputGradient>
721 inline
722 std::size_t
724  std::string_view expr) const
725 {
726  const std::size_t namesize = varname.size();
727  std::size_t varname_i = expr.find(varname);
728 
729  while ((varname_i != std::string::npos) &&
730  (((varname_i > 0) &&
731  (std::isalnum(expr[varname_i-1]) ||
732  (expr[varname_i-1] == '_'))) ||
733  ((varname_i+namesize < expr.size()) &&
734  (std::isalnum(expr[varname_i+namesize]) ||
735  (expr[varname_i+namesize] == '_')))))
736  {
737  varname_i = expr.find(varname, varname_i+1);
738  }
739 
740  return varname_i;
741 }
742 template <typename Output, typename OutputGradient>
743 inline
744 bool
746 {
747  bool is_time_dependent = false;
748 
749  // 根据定义,对于基于functionbase的对象,时间是“t”,所以只需要看看这个表达式中是否有变量“t”。
750  if (this->find_name(std::string("t"), expression) != std::string::npos)
751  is_time_dependent = true;
752 
753  return is_time_dependent;
754 }
755 
756 // 设置_spacetime参数向量
757 template <typename Output, typename OutputGradient>
758 inline
759 void
761  const Real time)
762 {
763  _spacetime[0] = p(0);
764 #if LIBMESH_DIM > 1
765  _spacetime[1] = p(1);
766 #endif
767 #if LIBMESH_DIM > 2
768  _spacetime[2] = p(2);
769 #endif
770  _spacetime[LIBMESH_DIM] = time;
771 
772  // _spacetime中的其余位置目前在构建时是固定的,但可能会被动态化
773 }
774 
775 // 对第i个FunctionParser求值并检查结果
776 template <typename Output, typename OutputGradient>
777 inline
778 Output
779 ParsedFunction<Output,OutputGradient>::eval (FunctionParserADBase<Output> & parser,
780  std::string_view function_name,
781  unsigned int component_idx) const
782 {
783  Output result = parser.Eval(_spacetime.data());
784  int error_code = parser.EvalError();
785  if (error_code)
786  {
787  libMesh::err << "ERROR: FunctionParser is unable to evaluate component "
788  << component_idx
789  << " for '"
790  << function_name;
791 
792  for (auto i : index_range(parsers))
793  if (parsers[i].get() == &parser)
794  libMesh::err << "' of expression '"
795  << _subexpressions[i];
796 
797  libMesh::err << "' with arguments:\n";
798  for (const auto & item : _spacetime)
799  libMesh::err << '\t' << item << '\n';
800  libMesh::err << '\n';
801 
802  // 目前没有API来报告错误消息,我们将手动完成
803  std::string error_message = "Reason: ";
804 
805  switch (error_code)
806  {
807  case 1:
808  error_message += "Division by zero";
809  break;
810  case 2:
811  error_message += "Square Root error (negative value)";
812  break;
813  case 3:
814  error_message += "Log error (negative value)";
815  break;
816  case 4:
817  error_message += "Trigonometric error (asin or acos of illegal value)";
818  break;
819  case 5:
820  error_message += "Maximum recursion level reached";
821  break;
822  default:
823  error_message += "Unknown";
824  break;
825  }
826  libmesh_error_msg(error_message);
827  }
828 
829  return result;
830 }
831 
832 } // namespace libMesh
833 
834 
835 #else // !LIBMESH_HAVE_FPARSER
836 
837 
838 namespace libMesh {
839 
840 
841 template <typename Output=Number>
842 class ParsedFunction : public FunctionBase<Output>
843 {
844 public:
845  ParsedFunction (std::string /* expression */,
846  const std::vector<std::string> * = nullptr,
847  const std::vector<Output> * = nullptr) : _dummy(0)
848  {
849  libmesh_not_implemented();
850  }
851 
856  ParsedFunction (ParsedFunction &&) = delete;
857  ParsedFunction (const ParsedFunction &) = delete;
858  ParsedFunction & operator= (const ParsedFunction &) = delete;
860  virtual ~ParsedFunction () = default;
861 
862  virtual Output operator() (const Point &,
863  const Real /* time */ = 0)
864  { return 0.; }
865 
866  virtual void operator() (const Point &,
867  const Real /* time */,
868  DenseVector<Output> & /* output */) {}
869 
870  virtual void init() {}
871  virtual void clear() {}
872  virtual Output & getVarAddress(std::string_view /*variable_name*/) { return _dummy; }
873  virtual std::unique_ptr<FunctionBase<Output>> clone() const
874  {
875  return std::make_unique<ParsedFunction<Output>>("");
876  }
877 private:
878  Output _dummy;
879 };
880 
881 
882 
883 } // namespace libMesh
884 
885 
886 #endif // LIBMESH_HAVE_FPARSER
887 
888 #endif // LIBMESH_PARSED_FUNCTION_H
virtual Output dot(const Point &p, const Real time=0)
计算 ParsedFunction 在给定点上的点乘结果。
virtual std::unique_ptr< FunctionBase< Output > > clone() const
void set_inline_value(std::string_view inline_var_name, Output newval)
Changes the value of an inline variable.
Output eval(FunctionParserADBase< Output > &parser, std::string_view libmesh_dbg_var(function_name), unsigned int libmesh_dbg_var(component_idx)) const
评估第 i 个 FunctionParser 并检查结果。
virtual std::unique_ptr< FunctionBase< Output > > clone() const override
克隆 ParsedFunction 对象。
virtual void clear()
清除函数。
void partial_reparse(std::string expression)
重新解析数学表达式,仅对表达式进行轻微更改。
Output get_inline_value(std::string_view inline_var_name) const
获取内联变量的值。
通过解析数学表达式生成(通过 FParser)的函数。所有重写的虚拟函数在 function_base.h 中都有文档说明。
ParsedFunction & operator=(const ParsedFunction &)
std::vector< Output > _spacetime
存储空间-时间参数向量的值。
std::vector< std::unique_ptr< FunctionParserADBase< Output > > > parsers
存储用于计算数学表达式的解析器的集合。
std::vector< std::string > _additional_vars
存储附加变量的名称,这些变量可以在函数中进行解析和处理。
void set_spacetime(const Point &p, const Real time=0)
设置 _spacetime 参数向量。
bool _initialized
当 init() 被调用以确保一切都准备好后,可以调用 operator() (...) 时为 true。
std::vector< std::string > _subexpressions
存储在数学表达式中找到的子表达式的字符串表示。
std::string _expression
存储数学表达式的字符串表示。
std::vector< std::unique_ptr< FunctionParserADBase< Output > > > dy_parsers
存储用于计算二维场景中 y 方向导数的解析器的集合。
std::vector< std::unique_ptr< FunctionParserADBase< Output > > > dt_parsers
存储用于计算时间导数的解析器的集合。
bool _valid_derivatives
用于跟踪导数是否有效的标志。
virtual Output & getVarAddress(std::string_view variable_name)
获取一个解析变量的地址,以便提供参数化的值。
std::size_t find_name(std::string_view varname, std::string_view expr) const
解析出变量名的辅助函数。
virtual Output component(unsigned int i, const Point &p, Real time) override
计算 ParsedFunction 的特定分量在给定点上的值。
ParsedFunction(std::string expression, const std::vector< std::string > *additional_vars=nullptr, const std::vector< Output > *initial_vals=nullptr)
构造函数。使用给定的数学表达式创建一个 ParsedFunction。
virtual ~ParsedFunction()=default
std::vector< std::unique_ptr< FunctionParserADBase< Output > > > dx_parsers
存储用于计算导数的解析器的集合。
OStreamProxy err
virtual bool has_derivatives()
查询是否成功生成了自动导数。
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual Output & getVarAddress(std::string_view)
ParsedFunction(std::string, const std::vector< std::string > *=nullptr, const std::vector< Output > *=nullptr)
bool expression_is_time_dependent(std::string_view expression) const
检查表达式是否与时间有关。
std::vector< std::unique_ptr< FunctionParserADBase< Output > > > dz_parsers
存储用于计算三维场景中 z 方向导数的解析器的集合。
void reparse(std::string expression)
重新解析 ParsedFunction 的数学表达式。
FunctionBase是一个函数对象的基类,可以在某一点(可选地包括时间)进行评估。
std::vector< Output > _initial_vals
存储函数中变量的初始值。
virtual Output operator()(const Point &p, const Real time=0) override
计算 ParsedFunction 在给定点上的值。
const std::string & expression()
获取 ParsedFunction 的数学表达式。
std::string variables
存储函数中可以解析和处理的变量名称和值。
virtual void init()
实际的初始化过程。
virtual OutputGradient gradient(const Point &p, const Real time=0)
计算 ParsedFunction 在给定点上的梯度。