19using namespace std::string_literals;
26template <
short_t d,
typename T>
29 static_assert(d >= 1 && d <= 3,
"Spatial dimension must be between 1 and 3");
42 using space_type =
typename gismo::gsExprAssembler<T>::space;
51 gismo::gsBoundaryConditions<T>
bc_;
74 u.setup(
bc_, gismo::dirichlet::l2Projection, 0);
80 assembler_.assemble(igrad(u, G) * igrad(u, G).tr() * meas(G)
86 assembler_.assemble(igrad(u, G) * igrad(u, G).tr() * meas(G)
93 auto bcNeumann =
bc_.get(
"Neumann");
94 if (!bcNeumann.empty()) {
96 assembler_.assembleBdr(bcNeumann, u * g * meas(G));
100 auto bcNeumannParametric =
bc_.get(
"NeumannParametric");
101 if (!bcNeumannParametric.empty()) {
103 assembler_.assembleBdr(bcNeumannParametric, u * g * meas(G));
107 typename gismo::gsSparseSolver<T>::CGDiagonal solver;
110 gismo::gsMatrix<T> solutionVector;
112 solutionVector = solver.solve(
assembler_.rhs());
124 const std::array<int64_t, d> ncoeffs,
125 const std::array<int64_t, d> npatches,
126 const std::array<T, d> dimensions)
129 rhsFunc_(d == 1 ?
"2*pi^2*sin(pi*x)"
130 : d == 2 ?
"2*pi^2*sin(pi*x)*sin(pi*y)"
131 :
"2*pi^2*sin(pi*x)*sin(pi*y)*sin(pi*z)",
136 gismo::gsOptionList Aopt = gismo::gsExprAssembler<>::defaultOptions();
145 for (
auto const &bdr :
Base::geo_.boundaries()) {
146 auto patch = bdr.patch;
147 auto side = bdr.side();
148 auto bc =
bcMap_[patch][
side] = { gismo::gsFunctionExpr<T>(
"0", d),
149 gismo::condition_type::dirichlet,
154 for (
auto const & p :
bcMap_) {
155 std::size_t patch = p.first;
157 for (
auto const & bc : p.second) {
158 auto side =
static_cast<gismo::boundary::side
>(bc.first);
160 bc_.addCondition(patch,
side, bc.second.type, bc.second.function, 0, bc.second.isParametric);
176 return "GismoPoisson" + std::to_string(d) +
"d";
181 return "G+Smo Poisson model in " + std::to_string(d) +
" dimensions";
188 "description" : "Solution of the Poisson equation",
191 "description" : "Right-hand side function",
195 json.push_back(output);
203 auto json = nlohmann::json::array();
207 auto add_json = [&json, &uiid]<
typename Type,
typename Value>(
int patch,
208 const std::string &name,
209 const std::string &label,
210 const std::string &group,
211 const std::string &description,
213 const Value &value) {
215 item[
"patch"] = patch;
217 item[
"label"] = label;
218 item[
"description"] = description;
219 item[
"group"] = group;
221 item[
"value"] = value;
222 item[
"default"] = value;
223 item[
"uuid"] = uiid++;
224 json.push_back(item);
228 auto add_json_default =
229 [&json, &uiid]<
typename Type,
typename Value,
typename DefaultValue>(
int patch,
230 const std::string &name,
const std::string &label,
231 const std::string &group,
const std::string &description,
232 const Type &type,
const Value &value,
233 const DefaultValue &defaultValue) {
235 item[
"patch"] = patch;
237 item[
"label"] = label;
238 item[
"description"] = description;
239 item[
"group"] = group;
241 item[
"value"] = value;
242 item[
"default"] = defaultValue;
243 item[
"uuid"] = uiid++;
244 json.push_back(item);
247 add_json(0,
"rhs",
"Rhs function",
"rhs",
"Right-hand side function",
"text",
249 add_json(0,
"rhs_parametric",
"Parametric",
"rhs",
250 "Right-hand side function defined in parametric domain",
"bool",
253 for (
auto const & p :
bcMap_) {
254 std::size_t patch = p.first;
256 for (
auto const & bc : p.second) {
257 auto side =
static_cast<gismo::boundary::side
>(bc.first);
258 std::string str = *(GismoBoundarySideStrings<d>.begin()+
side-1);
260 add_json(patch,
"bc["s + std::to_string(patch) +
":" + str +
"]"s,
"Value", str,
261 "Boundary value at the "s + str +
" boundary of patch "s + std::to_string(patch),
"text",
262 bc.second.function.expression(0));
263 add_json(patch,
"bc_parametric["s + std::to_string(patch) +
":" + str +
"]",
"Parametric", str,
264 "Boundary value at the "s + str +
265 " boundary of patch "s + std::to_string(patch) +
"defined in parametric domain"s,
266 "bool", bc.second.isParametric);
267 add_json_default(patch,
"bc_type["s + std::to_string(patch) +
":" + str +
"]",
"Type", str,
268 "Type of boundary condition at the "s + str +
" boundary of patch "s + std::to_string(patch),
"select",
269 R
"([ "Dirichlet", "Neumann" ])"_json,
270 bc.second.type == gismo::condition_type::dirichlet ? "Dirichlet" :
"Neumann");
279 const std::string &component,
280 const std::string &attribute,
281 const nlohmann::json &json)
override {
283 bool updateBC(
false);
284 nlohmann::json result = R
"({})"_json;
287 std::size_t patch = p.first;
289 for (
auto & bc : p.second) {
290 auto side =
static_cast<gismo::boundary::side
>(bc.first);
291 std::string str = *(GismoBoundarySideStrings<d>.begin()+
side-1);
294 if (attribute ==
"bc_parametric["s + std::to_string(patch) +
":" + str +
"]"s) {
295 if (!json.contains(
"data"))
297 if (!json[
"data"].contains(
"bc_parametric["s + std::to_string(patch) +
":" + str +
"]"s))
300 bc.second.isParametric =
301 json[
"data"][
"bc_parametric["s + std::to_string(patch) +
":" + str +
"]"s].template get<bool>();
304 gismo::give(gismo::gsFunctionExpr<T>(bc.second.function.expression(0),
305 bc.second.isParametric ? d : 3));
312 else if (attribute ==
"bc_type["s + std::to_string(patch) +
":" + str +
"]"s) {
313 if (!json.contains(
"data"))
315 if (!json[
"data"].contains(
"bc_type["s + std::to_string(patch) +
":" + str +
"]"s))
318 std::string bc_type =
319 json[
"data"][
"bc_type["s + std::to_string(patch) +
":" + str +
"]"s].template get<std::string>();
321 if (bc_type ==
"Dirichlet")
322 bc.second.type = gismo::condition_type::type::dirichlet;
323 else if (bc_type ==
"Neumann")
324 bc.second.type = gismo::condition_type::type::neumann;
333 else if (attribute ==
"bc["s + std::to_string(patch) +
":" + str +
"]"s) {
334 if (!json.contains(
"data"))
336 if (!json[
"data"].contains(
"bc["s + std::to_string(patch) +
":" + str +
"]"s))
339 bc.second.function =gismo::give(gismo::gsFunctionExpr<T>(
340 json[
"data"][
"bc["s + std::to_string(patch) +
":" + str +
"]"s].
template get<std::string>(),
341 bc.second.isParametric ? d : 3));
350 if (attribute ==
"rhs_parametric") {
351 if (!json.contains(
"data"))
353 if (!json[
"data"].contains(
"rhs_parametric"))
361 else if (attribute ==
"rhs") {
362 if (!json.contains(
"data"))
364 if (!json[
"data"].contains(
"rhs"))
366 rhsFunc_ = gismo::give(gismo::gsFunctionExpr<T>(
378 std::size_t patch = p.first;
380 for (
auto & bc : p.second) {
381 auto side =
static_cast<gismo::boundary::side
>(bc.first);
383 bc_.addCondition(patch,
side, bc.second.type, bc.second.function, 0, bc.second.isParametric);
395 nlohmann::json
eval(
const std::string &patch,
const std::string &component,
396 const nlohmann::json &json)
const override {
401 patchIndex = stoi(patch);
404 return R
"({ INVALID REQUEST })"_json;
407 if (component ==
"Solution" || component ==
"Rhs") {
409 nlohmann::json result;
412 result[
"degrees"] = nlohmann::json::array();
414 for (std::size_t i = 0; i <
Base::solution_.patch(patchIndex).parDim(); ++i)
418 result[
"ncoeffs"] = nlohmann::json::array();
421 dynamic_cast<const gismo::gsBSpline<T> *
>(&
Base::solution_.patch(patchIndex)))
422 for (std::size_t i = 0; i < bspline->parDim(); ++i)
423 result[
"ncoeffs"].push_back(bspline->basis().size(i));
424 else if (
auto bspline =
dynamic_cast<const gismo::gsTensorBSpline<d, T> *
>(
426 for (std::size_t i = 0; i < bspline->parDim(); ++i)
427 result[
"ncoeffs"].push_back(bspline->basis().size(i));
429 return R
"({ INVALID REQUEST })"_json;
432 result[
"nknots"] = nlohmann::json::array();
435 dynamic_cast<const gismo::gsBSpline<T> *
>(&
Base::solution_.patch(patchIndex)))
436 for (std::size_t i = 0; i < bspline->parDim(); ++i)
437 result[
"nknots"].push_back(bspline->knots(i).size());
438 else if (
auto bspline =
dynamic_cast<const gismo::gsTensorBSpline<d, T> *
>(
440 for (std::size_t i = 0; i < bspline->parDim(); ++i)
441 result[
"nknots"].push_back(bspline->knots(i).size());
443 return R
"({ INVALID REQUEST })"_json;
446 result[
"knots"] = nlohmann::json::array();
449 dynamic_cast<const gismo::gsBSpline<T> *
>(&
Base::solution_.patch(patchIndex)))
450 for (std::size_t i = 0; i < bspline->parDim(); ++i)
451 result[
"knots"].push_back(bspline->knots(i));
452 else if (
auto bspline =
dynamic_cast<const gismo::gsTensorBSpline<d, T> *
>(
454 for (std::size_t i = 0; i < bspline->parDim(); ++i)
455 result[
"knots"].push_back(bspline->knots(i));
457 return R
"({ INVALID REQUEST })"_json;
460 if (component ==
"Solution") {
465 auto pts =
rhsFunc_.eval(basis.anchors());
466 auto rhs = basis.interpolateAtAnchors(pts);
471 auto pts =
rhsFunc_.eval(basis.anchors());
472 auto rhs = basis.interpolateAtAnchors(pts);
485 void elevate(
const nlohmann::json &json = NULL)
override {
487 bool geometry =
true;
489 if (json.contains(
"data"))
490 if (json[
"data"].contains(
"num"))
491 geometry = json[
"data"][
"geometry"].get<
bool>();
501 int num(1), dim(-1), patchIndex(-1);
503 if (json.contains(
"data")) {
504 if (json[
"data"].contains(
"num"))
505 num = json[
"data"][
"num"].get<
int>();
507 if (json[
"data"].contains(
"dim"))
508 dim = json[
"data"][
"dim"].get<int>();
510 if (json[
"data"].contains(
"patch"))
511 patchIndex = json[
"data"][
"patch"].get<int>();
515 if (patchIndex == -1)
516 basis_.degreeElevate(num, dim);
518 basis_.basis(patchIndex).degreeElevate(num, dim);
528 void increase(
const nlohmann::json &json = NULL)
override {
530 bool geometry =
true;
532 if (json.contains(
"data"))
533 if (json[
"data"].contains(
"num"))
534 geometry = json[
"data"][
"geometry"].get<
bool>();
544 int num(1), dim(-1), patchIndex(-1);
546 if (json.contains(
"data")) {
547 if (json[
"data"].contains(
"num"))
548 num = json[
"data"][
"num"].get<
int>();
550 if (json[
"data"].contains(
"dim"))
551 dim = json[
"data"][
"dim"].get<int>();
553 if (json[
"data"].contains(
"patch"))
554 patchIndex = json[
"data"][
"patch"].get<int>();
558 if (patchIndex == -1)
559 basis_.degreeIncrease(num, dim);
561 basis_.basis(patchIndex).degreeIncrease(num, dim);
571 void refine(
const nlohmann::json &json = NULL)
override {
573 bool geometry =
true;
575 if (json.contains(
"data"))
576 if (json[
"data"].contains(
"num"))
577 geometry = json[
"data"][
"geometry"].get<
bool>();
587 int num(1), dim(-1), patchIndex(-1);
589 if (json.contains(
"data")) {
590 if (json[
"data"].contains(
"num"))
591 num = json[
"data"][
"num"].get<
int>();
593 if (json[
"data"].contains(
"dim"))
594 dim = json[
"data"][
"dim"].get<int>();
596 if (json[
"data"].contains(
"patch"))
597 patchIndex = json[
"data"][
"patch"].get<int>();
601 if (patchIndex == -1)
602 basis_.uniformRefine(num, 1, dim);
604 basis_.basis(patchIndex).uniformRefine(num, 1, dim);
614 void addPatch(
const nlohmann::json &json = NULL)
override {
622 throw std::runtime_error(
"Adding patches is not yet implemented in G+Smo");
630 const nlohmann::json &json = NULL)
override {
645 for (
auto const &bdr :
Base::geo_.boundaries()) {
646 auto patch = bdr.patch;
647 auto side = bdr.side();
648 auto bc =
bcMap_[patch][
side] = { gismo::gsFunctionExpr<T>(
"0", d),
649 gismo::condition_type::dirichlet,
657 for (
auto const & p :
bcMap_) {
658 std::size_t patch = p.first;
660 for (
auto const & bc : p.second) {
661 auto side =
static_cast<gismo::boundary::side
>(bc.first);
663 bc_.addCondition(patch,
side, bc.second.type, bc.second.function, 0, bc.second.isParametric);
673 patchIndex = stoi(patch);
virtual void addPatch(const nlohmann::json &json)=0
Adds a patch to a model.
virtual void elevate(const nlohmann::json &json)=0
Elevates the model's degrees, preserves smoothness.
virtual nlohmann::json eval(const std::string &patch, const std::string &component, const nlohmann::json &json) const =0
Evaluates model.
virtual nlohmann::json getOutputs() const =0
Returns the model's outputs.
virtual nlohmann::json updateAttribute(const std::string &patch, const std::string &component, const std::string &attribute, const nlohmann::json &json)
Updates the attributes of the model.
Definition model.hpp:297
virtual void increase(const nlohmann::json &json)=0
Increases the model's degrees, preserves multiplicity.
virtual void refine(const nlohmann::json &json)=0
Refines model.
virtual void removePatch(const std::string &patch, const nlohmann::json &json)=0
Adds a patch to a model.
gismo::gsMultiPatch< T > geo_
Multi-patch geometry.
Definition GismoGeometryModel.hpp:39
G+Smo PDE model.
Definition GismoPdeModel.hpp:58
gismo::gsMultiPatch< T > solution_
Solution.
Definition GismoPdeModel.hpp:190
G+Smo Poisson model.
Definition GismoPoissonModel.hpp:27
~GismoPoissonModel()
Destructor.
Definition GismoPoissonModel.hpp:172
void refine(const nlohmann::json &json=NULL) override
Refines the model.
Definition GismoPoissonModel.hpp:571
typename gismo::gsExprAssembler< T >::solution solution_type
Type of the solution.
Definition GismoPoissonModel.hpp:45
void elevate(const nlohmann::json &json=NULL) override
Elevates the model's degrees, preserves smoothness.
Definition GismoPoissonModel.hpp:485
gismo::gsExprAssembler< T > assembler_
Expression assembler.
Definition GismoPoissonModel.hpp:64
void addPatch(const nlohmann::json &json=NULL) override
Add new patch to the model.
Definition GismoPoissonModel.hpp:614
gismo::gsBoundaryConditions< T > bc_
Boundary conditions.
Definition GismoPoissonModel.hpp:51
GismoPoissonModel()=delete
Default constructor.
void removePatch(const std::string &patch, const nlohmann::json &json=NULL) override
Remove existing patch from the model.
Definition GismoPoissonModel.hpp:629
typename gismo::gsExprAssembler< T >::space space_type
Type of the function space.
Definition GismoPoissonModel.hpp:42
nlohmann::json eval(const std::string &patch, const std::string &component, const nlohmann::json &json) const override
Evaluates the model.
Definition GismoPoissonModel.hpp:395
nlohmann::json getParameters() const override
Returns the model's parameters.
Definition GismoPoissonModel.hpp:201
void increase(const nlohmann::json &json=NULL) override
Increases the model's degrees, preserves multiplicity.
Definition GismoPoissonModel.hpp:528
gismo::gsFunctionExpr< T > rhsFunc_
Right-hand side function.
Definition GismoPoissonModel.hpp:54
gismo::gsMultiBasis< T > basis_
Multi-patch basis.
Definition GismoPoissonModel.hpp:48
void solve()
Solve the Poisson problem.
Definition GismoPoissonModel.hpp:67
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 GismoPoissonModel.hpp:278
bool rhsFuncParametric_
Right-hand side function defined on parametric domain (default false)
Definition GismoPoissonModel.hpp:58
typename gismo::gsExprAssembler< T >::geometryMap geometryMap_type
Type of the geometry mapping.
Definition GismoPoissonModel.hpp:36
std::string getDescription() const override
Returns the model's description.
Definition GismoPoissonModel.hpp:180
GismoPoissonModel(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 GismoPoissonModel.hpp:123
std::string getName() const override
Returns the model's name.
Definition GismoPoissonModel.hpp:175
nlohmann::json getOutputs() const override
Returns the model's outputs.
Definition GismoPoissonModel.hpp:185
GismoBoundaryConditionMap< T > bcMap_
Boundary condition look-up table.
Definition GismoPoissonModel.hpp:61
typename gismo::gsExprAssembler< T >::variable variable_type
Type of the variable.
Definition GismoPoissonModel.hpp:39
auto to_json(const torch::TensorAccessor< T, N > &accessor)
Converts a torch::TensorAccessor object to a JSON object.
Definition serialize.hpp:41
degree
Enumerator for specifying the degree of B-splines.
Definition BSplineModel.hpp:23
std::map< int, std::map< int, GismoBoundaryCondition< T > > > GismoBoundaryConditionMap
G+Smo boundary condition look-up table.
Definition GismoPdeModel.hpp:39
Definition boundary.hpp:22
side
Identifiers for topological sides.
Definition boundary.hpp:25
InvalidModelAttribute exception.
Definition model.hpp:42