24template <
short_t d,
class T>
35 static_assert(
d >= 1 &&
d <= 4,
"Spatial dimension must be between 1 and 4");
39 gismo::gsMultiPatch<T>
geo_;
47 const std::array<int64_t, d> ncoeffs,
48 const std::array<int64_t, d> npatches,
52 if constexpr (
d == 1) {
53 gismo::gsKnotVector<T>
KV0(0, 1, ncoeffs[0] - degrees[0] - 1, degrees[0] + 1);
55 gismo::gsMatrix<T>
C(ncoeffs[0], 3),
P;
58 C(
i, 0) = ((T)
i) / (T)(ncoeffs[0] - 1);
68 P.col(0).array() += (T)(
i) / (T)npatches[0];
72 geo_.computeTopology();
74 }
else if constexpr (
d == 2) {
75 gismo::gsKnotVector<T>
KV0(0, 1, ncoeffs[0] - degrees[0] - 1, degrees[0] + 1);
76 gismo::gsKnotVector<T>
KV1(0, 1, ncoeffs[1] - degrees[1] - 1, degrees[1] + 1);
78 gismo::gsMatrix<T>
C(ncoeffs[0] * ncoeffs[1], 3),
P;
83 C(
r, 0) = ((T)
i) / (T)(ncoeffs[0] - 1);
84 C(
r, 1) = ((T)
j) / (T)(ncoeffs[1] - 1);
96 P.col(0).array() += (T)(
i) / (T)npatches[0];
97 P.col(1).array() += (T)(
j) / (T)npatches[1];
101 geo_.computeTopology();
103 }
else if constexpr (
d == 3) {
104 gismo::gsKnotVector<T>
KV0(0, 1, ncoeffs[0] - degrees[0] - 1, degrees[0] + 1);
105 gismo::gsKnotVector<T>
KV1(0, 1, ncoeffs[1] - degrees[1] - 1, degrees[1] + 1);
106 gismo::gsKnotVector<T>
KV2(0, 1, ncoeffs[2] - degrees[2] - 1, degrees[2] + 1);
108 gismo::gsMatrix<T>
C(ncoeffs[0] * ncoeffs[1] * ncoeffs[2], 3),
P;
114 C(
r, 0) = ((T)
i) / (T)(ncoeffs[0] - 1);
115 C(
r, 1) = ((T)
j) / (T)(ncoeffs[1] - 1);
116 C(
r, 2) = ((T)
k) / (T)(ncoeffs[2] - 1);
129 P.col(0).array() += (T)(
i) / (T)npatches[0];
130 P.col(1).array() += (T)(
j) / (T)npatches[1];
131 P.col(2).array() += (T)(
k) / (T)npatches[2];
135 geo_.computeTopology();
137 }
else if constexpr (
d == 4) {
138 gismo::gsKnotVector<T>
KV0(0, 1, ncoeffs[0] - degrees[0] - 1, degrees[0] + 1);
139 gismo::gsKnotVector<T>
KV1(0, 1, ncoeffs[1] - degrees[1] - 1, degrees[1] + 1);
140 gismo::gsKnotVector<T>
KV2(0, 1, ncoeffs[2] - degrees[2] - 1, degrees[2] + 1);
141 gismo::gsKnotVector<T>
KV3(0, 1, ncoeffs[3] - degrees[3] - 1, degrees[3] + 1);
143 gismo::gsMatrix<T>
C(ncoeffs[0] * ncoeffs[1] * ncoeffs[2] * ncoeffs[3], 4),
P;
150 C(
r, 0) = ((T)
i) / (T)(ncoeffs[0] - 1);
151 C(
r, 1) = ((T)
j) / (T)(ncoeffs[1] - 1);
152 C(
r, 2) = ((T)
k) / (T)(ncoeffs[2] - 1);
153 C(
r, 3) = ((T)
l) / (T)(ncoeffs[3] - 1);
168 P.col(0).array() += (T)(
i) / (T)npatches[0];
169 P.col(1).array() += (T)(
j) / (T)npatches[1];
170 P.col(2).array() += (T)(
k) / (T)npatches[2];
171 P.col(3).array() += (T)(
l) / (T)npatches[3];
175 geo_.computeTopology();
186 if constexpr (
d == 1)
189 "label" : "Number of patches",
190 "description" : "Number of patches per spatial dimension",
196 "label" : "Spline degree",
197 "description" : "Spline degree",
203 "label" : "Number of coefficients",
204 "description" : "Number of coefficients per parametric dimension",
209 "name" : "dimension",
210 "label" : "Dimension [width]",
211 "description" : "Dimension in physical space",
217 else if constexpr (
d == 2)
220 "label" : "Number of patches",
221 "description" : "Number of patches per spatial dimension",
222 "type" : ["int","int"],
227 "label" : "Spline degrees",
228 "description" : "Spline degrees per parametric dimension",
229 "type" : ["int","int"],
234 "label" : "Number of coefficients",
235 "description" : "Number of coefficients per parametric dimension",
236 "type" : ["int","int"],
240 "name" : "dimensions",
241 "label" : "Dimensions [width, height]",
242 "description" : "Dimensions in physical space",
243 "type" : ["float", "float"],
244 "value" : [1.0, 1.0],
245 "default" : [1.0, 1.0],
248 else if constexpr (
d == 3)
251 "label" : "Number of patches",
252 "description" : "Number of patches per spatial dimension",
253 "type" : ["int","int","int"],
258 "label" : "Spline degrees",
259 "description" : "Spline degrees per parametric dimension",
260 "type" : ["int","int","int"],
265 "label" : "Number of coefficients",
266 "description" : "Number of coefficients per parametric dimension",
267 "type" : ["int","int","int"],
271 "name" : "dimensions",
272 "label" : "Dimensions [width, height, depth]",
273 "description" : "Dimensions in physical space",
274 "type" : ["float", "float", "float"],
275 "value" : [1.0, 1.0, 1.0],
276 "default" : [1.0, 1.0, 1.0],
279 else if constexpr (
d == 4)
282 "label" : "Number of patches",
283 "description" : "Number of patches per spatial dimension",
284 "type" : ["int","int","int","int"],
286 "default" : [1,1,1,1],
289 "label" : "Spline degrees",
290 "description" : "Spline degrees per parametric dimension",
291 "type" : ["int","int","int","int"],
293 "default" : [2,2,2,2],
296 "label" : "Number of coefficients",
297 "description" : "Number of coefficients per parametric dimension",
298 "type" : ["int","int","int","int"],
300 "default" : [3,3,3,3],
302 "name" : "dimensions",
303 "label" : "Dimensions [width, height, depth, time]",
304 "description" : "Dimensions in physical space",
305 "type" : ["float", "float", "float", "float"],
306 "value" : [1.0, 1.0, 1.0, 1.0],
307 "default" : [1.0, 1.0, 1.0, 1.0],
311 return R
"({ INVALID REQUEST })"_json;
318 "description" : "Geometry",
325 "name" : "ScaledJacobian",
326 "description" : "Scaled Jacobian of the geometry mapping as quality measure for orthogonality",
328 "name" : "UniformityMetric",
329 "description" : "Uniformity metric quality measure for area distortion of the geometry map",
335 const std::string &
attribute)
const override {
345 else if (patch !=
"") {
354 return R
"({ INVALID REQUEST })"_json;
358 return R
"({ INVALID REQUEST })"_json;
371 json[
"degrees"] = nlohmann::json::array();
384 json[
"ncoeffs"] = nlohmann::json::array();
387 dynamic_cast<const gismo::gsBSpline<T> *
>(&
geo_.patch(
patchIndex)))
388 for (std::size_t
i = 0;
i <
bspline->parDim(); ++
i)
390 else if (
auto bspline =
dynamic_cast<const gismo::gsTensorBSpline<d, T> *
>(
392 for (std::size_t
i = 0;
i <
bspline->parDim(); ++
i)
395 return R
"({ INVALID REQUEST })"_json;
400 json[
"nknots"] = nlohmann::json::array();
403 dynamic_cast<const gismo::gsBSpline<T> *
>(&
geo_.patch(
patchIndex)))
404 for (std::size_t
i = 0;
i <
bspline->parDim(); ++
i)
406 else if (
auto bspline =
dynamic_cast<const gismo::gsTensorBSpline<d, T> *
>(
408 for (std::size_t
i = 0;
i <
bspline->parDim(); ++
i)
411 return R
"({ INVALID REQUEST })"_json;
417 dynamic_cast<const gismo::gsBSpline<T> *
>(&
geo_.patch(
patchIndex)))
419 else if (
auto bspline =
dynamic_cast<const gismo::gsTensorBSpline<d, T> *
>(
423 return R
"({ INVALID REQUEST })"_json;
428 json[
"knots"] = nlohmann::json::array();
431 dynamic_cast<const gismo::gsBSpline<T> *
>(&
geo_.patch(
patchIndex)))
432 for (std::size_t
i = 0;
i <
bspline->parDim(); ++
i)
434 else if (
auto bspline =
dynamic_cast<const gismo::gsTensorBSpline<d, T> *
>(
436 for (std::size_t
i = 0;
i <
bspline->parDim(); ++
i)
439 return R
"({ INVALID REQUEST })"_json;
444 return R
"({ INVALID REQUEST })"_json;
451 return R
"({ INVALID REQUEST })"_json;
462 const nlohmann::json &
json)
override {
469 return R
"({ INVALID REQUEST })"_json;
473 if (!
json.contains(
"data"))
478 auto indices =
json[
"data"][
"indices"].get<std::vector<int64_t>>();
481 switch (
geo_.geoDim()) {
483 auto coords =
json[
"data"][
"coeffs"].get<std::vector<std::tuple<T>>>();
495 json[
"data"][
"coeffs"].get<std::vector<std::tuple<T, T>>>();
508 json[
"data"][
"coeffs"].get<std::vector<std::tuple<T, T, T>>>();
522 json[
"data"][
"coeffs"].get<std::vector<std::tuple<T, T, T, T>>>();
546 const nlohmann::json &
json)
const override {
553 return R
"({ INVALID REQUEST })"_json;
559 result[
"degrees"] = nlohmann::json::array();
565 result[
"ncoeffs"] = nlohmann::json::array();
568 dynamic_cast<const gismo::gsBSpline<T> *
>(&
geo_.patch(
patchIndex)))
569 for (std::size_t
i = 0;
i <
bspline->parDim(); ++
i)
571 else if (
auto bspline =
dynamic_cast<const gismo::gsTensorBSpline<d, T> *
>(
573 for (std::size_t
i = 0;
i <
bspline->parDim(); ++
i)
576 return R
"({ INVALID REQUEST })"_json;
579 result[
"nknots"] = nlohmann::json::array();
582 dynamic_cast<const gismo::gsBSpline<T> *
>(&
geo_.patch(
patchIndex)))
583 for (std::size_t
i = 0;
i <
bspline->parDim(); ++
i)
585 else if (
auto bspline =
dynamic_cast<const gismo::gsTensorBSpline<d, T> *
>(
587 for (std::size_t
i = 0;
i <
bspline->parDim(); ++
i)
590 return R
"({ INVALID REQUEST })"_json;
593 result[
"knots"] = nlohmann::json::array();
596 dynamic_cast<const gismo::gsBSpline<T> *
>(&
geo_.patch(
patchIndex)))
597 for (std::size_t
i = 0;
i <
bspline->parDim(); ++
i)
599 else if (
auto bspline =
dynamic_cast<const gismo::gsTensorBSpline<d, T> *
>(
601 for (std::size_t
i = 0;
i <
bspline->parDim(); ++
i)
604 return R
"({ INVALID REQUEST })"_json;
610 gismo::gsExprEvaluator<T>
ev;
611 ev.setIntegrationElements(
basis);
616 auto parDim =
geo_.parDim();
619 gismo::gsMatrix<T>
eval(1,
pts.cols());
621 if (parDim == 2 &&
geo_.geoDim() == 3) {
622 for (std::size_t
i = 0;
i <
pts.cols();
i++) {
623 auto jac =
ev.eval(gismo::expr::jac(G),
pts.col(
i));
624 eval(0,
i) = jac.col(0).dot(jac.col(1));
625 for (std::size_t
j = 0;
j < parDim;
j++)
626 eval(0,
i) /= (jac.col(
j).norm());
629 for (std::size_t
i = 0;
i <
pts.cols();
i++) {
630 auto jac =
ev.eval(gismo::expr::jac(G),
pts.col(
i));
631 eval(0,
i) = jac.determinant();
632 for (std::size_t
j = 0;
j < parDim;
j++)
633 eval(0,
i) /= (jac.col(
j).norm());
637 auto jac =
basis.interpolateAtAnchors(
eval);
641 else if (
component ==
"UniformityMetric") {
646 auto expr = gismo::expr::pow((gismo::expr::meas(G) -
area.val()) /
area.val(), 2);
650 gismo::gsMatrix<T>
eval(1,
pts.cols());
652 for (std::size_t
i = 0;
i <
pts.cols();
i++)
659 return R
"({ INVALID REQUEST })"_json;
672 if (
json.contains(
"data")) {
674 num =
json[
"data"][
"num"].get<
int>();
693 if (
json.contains(
"data")) {
695 num =
json[
"data"][
"num"].get<
int>();
714 if (
json.contains(
"data")) {
716 num =
json[
"data"][
"num"].get<
int>();
726 geo_.uniformRefine(
num, 1, dim);
733 const nlohmann::json &
json =
NULL)
override {
734 std::string type(
"volume");
738 if (
json.contains(
"data")) {
740 type =
json[
"data"][
"type"].get<std::string>();
752 if (type ==
"surface") {
754 if (
geo_.parDim() == 2) {
759 for (
auto&
p :
geo_) {
760 gismo::gsMultiPatch<T>
mp;
mp.addPatch(*
p);
775 else if (
geo_.parDim() == 3) {
779 geo_.computeTopology();
782 for (
auto&
bdr :
geo_.boundaries()) {
783 auto b =
geo_.patch(
bdr.patch).boundary(
bdr.side());
784 gismo::gsMultiPatch<T>
mp;
mp.addPatch(*
b);
788 gismo::gsMatrix<T>
ind =
geo_.patch(
bdr.patch).basis().boundary(
bdr.side());
789 for (
int i = 0;
i !=
ind.size();
i++ )
797 }
else if (type ==
"volume") {
799 if (
geo_.parDim() == 2 &&
geo_.geoDim() == 3) {
804 opt.options().setInt(
"ParamMethod", 1);
814 gismo::gsBarrierPatch<2, T> opt(
mp,
true);
815 opt.options().setInt(
"ParamMethod", 1);
824 else if (
geo_.parDim() == 3 &&
geo_.geoDim() == 3) {
828 opt.options().setInt(
"ParamMethod", 1);
836 gismo::gsBarrierPatch<d, T> opt(
mp,
true);
837 opt.options().setInt(
"ParamMethod", 1);
850 throw std::runtime_error(
"Adding patches is not yet implemented in G+Smo");
855 const nlohmann::json &
json =
NULL)
override {
862 gismo::gsMultiPatch<T>
geo;
863 for (
int i=0;
i<
geo_.nPatches(); ++
i) {
875 const nlohmann::json &
json,
878 if (
json.contains(
"data")) {
881 std::string
xml_str =
json[
"data"][
"xml"].get<std::string>();
883 gismo::internal::gsXmlTree
xml;
884 xml.parse<0>(
const_cast<char*
>(
xml_str.c_str()));
892 throw std::runtime_error(
"No XML node in JSON object");
898 const pugi::xml_node &
xml,
901 gsWarn <<
"Using generic importXML implementation\n";
912 throw std::runtime_error(
"Unsupported component");
918 const gismo::internal::gsXmlTree &
xml,
925 auto *
geo = gismo::internal::gsXml<gismo::gsMultiPatch<T>>
::getFirst(
xml.getRoot());
931 auto *
p = gismo::internal::gsXml<gismo::gsGeometry<T>>
::getFirst(
xml.getRoot());
939 throw std::runtime_error(
"Unsupported component");
944 gismo::internal::gsXmlTree
xml;
950 rapidxml::print(std::back_inserter(
xml_str),
xml, 0);
971 gsWarn <<
"Using generic exportXML implementation\n";
975 gismo::internal::gsXmlTree data;
978 gismo::internal::gsXmlNode *
node = (patch ==
""
980 gismo::internal::gsXml<gismo::gsMultiPatch<T>>
::put(
geo_, data)
982 gismo::internal::gsXml<gismo::gsGeometry<T>>
::put(
geo_.patch(
stoi(patch)), data));
985 data.appendToRoot(
node, -1);
988 rapidxml::print(std::back_inserter(
xml_str), data, 1);
990 pugi::xml_document
doc;
994 for (
auto node :
doc.first_child())
998 throw std::runtime_error(
"Unsupported component");
1004 gismo::internal::gsXmlTree &
exportXML(
const std::string &patch,
1006 gismo::internal::gsXmlTree &
xml,
1011 gismo::internal::gsXmlNode *
node = (patch ==
""
1013 gismo::internal::gsXml<gismo::gsMultiPatch<T>>
::put(
geo_,
xml)
1015 gismo::internal::gsXml<gismo::gsGeometry<T>>
::put(
geo_.patch(
stoi(patch)),
xml));
1021 throw std::runtime_error(
"Unsupported component");
Model add patch.
Definition model.hpp:47
Model degree elevation.
Definition model.hpp:86
Model evaluator.
Definition model.hpp:98
Model degree increase.
Definition model.hpp:112
Model refinement.
Definition model.hpp:124
Model remove patch.
Definition model.hpp:59
Model reparameterization.
Definition model.hpp:136
Model XML serialization.
Definition model.hpp:163
G+Smo geometry model.
Definition GismoGeometryModel.hpp:33
nlohmann::json getOutputs() const override
Returns the model's outputs.
Definition GismoGeometryModel.hpp:323
void reparameterize(const std::string &patch, const nlohmann::json &json=NULL) override
Reparameterize the model.
Definition GismoGeometryModel.hpp:732
gismo::gsMultiPatch< T > geo_
Multi-patch geometry.
Definition GismoGeometryModel.hpp:39
nlohmann::json eval(const std::string &patch, const std::string &component, const nlohmann::json &json) const override
Evaluates the model.
Definition GismoGeometryModel.hpp:545
nlohmann::json getInputs() const override
Returns the model's inputs.
Definition GismoGeometryModel.hpp:315
nlohmann::json to_json(const std::string &patch, const std::string &component, const std::string &attribute) const override
Serializes the model to JSON.
Definition GismoGeometryModel.hpp:334
nlohmann::json getOptions() const override
Returns the model's options.
Definition GismoGeometryModel.hpp:185
GismoGeometryModel(const pugi::xml_node root)
Constructor from XML.
Definition GismoGeometryModel.hpp:180
nlohmann::json updateAttribute(const std::string &patch, const std::string &component, const std::string &attribute, const nlohmann::json &json) override
Updates the attributes of the model.
Definition GismoGeometryModel.hpp:459
void refine(const nlohmann::json &json=NULL) override
Refines the model.
Definition GismoGeometryModel.hpp:711
nlohmann::json exportXML(const std::string &patch, const std::string &component, int id) override
Exports the model to XML (as JSON object)
Definition GismoGeometryModel.hpp:943
void increase(const nlohmann::json &json=NULL) override
Increases the model's degrees, preserves multiplicity.
Definition GismoGeometryModel.hpp:690
void removePatch(const std::string &patch, const nlohmann::json &json=NULL) override
Remove existing patch from the model.
Definition GismoGeometryModel.hpp:854
pugi::xml_node & exportXML(const std::string &patch, const std::string &component, pugi::xml_node &xml, int id) override
Exports the model to XML (as XML object)
Definition GismoGeometryModel.hpp:966
gismo::internal::gsXmlTree & exportXML(const std::string &patch, const std::string &component, gismo::internal::gsXmlTree &xml, int id)
Exports the model to XML (as XML object) optimized for G+Smo.
Definition GismoGeometryModel.hpp:1004
GismoGeometryModel()=default
Default constructor.
void importXML(const std::string &patch, const std::string &component, const nlohmann::json &json, int id) override
Imports the model from XML (as JSON object)
Definition GismoGeometryModel.hpp:873
void importXML(const std::string &patch, const std::string &component, const pugi::xml_node &xml, int id) override
Imports the model from XML (as XML object)
Definition GismoGeometryModel.hpp:896
void addPatch(const nlohmann::json &json=NULL) override
Add new patch to the model.
Definition GismoGeometryModel.hpp:848
void elevate(const nlohmann::json &json=NULL) override
Elevates the model's degrees, preserves smoothness.
Definition GismoGeometryModel.hpp:669
void importXML(const std::string &patch, const std::string &component, const gismo::internal::gsXmlTree &xml, int id)
Imports the model from XML (as XML object) optimized for G+Smo.
Definition GismoGeometryModel.hpp:916
GismoGeometryModel(const std::array< short_t, d > degrees, const std::array< int64_t, d > ncoeffs, const std::array< int64_t, d > npatches, const std::array< T, d > dimensions)
Constructor for equidistant knot vectors.
Definition GismoGeometryModel.hpp:46
G+Smo base model.
Definition GismoModel.hpp:75
virtual nlohmann::json to_json(const std::string &patch, const std::string &component, const std::string &attribute) const override
Serializes the model to JSON.
Definition GismoModel.hpp:85
virtual nlohmann::json updateAttribute(const std::string &patch, const std::string &component, const std::string &attribute, const nlohmann::json &json) override
Updates the attributes of the model.
Definition GismoModel.hpp:93
auto to_json(const torch::TensorAccessor< T, N > &accessor)
Converts a torch::TensorAccessor object to a JSON object.
Definition serialize.hpp:41
auto zip(T &&...seqs)
Definition zip.hpp:97
Definition boundary.hpp:22
constexpr bool is_SplineType_v
Alias to the value of is_SplineType.
Definition bspline.hpp:3243
IndexOutOfBounds exception.
Definition model.hpp:32
InvalidModelAttribute exception.
Definition model.hpp:42