23 template<
short_t d,
typename T>
28 options.
addInt(
"Verbose",
"Print output level", 0);
31 options.
addInt(
"InitialMethod",
"Initialization method", 0);
34 options.
addInt(
"ParamMethod",
"Parameterization method", 0);
37 options.
addReal(
"ff_Delta",
"Delta for foldover-free optimization", 0.05);
38 options.
addInt(
"ff_MaxIterations",
39 "Max iterations for quality improvement",
41 options.
addReal(
"ff_MinGradientLength",
42 "Min gradient length for foldover-free optimization",
44 options.
addReal(
"ff_MinStepLength",
45 "Min step length for foldover-free optimization",
49 options.
addInt(
"qi_MaxIterations",
50 "Max iterations for quality improvement",
52 options.
addReal(
"qi_MinGradientLength",
53 "Min gradient length for quality improvement",
55 options.
addReal(
"qi_MinStepLength",
56 "Min step length for quality improvement",
61 "Quadrature points: quA*deg + quB; For patchRule: Order of target space",
64 "Quadrature points: quA*deg + quB; For patchRule: Regularity of target space",
67 "Quadrature rule [1:GaussLegendre,2:GaussLobatto,3:PatchRule]",
69 options.
addInt(
"overInt",
"Apply over-integration?", 0);
72 options.
addInt(
"AAPreconditionType",
"Preconditioner type for AA", 0);
75 options.
addInt(
"N_update",
"update preconditioner every N_update steps", 10);
78 options.
addInt(
"AAwindowsize",
"window size for preconditioned AA solver", 5);
81 options.
addSwitch(
"needPDEH1",
"improve quality by H1 discrezation?",
true);
87 template<
short_t d,
typename T>
89 return computeAreaInterior(mp);
93 template<
short_t d,
typename T>
105 geometryMap geometry = evaluator.
getMap(multiPatch);
113 template<
short_t d,
typename T>
119 enum class ParamMethod {
124 VariationalHarmonicPatch,
128 template<
short_t d,
typename T>
135 method =
static_cast<ParamMethod
>(options.
askInt(
"ParamMethod", 0));
138 case ParamMethod::PenaltyPatch: {
139 #ifdef gsHLBFGS_ENABLED
140 result = computePenaltyPatch(mp, mapper, options);
142 GISMO_ERROR(
"PenaltyPatch not available without gsHLBFGS. Please "
143 "compile with gsHLBGFS enabled");
147 case ParamMethod::PenaltyPatch2: {
148 #ifdef gsHLBFGS_ENABLED
149 result = computePenaltyPatch2(mp, mapper, options);
151 GISMO_ERROR(
"PenaltyPatch2 not available without gsHLBFGS. Please "
152 "compile with gsHLBGFS enabled");
156 case ParamMethod::BarrierPatch: {
157 #ifdef gsHLBFGS_ENABLED
158 result = computeBarrierPatch(mp, mapper, options);
160 GISMO_ERROR(
"BarrierPatch not available without gsHLBFGS. Please "
161 "compile with gsHLBGFS enabled");
165 case ParamMethod::VariationalHarmonicPatch: {
166 #ifdef gsHLBFGS_ENABLED
167 result = computeVHPatch(mp, mapper, options);
169 GISMO_ERROR(
"VHPatch not available without gsHLBFGS. Please "
170 "compile with gsHLBGFS enabled");
174 case ParamMethod::PDEPatch:
176 if (method != ParamMethod::PDEPatch) {
177 gsWarn <<
"Invalid ParamMethod value. Defaulting to PDEPatch.\n";
179 result = computePDEPatch(mp, mapper, options);
186 #ifdef gsHLBFGS_ENABLED
188 template<
short_t d,
typename T>
194 verboseLog(
"Start variational harmonic parameterization construction...",
195 options.
askInt(
"Verbose", 0));
200 gsObjVHPt<d, T> objVHPt(mp, mapper);
201 objVHPt.applyOptions(options);
203 gsHLBFGS<T> optimizer(&objVHPt);
204 setOptimizerOptions<T>(optimizer, options);
206 optimizer.solve(initialGuessVector);
208 convertFreeVectorToMultiPatch<T>(optimizer.currentDesign(), mapper, result);
215 template<
short_t d,
typename T>
218 const gsDofMapper &mapper,
219 const gsOptionList &options) {
221 verboseLog(
"Start penalty function-based parameterization construction...",
222 options.askInt(
"Verbose", 0));
225 T scaledArea = computeAreaInterior(mp);
230 gsObjPenaltyPt<d, T> objPenaltyPt(mp, mapper);
231 gsOptionList thisOptions = options;
232 thisOptions.addReal(
"qi_lambda1",
"Sets the lambda_1 value for Emips", 1.0);
233 thisOptions.addReal(
"qi_lambda2",
234 "Sets the lambda 2 value for Eunif",
235 1.0 / pow(scaledArea, 2));
236 objPenaltyPt.applyOptions(thisOptions);
238 gsHLBFGS<T> optimizer(&objPenaltyPt);
239 setOptimizerOptions<T>(optimizer, options);
241 optimizer.solve(initialGuessVector);
242 gsMultiPatch<T> result = mp;
243 convertFreeVectorToMultiPatch<T>(optimizer.currentDesign(), mapper, result);
245 verboseLog(
"Finished!", options.askInt(
"Verbose", 0));
250 template<
short_t d,
typename T>
253 const gsDofMapper &mapper,
254 const gsOptionList &options) {
256 verboseLog(
"Penalty function-based (2) parameterization construction ...",
257 options.askInt(
"Verbose", 0));
260 T scaledArea = computeAreaInterior(mp);
265 gsObjPenaltyPt2<d, T> objPenaltyPt(mp, mapper);
266 objPenaltyPt.setEps(options.askReal(
"penaltyFactor", 0.01) * scaledArea);
268 gsOptionList thisOptions = options;
269 thisOptions.addReal(
"qi_lambda1",
"Sets the lambda_1 value for Emips", 1.0);
270 thisOptions.addReal(
"qi_lambda2",
271 "Sets the lambda 2 value for Eunif",
272 1.0 / pow(scaledArea, 2));
273 objPenaltyPt.applyOptions(thisOptions);
275 gsHLBFGS<T> optimizer(&objPenaltyPt);
276 setOptimizerOptions<T>(optimizer, options);
278 optimizer.solve(initialGuessVector);
279 gsMultiPatch<T> result = mp;
280 convertFreeVectorToMultiPatch<T>(optimizer.currentDesign(), mapper, result);
282 verboseLog(
"Finished!", options.askInt(
"Verbose", 0));
287 template<
short_t d,
typename T>
290 const gsDofMapper &mapper,
291 const gsOptionList &options) {
294 T scaledArea = computeAreaInterior(mp);
300 foldoverElimination(mp, mapper, initialGuessVector, scaledArea, options);
303 qualityImprovement(mp, mapper, initialGuessVector, scaledArea, options);
306 gsMultiPatch<T> result = mp;
312 template<
short_t d,
typename T>
313 void gsBarrierCore<d, T>::foldoverElimination(
const gsMultiPatch<T> &mp,
314 const gsDofMapper &mapper,
315 gsVector<T> &initialGuessVector,
317 const gsOptionList &options) {
319 verboseLog(
"Start foldover elimination step...",
320 options.askInt(
"Verbose", 0));
321 constexpr T EPSILON = 1e-20;
322 constexpr
int MAX_ITER = 10;
323 gsObjFoldoverFree<d, T> objFoldoverFree(mp, mapper);
324 objFoldoverFree.addOptions(options);
326 gsHLBFGS<T> optFoldoverFree(&objFoldoverFree);
327 optFoldoverFree.options().setInt(
"MaxIterations",
328 options.askInt(
"ff_MaxIterations", 1e4));
329 optFoldoverFree.options().setReal(
"MinGradientLength",
330 options.askReal(
"ff_MinGradientLength",
332 optFoldoverFree.options().setReal(
"MinStepLength",
333 options.askReal(
"ff_MinStepLength", 1e-12));
334 optFoldoverFree.options().setInt(
"Verbose", options.askInt(
"Verbose", 0));
336 T Efoldover = std::numeric_limits<T>::max();
337 for (
index_t it = 0; it < MAX_ITER; ++it) {
338 T delta = pow(0.1, it) * 5e-2 * scaledArea;
339 objFoldoverFree.setDelta(delta);
341 optFoldoverFree.solve(initialGuessVector);
343 Efoldover = optFoldoverFree.objective();
344 initialGuessVector = optFoldoverFree.currentDesign();
346 if (Efoldover <= EPSILON) {
break; }
349 if (Efoldover > EPSILON) {
350 throw std::runtime_error(
351 "Maximum iterations reached. The foldover-energy value is " +
353 ". This suggests there may be issues with the input data.");
357 template<
short_t d,
typename T>
358 void gsBarrierCore<d, T>::qualityImprovement(
const gsMultiPatch<T> &mp,
359 const gsDofMapper &mapper,
360 gsVector<T> &initialGuessVector,
362 const gsOptionList &options) {
363 verboseLog(
"Start parameterization quality improvement step...",
364 options.askInt(
"Verbose", 0));
365 gsObjQualityImprovePt<d, T> objQualityImprovePt(mp, mapper);
367 gsOptionList thisOptions = options;
368 thisOptions.addReal(
"qi_lambda1",
"Sets the lambda_1 value for Emips", 1.0);
369 thisOptions.addReal(
"qi_lambda2",
370 "Sets the lambda 2 value for Eunif",
371 1.0 / pow(scaledArea, 2));
372 objQualityImprovePt.applyOptions(thisOptions);
374 gsHLBFGS<T> optQualityImprovePt(&objQualityImprovePt);
375 setOptimizerOptions<T>(optQualityImprovePt, options);
377 optQualityImprovePt.solve(initialGuessVector);
378 initialGuessVector = optQualityImprovePt.currentDesign();
381 template<
short_t d,
typename T>
382 gsObjFoldoverFree<d, T>::gsObjFoldoverFree(
const gsMultiPatch<T> &patches,
386 m_mapper(std::move(mapper)),
389 m_assembler.setIntegrationElements(m_mb);
390 m_evaluator = gsExprEvaluator<T>(m_assembler);
393 template<
short_t d,
typename T>
394 void gsObjFoldoverFree<d, T>::defaultOptions() {
396 m_options.addReal(
"ff_Delta",
"Sets the delta value", 1e-2);
399 template<
short_t d,
typename T>
400 void gsObjFoldoverFree<d, T>::addOptions(
const gsOptionList &options) {
401 m_options.update(options, gsOptionList::addIfUnknown);
404 template<
short_t d,
typename T>
405 void gsObjFoldoverFree<d, T>::applyOptions(
const gsOptionList &options) {
406 m_eps = m_options.getReal(
"ff_Delta");
407 m_evaluator.options().update(m_options, gsOptionList::addIfUnknown);
410 template<
short_t d,
typename T>
411 T gsObjFoldoverFree<d, T>::evalObj(
const gsAsConstVector<T> &u)
const {
412 convertFreeVectorToMultiPatch<T>(u, m_mapper, m_mp);
413 geometryMap G = m_evaluator.getMap(m_mp);
415 auto EfoldoverFree = (m_eps -
jac(G).det()).ppartval();
416 return m_evaluator.integral(EfoldoverFree);
419 template<
short_t d,
typename T>
420 void gsObjFoldoverFree<d, T>::gradObj_into(
const gsAsConstVector<T> &u,
421 gsAsVector<T> &result)
const {
422 convertFreeVectorToMultiPatch<T>(u, m_mapper, m_mp);
423 geometryMap G = m_assembler.getMap(m_mp);
426 space space1 = m_assembler.getSpace(m_mb, d);
427 space1.setupMapper(m_mapper);
430 auto derJacDet = frprod2(space1,
jac(G).tr().adj());
432 gsConstantFunction<T> zeroFunc(gsVector<T>::Zero(d), d);
433 auto zeroVar = m_evaluator.getVariable(zeroFunc);
435 auto Eder =
ternary(m_eps -
jac(G).det(), -derJacDet, space1 * zeroVar);
437 m_assembler.initSystem();
438 m_assembler.assemble(Eder);
440 result.resize(m_assembler.rhs().rows());
442 m_assembler.rhs().data() + m_assembler.rhs().rows(),
446 template<
short_t d,
typename T>
447 gsObjQualityImprovePt<d, T>::gsObjQualityImprovePt(
448 const gsMultiPatch<T> &patches,
452 m_mapper(std::move(mapper)),
454 m_assembler.setIntegrationElements(m_mb);
455 m_evaluator = gsExprEvaluator<T>(m_assembler);
459 template<
short_t d,
typename T>
460 void gsObjQualityImprovePt<d, T>::defaultOptions() {
462 m_options.addReal(
"qi_lambda1",
"Sets the lambda 1 value", 1.0);
463 m_options.addReal(
"qi_lambda2",
"Sets the lambda 2 value", 1.0);
466 template<
short_t d,
typename T>
467 void gsObjQualityImprovePt<d, T>::addOptions(
const gsOptionList &options) {
468 m_options.update(options, gsOptionList::addIfUnknown);
471 template<
short_t d,
typename T>
472 void gsObjQualityImprovePt<d, T>::applyOptions(
const gsOptionList &options) {
473 m_options.update(options, gsOptionList::addIfUnknown);
474 m_lambda1 = m_options.getReal(
"qi_lambda1");
475 m_lambda2 = m_options.getReal(
"qi_lambda2");
476 m_evaluator.options().update(m_options, gsOptionList::addIfUnknown);
479 template<
short_t d,
typename T>
480 T gsObjQualityImprovePt<d, T>::evalObj(
const gsAsConstVector<T> &u)
const {
481 return evalObj_impl<d>(u);
484 template<
short_t d,
typename T>
486 typename std::enable_if<_d == 2, T>::type
487 gsObjQualityImprovePt<d, T>::evalObj_impl(
const gsAsConstVector<T> &u)
const {
488 convertFreeVectorToMultiPatch<T>(u, m_mapper, m_mp);
489 geometryMap G = m_evaluator.getMap(m_mp);
491 if (m_evaluator.min(
jac(G).det()) < 0) {
492 return std::numeric_limits<T>::max();
494 auto Ewinslow =
jac(G).sqNorm() /
jac(G).det();
495 auto Euniform = pow(
jac(G).det(), 2);
497 return m_evaluator.integral(m_lambda1 * Ewinslow + m_lambda2 * Euniform);
501 template<
short_t d,
typename T>
503 typename std::enable_if<_d == 3, T>::type
504 gsObjQualityImprovePt<d, T>::evalObj_impl(
const gsAsConstVector<T> &u)
const {
506 convertFreeVectorToMultiPatch<T>(u, m_mapper, m_mp);
508 geometryMap G = m_evaluator.getMap(m_mp);
510 if (m_evaluator.min(
jac(G).det()) < 0) {
511 return std::numeric_limits<T>::max();
513 auto Euniform = pow(
jac(G).det(), 2);
514 auto Ewinslow = 0.5 * (
jac(G).sqNorm() *
jac(G).inv().sqNorm());
519 return m_evaluator.integral(m_lambda1 * Ewinslow + m_lambda2 * Euniform);
523 template<
short_t d,
typename T>
524 void gsObjQualityImprovePt<d, T>::gradObj_into(
const gsAsConstVector<T> &u,
525 gsAsVector<T> &result)
const {
526 gradObj_into_impl<d>(u, result);
529 template<
short_t d,
typename T>
531 typename std::enable_if<_d == 2, T>::type
532 gsObjQualityImprovePt<d, T>::gradObj_into_impl(
const gsAsConstVector<T> &u,
533 gsAsVector<T> &result)
const {
534 convertFreeVectorToMultiPatch<T>(u, m_mapper, m_mp);
536 geometryMap G = m_assembler.getMap(m_mp);
538 space space1 = m_assembler.getSpace(m_mb, d);
539 space1.setupMapper(m_mapper);
542 auto derJacDet = frprod2(space1,
jac(G).tr().adj());
544 auto Ewinslow =
jac(G).sqNorm() /
jac(G).det();
545 auto derEwinslow = 2.0 /
jac(G).det() * (frprod2(space1,
jac(G))) -
546 Ewinslow.val() /
jac(G).det() * derJacDet;
547 auto derEuniform = 2.0 *
jac(G).det() * derJacDet;
549 m_assembler.initSystem();
550 m_assembler.assemble(m_lambda1 * derEwinslow + m_lambda2 * derEuniform);
551 result = gsAsVector<T>(
const_cast<T *
>(m_assembler.rhs().data()),
552 m_assembler.rhs().rows());
556 template<
short_t d,
typename T>
558 typename std::enable_if<_d == 3, T>::type
559 gsObjQualityImprovePt<d, T>::gradObj_into_impl(
const gsAsConstVector<T> &u,
560 gsAsVector<T> &result)
const {
561 convertFreeVectorToMultiPatch<T>(u, m_mapper, m_mp);
562 geometryMap G = m_assembler.getMap(m_mp);
564 space space1 = m_assembler.getSpace(m_mb, d);
565 space1.setupMapper(m_mapper);
568 auto derJacDet = frprod2(space1,
jac(G).tr().adj());
570 auto derEwinslow = frprod2(space1, (
jac(G).inv().sqNorm() *
jac(G) -
jac(G)
571 .sqNorm() * (
jac(G).tr() *
jac(G) *
jac(G).tr()).inv()));
578 auto derEuniform = 2.0 *
jac(G).det() * derJacDet;
580 m_assembler.initSystem();
581 m_assembler.assemble(m_lambda1 * derEwinslow + m_lambda2 * derEuniform);
582 result = gsAsVector<T>(
const_cast<T *
>(m_assembler.rhs().data()),
583 m_assembler.rhs().rows());
587 template<
short_t d,
typename T>
588 gsObjVHPt<d, T>::gsObjVHPt(
const gsMultiPatch<T> &patches,
592 m_mapper(std::move(mapper)),
595 m_assembler.setIntegrationElements(m_mb);
596 m_evaluator = gsExprEvaluator<T>(m_assembler);
599 template<
short_t d,
typename T>
600 void gsObjVHPt<d, T>::defaultOptions() {
602 m_options.addReal(
"qi_lambda1",
"Sets the lambda 1 value", 1.0);
603 m_options.addReal(
"qi_lambda2",
"Sets the lambda 2 value", 1.0);
606 template<
short_t d,
typename T>
607 void gsObjVHPt<d, T>::addOptions(
const gsOptionList &options) {
608 m_options.update(options, gsOptionList::addIfUnknown);
611 template<
short_t d,
typename T>
612 void gsObjVHPt<d, T>::applyOptions(
const gsOptionList &options) {
613 m_options.update(options, gsOptionList::addIfUnknown);
614 m_evaluator.options().update(m_options, gsOptionList::addIfUnknown);
617 template<
short_t d,
typename T>
618 T gsObjVHPt<d, T>::evalObj(
const gsAsConstVector<T> &u)
const {
619 return evalObj_impl<d>(u);
622 template<
short_t d,
typename T>
624 typename std::enable_if<_d == 2, T>::type
625 gsObjVHPt<d, T>::evalObj_impl(
const gsAsConstVector<T> &u)
const {
627 convertFreeVectorToMultiPatch<T>(u, m_mapper, m_mp);
630 geometryMap G = m_evaluator.getMap(m_mp);
633 space space1 = m_assembler.getSpace(m_mb, d);
634 space1.setupMapper(m_mapper);
637 auto metricMat =
jac(G).tr() *
jac(G);
640 auto hessG = hess(G);
643 auto scale = metricMat.trace();
646 auto Lx = hessG % metricMat.adj() / scale.val();
649 auto nonlinearSystem =
frprod3(space1, Lx);
652 m_assembler.initSystem();
653 m_assembler.assemble(nonlinearSystem);
656 gsVector<T> result = gsAsVector<T>(
657 const_cast<T *
>(m_assembler.rhs().data()),
658 m_assembler.rhs().rows());
660 return result.squaredNorm();
663 template<
short_t d,
typename T>
665 typename std::enable_if<_d == 3, T>::type
666 gsObjVHPt<d, T>::evalObj_impl(
const gsAsConstVector<T> &u)
const {
670 template<
short_t d,
typename T>
671 void gsObjVHPt<d, T>::gradObj2_into(
const gsAsConstVector<T> &u,
672 gsAsVector<T> &result)
const {
673 gradObj_into_impl<d>(u, result);
676 template<
short_t d,
typename T>
677 gsObjPenaltyPt<d, T>::gsObjPenaltyPt(
const gsMultiPatch<T> &patches,
681 m_mapper(std::move(mapper)),
684 m_assembler.setIntegrationElements(m_mb);
685 m_evaluator = gsExprEvaluator<T>(m_assembler);
688 template<
short_t d,
typename T>
689 void gsObjPenaltyPt<d, T>::defaultOptions() {
691 m_options.addReal(
"qi_lambda1",
"Sets the lambda 1 value", 1.0);
692 m_options.addReal(
"qi_lambda2",
"Sets the lambda 2 value", 1.0);
695 template<
short_t d,
typename T>
696 void gsObjPenaltyPt<d, T>::addOptions(
const gsOptionList &options) {
697 m_options.update(options, gsOptionList::addIfUnknown);
700 template<
short_t d,
typename T>
701 void gsObjPenaltyPt<d, T>::applyOptions(
const gsOptionList &options) {
702 m_options.update(options, gsOptionList::addIfUnknown);
703 m_lambda1 = m_options.getReal(
"qi_lambda1");
704 m_lambda2 = m_options.getReal(
"qi_lambda2");
705 m_evaluator.options().update(m_options, gsOptionList::addIfUnknown);
708 template<
short_t d,
typename T>
709 T gsObjPenaltyPt<d, T>::evalObj(
const gsAsConstVector<T> &u)
const {
711 convertFreeVectorToMultiPatch<T>(u, m_mapper, m_mp);
714 geometryMap G = m_evaluator.getMap(m_mp);
717 gsConstantFunction<T> eps1(pow(m_eps, 2.0), d);
718 auto eps = m_evaluator.getVariable(eps1);
722 chi = 0.5 * (
jac(G).det() + pow(eps.val() + pow(
jac(G).det(), 2.0), 0.5));
725 auto Ewinslow =
jac(G).sqNorm() / pow(chi, (2.0 / static_cast<T>(d)));
726 auto Euniform = pow(
jac(G).det(), 2.0);
728 return m_evaluator.integral(m_lambda1 * Ewinslow + m_lambda2 * Euniform);
732 template<
short_t d,
typename T>
733 void gsObjPenaltyPt<d, T>::gradObj_into(
const gsAsConstVector<T> &u,
734 gsAsVector<T> &result)
const {
735 gradObj_into_impl<d>(u, result);
738 template<
short_t d,
typename T>
740 typename std::enable_if<_d == 2, T>::type
741 gsObjPenaltyPt<d, T>::gradObj_into_impl(
const gsAsConstVector<T> &u,
742 gsAsVector<T> &result)
const {
745 convertFreeVectorToMultiPatch<T>(u, m_mapper, m_mp);
748 geometryMap G = m_assembler.getMap(m_mp);
749 space space1 = m_assembler.getSpace(m_mb, d);
750 space1.setupMapper(m_mapper);
753 auto derJacDet =
jac(space1) %
jac(G).tr().adj();
756 gsConstantFunction<T> eps1(pow(m_eps, 2.0), d);
757 gsConstantFunction<T> unit1(1.0, d);
758 auto eps = m_evaluator.getVariable(eps1);
759 auto unit = m_evaluator.getVariable(unit1);
762 auto commonTerm = pow(eps.val() + pow(
jac(G).det(), 2.0), 0.5);
763 auto chi = 0.5 * (
jac(G).det() + commonTerm);
764 auto chip = 0.5 * (unit.val() +
jac(G).det() / commonTerm);
767 auto Ewinslow =
jac(G).sqNorm() / chi;
770 auto derEwinslow = 1.0 / chi * (2.0 * frprod2(space1,
jac(G)) -
771 Ewinslow.val() * chip * derJacDet);
772 auto derEuniform = 2.0 *
jac(G).det() * derJacDet;
775 m_assembler.initSystem();
776 m_assembler.assemble(m_lambda1 * derEwinslow + m_lambda2 * derEuniform);
779 result = gsAsVector<T>(
const_cast<T *
>(m_assembler.rhs().data()),
780 m_assembler.rhs().rows());
785 template<
short_t d,
typename T>
787 typename std::enable_if<_d == 3, T>::type
788 gsObjPenaltyPt<d, T>::gradObj_into_impl(
const gsAsConstVector<T> &u,
789 gsAsVector<T> &result)
const {
790 const T twoThirds = 2.0 / 3.0;
793 convertFreeVectorToMultiPatch<T>(u, m_mapper, m_mp);
796 geometryMap G = m_assembler.getMap(m_mp);
797 space space1 = m_assembler.getSpace(m_mb, d);
798 space1.setupMapper(m_mapper);
801 auto derJacDet = frprod2(space1,
jac(G).tr().adj());
804 gsConstantFunction<T> eps1(pow(m_eps, 2.0), d);
805 gsConstantFunction<T> unit1(1.0, d);
806 auto eps = m_evaluator.getVariable(eps1);
807 auto unit = m_evaluator.getVariable(unit1);
810 auto commonTerm = pow(eps.val() + pow(
jac(G).det(), 2.0), 0.5);
811 auto chi = 0.5 * (
jac(G).det() + commonTerm);
812 auto chip = 0.5 * (unit.val() +
jac(G).det() / commonTerm);
815 auto Ewinslow =
jac(G).sqNorm() / pow(chi, twoThirds);
818 auto derEwinslow = 2.0 * frprod2(space1,
jac(G)) / pow(chi, twoThirds) -
819 twoThirds * Ewinslow / chi * chip * derJacDet;
820 auto derEuniform = 2.0 *
jac(G).det() * derJacDet;
823 m_assembler.initSystem();
824 m_assembler.assemble(m_lambda1 * derEwinslow + m_lambda2 * derEuniform);
827 result = gsAsVector<T>(
const_cast<T *
>(m_assembler.rhs().data()),
828 m_assembler.rhs().rows());
834 template<
short_t d,
typename T>
835 gsObjPenaltyPt2<d, T>::gsObjPenaltyPt2(
const gsMultiPatch<T> &patches,
839 m_mapper(std::move(mapper)),
842 m_assembler.setIntegrationElements(m_mb);
843 m_evaluator = gsExprEvaluator<T>(m_assembler);
846 template<
short_t d,
typename T>
847 void gsObjPenaltyPt2<d, T>::defaultOptions() {
849 m_options.addReal(
"qi_lambda1",
"Sets the lambda 1 value", 1.0);
850 m_options.addReal(
"qi_lambda2",
"Sets the lambda 2 value", 1.0);
853 template<
short_t d,
typename T>
854 void gsObjPenaltyPt2<d, T>::addOptions(
const gsOptionList &options) {
855 m_options.update(options, gsOptionList::addIfUnknown);
858 template<
short_t d,
typename T>
859 void gsObjPenaltyPt2<d, T>::applyOptions(
const gsOptionList &options) {
860 m_options.update(options, gsOptionList::addIfUnknown);
861 m_lambda1 = m_options.getReal(
"qi_lambda1");
862 m_lambda2 = m_options.getReal(
"qi_lambda2");
863 m_evaluator.options().update(m_options, gsOptionList::addIfUnknown);
866 template<
short_t d,
typename T>
867 T gsObjPenaltyPt2<d, T>::evalObj(
const gsAsConstVector<T> &u)
const {
868 return evalObj_impl<d>(u);
871 template<
short_t d,
typename T>
873 typename std::enable_if<_d == 2, T>::type
874 gsObjPenaltyPt2<d, T>::evalObj_impl(
const gsAsConstVector<T> &u)
const {
876 convertFreeVectorToMultiPatch<T>(u, m_mapper, m_mp);
879 geometryMap G = m_evaluator.getMap(m_mp);
882 gsConstantFunction<T> epsilon(m_eps, d);
883 auto eps = m_evaluator.getVariable(epsilon);
886 auto chiPPart = eps * ((
jac(G).det() - eps.val()).exp());
888 ternary(eps.val() -
jac(G).det(), chiPPart.val(),
jac(G).det().val());
891 auto Ewinslow =
jac(G).sqNorm() / chi;
893 auto Euniform = pow(
jac(G).det(), 2.0);
896 return m_evaluator.integral(m_lambda1 * Ewinslow + m_lambda2 * Euniform);
899 template<
short_t d,
typename T>
901 typename std::enable_if<_d == 3, T>::type
902 gsObjPenaltyPt2<d, T>::evalObj_impl(
const gsAsConstVector<T> &u)
const {
904 convertFreeVectorToMultiPatch<T>(u, m_mapper, m_mp);
907 geometryMap G = m_evaluator.getMap(m_mp);
910 gsConstantFunction<T> epsilon(m_eps, d);
911 auto eps = m_evaluator.getVariable(epsilon);
914 auto chiPPart = eps * ((
jac(G).det() - eps.val()).exp());
916 ternary(eps.val() -
jac(G).det(), chiPPart.val(),
jac(G).det().val());
919 auto Ewinslow = 0.5 * (
jac(G).sqNorm() *
jac(G).inv().sqNorm()) *
920 pow(
jac(G).det(), 2.0) / pow(chi, 2.0);
924 auto Euniform = pow(
jac(G).det(), 2.0);
927 return m_evaluator.integral(m_lambda1 * Ewinslow + m_lambda2 * Euniform);
930 template<
short_t d,
typename T>
931 void gsObjPenaltyPt2<d, T>::gradObj_into(
const gsAsConstVector<T> &u,
932 gsAsVector<T> &result)
const {
933 gradObj_into_impl<d>(u, result);
936 template<
short_t d,
typename T>
938 typename std::enable_if<_d == 2, T>::type
939 gsObjPenaltyPt2<d, T>::gradObj_into_impl(
const gsAsConstVector<T> &u,
940 gsAsVector<T> &result)
const {
942 convertFreeVectorToMultiPatch<T>(u, m_mapper, m_mp);
945 geometryMap G = m_assembler.getMap(m_mp);
948 space spaceMapper = m_assembler.getSpace(m_mb, d);
949 spaceMapper.setupMapper(m_mapper);
952 auto derJacDet = frprod2(spaceMapper,
jac(G).tr().adj());
955 gsConstantFunction<T> epsilon(m_eps, d);
956 gsConstantFunction<T> unity(1.0, d);
959 auto eps = m_evaluator.getVariable(epsilon);
960 auto unit = m_evaluator.getVariable(unity);
963 auto chiPPart = eps * ((
jac(G).det() - eps.val()).exp());
965 ternary(eps.val() -
jac(G).det(), chiPPart.val(),
jac(G).det().val());
966 auto chip =
ternary(eps.val() -
jac(G).det(), chiPPart.val(), unit.val());
969 auto Ewinslow =
jac(G).sqNorm() / chi;
970 auto derEwinslow = 1.0 / chi * (2.0 * frprod2(spaceMapper,
jac(G)) -
971 Ewinslow.val() * chip * derJacDet);
975 auto derEuniform = 2.0 *
jac(G).det() * derJacDet;
978 m_assembler.initSystem();
979 m_assembler.assemble(m_lambda1 * derEwinslow + m_lambda2 * derEuniform);
980 result = gsAsVector<T>(
const_cast<T *
>(m_assembler.rhs().data()),
981 m_assembler.rhs().rows());
987 template<
short_t d,
typename T>
989 typename std::enable_if<_d == 3, T>::type
990 gsObjPenaltyPt2<d, T>::gradObj_into_impl(
const gsAsConstVector<T> &u,
991 gsAsVector<T> &result)
const {
993 convertFreeVectorToMultiPatch<T>(u, m_mapper, m_mp);
996 geometryMap G = m_assembler.getMap(m_mp);
999 space space1 = m_assembler.getSpace(m_mb, d);
1000 space1.setupMapper(m_mapper);
1003 auto derJacDet = frprod2(space1,
jac(G).tr().adj());
1006 gsConstantFunction<T> epsilonFunction(m_eps, d);
1007 gsConstantFunction<T> unityFunction(1.0, d);
1010 auto eps = m_evaluator.getVariable(epsilonFunction);
1011 auto unit = m_evaluator.getVariable(unityFunction);
1014 auto chiPPart = eps * ((
jac(G).det() - eps.val()).exp());
1018 ternary(eps.val() -
jac(G).det(), chiPPart.val(),
jac(G).det().val());
1019 auto chip =
ternary(eps.val() -
jac(G).det(), chiPPart.val(), unit.val());
1022 auto jacFrobNorm2 =
jac(G).sqNorm() *
jac(G).inv().sqNorm();
1023 auto derJacFrob2 = frprod2(space1,
1024 (
jac(G).inv().sqNorm() *
jac(G) -
jac(G).sqNorm()
1025 * (
jac(G).tr() *
jac(G) *
jac(G).tr()).inv()));
1027 auto derEwinslow = derJacFrob2 * pow(
jac(G).det(), 2) / pow(chi, 2)
1028 + jacFrobNorm2 / pow(chi, 2)
1029 * (
jac(G).det() - chip / chi * pow(
jac(G).det(), 2)) * derJacDet;
1031 auto derEuniform = 2.0 *
jac(G).det() * derJacDet;
1034 m_assembler.initSystem();
1035 m_assembler.assemble(m_lambda1 * derEwinslow + m_lambda2 * derEuniform);
1038 result = gsAsVector<T>(
const_cast<T *
>(m_assembler.rhs().data()),
1039 m_assembler.rhs().rows());
1040 return EXIT_SUCCESS;
1044 template<
short_t d,
typename T>
1064 verboseLog(
"PDE-based parameterization construction ...\n",
1065 options.
askInt(
"Verbose", 0));
1075 for (
auto bit = mp.
bBegin(); bit != mp.
bEnd(); ++bit) {
1080 space1.setup(bc, dirichlet::homogeneous, 0);
1083 typedef std::function<gsSparseMatrix<T>(
gsVector<T> const &)> Jacobian_t;
1084 typedef std::function<gsVector<T>(
gsVector<T> const &)> Residual_t;
1087 Residual_t Residual = [&assembler, &mapper, &mpSubstitute, &space1](
1090 convertFreeVectorToMultiPatch<T>(x, mapper, mpSubstitute);
1093 geometryMap G = assembler.
getMap(mpSubstitute);
1096 auto metricMat =
jac(G).tr() *
jac(G);
1097 auto hessG = hess(G);
1100 auto scale = metricMat.trace();
1103 auto Lx = hessG % metricMat.adj() / scale.val();
1106 auto nonlinearSystem =
frprod3(space1, Lx);
1110 assembler.
assemble(nonlinearSystem);
1113 return assembler.
rhs();
1116 Jacobian_t Jacobian;
1117 int preconditionerType = options.
askInt(
"AAPreconditionType", 0);
1118 switch (preconditionerType) {
1120 Jacobian = [&assembler, &mapper, &mpSubstitute, &space1](
gsVector<T> const &x)
1123 convertFreeVectorToMultiPatch<T>(x, mapper, mpSubstitute);
1124 geometryMap G = assembler.
getMap(mpSubstitute);
1130 return assembler.
matrix();
1135 Jacobian = [&assembler, &mapper, &mpSubstitute, &space1](
gsVector<T> const &x)
1138 convertFreeVectorToMultiPatch<T>(x, mapper, mpSubstitute);
1139 geometryMap G = assembler.
getMap(mpSubstitute);
1145 return assembler.
matrix();
1151 Jacobian = [&assembler, &mapper, &mpSubstitute, &space1](
gsVector<T> const &x)
1153 convertFreeVectorToMultiPatch<T>(x, mapper, mpSubstitute);
1154 geometryMap G = assembler.
getMap(mpSubstitute);
1160 return assembler.
matrix();
1165 param.
m = options.
askInt(
"AAwindowsize", 5);
1173 if (options.
askSwitch(
"needPDEH1",
true))
1175 verboseLog(
"\nStart parameterization improvement by H1 discrezation...",options.
askInt(
"Verbose", 0));
1176 Residual = [&assembler, &mapper, &mpSubstitute, &space1](
gsVector<T> const &x)
1179 convertFreeVectorToMultiPatch<T>(x, mapper, mpSubstitute);
1180 geometryMap G = assembler.
getMap(mpSubstitute);
1182 auto invJacMat =
jac(G).inv();
1183 auto jacU =
jac(space1) * invJacMat;
1184 auto nonlinearSystem = jacU % invJacMat;
1187 assembler.
assemble(nonlinearSystem);
1188 return assembler.
rhs();
1191 preconditionerType = options.
askInt(
"AAPreconditionType", 0);
1192 switch (preconditionerType) {
1194 Jacobian = [&assembler, &mapper, &mpSubstitute, &space1](
gsVector<T> const &x)
1197 convertFreeVectorToMultiPatch<T>(x, mapper, mpSubstitute);
1198 geometryMap G = assembler.
getMap(mpSubstitute);
1205 return assembler.
matrix();
1210 Jacobian = [&assembler, &mapper, &mpSubstitute,&space1](
gsVector<T> const &x)
1213 convertFreeVectorToMultiPatch<T>(x, mapper, mpSubstitute);
1214 geometryMap G = assembler.
getMap(mpSubstitute);
1221 return assembler.
matrix();
1226 solVector = AASolver2.
compute(solVector, Residual, Jacobian);
1230 convertFreeVectorToMultiPatch<T>(solVector, mapper, result);
1239 template<
typename E1,
typename E2>
1241 template<
typename E1,
typename E2>
1243 template<
class E0,
class E1,
class E2>
1246 class jacScaledLx_expr;
1248 class jacScaledLxDiag_expr;
1250 class jacScaledLxDiagBlock_expr;
1252 class jacScaledLxH1_expr;
1254 class jacScaledLxH1DiagBlock_expr;
1281 template<
typename E1,
typename E2>
1282 class frprod3_expr :
public _expr<frprod3_expr<E1, E2> > {
1284 typedef typename E2::Scalar Scalar;
1285 enum { ScalarValued = 0, Space = E1::Space, ColBlocks = 0 };
1288 typename E1::Nested_t _u;
1289 typename E2::Nested_t _v;
1291 mutable gsMatrix<Scalar> res, bGrads, b;
1295 frprod3_expr(_expr<E1>
const &u, _expr<E2>
const &v)
1304 const gsMatrix<Scalar> &eval(
const index_t k)
const
1306 auto A = _v.eval(k);
1310 res.noalias() = b * A;
1314 index_t rows()
const {
return 1; }
1315 index_t cols()
const {
return 1; }
1317 void parse(gsExprHelper<Scalar> &evList)
const {
1324 const gsFeSpace<Scalar> &rowVar()
const {
return _u.rowVar(); }
1325 const gsFeSpace<Scalar> &colVar()
const {
return _v.rowVar(); }
1327 void print(std::ostream &os)
const {
1337 template<
typename E1,
typename E2>
1341 return frprod3_expr<E1, E2>(u, M);
1344 template<
class E0,
class E1,
class E2>
1345 class ternary_expr :
public _expr<ternary_expr<E0, E1, E2> > {
1346 typename E0::Nested_t _u;
1347 typename E1::Nested_t _v;
1348 typename E2::Nested_t _w;
1350 typedef typename E1::Scalar Scalar;
1352 explicit ternary_expr(_expr<E0>
const &u,
1359 GISMO_ASSERT(E0::ScalarValued,
"Condition must be scalar valued");
1360 GISMO_ASSERT((
int) E1::ScalarValued == (
int) E2::ScalarValued,
1361 "Both v and w must be scalar valued (or not).");
1362 GISMO_ASSERT((
int) E1::ColBlocks == (
int) E2::ColBlocks,
1363 "Both v and w must be colblocks (or not).");
1365 "Both v and w must be space (or not), but E1::Space = "
1366 << E1::Space <<
" and E2::Space = " << E2::Space);
1368 "Rows of v and w differ. _v.rows() = " << _v.rows()
1372 "Columns of v and w differ. _v.cols() = " << _v.cols()
1375 GISMO_ASSERT(_v.rowVar() == _w.rowVar(),
"rowVar of v and w differ.");
1376 GISMO_ASSERT(_v.colVar() == _w.colVar(),
"colVar of v and w differ.");
1380 ScalarValued = E1::ScalarValued,
1381 ColBlocks = E1::ColBlocks,
1388 const Temporary_t eval(
const index_t k)
const {
1389 return (_u.eval(k) > 0 ? _v.eval(k) : _w.eval(k));
1394 index_t rows()
const {
return _v.rows(); }
1395 index_t cols()
const {
return _v.cols(); }
1396 void parse(gsExprHelper<Scalar> &evList)
const {
1402 const gsFeSpace<Scalar> &rowVar()
const {
return _v.rowVar(); }
1403 const gsFeSpace<Scalar> &colVar()
const {
return _v.colVar(); }
1449 class jacScaledLx_expr :
public _expr<jacScaledLx_expr<E> > {
1451 typedef typename E::Scalar Scalar;
1454 typename E::Nested_t _u;
1455 typename gsGeometryMap<Scalar>::Nested_t _G;
1458 enum { Space = 3, ScalarValued = 0, ColBlocks = 0 };
1460 jacScaledLx_expr(
const E &u,
const gsGeometryMap<Scalar> &G) : _u(u), _G(G) {}
1462 mutable gsMatrix<Scalar> res, derivGeom, deriv2Geom,
derivBasis, deriv2Basis;
1463 mutable gsMatrix<Scalar> dg11dx, dg11dy, dg22dx, dg22dy, dg12dx, dg12dy;
1464 mutable gsMatrix<Scalar> commonTerm, dLxdx, dLxdy, dLydx, dLydy;
1468 const gsMatrix<Scalar> &eval(
const index_t k)
const {
1469 gsMatrix<Scalar> basis = _u.data().values[0].col(k);
1471 derivBasis = _u.data().values[1].col(k).transpose();
1472 deriv2Basis = _u.data().values[2].col(k).transpose();
1475 deriv2Basis.blockTransposeInPlace(1 + _u.dim());
1477 derivGeom = _G.data().values[1].col(k);
1478 deriv2Geom = _G.data().values[2].col(k);
1480 Scalar g11 = derivGeom(0) * derivGeom(0) + derivGeom(2) * derivGeom(2);
1481 Scalar g12 = derivGeom(0) * derivGeom(1) + derivGeom(2) * derivGeom(3);
1482 Scalar g22 = derivGeom(1) * derivGeom(1) + derivGeom(3) * derivGeom(3);
1484 Scalar scaleFactor = g11 + g22;
1487 (g22 * deriv2Geom(0) + g11 * deriv2Geom(1) - 2.0 * g12 * deriv2Geom(2))
1490 (g22 * deriv2Geom(3) + g11 * deriv2Geom(4) - 2.0 * g12 * deriv2Geom(5))
1493 dg11dx.noalias() = 2.0 * derivGeom(0) *
derivBasis.row(0);
1494 dg11dy.noalias() = 2.0 * derivGeom(2) *
derivBasis.row(0);
1495 dg22dx.noalias() = 2.0 * derivGeom(1) *
derivBasis.row(1);
1496 dg22dy.noalias() = 2.0 * derivGeom(3) *
derivBasis.row(1);
1502 commonTerm.noalias() = g22 * deriv2Basis.row(0) + g11 * deriv2Basis.row(1)
1503 - 2.0 * g12 * deriv2Basis.row(2);
1504 dLxdx.noalias() = dg22dx * deriv2Geom(0) + dg11dx * deriv2Geom(1)
1505 - 2.0 * dg12dx * deriv2Geom(2) + commonTerm;
1506 dLxdy.noalias() = dg22dy * deriv2Geom(0) + dg11dy * deriv2Geom(1)
1507 - 2.0 * dg12dy * deriv2Geom(2);
1508 dLydx.noalias() = dg22dx * deriv2Geom(3) + dg11dx * deriv2Geom(4)
1509 - 2.0 * dg12dx * deriv2Geom(5);
1510 dLydy.noalias() = dg22dy * deriv2Geom(3) + dg11dy * deriv2Geom(4)
1511 - 2.0 * dg12dy * deriv2Geom(5) + commonTerm;
1513 dLxdx = (dLxdx - Lx * (dg11dx + dg22dx)) / scaleFactor;
1514 dLxdy = (dLxdy - Lx * (dg11dy + dg22dy)) / scaleFactor;
1515 dLydx = (dLydx - Ly * (dg11dx + dg22dx)) / scaleFactor;
1516 dLydy = (dLydy - Ly * (dg11dy + dg22dy)) / scaleFactor;
1518 const index_t A = _u.cardinality() / _u.dim();
1519 res.resize(_u.cardinality(), _u.cardinality());
1521 res.topLeftCorner(A, A).noalias() = basis * dLxdx;
1522 res.topRightCorner(A, A).noalias() = basis * dLxdy;
1523 res.bottomLeftCorner(A, A).noalias() = basis * dLydx;
1524 res.bottomRightCorner(A, A).noalias() = basis * dLydy;
1529 index_t rows()
const {
return 1; }
1531 index_t cols()
const {
return 1; }
1533 void parse(gsExprHelper<Scalar> &evList)
const {
1541 const gsFeSpace<Scalar> &rowVar()
const {
return _u.rowVar(); }
1542 const gsFeSpace<Scalar> &colVar()
const {
return _u.rowVar(); }
1544 index_t cardinality_impl()
const {
return _u.cardinality_impl(); }
1546 void print(std::ostream &os)
const {
1547 os <<
"jacScaledLx(";
1557 class jacScaledLxDiag_expr :
public _expr<jacScaledLxDiag_expr<E> > {
1559 typedef typename E::Scalar Scalar;
1562 typename E::Nested_t _u;
1563 typename gsGeometryMap<Scalar>::Nested_t _G;
1566 enum { Space = 3, ScalarValued = 0, ColBlocks = 0 };
1568 jacScaledLxDiag_expr(
const E &u,
const gsGeometryMap<Scalar> &G)
1571 mutable gsMatrix<Scalar> res, derivGeom, deriv2Geom,
derivBasis, deriv2Basis;
1572 mutable gsMatrix<Scalar> dg11dx, dg11dy, dg22dx, dg22dy, dg12dx, dg12dy;
1573 mutable gsMatrix<Scalar> commonTerm, dLxdx, dLydy;
1577 const gsMatrix<Scalar> &eval(
const index_t k)
const {
1578 derivBasis = _u.data().values[1].col(k).transpose();
1579 deriv2Basis = _u.data().values[2].col(k).transpose();
1582 deriv2Basis.blockTransposeInPlace(1 + _u.dim());
1584 derivGeom = _G.data().values[1].col(k);
1585 deriv2Geom = _G.data().values[2].col(k);
1587 Scalar g11 = derivGeom(0) * derivGeom(0) + derivGeom(2) * derivGeom(2);
1588 Scalar g12 = derivGeom(0) * derivGeom(1) + derivGeom(2) * derivGeom(3);
1589 Scalar g22 = derivGeom(1) * derivGeom(1) + derivGeom(3) * derivGeom(3);
1591 Scalar scaleFactor = g11 + g22;
1594 (g22 * deriv2Geom(0) + g11 * deriv2Geom(1) - 2.0 * g12 * deriv2Geom(2))
1597 (g22 * deriv2Geom(3) + g11 * deriv2Geom(4) - 2.0 * g12 * deriv2Geom(5))
1600 dg11dx.noalias() = 2.0 * derivGeom(0) *
derivBasis.row(0);
1601 dg11dy.noalias() = 2.0 * derivGeom(2) *
derivBasis.row(0);
1602 dg22dx.noalias() = 2.0 * derivGeom(1) *
derivBasis.row(1);
1603 dg22dy.noalias() = 2.0 * derivGeom(3) *
derivBasis.row(1);
1609 commonTerm.noalias() = g22 * deriv2Basis.row(0) + g11 * deriv2Basis.row(1)
1610 - 2.0 * g12 * deriv2Basis.row(2);
1611 dLxdx.noalias() = dg22dx * deriv2Geom(0) + dg11dx * deriv2Geom(1)
1612 - 2.0 * dg12dx * deriv2Geom(2) + commonTerm;
1613 dLydy.noalias() = dg22dy * deriv2Geom(3) + dg11dy * deriv2Geom(4)
1614 - 2.0 * dg12dy * deriv2Geom(5) + commonTerm;
1616 dLxdx = (dLxdx - Lx * (dg11dx + dg22dx)) / scaleFactor;
1617 dLydy = (dLydy - Ly * (dg11dy + dg22dy)) / scaleFactor;
1619 const index_t A = _u.cardinality() / _u.dim();
1620 res.resize(_u.cardinality(), _u.cardinality());
1622 res.topLeftCorner(A, A) = (_u.data().values[0].col(k).array()
1623 * dLxdx.array()).matrix().asDiagonal();
1624 res.bottomRightCorner(A, A) = (_u.data().values[0].col(k).array()
1625 * dLydy.array()).matrix().asDiagonal();
1630 index_t rows()
const {
return 1; }
1632 index_t cols()
const {
return 1; }
1634 void parse(gsExprHelper<Scalar> &evList)
const {
1642 const gsFeSpace<Scalar> &rowVar()
const {
return _u.rowVar(); }
1643 const gsFeSpace<Scalar> &colVar()
const {
return _u.rowVar(); }
1645 index_t cardinality_impl()
const {
return _u.cardinality_impl(); }
1647 void print(std::ostream &os)
const {
1648 os <<
"jacScaledLxDiag(";
1658 class jacScaledLxDiagBlock_expr :
public _expr<jacScaledLxDiagBlock_expr<E> > {
1660 typedef typename E::Scalar Scalar;
1663 typename E::Nested_t _u;
1664 typename gsGeometryMap<Scalar>::Nested_t _G;
1667 enum { Space = 3, ScalarValued = 0, ColBlocks = 0 };
1669 jacScaledLxDiagBlock_expr(
const E &u,
const gsGeometryMap<Scalar> &G)
1672 mutable gsMatrix<Scalar> res, basis, derivGeom, deriv2Geom,
derivBasis,
1674 mutable gsMatrix<Scalar> dg11dx, dg11dy, dg22dx, dg22dy, dg12dx, dg12dy;
1675 mutable gsMatrix<Scalar> commonTerm, dLxdx, dLydy;
1679 const gsMatrix<Scalar> &eval(
const index_t k)
const {
1682 derivBasis = _u.data().values[1].col(k).transpose();
1683 deriv2Basis = _u.data().values[2].col(k).transpose();
1686 deriv2Basis.blockTransposeInPlace(1 + _u.dim());
1688 derivGeom = _G.data().values[1].col(k);
1689 deriv2Geom = _G.data().values[2].col(k);
1691 Scalar g11 = derivGeom(0) * derivGeom(0) + derivGeom(2) * derivGeom(2);
1692 Scalar g12 = derivGeom(0) * derivGeom(1) + derivGeom(2) * derivGeom(3);
1693 Scalar g22 = derivGeom(1) * derivGeom(1) + derivGeom(3) * derivGeom(3);
1694 Scalar scaleFactor = g11 + g22;
1697 (g22 * deriv2Geom(0) + g11 * deriv2Geom(1) - 2.0 * g12 * deriv2Geom(2))
1700 (g22 * deriv2Geom(3) + g11 * deriv2Geom(4) - 2.0 * g12 * deriv2Geom(5))
1703 dg11dx.noalias() = 2.0 * derivGeom(0) *
derivBasis.row(0);
1704 dg11dy.noalias() = 2.0 * derivGeom(2) *
derivBasis.row(0);
1705 dg22dx.noalias() = 2.0 * derivGeom(1) *
derivBasis.row(1);
1706 dg22dy.noalias() = 2.0 * derivGeom(3) *
derivBasis.row(1);
1712 commonTerm.noalias() = g22 * deriv2Basis.row(0) + g11 * deriv2Basis.row(1)
1713 - 2.0 * g12 * deriv2Basis.row(2);
1714 dLxdx.noalias() = dg22dx * deriv2Geom(0) + dg11dx * deriv2Geom(1)
1715 - 2.0 * dg12dx * deriv2Geom(2) + commonTerm;
1716 dLydy.noalias() = dg22dy * deriv2Geom(3) + dg11dy * deriv2Geom(4)
1717 - 2.0 * dg12dy * deriv2Geom(5) + commonTerm;
1719 dLxdx = (dLxdx - Lx * (dg11dx + dg22dx)) / scaleFactor;
1720 dLydy = (dLydy - Ly * (dg11dy + dg22dy)) / scaleFactor;
1722 const index_t A = _u.cardinality() / _u.dim();
1723 res.resize(_u.cardinality(), _u.cardinality());
1725 res.topLeftCorner(A, A).noalias() =
1726 _u.data().values[0].col(k) * dLxdx;
1727 res.bottomRightCorner(A, A).noalias() =
1728 _u.data().values[0].col(k) * dLydy;
1733 index_t rows()
const {
return 1; }
1735 index_t cols()
const {
return 1; }
1737 void parse(gsExprHelper<Scalar> &evList)
const {
1745 const gsFeSpace<Scalar> &rowVar()
const {
return _u.rowVar(); }
1746 const gsFeSpace<Scalar> &colVar()
const {
return _u.rowVar(); }
1748 index_t cardinality_impl()
const {
return _u.cardinality_impl(); }
1750 void print(std::ostream &os)
const {
1751 os <<
"jacScaledLxDiagBlock(";
1761 class jacScaledLxH1_expr :
public _expr<jacScaledLxH1_expr<E> > {
1763 typedef typename E::Scalar Scalar;
1766 typename E::Nested_t _u;
1767 typename gsGeometryMap<Scalar>::Nested_t _G;
1770 enum { Space = 3, ScalarValued = 0, ColBlocks = 0 };
1772 jacScaledLxH1_expr(
const E &u,
const gsGeometryMap<Scalar> &G)
1779 const gsMatrix<Scalar> &eval(
const index_t k)
const {
1780 gsMatrix<Scalar> jacMat = _G.data().values[1].reshapeCol(k,
1781 _G.data().dim.first,
1782 _G.data().dim.second);
1783 gsMatrix<Scalar> invJacMat = jacMat.inverse();
1785 derivBasis = _u.data().values[1].col(k).transpose();
1787 gsMatrix<Scalar> invJacHatG;
1788 invJacHatG.noalias() = invJacMat *
derivBasis;
1790 const index_t N = _u.cardinality() / _u.dim();
1791 gsMatrix<Scalar> jacdLxdx(N, N);
1792 gsMatrix<Scalar> jacdLxdy(N, N);
1793 gsMatrix<Scalar> jacdLydx(N, N);
1794 gsMatrix<Scalar> jacdLydy(N, N);
1796 gsMatrix<> temp(2, N);
1797 for (
auto i = 0; i < N; ++i) {
1799 temp.row(0).noalias() = invJacHatG(0, i) * invJacHatG.row(0);
1800 temp.row(1).noalias() = invJacHatG(1, i) * invJacHatG.row(0);
1801 gsMatrix<Scalar> dinvJacdx(2, 2);
1802 dinvJacdx.row(0).noalias() = invJacHatG(0, i) * invJacMat.row(0);
1803 dinvJacdx.row(1).noalias() = invJacHatG(1, i) * invJacMat.row(0);
1804 jacdLxdx.col(i).noalias() = -temp.transpose() * invJacMat.col(0)
1805 - invJacHatG.transpose() * dinvJacdx.col(0);
1806 jacdLydx.col(i).noalias() = -temp.transpose() * invJacMat.col(1)
1807 - invJacHatG.transpose() * dinvJacdx.col(1);
1810 temp.row(0).noalias() = invJacHatG(0, i) * invJacHatG.row(1);
1811 temp.row(1).noalias() = invJacHatG(1, i) * invJacHatG.row(1);
1812 gsMatrix<Scalar> dinvJacdy(2, 2);
1813 dinvJacdy.row(0).noalias() = invJacHatG(0, i) * invJacMat.row(1);
1814 dinvJacdy.row(1).noalias() = invJacHatG(1, i) * invJacMat.row(1);
1815 jacdLxdy.col(i).noalias() = -temp.transpose() * invJacMat.col(0)
1816 - invJacHatG.transpose() * dinvJacdy.col(0);
1817 jacdLydy.col(i).noalias() = -temp.transpose() * invJacMat.col(1)
1818 - invJacHatG.transpose() * dinvJacdy.col(1);
1821 res.resize(_u.cardinality(), _u.cardinality());
1823 res.topLeftCorner(N, N).noalias() = jacdLxdx;
1824 res.topRightCorner(N, N).noalias() = jacdLxdy;
1825 res.bottomLeftCorner(N, N).noalias() = jacdLydx;
1826 res.bottomRightCorner(N, N).noalias() = jacdLydy;
1831 index_t rows()
const {
return 1; }
1833 index_t cols()
const {
return 1; }
1835 void parse(gsExprHelper<Scalar> &evList)
const {
1837 _u.data().flags |= NEED_GRAD;
1843 const gsFeSpace<Scalar> &rowVar()
const {
return _u.rowVar(); }
1844 const gsFeSpace<Scalar> &colVar()
const {
return _u.rowVar(); }
1846 index_t cardinality_impl()
const {
return _u.cardinality_impl(); }
1848 void print(std::ostream &os)
const {
1849 os <<
"jacScaledLx(";
1859 class jacScaledLxH1DiagBlock_expr
1860 :
public _expr<jacScaledLxH1DiagBlock_expr<E> > {
1862 typedef typename E::Scalar Scalar;
1865 typename E::Nested_t _u;
1866 typename gsGeometryMap<Scalar>::Nested_t _G;
1869 enum { Space = 3, ScalarValued = 0, ColBlocks = 0 };
1871 jacScaledLxH1DiagBlock_expr(
const E &u,
const gsGeometryMap<Scalar> &G)
1878 const gsMatrix<Scalar> &eval(
const index_t k)
const {
1879 gsMatrix<Scalar> jacMat = _G.data().values[1].reshapeCol(k,
1880 _G.data().dim.first,
1881 _G.data().dim.second);
1882 gsMatrix<Scalar> invJacMat = jacMat.inverse();
1884 derivBasis = _u.data().values[1].col(k).transpose();
1885 derivBasis.blockTransposeInPlace(_u.dim());
1886 gsMatrix<Scalar> invJacHatG = invJacMat *
derivBasis;
1888 const index_t N = _u.cardinality() / _u.dim();
1889 gsMatrix<Scalar> jacdLxdx(N, N);
1892 gsMatrix<Scalar> jacdLydy(N, N);
1894 gsMatrix<> temp(2, N);
1895 for (
auto i = 0; i < N; ++i) {
1897 temp.row(0) = invJacHatG(0, i) * invJacHatG.row(0);
1898 temp.row(1) = invJacHatG(1, i) * invJacHatG.row(0);
1899 gsMatrix<Scalar> dinvJacdx(2, 2);
1900 dinvJacdx.row(0) = invJacHatG(0, i) * invJacMat.row(0);
1901 dinvJacdx.row(1) = invJacHatG(1, i) * invJacMat.row(0);
1902 jacdLxdx.col(i) = -temp.transpose() * invJacMat.col(0)
1903 - invJacHatG.transpose() * dinvJacdx.col(0);
1907 temp.row(0) = invJacHatG(0, i) * invJacHatG.row(1);
1908 temp.row(1) = invJacHatG(1, i) * invJacHatG.row(1);
1909 gsMatrix<Scalar> dinvJacdy(2, 2);
1910 dinvJacdy.row(0) = invJacHatG(0, i) * invJacMat.row(1);
1911 dinvJacdy.row(1) = invJacHatG(1, i) * invJacMat.row(1);
1913 jacdLydy.col(i) = -temp.transpose() * invJacMat.col(1)
1914 - invJacHatG.transpose() * dinvJacdy.col(1);
1917 res.resize(_u.cardinality(), _u.cardinality());
1919 res.topLeftCorner(N, N) = jacdLxdx;
1922 res.bottomRightCorner(N, N) = jacdLydy;
1927 index_t rows()
const {
return 1; }
1929 index_t cols()
const {
return 1; }
1931 void parse(gsExprHelper<Scalar> &evList)
const {
1933 _u.data().flags |= NEED_GRAD;
1939 const gsFeSpace<Scalar> &rowVar()
const {
return _u.rowVar(); }
1940 const gsFeSpace<Scalar> &colVar()
const {
return _u.rowVar(); }
1942 index_t cardinality_impl()
const {
return _u.cardinality_impl(); }
1944 void print(std::ostream &os)
const {
1945 os <<
"jacScaledLx(";
1976 template<
typename E1,
typename E2>
1977 class frprod2_expr :
public _expr<frprod2_expr<E1, E2> > {
1979 typedef typename E2::Scalar Scalar;
1980 enum { ScalarValued = 0, Space = E1::Space, ColBlocks = 0 };
1983 typename E1::Nested_t _u;
1984 typename E2::Nested_t _v;
1986 mutable gsMatrix<Scalar> res, bGrads;
1990 frprod2_expr(_expr<E1>
const &u, _expr<E2>
const &v)
1999 const gsMatrix<Scalar> &eval(
const index_t k)
const
2001 auto A = _v.eval(k);
2002 bGrads = _u.data().values[1].col(k).transpose();
2003 bGrads.blockTransposeInPlace(_u.dim());
2004 res.noalias() = A * bGrads;
2005 res.transposeInPlace();
2006 res.resize(1, _u.cardinality());
2008 res.transposeInPlace();
2012 index_t rows()
const {
return 1; }
2013 index_t cols()
const {
return 1; }
2015 void parse(gsExprHelper<Scalar> &evList)
const {
2018 _u.data().flags |= NEED_GRAD;
2021 const gsFeSpace<Scalar> &rowVar()
const {
return _u.rowVar(); }
2022 const gsFeSpace<Scalar> &colVar()
const {
return _v.rowVar(); }
2024 void print(std::ostream &os)
const {
2037 const gsGeometryMap<typename E::Scalar> &G) {
2038 return jacScaledLx_expr<E>(u, G);
2045 const gsGeometryMap<typename E::Scalar> &G) {
2046 return jacScaledLxDiag_expr<E>(u, G);
2053 const gsGeometryMap<typename E::Scalar> &G) {
2054 return jacScaledLxDiagBlock_expr<E>(u, G);
2061 const gsGeometryMap<typename E::Scalar> &G) {
2062 return jacScaledLxH1_expr<E>(u, G);
2069 const gsGeometryMap<
2070 typename E::Scalar> &G) {
2071 return jacScaledLxH1DiagBlock_expr<E>(u, G);
2075 template<
typename E1,
typename E2>
2077 frprod2_expr<E1, E2>
const frprod2(E1
const &u,
2079 return frprod2_expr<E1, E2>(u, M);
2083 template<
class E0,
class E1,
class E2>
2088 return ternary_expr<E0, E1, E2>(u, v, w);
static T computeAreaBoundary(const gsMultiPatch< T > &mp)
Computes the area of a multipatch representing boundary curves.
Definition: gsBarrierCore.hpp:114
EIGEN_STRONG_INLINE ternary_expr< E0, E1, E2 > ternary(const E0 &u, const E1 &v, const E2 &w)
Ternary ternary_expr.
Definition: gsBarrierCore.hpp:2085
T integral(const expr::_expr< E > &expr)
Calculates the integral of the expression expr on the whole integration domain.
Definition: gsExprEvaluator.h:154
Definition: gsExprAssembler.h:30
Scalar epsilon
Definition: gsBarrierCore.h:521
#define GISMO_NO_IMPLEMENTATION
Definition: gsDebug.h:129
Dirichlet type.
Definition: gsBoundaryConditions.h:31
Definition: gsBarrierCore.h:504
Gradient of the object.
Definition: gsForwardDeclarations.h:73
void setIntegrationElements(const gsMultiBasis< T > &mesh)
Sets the domain of integration.
Definition: gsExprEvaluator.h:110
EIGEN_STRONG_INLINE frprod3_expr< E1, E2 > const frprod3(E1 const &u, E2 const &M)
Frobenious product (also known as double dot product) operator for expressions.
Definition: gsBarrierCore.hpp:1339
static gsMultiPatch< T > computePDEPatch(const gsMultiPatch< T > &mp, const gsDofMapper &mapper, const gsOptionList &options)
PDE-based methods, including H2 and H1.
Definition: gsBarrierCore.hpp:1046
EIGEN_STRONG_INLINE jacScaledLxDiagBlock_expr< E > jacScaledLxDiagBlock(const E &u, const gsGeometryMap< typename E::Scalar > &G)
diagonal block part of jacobian matrix of scaled Lx for PDE-based parameterization construction ...
Definition: gsBarrierCore.hpp:2052
const_biterator bBegin() const
Definition: gsBoxTopology.h:139
const gsVector< Scalar > & compute(const gsVector< Scalar > &u0, const Residual_t &F, const Jacobian_t &Jacobian)
perform Anderson acceleration iteration
Definition: gsBarrierCore.h:618
Anderson acceleration solver and its (preconditioned) variants.
Definition: gsBarrierCore.h:607
void assemble(const expr &...args)
Adds the expressions args to the system matrix/rhs The arguments are considered as integrals over the...
Definition: gsExprAssembler.h:756
Second derivatives.
Definition: gsForwardDeclarations.h:80
#define index_t
Definition: gsConfig.h:32
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
Maintains a mapping from patch-local dofs to global dof indices and allows the elimination of individ...
Definition: gsDofMapper.h:68
void verboseLog(const std::string &message, const index_t &verbose)
helper function to set optimizer options
Definition: gsBarrierCore.h:101
static gsMultiPatch< T > computeVHPatch(const gsMultiPatch< T > &mp, const gsDofMapper &mapper, const gsOptionList &options)
variational harmonic method
const gsMatrix< T > & rhs() const
Returns the right-hand side vector(s)
Definition: gsExprAssembler.h:129
void addInt(const std::string &label, const std::string &desc, const index_t &value)
Adds a option named label, with description desc and value value.
Definition: gsOptionList.cpp:201
const gsSparseMatrix< T > & matrix() const
Returns the left-hand global matrix.
Definition: gsExprAssembler.h:116
std::string to_string(const unsigned &i)
Helper to convert small unsigned to string.
Definition: gsXml.cpp:74
void convertFreeVectorToMultiPatch(const gsVector< T > &gsFreeVec, const gsDofMapper &mapper, gsMultiPatch< T > &mp)
Convert free control points from a vector into a multi-patch.
Definition: gsBarrierCore.h:70
static T computeAreaInterior(const gsMultiPatch< T > &mp)
Computes the area of a multipatch representing a full domain.
Definition: gsBarrierCore.hpp:94
#define gsWarn
Definition: gsDebug.h:50
Holds a set of patch-wise bases and their topology information.
Definition: gsMultiBasis.h:36
static gsMultiPatch< T > computeBarrierPatch(const gsMultiPatch< T > &mp, const gsDofMapper &mapper, const gsOptionList &options)
Barrier function-based method.
static gsMultiPatch< T > compute(const gsMultiPatch< T > &mp, const gsDofMapper &mapper, const gsOptionList &options)
construct analysis-suitable parameterization
Definition: gsBarrierCore.hpp:129
int updatePreconditionerStep
Definition: gsBarrierCore.h:542
Definition: gsDirichletValues.h:23
geometryMap getMap(const gsFunctionSet< T > &g)
Registers g as an isogeometric geometry map and return a handle to it.
Definition: gsExprAssembler.h:161
Container class for a set of geometry patches and their topology, that is, the interface connections ...
Definition: gsMultiPatch.h:33
Generic evaluator of isogeometric expressions.
Definition: gsExprEvaluator.h:38
space getSpace(const gsFunctionSet< T > &mp, index_t dim=1, index_t id=0)
Definition: gsExprAssembler.h:166
static gsOptionList defaultOptions()
Default options.
Definition: gsBarrierCore.hpp:24
EIGEN_STRONG_INLINE jacScaledLx_expr< E > jacScaledLx(const E &u, const gsGeometryMap< typename E::Scalar > &G)
jacobian matrix of scaled Lx for PDE-based parameterization construction
Definition: gsBarrierCore.hpp:2036
Class containing a set of boundary conditions.
Definition: gsBoundaryConditions.h:341
Value of the object.
Definition: gsForwardDeclarations.h:72
index_t askInt(const std::string &label, const index_t &value=0) const
Reads value for option label from options.
Definition: gsOptionList.cpp:117
void addReal(const std::string &label, const std::string &desc, const Real &value)
Adds a option named label, with description desc and value value.
Definition: gsOptionList.cpp:211
void addCondition(int p, boxSide s, condition_type::type t, gsFunctionSet< T > *f, short_t unknown=0, bool parametric=false, int comp=-1)
Adds another boundary condition.
Definition: gsBoundaryConditions.h:650
EIGEN_STRONG_INLINE jacScaledLxH1_expr< E > jacScaledLxH1(const E &u, const gsGeometryMap< typename E::Scalar > &G)
jacobian matrix of scaled Lx (in H1 space) for PDE-based parameterization construction ...
Definition: gsBarrierCore.hpp:2060
#define GISMO_ERROR(message)
Definition: gsDebug.h:118
static gsMultiPatch< T > computePenaltyPatch2(const gsMultiPatch< T > &mp, const gsDofMapper &mapper, const gsOptionList &options)
Penalty function-based method (2)
bool askSwitch(const std::string &label, const bool &value=false) const
Reads value for option label from options.
Definition: gsOptionList.cpp:128
void setGeoMap(const gsFunctionSet< T > &gm)
Set the geometry map to evaluate boundary conditions.
Definition: gsBoundaryConditions.h:916
Class which holds a list of parameters/options, and provides easy access to them. ...
Definition: gsOptionList.h:32
gsVector< T > convertMultiPatchToFreeVector(const gsMultiPatch< T > &mp, const gsDofMapper &mapper)
Computes a patch parametrization given a set of boundary geometries. Parametrization is not guarantee...
Definition: gsBarrierCore.h:50
void setIntegrationElements(const gsMultiBasis< T > &mesh)
Sets the domain of integration.
Definition: gsExprAssembler.h:136
void derivBasis()
Definition: gsBSplineAlgorithms.h:199
const_biterator bEnd() const
Definition: gsBoxTopology.h:144
void addSwitch(const std::string &label, const std::string &desc, const bool &value)
Adds a option named label, with description desc and value value.
Definition: gsOptionList.cpp:235
EIGEN_STRONG_INLINE jacScaledLxDiag_expr< E > jacScaledLxDiag(const E &u, const gsGeometryMap< typename E::Scalar > &G)
diagonal part of jacobian matrix of scaled Lx for PDE-based parameterization construction ...
Definition: gsBarrierCore.hpp:2044
bool usePreconditioning
Definition: gsBarrierCore.h:552
static T computeArea(const gsMultiPatch< T > &mp)
Compute the area of the computational domain.
Definition: gsBarrierCore.hpp:88
void initSystem(const index_t numRhs=1)
Initializes the sparse system (sparse matrix and rhs)
Definition: gsExprAssembler.h:290
geometryMap getMap(const gsMultiPatch< T > &mp)
Registers mp as an isogeometric geometry map and return a handle to it.
Definition: gsExprEvaluator.h:116
int m
Definition: gsBarrierCore.h:513
static gsMultiPatch< T > computePenaltyPatch(const gsMultiPatch< T > &mp, const gsDofMapper &mapper, const gsOptionList &options)
Penalty function-based method (1)
EIGEN_STRONG_INLINE jacScaledLxH1DiagBlock_expr< E > jacScaledLxH1DiagBlock(const E &u, const gsGeometryMap< typename E::Scalar > &G)
jacobian matrix of scaled Lx (in H1 space) for PDE-based parameterization construction ...
Definition: gsBarrierCore.hpp:2068
void copy(T begin, T end, U *result)
Small wrapper for std::copy mimicking std::copy for a raw pointer destination, copies n positions sta...
Definition: gsMemory.h:391
EIGEN_STRONG_INLINE jac_expr< E > jac(const symbol_expr< E > &u)
The Jacobian matrix of a FE variable.
Definition: gsExpressions.h:4530