8#include <kernel/geometry/conformal_mesh.hpp> 
    9#include <kernel/geometry/mesh_atlas.hpp> 
   10#include <kernel/geometry/mesh_part.hpp> 
   11#include <kernel/geometry/mesh_node.hpp> 
   12#include <kernel/geometry/atlas/bezier.hpp> 
   13#include <kernel/geometry/atlas/circle.hpp> 
   14#include <kernel/geometry/atlas/extrude.hpp> 
   15#include <kernel/geometry/atlas/surface_mesh.hpp> 
   16#include <kernel/geometry/atlas/sphere.hpp> 
   17#include <kernel/adjacency/dynamic_graph.hpp> 
   19#include <kernel/util/xml_scanner.hpp> 
   20#include <kernel/util/dist_file_io.hpp> 
   55    template<
typename RootMesh_>
 
   65      std::deque<std::pair<String,String>> _meshpart_to_chart;
 
   67      std::deque<String> _meshpart_deduct_topo;
 
   96        _meshpart_to_chart.emplace_back(std::make_pair(meshpart, chart));
 
  107        _meshpart_deduct_topo.emplace_back(meshpart);
 
  118        while(!_meshpart_to_chart.empty())
 
  120          String mpart_name = _meshpart_to_chart.front().first;
 
  121          String chart_name = _meshpart_to_chart.front().second;
 
  127            String msg = 
String(
"Chart '") + chart_name + 
"' not found for meshpart '" + mpart_name + 
"'";
 
  132          if(!
_mesh_node.set_mesh_part_chart(mpart_name, chart_name, chart))
 
  134            String msg = 
String(
"meshpart '" + mpart_name + 
"' not found");
 
  139          _meshpart_to_chart.pop_front();
 
  143        const RootMesh_* root_mesh = 
_mesh_node.get_mesh();
 
  146        while(!_meshpart_deduct_topo.empty())
 
  148          String mpart_name = _meshpart_deduct_topo.front();
 
  151          if(mesh_part == 
nullptr)
 
  153            String msg = 
String(
"meshpart '" + mpart_name + 
"' not found");
 
  158          if(root_mesh == 
nullptr)
 
  160            String msg = 
String(
"Cannot deduct topology for meshpart '") + mpart_name + 
"'; no root mesh found";
 
  168          _meshpart_deduct_topo.pop_front();
 
  177    template<
typename RootMesh_, 
int world_dim>
 
  178    struct DimensionalChartHelper;
 
  180    template<
typename RootMesh_>
 
  185      MeshAtlas<RootMesh_>& _atlas;
 
  187      std::unique_ptr<Atlas::ChartBase<RootMesh_>> _chart;
 
  190      explicit ChartParser(MeshAtlas<RootMesh_>& atlas) :
 
  191        _atlas(atlas), _chart_name(), _chart()
 
  195      virtual ~ChartParser()
 
  199      virtual bool attribs(std::map<String,bool>& attrs)
 const override 
  201        attrs.emplace(
"name", 
true); 
 
  206        int iline, 
const String& sline, 
const String&,
 
  207        const std::map<String, String>& attrs, 
bool closed)
 override 
  210          throw Xml::GrammarError(iline, sline, 
"Invalid closed markup");
 
  213        _chart_name = attrs.find(
"name")->second.
trim();
 
  214        if(_chart_name.empty())
 
  215          throw Xml::GrammarError(iline, sline, 
"Empty chart name");
 
  218        XASSERTM(_atlas.find_mesh_chart(_chart_name) == 
nullptr,
 
  219          String(
"Chart '") + _chart_name + 
"' already exists in atlas");
 
  224      virtual void close(
int iline, 
const String& sline)
 override 
  228          throw Xml::GrammarError(iline, sline, 
"Invalid empty chart");
 
  231        _atlas.add_mesh_chart(_chart_name, std::move(_chart));
 
  234      virtual bool content(
int, 
const String&)
 override 
  239      virtual std::shared_ptr<MarkupParser> markup(
int, 
const String&, 
const String& name)
 override 
  241        return DimensionalChartHelper<RootMesh_, RootMesh_::world_dim>::markup(name, _chart);
 
  246    template<
int num_coords_, 
typename Coord_>
 
  247    class VerticesParser :
 
  248      public Xml::MarkupParser
 
  251      typedef VertexSet<num_coords_, Coord_> VertexSetType;
 
  254      VertexSetType& _vertex_set;
 
  258      explicit VerticesParser(VertexSetType& vertex_set) :
 
  259        _vertex_set(vertex_set),
 
  264      virtual bool attribs(std::map<String,bool>&)
 const override 
  269      virtual void create(
int iline, 
const String& sline, 
const String&, 
const std::map<String, String>&, 
bool closed)
 override 
  272          throw Xml::GrammarError(iline, sline, 
"Invalid closed markup");
 
  275      virtual void close(
int iline, 
const String& sline)
 override 
  278        if(_read < _vertex_set.get_num_vertices())
 
  279          throw Xml::GrammarError(iline, sline, 
"Invalid terminator; expected point");
 
  282      virtual std::shared_ptr<MarkupParser> markup(
int, 
const String&, 
const String&)
 override 
  288      virtual bool content(
int iline, 
const String& sline)
 override 
  291        if(_read >= _vertex_set.get_num_vertices())
 
  292          throw Xml::ContentError(iline, sline, 
"Invalid content; expected terminator");
 
  295        std::deque<String> scoords = sline.split_by_whitespaces();
 
  298        if(scoords.size() != std::size_t(num_coords_))
 
  299          throw Xml::ContentError(iline, sline, 
"Invalid number of coordinates");
 
  302        auto& vtx = _vertex_set[_read];
 
  305        for(
int i(0); i < num_coords_; ++i)
 
  307          if(!scoords.at(std::size_t(i)).parse(vtx[i]))
 
  308            throw Xml::ContentError(iline, sline, 
"Failed to parse vertex coordinate");
 
  320      template<
typename Shape_, 
int dim_ = Shape_::dimension>
 
  321      struct TopoParseHelper
 
  323        template<
typename TopoParser_>
 
  324        static void init_topo(TopoParser_& tp, IndexSetHolder<Shape_>& ish, 
int dim)
 
  327            tp.init_idx_set(ish.template get_index_set<dim_, 0>(), dim_);
 
  329            TopoParseHelper<Shape_, dim_-1>::init_topo(tp, ish, dim);
 
  333      template<
typename Shape_>
 
  334      struct TopoParseHelper<Shape_, 0>
 
  336        template<
typename TopoParser_>
 
  337        static void init_topo(TopoParser_&, IndexSetHolder<Shape_>&, 
int)
 
  339          XABORTM(
"Thou shall not arrive here");
 
  343      template<
typename Shape_, 
int dim_ = Shape_::dimension>
 
  344      struct MappParseHelper
 
  346        template<
typename MappParser_>
 
  347        static void init_mapp(MappParser_& mp, TargetSetHolder<Shape_>& tsh, 
int dim)
 
  350            mp.init_trg_set(tsh.template get_target_set<dim_>(), dim_);
 
  352            MappParseHelper<Shape_, dim_-1>::init_mapp(mp, tsh, dim);
 
  356      template<
typename Shape_>
 
  357      struct MappParseHelper<Shape_, 0>
 
  359        template<
typename MappParser_>
 
  360        static void init_mapp(MappParser_& mp, TargetSetHolder<Shape_>& tsh, 
int)
 
  362          mp.init_trg_set(tsh.template get_target_set<0>(), 0);
 
  367    template<
typename Shape_>
 
  368    class TopologyParser :
 
  369      public Xml::MarkupParser
 
  372      typedef IndexSetHolder<Shape_> TopologyType;
 
  375      TopologyType& _topology;
 
  376      std::deque<int>& _have_topology;
 
  385      template<
int num_
idx_>
 
  386      void init_idx_set(IndexSet<num_idx_>& idx_set, 
int dim)
 
  388        _indices = 
reinterpret_cast<Index*
>(idx_set.get_indices());
 
  389        _my_dim = 
Index(dim);
 
  390        _num_idx = 
Index(num_idx_);
 
  391        _bound = idx_set.get_index_bound();
 
  392        _count = idx_set.get_num_entities();
 
  397      explicit TopologyParser(TopologyType& topology, std::deque<int>& have_topology) :
 
  399        _have_topology(have_topology),
 
  409      virtual bool attribs(std::map<String,bool>& attrs)
 const override 
  411        attrs.emplace(
"dim", 
true);
 
  415      virtual void create(
int iline, 
const String& sline, 
const String&, 
const std::map<String, String>& attrs, 
bool closed)
 override 
  418          throw Xml::GrammarError(iline, sline, 
"Invalid closed markup");
 
  421        if(!attrs.find(
"dim")->second.parse(_my_dim))
 
  422          throw Xml::ContentError(iline, sline, 
"Failed to parse 'dim' attribute");
 
  425        if((_my_dim > 
Index(_have_topology.size())) || (_my_dim == 
Index(0)))
 
  426          throw Xml::ContentError(iline, sline, 
"Invalid topology dimension");
 
  429        if(_have_topology.at(_my_dim-1) != 0)
 
  430          throw Xml::ContentError(iline, sline, 
"Multiple topology for dimension " + 
stringify(_my_dim));
 
  431        _have_topology.at(_my_dim-1) = 1;
 
  434        Intern::TopoParseHelper<Shape_>::init_topo(*
this, _topology, 
int(_my_dim));
 
  437      virtual void close(
int iline, 
const String& sline)
 override 
  441          throw Xml::GrammarError(iline, sline, 
"Invalid terminator; expected index tuple");
 
  444      virtual std::shared_ptr<MarkupParser> markup(
int, 
const String&, 
const String&)
 override 
  450      virtual bool content(
int iline, 
const String& sline)
 override 
  454          throw Xml::ContentError(iline, sline, 
"Invalid content; expected terminator");
 
  457        std::deque<String> sidx = sline.split_by_whitespaces();
 
  460        if(sidx.size() != std::size_t(_num_idx))
 
  461          throw Xml::ContentError(iline, sline, 
"Invalid number of indices");
 
  464        for(Index i(0); i < _num_idx; ++i)
 
  466          Index& idx = _indices[_read*_num_idx+i];
 
  469          if(!sidx.at(i).parse(idx))
 
  470            throw Xml::ContentError(iline, sline, 
"Failed to parse index");
 
  474            throw Xml::ContentError(iline, sline, 
"Index out of bounds");
 
  484    template<
typename Shape_>
 
  485    class MappingParser :
 
  486      public Xml::MarkupParser
 
  489      typedef TargetSetHolder<Shape_> MappingType;
 
  492      MappingType& _mapping;
 
  493      std::deque<int>& _have_mapping;
 
  500      void init_trg_set(TargetSet& trg_set, 
int dim)
 
  502        _indices = trg_set.get_indices();
 
  503        _my_dim = 
Index(dim);
 
  504        _count = trg_set.get_num_entities();
 
  508      explicit MappingParser(MappingType& mapping, std::deque<int>& have_mapping) :
 
  510        _have_mapping(have_mapping),
 
  518      virtual bool attribs(std::map<String,bool>& attrs)
 const override 
  520        attrs.emplace(
"dim", 
true);
 
  524      virtual void create(
int iline, 
const String& sline, 
const String&, 
const std::map<String, String>& attrs, 
bool closed)
 override 
  527          throw Xml::GrammarError(iline, sline, 
"Invalid closed markup");
 
  530        if(!attrs.find(
"dim")->second.parse(_my_dim))
 
  531          throw Xml::ContentError(iline, sline, 
"Failed to parse 'dim' attribute");
 
  534        if((_my_dim > 
Index(_have_mapping.size())))
 
  535          throw Xml::ContentError(iline, sline, 
"Invalid mapping dimension");
 
  538        if(_have_mapping.at(_my_dim) != 0)
 
  539          throw Xml::ContentError(iline, sline, 
"Multiple mapping for dimension " + 
stringify(_my_dim));
 
  540        _have_mapping.at(_my_dim) = 1;
 
  543        Intern::MappParseHelper<Shape_>::init_mapp(*
this, _mapping, 
int(_my_dim));
 
  546      virtual void close(
int iline, 
const String& sline)
 override 
  550          throw Xml::GrammarError(iline, sline, 
"Invalid terminator; expected index");
 
  553      virtual std::shared_ptr<MarkupParser> markup(
int, 
const String&, 
const String&)
 override 
  559      virtual bool content(
int iline, 
const String& sline)
 override 
  563          throw Xml::ContentError(iline, sline, 
"Invalid content; expected terminator");
 
  566        if(!sline.parse(_indices[_read]))
 
  567          throw Xml::ContentError(iline, sline, 
"Failed to parse index");
 
  576    template<
typename MeshPart_, 
typename DataType_ = 
typename MeshPart_::AttributeDataType>
 
  577    class AttributeParser :
 
  578      public Xml::MarkupParser
 
  581      typedef AttributeSet<DataType_> AttribType;
 
  584      MeshPart_& _mesh_part;
 
  585      std::unique_ptr<AttribType> _attrib;
 
  592      explicit AttributeParser(MeshPart_& mesh_part) :
 
  593        _mesh_part(mesh_part),
 
  601      virtual ~AttributeParser()
 
  605      virtual bool attribs(std::map<String,bool>& attrs)
 const override 
  607        attrs.emplace(
"dim", 
true);
 
  608        attrs.emplace(
"name", 
true);
 
  612      virtual void create(
int iline, 
const String& sline, 
const String&, 
const std::map<String, String>& attrs, 
bool closed)
 override 
  615          throw Xml::GrammarError(iline, sline, 
"Invalid closed markup");
 
  618        if(!attrs.find(
"dim")->second.parse(_my_dim))
 
  619          throw Xml::ContentError(iline, sline, 
"Failed to parse 'dim' attribute");
 
  622        if(_my_dim == 
Index(0))
 
  623          throw Xml::ContentError(iline, sline, 
"Invalid attribute dimension");
 
  626        _my_name = attrs.find(
"name")->second;
 
  629        _count = _mesh_part.get_num_entities(0);
 
  630        _attrib.reset(
new AttribType(_count, 
int(_my_dim)));
 
  633      virtual void close(
int iline, 
const String& sline)
 override 
  637          throw Xml::GrammarError(iline, sline, 
"Invalid terminator; expected index");
 
  640        _mesh_part.add_attribute(std::move(_attrib), _my_name);
 
  643      virtual std::shared_ptr<MarkupParser> markup(
int, 
const String&, 
const String&)
 override 
  649      virtual bool content(
int iline, 
const String& sline)
 override 
  653          throw Xml::ContentError(iline, sline, 
"Invalid content; expected terminator");
 
  656        std::deque<String> svals = sline.split_by_whitespaces();
 
  659        if(svals.size() != std::size_t(_my_dim))
 
  660          throw Xml::ContentError(iline, sline, 
"Invalid number of values");
 
  663        for(
int i(0); i < int(_my_dim); ++i)
 
  665          if(!svals.at(std::size_t(i)).parse(_attrib->operator()(_read,i)))
 
  666            throw Xml::ContentError(iline, sline, 
"Failed to parse value");
 
  676    template<
typename Mesh_>
 
  679    template<
typename Shape_, 
int num_coords_, 
typename Coord_>
 
  680    class MeshParser<ConformalMesh<Shape_, num_coords_, Coord_>> :
 
  681      public Xml::MarkupParser
 
  684      typedef ConformalMesh<Shape_, num_coords_, Coord_> MeshType;
 
  687      RootMeshNode<MeshType>& _root_node;
 
  688      std::unique_ptr<MeshType> _mesh;
 
  690      std::deque<int> _have_topology;
 
  691      std::vector<Index> _sizes;
 
  693      template<
int shape_dim_>
 
  694      static String aux_shape_string(
const Shape::Hypercube<shape_dim_>&)
 
  699      template<
int shape_dim_>
 
  700      static String aux_shape_string(
const Shape::Simplex<shape_dim_>&)
 
  706      explicit MeshParser(RootMeshNode<MeshType>& root_node) :
 
  707        _root_node(root_node),
 
  713      virtual ~MeshParser()
 
  717      virtual bool attribs(std::map<String,bool>& attrs)
 const override 
  719        attrs.emplace(
"type", 
true);
 
  720        attrs.emplace(
"size", 
true);
 
  724      virtual void create(
int iline, 
const String& sline, 
const String&, 
const std::map<String, String>& attrs, 
bool closed)
 override 
  727          throw Xml::GrammarError(iline, sline, 
"Invalid closed markup");
 
  730        std::deque<String> stype = attrs.find(
"type")->second.split_by_string(
":");
 
  733        if(stype.size() != std::size_t(4))
 
  734          throw Xml::ContentError(iline, sline, 
"Invalid mesh type attribue");
 
  735        if(stype.at(0) != 
"conformal")
 
  736          throw Xml::ContentError(iline, sline, 
"Invalid mesh type; expected 'conformal'");
 
  737        String sshape = aux_shape_string(Shape_());
 
  738        if(stype.at(1) != sshape)
 
  739          throw Xml::ContentError(iline, sline, 
"Invalid mesh shape type; expected '" + sshape + 
"'");
 
  740        int ishape_dim(0), iworld_dim(0);
 
  741        if(!stype.at(2).parse(ishape_dim))
 
  742          throw Xml::ContentError(iline, sline, 
"Failed to parse mesh shape dimension");
 
  743        if(ishape_dim != Shape_::dimension)
 
  744          throw Xml::ContentError(iline, sline, 
"Invalid mesh shape dimension");
 
  745        if(!stype.at(3).parse(iworld_dim))
 
  746          throw Xml::ContentError(iline, sline, 
"Failed to parse mesh world dimension");
 
  747        if(iworld_dim != num_coords_)
 
  748          throw Xml::ContentError(iline, sline, 
"Invalid mesh world dimension");
 
  753        std::deque<String> ssize = attrs.find(
"size")->second.split_by_whitespaces();
 
  754        if(ssize.size() != std::size_t(Shape_::dimension+1))
 
  755          throw Xml::ContentError(iline, sline, 
"Invalid mesh size count");
 
  758        _sizes.resize(ssize.size());
 
  759        for(std::size_t i(0); i <= std::size_t(Shape_::dimension); ++i)
 
  761          if(!ssize.at(i).parse(_sizes.at(i)))
 
  762            throw Xml::ContentError(iline, sline, 
"Failed to parse mesh size");
 
  766        _mesh.reset(
new MeshType(_sizes.data()));
 
  770        _have_topology.resize(std::size_t(Shape_::dimension), 0);
 
  773      virtual void close(
int iline, 
const String& sline)
 override 
  777          throw Xml::GrammarError(iline, sline, 
"Mesh has no Vertices");
 
  780        for(std::size_t i(0); i < _have_topology.size(); ++i)
 
  782          if(_have_topology.at(i) == 0)
 
  783            throw Xml::GrammarError(iline, sline, 
"Missing topology for dimension " + 
stringify(i+1));
 
  789        RedundantIndexSetBuilder<Shape_>::compute(*_mesh->get_topology());
 
  792        _root_node.set_mesh(std::move(_mesh));
 
  795      virtual std::shared_ptr<Xml::MarkupParser> markup(
int iline, 
const String& sline, 
const String& name)
 override 
  798        if(name == 
"Vertices")
 
  801            throw Xml::GrammarError(iline, sline, 
"More than one Vertices block in mesh");
 
  805          return std::make_shared<VerticesParser<num_coords_, Coord_>>(_mesh->get_vertex_set());
 
  809        if(name == 
"Topology")
 
  812          return std::make_shared<TopologyParser<Shape_>>(*_mesh->get_topology(), _have_topology);
 
  819      virtual bool content(
int, 
const String&)
 override 
  825    template<
typename Mesh_>
 
  826    class MeshPartParser;
 
  828    template<
typename Shape_, 
int num_coords_, 
typename Coord_>
 
  829    class MeshPartParser<ConformalMesh<Shape_, num_coords_, Coord_>> :
 
  830      public Xml::MarkupParser
 
  833      typedef ConformalMesh<Shape_, num_coords_, Coord_> MeshType;
 
  834      typedef MeshPart<MeshType> MeshPartType;
 
  835      typedef Atlas::ChartBase<MeshType> ChartType;
 
  844      RootMeshNode<MeshType>& _root_node;
 
  845      MeshNodeLinker<MeshType>& _linker;
 
  846      std::unique_ptr<MeshPartType> _mesh_part;
 
  849      String _name, _parent, _chart_name;
 
  850      std::deque<int> _have_topology;
 
  851      std::deque<int> _have_mapping;
 
  852      std::vector<Index> _sizes;
 
  855      explicit MeshPartParser(RootMeshNode<MeshType>& root_node, MeshNodeLinker<MeshType>& linker) :
 
  856        _root_node(root_node),
 
  860        _topo_type(TopoType::none)
 
  864      virtual ~MeshPartParser()
 
  868      virtual bool attribs(std::map<String,bool>& attrs)
 const override 
  870        attrs.emplace(
"name", 
true);
 
  871        attrs.emplace(
"parent", 
true);
 
  872        attrs.emplace(
"size", 
true);
 
  873        attrs.emplace(
"topology", 
true);
 
  874        attrs.emplace(
"chart", 
false);
 
  878      virtual void create(
int iline, 
const String& sline, 
const String&, 
const std::map<String, String>& attrs, 
bool closed)
 override 
  881          throw Xml::GrammarError(iline, sline, 
"Invalid closed markup");
 
  884        _name = attrs.find(
"name")->second;
 
  885        _parent = attrs.find(
"parent")->second;
 
  888        if(_root_node.find_mesh_part(_name) != 
nullptr)
 
  889          throw Xml::ContentError(iline, sline, String(
"Mesh Part '") + _name + 
"' already exists in mesh node");
 
  893          auto it = attrs.find(
"chart");
 
  894          if(it != attrs.end())
 
  897            _chart_name = it->second;
 
  898            _linker.meshpart_link_to_chart(_name, _chart_name);
 
  903        if(_parent != 
"root")
 
  904          throw Xml::ContentError(iline, sline, 
"Invalid mesh part parent; only 'root' is accepted");
 
  907        String stopo_type = attrs.find(
"topology")->second;
 
  908        if(stopo_type == 
"none")
 
  909          _topo_type = TopoType::none;
 
  910        else if(stopo_type == 
"full")
 
  911          _topo_type = TopoType::full;
 
  912        else if(stopo_type == 
"parent")
 
  914          _topo_type = TopoType::parent;
 
  915          _linker.meshpart_deduct_topology(_name);
 
  918          throw Xml::ContentError(iline, sline, 
"Invalid topology attribute '" + stopo_type + 
"'");
 
  921        std::deque<String> ssize = attrs.find(
"size")->second.split_by_whitespaces();
 
  922        if(ssize.size() > std::size_t(Shape_::dimension+1))
 
  923          throw Xml::ContentError(iline, sline, 
"Invalid mesh part size count");
 
  926        _sizes.resize(std::size_t(Shape_::dimension+1), 
Index(0));
 
  927        for(std::size_t i(0); i < ssize.size(); ++i)
 
  929          if(!ssize.at(i).parse(_sizes.at(i)))
 
  930            throw Xml::ContentError(iline, sline, 
"Failed to parse mesh part size");
 
  934        _mesh_part.reset(
new MeshPartType(_sizes.data(), _topo_type != TopoType::none));
 
  937        _have_topology.resize(std::size_t(Shape_::dimension), 0);
 
  938        _have_mapping.resize(std::size_t(Shape_::dimension+1), 0);
 
  941      virtual void close(
int iline, 
const String& sline)
 override 
  944        for(std::size_t i(0); i < _have_mapping.size(); ++i)
 
  946          if((_have_mapping.at(i) == 0) && (_sizes.at(i) > 
Index(0)))
 
  947            throw Xml::GrammarError(iline, sline, 
"Missing mapping for dimension " + 
stringify(i));
 
  950        if(_topo_type == TopoType::full)
 
  954          for(std::size_t i(0); i < _have_topology.size(); ++i)
 
  957            if(_sizes.at(i+1) > 0)
 
  958              topo_all = topo_all && (_have_topology.at(i) != 0);
 
  963            throw Xml::GrammarError(iline, sline, 
"Incomplete topology");
 
  967            RedundantIndexSetBuilder<Shape_>::compute(*_mesh_part->get_topology());
 
  969        else if(_topo_type == TopoType::parent)
 
  978        _root_node.add_mesh_part(_name, std::move(_mesh_part));
 
  981      virtual std::shared_ptr<Xml::MarkupParser> markup(
int iline, 
const String& sline, 
const String& name)
 override 
  984        if(name == 
"Mapping")
 
  987          return std::make_shared<MappingParser<Shape_>>(_mesh_part->get_target_set_holder(), _have_mapping);
 
  991        if(name == 
"Topology")
 
  993          if(_topo_type == TopoType::none)
 
  994            throw Xml::ContentError(iline, sline, 
"Unexpected Topology found");
 
  997          return std::make_shared<TopologyParser<Shape_>>(*_mesh_part->get_topology(), _have_topology);
 
 1001        if(name == 
"Attribute")
 
 1003          return std::make_shared<AttributeParser<MeshPartType>>(*_mesh_part);
 
 1010      virtual bool content(
int, 
const String&)
 override 
 1017      public Xml::MarkupParser
 
 1020      Adjacency::DynamicGraph& _patches;
 
 1026      explicit PatchParser(Adjacency::DynamicGraph& patches) :
 
 1034      virtual bool attribs(std::map<String,bool>& attrs)
 const override 
 1036        attrs.emplace(
"rank", 
true);
 
 1037        attrs.emplace(
"size", 
true);
 
 1041      virtual void create(
int iline, 
const String& sline, 
const String&, 
const std::map<String, String>& attrs, 
bool)
 override 
 1044        if(!attrs.find(
"rank")->second.parse(_rank))
 
 1045          throw Xml::ContentError(iline, sline, 
"Cannot parse patch rank index");
 
 1046        if(!attrs.find(
"size")->second.parse(_size))
 
 1047          throw Xml::ContentError(iline, sline, 
"Cannot parse patch size");
 
 1050        if(_rank >= _patches.get_num_nodes_domain())
 
 1051          throw Xml::ContentError(iline, sline, 
"Patch rank index is out of bounds");
 
 1054      virtual void close(
int iline, 
const String& sline)
 override 
 1057          throw Xml::GrammarError(iline, sline, 
"Invalid terminator; expected index");
 
 1060      virtual bool content(
int iline, 
const String& sline)
 override 
 1064          throw Xml::ContentError(iline, sline, 
"Invalid content; expected terminator");
 
 1068        if(!sline.parse(elem))
 
 1069          throw Xml::ContentError(iline, sline, 
"Failed to parse element index");
 
 1071        if(elem >= _patches.get_num_nodes_image())
 
 1072          throw Xml::ContentError(iline, sline, 
"Patch element index is out of bounds");
 
 1075        _patches.insert(_rank, elem);
 
 1083      virtual std::shared_ptr<MarkupParser> markup(
int, 
const String&, 
const String&)
 override 
 1089    class PartitionParser :
 
 1090      public Xml::MarkupParser
 
 1093      PartitionSet& _part_set;
 
 1097      int _num_ranks, _num_elems;
 
 1098      Adjacency::DynamicGraph _patches;
 
 1101      explicit PartitionParser(PartitionSet& part_set) :
 
 1102        _part_set(part_set),
 
 1112      virtual bool attribs(std::map<String,bool>& attrs)
 const override 
 1114        attrs.emplace(
"size", 
true);
 
 1115        attrs.emplace(
"name", 
false);
 
 1116        attrs.emplace(
"priority", 
false);
 
 1117        attrs.emplace(
"level", 
false);
 
 1121      virtual void create(
int iline, 
const String& sline, 
const String&, 
const std::map<String, String>& attrs, 
bool)
 override 
 1124        std::deque<String> ssize = attrs.find(
"size")->second.split_by_whitespaces();
 
 1125        if(ssize.size() != std::size_t(2))
 
 1126          throw Xml::ContentError(iline, sline, 
"Invalid partition size");
 
 1129        if(!ssize.front().parse(_num_ranks))
 
 1130          throw Xml::ContentError(iline, sline, 
"Failed to parse partition rank count");
 
 1131        if(!ssize.back().parse(_num_elems))
 
 1132          throw Xml::ContentError(iline, sline, 
"Failed to parse partition element count");
 
 1136          auto it = attrs.find(
"name");
 
 1137          if(it != attrs.end())
 
 1143          auto it = attrs.find(
"priority");
 
 1144          if(it != attrs.end())
 
 1146            if(!it->second.parse(_prio))
 
 1147              throw Xml::ContentError(iline, sline, 
"Cannot parse partition priority");
 
 1153          auto it = attrs.find(
"level");
 
 1154          if(it != attrs.end())
 
 1156            if(!it->second.parse(_level))
 
 1157              throw Xml::ContentError(iline, sline, 
"Cannot parse partition level");
 
 1159              throw Xml::ContentError(iline, sline, 
"Invalid negative partition level");
 
 1164        _patches = Adjacency::DynamicGraph(
Index(_num_ranks), 
Index(_num_elems));
 
 1167      virtual void close(
int, 
const String&)
 override 
 1170        _part_set.add_partition(Partition(_patches, _name, _prio, _level));
 
 1173      virtual bool content(
int, 
const String&)
 override 
 1178      virtual std::shared_ptr<MarkupParser> markup(
int, 
const String&, 
const String& name)
 override 
 1181          return std::make_shared<PatchParser>(_patches);
 
 1187    template<
typename RootMesh_>
 
 1188    class MeshNodeParser :
 
 1189      public Xml::MarkupParser
 
 1192      typedef RootMesh_ RootMeshType;
 
 1193      typedef RootMeshNode<RootMesh_> RootMeshNodeType;
 
 1194      typedef MeshAtlas<RootMesh_> MeshAtlasType;
 
 1198      RootMeshNodeType& _root_node;
 
 1200      MeshAtlasType& _mesh_atlas;
 
 1202      PartitionSet* _part_set;
 
 1204      MeshNodeLinker<RootMesh_>& _linker;
 
 1209      explicit MeshNodeParser(RootMeshNodeType& root_node, MeshAtlasType& mesh_atlas, PartitionSet* part_set,  MeshNodeLinker<RootMesh_>& linker) :
 
 1210        _root_node(root_node),
 
 1211        _mesh_atlas(mesh_atlas),
 
 1212        _part_set(part_set),
 
 1218      virtual bool attribs(std::map<String,bool>& attrs)
 const override 
 1220        attrs.emplace(
"version", 
true); 
 
 1221        attrs.emplace(
"mesh", 
false); 
 
 1225      virtual void create(
int iline, 
const String& sline, 
const String& name, 
const std::map<String, String>& attrs, 
bool)
 override 
 1228        if(name != 
"FeatMeshFile")
 
 1229          throw Xml::GrammarError(iline, sline, 
"Invalid root markup; expected '<FeatMeshFile ...>'");
 
 1233        if(!attrs.find(
"version")->second.parse(version))
 
 1234          throw Xml::ContentError(iline, sline, 
"Cannot parse file version");
 
 1236          throw Xml::ContentError(iline, sline, 
"Invalid file version; expected 1");
 
 1239        auto it = attrs.find(
"mesh");
 
 1240        if(it != attrs.end())
 
 1243          _mesh_decl = it->second;
 
 1247      virtual void close(
int, 
const String&)
 override 
 1251      virtual bool content(
int, 
const String&)
 override 
 1256      virtual std::shared_ptr<MarkupParser> markup(
int iline, 
const String& sline, 
const String& name)
 override 
 1262          return std::make_shared<Xml::DummyParser>();
 
 1267          return std::make_shared<ChartParser<RootMeshType>>(_mesh_atlas);
 
 1271          if(_root_node.get_mesh() != 
nullptr)
 
 1274            throw Xml::GrammarError(iline, sline, 
"Invalid second Mesh in file");
 
 1278          return std::make_shared<MeshParser<RootMeshType>>(_root_node);
 
 1280        if(name == 
"MeshPart")
 
 1283          return std::make_shared<MeshPartParser<RootMeshType>>(_root_node, _linker);
 
 1285        if(name == 
"Partition")
 
 1288          if(_part_set != 
nullptr)
 
 1289            return std::make_shared<PartitionParser>(*_part_set);
 
 1293            return std::make_shared<Xml::DummyParser>();
 
 1348      std::deque<std::shared_ptr<std::stringstream>> 
_streams;
 
 1392        _scanners.push_back(std::make_shared<Xml::Scanner>(is));
 
 1416        _scanners.push_back(std::make_shared<Xml::Scanner>(is));
 
 1435        if(filenames.empty())
 
 1439        if(!dirpath.empty())
 
 1443          if((dirpath.back() != 
'/') && (dirpath.back() != 
'\\'))
 
 1444            dirpath.push_back(
'\\');
 
 1446          if(dirpath.back() != 
'/')
 
 1447            dirpath.push_back(
'/');
 
 1452        for(std::size_t i(0); i < filenames.size(); ++i)
 
 1455          String filepath = dirpath + filenames.at(i);
 
 1458          auto stream = std::make_shared<std::stringstream>();
 
 1497        std::deque<String> filenames;
 
 1498        filenames.push_back(filename);
 
 1613          auto it_v = attr.find(
"version");
 
 1614          if(it_v == attr.end())
 
 1615            scanner.
throw_grammar(
"Mesh file is missing mandatory attribute 'version'");
 
 1617          if(!(it_v->second.parse(iversion)))
 
 1618            scanner.
throw_grammar(
"Failed to parse mesh file version attribute");
 
 1623          auto it_m = attr.find(
"mesh");
 
 1624          if(it_m != attr.end())
 
 1640              if(mts.size() != std::size_t(4))
 
 1641                scanner.
throw_grammar(
"Mesh file root markup has invalid 'mesh' attribute");
 
 1644              if(mts.at(0) == 
"conformal")
 
 1647                scanner.
throw_grammar(
"Invalid 'mesh' attribute mesh type");
 
 1650              if(mts.at(1) == 
"simplex")
 
 1652              else if(mts.at(1) == 
"hypercube")
 
 1655                scanner.
throw_grammar(
"Invalid 'mesh' attribute shape type");
 
 1658              if(!mts.at(2).parse(_shape_dim) || (_shape_dim <= 0))
 
 1659                scanner.
throw_content(
"Invalid 'mesh' attribute shape dimension");
 
 1662              if(!mts.at(3).parse(_world_dim) || (_world_dim <= 0))
 
 1663                scanner.
throw_content(
"Invalid 'mesh' attribute world dimension");
 
 1691      template<
typename RootMesh_>
 
 1706          (*it)->set_root_parser(std::make_shared<MeshNodeParser<RootMesh_>>(root_mesh_node, mesh_atlas, part_set, linker));
 
 1725      template<
typename RootMesh_>
 
 1735        parse(linker, root_mesh_node, mesh_atlas, part_set);
 
 1756      template<
typename RootMesh_>
 
 1757      std::unique_ptr<RootMeshNode<RootMesh_>> 
parse(
 
 1762        std::unique_ptr<RootMeshNode<RootMesh_>> root_mesh_node =
 
 1766        this->
parse(*root_mesh_node, mesh_atlas, part_set);
 
 1769        return root_mesh_node;
 
 1787    template<
typename RootMesh_, 
int world_dim>
 
 1790      static_assert(RootMesh_::world_dim == world_dim, 
"Nonmatching world_dim.");
 
 1810    template<
typename RootMesh_>
 
 1811    struct DimensionalChartHelper<RootMesh_,2>
 
 1813      static std::shared_ptr<Xml::MarkupParser> 
markup(
const String& name,
 
 1814        std::unique_ptr<Atlas::ChartBase<RootMesh_>>& chart)
 
 1816        if(name == 
"Circle")
 
 1817          return std::make_shared<Atlas::CircleChartParser<RootMesh_>>(chart);
 
 1818        if(name == 
"Bezier")
 
 1819          return std::make_shared<Atlas::BezierChartParser<RootMesh_>>(chart);
 
 1825    template<
typename RootMesh_>
 
 1826    struct DimensionalChartHelper<RootMesh_,3>
 
 1828      static std::shared_ptr<Xml::MarkupParser> 
markup(
const String& name,
 
 1829        std::unique_ptr<Atlas::ChartBase<RootMesh_>>& chart)
 
 1831        if(name == 
"Sphere")
 
 1832          return std::make_shared<Atlas::SphereChartParser<RootMesh_>>(chart);
 
 1833        if(name == 
"SurfaceMesh")
 
 1834          return std::make_shared<Atlas::SurfaceMeshChartParser<RootMesh_>>(chart);
 
 1835        if(name == 
"Extrude")
 
 1836          return std::make_shared<Atlas::ExtrudeChartParser<RootMesh_>>(chart);
 
 1844    extern template class MeshNodeLinker<ConformalMesh<Shape::Simplex<2>, 2, 
Real>>;
 
 1845    extern template class MeshNodeLinker<ConformalMesh<Shape::Simplex<3>, 3, 
Real>>;
 
 1846    extern template class MeshNodeLinker<ConformalMesh<Shape::Hypercube<2>, 2, 
Real>>;
 
 1847    extern template class MeshNodeLinker<ConformalMesh<Shape::Hypercube<3>, 3, 
Real>>;
 
 1849    extern template void MeshFileReader::parse<ConformalMesh<Shape::Simplex<2>, 2, 
Real>>(
 
 1850      MeshNodeLinker<ConformalMesh<Shape::Simplex<2>, 2, 
Real>>&,
 
 1851      RootMeshNode<ConformalMesh<Shape::Simplex<2>, 2, 
Real>>&,
 
 1852      MeshAtlas<ConformalMesh<Shape::Simplex<2>, 2, 
Real>>&,
 
 1854    extern template void MeshFileReader::parse<ConformalMesh<Shape::Simplex<3>, 3, 
Real>>(
 
 1855      MeshNodeLinker<ConformalMesh<Shape::Simplex<3>, 3, 
Real>>&,
 
 1856      RootMeshNode<ConformalMesh<Shape::Simplex<3>, 3, 
Real>>&,
 
 1857      MeshAtlas<ConformalMesh<Shape::Simplex<3>, 3, 
Real>>&,
 
 1859    extern template void MeshFileReader::parse<ConformalMesh<Shape::Hypercube<2>, 2, 
Real>>(
 
 1860      MeshNodeLinker<ConformalMesh<Shape::Hypercube<2>, 2, 
Real>>&,
 
 1861      RootMeshNode<ConformalMesh<Shape::Hypercube<2>, 2, 
Real>>&,
 
 1862      MeshAtlas<ConformalMesh<Shape::Hypercube<2>, 2, 
Real>>&,
 
 1864    extern template void MeshFileReader::parse<ConformalMesh<Shape::Hypercube<3>, 3, 
Real>>(
 
 1865      MeshNodeLinker<ConformalMesh<Shape::Hypercube<3>, 3, 
Real>>&,
 
 1866      RootMeshNode<ConformalMesh<Shape::Hypercube<3>, 3, 
Real>>&,
 
 1867      MeshAtlas<ConformalMesh<Shape::Hypercube<3>, 3, 
Real>>&,
 
#define XABORTM(msg)
Abortion macro definition with custom message.
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
static Comm world()
Returns a copy of the world communicator.
static void read_common(std::stringstream &stream, const String &filename, const Dist::Comm &comm, int root_rank=0)
Reads a common text file for all ranks.
Mesh Atlas class template.
MeshChartType * find_mesh_chart(const String &name)
Searches for a mesh chart.
void add_mesh_files(const Dist::Comm &comm, const std::deque< String > &filenames, String dirpath="")
Adds a list of mesh files to the list of streams to be parsed.
void add_mesh_file(const String &filename)
Adds a single mesh file to the list of streams to be parsed.
MeshFileReader(std::istream &is)
Input-Stream constructor.
const String & get_meshtype_string() const
Returns the mesh-type string from the root markup node.
ShapeType
shape type enumeration
@ simplex
simplex shape type
@ hypercube
hypercube shape type
int get_shape_dim() const
Returns the shape-dimension from the root markup node.
virtual ~MeshFileReader()
virtual destructor
MeshFileReader()
default constructor
void parse(MeshNodeLinker< RootMesh_ > &linker, RootMeshNode< RootMesh_ > &root_mesh_node, MeshAtlas< RootMesh_ > &mesh_atlas, PartitionSet *part_set=nullptr)
Parses the mesh file into a mesh node and a mesh atlas.
void parse(RootMeshNode< RootMesh_ > &root_mesh_node, MeshAtlas< RootMesh_ > &mesh_atlas, PartitionSet *part_set=nullptr)
Parses the mesh file into a mesh node and a mesh atlas.
ShapeType get_shape_type() const
Returns the shape-type from the root markup node.
void add_mesh_file(const Dist::Comm &comm, const String &filename)
Adds a single mesh file to the list of streams to be parsed.
MeshType
mesh type enumeration
@ unknown
unknown mesh type
@ conformal
conformal mesh type
String _mesh_type_string
The parsed mesh type.
std::deque< std::shared_ptr< std::stringstream > > _streams
Our internally managed streams.
MeshType get_mesh_type() const
Returns the mesh-type from the root markup node.
void add_mesh_files(const std::deque< String > &filenames, String dirpath="")
Adds a list of mesh files to the list of streams to be parsed.
void add_stream(std::istream &is)
Adds an input stream to the list of streams to be parsed.
int get_world_dim() const
Returns the world-dimension from the root markup node.
std::deque< std::shared_ptr< Xml::Scanner > > _scanners
Our Xml scanner objects.
std::unique_ptr< RootMeshNode< RootMesh_ > > parse(MeshAtlas< RootMesh_ > &mesh_atlas, PartitionSet *part_set=nullptr)
Parses the mesh file into a mesh node and a mesh atlas.
bool _have_root_markup
Did we read the root markup yet?
void read_root_markup()
Reads the root markup from the input stream and analyses it.
MeshNodeLinker Error class.
MeshNode liner class template.
void meshpart_deduct_topology(const String &meshpart)
Adds a task to deduct a meshpart topology from the root mesh.
MeshAtlas< RootMesh_ > & _atlas
our atlas
RootMeshNode< RootMesh_ > & _mesh_node
our mesh node
void meshpart_link_to_chart(const String &meshpart, const String &chart)
Adds a task to link a meshpart to a chart.
void execute()
Executes the linker.
MeshNodeLinker(RootMeshNode< RootMesh_ > &mesh_node, MeshAtlas< RootMesh_ > &atlas)
Constructor.
Class template for partial meshes.
void deduct_topology(const ParentIndexSetHolderType &parent_ish)
Fills the mesh topology from parent information.
Root mesh node class template.
static std::unique_ptr< RootMeshNode > make_unique(std::unique_ptr< MeshType > mesh, MeshAtlasType *atlas=nullptr)
Creates a new RootMeshNode on the heap and returns a unique pointer to it.
String class implementation.
std::deque< String > split_by_string(const String &delimiter) const
Splits the string by a delimiter substring.
String trim(const String &charset) const
Trims the string.
XML Markup Parser interface.
void read_root()
Tries to read the XML root markup.
void throw_content(const String &msg) const
Throws a ContentError for the current line.
void throw_grammar(const String &msg) const
Throws a GrammarError for the current line.
const std::map< String, String > & get_cur_attribs() const
const String & get_cur_name() const
@ parent
indicates that the level is a parent level
@ full
full Uzawa preconditioner
double Real
Real data type.
String stringify(const T_ &item)
Converts an item into a String.
std::uint64_t Index
Index data type.
World dimension dependent helper class for parsing charts.
static std::shared_ptr< Xml::MarkupParser > markup(const String &name, std::unique_ptr< Atlas::ChartBase< RootMesh_ > > &chart)
Creates a parser for a chart, its type identified by a name String.