KratosMultiphysics
KRATOS Multiphysics (Kratos) is a framework for building parallel, multi-disciplinary simulation software, aiming at modularity, extensibility, and high performance. Kratos is written in C++, and counts with an extensive Python interface.
cad_json_input.h
Go to the documentation of this file.
1 // | / |
2 // ' / __| _` | __| _ \ __|
3 // . \ | ( | | ( |\__ `
4 // _|\_\_| \__,_|\__|\___/ ____/
5 // Multi-Physics
6 //
7 // License: BSD License
8 // Kratos default license: kratos/license.txt
9 //
10 
11 #if !defined(KRATOS_CAD_JSON_INPUT_INCLUDED )
12 #define KRATOS_CAD_JSON_INPUT_INCLUDED
13 
14 
15 // System includes
16 
17 // External includes
18 
19 // Project includes
20 #include "includes/io.h"
22 #include "includes/model_part.h"
23 
24 // Geometries
26 
30 
33 #include "geometries/brep_curve.h"
34 
36 
37 namespace Kratos
38 {
39 
43 
45 template<class TNodeType = Node, class TEmbeddedNodeType = Point>
46 class CadJsonInput : public IO
47 {
48  public:
49 
53 
56 
57  typedef std::size_t SizeType;
58  typedef std::size_t IndexType;
59 
61  typedef typename GeometryType::Pointer GeometryPointerType;
62 
65 
67 
70 
71  typedef typename NurbsSurfaceType::Pointer NurbsSurfacePointerType;
72  typedef typename NurbsTrimmingCurveType::Pointer NurbsTrimmingCurvePointerType;
73 
79 
83 
87 
90  const std::string& rDataFileName,
91  SizeType EchoLevel = 0)
92  : mEchoLevel(EchoLevel)
93  {
94  mCadJsonParameters = ReadParamatersFile(rDataFileName, EchoLevel);
95  }
96 
99  Parameters CadJsonParameters,
100  SizeType EchoLevel = 0)
101  : mCadJsonParameters(CadJsonParameters)
102  , mEchoLevel(EchoLevel)
103  {
104  }
105 
107  ~CadJsonInput() = default;
108 
112 
114  void ReadModelPart(ModelPart& rModelPart) override
115  {
116  ReadGeometryModelPart(mCadJsonParameters, rModelPart, mEchoLevel);
117  }
118 
120 
121 private:
124 
126  static void ReadGeometryModelPart(
127  const Parameters rCadJsonParameters,
128  ModelPart& rModelPart,
129  SizeType EchoLevel = 0)
130  {
131  KRATOS_ERROR_IF_NOT(rCadJsonParameters.Has("breps"))
132  << "Missing \"breps\" section" << std::endl;
133 
134  ReadBreps(rCadJsonParameters["breps"], rModelPart, EchoLevel);
135  }
136 
140 
141  static void ReadBreps(
142  const Parameters rParameters,
143  ModelPart& rModelPart,
144  SizeType EchoLevel = 0)
145  {
146  for (IndexType brep_index = 0; brep_index < rParameters.size(); brep_index++)
147  {
148  KRATOS_INFO_IF("ReadBreps", (EchoLevel > 0))
149  << "Reading Brep \"" << GetIdOrName(rParameters[brep_index])
150  << "\" - faces." << std::endl;
151 
152  if (rParameters[brep_index].Has("faces"))
153  {
154  ReadBrepSurfaces(rParameters[brep_index]["faces"], rModelPart, EchoLevel);
155  }
156  }
157 
158  for (IndexType brep_index = 0; brep_index < rParameters.size(); brep_index++)
159  {
160  KRATOS_INFO_IF("ReadBreps", (EchoLevel > 0))
161  << "Reading Brep \"" << GetIdOrName(rParameters[brep_index])
162  << "\" - edges." << std::endl;
163 
164  if (rParameters[brep_index].Has("edges"))
165  {
166  ReadBrepCurveOnSurfaces(rParameters[brep_index]["edges"], rModelPart, EchoLevel);
167  }
168  }
169 
170  for (IndexType brep_index = 0; brep_index < rParameters.size(); brep_index++)
171  {
172  KRATOS_INFO_IF("ReadBreps", (EchoLevel > 0))
173  << "Reading Brep \"" << GetIdOrName(rParameters[brep_index])
174  << "\" - points." << std::endl;
175 
176  if (rParameters[brep_index].Has("vertices"))
177  {
178  ReadPointsOnGeometries(rParameters[brep_index]["vertices"], rModelPart, EchoLevel);
179  }
180  }
181  }
182 
186 
187  static void ReadBrepSurfaces(
188  const Parameters rParameters,
189  ModelPart& rModelPart,
190  SizeType EchoLevel = 0)
191  {
192  KRATOS_ERROR_IF_NOT(rParameters.IsArray())
193  << "\"faces\" section needs to be an array of BrepSurfaces." << std::endl;
194 
195  KRATOS_INFO_IF("ReadBrepSurfaces", EchoLevel > 2)
196  << "Reading " << rParameters.size() << " BrepSurfaces..." << std::endl;
197 
198  for (IndexType brep_surface_i = 0; brep_surface_i < rParameters.size(); ++brep_surface_i)
199  {
200  ReadBrepSurface(rParameters[brep_surface_i], rModelPart, EchoLevel);
201  }
202  }
203 
204  static void ReadBrepSurface(
205  const Parameters rParameters,
206  ModelPart& rModelPart,
207  SizeType EchoLevel = 0)
208  {
209  KRATOS_INFO_IF("ReadBrepSurface", (EchoLevel > 3))
210  << "Reading BrepSurface \"" << GetIdOrName(rParameters) << "\"" << std::endl;
211 
212  KRATOS_ERROR_IF_NOT(HasIdOrName(rParameters))
213  << "Missing 'brep_id' or 'brep_name' in brep face." << std::endl;
214 
215  KRATOS_ERROR_IF_NOT(rParameters.Has("surface"))
216  << "Missing 'surface' in brep face." << std::endl;
217 
218  auto p_surface(ReadNurbsSurface<3, TNodeType>(
219  rParameters["surface"], rModelPart, EchoLevel));
220 
221  const bool is_trimmed = (rParameters["surface"].Has("is_trimmed"))
222  ? rParameters["surface"]["is_trimmed"].GetBool()
223  : true;
224  KRATOS_INFO_IF("ReadBrepSurface", (EchoLevel > 4) && !rParameters["surface"].Has("is_trimmed"))
225  << "For BrepSurface \"" << GetIdOrName(rParameters) << "\""
226  << "\", is_trimmed is not provided in the input."
227  << " is_trimmed = true is considered." << std::endl;
228 
229  if (rParameters.Has("boundary_loops"))
230  {
231  BrepCurveOnSurfaceLoopArrayType outer_loops, inner_loops;
232  tie(outer_loops, inner_loops) =
233  ReadBoundaryLoops(rParameters["boundary_loops"], p_surface, rModelPart, EchoLevel);
234 
235  auto p_brep_surface =
236  Kratos::make_shared<BrepSurfaceType>(
237  p_surface,
238  outer_loops,
239  inner_loops,
240  is_trimmed);
241 
243  p_surface->SetGeometryParent(p_brep_surface.get());
244 
245  SetIdOrName<BrepSurfaceType>(rParameters, p_brep_surface);
246 
247  ReadAndAddEmbeddedEdges(p_brep_surface, rParameters, p_surface, rModelPart, EchoLevel);
248 
249  rModelPart.AddGeometry(p_brep_surface);
250  }
251  else
252  {
253  KRATOS_INFO_IF("ReadBrepSurface", (EchoLevel > 4))
254  << "For BrepSurface \"" << GetIdOrName(rParameters) << "\""
255  << "\", boundary_loops are not provided in the input."
256  << " It will be considered as untrimmed." << std::endl;
257 
258  auto p_brep_surface =
259  Kratos::make_shared<BrepSurfaceType>(
260  p_surface);
261 
262  SetIdOrName<BrepSurfaceType>(rParameters, p_brep_surface);
263 
264  ReadAndAddEmbeddedEdges(p_brep_surface, rParameters, p_surface, rModelPart, EchoLevel);
265 
266  rModelPart.AddGeometry(p_brep_surface);
267  }
268  }
269 
273 
275  ReadTrimmingCurveVector(
276  const Parameters rParameters,
277  typename NurbsSurfaceType::Pointer pNurbsSurface,
278  ModelPart& rModelPart,
279  SizeType EchoLevel = 0)
280  {
281  KRATOS_ERROR_IF(rParameters.size() < 1)
282  << "Trimming curve list has no element." << std::endl;
283 
285  trimming_brep_curve_vector(rParameters.size());
286 
287  for (IndexType tc_idx = 0; tc_idx < rParameters.size(); tc_idx++)
288  {
289  trimming_brep_curve_vector[tc_idx] = ReadTrimmingCurve(
290  rParameters[tc_idx], pNurbsSurface, rModelPart, EchoLevel);
291  }
292 
293  return trimming_brep_curve_vector;
294  }
295 
296  static typename BrepCurveOnSurfaceType::Pointer
297  ReadTrimmingCurve(
298  const Parameters rParameters,
299  typename NurbsSurfaceType::Pointer pNurbsSurface,
300  ModelPart& rModelPart,
301  SizeType EchoLevel = 0)
302  {
303  KRATOS_ERROR_IF_NOT(rParameters.Has("curve_direction"))
304  << "Missing 'curve_direction' in nurbs curve" << std::endl;
305  bool curve_direction = rParameters["curve_direction"].GetBool();
306 
307  KRATOS_ERROR_IF_NOT(rParameters.Has("parameter_curve"))
308  << "Missing 'parameter_curve' in nurbs curve" << std::endl;
309 
310  auto p_trimming_curve(ReadNurbsCurve<2, TEmbeddedNodeType>(
311  rParameters["parameter_curve"], rModelPart, EchoLevel));
312 
313  KRATOS_ERROR_IF_NOT(rParameters["parameter_curve"].Has("active_range"))
314  << "Missing 'active_range' in parameter_curve, in trimming curve." << std::endl;
315  Vector active_range_vector = rParameters["parameter_curve"]["active_range"].GetVector();
316  NurbsInterval brep_active_range(active_range_vector[0], active_range_vector[1]);
317 
318  auto p_brep_curve_on_surface
319  = Kratos::make_shared<BrepCurveOnSurfaceType>(
320  pNurbsSurface, p_trimming_curve, brep_active_range, curve_direction);
321 
322  if (rParameters.Has("trim_index")) {
323  p_brep_curve_on_surface->SetId(rParameters["trim_index"].GetInt());
324  }
325 
326  return p_brep_curve_on_surface;
327  }
328 
329  static std::tuple<BrepCurveOnSurfaceLoopArrayType, BrepCurveOnSurfaceLoopArrayType>
330  ReadBoundaryLoops(
331  const Parameters rParameters,
332  typename NurbsSurfaceType::Pointer pNurbsSurface,
333  ModelPart& rModelPart,
334  SizeType EchoLevel = 0)
335  {
338 
339  for (IndexType bl_idx = 0; bl_idx < rParameters.size(); bl_idx++)
340  {
341  KRATOS_ERROR_IF_NOT(rParameters[bl_idx].Has("loop_type"))
342  << "Missing 'loop_type' in boundary loops, in "
343  << bl_idx << " loop." << std::endl;
344  std::string loop_type = rParameters[bl_idx]["loop_type"].GetString();
345 
346  KRATOS_ERROR_IF_NOT(rParameters[bl_idx].Has("trimming_curves"))
347  << "Missing 'trimming_curves' in boundary loops"
348  << bl_idx << " loop." << std::endl;
349  auto trimming_curves(ReadTrimmingCurveVector(
350  rParameters[bl_idx]["trimming_curves"], pNurbsSurface, rModelPart, EchoLevel));
351 
352  if (loop_type == "outer")
353  {
354  outer_loops.resize(outer_loops.size() + 1);
355  outer_loops[outer_loops.size() - 1] = trimming_curves;
356  }
357  else if (loop_type == "inner")
358  {
359  inner_loops.resize(inner_loops.size() + 1);
360  inner_loops[inner_loops.size() - 1] = trimming_curves;
361  }
362  else
363  {
364  KRATOS_ERROR << "Loop type: " << loop_type
365  << " is not supported." << std::endl;
366  }
367  }
368 
369  return std::make_tuple(outer_loops, inner_loops);
370  }
371 
372  static void ReadAndAddEmbeddedEdges(
373  typename BrepSurfaceType::Pointer pBrepSurface,
374  const Parameters rParameters,
375  typename NurbsSurfaceType::Pointer pNurbsSurface,
376  ModelPart& rModelPart,
377  SizeType EchoLevel = 0)
378  {
379  if (rParameters.Has("embedded_edges")) {
380  if (rParameters["embedded_edges"].size() > 0) {
381  BrepCurveOnSurfaceArrayType embedded_edges(ReadTrimmingCurveVector(
382  rParameters["embedded_edges"], pNurbsSurface, rModelPart, EchoLevel));
383 
384  pBrepSurface->AddEmbeddedEdges(embedded_edges);
385  }
386  }
387  }
388 
392 
393  static void ReadBrepCurveOnSurfaces(
394  const Parameters rParameters,
395  ModelPart& rModelPart,
396  SizeType EchoLevel = 0)
397  {
398  KRATOS_ERROR_IF_NOT(rParameters.IsArray())
399  << "\"faces\" section needs to be an array of BrepSurfaces." << std::endl;
400 
401  KRATOS_INFO_IF("ReadBrepCurveOnSurfaces", EchoLevel > 2)
402  << "Reading " << rParameters.size() << " BrepEdge..." << std::endl;
403 
404  for (IndexType i = 0; i < rParameters.size(); i++)
405  {
406  ReadBrepEdge(rParameters[i], rModelPart, EchoLevel);
407  }
408  }
409 
410  static void ReadBrepEdge(
411  const Parameters rParameters,
412  ModelPart& rModelPart,
413  SizeType EchoLevel = 0)
414  {
415  KRATOS_ERROR_IF_NOT(HasIdOrName(rParameters))
416  << "Missing 'brep_id' or 'brep_name' in brep edge" << std::endl;
417 
418  if (rParameters.Has("topology"))
419  {
420  if (rParameters["topology"].size() == 0)
421  {
422  ReadBrepCurve(rParameters, rModelPart, EchoLevel);
423  }
424  else if (rParameters["topology"].size() == 1)
425  {
426  ReadBrepEdgeBrepCurveOnSurface(rParameters, rModelPart, EchoLevel);
427  }
428  else { // More than one topology means that a coupling geometry is required.
429  ReadCouplingGeometry(rParameters, rModelPart, EchoLevel);
430  }
431  }
432  }
433 
434  static void ReadBrepCurve(
435  const Parameters rParameters,
436  ModelPart& rModelPart,
437  SizeType EchoLevel = 0)
438  {
439  KRATOS_ERROR_IF_NOT(HasIdOrName(rParameters))
440  << "Missing 'brep_id' or 'brep_name' in brep curve." << std::endl;
441 
442  KRATOS_INFO_IF("ReadBrepCurve", (EchoLevel > 3))
443  << "Reading BrepCurve \"" << GetIdOrName(rParameters) << "\"" << std::endl;
444 
445  KRATOS_ERROR_IF_NOT(rParameters.Has("3d_curve"))
446  << "Missing '3d_curve' in brep curve." << std::endl;
447 
448  auto p_curve = ReadNurbsCurve<3, TNodeType>(
449  rParameters["3d_curve"], rModelPart, EchoLevel);
450 
451  auto p_brep_curve = Kratos::make_shared<BrepCurveType>(p_curve);
452 
453  SetIdOrName<BrepCurveType>(rParameters, p_brep_curve);
454 
455  rModelPart.AddGeometry(p_brep_curve);
456  }
457 
458 
459  static void ReadBrepEdgeBrepCurveOnSurface(
460  const Parameters & rParameters,
461  ModelPart & rModelPart,
462  SizeType EchoLevel = 0)
463  {
464  KRATOS_INFO_IF("ReadBrepEdge", (EchoLevel > 3))
465  << "Reading BrepEdge \"" << GetIdOrName(rParameters) << "\"" << std::endl;
466 
467  KRATOS_ERROR_IF_NOT(HasIdOrName(rParameters["topology"][0]))
468  << "Missing 'brep_id' or 'brep_name' in topology" << std::endl;
469 
470  KRATOS_INFO_IF("ReadBrepEdge", (EchoLevel > 4))
471  << "Getting trim: \"" << rParameters["topology"][0]["trim_index"].GetInt()
472  << "\" from geometry: \"" << GetIdOrName(rParameters["topology"][0])
473  << "\"." << std::endl;
474 
475  GeometryPointerType p_geometry = GetGeometry(rParameters["topology"][0], rModelPart);
476  GeometryPointerType p_brep_trim =
477  p_geometry->pGetGeometryPart(rParameters["topology"][0]["trim_index"].GetInt());
478 
479  auto p_brep_curve_on_surface
480  = dynamic_pointer_cast<BrepCurveOnSurfaceType>(p_brep_trim);
481  KRATOS_ERROR_IF(p_brep_curve_on_surface == nullptr)
482  << "dynamic_cast from Geometry to BrepCurveOnSurface not successfull. Brep Id: "
483  << GetIdOrName(rParameters["topology"][0]) << " and trim index: "
484  << rParameters["topology"][0]["trim_index"].GetInt() << std::endl;
485 
486  bool relative_direction = true;
487  if (rParameters["topology"][0].Has("relative_direction")) {
488  relative_direction = rParameters["topology"][0]["relative_direction"].GetBool();
489  }
490  else {
491  KRATOS_INFO_IF("ReadBrepEdge", (EchoLevel > 4))
492  << "For trim: \"" << rParameters["topology"][0]["trim_index"].GetInt()
493  << "\" from geometry: \"" << GetIdOrName(rParameters["topology"][0])
494  << "\", no relative_direction is provided in the input." << std::endl;
495  }
496 
497  auto p_nurbs_curve_on_surface = p_brep_curve_on_surface->pGetCurveOnSurface();
498 
499  auto brep_nurbs_interval = p_brep_curve_on_surface->DomainInterval();
500  auto p_bre_edge_brep_curve_on_surface = Kratos::make_shared<BrepCurveOnSurfaceType>(
501  p_nurbs_curve_on_surface, brep_nurbs_interval, relative_direction);
502 
503  SetIdOrName<BrepCurveOnSurfaceType>(rParameters, p_bre_edge_brep_curve_on_surface);
504 
505  rModelPart.AddGeometry(p_bre_edge_brep_curve_on_surface);
506  }
507 
508  static void ReadCouplingGeometry(
509  const Parameters rParameters,
510  ModelPart& rModelPart,
511  SizeType EchoLevel = 0)
512  {
513  KRATOS_INFO_IF("ReadCouplingGeometry", (EchoLevel > 3))
514  << "Reading CouplingGeometry \"" << GetIdOrName(rParameters) << "\"" << std::endl;
515 
516  typename CouplingGeometryType::GeometryPointerVector geometry_vector;
517 
518  for (IndexType i = 0; i < rParameters["topology"].size(); i++)
519  {
520  KRATOS_ERROR_IF_NOT(HasIdOrName(rParameters["topology"][0]))
521  << "Missing 'brep_id' or 'brep_name' in topology of Coupling - BrepEdge" << std::endl;
522 
523  auto p_geometry = GetGeometry(rParameters["topology"][i], rModelPart);
524 
525  geometry_vector.push_back(
526  p_geometry->pGetGeometryPart(rParameters["topology"][i]["trim_index"].GetInt()));
527  }
528 
529  auto p_coupling_geometry = Kratos::make_shared<CouplingGeometryType>(
530  geometry_vector);
531 
532  SetIdOrName<CouplingGeometryType>(rParameters, p_coupling_geometry);
533 
534  rModelPart.AddGeometry(p_coupling_geometry);
535  }
536 
537  static void ReadPointsOnGeometries(
538  const Parameters rParameters,
539  ModelPart& rModelPart,
540  SizeType EchoLevel = 0)
541  {
542  KRATOS_ERROR_IF_NOT(rParameters.IsArray())
543  << "\"vertices\" section needs to be an array of PointsOnGeometries." << std::endl;
544 
545  KRATOS_INFO_IF("ReadPointsOnGeometries", EchoLevel > 2)
546  << "Reading " << rParameters.size() << " PointsOnGeometries..." << std::endl;
547 
548  for (IndexType brep_point_i = 0; brep_point_i < rParameters.size(); ++brep_point_i)
549  {
550  KRATOS_INFO_IF("ReadPointsOnGeometries", (EchoLevel > 3))
551  << "Reading PointOnGeometry \"" << GetIdOrName(rParameters[brep_point_i]) << "\"" << std::endl;
552 
553  if (rParameters[brep_point_i]["topology"].size() == 1) {
554  if (rParameters[brep_point_i]["topology"][0].Has("local_coordinates"))
555  {
556  auto p_geometry = GetGeometry(rParameters[brep_point_i]["topology"][0], rModelPart);
557 
558  GeometryPointerType p_point_on_geometry = ReadPointOnGeometry(rParameters[brep_point_i]["topology"][0], rModelPart, p_geometry, EchoLevel);
559 
560  SetIdOrName(rParameters[brep_point_i], p_point_on_geometry);
561  rModelPart.AddGeometry(p_point_on_geometry);
562  }
563  else {
564  KRATOS_ERROR << "Topology of brep point: " << GetIdOrName(rParameters[brep_point_i])
565  << " does not provide local coordinates. No other import option provided. Topology as following: "
566  << rParameters[brep_point_i] << std::endl;
567  }
568  }
569  else if (rParameters[brep_point_i]["topology"].size() > 1) {
570  std::vector<GeometryPointerType> coupling_point_geometries(rParameters[brep_point_i]["topology"].size());
571 
572  for (IndexType i = 0; i < rParameters[brep_point_i]["topology"].size(); ++i) {
573  auto p_geometry = GetGeometry(rParameters[brep_point_i]["topology"][i], rModelPart);
574 
575  coupling_point_geometries[i] = ReadPointOnGeometry(rParameters[brep_point_i]["topology"][i], rModelPart, p_geometry, EchoLevel);
576  }
577 
578  auto p_coupling_geometry = Kratos::make_shared<CouplingGeometryType>(
579  coupling_point_geometries);
580 
581  SetIdOrName<CouplingGeometryType>(rParameters[brep_point_i], p_coupling_geometry);
582  rModelPart.AddGeometry(p_coupling_geometry);
583  }
584  else {
585  KRATOS_ERROR << "PointOnGeometry did not provide any topology, which is not allowed.\n Parameters are read as following: \n"
586  << rParameters[brep_point_i] << std::endl;
587  }
588  }
589  }
590 
591  static GeometryPointerType ReadPointOnGeometry(
592  const Parameters rParameters,
593  ModelPart& rModelPart,
594  GeometryPointerType pBackgroundGeometry,
595  SizeType EchoLevel = 0)
596  {
597  auto coordinates_vector = rParameters["local_coordinates"].GetVector();
598  array_1d<double, 3> local_coordinates;
599  local_coordinates[0] = coordinates_vector[0];
600  local_coordinates[1] = coordinates_vector[1];
601  local_coordinates[2] = coordinates_vector[2];
602 
603  if (pBackgroundGeometry->LocalSpaceDimension() == 2)
604  return Kratos::make_shared<PointOnGeometryOnSurfaceType>(local_coordinates, pBackgroundGeometry);
605  else if (pBackgroundGeometry->LocalSpaceDimension() == 1)
606  return Kratos::make_shared<PointOnGeometryOnCurveType>(local_coordinates, pBackgroundGeometry);
607  else {
608  KRATOS_ERROR << "Local space dimension of: " << pBackgroundGeometry->LocalSpaceDimension()
609  << " is not supported for point on geometry." << std::endl;
610  }
611  }
612 
616 
617  /* @brief read NurbsCurves from the given parameter input.
618  *
619  * The input needs to be provided in the following shape:
620  * {
621  * "is_rational": bool,
622  * "degree": p:int,
623  * "knot_vector": [ double, ... ],
624  * "active_range": [ double, double ],
625  * "control_points": [
626  * [ id: int, [ x, y, z, weight ] ],
627  * ...
628  * ]
629  * }
630  */
631  template<int TWorkingSpaceDimension, class TThisNodeType>
632  static typename NurbsCurveGeometry<TWorkingSpaceDimension, PointerVector<TThisNodeType>>::Pointer
633  ReadNurbsCurve(
634  const Parameters rParameters,
635  ModelPart& rModelPart,
636  SizeType EchoLevel = 0)
637  {
638  bool is_rational = true;
639  if (rParameters.Has("is_rational")) {
640  is_rational = rParameters["is_rational"].GetBool();
641  }
642  else {
643  KRATOS_INFO_IF("ReadNurbsCurve", (EchoLevel > 4))
644  << "\"is_rational\" is not provided within \"surface\". Thus, it is considered as rational. "
645  << "If this curve is non-rational the computation of the shape functions is less optimized."
646  << std::endl;
647  }
648 
649  KRATOS_ERROR_IF_NOT(rParameters.Has("knot_vector"))
650  << "Missing 'knot_vector' in nurbs curve" << std::endl;
651  Vector knot_vector = rParameters["knot_vector"].GetVector();
652 
653  KRATOS_ERROR_IF_NOT(rParameters.Has("degree"))
654  << "Missing 'degree' in nurbs curve" << std::endl;
655  int polynomial_degree = rParameters["degree"].GetInt();
656 
657  PointerVector<TThisNodeType> control_points;
658 
659  ReadControlPointVector(control_points,
660  rParameters["control_points"], rModelPart, EchoLevel);
661 
662  if (is_rational)
663  {
664  Vector control_point_weights = ReadControlPointWeightVector(
665  rParameters["control_points"]);
666 
667  return Kratos::make_shared<NurbsCurveGeometry<TWorkingSpaceDimension, PointerVector<TThisNodeType>>>(
668  NurbsCurveGeometry<TWorkingSpaceDimension, PointerVector<TThisNodeType>>(
669  control_points,
670  polynomial_degree,
671  knot_vector,
672  control_point_weights));
673  }
674  typename NurbsCurveGeometry<TWorkingSpaceDimension, PointerVector<TThisNodeType>>::Pointer p_nurbs_curve(
675  new NurbsCurveGeometry<TWorkingSpaceDimension, PointerVector<TThisNodeType>>(
676  control_points,
677  polynomial_degree,
678  knot_vector));
679 
680  return p_nurbs_curve;
681  }
682 
683  /* @brief read NurbsSurfaces from the given parameter input.
684  *
685  * The input needs to be provided in the following shape:
686  * {
687  * "is_trimmed": bool,
688  * "is_rational" : bool,
689  * "degrees" : [int, int] ,
690  * "knot_vectors" : [
691  * [ double, ... ],
692  * [double, ...]
693  * ],
694  * "control_points" : [
695  * [ id:p, [0, 10, 0, 1] ],
696  * ...
697  * ]
698  * }
699  */
700  template<int TWorkingSpaceDimension, class TThisNodeType>
701  static typename NurbsSurfaceGeometry<TWorkingSpaceDimension, PointerVector<TThisNodeType>>::Pointer
702  ReadNurbsSurface(
703  const Parameters rParameters,
704  ModelPart& rModelPart,
705  SizeType EchoLevel = 0)
706  {
707  bool is_rational = true;
708  if (rParameters.Has("is_rational")) {
709  is_rational = rParameters["is_rational"].GetBool();
710  }
711  else {
712  KRATOS_INFO_IF("ReadNurbsSurface", (EchoLevel > 4))
713  << "\"is_rational\" is not provided within \"surface\". Thus, it is considered as rational. "
714  << "If this surface is non-rational the computation of the shape functions is less optimized."
715  << std::endl;
716  }
717 
718  KRATOS_ERROR_IF_NOT(rParameters.Has("knot_vectors"))
719  << "Missing 'knot_vector' in nurbs surface" << std::endl;
720  KRATOS_ERROR_IF(rParameters["knot_vectors"].size() != 2)
721  << "'knot_vectors' need to be of size two, knot_vector_u and knot_vector_v" << std::endl;
722  Vector knot_vector_u = rParameters["knot_vectors"][0].GetVector();
723  Vector knot_vector_v = rParameters["knot_vectors"][1].GetVector();
724 
725  KRATOS_ERROR_IF_NOT(rParameters.Has("degrees"))
726  << "Missing 'degrees' in nurbs surface" << std::endl;
727  KRATOS_ERROR_IF(rParameters["degrees"].size() != 2)
728  << "'degrees' need to be of size two, p and q" << std::endl;
729  int p = rParameters["degrees"][0].GetInt();
730  int q = rParameters["degrees"][1].GetInt();
731 
732  PointerVector<TThisNodeType> control_points;
733 
734  ReadControlPointVector(control_points,
735  rParameters["control_points"], rModelPart, EchoLevel);
736 
737  if (is_rational)
738  {
739  Vector control_point_weights = ReadControlPointWeightVector(
740  rParameters["control_points"]);
741 
742  return Kratos::make_shared<NurbsSurfaceGeometry<TWorkingSpaceDimension, PointerVector<TThisNodeType>>>(
743  control_points,
744  p,
745  q,
746  knot_vector_u,
747  knot_vector_v,
748  control_point_weights);
749  }
750  typename NurbsSurfaceGeometry<TWorkingSpaceDimension, PointerVector<TThisNodeType>>::Pointer p_nurbs_surface(
751  new NurbsSurfaceGeometry<TWorkingSpaceDimension, PointerVector<TThisNodeType>>(
752  control_points,
753  p,
754  q,
755  knot_vector_u,
756  knot_vector_v));
757 
758  return p_nurbs_surface;
759  }
760 
764 
766  static Vector ReadControlPointWeightVector(
767  const Parameters rParameters,
768  SizeType EchoLevel = 0)
769  {
770  Vector control_point_weights = ZeroVector(rParameters.size());
771  KRATOS_ERROR_IF(rParameters.size() == 0)
772  << "Length of control point list is zero!" << std::endl;
773 
774  SizeType number_of_entries = rParameters[0].size();
775  KRATOS_ERROR_IF(rParameters[0][number_of_entries - 1].size() != 4)
776  << "Control points need to be provided in following structure: [[x, y, z, weight]] or [id, [x, y, z, weight]]"
777  << "Size of inner vector incorrect!"
778  << std::endl;
779 
780  for (IndexType cp_idx = 0; cp_idx < rParameters.size(); cp_idx++)
781  {
782  control_point_weights[cp_idx] = rParameters[cp_idx][number_of_entries - 1][3].GetDouble();
783  }
784 
785  return control_point_weights;
786  }
787 
789  static void ReadControlPointVector(
790  PointerVector<Node>& rControlPoints,
791  const Parameters rParameters,
792  ModelPart& rModelPart,
793  SizeType EchoLevel = 0)
794  {
795  KRATOS_ERROR_IF_NOT(rParameters.IsArray())
796  << "\"control_points\" section needs to be an array." << std::endl;
797 
798  KRATOS_INFO_IF("ReadControlPointVector", EchoLevel > 4)
799  << "Reading " << rParameters.size() << " control points of type Node." << std::endl;
800 
801  for (IndexType cp_idx = 0; cp_idx < rParameters.size(); cp_idx++)
802  {
803  rControlPoints.push_back(ReadAndCreateNode(rParameters[cp_idx], rModelPart));
804  }
805  }
806 
808  static void ReadControlPointVector(
809  PointerVector<Point>& rControlPoints,
810  const Parameters rParameters,
811  ModelPart& rModelPart,
812  SizeType EchoLevel = 0)
813  {
814  KRATOS_ERROR_IF_NOT(rParameters.IsArray())
815  << "\"control_points\" section needs to be an array." << std::endl;
816 
817  KRATOS_INFO_IF("ReadControlPointVector", EchoLevel > 4)
818  << "Reading " << rParameters.size() << " control points of type Point." << std::endl;
819 
820  for (IndexType cp_idx = 0; cp_idx < rParameters.size(); cp_idx++)
821  {
822  rControlPoints.push_back(ReadPoint(rParameters[cp_idx]));
823  }
824  }
825 
829 
830  /* Reads, and returns a Pointer to Node.
831  * Input needs to be a Parameter object:
832  * [id, [x, y, z, weight]]
833  */
834  static Node::Pointer ReadAndCreateNode(
835  const Parameters rParameters,
836  ModelPart& rModelPart,
837  SizeType EchoLevel = 0)
838  {
839  SizeType number_of_entries = rParameters.size();
840  KRATOS_ERROR_IF((number_of_entries != 2))
841  << "Control points as Node need to be provided in following structure: [id, [x, y, z, weight]]"
842  << std::endl;
843 
844  IndexType id = rParameters[0].GetInt();
845  Vector cp = rParameters[1].GetVector();
846 
847  return rModelPart.CreateNewNode(id, cp[0], cp[1], cp[2]);
848  }
849 
850  /* Reads, and returns a Pointer to Point.
851  * Input needs to be a Parameter object:
852  * [[x, y, z, weight]] or [id, [x, y, z, weight]]
853  */
854  static Point::Pointer ReadPoint(
855  const Parameters rParameters,
856  SizeType EchoLevel = 0)
857  {
858  SizeType number_of_entries = rParameters.size();
859  KRATOS_ERROR_IF((number_of_entries != 1) && (number_of_entries != 2))
860  << "Control points as Point need to be provided in following structure: "
861  << "[[x, y, z, weight]] or [id, [x, y, z, weight]]" << std::endl;
862 
863  Vector cp = rParameters[number_of_entries - 1].GetVector();
864 
865  return Kratos::make_shared<Point>(cp[0], cp[1], cp[2]);
866  }
867 
871 
873  template<class TGeometry>
874  static void SetIdOrName(
875  const Parameters rParameters,
876  typename TGeometry::Pointer pGeometry)
877  {
878  if (rParameters.Has("brep_id")) {
879  pGeometry->SetId(rParameters["brep_id"].GetInt());
880  }
881  else if (rParameters.Has("brep_name")) {
882  pGeometry->SetId(rParameters["brep_name"].GetString());
883  }
884  }
885 
887  static void SetIdOrName(
888  const Parameters rParameters,
889  GeometryPointerType pGeometry)
890  {
891  if (rParameters.Has("brep_id")) {
892  pGeometry->SetId(rParameters["brep_id"].GetInt());
893  }
894  else if (rParameters.Has("brep_name")) {
895  pGeometry->SetId(rParameters["brep_name"].GetString());
896  }
897  }
898 
900  static std::string GetIdOrName(
901  const Parameters rParameters)
902  {
903  if (rParameters.Has("brep_id")) {
904  return std::to_string(rParameters["brep_id"].GetInt());
905  }
906  else if (rParameters.Has("brep_name")) {
907  return rParameters["brep_name"].GetString();
908  }
909  else {
910  return "no_id_assigned";
911  }
912  }
913 
915  static bool HasIdOrName(
916  const Parameters rParameters)
917  {
918  return (rParameters.Has("brep_id") || rParameters.Has("brep_name"));
919  }
920 
922  static typename GeometryType::Pointer GetGeometry(
923  const Parameters rParameters,
924  ModelPart& rModelPart)
925  {
926  if (rParameters.Has("brep_id")) {
927  return rModelPart.pGetGeometry(rParameters["brep_id"].GetInt());
928  }
929  else { // if (rParameters["topology"][i].Has("brep_name"))
930  return rModelPart.pGetGeometry(rParameters["brep_name"].GetString());
931  }
932  }
933 
935  static Parameters ReadParamatersFile(
936  const std::string& rDataFileName,
937  SizeType EchoLevel = 0)
938  {
939  // Check if rDataFileName ends with ".cad.json" and add it if needed.
940  const std::string data_file_name = (rDataFileName.compare(rDataFileName.size() - 9, 9, ".cad.json") != 0)
941  ? rDataFileName + ".cad.json"
942  : rDataFileName;
943 
944  std::ifstream infile(data_file_name);
945  KRATOS_ERROR_IF_NOT(infile.good()) << "CAD geometry file: "
946  << data_file_name << " cannot be found." << std::endl;
947  KRATOS_INFO_IF("ReadParamatersFile", EchoLevel > 3)
948  << "Reading file: \"" << data_file_name << "\"" << std::endl;
949 
950  std::stringstream buffer;
951  buffer << infile.rdbuf();
952 
953  return Parameters(buffer.str());
954  }
955 
959 
960  Parameters mCadJsonParameters;
961  int mEchoLevel;
962 
964 }; // Class CadJsonInput
965 } // namespace Kratos.
966 
967 #endif // KRATOS_CAD_JSON_INPUT_INCLUDED defined
The BrepCurve acts as topology for curves. Those can be enclosed by a certain set of points.
Definition: brep_curve.h:37
The BrepCurveOnSurface acts as topology for curves on surfaces.
Definition: brep_curve_on_surface.h:44
The BrepSurface acts as topology for faces. Those can be enclosed by a certain set of brep face curve...
Definition: brep_surface.h:45
Definition: cad_json_input.h:47
BrepCurve< ContainerNodeType, ContainerEmbeddedNodeType > BrepCurveType
Definition: cad_json_input.h:76
Geometry< TNodeType > GeometryType
Definition: cad_json_input.h:60
CadJsonInput(const std::string &rDataFileName, SizeType EchoLevel=0)
Constructor with path to input file.
Definition: cad_json_input.h:89
~CadJsonInput()=default
Destructor.
NurbsTrimmingCurveType::Pointer NurbsTrimmingCurvePointerType
Definition: cad_json_input.h:72
PointOnGeometry< ContainerNodeType, 3, 1 > PointOnGeometryOnCurveType
Definition: cad_json_input.h:78
GeometryType::Pointer GeometryPointerType
Definition: cad_json_input.h:61
NurbsCurveGeometry< 2, ContainerEmbeddedNodeType > NurbsTrimmingCurveType
Definition: cad_json_input.h:69
std::size_t IndexType
Definition: cad_json_input.h:58
NurbsSurfaceType::Pointer NurbsSurfacePointerType
Definition: cad_json_input.h:71
std::size_t SizeType
Definition: cad_json_input.h:57
PointerVector< TNodeType > ContainerNodeType
Definition: cad_json_input.h:63
BrepSurface< ContainerNodeType, ContainerEmbeddedNodeType > BrepSurfaceType
Definition: cad_json_input.h:74
CadJsonInput(Parameters CadJsonParameters, SizeType EchoLevel=0)
Constructor with KratosParameters.
Definition: cad_json_input.h:98
void ReadModelPart(ModelPart &rModelPart) override
Adds all CAD geometries to the herin provided model_part.
Definition: cad_json_input.h:114
DenseVector< typename BrepCurveOnSurfaceType::Pointer > BrepCurveOnSurfaceArrayType
Definition: cad_json_input.h:80
DenseVector< DenseVector< typename BrepCurveOnSurfaceType::Pointer > > BrepCurveOnSurfaceLoopArrayType
Definition: cad_json_input.h:82
PointerVector< TEmbeddedNodeType > ContainerEmbeddedNodeType
Definition: cad_json_input.h:64
KRATOS_CLASS_POINTER_DEFINITION(CadJsonInput)
Pointer definition of CadJsonInput.
DenseVector< typename BrepCurveOnSurfaceType::Pointer > BrepCurveOnSurfaceLoopType
Definition: cad_json_input.h:81
CouplingGeometry< TNodeType > CouplingGeometryType
Definition: cad_json_input.h:66
BrepCurveOnSurface< ContainerNodeType, ContainerEmbeddedNodeType > BrepCurveOnSurfaceType
Definition: cad_json_input.h:75
NurbsSurfaceGeometry< 3, ContainerNodeType > NurbsSurfaceType
Definition: cad_json_input.h:68
PointOnGeometry< ContainerNodeType, 3, 2 > PointOnGeometryOnSurfaceType
Definition: cad_json_input.h:77
The CouplingGeometry connects two or more geometries of different types and entities.
Definition: coupling_geometry.h:41
std::vector< GeometryPointer > GeometryPointerVector
Definition: coupling_geometry.h:52
Geometry base class.
Definition: geometry.h:71
IO provides different implementation of input output procedures which can be used to read and write w...
Definition: io.h:58
std::size_t SizeType
Definition: io.h:97
Definition: amatrix_interface.h:41
This class aims to manage meshes for multi-physics simulations.
Definition: model_part.h:77
Definition: nurbs_curve_geometry.h:33
Definition: nurbs_surface_geometry.h:38
This class provides to Kratos a data structure for I/O based on the standard of JSON.
Definition: kratos_parameters.h:59
bool Has(const std::string &rEntry) const
This method checks if the Parameter contains a certain entry.
Definition: kratos_parameters.cpp:520
Definition: point_on_geometry.h:36
PointerVector is a container like stl vector but using a vector to store pointers to its data.
Definition: pointer_vector.h:72
#define KRATOS_ERROR
Definition: exception.h:161
#define KRATOS_ERROR_IF_NOT(conditional)
Definition: exception.h:163
#define KRATOS_ERROR_IF(conditional)
Definition: exception.h:162
#define KRATOS_INFO_IF(label, conditional)
Definition: logger.h:251
static int EchoLevel
Definition: co_sim_EMPIRE_API.h:42
bool Has(const std::string &ModelerName)
Checks if the modeler is registered.
Definition: modeler_factory.cpp:24
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
KratosZeroVector< double > ZeroVector
Definition: amatrix_interface.h:561
Internals::Matrix< double, AMatrix::dynamic, 1 > Vector
Definition: amatrix_interface.h:472
std::size_t SizeType
The definition of the size type.
Definition: mortar_classes.h:43
q
Definition: generate_convection_diffusion_explicit_element.py:109
p
Definition: sensitivityMatrix.py:52
integer i
Definition: TensorModule.f:17