9#include <kernel/cubature/rule.hpp> 
   20        typename Shape_ = 
typename Rule_::ShapeType>
 
   28      template<
typename Shape_, 
typename Weight_, 
typename Coord_, 
typename Po
int_>
 
   32        Index num_refines = 1)
 
   35        typedef Intern::RuleRefinery<RuleType> RefineryType;
 
   39          rule = std::move(rule_in.clone());
 
   41        else if(num_refines == 1)
 
   44            "refine:" + rule_in.get_name());
 
   45          RefineryType::refine(rule, rule_in);
 
   50          rule = std::move(rule_in.clone());
 
   51          for(
Index i(0); i < num_refines; ++i)
 
   53            RuleType rule_tmp(rule.get_num_points() * RefineryType::count,
 
   54              "refine*" + 
stringify(i+1) + 
":" + rule_in.get_name());
 
   55            RefineryType::refine(rule_tmp, rule);
 
   56            rule = std::move(rule_tmp);
 
   62    template<
typename Factory_>
 
   67      typedef Factory_ FactoryType;
 
   68      typedef typename Factory_::ShapeType ShapeType;
 
  102      using BaseClass::create;
 
  104      template<
typename Weight_, 
typename Coord_, 
typename Po
int_>
 
  108        String::size_type k = name.find_first_of(
':');
 
  113        String head(name.substr(0, k));
 
  114        String tail(name.substr(k + 1));
 
  117        Index num_refines = 1;
 
  120        k = head.find_first_of(
'*');
 
  128          head = head.substr(0, k);
 
  137        if(!FactoryType::create(rule_in, tail.
trim()))
 
  141        create(rule, rule_in, num_refines);
 
  148      bool variadic_ = Factory_::variadic>
 
  151    template<
typename Factory_>
 
  156      typedef Factory_ FactoryType;
 
  157      typedef typename Factory_::ShapeType ShapeType;
 
  159      static constexpr bool variadic = 
false;
 
  160      static constexpr int num_points = FactoryType::num_points;
 
  167        _num_refines(num_refines)
 
  171      using BaseClass::create;
 
  173      template<
typename Weight_, 
typename Coord_, 
typename Po
int_>
 
  176        create(rule, _num_refines);
 
  179      template<
typename Weight_, 
typename Coord_, 
typename Po
int_>
 
  183        FactoryType::create(rule_in);
 
  184        create(rule, rule_in, num_refines);
 
  188    template<
typename Factory_>
 
  193      typedef Factory_ FactoryType;
 
  194      typedef typename Factory_::ShapeType ShapeType;
 
  196      static constexpr bool variadic = 
true;
 
  197      static constexpr int min_points = FactoryType::min_points;
 
  198      static constexpr int max_points = FactoryType::max_points;
 
  206        _num_points(num_points),
 
  207        _num_refines(num_refines)
 
  211      using BaseClass::create;
 
  213      template<
typename Weight_, 
typename Coord_, 
typename Po
int_>
 
  216        create(rule, _num_points, _num_refines);
 
  219      template<
typename Weight_, 
typename Coord_, 
typename Po
int_>
 
  223        FactoryType::create(rule_in, num_points);
 
  224        create(rule, rule_in, num_refines);
 
  231      template<
typename Rule_>
 
  232      class RuleRefinery<Rule_, Shape::Simplex<1> >
 
  235        typedef typename Rule_::WeightType Weight_;
 
  236        typedef typename Rule_::CoordType Coord_;
 
  237        static constexpr int count = 2;
 
  239        static void refine(Rule_& rule, 
const Rule_& rule_in)
 
  241          int n = rule_in.get_num_points();
 
  242          for(
int i(0); i < n; ++i)
 
  244            rule.get_coord(  i, 0) = Coord_(0.5) *  rule_in.get_coord(i,0);
 
  245            rule.get_coord(n+i, 0) = Coord_(0.5) * (rule_in.get_coord(i,0) + Coord_(1));
 
  246            rule.get_weight(  i) = Weight_(0.5) * rule_in.get_weight(i);
 
  247            rule.get_weight(n+i) = Weight_(0.5) * rule_in.get_weight(i);
 
  252      template<
typename Rule_>
 
  253      class RuleRefinery<Rule_, Shape::Simplex<2> >
 
  256        typedef typename Rule_::WeightType Weight_;
 
  257        typedef typename Rule_::CoordType Coord_;
 
  258        static constexpr int count = 4;
 
  260        static void refine(Rule_& rule, 
const Rule_& rule_in)
 
  262          int n = rule_in.get_num_points();
 
  266          v[0][0][0] = Coord_(0);
 
  267          v[0][0][1] = Coord_(0);
 
  268          v[0][1][0] = Coord_(1)/Coord_(2);
 
  269          v[0][1][1] = Coord_(0);
 
  270          v[0][2][0] = Coord_(0);
 
  271          v[0][2][1] = Coord_(1)/Coord_(2);
 
  273          v[1][0][0] = Coord_(1)/Coord_(2);
 
  274          v[1][0][1] = Coord_(0);
 
  275          v[1][1][0] = Coord_(1);
 
  276          v[1][1][1] = Coord_(0);
 
  277          v[1][2][0] = Coord_(1)/Coord_(2);
 
  278          v[1][2][1] = Coord_(1)/Coord_(2);
 
  280          v[2][0][0] = Coord_(0);
 
  281          v[2][0][1] = Coord_(1)/Coord_(2);
 
  282          v[2][1][0] = Coord_(1)/Coord_(2);
 
  283          v[2][1][1] = Coord_(1)/Coord_(2);
 
  284          v[2][2][0] = Coord_(0);
 
  285          v[2][2][1] = Coord_(1);
 
  287          v[3][0][0] = Coord_(1)/Coord_(2);
 
  288          v[3][0][1] = Coord_(1)/Coord_(2);
 
  289          v[3][1][0] = Coord_(0);
 
  290          v[3][1][1] = Coord_(1)/Coord_(2);
 
  291          v[3][2][0] = Coord_(1)/Coord_(2);
 
  292          v[3][2][1] = Coord_(0);
 
  295          for(
int i(0); i <= 3; ++i)
 
  297            for(
int j(0); j < n; ++j)
 
  299              Coord_ x = rule_in.get_coord(j,0);
 
  300              Coord_ y = rule_in.get_coord(j,1);
 
  301              Coord_ w = Coord_(1) - x - y;
 
  302              rule.get_coord(i*n + j, 0) = w*v[i][0][0] + x*v[i][1][0] + y*v[i][2][0];
 
  303              rule.get_coord(i*n + j, 1) = w*v[i][0][1] + x*v[i][1][1] + y*v[i][2][1];
 
  304              rule.get_weight(i*n + j) = Weight_(0.25) * rule_in.get_weight(j);
 
  310      template<
typename Rule_>
 
  311      class RuleRefinery<Rule_, Shape::Simplex<3> >
 
  314        typedef typename Rule_::WeightType Weight_;
 
  315        typedef typename Rule_::CoordType Coord_;
 
  316        static constexpr int count = 12;
 
  318        static void refine(Rule_& rule, 
const Rule_& rule_in)
 
  326          v[0][0][0] = Coord_(1)/Coord_(2);
 
  327          v[0][0][1] = Coord_(0);
 
  328          v[0][0][2] = Coord_(0);
 
  331          v[0][1][0] = Coord_(0);
 
  332          v[0][1][1] = Coord_(0);
 
  333          v[0][1][2] = Coord_(1)/Coord_(2);
 
  336          v[0][2][0] = Coord_(0);
 
  337          v[0][2][1] = Coord_(1)/Coord_(2);
 
  338          v[0][2][2] = Coord_(0);
 
  341          v[0][3][0] = Coord_(0);
 
  342          v[0][3][1] = Coord_(0);
 
  343          v[0][3][2] = Coord_(0);
 
  349          v[1][0][0] = Coord_(1)/Coord_(2);
 
  350          v[1][0][1] = Coord_(0);
 
  351          v[1][0][2] = Coord_(0);
 
  354          v[1][1][0] = Coord_(0);
 
  355          v[1][1][1] = Coord_(1)/Coord_(2);
 
  356          v[1][1][2] = Coord_(0);
 
  359          v[1][2][0] = Coord_(0);
 
  360          v[1][2][1] = Coord_(0);
 
  361          v[1][2][2] = Coord_(1)/Coord_(2);
 
  364          v[1][3][0] = Coord_(1)/Coord_(4);
 
  365          v[1][3][1] = Coord_(1)/Coord_(4);
 
  366          v[1][3][2] = Coord_(1)/Coord_(4);
 
  372          v[2][0][0] = Coord_(1)/Coord_(2);
 
  373          v[2][0][1] = Coord_(0);
 
  374          v[2][0][2] = Coord_(0);
 
  377          v[2][1][0] = Coord_(1)/Coord_(2);
 
  378          v[2][1][1] = Coord_(1)/Coord_(2);
 
  379          v[2][1][2] = Coord_(0);
 
  382          v[2][2][0] = Coord_(1)/Coord_(2);
 
  383          v[2][2][1] = Coord_(0);
 
  384          v[2][2][2] = Coord_(1)/Coord_(2);
 
  387          v[2][3][0] = Coord_(1);
 
  388          v[2][3][1] = Coord_(0);
 
  389          v[2][3][2] = Coord_(0);
 
  395          v[3][0][0] = Coord_(1)/Coord_(2);
 
  396          v[3][0][1] = Coord_(0);
 
  397          v[3][0][2] = Coord_(0);
 
  400          v[3][1][0] = Coord_(1)/Coord_(2);
 
  401          v[3][1][1] = Coord_(0);
 
  402          v[3][1][2] = Coord_(1)/Coord_(2);
 
  405          v[3][2][0] = Coord_(1)/Coord_(2);
 
  406          v[3][2][1] = Coord_(1)/Coord_(2);
 
  407          v[3][2][2] = Coord_(0);
 
  410          v[3][3][0] = Coord_(1)/Coord_(4);
 
  411          v[3][3][1] = Coord_(1)/Coord_(4);
 
  412          v[3][3][2] = Coord_(1)/Coord_(4);
 
  418          v[4][0][0] = Coord_(0);
 
  419          v[4][0][1] = Coord_(1)/Coord_(2);
 
  420          v[4][0][2] = Coord_(0);
 
  423          v[4][1][0] = Coord_(0);
 
  424          v[4][1][1] = Coord_(1)/Coord_(2);
 
  425          v[4][1][2] = Coord_(1)/Coord_(2);
 
  428          v[4][2][0] = Coord_(1)/Coord_(2);
 
  429          v[4][2][1] = Coord_(1)/Coord_(2);
 
  430          v[4][2][2] = Coord_(0);
 
  433          v[4][3][0] = Coord_(0);
 
  434          v[4][3][1] = Coord_(1);
 
  435          v[4][3][2] = Coord_(0);
 
  441          v[5][0][0] = Coord_(0);
 
  442          v[5][0][1] = Coord_(1)/Coord_(2);
 
  443          v[5][0][2] = Coord_(0);
 
  446          v[5][1][0] = Coord_(1)/Coord_(2);
 
  447          v[5][1][1] = Coord_(1)/Coord_(2);
 
  448          v[5][1][2] = Coord_(0);
 
  451          v[5][2][0] = Coord_(0);
 
  452          v[5][2][1] = Coord_(1)/Coord_(2);
 
  453          v[5][2][2] = Coord_(1)/Coord_(2);
 
  456          v[5][3][0] = Coord_(1)/Coord_(4);
 
  457          v[5][3][1] = Coord_(1)/Coord_(4);
 
  458          v[5][3][2] = Coord_(1)/Coord_(4);
 
  464          v[6][0][0] = Coord_(0);
 
  465          v[6][0][1] = Coord_(0);
 
  466          v[6][0][2] = Coord_(1)/Coord_(2);
 
  469          v[6][1][0] = Coord_(1)/Coord_(2);
 
  470          v[6][1][1] = Coord_(0);
 
  471          v[6][1][2] = Coord_(1)/Coord_(2);
 
  474          v[6][2][0] = Coord_(0);
 
  475          v[6][2][1] = Coord_(1)/Coord_(2);
 
  476          v[6][2][2] = Coord_(1)/Coord_(2);
 
  479          v[6][3][0] = Coord_(0);
 
  480          v[6][3][1] = Coord_(0);
 
  481          v[6][3][2] = Coord_(1);
 
  487          v[7][0][0] = Coord_(0);
 
  488          v[7][0][1] = Coord_(0);
 
  489          v[7][0][2] = Coord_(1)/Coord_(2);
 
  492          v[7][1][0] = Coord_(0);
 
  493          v[7][1][1] = Coord_(1)/Coord_(2);
 
  494          v[7][1][2] = Coord_(1)/Coord_(2);
 
  497          v[7][2][0] = Coord_(1)/Coord_(2);
 
  498          v[7][2][1] = Coord_(0);
 
  499          v[7][2][2] = Coord_(1)/Coord_(2);
 
  502          v[7][3][0] = Coord_(1)/Coord_(4);
 
  503          v[7][3][1] = Coord_(1)/Coord_(4);
 
  504          v[7][3][2] = Coord_(1)/Coord_(4);
 
  510          v[8][0][0] = Coord_(1)/Coord_(2);
 
  511          v[8][0][1] = Coord_(1)/Coord_(2);
 
  512          v[8][0][2] = Coord_(0);
 
  515          v[8][1][0] = Coord_(1)/Coord_(2);
 
  516          v[8][1][1] = Coord_(0);
 
  517          v[8][1][2] = Coord_(1)/Coord_(2);
 
  520          v[8][2][0] = Coord_(0);
 
  521          v[8][2][1] = Coord_(1)/Coord_(2);
 
  522          v[8][2][2] = Coord_(1)/Coord_(2);
 
  525          v[8][3][0] = Coord_(1)/Coord_(4);
 
  526          v[8][3][1] = Coord_(1)/Coord_(4);
 
  527          v[8][3][2] = Coord_(1)/Coord_(4);
 
  533          v[9][0][0] = Coord_(0);
 
  534          v[9][0][1] = Coord_(1)/Coord_(2);
 
  535          v[9][0][2] = Coord_(0);
 
  538          v[9][1][0] = Coord_(0);
 
  539          v[9][1][1] = Coord_(1)/Coord_(2);
 
  540          v[9][1][2] = Coord_(1)/Coord_(2);
 
  543          v[9][2][0] = Coord_(0);
 
  544          v[9][2][1] = Coord_(0);
 
  545          v[9][2][2] = Coord_(1)/Coord_(2);
 
  548          v[9][3][0] = Coord_(1)/Coord_(4);
 
  549          v[9][3][1] = Coord_(1)/Coord_(4);
 
  550          v[9][3][2] = Coord_(1)/Coord_(4);
 
  556          v[10][0][0] = Coord_(1)/Coord_(2);
 
  557          v[10][0][1] = Coord_(0);
 
  558          v[10][0][2] = Coord_(0);
 
  561          v[10][1][0] = Coord_(0);
 
  562          v[10][1][1] = Coord_(0);
 
  563          v[10][1][2] = Coord_(1)/Coord_(2);
 
  566          v[10][2][0] = Coord_(1)/Coord_(2);
 
  567          v[10][2][1] = Coord_(0);
 
  568          v[10][2][2] = Coord_(1)/Coord_(2);
 
  571          v[10][3][0] = Coord_(1)/Coord_(4);
 
  572          v[10][3][1] = Coord_(1)/Coord_(4);
 
  573          v[10][3][2] = Coord_(1)/Coord_(4);
 
  579          v[11][0][0] = Coord_(1)/Coord_(2);
 
  580          v[11][0][1] = Coord_(0);
 
  581          v[11][0][2] = Coord_(0);
 
  584          v[11][1][0] = Coord_(1)/Coord_(2);
 
  585          v[11][1][1] = Coord_(1)/Coord_(2);
 
  586          v[11][1][2] = Coord_(0);
 
  589          v[11][2][0] = Coord_(0);
 
  590          v[11][2][1] = Coord_(1)/Coord_(2);
 
  591          v[11][2][2] = Coord_(0);
 
  594          v[11][3][0] = Coord_(1)/Coord_(4);
 
  595          v[11][3][1] = Coord_(1)/Coord_(4);
 
  596          v[11][3][2] = Coord_(1)/Coord_(4);
 
  599          int n = rule_in.get_num_points();
 
  603          for(
int i(0); i <= 11; ++i)
 
  605            for(
int j(0); j < n; ++j)
 
  607              Coord_ x = rule_in.get_coord(j,0);
 
  608              Coord_ y = rule_in.get_coord(j,1);
 
  609              Coord_ z = rule_in.get_coord(j,2);
 
  610              Coord_ w = Coord_(1) - x - y - z;
 
  611              rule.get_coord(i*n + j, 0) = w*v[i][0][0] + x*v[i][1][0] + y*v[i][2][0] + z*v[i][3][0];
 
  612              rule.get_coord(i*n + j, 1) = w*v[i][0][1] + x*v[i][1][1] + y*v[i][2][1] + z*v[i][3][1];
 
  613              rule.get_coord(i*n + j, 2) = w*v[i][0][2] + x*v[i][1][2] + y*v[i][2][2] + z*v[i][3][2];
 
  624              if(i == 0 || i == 2 || i == 4|| i == 6)
 
  626                vol = Weight_(1)/Weight_(8);
 
  630                vol = Weight_(1)/Weight_(16);
 
  633              rule.get_weight(i*n + j) = rule_in.get_weight(j)*Math::abs(vol);
 
  639      template<
typename Rule_>
 
  640      class RuleRefinery<Rule_, Shape::Hypercube<1> >
 
  643        typedef typename Rule_::WeightType Weight_;
 
  644        typedef typename Rule_::CoordType Coord_;
 
  645        static constexpr int count = 2;
 
  647        static void refine(Rule_& rule, 
const Rule_& rule_in)
 
  649          int n = rule_in.get_num_points();
 
  650          for(
int i(0); i < n; ++i)
 
  652            rule.get_coord(  i, 0) = Coord_(0.5) * rule_in.get_coord(i,0) - Coord_(0.5);
 
  653            rule.get_coord(n+i, 0) = Coord_(0.5) * rule_in.get_coord(i,0) + Coord_(0.5);
 
  654            rule.get_weight(  i) = Weight_(0.5) * rule_in.get_weight(i);
 
  655            rule.get_weight(n+i) = Weight_(0.5) * rule_in.get_weight(i);
 
  661      template<
typename Rule_>
 
  662      class RuleRefinery<Rule_, Shape::Hypercube<2> >
 
  665        typedef typename Rule_::WeightType Weight_;
 
  666        typedef typename Rule_::CoordType Coord_;
 
  667        static constexpr int count = 4;
 
  669        static void refine(Rule_& rule, 
const Rule_& rule_in)
 
  672          int n = rule_in.get_num_points();
 
  675          for(
int i(0); i <= 3; ++i)
 
  678            Coord_ dx = Coord_(0);
 
  679            Coord_ dy = Coord_(0);
 
  683              dx = -Coord_(1)/Coord_(2);
 
  684              dy = -Coord_(1)/Coord_(2);
 
  688              dx = Coord_(1)/Coord_(2);
 
  689              dy = -Coord_(1)/Coord_(2);
 
  693              dx = -Coord_(1)/Coord_(2);
 
  694              dy = Coord_(1)/Coord_(2);
 
  698              dx = Coord_(1)/Coord_(2);
 
  699              dy = Coord_(1)/Coord_(2);
 
  702            for(
int j(0); j < n; ++j)
 
  704              rule.get_coord(i*n + j, 0) = Coord_(0.5) * rule_in.get_coord(j,0) + dx;
 
  705              rule.get_coord(i*n + j, 1) = Coord_(0.5) * rule_in.get_coord(j,1) + dy;
 
  706              rule.get_weight(i*n + j) = rule_in.get_weight(j)/Weight_(4);
 
  712      template<
typename Rule_>
 
  713      class RuleRefinery<Rule_, Shape::Hypercube<3> >
 
  716        typedef typename Rule_::WeightType Weight_;
 
  717        typedef typename Rule_::CoordType Coord_;
 
  718        static constexpr int count = 8;
 
  720        static void refine(Rule_& rule, 
const Rule_& rule_in)
 
  723          int n = rule_in.get_num_points();
 
  726          for(
int i(0); i <= 7; ++i)
 
  729            Coord_ dx = Coord_(0);
 
  730            Coord_ dy = Coord_(0);
 
  731            Coord_ dz = Coord_(0);
 
  735              dx = -Coord_(1)/Coord_(2);
 
  736              dy = -Coord_(1)/Coord_(2);
 
  737              dz = -Coord_(1)/Coord_(2);
 
  741              dx =  Coord_(1)/Coord_(2);
 
  742              dy = -Coord_(1)/Coord_(2);
 
  743              dz = -Coord_(1)/Coord_(2);
 
  747              dx = -Coord_(1)/Coord_(2);
 
  748              dy =  Coord_(1)/Coord_(2);
 
  749              dz = -Coord_(1)/Coord_(2);
 
  753              dx =  Coord_(1)/Coord_(2);
 
  754              dy =  Coord_(1)/Coord_(2);
 
  755              dz = -Coord_(1)/Coord_(2);
 
  759              dx = -Coord_(1)/Coord_(2);
 
  760              dy = -Coord_(1)/Coord_(2);
 
  761              dz =  Coord_(1)/Coord_(2);
 
  765              dx =  Coord_(1)/Coord_(2);
 
  766              dy = -Coord_(1)/Coord_(2);
 
  767              dz =  Coord_(1)/Coord_(2);
 
  771              dx = -Coord_(1)/Coord_(2);
 
  772              dy =  Coord_(1)/Coord_(2);
 
  773              dz =  Coord_(1)/Coord_(2);
 
  777              dx =  Coord_(1)/Coord_(2);
 
  778              dy =  Coord_(1)/Coord_(2);
 
  779              dz =  Coord_(1)/Coord_(2);
 
  782            for(
int j(0); j < n; ++j)
 
  784              rule.get_coord(i*n + j, 0) = Coord_(0.5) * rule_in.get_coord(j,0) + dx;
 
  785              rule.get_coord(i*n + j, 1) = Coord_(0.5) * rule_in.get_coord(j,1) + dy;
 
  786              rule.get_coord(i*n + j, 2) = Coord_(0.5) * rule_in.get_coord(j,2) + dz;
 
  787              rule.get_weight(i*n + j) = rule_in.get_weight(j)/Weight_(8);
 
Cubature Rule class template.
String class implementation.
bool parse(T_ &t) const
Parses the string and stores its value in the provided variable.
int compare_no_case(const String &other) const
Compares two strings without regard to case.
String trim(const String &charset) const
Trims the string.
String stringify(const T_ &item)
Converts an item into a String.
std::uint64_t Index
Index data type.