Skip to content

Commit 118e694

Browse files
authored
Merge pull request #576 from sebproell/knotvectors
Read NURBS knotvectors on rank 0 and communicate
2 parents 8357daf + 4187b5b commit 118e694

File tree

1 file changed

+53
-219
lines changed

1 file changed

+53
-219
lines changed

src/core/io/src/4C_io_input_file_utils.cpp

Lines changed: 53 additions & 219 deletions
Original file line numberDiff line numberDiff line change
@@ -554,308 +554,142 @@ void Core::IO::read_design(InputFile& input, const std::string& name,
554554
void Core::IO::read_knots(InputFile& input, const std::string& name,
555555
std::shared_ptr<Core::FE::Nurbs::Knotvector>& disknots)
556556
{
557-
// io to shell
558557
const int myrank = Core::Communication::my_mpi_rank(input.get_comm());
559-
560558
Teuchos::Time time("", true);
561559

562-
// only the knotvector section of this discretisation
563-
// type is of interest
564560
std::string field;
565-
if (name == "fluid" or name == "xfluid" or name == "porofluid")
566-
{
561+
if (name == "fluid" || name == "xfluid" || name == "porofluid")
567562
field = "FLUID";
568-
}
569563
else if (name == "structure")
570-
{
571564
field = "STRUCTURE";
572-
}
573565
else if (name == "ale")
574-
{
575566
field = "ALE";
576-
}
577567
else if (name == "scatra")
578-
{
579568
field = "TRANSPORT";
580-
}
581569
else if (name == "thermo")
582-
{
583570
field = "THERMO";
584-
}
585571
else if (name == "scatra_micro")
586-
{
587572
field = "TRANSPORT2";
588-
}
589573
else
590-
{
591-
FOUR_C_THROW("Unknown discretization name for knotvector input\n");
592-
}
574+
FOUR_C_THROW("Unknown discretization name for knotvector input.");
593575

594-
// another valid section name was found
595576
const std::string sectionname = field + " KNOTVECTORS";
596577

597578
if (myrank == 0)
598579
{
599580
Core::IO::cout << "Reading knot vectors for " << name << " discretization :\n";
600581
fflush(stdout);
601-
}
602-
603-
// number of patches to be determined
604-
int npatches = 0;
605582

606-
// dimension of nurbs patches
607-
int nurbs_dim = 0;
583+
int npatches = 0;
584+
int nurbs_dim = 0;
608585

609-
//--------------------------------------------------------------------
610-
//--------------------------------------------------------------------
611-
// first, determine number of patches and dimension of nurbs
612-
//--------------------------------------------------------------------
613-
//--------------------------------------------------------------------
614-
{
615-
// temporary string
616-
std::string tmp;
617-
// loop lines in file
618-
for (const auto& line : input.in_section(sectionname))
586+
for (const auto& line : input.in_section_rank_0_only(sectionname))
619587
{
620-
// count number of patches in knotvector section of
621-
// this discretisation
622-
{
623-
std::string::size_type loc;
624-
std::istringstream file{std::string{line.get_as_dat_style_string()}};
625-
file >> tmp;
626-
627-
// check for the number of dimensions
628-
loc = tmp.rfind("NURBS_DIMENSION");
629-
if (loc != std::string::npos)
630-
{
631-
// set number of nurbs dimension
632-
std::string str_nurbs_dim;
633-
file >> str_nurbs_dim;
634-
char* endptr = nullptr;
635-
nurbs_dim = static_cast<int>(strtol(str_nurbs_dim.c_str(), &endptr, 10));
636-
637-
continue;
638-
}
588+
std::string line_str{line.get_as_dat_style_string()};
589+
std::istringstream file{line_str};
590+
std::string tmp;
591+
file >> tmp;
639592

640-
// check for a new patch
641-
loc = tmp.rfind("ID");
642-
if (loc != std::string::npos)
643-
{
644-
// increase number of patches
645-
npatches++;
593+
std::cout << "Token: " << tmp << std::endl;
646594

647-
continue;
648-
}
595+
if (tmp == "NURBS_DIMENSION")
596+
{
597+
file >> nurbs_dim;
649598
}
650-
} // end loop through file
651-
}
599+
else if (tmp == "ID")
600+
{
601+
npatches++;
602+
}
603+
}
652604

653-
if (myrank == 0)
654-
{
655605
printf(" %8d patches", npatches);
656606
fflush(stdout);
657-
}
658-
659607

660-
//--------------------------------------------------------------------
661-
//--------------------------------------------------------------------
662-
// alloc knotvector object to fill
663-
//--------------------------------------------------------------------
664-
//--------------------------------------------------------------------
608+
disknots = std::make_shared<Core::FE::Nurbs::Knotvector>(nurbs_dim, npatches);
665609

666-
// allocate knotvector for this dis
667-
disknots = std::make_shared<Core::FE::Nurbs::Knotvector>(nurbs_dim, npatches);
668-
669-
// make sure that we have some Knotvector object to fill
670-
if (disknots == nullptr)
671-
{
672-
FOUR_C_THROW("disknots should have been allocated before");
673-
}
674-
675-
//--------------------------------------------------------------------
676-
//--------------------------------------------------------------------
677-
// finally read knotvector section
678-
//--------------------------------------------------------------------
679-
//--------------------------------------------------------------------
680-
{
681-
// this is a pointer to the knots of one patch in one direction
682-
// we will read them and put them
683610
std::vector<std::shared_ptr<std::vector<double>>> patch_knots(nurbs_dim);
684-
685-
// temporary string
686-
std::string tmp;
687-
688-
// start to read something when read is true
689-
bool read = false;
690-
691-
// index for number of patch
692-
int npatch = 0;
693-
// index for u/v/w
694-
int actdim = -1;
695-
// ints for the number of knots
696-
std::vector<int> n_x_m_x_l(nurbs_dim);
697-
// ints for patches degrees
698-
std::vector<int> degree(nurbs_dim);
699-
// a vector of strings holding the knotvectortypes read
611+
std::vector<int> n_x_m_x_l(nurbs_dim), degree(nurbs_dim), count_vals(nurbs_dim);
700612
std::vector<std::string> knotvectortype(nurbs_dim);
701613

702-
// count for sanity check
703-
int count_read = 0;
704-
std::vector<int> count_vals(nurbs_dim);
614+
bool read = false;
615+
int npatch = 0, actdim = -1, count_read = 0;
705616

706-
// loop lines in file
707-
for (const auto& line : input.in_section(sectionname))
617+
for (const auto& line : input.in_section_rank_0_only(sectionname))
708618
{
709-
std::istringstream file{std::string{line.get_as_dat_style_string()}};
619+
std::string line_str{line.get_as_dat_style_string()};
620+
std::istringstream file{line_str};
621+
std::string tmp;
710622
file >> tmp;
711623

712-
// check for a new patch
713-
std::string::size_type loc = tmp.rfind("BEGIN");
714-
if (loc != std::string::npos)
624+
if (tmp == "BEGIN")
715625
{
716-
file >> tmp;
717-
718-
// activate reading
719626
read = true;
720-
721627
actdim = -1;
722-
723-
// create vectors for knots in this patch
724-
for (int rr = 0; rr < nurbs_dim; ++rr)
725-
{
726-
patch_knots[rr] = std::make_shared<std::vector<double>>();
727-
(*(patch_knots[rr])).clear();
728-
}
729-
730-
// reset counter for knot values
731-
for (int rr = 0; rr < nurbs_dim; rr++)
732-
{
733-
count_vals[rr] = 0;
734-
}
735-
736-
continue;
628+
for (auto& knots : patch_knots) knots = std::make_shared<std::vector<double>>();
629+
std::fill(count_vals.begin(), count_vals.end(), 0);
737630
}
738-
739-
// get ID of patch we are currently reading
740-
loc = tmp.rfind("ID");
741-
if (loc != std::string::npos)
631+
else if (tmp == "ID")
742632
{
743-
std::string str_npatch;
744-
file >> str_npatch;
745-
746-
char* endptr = nullptr;
747-
npatch = static_cast<int>(strtol(str_npatch.c_str(), &endptr, 10));
633+
file >> npatch;
748634
npatch--;
749-
750-
continue;
751635
}
752-
753-
// get number of knots in the knotvector direction
754-
// we are currently reading
755-
loc = tmp.rfind("NUMKNOTS");
756-
if (loc != std::string::npos)
636+
else if (tmp == "NUMKNOTS")
757637
{
758-
std::string str_numknots;
759-
file >> str_numknots;
760-
761-
// increase dimesion for knotvector (i.e. next time
762-
// we'll fill the following knot vector)
763-
actdim++;
764-
if (actdim > nurbs_dim)
765-
{
766-
FOUR_C_THROW(
767-
"too many knotvectors, we only need one for each dimension (nurbs_dim = {})\n",
768-
nurbs_dim);
769-
}
770-
771-
char* endptr = nullptr;
772-
n_x_m_x_l[actdim] = static_cast<int>(strtol(str_numknots.c_str(), &endptr, 10));
773-
774-
continue;
638+
file >> n_x_m_x_l[++actdim];
775639
}
776-
777-
// get number of bspline polinomial associated with
778-
// knots in this direction
779-
loc = tmp.rfind("DEGREE");
780-
if (loc != std::string::npos)
640+
else if (tmp == "DEGREE")
781641
{
782-
std::string str_degree;
783-
file >> str_degree;
784-
785-
char* endptr = nullptr;
786-
degree[actdim] = static_cast<int>(strtol(str_degree.c_str(), &endptr, 10));
787-
788-
continue;
642+
file >> degree[actdim];
789643
}
790-
791-
// get type of knotvector (interpolated or periodic)
792-
loc = tmp.rfind("TYPE");
793-
if (loc != std::string::npos)
644+
else if (tmp == "TYPE")
794645
{
795-
std::string type;
796-
797-
file >> type;
798-
knotvectortype[actdim] = type;
799-
800-
continue;
646+
file >> knotvectortype[actdim];
801647
}
802-
803-
// locate end of patch
804-
loc = tmp.rfind("END");
805-
if (loc != std::string::npos)
648+
else if (tmp == "END")
806649
{
807650
for (int rr = 0; rr < nurbs_dim; ++rr)
808651
{
809652
disknots->set_knots(
810653
rr, npatch, degree[rr], n_x_m_x_l[rr], knotvectortype[rr], patch_knots[rr]);
811654
}
812-
file >> tmp;
813-
// stop reading of knot values if we are here
814655
read = false;
815-
816-
for (int rr = 0; rr < nurbs_dim; rr++)
656+
for (int rr = 0; rr < nurbs_dim; ++rr)
817657
{
818658
if (n_x_m_x_l[rr] != count_vals[rr])
819659
{
820660
FOUR_C_THROW("not enough knots read in dim {} ({}!=NUMKNOTS={}), nurbs_dim={}\n", rr,
821661
count_vals[rr], n_x_m_x_l[rr], nurbs_dim);
822662
}
823663
}
824-
825-
// count for sanity check
826664
count_read++;
827-
828-
continue;
829665
}
830-
831-
// reading of knot values if read is true and no
832-
// other keyword was found
833-
if (read)
666+
else if (read)
834667
{
835-
char* endptr = nullptr;
836-
837-
double dv = strtod(tmp.c_str(), &endptr);
838-
839-
// count for sanity check
668+
patch_knots[actdim]->push_back(std::stod(tmp));
840669
count_vals[actdim]++;
841-
842-
(*(patch_knots[actdim])).push_back(dv);
843670
}
844-
} // end loop through file
671+
}
845672

846673
if (count_read != npatches)
847674
{
848675
FOUR_C_THROW("wasn't able to read enough patches\n");
849676
}
850-
}
851677

852-
if (myrank == 0)
853-
{
854-
Core::IO::cout << " in...." << time.totalElapsedTime(true) << " secs\n";
678+
std::cout << "Rank 0 sending out knot vectors to all other processors" << std::endl;
679+
// Now we have to broadcast the knot vectors to all other processors
680+
Core::Communication::broadcast(*disknots, 0, input.get_comm());
855681

682+
Core::IO::cout << " in...." << time.totalElapsedTime(true) << " secs\n";
856683
time.reset();
857684
fflush(stdout);
858685
}
686+
else
687+
{
688+
std::cout << "Rank " << myrank << " waiting for knot vectors from rank 0" << std::endl;
689+
// All other ranks receive the knot vectors from rank 0.
690+
disknots = std::make_shared<Core::FE::Nurbs::Knotvector>();
691+
Core::Communication::broadcast(*disknots, 0, input.get_comm());
692+
}
859693
}
860694

861695
FOUR_C_NAMESPACE_CLOSE

0 commit comments

Comments
 (0)