G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsThinShellAssemblerDWR.hpp
Go to the documentation of this file.
1 
16 #pragma once
17 
23 
24 #include <gsCore/gsFunctionExpr.h>
26 
27 namespace gismo
28 {
29 
30 template <short_t d, class T, bool bending>
31 gsThinShellAssemblerDWR<d, T, bending>::gsThinShellAssemblerDWR(
32  const gsMultiPatch<T> & patches,
33  const gsMultiBasis<T> & basisL,
34  const gsMultiBasis<T> & basisH,
35  const gsBoundaryConditions<T> & bconditions,
36  const gsFunction<T> & surface_force,
37  gsMaterialMatrixBase<T> * materialmatrix
38  )
39  :
40  Base(patches,basisL,bconditions,surface_force,materialmatrix),
41  m_bcs(bconditions)
42 {
43  m_assemblerL = new gsThinShellAssembler<d,T,bending>(patches,basisL,bconditions,surface_force,materialmatrix);
44  m_assemblerH = new gsThinShellAssembler<d,T,bending>(patches,basisH,bconditions,surface_force,materialmatrix);
45 
46  m_dL = gsVector<T>::Zero(m_assemblerL->numDofs());
47  m_dH = gsVector<T>::Zero(m_assemblerH->numDofs());
48  }
49 
50 template <short_t d, class T, bool bending>
51 ThinShellAssemblerStatus gsThinShellAssemblerDWR<d, T, bending>::_assembleMass(gsThinShellAssemblerBase<T> * assembler, gsSparseMatrix<T> & result, bool lumped)
52 {
53  ThinShellAssemblerStatus status = assembler->assembleMass(lumped);
54  result = assembler->matrix();
55  GISMO_ENSURE(status==ThinShellAssemblerStatus::Success,"Assembly failed");
56  return status;
57 }
58 
59 // template <short_t d, class T, bool bending>
60 // gsSparseMatrix<T> gsThinShellAssemblerDWR<d, T, bending>::_assembleMassLM(gsThinShellAssemblerBase<T> * assembler, bool lumped)
61 // {
62 // gsExprAssembler<T> assembler(1,1);
63 // // Elements used for numerical integration
64 
65 // assembler.setIntegrationElements(m_assemblerH->getBasis());
66  // GISMO_ENSURE(m_assemblerL->options().hasGroup("ExprAssembler"),"The option list does not contain options with the label 'ExprAssembler'!");
67  // exprAssembler.setOptions(m_assemblerL->options().getGroup("ExprAssembler"));
68 
69 
70 // // Initialize the geometry maps
71 // geometryMap m_ori = assembler.getMap(m_patches); // this map is used for integrals
72 
73 // // Set the discretization space
74 // space spaceL = assembler.getSpace(m_assemblerL->getBasis(), d, 0); // last argument is the space ID
75 // space spaceH = assembler.getTestSpace(spaceL , m_assemblerH->getBasis());
76 
77 // this->_assembleDirichlet();
78 
79 // // Initialize stystem
80 // assembler.initSystem();
81 
82 // gsMaterialMatrixIntegrate<T,MaterialOutput::Density> m_mm(m_materialMat,&m_patches);
83 // auto mm0 = assembler.getCoeff(m_mm);
84 
85 // space m_space = assembler.trialSpace(0);
86 
87 // // assemble system
88 // assembler.assemble(mm0.val()*spaceL*spaceH.tr()*meas(m_ori));
89 // return assembler.matrix();
90 
91  // m_assembler.cleanUp();
92  // m_assembler.setOptions(m_options);
93 
94  // m_assembler.getMap(m_patches); // this map is used for integrals
95 
96  // // Initialize stystem
97  // m_assembler.initSystem();
98 
99  // gsMaterialMatrixIntegrate<T,MaterialOutput::Density> m_mm(m_materialMat,&m_patches);
100  // auto mm0 = m_assembler.getCoeff(m_mm);
101 
102  // space m_space = m_assembler.trialSpace(0);
103  // geometryMap m_ori = m_assembler.exprData()->getMap();
104 
105  // // assemble system
106  // if (!lumped)
107  // m_assembler.assemble(mm0.val()*m_space*m_space.tr()*meas(m_ori));
108  // else
109  // m_assembler.assemble(mm0.val()*(m_space.rowSum())*meas(m_ori));
110 // }
111 
112 template <short_t d, class T, bool bending>
113 ThinShellAssemblerStatus gsThinShellAssemblerDWR<d, T, bending>::assembleL()
114 {
115  std::pair<gsSparseMatrix<T>,gsVector<T>> result;
116  ThinShellAssemblerStatus status = _assemble(m_assemblerL,result);
117  m_matrixL = result.first;
118  m_pL = result.second;
119  GISMO_ENSURE(status==ThinShellAssemblerStatus::Success,"Assembly failed");
120  return status;
121 }
122 
123 template <short_t d, class T, bool bending>
124 ThinShellAssemblerStatus gsThinShellAssemblerDWR<d, T, bending>::assembleH()
125 {
126  std::pair<gsSparseMatrix<T>,gsVector<T>> result;
127  ThinShellAssemblerStatus status = _assemble(m_assemblerH,result);
128  m_matrixH = result.first;
129  m_pH = result.second;
130  return status;
131 }
132 
133 template <short_t d, class T, bool bending>
134 ThinShellAssemblerStatus gsThinShellAssemblerDWR<d, T, bending>::_assemble(gsThinShellAssemblerBase<T> * assembler, std::pair<gsSparseMatrix<T>,gsVector<T>> & result)
135 {
136  ThinShellAssemblerStatus status = assembler->assemble();
137  result = std::make_pair(assembler->matrix(),assembler->rhs());
138  GISMO_ENSURE(status==ThinShellAssemblerStatus::Success,"Assembly failed");
139  return status;
140 }
141 
142 template <short_t d, class T, bool bending>
143 ThinShellAssemblerStatus gsThinShellAssemblerDWR<d, T, bending>::_assembleMatrix(gsThinShellAssemblerBase<T> * assembler, gsSparseMatrix<T> & result)
144 {
145  ThinShellAssemblerStatus status = assembler->assemble();
146  result = assembler->matrix();
147  GISMO_ENSURE(status==ThinShellAssemblerStatus::Success,"Assembly failed");
148  return status;
149 }
150 
151 template <short_t d, class T, bool bending>
152 ThinShellAssemblerStatus gsThinShellAssemblerDWR<d, T, bending>::_assembleMatrix(gsThinShellAssemblerBase<T> * assembler, const gsMultiPatch<T> & deformed, gsSparseMatrix<T> & result)
153 {
154  ThinShellAssemblerStatus status = assembler->assembleMatrix(deformed);
155  result = assembler->matrix();
156  GISMO_ENSURE(status==ThinShellAssemblerStatus::Success,"Assembly failed");
157  return status;
158 }
159 
160 template <short_t d, class T, bool bending>
161 ThinShellAssemblerStatus gsThinShellAssemblerDWR<d, T, bending>::_assemblePrimal(gsThinShellAssemblerBase<T> * assembler, const gsMultiPatch<T> & deformed, gsVector<T> & result)
162 {
163  ThinShellAssemblerStatus status = assembler->assembleVector(deformed);
164  result = assembler->rhs();
165  GISMO_ENSURE(status==ThinShellAssemblerStatus::Success,"Assembly failed");
166  return status;
167 }
168 
169 template <short_t d, class T, bool bending>
170 ThinShellAssemblerStatus gsThinShellAssemblerDWR<d, T, bending>::_assemblePrimal(gsThinShellAssemblerBase<T> * assembler, gsVector<T> & result)
171 {
172  ThinShellAssemblerStatus status = assembler->assemble();
173  GISMO_ENSURE(status==ThinShellAssemblerStatus::Success,"Assembly failed");
174  result = assembler->rhs();
175  return status;
176 }
177 
178 template <short_t d, class T, bool bending>
179 ThinShellAssemblerStatus gsThinShellAssemblerDWR<d, T, bending>::_assembleDual(gsThinShellAssemblerBase<T> * assembler, const gsMultiPatch<T> & primal, const gsMultiPatch<T> & deformed, gsVector<T> & result)
180 {
181  GISMO_ASSERT(m_component < d || m_component==9,"Component is out of bounds");
182 
183  // For the stretches
184  // ! Only works with Z=0 for now, since principal stresses and directions are implemented for Z=0, since principal stresses and directions are implemented for Z=0
185  gsMatrix<T> Z(1,1);
186  Z.setZero();
188 
189  gsExprAssembler<T> exprAssembler = assembler->assembler();
190  exprAssembler.cleanUp();
191  GISMO_ENSURE(assembler->options().hasGroup("ExprAssembler"),"The option list does not contain options with the label 'ExprAssembler'!");
192  exprAssembler.setOptions(assembler->options().getGroup("ExprAssembler"));
193 
194  // Geometries
195  geometryMap Gori = exprAssembler.getMap(m_patches); // this map is used for integrals
196  geometryMap Gdef = exprAssembler.getMap(deformed);
197 
198  // Initialize vector
199  exprAssembler.initSystem();
200  exprAssembler.initVector(1);
201 
202  // Space
203  space space = exprAssembler.trialSpace(0);
204  // Homogenize Dirichlet
205  space.setup(m_bcs, dirichlet::homogeneous, 0);
206 
207  // Solution
208  auto usol = exprAssembler.getCoeff(primal);
209 
210  // Transformation for stretches
211  gsMaterialMatrixEval<T,MaterialOutput::StretchTransform> Tstretchf(assembler->materials(),&deformed,Z);
212  gsMaterialMatrixEval<T,MaterialOutput::PStressTransform> Tpstressf(assembler->materials(),&deformed,Z);
213  auto Tstretch = exprAssembler.getCoeff(Tstretchf);
214  auto Tpstress = exprAssembler.getCoeff(Tpstressf);
215 
216  // Material tensors at Z
217  gsMaterialMatrixEval<T,MaterialOutput::MatrixA> mmAf(assembler->materials(),&deformed,Z);
218  gsMaterialMatrixEval<T,MaterialOutput::MatrixD> mmDf(assembler->materials(),&deformed,Z);
219  auto mmA = exprAssembler.getCoeff(mmAf);
220  auto mmD = exprAssembler.getCoeff(mmDf);
221 
222  // Material tensors integrated
223  gsMaterialMatrixIntegrate<T,MaterialOutput::MatrixA> mmAfi(assembler->materials(),&deformed);
224  gsMaterialMatrixIntegrate<T,MaterialOutput::MatrixB> mmBfi(assembler->materials(),&deformed);
225  gsMaterialMatrixIntegrate<T,MaterialOutput::MatrixC> mmCfi(assembler->materials(),&deformed);
226  gsMaterialMatrixIntegrate<T,MaterialOutput::MatrixD> mmDfi(assembler->materials(),&deformed);
227  auto mmAi = exprAssembler.getCoeff(mmAfi);
228  auto mmBi = exprAssembler.getCoeff(mmBfi);
229  auto mmCi = exprAssembler.getCoeff(mmCfi);
230  auto mmDi = exprAssembler.getCoeff(mmDfi);
231 
232  // Stress tensors
233  gsMaterialMatrixEval<T,MaterialOutput::VectorN> S0f(assembler->materials(),&deformed,Z);
234  gsMaterialMatrixEval<T,MaterialOutput::VectorM> S1f(assembler->materials(),&deformed,Z);
235  auto S0 = exprAssembler.getCoeff(S0f);
236  auto S1 = exprAssembler.getCoeff(S1f);
237 
238  // Principal stress tensors
239  gsMaterialMatrixEval<T,MaterialOutput::PStress> P0f(assembler->materials(),&deformed,Z);
240  auto P0 = exprAssembler.getCoeff(P0f);
241 
242  // Force and moment tensors
243  gsMaterialMatrixIntegrate<T,MaterialOutput::VectorN> Nf(assembler->materials(),&deformed);
244  gsMaterialMatrixIntegrate<T,MaterialOutput::VectorM> Mf(assembler->materials(),&deformed);
245  auto N = exprAssembler.getCoeff(Nf);
246  auto M = exprAssembler.getCoeff(Mf);
247 
248  // Helper matrix for flexural components
249  gsFunctionExpr<T> mult2t("1","0","0","0","1","0","0","0","2",2);
250  auto m2 = exprAssembler.getCoeff(mult2t);
251 
252  // Deformation gradient and its first variation
253  // To compensate for the flat, since flat does [E11,E22,2*E12]
254  gsFunctionExpr<T> mult12t("1","0","0","0","1","0","0","0","0.5",2);
255  auto m12 = exprAssembler.getCoeff(mult12t);
256 
257  auto Cm = flat( jac(Gdef).tr() * jac(Gdef) ) * reshape(m12,3,3);
258  auto Cm_der = 2* flat( jac(Gdef).tr() * jac(space) ) * reshape(m12,3,3);
259 
260  // Principal stretch and its first variation
261  auto lambda = Cm * reshape(Tstretch,3,3).tr();
262  auto lambda_der = Cm_der * reshape(Tstretch,3,3).tr();
263 
264  // Membrane strain and its first variation
265  auto Em = 0.5 * ( flat(jac(Gdef).tr()*jac(Gdef)) - flat(jac(Gori).tr()* jac(Gori)) ) ;
266  auto Em_der = flat( jac(Gdef).tr() * jac(space) ) ;
267 
268  // Principal membrane strain and its first variation
269  auto Emp = (Em * reshape(m12,3,3)) * reshape(Tstretch,3,3).tr();
270  auto Emp_der= (Em_der * reshape(m12,3,3)) * reshape(Tstretch,3,3).tr();
271 
272  // Flexural strain and its first variation
273  auto Ef = ( deriv2(Gori,sn(Gori).normalized().tr()) - deriv2(Gdef,sn(Gdef).normalized().tr()) ) * reshape(m2,3,3) ;
274  auto Ef_der = -( deriv2(space,sn(Gdef).normalized().tr() ) + deriv2(Gdef,var1(space,Gdef) ) ) * reshape(m2,3,3);
275 
276  // Membrane stress (its first variation)
277  auto Sm_der = Em_der * reshape(mmA,3,3);
278 
279  // Principal membrane stress (its first variation)
280  auto Smp_der = Sm_der * reshape(Tpstress,3,3).tr();
281 
282  // Flexural stress (its first variation)
283  auto Sf_der = Ef_der * reshape(mmD,3,3);
284 
285  // Membrane force (its first variation)
286  auto N_der = Em_der * reshape(mmAi,3,3) + Ef_der * reshape(mmBi,3,3);
287  auto M_der = Em_der * reshape(mmCi,3,3) + Ef_der * reshape(mmDi,3,3);
288 
289  if (m_goalFunction == GoalFunction::Displacement)
290  {
291  if (m_component==9)
292  {
293  auto expr = 2 * space * usol * meas(Gori);
294  try
295  {
296  exprAssembler.assemble(expr);
297  result = exprAssembler.rhs();
299  }
300  catch (...)
301  {
302  exprAssembler.cleanUp();
304  }
305  }
306  else
307  {
308  auto expr = space * gismo::expr::uv(m_component,3) * meas(Gori);
309  try
310  {
311  exprAssembler.assemble(expr);
312  result = exprAssembler.rhs();
314  }
315  catch (...)
316  {
317  exprAssembler.cleanUp();
319  }
320  }
321  }
322  else if (m_goalFunction == GoalFunction::Stretch)
323  {
324  if (m_component==9)
325  {
326  auto expr = 2 * lambda_der * lambda.tr() * meas(Gori);
327  try
328  {
329  exprAssembler.assemble(expr);
330  result = exprAssembler.rhs();
332  }
333  catch (...)
334  {
335  exprAssembler.cleanUp();
337  }
338  }
339  else
340  {
341  auto expr = lambda_der * gismo::expr::uv(m_component,3) * meas(Gori);
342  try
343  {
344  exprAssembler.assemble(expr);
345  result = exprAssembler.rhs();
347  }
348  catch (...)
349  {
350  exprAssembler.cleanUp();
352  }
353  }
354  }
355  else if (m_goalFunction == GoalFunction::PStrain)
356  {
357  if (m_component==9)
358  {
359  auto expr = 2 * Emp_der * Emp.tr() * meas(Gori);
360  try
361  {
362  exprAssembler.assemble(expr);
363  result = exprAssembler.rhs();
365  }
366  catch (...)
367  {
368  exprAssembler.cleanUp();
370  }
371  }
372  else
373  {
374  auto expr = Emp_der * gismo::expr::uv(m_component,3) * meas(Gori);
375  try
376  {
377  exprAssembler.assemble(expr);
378  result = exprAssembler.rhs();
380  }
381  catch (...)
382  {
383  exprAssembler.cleanUp();
385  }
386  }
387  }
388  else if (m_goalFunction == GoalFunction::PStress)
389  {
390  // to convert P0 from a vector of length 2 to 3, this matrix is [[1,0],[0,1],[0,0]]
391  gsMatrix<T> convMat(3,2);
392  convMat.setZero();
393  convMat(0,0) = convMat(1,1) = 1;
394  gsConstantFunction<T> convFun(convMat.reshape(6,1),2);
395  auto conv = exprAssembler.getCoeff(convFun);
396  if (m_component==9)
397  {
398  auto expr = 2 * Smp_der * reshape(conv,3,2) * P0 * meas(Gori);
399  try
400  {
401  exprAssembler.assemble(expr);
402  result = exprAssembler.rhs();
404  }
405  catch (...)
406  {
407  exprAssembler.cleanUp();
409  }
410  }
411  else
412  {
413  GISMO_ASSERT(m_component < 2,"Can only select principle stress component 0 or 1, but "<<m_component<<" selected.");
414  auto expr = Smp_der * reshape(conv,3,2) * gismo::expr::uv(m_component,2) * meas(Gori);
415  try
416  {
417  exprAssembler.assemble(expr);
418  result = exprAssembler.rhs();
420  }
421  catch (...)
422  {
423  exprAssembler.cleanUp();
425  }
426  }
427  }
428  else if (m_goalFunction == GoalFunction::MembraneStrain)
429  {
430  if (m_component==9)
431  {
432  auto expr = 2 * Em_der * Em.tr() * meas(Gori);
433  try
434  {
435  exprAssembler.assemble(expr);
436  result = exprAssembler.rhs();
438  }
439  catch (...)
440  {
441  exprAssembler.cleanUp();
443  }
444  }
445  else
446  {
447  auto expr = Em_der * gismo::expr::uv(m_component,3) * meas(Gori);
448  try
449  {
450  exprAssembler.assemble(expr);
451  result = exprAssembler.rhs();
453  }
454  catch (...)
455  {
456  exprAssembler.cleanUp();
458  }
459  }
460  }
461  else if (m_goalFunction == GoalFunction::MembraneStress)
462  {
463  if (m_component==9)
464  {
465  auto expr = 2 * Sm_der * S0 * meas(Gori);
466  try
467  {
468  exprAssembler.assemble(expr);
469  result = exprAssembler.rhs();
471  }
472  catch (...)
473  {
474  exprAssembler.cleanUp();
476  }
477  }
478  else
479  {
480  auto expr = Sm_der * gismo::expr::uv(m_component,3) * meas(Gori);
481  try
482  {
483  exprAssembler.assemble(expr);
484  result = exprAssembler.rhs();
486  }
487  catch (...)
488  {
489  exprAssembler.cleanUp();
491  }
492  }
493  }
494  else if (m_goalFunction == GoalFunction::MembraneForce)
495  {
496  if (m_component==9)
497  {
498  auto expr = 2 * N_der * N * meas(Gori);
499  try
500  {
501  exprAssembler.assemble(expr);
502  result = exprAssembler.rhs();
504  }
505  catch (...)
506  {
507  exprAssembler.cleanUp();
509  }
510  }
511  else
512  {
513  auto expr = N_der * gismo::expr::uv(m_component,3) * meas(Gori);
514  try
515  {
516  exprAssembler.assemble(expr);
517  result = exprAssembler.rhs();
519  }
520  catch (...)
521  {
522  exprAssembler.cleanUp();
524  }
525  }
526  }
527  else if (m_goalFunction == GoalFunction::FlexuralStrain)
528  {
529  if (m_component==9)
530  {
531  auto expr = 2 * Ef_der * Ef.tr() * meas(Gori);
532  try
533  {
534  exprAssembler.assemble(expr);
535  result = exprAssembler.rhs();
537  }
538  catch (...)
539  {
540  exprAssembler.cleanUp();
542  }
543  }
544  else
545  {
546  auto expr = Ef_der * gismo::expr::uv(m_component,3) * meas(Gori);
547  try
548  {
549  exprAssembler.assemble(expr);
550  result = exprAssembler.rhs();
552  }
553  catch (...)
554  {
555  exprAssembler.cleanUp();
557  }
558  }
559  }
560  else if (m_goalFunction == GoalFunction::FlexuralStress)
561  {
562  if (m_component==9)
563  {
564  auto expr = 2 * Sf_der * S1 * meas(Gori);
565  try
566  {
567  exprAssembler.assemble(expr);
568  result = exprAssembler.rhs();
570  }
571  catch (...)
572  {
573  exprAssembler.cleanUp();
575  }
576  }
577  else
578  {
579  auto expr = Sf_der * gismo::expr::uv(m_component,3) * meas(Gori);
580  try
581  {
582  exprAssembler.assemble(expr);
583  result = exprAssembler.rhs();
585  }
586  catch (...)
587  {
588  exprAssembler.cleanUp();
590  }
591  }
592  }
593  else if (m_goalFunction == GoalFunction::FlexuralMoment)
594  {
595  if (m_component==9)
596  {
597  auto expr = 2 * M_der * M * meas(Gori);
598  try
599  {
600  exprAssembler.assemble(expr);
601  result = exprAssembler.rhs();
603  }
604  catch (...)
605  {
606  exprAssembler.cleanUp();
608  }
609  }
610  else
611  {
612  auto expr = M_der * gismo::expr::uv(m_component,3) * meas(Gori);
613  try
614  {
615  exprAssembler.assemble(expr);
616  result = exprAssembler.rhs();
618  }
619  catch (...)
620  {
621  exprAssembler.cleanUp();
623  }
624  }
625  }
626  else
627  GISMO_ERROR("Goal function not known");
628 }
629 
630 template <short_t d, class T, bool bending>
631 ThinShellAssemblerStatus gsThinShellAssemblerDWR<d, T, bending>::_assembleDual(const bContainer & bnds, gsThinShellAssemblerBase<T> * assembler, const gsMultiPatch<T> & primal, const gsMultiPatch<T> & deformed, gsVector<T> & result)
632 {
633  GISMO_ASSERT(m_component < d || m_component==9,"Component is out of bounds");
634 
635  // For the stretches
636  // ! Only works with Z=0 for now, since principal stresses and directions are implemented for Z=0, since principal stresses and directions are implemented for Z=0
637  gsMatrix<T> Z(1,1);
638  Z.setZero();
640 
641  gsExprAssembler<T> exprAssembler = assembler->assembler();
642  exprAssembler.cleanUp();
643  GISMO_ENSURE(assembler->options().hasGroup("ExprAssembler"),"The option list does not contain options with the label 'ExprAssembler'!");
644  exprAssembler.setOptions(assembler->options().getGroup("ExprAssembler"));
645 
646  // Geometries
647  geometryMap Gori = exprAssembler.getMap(m_patches); // this map is used for integrals
648  geometryMap Gdef = exprAssembler.getMap(deformed);
649 
650  // Initialize vector
651  exprAssembler.initSystem();
652  exprAssembler.initVector(1);
653  if (bnds.size()==0)
654  {
655  result = exprAssembler.rhs();
657  }
658 
659  // Space
660  space space = exprAssembler.trialSpace(0);
661  // Homogenize Dirichlet
662  space.setup(m_bcs, dirichlet::homogeneous, 0);
663 
664  // Solution
665  auto usol = exprAssembler.getCoeff(primal);
666 
667  // Transformation for stretches
668  gsMaterialMatrixEval<T,MaterialOutput::StretchTransform> Tstretchf(assembler->materials(),&deformed,Z);
669  gsMaterialMatrixEval<T,MaterialOutput::PStressTransform> Tpstressf(assembler->materials(),&deformed,Z);
670  auto Tstretch = exprAssembler.getCoeff(Tstretchf);
671  auto Tpstress = exprAssembler.getCoeff(Tpstressf);
672 
673  // Material tensors at Z
674  gsMaterialMatrixEval<T,MaterialOutput::MatrixA> mmAf(assembler->materials(),&deformed,Z);
675  gsMaterialMatrixEval<T,MaterialOutput::MatrixD> mmDf(assembler->materials(),&deformed,Z);
676  auto mmA = exprAssembler.getCoeff(mmAf);
677  auto mmD = exprAssembler.getCoeff(mmDf);
678 
679  // Material tensors integrated
680  gsMaterialMatrixIntegrate<T,MaterialOutput::MatrixA> mmAfi(assembler->materials(),&deformed);
681  gsMaterialMatrixIntegrate<T,MaterialOutput::MatrixB> mmBfi(assembler->materials(),&deformed);
682  gsMaterialMatrixIntegrate<T,MaterialOutput::MatrixC> mmCfi(assembler->materials(),&deformed);
683  gsMaterialMatrixIntegrate<T,MaterialOutput::MatrixD> mmDfi(assembler->materials(),&deformed);
684  auto mmAi = exprAssembler.getCoeff(mmAfi);
685  auto mmBi = exprAssembler.getCoeff(mmBfi);
686  auto mmCi = exprAssembler.getCoeff(mmCfi);
687  auto mmDi = exprAssembler.getCoeff(mmDfi);
688 
689  // Stress tensors
690  gsMaterialMatrixEval<T,MaterialOutput::VectorN> S0f(assembler->materials(),&deformed,Z);
691  gsMaterialMatrixEval<T,MaterialOutput::VectorM> S1f(assembler->materials(),&deformed,Z);
692  auto S0 = exprAssembler.getCoeff(S0f);
693  auto S1 = exprAssembler.getCoeff(S1f);
694 
695  // Principal stress tensors
696  gsMaterialMatrixEval<T,MaterialOutput::PStress> P0f(assembler->materials(),&deformed,Z);
697  auto P0 = exprAssembler.getCoeff(P0f);
698 
699  // Force and moment tensors
700  gsMaterialMatrixIntegrate<T,MaterialOutput::VectorN> Nf(assembler->materials(),&deformed);
701  gsMaterialMatrixIntegrate<T,MaterialOutput::VectorM> Mf(assembler->materials(),&deformed);
702  auto N = exprAssembler.getCoeff(Nf);
703  auto M = exprAssembler.getCoeff(Mf);
704 
705  // Helper matrix for flexural components
706  gsFunctionExpr<T> mult2t("1","0","0","0","1","0","0","0","2",2);
707  auto m2 = exprAssembler.getCoeff(mult2t);
708 
709  // Deformation gradient and its first variation
710  // To compensate for the flat, since flat does [E11,E22,2*E12]
711  gsFunctionExpr<T> mult12t("1","0","0","0","1","0","0","0","0.5",2);
712  auto m12 = exprAssembler.getCoeff(mult12t);
713 
714  auto Cm = flat( jac(Gdef).tr() * jac(Gdef) ) * reshape(m12,3,3);
715  auto Cm_der = 2* flat( jac(Gdef).tr() * jac(space) ) * reshape(m12,3,3);
716 
717  // Principal stretch and its first variation
718  auto lambda = Cm * reshape(Tstretch,3,3).tr();
719  auto lambda_der = Cm_der * reshape(Tstretch,3,3).tr();
720 
721  // Membrane strain and its first variation
722  auto Em = 0.5 * ( flat(jac(Gdef).tr()*jac(Gdef)) - flat(jac(Gori).tr()* jac(Gori)) ) ;
723  auto Em_der = flat( jac(Gdef).tr() * jac(space) ) ;
724 
725  // Principal membrane strain and its first variation
726  auto Emp = (Em * reshape(m12,3,3)) * reshape(Tstretch,3,3).tr();
727  auto Emp_der= (Em_der * reshape(m12,3,3)) * reshape(Tstretch,3,3).tr();
728 
729  // Flexural strain and its first variation
730  auto Ef = ( deriv2(Gori,sn(Gori).normalized().tr()) - deriv2(Gdef,sn(Gdef).normalized().tr()) ) * reshape(m2,3,3) ;
731  auto Ef_der = -( deriv2(space,sn(Gdef).normalized().tr() ) + deriv2(Gdef,var1(space,Gdef) ) ) * reshape(m2,3,3);
732 
733  // Membrane stress (its first variation)
734  auto Sm_der = Em_der * reshape(mmA,3,3);
735 
736  // Principal membrane stress (its first variation)
737  auto Smp_der = Sm_der * reshape(Tpstress,3,3).tr();
738 
739  // Flexural stress (its first variation)
740  auto Sf_der = Ef_der * reshape(mmD,3,3);
741 
742  // Membrane force (its first variation)
743  auto N_der = Em_der * reshape(mmAi,3,3) + Ef_der * reshape(mmBi,3,3);
744  auto M_der = Em_der * reshape(mmCi,3,3) + Ef_der * reshape(mmDi,3,3);
745 
746  if (m_goalFunction == GoalFunction::Displacement)
747  {
748  if (m_component==9)
749  {
750  auto expr = 2 * space * usol * meas(Gori);
751  try
752  {
753  exprAssembler.assembleBdr(bnds,expr);
754  result = exprAssembler.rhs();
756  }
757  catch (...)
758  {
759  exprAssembler.cleanUp();
761  }
762  }
763  else
764  {
765  auto expr = space * gismo::expr::uv(m_component,3) * meas(Gori);
766  try
767  {
768  exprAssembler.assembleBdr(bnds,expr);
769  result = exprAssembler.rhs();
771  }
772  catch (...)
773  {
774  exprAssembler.cleanUp();
776  }
777  }
778  }
779  else if (m_goalFunction == GoalFunction::Stretch)
780  {
781  if (m_component==9)
782  {
783  auto expr = 2 * lambda_der * lambda.tr() * meas(Gori);
784  try
785  {
786  exprAssembler.assembleBdr(bnds,expr);
787  result = exprAssembler.rhs();
789  }
790  catch (...)
791  {
792  exprAssembler.cleanUp();
794  }
795  }
796  else
797  {
798  auto expr = lambda_der * gismo::expr::uv(m_component,3) * meas(Gori);
799  try
800  {
801  exprAssembler.assembleBdr(bnds,expr);
802  result = exprAssembler.rhs();
804  }
805  catch (...)
806  {
807  exprAssembler.cleanUp();
809  }
810  }
811  }
812  else if (m_goalFunction == GoalFunction::PStrain)
813  {
814  if (m_component==9)
815  {
816  auto expr = 2 * Emp_der * Emp.tr() * meas(Gori);
817  try
818  {
819  exprAssembler.assembleBdr(bnds,expr);
820  result = exprAssembler.rhs();
822  }
823  catch (...)
824  {
825  exprAssembler.cleanUp();
827  }
828  }
829  else
830  {
831  auto expr = Emp_der * gismo::expr::uv(m_component,3) * meas(Gori);
832  try
833  {
834  exprAssembler.assembleBdr(bnds,expr);
835  result = exprAssembler.rhs();
837  }
838  catch (...)
839  {
840  exprAssembler.cleanUp();
842  }
843  }
844  }
845  else if (m_goalFunction == GoalFunction::PStress)
846  {
847  // to convert P0 from a vector of length 2 to 3, this matrix is [[1,0],[0,1],[0,0]]
848  gsMatrix<T> convMat(3,2);
849  convMat.setZero();
850  convMat(0,0) = convMat(1,1) = 1;
851  gsConstantFunction<T> convFun(convMat.reshape(6,1),2);
852  auto conv = exprAssembler.getCoeff(convFun);
853  if (m_component==9)
854  {
855  auto expr = 2 * Smp_der * reshape(conv,3,2) * P0 * meas(Gori);
856  try
857  {
858  exprAssembler.assembleBdr(bnds,expr);
859  result = exprAssembler.rhs();
861  }
862  catch (...)
863  {
864  exprAssembler.cleanUp();
866  }
867  }
868  else
869  {
870  GISMO_ASSERT(m_component < 2,"Can only select principle stress component 0 or 1, but "<<m_component<<" selected.");
871  auto expr = Smp_der * reshape(conv,3,2) * gismo::expr::uv(m_component,2) * meas(Gori);
872  try
873  {
874  exprAssembler.assembleBdr(bnds,expr);
875  result = exprAssembler.rhs();
877  }
878  catch (...)
879  {
880  exprAssembler.cleanUp();
882  }
883  }
884  }
885  else if (m_goalFunction == GoalFunction::MembraneStrain)
886  {
887  if (m_component==9)
888  {
889  auto expr = 2 * Em_der * Em.tr() * meas(Gori);
890  try
891  {
892  exprAssembler.assembleBdr(bnds,expr);
893  result = exprAssembler.rhs();
895  }
896  catch (...)
897  {
898  exprAssembler.cleanUp();
900  }
901  }
902  else
903  {
904  auto expr = Em_der * gismo::expr::uv(m_component,3) * meas(Gori);
905  try
906  {
907  exprAssembler.assembleBdr(bnds,expr);
908  result = exprAssembler.rhs();
910  }
911  catch (...)
912  {
913  exprAssembler.cleanUp();
915  }
916  }
917  }
918  else if (m_goalFunction == GoalFunction::MembraneStress)
919  {
920  if (m_component==9)
921  {
922  auto expr = 2 * Sm_der * S0 * meas(Gori);
923  try
924  {
925  exprAssembler.assembleBdr(bnds,expr);
926  result = exprAssembler.rhs();
928  }
929  catch (...)
930  {
931  exprAssembler.cleanUp();
933  }
934  }
935  else
936  {
937  auto expr = Sm_der * gismo::expr::uv(m_component,3) * meas(Gori);
938  try
939  {
940  exprAssembler.assembleBdr(bnds,expr);
941  result = exprAssembler.rhs();
943  }
944  catch (...)
945  {
946  exprAssembler.cleanUp();
948  }
949  }
950  }
951  else if (m_goalFunction == GoalFunction::MembraneForce)
952  {
953  if (m_component==9)
954  {
955  auto expr = 2 * N_der * N * meas(Gori);
956  try
957  {
958  exprAssembler.assembleBdr(bnds,expr);
959  result = exprAssembler.rhs();
961  }
962  catch (...)
963  {
964  exprAssembler.cleanUp();
966  }
967  }
968  else
969  {
970  auto expr = N.tr() * gismo::expr::uv(m_component,3) * meas(Gori);
971  try
972  {
973  exprAssembler.assembleBdr(bnds,expr);
974  result = exprAssembler.rhs();
976  }
977  catch (...)
978  {
979  exprAssembler.cleanUp();
981  }
982  }
983  }
984  else if (m_goalFunction == GoalFunction::FlexuralStrain)
985  {
986  if (m_component==9)
987  {
988  gsFunctionExpr<T> mult110t("1","0","0","0","1","0","0","0","0",2);
989  auto m110 = exprAssembler.getCoeff(mult2t);
990  auto expr = 2*Ef_der * reshape(m110,3,3) * Ef.tr() * meas(Gori);
991  try
992  {
993  exprAssembler.assembleBdr(bnds,expr);
994  result = exprAssembler.rhs();
996  }
997  catch (...)
998  {
999  exprAssembler.cleanUp();
1001  }
1002  }
1003  else
1004  {
1005  auto expr = Ef_der * gismo::expr::uv(m_component,3) * meas(Gori);
1006  try
1007  {
1008  exprAssembler.assembleBdr(bnds,expr);
1009  result = exprAssembler.rhs();
1011  }
1012  catch (...)
1013  {
1014  exprAssembler.cleanUp();
1016  }
1017  }
1018  }
1019  else if (m_goalFunction == GoalFunction::FlexuralStress)
1020  {
1021  if (m_component==9)
1022  {
1023  auto expr = 2 * Sf_der * S1 * meas(Gori);
1024  try
1025  {
1026  exprAssembler.assembleBdr(bnds,expr);
1027  result = exprAssembler.rhs();
1029  }
1030  catch (...)
1031  {
1032  exprAssembler.cleanUp();
1034  }
1035  }
1036  else
1037  {
1038  auto expr = Sf_der * gismo::expr::uv(m_component,3) * meas(Gori);
1039  try
1040  {
1041  exprAssembler.assembleBdr(bnds,expr);
1042  result = exprAssembler.rhs();
1044  }
1045  catch (...)
1046  {
1047  exprAssembler.cleanUp();
1049  }
1050  }
1051  }
1052  else if (m_goalFunction == GoalFunction::FlexuralMoment)
1053  {
1054  if (m_component==9)
1055  {
1056  auto expr = 2 * M_der * M * meas(Gori);
1057  try
1058  {
1059  exprAssembler.assembleBdr(bnds,expr);
1060  result = exprAssembler.rhs();
1062  }
1063  catch (...)
1064  {
1065  exprAssembler.cleanUp();
1067  }
1068  }
1069  else
1070  {
1071  auto expr = M_der * gismo::expr::uv(m_component,3) * meas(Gori);
1072  try
1073  {
1074  exprAssembler.assembleBdr(bnds,expr);
1075  result = exprAssembler.rhs();
1077  }
1078  catch (...)
1079  {
1080  exprAssembler.cleanUp();
1082  }
1083  }
1084  }
1085  else
1086  GISMO_ERROR("Goal function not known");
1087 }
1088 
1089 
1090 template <short_t d, class T, bool bending>
1091 ThinShellAssemblerStatus gsThinShellAssemblerDWR<d, T, bending>::_assembleDual(const gsMatrix<T> & points, gsThinShellAssemblerBase<T> * assembler, const gsMultiPatch<T> & primal, const gsMultiPatch<T> & deformed, gsVector<T> & result)
1092 {
1093  /* SINGLE PATCH IMPLEMENTATION */
1094  index_t pIndex = 0;
1095  gsMatrix<T> tmp;
1096  gsMatrix<index_t> actives, globalActives;
1097 
1098  GISMO_ASSERT(m_component < d || m_component==9,"Component is out of bounds");
1099 
1100  // For the stretches
1101  // ! Only works with Z=0 for now, since principal stresses and directions are implemented for Z=0
1102  gsMatrix<T> Z(1,1);
1103  Z.setZero();
1105 
1106  gsExprAssembler<T> exprAssembler = assembler->assembler();
1107  exprAssembler.cleanUp();
1108  GISMO_ENSURE(assembler->options().hasGroup("ExprAssembler"),"The option list does not contain options with the label 'ExprAssembler'!");
1109  exprAssembler.setOptions(assembler->options().getGroup("ExprAssembler"));
1110 
1111  // Geometries
1112  geometryMap Gori = exprAssembler.getMap(m_patches); // this map is used for integrals
1113  geometryMap Gdef = exprAssembler.getMap(deformed);
1114 
1115  // Initialize vector
1116  exprAssembler.initSystem();
1117  exprAssembler.initVector(1);
1118  if (points.cols()==0)
1119  {
1120  result = exprAssembler.rhs();
1122  }
1123 
1124  // Space
1125  space space = exprAssembler.trialSpace(0);
1126  // Homogenize Dirichlet
1127  space.setup(m_bcs, dirichlet::homogeneous, 0);
1128 
1129  // Solution
1130  auto usol = exprAssembler.getCoeff(primal);
1131 
1132  // Transformation for stretches
1133  gsMaterialMatrixEval<T,MaterialOutput::StretchTransform> Tstretchf(assembler->materials(),&deformed,Z);
1134  gsMaterialMatrixEval<T,MaterialOutput::PStressTransform> Tpstressf(assembler->materials(),&deformed,Z);
1135  auto Tstretch = exprAssembler.getCoeff(Tstretchf);
1136  auto Tpstress = exprAssembler.getCoeff(Tpstressf);
1137 
1138  // Material tensors at Z
1139  gsMaterialMatrixEval<T,MaterialOutput::MatrixA> mmAf(assembler->materials(),&deformed,Z);
1140  gsMaterialMatrixEval<T,MaterialOutput::MatrixD> mmDf(assembler->materials(),&deformed,Z);
1141  auto mmA = exprAssembler.getCoeff(mmAf);
1142  auto mmD = exprAssembler.getCoeff(mmDf);
1143 
1144  // Material tensors integrated
1145  gsMaterialMatrixIntegrate<T,MaterialOutput::MatrixA> mmAfi(assembler->materials(),&deformed);
1146  gsMaterialMatrixIntegrate<T,MaterialOutput::MatrixB> mmBfi(assembler->materials(),&deformed);
1147  gsMaterialMatrixIntegrate<T,MaterialOutput::MatrixC> mmCfi(assembler->materials(),&deformed);
1148  gsMaterialMatrixIntegrate<T,MaterialOutput::MatrixD> mmDfi(assembler->materials(),&deformed);
1149  auto mmAi = exprAssembler.getCoeff(mmAfi);
1150  auto mmBi = exprAssembler.getCoeff(mmBfi);
1151  auto mmCi = exprAssembler.getCoeff(mmCfi);
1152  auto mmDi = exprAssembler.getCoeff(mmDfi);
1153 
1154  // Stress tensors
1155  gsMaterialMatrixEval<T,MaterialOutput::VectorN> S0f(assembler->materials(),&deformed,Z);
1156  gsMaterialMatrixEval<T,MaterialOutput::VectorM> S1f(assembler->materials(),&deformed,Z);
1157  auto S0 = exprAssembler.getCoeff(S0f);
1158  auto S1 = exprAssembler.getCoeff(S1f);
1159 
1160  // Principal stress tensors
1161  gsMaterialMatrixEval<T,MaterialOutput::PStress> P0f(assembler->materials(),&deformed,Z);
1162  auto P0 = exprAssembler.getCoeff(P0f);
1163 
1164  // Force and moment tensors
1165  gsMaterialMatrixIntegrate<T,MaterialOutput::VectorN> Nf(assembler->materials(),&deformed);
1166  gsMaterialMatrixIntegrate<T,MaterialOutput::VectorM> Mf(assembler->materials(),&deformed);
1167  auto N = exprAssembler.getCoeff(Nf);
1168  auto M = exprAssembler.getCoeff(Mf);
1169 
1170  // Helper matrix for flexural components
1171  gsFunctionExpr<T> mult2t("1","0","0","0","1","0","0","0","2",2);
1172  auto m2 = exprAssembler.getCoeff(mult2t);
1173 
1174  // Deformation gradient and its first variation
1175  // To compensate for the flat, since flat does [E11,E22,2*E12]
1176  gsFunctionExpr<T> mult12t("1","0","0","0","1","0","0","0","0.5",2);
1177  auto m12 = exprAssembler.getCoeff(mult12t);
1178 
1179  auto Cm = flat( jac(Gdef).tr() * jac(Gdef) ) * reshape(m12,3,3);
1180  auto Cm_der = 2* flat( jac(Gdef).tr() * jac(space) ) * reshape(m12,3,3);
1181 
1182  // Principal stretch and its first variation
1183  auto lambda = Cm * reshape(Tstretch,3,3).tr();
1184  auto lambda_der = Cm_der * reshape(Tstretch,3,3).tr();
1185 
1186  // Membrane strain and its first variation
1187  auto Em = 0.5 * ( flat(jac(Gdef).tr()*jac(Gdef)) - flat(jac(Gori).tr()* jac(Gori)) ) ;
1188  auto Em_der = flat( jac(Gdef).tr() * jac(space) ) ;
1189 
1190  // Principal membrane strain and its first variation
1191  auto Emp = (Em * reshape(m12,3,3)) * reshape(Tstretch,3,3).tr();
1192  auto Emp_der= (Em_der * reshape(m12,3,3)) * reshape(Tstretch,3,3).tr();
1193 
1194  // Flexural strain and its first variation
1195  auto Ef = ( deriv2(Gori,sn(Gori).normalized().tr()) - deriv2(Gdef,sn(Gdef).normalized().tr()) ) * reshape(m2,3,3) ;
1196  auto Ef_der = -( deriv2(space,sn(Gdef).normalized().tr() ) + deriv2(Gdef,var1(space,Gdef) ) ) * reshape(m2,3,3);
1197 
1198  // Membrane stress (its first variation)
1199  auto Sm_der = Em_der * reshape(mmA,3,3);
1200 
1201  // Principal membrane stress (its first variation)
1202  auto Smp_der = Sm_der * reshape(Tpstress,3,3).tr();
1203 
1204  // Flexural stress (its first variation)
1205  auto Sf_der = Ef_der * reshape(mmD,3,3);
1206 
1207  // Membrane force (its first variation)
1208  auto N_der = Em_der * reshape(mmAi,3,3) + Ef_der * reshape(mmBi,3,3);
1209  auto M_der = Em_der * reshape(mmCi,3,3) + Ef_der * reshape(mmDi,3,3);
1210 
1211 
1212  gsExprEvaluator<T> ev(exprAssembler);
1213  result.resize(exprAssembler.numDofs());
1214  result.setZero();
1215  if (m_goalFunction == GoalFunction::Displacement)
1216  {
1217  if (m_component==9)
1218  {
1219  auto expr = 2 * space * usol * meas(Gori);
1220  for (index_t k = 0; k!=points.cols(); k++)
1221  {
1222  tmp = ev.eval(expr,points.col(k));
1223  exprAssembler.integrationElements().basis(pIndex).active_into( points.col(k), actives );
1224  for (index_t j = 0; j< space.dim(); ++j)
1225  {
1226  space.mapper().localToGlobal(actives, pIndex, globalActives,j);
1227  for (index_t i=0; i < globalActives.rows(); ++i)
1228  if (space.mapper().is_free_index(globalActives(i,0)))
1229  result.at(globalActives(i,0)) += tmp(i+j*actives.rows(),0);
1230  }
1231  }
1232  }
1233  else
1234  {
1235  auto expr = space * gismo::expr::uv(m_component,3) * meas(Gori);
1236  for (index_t k = 0; k!=points.cols(); k++)
1237  {
1238  tmp = ev.eval(expr,points.col(k));
1239  exprAssembler.integrationElements().basis(pIndex).active_into( points.col(k), actives );
1240  for (index_t j = 0; j< space.dim(); ++j)
1241  {
1242  space.mapper().localToGlobal(actives, pIndex, globalActives,j);
1243  for (index_t i=0; i < globalActives.rows(); ++i)
1244  if (space.mapper().is_free_index(globalActives(i,0)))
1245  result.at(globalActives(i,0)) += tmp(i+j*actives.rows(),0);
1246  }
1247  }
1248  }
1249  }
1250  else if (m_goalFunction == GoalFunction::Stretch)
1251  {
1252  if (m_component==9)
1253  {
1254  auto expr = 2* lambda_der * lambda.tr() * meas(Gori);//<<<--------NOTE: Square missing?
1255  for (index_t k = 0; k!=points.cols(); k++)
1256  {
1257  tmp = ev.eval(expr,points.col(k));
1258  exprAssembler.integrationElements().basis(pIndex).active_into( points.col(k), actives );
1259  for (index_t j = 0; j< space.dim(); ++j)
1260  {
1261  space.mapper().localToGlobal(actives, pIndex, globalActives,j);
1262  for (index_t i=0; i < globalActives.rows(); ++i)
1263  if (space.mapper().is_free_index(globalActives(i,0)))
1264  result.at(globalActives(i,0)) += tmp(i+j*actives.rows(),0);
1265  }
1266  }
1267  }
1268  else
1269  {
1270  auto expr = lambda_der * gismo::expr::uv(m_component,3) * meas(Gori);
1271  for (index_t k = 0; k!=points.cols(); k++)
1272  {
1273  tmp = ev.eval(expr,points.col(k));
1274  exprAssembler.integrationElements().basis(pIndex).active_into( points.col(k), actives );
1275  for (index_t j = 0; j< space.dim(); ++j)
1276  {
1277  space.mapper().localToGlobal(actives, pIndex, globalActives,j);
1278  for (index_t i=0; i < globalActives.rows(); ++i)
1279  if (space.mapper().is_free_index(globalActives(i,0)))
1280  result.at(globalActives(i,0)) += tmp(i+j*actives.rows(),0);
1281  }
1282  }
1283  }
1284  }
1285  else if (m_goalFunction == GoalFunction::PStrain)
1286  {
1287  if (m_component==9)
1288  {
1289  auto expr = 2 * Emp_der * Emp.tr() * meas(Gori);
1290  for (index_t k = 0; k!=points.cols(); k++)
1291  {
1292  tmp = ev.eval(expr,points.col(k));
1293  exprAssembler.integrationElements().basis(pIndex).active_into( points.col(k), actives );
1294  for (index_t j = 0; j< space.dim(); ++j)
1295  {
1296  space.mapper().localToGlobal(actives, pIndex, globalActives,j);
1297  for (index_t i=0; i < globalActives.rows(); ++i)
1298  if (space.mapper().is_free_index(globalActives(i,0)))
1299  result.at(globalActives(i,0)) += tmp(i+j*actives.rows(),0);
1300  }
1301  }
1302  }
1303  else
1304  {
1305  auto expr = Emp_der * gismo::expr::uv(m_component,3) * meas(Gori);
1306  for (index_t k = 0; k!=points.cols(); k++)
1307  {
1308  tmp = ev.eval(expr,points.col(k));
1309  exprAssembler.integrationElements().basis(pIndex).active_into( points.col(k), actives );
1310  for (index_t j = 0; j< space.dim(); ++j)
1311  {
1312  space.mapper().localToGlobal(actives, pIndex, globalActives,j);
1313  for (index_t i=0; i < globalActives.rows(); ++i)
1314  if (space.mapper().is_free_index(globalActives(i,0)))
1315  result.at(globalActives(i,0)) += tmp(i+j*actives.rows(),0);
1316  }
1317  }
1318  }
1319  }
1320  else if (m_goalFunction == GoalFunction::PStress)
1321  {
1322  if (m_component==9)
1323  {
1324  auto expr = 2 * Smp_der * P0 * meas(Gori);
1325  for (index_t k = 0; k!=points.cols(); k++)
1326  {
1327  tmp = ev.eval(expr,points.col(k));
1328  exprAssembler.integrationElements().basis(pIndex).active_into( points.col(k), actives );
1329  for (index_t j = 0; j< space.dim(); ++j)
1330  {
1331  space.mapper().localToGlobal(actives, pIndex, globalActives,j);
1332  for (index_t i=0; i < globalActives.rows(); ++i)
1333  if (space.mapper().is_free_index(globalActives(i,0)))
1334  result.at(globalActives(i,0)) += tmp(i+j*actives.rows(),0);
1335  }
1336  }
1337  }
1338  else
1339  {
1340  auto expr = Smp_der * gismo::expr::uv(m_component,3) * meas(Gori);
1341  for (index_t k = 0; k!=points.cols(); k++)
1342  {
1343  tmp = ev.eval(expr,points.col(k));
1344  exprAssembler.integrationElements().basis(pIndex).active_into( points.col(k), actives );
1345  for (index_t j = 0; j< space.dim(); ++j)
1346  {
1347  space.mapper().localToGlobal(actives, pIndex, globalActives,j);
1348  for (index_t i=0; i < globalActives.rows(); ++i)
1349  if (space.mapper().is_free_index(globalActives(i,0)))
1350  result.at(globalActives(i,0)) += tmp(i+j*actives.rows(),0);
1351  }
1352  }
1353  }
1354  }
1355  else if (m_goalFunction == GoalFunction::MembraneStrain)
1356  {
1357  if (m_component==9)
1358  {
1359  auto expr = 2 * Em_der * Em.tr() * meas(Gori);
1360  for (index_t k = 0; k!=points.cols(); k++)
1361  {
1362  tmp = ev.eval(expr,points.col(k));
1363  exprAssembler.integrationElements().basis(pIndex).active_into( points.col(k), actives );
1364  for (index_t j = 0; j< space.dim(); ++j)
1365  {
1366  space.mapper().localToGlobal(actives, pIndex, globalActives,j);
1367  for (index_t i=0; i < globalActives.rows(); ++i)
1368  if (space.mapper().is_free_index(globalActives(i,0)))
1369  result.at(globalActives(i,0)) += tmp(i+j*actives.rows(),0);
1370  }
1371  }
1372  }
1373  else
1374  {
1375  auto expr = Em_der * gismo::expr::uv(m_component,3) * meas(Gori);
1376  for (index_t k = 0; k!=points.cols(); k++)
1377  {
1378  tmp = ev.eval(expr,points.col(k));
1379  exprAssembler.integrationElements().basis(pIndex).active_into( points.col(k), actives );
1380  for (index_t j = 0; j< space.dim(); ++j)
1381  {
1382  space.mapper().localToGlobal(actives, pIndex, globalActives,j);
1383  for (index_t i=0; i < globalActives.rows(); ++i)
1384  if (space.mapper().is_free_index(globalActives(i,0)))
1385  result.at(globalActives(i,0)) += tmp(i+j*actives.rows(),0);
1386  }
1387  }
1388  }
1389  }
1390  else if (m_goalFunction == GoalFunction::MembraneStress)
1391  {
1392  if (m_component==9)
1393  {
1394  auto expr = 2 * Sm_der * S0 * meas(Gori);
1395  for (index_t k = 0; k!=points.cols(); k++)
1396  {
1397  tmp = ev.eval(expr,points.col(k));
1398  exprAssembler.integrationElements().basis(pIndex).active_into( points.col(k), actives );
1399  for (index_t j = 0; j< space.dim(); ++j)
1400  {
1401  space.mapper().localToGlobal(actives, pIndex, globalActives,j);
1402  for (index_t i=0; i < globalActives.rows(); ++i)
1403  if (space.mapper().is_free_index(globalActives(i,0)))
1404  result.at(globalActives(i,0)) += tmp(i+j*actives.rows(),0);
1405  }
1406  }
1407  }
1408  else
1409  {
1410  auto expr = Sm_der * gismo::expr::uv(m_component,3) * meas(Gori);
1411  for (index_t k = 0; k!=points.cols(); k++)
1412  {
1413  tmp = ev.eval(expr,points.col(k));
1414  exprAssembler.integrationElements().basis(pIndex).active_into( points.col(k), actives );
1415  for (index_t j = 0; j< space.dim(); ++j)
1416  {
1417  space.mapper().localToGlobal(actives, pIndex, globalActives,j);
1418  for (index_t i=0; i < globalActives.rows(); ++i)
1419  if (space.mapper().is_free_index(globalActives(i,0)))
1420  result.at(globalActives(i,0)) += tmp(i+j*actives.rows(),0);
1421  }
1422  }
1423  }
1424  }
1425  else if (m_goalFunction == GoalFunction::MembraneForce)
1426  {
1427  if (m_component==9)
1428  {
1429  auto expr = 2 * N_der * N * meas(Gori);
1430  for (index_t k = 0; k!=points.cols(); k++)
1431  {
1432  tmp = ev.eval(expr,points.col(k));
1433  exprAssembler.integrationElements().basis(pIndex).active_into( points.col(k), actives );
1434  for (index_t j = 0; j< space.dim(); ++j)
1435  {
1436  space.mapper().localToGlobal(actives, pIndex, globalActives,j);
1437  for (index_t i=0; i < globalActives.rows(); ++i)
1438  if (space.mapper().is_free_index(globalActives(i,0)))
1439  result.at(globalActives(i,0)) += tmp(i+j*actives.rows(),0);
1440  }
1441  }
1442  }
1443  else
1444  {
1445  // remove N_der from this scipe
1446  auto expr = N.tr() * gismo::expr::uv(m_component,3) * meas(Gori);
1447  for (index_t k = 0; k!=points.cols(); k++)
1448  {
1449  tmp = ev.eval(expr,points.col(k));
1450  exprAssembler.integrationElements().basis(pIndex).active_into( points.col(k), actives );
1451  for (index_t j = 0; j< space.dim(); ++j)
1452  {
1453  space.mapper().localToGlobal(actives, pIndex, globalActives,j);
1454  for (index_t i=0; i < globalActives.rows(); ++i)
1455  if (space.mapper().is_free_index(globalActives(i,0)))
1456  result.at(globalActives(i,0)) += tmp(i+j*actives.rows(),0);
1457  }
1458  }
1459  }
1460  }
1461  else if (m_goalFunction == GoalFunction::FlexuralStrain)
1462  {
1463  if (m_component==9)
1464  {
1465  auto expr = 2 * Ef_der * Ef.tr() * meas(Gori);
1466  for (index_t k = 0; k!=points.cols(); k++)
1467  {
1468  tmp = ev.eval(expr,points.col(k));
1469  exprAssembler.integrationElements().basis(pIndex).active_into( points.col(k), actives );
1470  for (index_t j = 0; j< space.dim(); ++j)
1471  {
1472  space.mapper().localToGlobal(actives, pIndex, globalActives,j);
1473  for (index_t i=0; i < globalActives.rows(); ++i)
1474  if (space.mapper().is_free_index(globalActives(i,0)))
1475  result.at(globalActives(i,0)) += tmp(i+j*actives.rows(),0);
1476  }
1477  }
1478  }
1479  else
1480  {
1481  auto expr = Ef_der * gismo::expr::uv(m_component,3) * meas(Gori);
1482  for (index_t k = 0; k!=points.cols(); k++)
1483  {
1484  tmp = ev.eval(expr,points.col(k));
1485  exprAssembler.integrationElements().basis(pIndex).active_into( points.col(k), actives );
1486  for (index_t j = 0; j< space.dim(); ++j)
1487  {
1488  space.mapper().localToGlobal(actives, pIndex, globalActives,j);
1489  for (index_t i=0; i < globalActives.rows(); ++i)
1490  if (space.mapper().is_free_index(globalActives(i,0)))
1491  result.at(globalActives(i,0)) += tmp(i+j*actives.rows(),0);
1492  }
1493  }
1494  }
1495  }
1496  else if (m_goalFunction == GoalFunction::FlexuralStress)
1497  {
1498  if (m_component==9)
1499  {
1500  auto expr = 2 * Sf_der * S1 * meas(Gori);
1501  for (index_t k = 0; k!=points.cols(); k++)
1502  {
1503  tmp = ev.eval(expr,points.col(k));
1504  exprAssembler.integrationElements().basis(pIndex).active_into( points.col(k), actives );
1505  for (index_t j = 0; j< space.dim(); ++j)
1506  {
1507  space.mapper().localToGlobal(actives, pIndex, globalActives,j);
1508  for (index_t i=0; i < globalActives.rows(); ++i)
1509  if (space.mapper().is_free_index(globalActives(i,0)))
1510  result.at(globalActives(i,0)) += tmp(i+j*actives.rows(),0);
1511  }
1512  }
1513  }
1514  else
1515  {
1516  auto expr = Sf_der * gismo::expr::uv(m_component,3) * meas(Gori);
1517  for (index_t k = 0; k!=points.cols(); k++)
1518  {
1519  tmp = ev.eval(expr,points.col(k));
1520  exprAssembler.integrationElements().basis(pIndex).active_into( points.col(k), actives );
1521  for (index_t j = 0; j< space.dim(); ++j)
1522  {
1523  space.mapper().localToGlobal(actives, pIndex, globalActives,j);
1524  for (index_t i=0; i < globalActives.rows(); ++i)
1525  if (space.mapper().is_free_index(globalActives(i,0)))
1526  result.at(globalActives(i,0)) += tmp(i+j*actives.rows(),0);
1527  }
1528  }
1529  }
1530  }
1531  else if (m_goalFunction == GoalFunction::FlexuralMoment)
1532  {
1533  if (m_component==9)
1534  {
1535  auto expr = 2 * M_der * M * meas(Gori);
1536  for (index_t k = 0; k!=points.cols(); k++)
1537  {
1538  tmp = ev.eval(expr,points.col(k));
1539  exprAssembler.integrationElements().basis(pIndex).active_into( points.col(k), actives );
1540  for (index_t j = 0; j< space.dim(); ++j)
1541  {
1542  space.mapper().localToGlobal(actives, pIndex, globalActives,j);
1543  for (index_t i=0; i < globalActives.rows(); ++i)
1544  if (space.mapper().is_free_index(globalActives(i,0)))
1545  result.at(globalActives(i,0)) += tmp(i+j*actives.rows(),0);
1546  }
1547  }
1548  }
1549  else
1550  {
1551  // remove N_der from this scipe
1552  auto expr = M_der * gismo::expr::uv(m_component,3) * meas(Gori);
1553  for (index_t k = 0; k!=points.cols(); k++)
1554  {
1555  tmp = ev.eval(expr,points.col(k));
1556  exprAssembler.integrationElements().basis(pIndex).active_into( points.col(k), actives );
1557  for (index_t j = 0; j< space.dim(); ++j)
1558  {
1559  space.mapper().localToGlobal(actives, pIndex, globalActives,j);
1560  for (index_t i=0; i < globalActives.rows(); ++i)
1561  if (space.mapper().is_free_index(globalActives(i,0)))
1562  result.at(globalActives(i,0)) += tmp(i+j*actives.rows(),0);
1563  }
1564  }
1565  }
1566  }
1567  else
1568  GISMO_ERROR("Goal function not known");
1569 
1571 };
1572 
1573 
1574 // template <short_t d, class T, bool bending>
1575 // gsVector<T> gsThinShellAssemblerDWR<d, T, bending>::_assembleDual_point(const gsMatrix<T> & points, gsThinShellAssemblerBase<T> * assembler, const gsMatrix<T> & tmp)
1576 // {
1577 // /* SINGLE PATCH IMPLEMENTATION */
1578 // index_t pIndex = 0;
1579 // gsVector<T> result;
1580 // gsMatrix<index_t> actives, globalActives;
1581 
1582 // space space = exprAssembler.trialSpace(0);
1583 
1584 // result.resize(exprAssembler.numDofs());
1585 // result.setZero();
1586 
1587 // for (index_t k = 0; k!=u.cols(); k++)
1588 // {
1589 // tmp = ev.eval(expr,u.col(k));
1590 // basis.front().basis(pIndex).active_into( u.col(k), actives ); // note: takes the first patch of pids as patch id. Works for non-overlapping patches.
1591 // for (index_t j = 0; j< space.dim(); ++j)
1592 // {
1593 // space.mapper().localToGlobal(actives, pIndex, globalActives,j);
1594 // for (index_t i=0; i < globalActives.rows(); ++i)
1595 // if (v.mapper().is_free_index(globalActs(i,0)))
1596 // result.at(globalActives(i,0)) += tmp(i,0);
1597 // }
1598 
1599 // }
1600 
1601 // return result;
1602 // }
1603 
1604 template <short_t d, class T, bool bending>
1605 void gsThinShellAssemblerDWR<d, T, bending>::updateMultiPatchL(const gsMatrix<T> & solVector, gsMultiPatch<T> & result)
1606 {
1607  m_assemblerL->updateMultiPatch(solVector,result);
1608 }
1609 
1610 template <short_t d, class T, bool bending>
1611 void gsThinShellAssemblerDWR<d, T, bending>::updateMultiPatchH(const gsMatrix<T> & solVector, gsMultiPatch<T> & result)
1612 {
1613  m_assemblerH->updateMultiPatch(solVector,result);
1614 }
1615 
1616 template <short_t d, class T, bool bending>
1617 void gsThinShellAssemblerDWR<d, T, bending>::constructMultiPatchL(const gsMatrix<T> & solVector, gsMultiPatch<T> & result)
1618 {
1619  result = m_assemblerL->constructMultiPatch(solVector);
1620 }
1621 
1622 template <short_t d, class T, bool bending>
1623 void gsThinShellAssemblerDWR<d, T, bending>::constructMultiPatchH(const gsMatrix<T> & solVector, gsMultiPatch<T> & result)
1624 {
1625  result = m_assemblerH->constructMultiPatch(solVector);
1626 }
1627 
1628 template <short_t d, class T, bool bending>
1629 void gsThinShellAssemblerDWR<d, T, bending>::constructSolutionL(const gsMatrix<T> & solVector, gsMultiPatch<T> & deformed)
1630 {
1631  m_assemblerL->constructSolution(solVector,deformed);
1632 }
1633 
1634 template <short_t d, class T, bool bending>
1635 void gsThinShellAssemblerDWR<d, T, bending>::constructSolutionH(const gsMatrix<T> & solVector, gsMultiPatch<T> & deformed)
1636 {
1637  m_assemblerH->constructSolution(solVector,deformed);
1638 }
1639 
1640 template <short_t d, class T, bool bending>
1641 gsMultiPatch<T> gsThinShellAssemblerDWR<d, T, bending>::constructSolutionL(const gsMatrix<T> & solVector)
1642 {
1643  return m_assemblerL->constructSolution(solVector);
1644 }
1645 
1646 template <short_t d, class T, bool bending>
1647 gsMultiPatch<T> gsThinShellAssemblerDWR<d, T, bending>::constructSolutionH(const gsMatrix<T> & solVector)
1648 {
1649  return m_assemblerH->constructSolution(solVector);
1650 }
1651 
1652 template <short_t d, class T, bool bending>
1653 gsMultiPatch<T> gsThinShellAssemblerDWR<d, T, bending>::constructDisplacementL(const gsMatrix<T> & solVector)
1654 {
1655  return m_assemblerL->constructDisplacement(solVector);
1656 }
1657 
1658 template <short_t d, class T, bool bending>
1659 gsMultiPatch<T> gsThinShellAssemblerDWR<d, T, bending>::constructDisplacementH(const gsMatrix<T> & solVector)
1660 {
1661  return m_assemblerH->constructDisplacement(solVector);
1662 }
1663 
1664 template <short_t d, class T, bool bending>
1665 gsVector<T> gsThinShellAssemblerDWR<d, T, bending>::constructSolutionVectorL(const gsMultiPatch<T> & deformed)
1666 {
1667  return m_assemblerL->constructSolutionVector(deformed);
1668 }
1669 
1670 template <short_t d, class T, bool bending>
1671 gsVector<T> gsThinShellAssemblerDWR<d, T, bending>::constructSolutionVectorH(const gsMultiPatch<T> & deformed)
1672 {
1673  return m_assemblerH->constructSolutionVector(deformed);
1674 }
1675 
1676 template <short_t d, class T, bool bending>
1677 gsMatrix<T> gsThinShellAssemblerDWR<d, T, bending>::projectL2_L(const gsFunction<T> &fun)
1678 {
1679  return m_assemblerL->projectL2(fun);
1680 }
1681 
1682 template <short_t d, class T, bool bending>
1683 gsMatrix<T> gsThinShellAssemblerDWR<d, T, bending>::projectL2_H(const gsFunction<T> &fun)
1684 {
1685  return m_assemblerH->projectL2(fun);
1686 }
1687 
1689 template <short_t d, class T, bool bending>
1690 T gsThinShellAssemblerDWR<d, T, bending>::computeError(const gsMultiPatch<T> & dualL, const gsMultiPatch<T> & dualH, bool withLoads,
1691  std::string filename, unsigned np, bool parametric, bool mesh)
1692 {
1693  computeError_impl<0>(dualL,dualH,withLoads,filename,np,parametric,mesh);
1694  return m_error;
1695 }
1696 
1697 template <short_t d, class T, bool bending>
1698 std::vector<T> gsThinShellAssemblerDWR<d, T, bending>::computeErrorElements(const gsMultiPatch<T> & dualL, const gsMultiPatch<T> & dualH, bool withLoads,
1699  std::string filename, unsigned np, bool parametric, bool mesh)
1700 {
1701  computeError_impl<1>(dualL,dualH,withLoads,filename,np,parametric,mesh);
1702  return m_errors;
1703 }
1704 
1705 template <short_t d, class T, bool bending>
1706 std::vector<T> gsThinShellAssemblerDWR<d, T, bending>::computeErrorDofs(const gsMultiPatch<T> & dualL, const gsMultiPatch<T> & dualH, bool withLoads,
1707  std::string filename, unsigned np, bool parametric, bool mesh)
1708 {
1709  computeError_impl<2>(dualL,dualH,withLoads,filename,np,parametric,mesh);
1710  return m_errors;
1711 }
1712 
1713 template <short_t d, class T, bool bending>
1714 template <index_t _elWise>
1715 void gsThinShellAssemblerDWR<d, T, bending>::computeError_impl( const gsMultiPatch<T> & dualL,
1716  const gsMultiPatch<T> & dualH,
1717  bool withLoads,
1718  std::string filename,
1719  unsigned np,
1720  bool parametric,
1721  bool mesh)
1722 {
1723  gsExprAssembler<T> exprAssembler = m_assemblerH->assembler();
1724  exprAssembler.cleanUp();
1725  GISMO_ENSURE(m_assemblerH->options().hasGroup("ExprAssembler"),"The option list does not contain options with the label 'ExprAssembler'!");
1726  exprAssembler.setOptions(m_assemblerH->options().getGroup("ExprAssembler"));
1727 
1728  // Geometries
1729  geometryMap Gori = exprAssembler.getMap(m_patches);
1730 
1731  auto F = exprAssembler.getCoeff(*m_forceFun, Gori);
1732  auto zsolL = exprAssembler.getCoeff(dualL);
1733  auto zsolH = exprAssembler.getCoeff(dualH);
1734 
1735  auto g_N = exprAssembler.getBdrFunction(Gori);
1736 
1737  auto expr = (zsolH-zsolL).tr() * F;
1738  auto bexpr= (zsolH-zsolL).tr() * g_N;
1739 
1740  gsExprEvaluator<T> ev(exprAssembler);
1741 
1742  T integral, bintegral;
1743  if (_elWise == 0)
1744  {
1745  integral = ev.integral(expr * meas(Gori)); // this one before otherwise it gives an error (?)
1746  bintegral = ev.integralBdrBc( m_bcs.get("Neumann"), bexpr * tv(Gori).norm());
1747  if (m_pLoads.numLoads()!=0 && withLoads)
1748  _applyLoadsToError(dualL,dualH,integral);
1749 
1750  m_error = integral+bintegral;
1751  }
1752  else if (_elWise == 1) // element-wise
1753  {
1754  m_error = ev.integralElWise(expr * meas(Gori));
1755  if (m_pLoads.numLoads()!=0 && withLoads)
1756  _applyLoadsToError(dualL,dualH,m_error);
1757  m_errors = ev.elementwise();
1758  if (m_pLoads.numLoads()!=0 && withLoads)
1759  _applyLoadsToElWiseError(dualL,dualH,m_errors);
1760  }
1761  else if (_elWise == 2) // function-wise
1762  {
1763  integral = 0;
1764  }
1765  else
1766  GISMO_ERROR("Unknown");
1767 
1768  if (!filename.empty())
1769  {
1770  ev.options().setSwitch("plot.elements",mesh);
1771  ev.options().setInt("plot.npts",np);
1772  // if (parametric)
1773  // ev.writeParaview(expr,filename);
1774  // else
1775  ev.writeParaview(expr,Gori,filename);
1776  }
1777 }
1778 
1779 template <short_t d, class T, bool bending>
1780 T gsThinShellAssemblerDWR<d, T, bending>::computeError(const gsMultiPatch<T> & dualL, const gsMultiPatch<T> & dualH, const gsMultiPatch<T> & deformed, bool withLoads,
1781  std::string filename, unsigned np, bool parametric, bool mesh)
1782 {
1783  computeError_impl<d,bending,0>(dualL,dualH,deformed,withLoads,filename,np,parametric,mesh);
1784  return m_error;
1785 }
1786 
1787 template <short_t d, class T, bool bending>
1788 std::vector<T> gsThinShellAssemblerDWR<d, T, bending>::computeErrorElements(const gsMultiPatch<T> & dualL, const gsMultiPatch<T> & dualH, const gsMultiPatch<T> & deformed, bool withLoads,
1789  std::string filename, unsigned np, bool parametric, bool mesh)
1790 {
1791  computeError_impl<d,bending,1>(dualL,dualH,deformed,withLoads,filename,np,parametric,mesh);
1792  return m_errors;
1793 }
1794 
1795 template <short_t d, class T, bool bending>
1796 std::vector<T> gsThinShellAssemblerDWR<d, T, bending>::computeErrorDofs(const gsMultiPatch<T> & dualL, const gsMultiPatch<T> & dualH, const gsMultiPatch<T> & deformed, bool withLoads,
1797  std::string filename, unsigned np, bool parametric, bool mesh)
1798 {
1799  computeError_impl<d,bending,2>(dualL,dualH,deformed,withLoads,filename,np,parametric,mesh);
1800  return m_errors;
1801 }
1802 
1803 template <short_t d, class T, bool bending>
1804 template<short_t _d, bool _bending, index_t _elWise>
1805 typename std::enable_if<(_d==3) && _bending, void>::type
1806 gsThinShellAssemblerDWR<d, T, bending>::computeError_impl(const gsMultiPatch<T> & dualL, const gsMultiPatch<T> & dualH, const gsMultiPatch<T> & deformed, bool withLoads,
1807  // bool withLoads,
1808  std::string filename, unsigned np, bool parametric, bool mesh)
1809 
1810 {
1811  gsExprAssembler<T> exprAssembler = m_assemblerH->assembler();
1812  exprAssembler.cleanUp();
1813  GISMO_ENSURE(m_assemblerH->options().hasGroup("ExprAssembler"),"The option list does not contain options with the label 'ExprAssembler'!");
1814  exprAssembler.setOptions(m_assemblerH->options().getGroup("ExprAssembler"));
1815 
1816  // Geometries
1817  geometryMap Gori = exprAssembler.getMap(m_patches); // this map is used for integrals
1818  geometryMap Gdef = exprAssembler.getMap(deformed);
1819 
1820  gsMaterialMatrixIntegrate<T,MaterialOutput::VectorN> S0f(m_assemblerH->materials(),&deformed);
1821  gsMaterialMatrixIntegrate<T,MaterialOutput::VectorM> S1f(m_assemblerH->materials(),&deformed);
1822  auto S0 = exprAssembler.getCoeff(S0f);
1823  auto S1 = exprAssembler.getCoeff(S1f);
1824 
1825  gsFunctionExpr<T> mult2t("1","0","0","0","1","0","0","0","2",2);
1826  auto m2 = exprAssembler.getCoeff(mult2t);
1827 
1828  auto F = exprAssembler.getCoeff(*m_forceFun, Gori);
1829  auto zsolL = exprAssembler.getCoeff(dualL);
1830  auto zsolH = exprAssembler.getCoeff(dualH);
1831  // auto m_thick = exprAssembler.getCoeff(*m_thickFun, m_ori);
1832 
1833  Base::homogenizeDirichlet();
1834 
1835  auto N = S0.tr();
1836  // auto Em_der = flat( jac(Gdef).tr() * jac(m_space) ) ;
1837  auto Em_der = flat( jac(Gdef).tr() * (jac(zsolH) - jac(zsolL)) ) ;
1838 
1839  auto M = S1.tr(); // output is a column
1840  // auto Ef_der = -( deriv2(space,sn(Gdef).normalized().tr() ) + deriv2(Gdef,var1(space,Gdef) ) ) * reshape(m2,3,3);
1841  auto Ef_der = -( deriv2(zsolH,sn(Gdef).normalized().tr() )
1842  - deriv2(zsolL,sn(Gdef).normalized().tr() ) + deriv2(Gdef,var1(zsolH,Gdef) )
1843  - deriv2(Gdef,var1(zsolL,Gdef) ) ) * reshape(m2,3,3);
1844 
1845  auto Fext = (zsolH-zsolL).tr() * F;
1846  auto Fint = ( N * Em_der.tr() + M * Ef_der.tr() );
1847 
1848  auto g_N = exprAssembler.getBdrFunction(Gori);
1849 
1850  auto expr = ( Fext - Fint );
1851  auto bexpr= (zsolH-zsolL).tr() * g_N;
1852 
1853  gsExprEvaluator<T> ev(exprAssembler);
1854 
1855  T integral, bintegral = 0;
1856  if (_elWise == 0)
1857  {
1858  if (withLoads)
1859  bintegral = ev.integralBdrBc( m_bcs.get("Neumann"), bexpr * tv(Gori).norm()); // goes wrong with sizes?
1860  integral = ev.integral(expr * meas(Gori));
1861  if (m_pLoads.numLoads()!=0 && withLoads)
1862  _applyLoadsToError(dualL,dualH,integral);
1863 
1864  m_error = integral+bintegral;
1865  }
1866  else if (_elWise == 1) // element-wise
1867  {
1868  m_error = ev.integralElWise(expr * meas(Gori));
1869  if (m_pLoads.numLoads()!=0 && withLoads)
1870  _applyLoadsToError(dualL,dualH,m_error);
1871  m_errors = ev.elementwise();
1872  if (m_pLoads.numLoads()!=0 && withLoads)
1873  _applyLoadsToElWiseError(dualL,dualH,m_errors);
1874  }
1875  else if (_elWise == 2) // function-wise
1876  {
1877  integral = 0;
1878  }
1879  else
1880  GISMO_ERROR("Unknown");
1881 
1882  // if (m_foundInd)
1883  // {
1884  // auto foundation = exprAssembler.getCoeff(*m_foundFun, Gori);
1885  // GISMO_ASSERT(m_foundFun->targetDim()==3,"Foundation function has dimension "<<m_foundFun->targetDim()<<", but expected 3");
1886 
1887  // integral += ev.integral( ( zsolH - zsolL ) * foundation.asDiag() * (Gdef - Gori) * meas(Gori) ); // [v_x,v_y,v_z] diag([k_x,k_y,k_z]) [u_x; u_y; u_z]
1888  // }
1889  // if (m_pressInd)
1890  // {
1891  // auto pressure = exprAssembler.getCoeff(*m_pressFun, Gori);
1892  // GISMO_ASSERT(m_pressFun->targetDim()==1,"Pressure function has dimension "<<m_pressFun->targetDim()<<", but expected 1");
1893 
1894  // integral += ev.integral( pressure.val() * ( zsolH - zsolL ) * sn(Gdef).normalized() * meas(Gori) );
1895  // }
1896 
1897  if (!filename.empty())
1898  {
1899  ev.options().setSwitch("plot.elements",mesh);
1900  ev.options().setInt("plot.npts",np);
1901  // if (parametric)
1902  // ev.writeParaview(expr,filename);
1903  // else
1904  ev.writeParaview(expr,Gori,filename);
1905  }
1906 }
1907 
1908 template <short_t d, class T, bool bending>
1909 template<short_t _d, bool _bending, index_t _elWise>
1910 typename std::enable_if<!(_d==3 && _bending), void>::type
1911 gsThinShellAssemblerDWR<d, T, bending>::computeError_impl( const gsMultiPatch<T> & dualL,
1912  const gsMultiPatch<T> & dualH,
1913  const gsMultiPatch<T> & deformed,
1914  bool withLoads,
1915  std::string filename,
1916  unsigned np,
1917  bool parametric,
1918  bool mesh)
1919 {
1920  gsExprAssembler<T> exprAssembler = m_assemblerH->assembler();
1921  exprAssembler.cleanUp();
1922  GISMO_ENSURE(m_assemblerH->options().hasGroup("ExprAssembler"),"The option list does not contain options with the label 'ExprAssembler'!");
1923  exprAssembler.setOptions(m_assemblerH->options().getGroup("ExprAssembler"));
1924 
1925  // Geometries
1926  geometryMap Gori = exprAssembler.getMap(m_patches); // this map is used for integrals
1927  geometryMap Gdef = exprAssembler.getMap(deformed);
1928 
1929  gsMaterialMatrixIntegrate<T,MaterialOutput::VectorN> S0f(m_assemblerH->materials(),&deformed);
1930  auto S0 = exprAssembler.getCoeff(S0f);
1931 
1932  auto F = exprAssembler.getCoeff(*m_forceFun, Gori);
1933 
1934  auto zsolL = exprAssembler.getCoeff(dualL);
1935  auto zsolH = exprAssembler.getCoeff(dualH);
1936  // auto m_thick = exprAssembler.getCoeff(*m_thickFun, m_ori);
1937 
1938  auto N = S0.tr();
1939  // auto Em_der = flat( jac(Gdef).tr() * jac(m_space) ) ;
1940  auto Em_der = flat( jac(Gdef).tr() * (jac(zsolH) - jac(zsolL)) ) ;
1941 
1942  auto Fext = (zsolH-zsolL).tr() * F;
1943  auto Fint = ( N * Em_der.tr() );
1944 
1945  auto g_N = exprAssembler.getBdrFunction(Gori);
1946 
1947  auto expr = ( Fext - Fint );
1948  auto bexpr= (zsolH-zsolL).tr() * g_N;
1949 
1950  gsExprEvaluator<T> ev(exprAssembler);
1951 
1952  T integral, bintegral;
1953  if (_elWise == 0)
1954  {
1955  bintegral = ev.integralBdrBc( m_bcs.get("Neumann"), bexpr * tv(Gori).norm());
1956  integral = ev.integral(expr * meas(Gori));
1957  m_error = bintegral+integral;
1958  if (m_pLoads.numLoads()!=0 && withLoads)
1959  _applyLoadsToError(dualL,dualH,m_error);
1960  }
1961  else if (_elWise == 1) // element-wise
1962  {
1963  m_error = ev.integralElWise(expr * meas(Gori));
1964  if (m_pLoads.numLoads()!=0 && withLoads)
1965  _applyLoadsToError(dualL,dualH,m_error);
1966  m_errors = ev.elementwise();
1967  if (m_pLoads.numLoads()!=0 && withLoads)
1968  _applyLoadsToElWiseError(dualL,dualH,m_errors);
1969  }
1970  else if (_elWise == 2) // function-wise
1971  {
1972  integral = 0;
1973  }
1974  else
1975  GISMO_ERROR("Unknown");
1976  // if (m_foundInd)
1977  // {
1978  // auto foundation = exprAssembler.getCoeff(*m_foundFun, Gori);
1979  // GISMO_ASSERT(m_foundFun->targetDim()==3,"Foundation function has dimension "<<m_foundFun->targetDim()<<", but expected 3");
1980 
1981  // integral += ev.integral( ( zsolH - zsolL ) * foundation.asDiag() * (Gdef - Gori) * meas(Gori) ); // [v_x,v_y,v_z] diag([k_x,k_y,k_z]) [u_x; u_y; u_z]
1982  // }
1983  // if (m_pressInd)
1984  // {
1985  // auto pressure = exprAssembler.getCoeff(*m_pressFun, Gori);
1986  // GISMO_ASSERT(m_pressFun->targetDim()==1,"Pressure function has dimension "<<m_pressFun->targetDim()<<", but expected 1");
1987 
1988  // integral += ev.integral( pressure.val() * ( zsolH - zsolL ) * sn(Gdef).normalized() * meas(Gori) );
1989  // }
1990 
1991  if (!filename.empty())
1992  {
1993  ev.options().setSwitch("plot.elements",mesh);
1994  ev.options().setInt("plot.npts",np);
1995  // if (parametric)
1996  // ev.writeParaview(expr,filename);
1997  // else
1998  ev.writeParaview(expr,Gori,filename);
1999  }
2000 }
2001 
2002 template <short_t d, class T, bool bending>
2003 T gsThinShellAssemblerDWR<d, T, bending>::computeSquaredError(const gsMultiPatch<T> & dualL, const gsMultiPatch<T> & dualH, bool withLoads,
2004  std::string filename, unsigned np, bool parametric, bool mesh)
2005 {
2006  computeSquaredError_impl<0>(dualL,dualH,withLoads,filename,np,parametric,mesh);
2007  return m_error;
2008 }
2009 
2010 template <short_t d, class T, bool bending>
2011 std::vector<T> gsThinShellAssemblerDWR<d, T, bending>::computeSquaredErrorElements(const gsMultiPatch<T> & dualL, const gsMultiPatch<T> & dualH, bool withLoads,
2012  std::string filename, unsigned np, bool parametric, bool mesh)
2013 {
2014  computeSquaredError_impl<1>(dualL,dualH,withLoads,filename,np,parametric,mesh);
2015  return m_errors;
2016 }
2017 
2018 template <short_t d, class T, bool bending>
2019 std::vector<T> gsThinShellAssemblerDWR<d, T, bending>::computeSquaredErrorDofs(const gsMultiPatch<T> & dualL, const gsMultiPatch<T> & dualH, bool withLoads,
2020  std::string filename, unsigned np, bool parametric, bool mesh)
2021 {
2022  computeSquaredError_impl<2>(dualL,dualH,withLoads,filename,np,parametric,mesh);
2023  return m_errors;
2024 }
2025 
2026 template <short_t d, class T, bool bending>
2027 template <index_t _elWise>
2028 void gsThinShellAssemblerDWR<d, T, bending>::computeSquaredError_impl( const gsMultiPatch<T> & dualL,
2029  const gsMultiPatch<T> & dualH,
2030  bool withLoads,
2031  std::string filename,
2032  unsigned np,
2033  bool parametric,
2034  bool mesh)
2035 {
2036  gsExprAssembler<T> exprAssembler = m_assemblerH->assembler();
2037  exprAssembler.cleanUp();
2038  GISMO_ENSURE(m_assemblerH->options().hasGroup("ExprAssembler"),"The option list does not contain options with the label 'ExprAssembler'!");
2039  exprAssembler.setOptions(m_assemblerH->options().getGroup("ExprAssembler"));
2040 
2041  // Geometries
2042  geometryMap Gori = exprAssembler.getMap(m_patches);
2043 
2044  auto F = exprAssembler.getCoeff(*m_forceFun, Gori);
2045  auto zsolL = exprAssembler.getCoeff(dualL);
2046  auto zsolH = exprAssembler.getCoeff(dualH);
2047 
2048  auto g_N = exprAssembler.getBdrFunction(Gori);
2049 
2050  auto expr = ((zsolH-zsolL).tr() * F).sqNorm();
2051  auto bexpr= (zsolH-zsolL).tr() * g_N;
2052 
2053  gsExprEvaluator<T> ev(exprAssembler);
2054 
2055  T integral, bintegral;
2056  if (_elWise == 0)
2057  {
2058  integral = ev.integral(expr * meas(Gori)); // this one before otherwise it gives an error (?)
2059  bintegral = ev.integralBdrBc( m_bcs.get("Neumann"), bexpr * tv(Gori).norm());
2060  if (m_pLoads.numLoads()!=0 && withLoads)
2061  _applyLoadsToError(dualL,dualH,integral);
2062 
2063  m_error = integral+bintegral;
2064  }
2065  else if (_elWise == 1) // element-wise
2066  {
2067  m_error = ev.integralElWise(expr * meas(Gori));
2068  if (m_pLoads.numLoads()!=0 && withLoads)
2069  _applyLoadsToError(dualL,dualH,m_error);
2070  m_errors = ev.elementwise();
2071  if (m_pLoads.numLoads()!=0 && withLoads)
2072  _applyLoadsToElWiseError(dualL,dualH,m_errors);
2073  }
2074  else if (_elWise == 2) // function-wise
2075  {
2076  integral = 0;
2077  }
2078  else
2079  GISMO_ERROR("Unknown");
2080 
2081  if (!filename.empty())
2082  {
2083  ev.options().setSwitch("plot.elements",mesh);
2084  ev.options().setInt("plot.npts",np);
2085  // if (parametric)
2086  // ev.writeParaview(expr,filename);
2087  // else
2088  ev.writeParaview(expr,Gori,filename);
2089  }
2090 }
2091 
2092 template <short_t d, class T, bool bending>
2093 T gsThinShellAssemblerDWR<d, T, bending>::computeSquaredError(const gsMultiPatch<T> & dualL, const gsMultiPatch<T> & dualH, const gsMultiPatch<T> & deformed, bool withLoads,
2094  std::string filename, unsigned np, bool parametric, bool mesh)
2095 {
2096  computeSquaredError_impl<d,bending,0>(dualL,dualH,deformed,withLoads,filename,np,parametric,mesh);
2097  return m_error;
2098 }
2099 
2100 template <short_t d, class T, bool bending>
2101 std::vector<T> gsThinShellAssemblerDWR<d, T, bending>::computeSquaredErrorElements(const gsMultiPatch<T> & dualL, const gsMultiPatch<T> & dualH, const gsMultiPatch<T> & deformed, bool withLoads,
2102  std::string filename, unsigned np, bool parametric, bool mesh)
2103 {
2104  computeSquaredError_impl<d,bending,1>(dualL,dualH,deformed,withLoads,filename,np,parametric,mesh);
2105  return m_errors;
2106 }
2107 
2108 template <short_t d, class T, bool bending>
2109 std::vector<T> gsThinShellAssemblerDWR<d, T, bending>::computeSquaredErrorDofs(const gsMultiPatch<T> & dualL, const gsMultiPatch<T> & dualH, const gsMultiPatch<T> & deformed, bool withLoads,
2110  std::string filename, unsigned np, bool parametric, bool mesh)
2111 {
2112  computeSquaredError_impl<d,bending,2>(dualL,dualH,deformed,withLoads,filename,np,parametric,mesh);
2113  return m_errors;
2114 }
2115 
2116 template <short_t d, class T, bool bending>
2117 template<short_t _d, bool _bending, index_t _elWise>
2118 typename std::enable_if<(_d==3) && _bending, void>::type
2119 gsThinShellAssemblerDWR<d, T, bending>::computeSquaredError_impl(const gsMultiPatch<T> & dualL, const gsMultiPatch<T> & dualH, const gsMultiPatch<T> & deformed, bool withLoads,
2120  // bool withLoads,
2121  std::string filename, unsigned np, bool parametric, bool mesh)
2122 
2123 {
2124  gsExprAssembler<T> exprAssembler = m_assemblerH->assembler();
2125  exprAssembler.cleanUp();
2126  GISMO_ENSURE(m_assemblerH->options().hasGroup("ExprAssembler"),"The option list does not contain options with the label 'ExprAssembler'!");
2127  exprAssembler.setOptions(m_assemblerH->options().getGroup("ExprAssembler"));
2128 
2129  // Geometries
2130  geometryMap Gori = exprAssembler.getMap(m_patches); // this map is used for integrals
2131  geometryMap Gdef = exprAssembler.getMap(deformed);
2132 
2133  gsMaterialMatrixIntegrate<T,MaterialOutput::VectorN> S0f(m_assemblerH->materials(),&deformed);
2134  gsMaterialMatrixIntegrate<T,MaterialOutput::VectorM> S1f(m_assemblerH->materials(),&deformed);
2135  auto S0 = exprAssembler.getCoeff(S0f);
2136  auto S1 = exprAssembler.getCoeff(S1f);
2137 
2138  gsFunctionExpr<T> mult2t("1","0","0","0","1","0","0","0","2",2);
2139  auto m2 = exprAssembler.getCoeff(mult2t);
2140 
2141  auto F = exprAssembler.getCoeff(*m_forceFun, Gori);
2142  auto zsolL = exprAssembler.getCoeff(dualL);
2143  auto zsolH = exprAssembler.getCoeff(dualH);
2144  // auto m_thick = exprAssembler.getCoeff(*m_thickFun, m_ori);
2145 
2146  Base::homogenizeDirichlet();
2147 
2148  auto N = S0.tr();
2149  // auto Em_der = flat( jac(Gdef).tr() * jac(m_space) ) ;
2150  auto Em_der = flat( jac(Gdef).tr() * (jac(zsolH) - jac(zsolL)) ) ;
2151 
2152  auto M = S1.tr(); // output is a column
2153  // auto Ef_der = -( deriv2(space,sn(Gdef).normalized().tr() ) + deriv2(Gdef,var1(space,Gdef) ) ) * reshape(m2,3,3);
2154  auto Ef_der = -( deriv2(zsolH,sn(Gdef).normalized().tr() )
2155  - deriv2(zsolL,sn(Gdef).normalized().tr() ) + deriv2(Gdef,var1(zsolH,Gdef) )
2156  - deriv2(Gdef,var1(zsolL,Gdef) ) ) * reshape(m2,3,3);
2157 
2158  auto Fext = (zsolH-zsolL).tr() * F;
2159  auto Fint = ( N * Em_der.tr() + M * Ef_der.tr() );
2160 
2161  auto g_N = exprAssembler.getBdrFunction(Gori);
2162 
2163  auto expr = ( Fext - Fint ).sqNorm();
2164  auto bexpr= (zsolH-zsolL).tr() * g_N;
2165 
2166  gsExprEvaluator<T> ev(exprAssembler);
2167 
2168  T integral, bintegral;
2169  if (_elWise == 0)
2170  {
2171  bintegral = ev.integralBdrBc( m_bcs.get("Neumann"), bexpr * tv(Gori).norm());
2172  integral = ev.integral(expr * meas(Gori));
2173  if (m_pLoads.numLoads()!=0 && withLoads)
2174  _applyLoadsToError(dualL,dualH,integral);
2175 
2176  m_error = integral+bintegral;
2177  }
2178  else if (_elWise == 1) // element-wise
2179  {
2180  m_error = ev.integralElWise(expr * meas(Gori));
2181  if (m_pLoads.numLoads()!=0 && withLoads)
2182  _applyLoadsToError(dualL,dualH,m_error);
2183  m_errors = ev.elementwise();
2184  if (m_pLoads.numLoads()!=0 && withLoads)
2185  _applyLoadsToElWiseError(dualL,dualH,m_errors);
2186  }
2187  else if (_elWise == 2) // function-wise
2188  {
2189  integral = 0;
2190  }
2191  else
2192  GISMO_ERROR("Unknown");
2193 
2194  // if (m_foundInd)
2195  // {
2196  // auto foundation = exprAssembler.getCoeff(*m_foundFun, Gori);
2197  // GISMO_ASSERT(m_foundFun->targetDim()==3,"Foundation function has dimension "<<m_foundFun->targetDim()<<", but expected 3");
2198 
2199  // integral += ev.integral( ( zsolH - zsolL ) * foundation.asDiag() * (Gdef - Gori) * meas(Gori) ); // [v_x,v_y,v_z] diag([k_x,k_y,k_z]) [u_x; u_y; u_z]
2200  // }
2201  // if (m_pressInd)
2202  // {
2203  // auto pressure = exprAssembler.getCoeff(*m_pressFun, Gori);
2204  // GISMO_ASSERT(m_pressFun->targetDim()==1,"Pressure function has dimension "<<m_pressFun->targetDim()<<", but expected 1");
2205 
2206  // integral += ev.integral( pressure.val() * ( zsolH - zsolL ) * sn(Gdef).normalized() * meas(Gori) );
2207  // }
2208 
2209  if (!filename.empty())
2210  {
2211  ev.options().setSwitch("plot.elements",mesh);
2212  ev.options().setInt("plot.npts",np);
2213  // if (parametric)
2214  // ev.writeParaview(expr,filename);
2215  // else
2216  ev.writeParaview(expr,Gori,filename);
2217  }
2218 }
2219 
2220 template <short_t d, class T, bool bending>
2221 template<short_t _d, bool _bending, index_t _elWise>
2222 typename std::enable_if<!(_d==3 && _bending), void>::type
2223 gsThinShellAssemblerDWR<d, T, bending>::computeSquaredError_impl( const gsMultiPatch<T> & dualL,
2224  const gsMultiPatch<T> & dualH,
2225  const gsMultiPatch<T> & deformed,
2226  bool withLoads,
2227  std::string filename,
2228  unsigned np,
2229  bool parametric,
2230  bool mesh)
2231 {
2232  gsExprAssembler<T> exprAssembler = m_assemblerH->assembler();
2233  exprAssembler.cleanUp();
2234  GISMO_ENSURE(m_assemblerH->options().hasGroup("ExprAssembler"),"The option list does not contain options with the label 'ExprAssembler'!");
2235  exprAssembler.setOptions(m_assemblerH->options().getGroup("ExprAssembler"));
2236 
2237  // Geometries
2238  geometryMap Gori = exprAssembler.getMap(m_patches); // this map is used for integrals
2239  geometryMap Gdef = exprAssembler.getMap(deformed);
2240 
2241  gsMaterialMatrixIntegrate<T,MaterialOutput::VectorN> S0f(m_assemblerH->materials(),&deformed);
2242  auto S0 = exprAssembler.getCoeff(S0f);
2243 
2244  auto F = exprAssembler.getCoeff(*m_forceFun, Gori);
2245 
2246  auto zsolL = exprAssembler.getCoeff(dualL);
2247  auto zsolH = exprAssembler.getCoeff(dualH);
2248  // auto m_thick = exprAssembler.getCoeff(*m_thickFun, m_ori);
2249 
2250  auto N = S0.tr();
2251  // auto Em_der = flat( jac(Gdef).tr() * jac(m_space) ) ;
2252  auto Em_der = flat( jac(Gdef).tr() * (jac(zsolH) - jac(zsolL)) ) ;
2253 
2254  auto Fext = (zsolH-zsolL).tr() * F;
2255  auto Fint = ( N * Em_der.tr() );
2256 
2257  auto g_N = exprAssembler.getBdrFunction(Gori);
2258 
2259  auto expr = ( Fext - Fint ).sqNorm();
2260  auto bexpr= (zsolH-zsolL).tr() * g_N;
2261 
2262  gsExprEvaluator<T> ev(exprAssembler);
2263 
2264  T integral, bintegral;
2265  if (_elWise == 0)
2266  {
2267  bintegral = ev.integralBdrBc( m_bcs.get("Neumann"), bexpr * tv(Gori).norm());
2268  integral = ev.integral(expr * meas(Gori));
2269  m_error = bintegral+integral;
2270  if (m_pLoads.numLoads()!=0 && withLoads)
2271  _applyLoadsToError(dualL,dualH,m_error);
2272  }
2273  else if (_elWise == 1) // element-wise
2274  {
2275  m_error = ev.integralElWise(expr * meas(Gori));
2276  if (m_pLoads.numLoads()!=0 && withLoads)
2277  _applyLoadsToError(dualL,dualH,m_error);
2278  m_errors = ev.elementwise();
2279  if (m_pLoads.numLoads()!=0 && withLoads)
2280  _applyLoadsToElWiseError(dualL,dualH,m_errors);
2281  }
2282  else if (_elWise == 2) // function-wise
2283  {
2284  integral = 0;
2285  }
2286  else
2287  GISMO_ERROR("Unknown");
2288  // if (m_foundInd)
2289  // {
2290  // auto foundation = exprAssembler.getCoeff(*m_foundFun, Gori);
2291  // GISMO_ASSERT(m_foundFun->targetDim()==3,"Foundation function has dimension "<<m_foundFun->targetDim()<<", but expected 3");
2292 
2293  // integral += ev.integral( ( zsolH - zsolL ) * foundation.asDiag() * (Gdef - Gori) * meas(Gori) ); // [v_x,v_y,v_z] diag([k_x,k_y,k_z]) [u_x; u_y; u_z]
2294  // }
2295  // if (m_pressInd)
2296  // {
2297  // auto pressure = exprAssembler.getCoeff(*m_pressFun, Gori);
2298  // GISMO_ASSERT(m_pressFun->targetDim()==1,"Pressure function has dimension "<<m_pressFun->targetDim()<<", but expected 1");
2299 
2300  // integral += ev.integral( pressure.val() * ( zsolH - zsolL ) * sn(Gdef).normalized() * meas(Gori) );
2301  // }
2302 
2303  if (!filename.empty())
2304  {
2305  ev.options().setSwitch("plot.elements",mesh);
2306  ev.options().setInt("plot.npts",np);
2307  // if (parametric)
2308  // ev.writeParaview(expr,filename);
2309  // else
2310  ev.writeParaview(expr,Gori,filename);
2311  }
2312 }
2313 
2314 
2332 template <short_t d, class T, bool bending>
2333 T gsThinShellAssemblerDWR<d, T, bending>::computeErrorEig( const T evPrimalL,
2334  const T evDualL,
2335  const T evDualH,
2336  const gsMultiPatch<T> & dualL,
2337  const gsMultiPatch<T> & dualH,
2338  const gsMultiPatch<T> & primal,
2339  const gsMultiPatch<T> & deformed,
2340  std::string filename, unsigned np, bool parametric, bool mesh)
2341 {
2342  computeErrorEig_impl<0>(evPrimalL, evDualL, evDualH, dualL, dualH, primal, deformed,filename,np,parametric,mesh);
2343  return m_error;
2344 }
2345 
2346 template <short_t d, class T, bool bending>
2347 std::vector<T> gsThinShellAssemblerDWR<d, T, bending>::computeErrorEigElements( const T evPrimalL,
2348  const T evDualL,
2349  const T evDualH,
2350  const gsMultiPatch<T> & dualL,
2351  const gsMultiPatch<T> & dualH,
2352  const gsMultiPatch<T> & primal,
2353  const gsMultiPatch<T> & deformed,
2354  std::string filename, unsigned np, bool parametric, bool mesh)
2355 {
2356  computeErrorEig_impl<1>(evPrimalL, evDualL, evDualH, dualL, dualH, primal, deformed,filename,np,parametric,mesh);
2357  return m_errors;
2358 }
2359 
2360 template <short_t d, class T, bool bending>
2361 std::vector<T> gsThinShellAssemblerDWR<d, T, bending>::computeErrorEigDofs( const T evPrimalL,
2362  const T evDualL,
2363  const T evDualH,
2364  const gsMultiPatch<T> & dualL,
2365  const gsMultiPatch<T> & dualH,
2366  const gsMultiPatch<T> & primal,
2367  const gsMultiPatch<T> & deformed,
2368  std::string filename, unsigned np, bool parametric, bool mesh)
2369 {
2370  computeErrorEig_impl<2>(evPrimalL, evDualL, evDualH, dualL, dualH, primal, deformed,filename,np,parametric,mesh);
2371  return m_errors;
2372 }
2373 
2374 
2375 template <short_t d, class T, bool bending>
2376 template <index_t _elWise>
2377 void gsThinShellAssemblerDWR<d, T, bending>::computeErrorEig_impl( const T evPrimalL,
2378  const T evDualL,
2379  const T evDualH,
2380  const gsMultiPatch<T> & dualL,
2381  const gsMultiPatch<T> & dualH,
2382  const gsMultiPatch<T> & primal,
2383  const gsMultiPatch<T> & deformed,
2384  std::string filename,
2385  unsigned np,
2386  bool parametric,
2387  bool mesh)
2388 {
2389  // Everything is evaluated in the lower basis L
2390  gsExprAssembler<T> exprAssembler = m_assemblerH->assembler();
2391  exprAssembler.cleanUp();
2392  GISMO_ENSURE(m_assemblerH->options().hasGroup("ExprAssembler"),"The option list does not contain options with the label 'ExprAssembler'!");
2393  exprAssembler.setOptions(m_assemblerH->options().getGroup("ExprAssembler"));
2394 
2395  // Geometries
2396  geometryMap Gori = exprAssembler.getMap(m_patches); // this map is used for integrals
2397  geometryMap Gdef = exprAssembler.getMap(deformed);
2398 
2399  // Initialize vector
2400  exprAssembler.initSystem();
2401  exprAssembler.initVector(1);
2402 
2403  gsMaterialMatrixIntegrate<T,MaterialOutput::MatrixA> mmAf_L(m_assemblerH->materials(),&m_patches);
2404  gsMaterialMatrixIntegrate<T,MaterialOutput::MatrixB> mmBf_L(m_assemblerH->materials(),&m_patches);
2405  gsMaterialMatrixIntegrate<T,MaterialOutput::MatrixC> mmCf_L(m_assemblerH->materials(),&m_patches);
2406  gsMaterialMatrixIntegrate<T,MaterialOutput::MatrixD> mmDf_L(m_assemblerH->materials(),&m_patches);
2407  auto mmA_L = exprAssembler.getCoeff(mmAf_L);
2408  auto mmB_L = exprAssembler.getCoeff(mmBf_L);
2409  auto mmC_L = exprAssembler.getCoeff(mmCf_L);
2410  auto mmD_L = exprAssembler.getCoeff(mmDf_L);
2411 
2412  gsMaterialMatrixIntegrate<T,MaterialOutput::MatrixA> mmAf_NL(m_assemblerH->materials(),&deformed);
2413  gsMaterialMatrixIntegrate<T,MaterialOutput::MatrixB> mmBf_NL(m_assemblerH->materials(),&deformed);
2414  gsMaterialMatrixIntegrate<T,MaterialOutput::MatrixC> mmCf_NL(m_assemblerH->materials(),&deformed);
2415  gsMaterialMatrixIntegrate<T,MaterialOutput::MatrixD> mmDf_NL(m_assemblerH->materials(),&deformed);
2416  auto mmA_NL = exprAssembler.getCoeff(mmAf_NL);
2417  auto mmB_NL = exprAssembler.getCoeff(mmBf_NL);
2418  auto mmC_NL = exprAssembler.getCoeff(mmCf_NL);
2419  auto mmD_NL = exprAssembler.getCoeff(mmDf_NL);
2420 
2421  gsMaterialMatrixIntegrate<T,MaterialOutput::VectorN> S0f(m_assemblerH->materials(),&deformed);
2422  gsMaterialMatrixIntegrate<T,MaterialOutput::VectorM> S1f(m_assemblerH->materials(),&deformed);
2423  // gsMaterialMatrixIntegrate<T,MaterialOutput::Density> rhof(m_assemblerH->materials(),deformed);
2424  auto S0 = exprAssembler.getCoeff(S0f);
2425  auto S1 = exprAssembler.getCoeff(S1f);
2426  // auto rho = exprAssembler.getCoeff(rhof);
2427 
2428  gsFunctionExpr<T> mult2t("1","0","0","0","1","0","0","0","2",2);
2429  auto m2 = exprAssembler.getCoeff(mult2t);
2430 
2431  auto usol = exprAssembler.getCoeff(primal);
2432  auto zsolL = exprAssembler.getCoeff(dualL);
2433  auto zsolH = exprAssembler.getCoeff(dualH);
2434 
2435  // // Matrix K_L
2436  // auto N = S0.tr();
2437  // auto Em_der = flat( jac(Gori).tr() * (jac(zsolH) - jac(zsolL)) ) ;
2438 
2439  // auto M = S1.tr(); // output is a column
2440  // auto Ef_der = -(deriv2(zsolH, sn(Gori).normalized().tr()) - deriv2(zsolL, sn(Gori).normalized().tr()) + deriv2(Gori, var1(zsolH, Gori)) - deriv2(Gori, var1(zsolL, Gori))) * reshape(m2, 3, 3);
2441 
2442  // auto N_der = Em_der * reshape(mmA,3,3) + Ef_der * reshape(mmB,3,3);
2443  // auto M_der = Em_der * reshape(mmC,3,3) + Ef_der * reshape(mmD,3,3);
2444 
2445  // auto Fint = ( N_der * Em_der.tr() + M_der * Ef_der.tr() );
2446 
2447  // // Matrix K_NL
2448  // auto Em_der2 = flatdot( jac(Gdef),jac(zsolH), N ) - flatdot( jac(Gdef),jac(zsolL), N );
2449  // auto Ef_der2 = -(flatdot2( deriv2(m_space), var1(m_space,m_def).tr(), m_M ).symmetrize()
2450  // + var2dot(m_space,m_space,m_def, m_M ))
2451 
2452  /*
2453  Weak form:
2454  Wint(u,v) = int eps(u,v)'*n(u) + kappa(u,v)'*m(u) dint
2455 
2456  Jacobian
2457  Wint(u,v,w) = int eps(u,v)'*n(u,w)' + eps''(u,v,w)*n(u) + kappa(u,v)'*m'(u,w) + kappa''(u,v,w)*m(u) dint
2458 
2459  */
2460 
2461 
2462  auto N_L = S0.tr();
2463  auto Em_der_L = flat( jac(Gori).tr() * ( jac(usol ) ) ) ;
2464  auto Em_derd_L = flat( jac(Gori).tr() * ( jac(zsolH) - jac(zsolL) ) ) ;
2465 
2466  auto M_L = S1.tr(); // output is a column
2467  auto Ef_der_L = -( deriv2(usol , sn(Gori).normalized().tr() ) - deriv2(Gori, var1(usol , Gori) ) ) * reshape(m2, 3, 3);
2468  auto Ef_derd_L = -(
2469  deriv2(zsolH, sn(Gori).normalized().tr() ) - deriv2(Gori, var1(zsolH, Gori) )
2470  -deriv2(zsolL, sn(Gori).normalized().tr() ) - deriv2(Gori, var1(zsolL, Gori) )
2471  ) * reshape(m2, 3, 3);
2472 
2473  auto N_der_L = Em_der_L * reshape(mmA_L,3,3) + Ef_der_L * reshape(mmB_L,3,3);
2474  auto M_der_L = Em_der_L * reshape(mmC_L,3,3) + Ef_der_L * reshape(mmD_L,3,3);
2475 
2476  auto N_derd_L = Em_derd_L * reshape(mmA_L,3,3) + Ef_derd_L * reshape(mmB_L,3,3);
2477  auto M_derd_L = Em_derd_L * reshape(mmC_L,3,3) + Ef_derd_L * reshape(mmD_L,3,3);
2478 
2479  auto Fint_L = ( N_derd_L * Em_derd_L.tr() + M_derd_L * Ef_derd_L.tr() );
2480 
2481  auto N_NL = S0.tr();
2482  auto Em_der_NL = flat( jac(Gdef).tr() * ( jac(usol ) ) ) ;
2483  auto Em_derd_NL = flat( jac(Gdef).tr() * ( jac(zsolH) - jac(zsolL) ) ) ;
2484 
2485  auto Em_der2 = flat( jac(usol).tr() * ( jac(usol) ) ) * N_NL.tr();
2486  auto Emd_der2 = flat( jac(usol).tr() * ( jac(zsolH) - jac(zsolL) ) ) * N_NL.tr();
2487 
2488  auto M_NL = S1.tr(); // output is a column
2489  auto Ef_der_NL = -( deriv2(usol , sn(Gdef).normalized().tr() ) - deriv2(Gdef, var1(usol , Gdef) ) ) * reshape(m2, 3, 3);
2490  auto Ef_derd_NL = -(
2491  deriv2(zsolH, sn(Gdef).normalized().tr() ) - deriv2(Gdef, var1(zsolH, Gdef) )
2492  -deriv2(zsolL, sn(Gdef).normalized().tr() ) - deriv2(Gdef, var1(zsolL, Gdef) )
2493  ) * reshape(m2, 3, 3);
2494 
2495  auto Ef_der2 = -(
2496  ( ( deriv2(usol ) ) * ( var1(usol ,Gdef) ).tr() ).tr() * reshape(m2, 3, 3)
2497  + ( ( deriv2(usol ) ) * ( var1(usol ,Gdef) ).tr() ).tr() * reshape(m2, 3, 3)
2498  + ( deriv2(Gdef) * ( var2(usol ,usol ,Gdef) ) ).tr() * reshape(m2, 3, 3)
2499  ) * M_NL.tr();
2500 
2501  auto Efd_der2 = -(
2502  ( ( deriv2(usol ) ) * ( var1(zsolH,Gdef) - var1(zsolL,Gdef) ).tr() ).tr() * reshape(m2, 3, 3)
2503  + ( ( deriv2(zsolH) - deriv2(zsolL) ) * ( var1(usol ,Gdef) ).tr() ).tr() * reshape(m2, 3, 3)
2504  + ( deriv2(Gdef) * ( var2(usol ,zsolH,Gdef) - var2(usol ,zsolL,Gdef) ) ).tr() * reshape(m2, 3, 3)
2505  ) * M_NL.tr();
2506 
2507 
2508  auto N_der_NL = Em_der_NL * reshape(mmA_NL,3,3) + Ef_der_NL * reshape(mmB_NL,3,3);
2509  auto M_der_NL = Em_der_NL * reshape(mmC_NL,3,3) + Ef_der_NL * reshape(mmD_NL,3,3);
2510 
2511  auto N_derd_NL = Em_derd_NL * reshape(mmA_NL,3,3) + Ef_derd_NL * reshape(mmB_NL,3,3);
2512  auto M_derd_NL = Em_derd_NL * reshape(mmC_NL,3,3) + Ef_derd_NL * reshape(mmD_NL,3,3);
2513 
2514  auto K_L = ( N_der_L * Em_der_L.tr() + M_der_L * Ef_der_L.tr() );
2515  auto Kd_L = ( N_derd_L * Em_der_L.tr() + M_derd_L * Ef_der_L.tr() );
2516  auto K_NL = ( N_der_NL * Em_der_NL.tr() + M_der_NL * Ef_der_NL.tr() + Em_der2 + Ef_der2 );
2517  auto Kd_NL = ( N_derd_NL * Em_der_NL.tr() + M_derd_NL * Ef_der_NL.tr() + Emd_der2 + Efd_der2 );
2518 
2519  auto A = Kd_L;
2520  auto Bdiff = Kd_NL - Kd_L;
2521  auto Bprimal = K_NL - K_L ;
2522 
2523  auto expr = A - evPrimalL * Bdiff + (evDualH - evDualL) * Bprimal;
2524 
2525  gsExprEvaluator<T> ev(exprAssembler);
2526  if (_elWise == 0)
2527  {
2528  m_error = ev.integral(expr * meas(Gori)) - (evDualH - evDualL);
2529  }
2530  else if (_elWise == 1)
2531  {
2532  m_error = ev.integralElWise(expr * meas(Gori)) - (evDualH - evDualL);
2533  m_errors = ev.elementwise();
2534  }
2535  else if (_elWise == 2)
2536  {
2537  m_error = 0;
2538  }
2539  else
2540  GISMO_ERROR("Unknown");
2541 
2542  if (!filename.empty())
2543  {
2544  ev.options().setSwitch("plot.elements",mesh);
2545  ev.options().setInt("plot.npts",np);
2546  // if (parametric)
2547  // ev.writeParaview(expr,filename);
2548  // else
2549  ev.writeParaview(expr,Gori,filename);
2550  }
2551 }
2552 
2553 // template <short_t d, class T, bool bending>
2554 // gsMatrix<T> gsThinShellAssemblerDWR<d, T, bending>::evalErrorEig( gsMatrix<T> & u,
2555 // const T evPrimalL,
2556 // const T evDualL,
2557 // const T evDualH,
2558 // const gsMultiPatch<T> & dualL,
2559 // const gsMultiPatch<T> & dualH,
2560 // const gsMultiPatch<T> & primal,
2561 // const gsMultiPatch<T> & deformed)
2562 // {
2563 // gsExprAssembler<T> exprAssembler = m_assemblerH->assembler();
2564 // exprAssembler.cleanUp();
2565  // GISMO_ENSURE(m_assemblerH->options().hasGroup("ExprAssembler"),"The option list does not contain options with the label 'ExprAssembler'!");
2566  // exprAssembler.setOptions(m_assemblerH->options().getGroup("ExprAssembler"));
2567 
2568 // gsExprEvaluator<T> ev(exprAssembler);
2569 
2570 // return ev.eval(expr,u);
2571 // }
2572 
2589 template <short_t d, class T, bool bending>
2590 T gsThinShellAssemblerDWR<d, T, bending>::computeErrorEig( const T evPrimalL,
2591  const T evDualL,
2592  const T evDualH,
2593  const gsMultiPatch<T> & dualL,
2594  const gsMultiPatch<T> & dualH,
2595  const gsMultiPatch<T> & primal,
2596  std::string filename, unsigned np, bool parametric, bool mesh)
2597 {
2598  computeErrorEig_impl<0>(evPrimalL, evDualL, evDualH, dualL, dualH, primal,filename,np,parametric,mesh);
2599  return m_error;
2600 }
2601 
2602 template <short_t d, class T, bool bending>
2603 std::vector<T> gsThinShellAssemblerDWR<d, T, bending>::computeErrorEigElements( const T evPrimalL,
2604  const T evDualL,
2605  const T evDualH,
2606  const gsMultiPatch<T> & dualL,
2607  const gsMultiPatch<T> & dualH,
2608  const gsMultiPatch<T> & primal,
2609  std::string filename, unsigned np, bool parametric, bool mesh)
2610 {
2611  computeErrorEig_impl<1>(evPrimalL, evDualL, evDualH, dualL, dualH, primal,filename,np,parametric,mesh);
2612  return m_errors;
2613 }
2614 
2615 template <short_t d, class T, bool bending>
2616 std::vector<T> gsThinShellAssemblerDWR<d, T, bending>::computeErrorEigDofs( const T evPrimalL,
2617  const T evDualL,
2618  const T evDualH,
2619  const gsMultiPatch<T> & dualL,
2620  const gsMultiPatch<T> & dualH,
2621  const gsMultiPatch<T> & primal,
2622  std::string filename, unsigned np, bool parametric, bool mesh)
2623 {
2624  computeErrorEig_impl<2>(evPrimalL, evDualL, evDualH, dualL, dualH, primal,filename,np,parametric,mesh);
2625  return m_errors;
2626 }
2627 
2628 template <short_t d, class T, bool bending>
2629 template <index_t _elWise>
2630 void gsThinShellAssemblerDWR<d, T, bending>::computeErrorEig_impl( const T evPrimalL,
2631  const T evDualL,
2632  const T evDualH,
2633  const gsMultiPatch<T> & dualL,
2634  const gsMultiPatch<T> & dualH,
2635  const gsMultiPatch<T> & primal,
2636  std::string filename,
2637  unsigned np,
2638  bool parametric,
2639  bool mesh)
2640 {
2641  // Everything is evaluated in the lower basis L
2642  gsExprAssembler<T> exprAssembler = m_assemblerH->assembler();
2643  exprAssembler.cleanUp();
2644  GISMO_ENSURE(m_assemblerH->options().hasGroup("ExprAssembler"),"The option list does not contain options with the label 'ExprAssembler'!");
2645  exprAssembler.setOptions(m_assemblerH->options().getGroup("ExprAssembler"));
2646 
2647  gsMultiPatch<T> deformed = m_patches;
2648  for ( size_t k =0; k!=primal.nPatches(); ++k) // Deform the geometry
2649  deformed.patch(k).coefs() += primal.patch(k).coefs(); // Gdef points to mp_def, therefore updated
2650 
2651  // Geometries
2652  geometryMap Gori = exprAssembler.getMap(m_patches); // this map is used for integrals
2653 
2654  // Initialize vector
2655  exprAssembler.initSystem();
2656  exprAssembler.initVector(1);
2657 
2658  gsMaterialMatrixIntegrate<T,MaterialOutput::MatrixA> mmAf(m_assemblerH->materials(),&m_patches);
2659  gsMaterialMatrixIntegrate<T,MaterialOutput::MatrixB> mmBf(m_assemblerH->materials(),&m_patches);
2660  gsMaterialMatrixIntegrate<T,MaterialOutput::MatrixC> mmCf(m_assemblerH->materials(),&m_patches);
2661  gsMaterialMatrixIntegrate<T,MaterialOutput::MatrixD> mmDf(m_assemblerH->materials(),&m_patches);
2662  auto mmA = exprAssembler.getCoeff(mmAf);
2663  auto mmB = exprAssembler.getCoeff(mmBf);
2664  auto mmC = exprAssembler.getCoeff(mmCf);
2665  auto mmD = exprAssembler.getCoeff(mmDf);
2666 
2667  gsMaterialMatrixIntegrate<T,MaterialOutput::VectorN> S0f(m_assemblerH->materials(),&m_patches);
2668  gsMaterialMatrixIntegrate<T,MaterialOutput::VectorM> S1f(m_assemblerH->materials(),&m_patches);
2669  gsMaterialMatrixIntegrate<T,MaterialOutput::Density> rhof(m_assemblerH->materials(),&m_patches);
2670  auto S0 = exprAssembler.getCoeff(S0f);
2671  auto S1 = exprAssembler.getCoeff(S1f);
2672  auto rho = exprAssembler.getCoeff(rhof);
2673 
2674  gsFunctionExpr<T> mult2t("1","0","0","0","1","0","0","0","2",2);
2675  auto m2 = exprAssembler.getCoeff(mult2t);
2676 
2677  auto usol = exprAssembler.getCoeff(primal);
2678  auto zsolL = exprAssembler.getCoeff(dualL);
2679  auto zsolH = exprAssembler.getCoeff(dualH);
2680 
2681  auto N = S0.tr();
2682  auto Em_derd= flat( jac(Gori).tr() * (jac(zsolH) - jac(zsolL)) ) ;
2683  auto Em_der = flat( jac(Gori).tr() * (jac(usol) ) ) ;
2684 
2685  auto Em_derdw= flat( jac(Gori).tr() * (jac(zsolH) - jac(zsolL)) ) ;
2686 
2687 
2688  auto M = S1.tr(); // output is a column
2689  auto Ef_derd= -( deriv2(zsolH, sn(Gori).normalized().tr() )
2690  - deriv2(zsolL, sn(Gori).normalized().tr() ) + deriv2(Gori, var1(zsolH, Gori) )
2691  - deriv2(Gori, var1(zsolL, Gori) ) ) * reshape(m2, 3, 3);
2692  auto Ef_der = -( deriv2(usol, sn(Gori).normalized().tr() ) + deriv2(Gori, var1(usol, Gori)) ) * reshape(m2, 3, 3);
2693 
2694  auto N_der = Em_derd * reshape(mmA,3,3) + Ef_derd * reshape(mmB,3,3);
2695  auto M_der = Em_derd * reshape(mmC,3,3) + Ef_derd * reshape(mmD,3,3);
2696 
2697  auto Fint = ( N_der * Em_der.tr() + M_der * Ef_der.tr() );
2698 
2699  gsExprEvaluator<T> ev(exprAssembler);
2700 
2701  auto A = Fint;
2702  auto Bdiff = rho.val() * usol.tr() * (zsolH - zsolL);
2703  auto Bprimal= rho.val() * usol.tr() * usol;
2704  auto expr = A - evPrimalL * Bdiff + (evDualH - evDualL) * Bprimal;
2705 
2706  if (_elWise == 0)
2707  m_error = ev.integral(expr * meas(Gori)) - (evDualH - evDualL);
2708  else if (_elWise == 1)
2709  {
2710  m_error = ev.integralElWise(expr * meas(Gori) ) - (evDualH - evDualL);
2711  m_errors = ev.elementwise();
2712  }
2713  else if (_elWise == 2)
2714  m_error = 0;
2715  else
2716  GISMO_ERROR("Unknown");
2717 
2718  if (!filename.empty())
2719  {
2720  ev.options().setSwitch("plot.elements",mesh);
2721  ev.options().setInt("plot.npts",np);
2722  // if (parametric)
2723  // ev.writeParaview(expr,filename);
2724  // else
2725  ev.writeParaview(expr,Gori,filename);
2726  }
2727 }
2728 
2729 //============================================================
2730 template <short_t d, class T, bool bending>
2731 T gsThinShellAssemblerDWR<d, T, bending>::computeGoal(const gsMultiPatch<T> & deformed)
2732 {
2733  gsMatrix<T> Z(1,1);
2734  Z.setZero();
2735 
2736  gsExprAssembler<T> exprAssembler = m_assemblerH->assembler();
2737  exprAssembler.cleanUp();
2738  GISMO_ENSURE(m_assemblerH->options().hasGroup("ExprAssembler"),"The option list does not contain options with the label 'ExprAssembler'!");
2739  exprAssembler.setOptions(m_assemblerH->options().getGroup("ExprAssembler"));
2740 
2741  // Initialize vector
2742  exprAssembler.initSystem();
2743  exprAssembler.initVector(1);
2744 
2745  // Geometries
2746  geometryMap Gori = exprAssembler.getMap(m_patches); // this map is used for integrals
2747  geometryMap Gdef = exprAssembler.getMap(deformed);
2748 
2749  // Transformation for stretches
2750  gsMaterialMatrixEval<T,MaterialOutput::StretchTransform> Tstretchf(m_assemblerH->materials(),&deformed,Z);
2751  auto Tstretch = exprAssembler.getCoeff(Tstretchf);
2752 
2753  // Stress tensors
2754  gsMaterialMatrixEval<T,MaterialOutput::VectorN> S0f(m_assemblerH->materials(),&deformed,Z);
2755  gsMaterialMatrixEval<T,MaterialOutput::VectorM> S1f(m_assemblerH->materials(),&deformed,Z);
2756  auto S0 = exprAssembler.getCoeff(S0f);
2757  auto S1 = exprAssembler.getCoeff(S1f);
2758 
2759  // Force tensors
2760  gsMaterialMatrixIntegrate<T,MaterialOutput::VectorN> Nf(m_assemblerH->materials(),&deformed);
2761  gsMaterialMatrixIntegrate<T,MaterialOutput::VectorM> Mf(m_assemblerH->materials(),&deformed);
2762  auto N = exprAssembler.getCoeff(Nf);
2763  auto M = exprAssembler.getCoeff(Mf);
2764 
2766  // gsMaterialMatrixIntegrate<T,MaterialOutput::VectorN> S0if(m_assemblerH->materials(),&deformed);
2767  // gsMaterialMatrixIntegrate<T,MaterialOutput::VectorM> S1if(m_assemblerH->materials(),&deformed);
2768  // auto S0i = exprAssembler.getCoeff(S0if);
2769  // auto S1i = exprAssembler.getCoeff(S1if);
2770  // gsMaterialMatrixIntegrate<T,MaterialOutput::MatrixD> mmAfi(m_assemblerH->materials(),&deformed);
2771  // auto mmAi = exprAssembler.getCoeff(mmAfi);
2772  // gsMaterialMatrixIntegrate<T,MaterialOutput::MatrixD> mmDfi(m_assemblerH->materials(),&deformed);
2773  // auto mmDi = exprAssembler.getCoeff(mmDfi);
2775 
2776  // Principal stress tensors
2777  gsMaterialMatrixEval<T,MaterialOutput::PStress> P0f(m_assemblerH->materials(),&deformed,Z);
2778  auto P0 = exprAssembler.getCoeff(P0f);
2779 
2780  // Helper matrix for flexural components
2781  gsFunctionExpr<T> mult2t("1","0","0","0","1","0","0","0","2",2);
2782  auto m2 = exprAssembler.getCoeff(mult2t);
2783 
2784  // Deformation gradient
2785  // To compensate for the flat, since flat does [E11,E22,2*E12]
2786  gsFunctionExpr<T> mult12t("1","0","0","0","1","0","0","0","0.5",2);
2787  auto m12 = exprAssembler.getCoeff(mult12t);
2788 
2789  auto Cm = flat( jac(Gdef).tr() * jac(Gdef) ) * reshape(m12,3,3);
2790 
2791  // Principal stretch
2792  auto lambda = reshape(Tstretch,3,3) * Cm.tr();
2793 
2794  // Membrane strain
2795  auto Em = 0.5 * ( flat(jac(Gdef).tr()*jac(Gdef)) - flat(jac(Gori).tr()* jac(Gori)) ) ;
2796 
2797  // Principal membrane strain
2798  auto Emp = (Em * reshape(m12,3,3)) * reshape(Tstretch,3,3).tr();
2799 
2800  // Flexural strain
2801  auto Ef = ( deriv2(Gori,sn(Gori).normalized().tr()) - deriv2(Gdef,sn(Gdef).normalized().tr()) ) * reshape(m2,3,3) ;
2802 
2803 
2804  // Membrane force (its first variation)
2805  // auto N_der = Em_der * reshape(mmA,3,3) + Ef_der * reshape(mmB,3,3);
2806 
2807  gsExprEvaluator<T> ev(exprAssembler);
2808  if (m_goalFunction == GoalFunction::Displacement)
2809  {
2810  if (m_component==9)
2811  {
2812  auto expr = (Gdef - Gori).tr() * (Gdef - Gori) * meas(Gori);
2813  return ev.integral( expr );
2814  }
2815  else
2816  {
2817  auto expr = (Gdef - Gori).tr() * gismo::expr::uv(m_component,3)*meas(Gori);
2818  return ev.integral( expr );
2819  }
2820  }
2821  else if (m_goalFunction == GoalFunction::Stretch)
2822  {
2823  /*
2824  NOTE:
2825  - Cm * Transformation does only give the in-plane stretches, since C is constructed with the in-plane jacobians (Gdef) only. In fact, Cm should have a third entry with the Jacobian Determinant J0, but this one is hard to compute the variations for.
2826  */
2827  if (m_component==9)
2828  {
2829  // gsMaterialMatrixEval<T,MaterialOutput::Stretch> lambdaf(m_assemblerH->materials(),&deformed,Z);
2830  // auto lambda = exprAssembler.getCoeff(lambdaf);
2831  // auto expr1 = gismo::expr::pow(lambda.tr() * lambda,2) * meas(Gori);
2832  auto expr = lambda.tr() * lambda * meas(Gori);
2833  return ev.integral( expr );
2834  }
2835  else
2836  {
2837  auto expr = lambda.tr() * gismo::expr::uv(m_component,3)*meas(Gori);
2838  return ev.integral( expr );
2839  }
2840  }
2841  else if (m_goalFunction == GoalFunction::PStrain)
2842  {
2843  if (m_component==9)
2844  {
2845  auto expr = Emp * Emp.tr() * meas(Gori);
2846  return ev.integral( expr );
2847  }
2848  else
2849  {
2850  auto expr = Emp * gismo::expr::uv(m_component,3) * meas(Gori);
2851  return ev.integral( expr );
2852  }
2853  }
2854  else if (m_goalFunction == GoalFunction::PStress)
2855  {
2856  if (m_component==9)
2857  {
2858  auto expr = P0.tr() * P0 * meas(Gori);
2859  return ev.integral( expr );
2860  }
2861  else
2862  {
2863  GISMO_ASSERT(m_component < 2,"Can only select principle stress component 0 or 1, but "<<m_component<<" selected.");
2864  auto expr = P0.tr() * gismo::expr::uv(m_component,2) * meas(Gori);
2865  return ev.integral( expr );
2866  }
2867  }
2868 
2869  else if (m_goalFunction == GoalFunction::MembraneStrain)
2870  {
2871  if (m_component==9)
2872  {
2873  // auto expr = Em * Em.tr() * meas(Gori);
2874  auto expr = Em.sqNorm() * meas(Gori);
2875  return ev.integral( expr );
2876  }
2877  else
2878  {
2879  auto expr = Em * gismo::expr::uv(m_component,3) * meas(Gori);
2880  return ev.integral( expr );
2881  }
2882  }
2883  else if (m_goalFunction == GoalFunction::MembraneStress)
2884  {
2885  if (m_component==9)
2886  {
2887  auto expr = S0.tr() * S0 * meas(Gori);
2888  return ev.integral( expr );
2889  }
2890  else
2891  {
2892  auto expr = S0.tr() * gismo::expr::uv(m_component,3) * meas(Gori);
2893  return ev.integral( expr );
2894  }
2895  }
2896  else if (m_goalFunction == GoalFunction::MembraneForce)
2897  {
2898  if (m_component==9)
2899  {
2900  auto expr = N.tr() * N * meas(Gori);
2901  return ev.integral( expr );
2902  }
2903  else
2904  {
2905  auto expr = N.tr() * gismo::expr::uv(m_component,3) * meas(Gori);
2906  return ev.integral( expr );
2907  }
2908  }
2909  else if (m_goalFunction == GoalFunction::FlexuralStrain)
2910  {
2911  if (m_component==9)
2912  {
2913  auto expr = Ef * Ef.tr() * meas(Gori);
2914  return ev.integral( expr );
2915  }
2916  else
2917  {
2918  auto expr = Ef * gismo::expr::uv(m_component,3) * meas(Gori);
2919  return ev.integral( expr );
2920  }
2921  }
2922  else if (m_goalFunction == GoalFunction::FlexuralStress)
2923  {
2924  if (m_component==9)
2925  {
2926  auto expr = S1.tr() * S1 * meas(Gori);
2927  return ev.integral( expr );
2928  }
2929  else
2930  {
2931  auto expr = S1.tr() * gismo::expr::uv(m_component,3) * meas(Gori);
2932  return ev.integral( expr );
2933  }
2934  }
2935  else if (m_goalFunction == GoalFunction::FlexuralMoment)
2936  {
2937  if (m_component==9)
2938  {
2939  auto expr = M.tr() * M * meas(Gori);
2940  return ev.integral( expr );
2941  }
2942  else
2943  {
2944  auto expr = M.tr() * gismo::expr::uv(m_component,3) * meas(Gori);
2945  return ev.integral( expr );
2946  }
2947  }
2948  else
2949  GISMO_ERROR("Goal function not known");
2950 }
2951 
2952 template <short_t d, class T, bool bending>
2953 T gsThinShellAssemblerDWR<d, T, bending>::computeGoal(const bContainer & bnds, const gsMultiPatch<T> & deformed)
2954 {
2955  if (bnds.size()==0) return 0;
2956 
2957  gsMatrix<T> Z(1,1);
2958  Z.setZero();
2959 
2960  gsExprAssembler<T> exprAssembler = m_assemblerH->assembler();
2961  exprAssembler.cleanUp();
2962  GISMO_ENSURE(m_assemblerH->options().hasGroup("ExprAssembler"),"The option list does not contain options with the label 'ExprAssembler'!");
2963  exprAssembler.setOptions(m_assemblerH->options().getGroup("ExprAssembler"));
2964 
2965  // Initialize vector
2966  exprAssembler.initSystem();
2967  exprAssembler.initVector(1);
2968 
2969  // Geometries
2970  geometryMap Gori = exprAssembler.getMap(m_patches); // this map is used for integrals
2971  geometryMap Gdef = exprAssembler.getMap(deformed);
2972 
2973  // Transformation for stretches
2974  gsMaterialMatrixEval<T,MaterialOutput::StretchTransform> Tstretchf(m_assemblerH->materials(),&deformed,Z);
2975  auto Tstretch = exprAssembler.getCoeff(Tstretchf);
2976 
2977  // Stress tensors
2978  gsMaterialMatrixEval<T,MaterialOutput::VectorN> S0f(m_assemblerH->materials(),&deformed,Z);
2979  gsMaterialMatrixEval<T,MaterialOutput::VectorM> S1f(m_assemblerH->materials(),&deformed,Z);
2980  auto S0 = exprAssembler.getCoeff(S0f);
2981  auto S1 = exprAssembler.getCoeff(S1f);
2982 
2983  // Force tensors
2984  gsMaterialMatrixIntegrate<T,MaterialOutput::VectorN> Nf(m_assemblerH->materials(),&deformed);
2985  gsMaterialMatrixIntegrate<T,MaterialOutput::VectorM> Mf(m_assemblerH->materials(),&deformed);
2986  auto N = exprAssembler.getCoeff(Nf);
2987  auto M = exprAssembler.getCoeff(Mf);
2988 
2990  // gsMaterialMatrixIntegrate<T,MaterialOutput::VectorN> S0if(m_assemblerH->materials(),&deformed);
2991  // gsMaterialMatrixIntegrate<T,MaterialOutput::VectorM> S1if(m_assemblerH->materials(),&deformed);
2992  // auto S0i = exprAssembler.getCoeff(S0if);
2993  // auto S1i = exprAssembler.getCoeff(S1if);
2994  // gsMaterialMatrixIntegrate<T,MaterialOutput::MatrixD> mmAfi(m_assemblerH->materials(),&deformed);
2995  // auto mmAi = exprAssembler.getCoeff(mmAfi);
2996  // gsMaterialMatrixIntegrate<T,MaterialOutput::MatrixD> mmDfi(m_assemblerH->materials(),&deformed);
2997  // auto mmDi = exprAssembler.getCoeff(mmDfi);
2999 
3000  // Principal stress tensors
3001  gsMaterialMatrixEval<T,MaterialOutput::PStress> P0f(m_assemblerH->materials(),&deformed,Z);
3002  auto P0 = exprAssembler.getCoeff(P0f);
3003 
3004  // Helper matrix for flexural components
3005  gsFunctionExpr<T> mult2t("1","0","0","0","1","0","0","0","2",2);
3006  auto m2 = exprAssembler.getCoeff(mult2t);
3007 
3008  // Deformation gradient
3009  // To compensate for the flat, since flat does [E11,E22,2*E12]
3010  gsFunctionExpr<T> mult12t("1","0","0","0","1","0","0","0","0.5",2);
3011  auto m12 = exprAssembler.getCoeff(mult12t);
3012 
3013  auto Cm = flat( jac(Gdef).tr() * jac(Gdef) ) * reshape(m12,3,3);
3014 
3015  // Principal stretch
3016  auto lambda = reshape(Tstretch,3,3) * Cm.tr();
3017 
3018  // Membrane strain
3019  auto Em = 0.5 * ( flat(jac(Gdef).tr()*jac(Gdef)) - flat(jac(Gori).tr()* jac(Gori)) ) ;
3020 
3021  // Principal membrane strain
3022  auto Emp = (Em * reshape(m12,3,3)) * reshape(Tstretch,3,3).tr();
3023 
3024  // Flexural strain
3025  auto Ef = ( deriv2(Gori,sn(Gori).normalized().tr()) - deriv2(Gdef,sn(Gdef).normalized().tr()) ) * reshape(m2,3,3) ;
3026 
3027 
3028  // Membrane force (its first variation)
3029  // auto N_der = Em_der * reshape(mmA,3,3) + Ef_der * reshape(mmB,3,3);
3030 
3031  gsExprEvaluator<T> ev(exprAssembler);
3032  if (m_goalFunction == GoalFunction::Displacement)
3033  {
3034  if (m_component==9)
3035  {
3036  auto expr = (Gdef - Gori).tr() * (Gdef - Gori) * meas(Gori);
3037  return ev.integralBdr( expr,bnds );
3038  }
3039  else
3040  {
3041  auto expr = (Gdef - Gori).tr() * gismo::expr::uv(m_component,3)*meas(Gori);
3042  return ev.integralBdr( expr,bnds );
3043  }
3044  }
3045  else if (m_goalFunction == GoalFunction::Stretch)
3046  {
3047  /*
3048  NOTE:
3049  - Cm * Transformation does only give the in-plane stretches, since C is constructed with the in-plane jacobians (Gdef) only. In fact, Cm should have a third entry with the Jacobian Determinant J0, but this one is hard to compute the variations for.
3050  */
3051  if (m_component==9)
3052  {
3053  // gsMaterialMatrixEval<T,MaterialOutput::Stretch> lambdaf(m_assemblerH->materials(),&deformed,Z);
3054  // auto lambda = exprAssembler.getCoeff(lambdaf);
3055  // auto expr1 = gismo::expr::pow(lambda.tr() * lambda,2) * meas(Gori);
3056  auto expr = lambda.tr() * lambda * meas(Gori);
3057  return ev.integralBdr( expr,bnds );
3058  }
3059  else
3060  {
3061  auto expr = lambda.tr() * gismo::expr::uv(m_component,3)*meas(Gori);
3062  return ev.integralBdr( expr,bnds );
3063  }
3064  }
3065  else if (m_goalFunction == GoalFunction::PStrain)
3066  {
3067  if (m_component==9)
3068  {
3069  auto expr = Emp * Emp.tr() * meas(Gori);
3070  return ev.integralBdr( expr,bnds );
3071  }
3072  else
3073  {
3074  auto expr = Emp * gismo::expr::uv(m_component,3) * meas(Gori);
3075  return ev.integralBdr( expr,bnds );
3076  }
3077  }
3078  else if (m_goalFunction == GoalFunction::PStress)
3079  {
3080  if (m_component==9)
3081  {
3082  auto expr = P0.tr() * P0 * meas(Gori);
3083  return ev.integralBdr( expr,bnds );
3084  }
3085  else
3086  {
3087  GISMO_ASSERT(m_component < 2,"Can only select principle stress component 0 or 1, but "<<m_component<<" selected.");
3088  auto expr = P0.tr() * gismo::expr::uv(m_component,2) * meas(Gori);
3089  return ev.integralBdr( expr,bnds );
3090  }
3091  }
3092  else if (m_goalFunction == GoalFunction::MembraneStrain)
3093  {
3094  if (m_component==9)
3095  {
3096  // auto expr = Em * Em.tr() * meas(Gori);
3097  auto expr = Em.sqNorm() * meas(Gori);
3098  return ev.integralBdr( expr,bnds );
3099  }
3100  else
3101  {
3102  auto expr = Em * gismo::expr::uv(m_component,3) * meas(Gori);
3103  return ev.integralBdr( expr,bnds );
3104  }
3105  }
3106  else if (m_goalFunction == GoalFunction::MembraneStress)
3107  {
3108  if (m_component==9)
3109  {
3110  auto expr = S0.tr() * S0 * meas(Gori);
3111  return ev.integralBdr( expr,bnds );
3112  }
3113  else
3114  {
3115  auto expr = S0.tr() * gismo::expr::uv(m_component,3) * meas(Gori);
3116  return ev.integralBdr( expr,bnds );
3117  }
3118  }
3119  else if (m_goalFunction == GoalFunction::MembraneForce)
3120  {
3121  if (m_component==9)
3122  {
3123  auto expr = N.tr() * N * meas(Gori);
3124  return ev.integralBdr( expr,bnds );
3125  }
3126  else
3127  {
3128  auto expr = N.tr() * gismo::expr::uv(m_component,3) * meas(Gori);
3129  return ev.integralBdr( expr,bnds );
3130  }
3131  }
3132  else if (m_goalFunction == GoalFunction::FlexuralStrain)
3133  {
3134  if (m_component==9)
3135  {
3136  auto expr = Ef * Ef.tr() * meas(Gori);
3137  return ev.integralBdr( expr,bnds );
3138  }
3139  else
3140  {
3141  auto expr = Ef * gismo::expr::uv(m_component,3) * meas(Gori);
3142  return ev.integralBdr( expr,bnds );
3143  }
3144  }
3145  else if (m_goalFunction == GoalFunction::FlexuralStress)
3146  {
3147  if (m_component==9)
3148  {
3149  auto expr = S1.tr() * S1 * meas(Gori);
3150  return ev.integralBdr( expr,bnds );
3151  }
3152  else
3153  {
3154  auto expr = S1.tr() * gismo::expr::uv(m_component,3) * meas(Gori);
3155  return ev.integralBdr( expr,bnds );
3156  }
3157  }
3158  else if (m_goalFunction == GoalFunction::FlexuralMoment)
3159  {
3160  if (m_component==9)
3161  {
3162  auto expr = M.tr() * M * meas(Gori);
3163  return ev.integralBdr( expr,bnds );
3164  }
3165  else
3166  {
3167  auto expr = M.tr() * gismo::expr::uv(m_component,3) * meas(Gori);
3168  return ev.integralBdr( expr,bnds );
3169  }
3170  }
3171  else
3172  GISMO_ERROR("Goal function not known");
3173 }
3174 
3175 template <short_t d, class T, bool bending>
3176 T gsThinShellAssemblerDWR<d, T, bending>::computeGoal(const gsMatrix<T> & points, const gsMultiPatch<T> & deformed)
3177 {
3178  if (points.cols()==0) return 0;
3179 
3180  gsMatrix<T> Z(1,1);
3181  Z.setZero();
3182 
3183  gsExprAssembler<T> exprAssembler = m_assemblerH->assembler();
3184  exprAssembler.cleanUp();
3185  GISMO_ENSURE(m_assemblerH->options().hasGroup("ExprAssembler"),"The option list does not contain options with the label 'ExprAssembler'!");
3186  exprAssembler.setOptions(m_assemblerH->options().getGroup("ExprAssembler"));
3187 
3188 
3189  // Initialize vector
3190  exprAssembler.initSystem();
3191  exprAssembler.initVector(1);
3192 
3193  // Geometries
3194  geometryMap Gori = exprAssembler.getMap(m_patches); // this map is used for integrals
3195  geometryMap Gdef = exprAssembler.getMap(deformed);
3196 
3197  // Transformation for stretches
3198  gsMaterialMatrixEval<T,MaterialOutput::StretchTransform> Tstretchf(m_assemblerH->materials(),&deformed,Z);
3199  auto Tstretch = exprAssembler.getCoeff(Tstretchf);
3200  // Material tensors
3201 
3202  // Stress tensors
3203  gsMaterialMatrixEval<T,MaterialOutput::VectorN> S0f(m_assemblerH->materials(),&deformed,Z);
3204  gsMaterialMatrixEval<T,MaterialOutput::VectorM> S1f(m_assemblerH->materials(),&deformed,Z);
3205  auto S0 = exprAssembler.getCoeff(S0f);
3206  auto S1 = exprAssembler.getCoeff(S1f);
3207 
3208  // Force tensors
3209  gsMaterialMatrixIntegrate<T,MaterialOutput::VectorN> Nf(m_assemblerH->materials(),&deformed);
3210  gsMaterialMatrixIntegrate<T,MaterialOutput::VectorM> Mf(m_assemblerH->materials(),&deformed);
3211  auto N = exprAssembler.getCoeff(Nf);
3212  auto M = exprAssembler.getCoeff(Mf);
3213 
3214  // Principal stress tensors
3215  gsMaterialMatrixEval<T,MaterialOutput::PStress> P0f(m_assemblerH->materials(),&deformed,Z);
3216  auto P0 = exprAssembler.getCoeff(P0f);
3217 
3218  // // Helper matrix for flexural components
3219  gsFunctionExpr<T> mult2t("1","0","0","0","1","0","0","0","2",2);
3220  auto m2 = exprAssembler.getCoeff(mult2t);
3221 
3222  // Deformation gradient
3223  // To compensate for the flat, since flat does [E11,E22,2*E12]
3224  gsFunctionExpr<T> mult12t("1","0","0","0","1","0","0","0","0.5",2);
3225  auto m12 = exprAssembler.getCoeff(mult12t);
3226 
3227  auto Cm = flat( jac(Gdef).tr() * jac(Gdef) ) * reshape(m12,3,3);
3228 
3229  // Principal stretch
3230  auto lambda = reshape(Tstretch,3,3).tr() * Cm.tr();
3231 
3232  // Membrane strain
3233  auto Em = 0.5 * ( flat(jac(Gdef).tr()*jac(Gdef)) - flat(jac(Gori).tr()* jac(Gori)) ) ;
3234 
3235  // Principal membrane strain
3236  auto Emp = (Em * reshape(m12,3,3)) * reshape(Tstretch,3,3).tr();
3237 
3238  // Flexural strain
3239  auto Ef = ( deriv2(Gori,sn(Gori).normalized().tr()) - deriv2(Gdef,sn(Gdef).normalized().tr()) ) * reshape(m2,3,3) ;
3240 
3241  // Membrane force (its first variation)
3242  // auto N_der = Em_der * reshape(mmA,3,3) + Ef_der * reshape(mmB,3,3);
3243 
3244  gsExprEvaluator<T> ev(exprAssembler);
3245  T result = 0;
3246  gsMatrix<T> tmp;
3247  if (m_goalFunction == GoalFunction::Displacement)
3248  {
3249  if (m_component==9)
3250  {
3251  auto expr = (Gdef - Gori).tr() * (Gdef - Gori) * meas(Gori);
3252  for (index_t k = 0; k!=points.cols(); k++)
3253  {
3254  tmp = ev.eval( expr, points.col(k));
3255  GISMO_ASSERT(tmp.cols()==tmp.rows() && tmp.cols()==1,"Goal function must be scalar!");
3256  result += tmp(0,0);
3257  }
3258  return result;
3259  }
3260  else
3261  {
3262  auto expr = (Gdef - Gori).tr() * gismo::expr::uv(m_component,3)*meas(Gori);
3263  for (index_t k = 0; k!=points.cols(); k++)
3264  {
3265  tmp = ev.eval( expr, points.col(k));
3266  GISMO_ASSERT(tmp.cols()==tmp.rows() && tmp.cols()==1,"Goal function must be scalar!");
3267  result += tmp(0,0);
3268  }
3269  return result;
3270  }
3271  }
3272  else if (m_goalFunction == GoalFunction::Stretch)
3273  {
3274  /*
3275  NOTE:
3276  - Cm * Transformation does only give the in-plane stretches, since C is constructed with the in-plane jacobians (Gdef) only. In fact, Cm should have a third entry with the Jacobian Determinant J0, but this one is hard to compute the variations for.
3277  */
3278  if (m_component==9)
3279  {
3280  // gsMaterialMatrixEval<T,MaterialOutput::Stretch> lambdaf(m_assemblerH->materials(),&deformed,Z);
3281  // auto lambda = exprAssembler.getCoeff(lambdaf);
3282  // auto expr1 = gismo::expr::pow(lambda.tr() * lambda,2) * meas(Gori);
3283  auto expr = lambda.tr() * lambda * meas(Gori);
3284  for (index_t k = 0; k!=points.cols(); k++)
3285  {
3286  tmp = ev.eval( expr, points.col(k));
3287  GISMO_ASSERT(tmp.cols()==tmp.rows() && tmp.cols()==1,"Goal function must be scalar!");
3288  result += tmp(0,0);
3289  }
3290  return result;
3291  }
3292  else
3293  {
3294  auto expr = (Gdef - Gori).tr() * gismo::expr::uv(m_component,3)*meas(Gori);
3295  for (index_t k = 0; k!=points.cols(); k++)
3296  {
3297  tmp = ev.eval( expr, points.col(k));
3298  GISMO_ASSERT(tmp.cols()==tmp.rows() && tmp.cols()==1,"Goal function must be scalar!");
3299  result += tmp(0,0);
3300  }
3301  return result;
3302  }
3303  }
3304  else if (m_goalFunction == GoalFunction::PStrain)
3305  {
3306  if (m_component==9)
3307  {
3308  auto expr = Emp * Emp.tr() * meas(Gori);
3309  for (index_t k = 0; k!=points.cols(); k++)
3310  {
3311  tmp = ev.eval( expr, points.col(k));
3312  GISMO_ASSERT(tmp.cols()==tmp.rows() && tmp.cols()==1,"Goal function must be scalar!");
3313  result += tmp(0,0);
3314  }
3315  return result;
3316  }
3317  else
3318  {
3319  auto expr = Emp * gismo::expr::uv(m_component,3) * meas(Gori);
3320  for (index_t k = 0; k!=points.cols(); k++)
3321  {
3322  tmp = ev.eval( expr, points.col(k));
3323  GISMO_ASSERT(tmp.cols()==tmp.rows() && tmp.cols()==1,"Goal function must be scalar!");
3324  result += tmp(0,0);
3325  }
3326  return result;
3327  }
3328  }
3329  else if (m_goalFunction == GoalFunction::PStress)
3330  {
3331  if (m_component==9)
3332  {
3333  auto expr = P0.tr() * P0 * meas(Gori);
3334  for (index_t k = 0; k!=points.cols(); k++)
3335  {
3336  tmp = ev.eval( expr, points.col(k));
3337  GISMO_ASSERT(tmp.cols()==tmp.rows() && tmp.cols()==1,"Goal function must be scalar!");
3338  result += tmp(0,0);
3339  }
3340  return result;
3341  }
3342  else
3343  {
3344  GISMO_ASSERT(m_component < 2,"Can only select principle stress component 0 or 1, but "<<m_component<<" selected.");
3345  auto expr = P0.tr() * gismo::expr::uv(m_component,2) * meas(Gori);
3346  for (index_t k = 0; k!=points.cols(); k++)
3347  {
3348  tmp = ev.eval( expr, points.col(k));
3349  GISMO_ASSERT(tmp.cols()==tmp.rows() && tmp.cols()==1,"Goal function must be scalar!");
3350  result += tmp(0,0);
3351  }
3352  return result;
3353  }
3354  }
3355  else if (m_goalFunction == GoalFunction::MembraneStrain)
3356  {
3357  if (m_component==9)
3358  {
3359  auto expr = Em * Em.tr() * meas(Gori);
3360  for (index_t k = 0; k!=points.cols(); k++)
3361  {
3362  tmp = ev.eval( expr, points.col(k));
3363  GISMO_ASSERT(tmp.cols()==tmp.rows() && tmp.cols()==1,"Goal function must be scalar!");
3364  result += tmp(0,0);
3365  }
3366  return result;
3367  }
3368  else
3369  {
3370  auto expr = Em * gismo::expr::uv(m_component,3) * meas(Gori);
3371  for (index_t k = 0; k!=points.cols(); k++)
3372  {
3373  tmp = ev.eval( expr, points.col(k));
3374  GISMO_ASSERT(tmp.cols()==tmp.rows() && tmp.cols()==1,"Goal function must be scalar!");
3375  result += tmp(0,0);
3376  }
3377  return result;
3378  }
3379  }
3380  else if (m_goalFunction == GoalFunction::MembraneStress)
3381  {
3382  if (m_component==9)
3383  {
3384  auto expr = S0.tr() * S0 * meas(Gori);
3385  for (index_t k = 0; k!=points.cols(); k++)
3386  {
3387  tmp = ev.eval( expr, points.col(k));
3388  GISMO_ASSERT(tmp.cols()==tmp.rows() && tmp.cols()==1,"Goal function must be scalar!");
3389  result += tmp(0,0);
3390  }
3391  return result;
3392  }
3393  else
3394  {
3395  auto expr = S0.tr() * gismo::expr::uv(m_component,3) * meas(Gori);
3396  for (index_t k = 0; k!=points.cols(); k++)
3397  {
3398  tmp = ev.eval( expr, points.col(k));
3399  GISMO_ASSERT(tmp.cols()==tmp.rows() && tmp.cols()==1,"Goal function must be scalar!");
3400  result += tmp(0,0);
3401  }
3402  return result;
3403  }
3404  }
3405  else if (m_goalFunction == GoalFunction::MembraneForce)
3406  {
3407  if (m_component==9)
3408  {
3409  auto expr = N.tr() * N * meas(Gori);
3410  for (index_t k = 0; k!=points.cols(); k++)
3411  {
3412  tmp = ev.eval( expr, points.col(k));
3413  GISMO_ASSERT(tmp.cols()==tmp.rows() && tmp.cols()==1,"Goal function must be scalar!");
3414  result += tmp(0,0);
3415  }
3416  return result;
3417  }
3418  else
3419  {
3420  auto expr = N.tr() * gismo::expr::uv(m_component,3) * meas(Gori);
3421  for (index_t k = 0; k!=points.cols(); k++)
3422  {
3423  tmp = ev.eval( expr, points.col(k));
3424  GISMO_ASSERT(tmp.cols()==tmp.rows() && tmp.cols()==1,"Goal function must be scalar!");
3425  result += tmp(0,0);
3426  }
3427  return result;
3428  }
3429  }
3430  else if (m_goalFunction == GoalFunction::FlexuralStrain)
3431  {
3432  if (m_component==9)
3433  {
3434  auto expr = Ef * Ef.tr() * meas(Gori);
3435  for (index_t k = 0; k!=points.cols(); k++)
3436  {
3437  tmp = ev.eval( expr, points.col(k));
3438  GISMO_ASSERT(tmp.cols()==tmp.rows() && tmp.cols()==1,"Goal function must be scalar!");
3439  result += tmp(0,0);
3440  }
3441  return result;
3442  }
3443  else
3444  {
3445  auto expr = Ef * gismo::expr::uv(m_component,3) * meas(Gori);
3446  for (index_t k = 0; k!=points.cols(); k++)
3447  {
3448  tmp = ev.eval( expr, points.col(k));
3449  GISMO_ASSERT(tmp.cols()==tmp.rows() && tmp.cols()==1,"Goal function must be scalar!");
3450  result += tmp(0,0);
3451  }
3452  return result;
3453  }
3454  }
3455  else if (m_goalFunction == GoalFunction::FlexuralStress)
3456  {
3457  if (m_component==9)
3458  {
3459  auto expr = S1.tr() * S1 * meas(Gori);
3460  for (index_t k = 0; k!=points.cols(); k++)
3461  {
3462  tmp = ev.eval( expr, points.col(k));
3463  GISMO_ASSERT(tmp.cols()==tmp.rows() && tmp.cols()==1,"Goal function must be scalar!");
3464  result += tmp(0,0);
3465  }
3466  return result;
3467  }
3468  else
3469  {
3470  auto expr = S1.tr() * gismo::expr::uv(m_component,3) * meas(Gori);
3471  for (index_t k = 0; k!=points.cols(); k++)
3472  {
3473  tmp = ev.eval( expr, points.col(k));
3474  GISMO_ASSERT(tmp.cols()==tmp.rows() && tmp.cols()==1,"Goal function must be scalar!");
3475  result += tmp(0,0);
3476  }
3477  return result;
3478  }
3479  }
3480  else if (m_goalFunction == GoalFunction::FlexuralMoment)
3481  {
3482  if (m_component==9)
3483  {
3484  auto expr = M.tr() * M * meas(Gori);
3485  for (index_t k = 0; k!=points.cols(); k++)
3486  {
3487  tmp = ev.eval( expr, points.col(k));
3488  GISMO_ASSERT(tmp.cols()==tmp.rows() && tmp.cols()==1,"Goal function must be scalar!");
3489  result += tmp(0,0);
3490  }
3491  return result;
3492  }
3493  else
3494  {
3495  auto expr = M.tr() * gismo::expr::uv(m_component,3) * meas(Gori);
3496  for (index_t k = 0; k!=points.cols(); k++)
3497  {
3498  tmp = ev.eval( expr, points.col(k));
3499  GISMO_ASSERT(tmp.cols()==tmp.rows() && tmp.cols()==1,"Goal function must be scalar!");
3500  result += tmp(0,0);
3501  }
3502  return result;
3503  }
3504  }
3505  else
3506  GISMO_ERROR("Goal function not known");
3507 
3508 }
3509 
3510 template <short_t d, class T, bool bending>
3511 T gsThinShellAssemblerDWR<d, T, bending>::matrixNorm(const gsMultiPatch<T> &primal, const gsMultiPatch<T> &other) const
3512 {
3513  GISMO_ASSERT(m_goalFunction==GoalFunction::Modal,"Only available for modal goal function");
3514 
3515  gsExprAssembler<T> exprAssembler = m_assemblerH->assembler();
3516  exprAssembler.cleanUp();
3517  GISMO_ENSURE(m_assemblerH->options().hasGroup("ExprAssembler"),"The option list does not contain options with the label 'ExprAssembler'!");
3518  exprAssembler.setOptions(m_assemblerH->options().getGroup("ExprAssembler"));
3519 
3520  // Geometries
3521  geometryMap Gori = exprAssembler.getMap(m_patches); // this map is used for integrals
3522 
3523  // Initialize vector
3524  exprAssembler.initSystem();
3525  exprAssembler.initVector(1);
3526 
3527  gsMaterialMatrixIntegrate<T,MaterialOutput::Density> rhof(m_assemblerH->materials(),&m_patches); // note: is this right?
3528  auto rho = exprAssembler.getCoeff(rhof);
3529 
3530  auto usol = exprAssembler.getCoeff(primal);
3531  auto zsol = exprAssembler.getCoeff(other);
3532 
3533  gsExprEvaluator<T> ev(exprAssembler);
3534  return ev.integral(rho.val() * usol.tr() * zsol * meas(Gori));
3535 }
3536 
3537 template <short_t d, class T, bool bending>
3538 T gsThinShellAssemblerDWR<d, T, bending>::matrixNorm(const gsMultiPatch<T> &primal, const gsMultiPatch<T> &other, const gsMultiPatch<T> &deformed) const
3539 {
3540  GISMO_ASSERT(m_goalFunction==GoalFunction::Buckling,"Only available for buckling goal function");
3541  gsExprAssembler<T> exprAssembler = m_assemblerH->assembler();
3542  exprAssembler.cleanUp();
3543  GISMO_ENSURE(m_assemblerH->options().hasGroup("ExprAssembler"),"The option list does not contain options with the label 'ExprAssembler'!");
3544  exprAssembler.setOptions(m_assemblerH->options().getGroup("ExprAssembler"));
3545 
3546  gsMultiPatch<T> defpatches = deformed;
3547 
3548  // Geometries
3549  geometryMap Gori = exprAssembler.getMap(m_patches); // this map is used for integrals
3550  geometryMap Gdef = exprAssembler.getMap(defpatches);
3551 
3552  // Initialize vector
3553  exprAssembler.initSystem();
3554  exprAssembler.initVector(1);
3555 
3556  gsMaterialMatrixIntegrate<T,MaterialOutput::MatrixA> mmAf_L(m_assemblerH->materials(),&m_patches);
3557  gsMaterialMatrixIntegrate<T,MaterialOutput::MatrixB> mmBf_L(m_assemblerH->materials(),&m_patches);
3558  gsMaterialMatrixIntegrate<T,MaterialOutput::MatrixC> mmCf_L(m_assemblerH->materials(),&m_patches);
3559  gsMaterialMatrixIntegrate<T,MaterialOutput::MatrixD> mmDf_L(m_assemblerH->materials(),&m_patches);
3560  auto mmA_L = exprAssembler.getCoeff(mmAf_L);
3561  auto mmB_L = exprAssembler.getCoeff(mmBf_L);
3562  auto mmC_L = exprAssembler.getCoeff(mmCf_L);
3563  auto mmD_L = exprAssembler.getCoeff(mmDf_L);
3564 
3565  gsMaterialMatrixIntegrate<T,MaterialOutput::MatrixA> mmAf_NL(m_assemblerH->materials(),&deformed);
3566  gsMaterialMatrixIntegrate<T,MaterialOutput::MatrixB> mmBf_NL(m_assemblerH->materials(),&deformed);
3567  gsMaterialMatrixIntegrate<T,MaterialOutput::MatrixC> mmCf_NL(m_assemblerH->materials(),&deformed);
3568  gsMaterialMatrixIntegrate<T,MaterialOutput::MatrixD> mmDf_NL(m_assemblerH->materials(),&deformed);
3569  auto mmA_NL = exprAssembler.getCoeff(mmAf_NL);
3570  auto mmB_NL = exprAssembler.getCoeff(mmBf_NL);
3571  auto mmC_NL = exprAssembler.getCoeff(mmCf_NL);
3572  auto mmD_NL = exprAssembler.getCoeff(mmDf_NL);
3573 
3574  gsMaterialMatrixIntegrate<T,MaterialOutput::VectorN> S0f(m_assemblerH->materials(),&defpatches);
3575  gsMaterialMatrixIntegrate<T,MaterialOutput::VectorM> S1f(m_assemblerH->materials(),&defpatches);
3576  auto S0 = exprAssembler.getCoeff(S0f);
3577  auto S1 = exprAssembler.getCoeff(S1f);
3578 
3579  gsFunctionExpr<T> mult2t("1","0","0","0","1","0","0","0","2",2);
3580  auto m2 = exprAssembler.getCoeff(mult2t);
3581 
3582  auto usol = exprAssembler.getCoeff(primal);
3583  auto zsol = exprAssembler.getCoeff(other);
3584 
3585  auto Em_der_L = flat( jac(Gori).tr() * ( jac(usol ) ) ) ;
3586  auto Ef_der_L = -( deriv2(usol , sn(Gori).normalized().tr() ) - deriv2(Gori, var1(usol , Gori) ) ) * reshape(m2, 3, 3);
3587 
3588  auto Em_derd_L = flat( jac(Gori).tr() * ( jac(zsol ) ) ) ;
3589  auto Ef_derd_L = -( deriv2(zsol , sn(Gori).normalized().tr() ) - deriv2(Gori, var1(zsol , Gori) ) ) * reshape(m2, 3, 3);
3590 
3591 
3592  auto N_der_L = Em_derd_L * reshape(mmA_L,3,3) + Ef_derd_L * reshape(mmB_L,3,3);
3593  auto M_der_L = Em_derd_L * reshape(mmC_L,3,3) + Ef_derd_L * reshape(mmD_L,3,3);
3594 
3595  auto N_NL = S0.tr();
3596  auto Em_der_NL = flat( jac(Gdef).tr() * ( jac(usol ) ) ) ;
3597  auto Ef_der_NL = -( deriv2(usol , sn(Gdef).normalized().tr() ) - deriv2(Gdef, var1(usol , Gdef) ) ) * reshape(m2, 3, 3);
3598 
3599  auto Em_derd_NL = flat( jac(Gdef).tr() * ( jac(zsol ) ) ) ;
3600  auto Ef_derd_NL = -( deriv2(zsol , sn(Gdef).normalized().tr() ) - deriv2(Gdef, var1(zsol , Gdef) ) ) * reshape(m2, 3, 3);
3601 
3602  auto Em_der2 = flat( jac(usol).tr() * ( jac(zsol ) ) ) * N_NL.tr();
3603 
3604  auto M_NL = S1.tr(); // output is a column
3605  auto Ef_der2 = -(
3606  ( ( deriv2(zsol ) ) * ( var1(usol ,Gdef) ).tr() ).tr() * reshape(m2, 3, 3)
3607  + ( ( deriv2(usol ) ) * ( var1(zsol ,Gdef) ).tr() ).tr() * reshape(m2, 3, 3)
3608  + ( deriv2(Gdef) * ( var2(usol ,zsol ,Gdef) ) ).tr() * reshape(m2, 3, 3)
3609  ) * M_NL.tr();
3610 
3611  auto N_der_NL = Em_derd_NL * reshape(mmA_NL,3,3) + Ef_derd_NL * reshape(mmB_NL,3,3);
3612  auto M_der_NL = Em_derd_NL * reshape(mmC_NL,3,3) + Ef_derd_NL * reshape(mmD_NL,3,3);
3613 
3614  auto K_L = ( N_der_L * Em_der_L.tr() + M_der_L * Ef_der_L.tr() );
3615  auto K_NL = ( N_der_NL * Em_der_NL.tr() + M_der_NL * Ef_der_NL.tr() + Em_der2 + Ef_der2 );
3616 
3617  auto Bprimal = K_NL - K_L ;
3618 
3619  auto expr = ( Bprimal ) * meas(Gori);
3620 
3621  gsExprEvaluator<T> ev(exprAssembler);
3622  T integral = ev.integral(expr);
3623 
3624  if (m_foundInd)
3625  {
3626  auto foundation = exprAssembler.getCoeff(*m_foundFun, Gori);
3627  GISMO_ASSERT(m_foundFun->targetDim()==3,"Foundation function has dimension "<<m_foundFun->targetDim()<<", but expected 3");
3628 
3629  integral += ev.integral( zsol * foundation.asDiag() * (Gdef - Gori) * meas(Gori) ); // [v_x,v_y,v_z] diag([k_x,k_y,k_z]) [u_x; u_y; u_z]
3630  }
3631  if (m_pressInd)
3632  {
3633  auto pressure = exprAssembler.getCoeff(*m_pressFun, Gori);
3634  GISMO_ASSERT(m_pressFun->targetDim()==1,"Pressure function has dimension "<<m_pressFun->targetDim()<<", but expected 1");
3635 
3636  integral += ev.integral( pressure.val() * zsol * sn(Gdef).normalized() * meas(Gori) );
3637  }
3638 
3639  return integral;
3640 }
3641 
3642 template <short_t d, class T, bool bending>
3643 void gsThinShellAssemblerDWR<d, T, bending>::_applyLoadsToElWiseError(const gsMultiPatch<T> &dualL, const gsMultiPatch<T> &dualH, std::vector<T> & errors) const
3644 {
3645 
3646  for (size_t i = 0; i<m_pLoads.numLoads(); ++i )
3647  {
3648  if (m_pLoads[i].value.size()!=d)
3649  gsWarn<<"Point load has wrong dimension "<<m_pLoads[i].value.size()<<" instead of "<<d<<"\n";
3650  // Compute actives and values of basis functions on point load location.
3651  gsMatrix<T> forcePoint;
3652  if ( m_pLoads[i].parametric ) // in parametric space
3653  forcePoint = m_pLoads[i].point;
3654  else // in physical space
3655  m_patches.patch(m_pLoads[i].patch).invertPoints(m_pLoads[i].point,forcePoint);
3656 
3657  std::vector<index_t> elements;
3658 
3659  #pragma omp parallel
3660  {
3661  std::vector<index_t> elements_private;
3662 #ifdef _OPENMP
3663  const int tid = omp_get_thread_num();
3664  const int nt = omp_get_num_threads();
3665  index_t patch_cnt = 0;
3666 #endif
3667 
3668  index_t c = 0;
3669  for (unsigned patchInd=0; patchInd < m_assemblerH->getBasis().nBases(); ++patchInd)
3670  {
3671  // Initialize domain element iterator
3672  typename gsBasis<T>::domainIter domIt =
3673  m_assemblerH->getBasis().piece(patchInd).makeDomainIterator();
3674 
3675 #ifdef _OPENMP
3676  c = patch_cnt + tid;
3677  patch_cnt += domIt->numElements();// a bit costy
3678  for ( domIt->next(tid); domIt->good(); domIt->next(nt) )
3679 #else
3680  for (; domIt->good(); domIt->next() )
3681 #endif
3682  {
3683  bool test = !(((((forcePoint - domIt->lowerCorner()).array() >= 0) &&
3684  (domIt->upperCorner() - forcePoint).array() >= 0) ).array() == 0).any();
3685  if (test)
3686  elements_private.push_back(c);
3687  #ifdef _OPENMP
3688  c += nt;
3689  #else
3690  c++;
3691  #endif
3692  }
3693 #pragma omp critical
3694  elements.insert(elements.end(), elements_private.begin(), elements_private.end());
3695  }
3696  }
3697 
3698  // Compute load value on the point
3699  gsMatrix<T> Lres, Hres;
3700  dualL.patch(m_pLoads[i].patch).eval_into(forcePoint,Lres);
3701  dualH.patch(m_pLoads[i].patch).eval_into(forcePoint,Hres);
3702  gsMatrix<T> result = (Hres-Lres).transpose() * m_pLoads[i].value;
3703  // Distribute load over all the elements
3704  GISMO_ASSERT(result.rows()==result.cols() && result.rows()==1,"Result must be scalar");
3705  for (size_t k=0; k!=elements.size(); k++)
3706  errors.at(elements.at(k)) += result(0,0)/elements.size();
3707  }
3708 }
3709 
3710 template <short_t d, class T, bool bending>
3711 void gsThinShellAssemblerDWR<d, T, bending>::_applyLoadsToError(const gsMultiPatch<T> &dualL, const gsMultiPatch<T> &dualH, T & error) const
3712 {
3713 
3714  for (size_t i = 0; i< m_pLoads.numLoads(); ++i )
3715  {
3716  if (m_pLoads[i].value.size()!=d)
3717  gsWarn<<"Point load has wrong dimension "<<m_pLoads[i].value.size()<<" instead of "<<d<<"\n";
3718  // Compute actives and values of basis functions on point load location.
3719  gsMatrix<T> forcePoint;
3720  if ( m_pLoads[i].parametric ) // in parametric space
3721  forcePoint = m_pLoads[i].point;
3722  else // in physical space
3723  m_patches.patch(m_pLoads[i].patch).invertPoints(m_pLoads[i].point,forcePoint);
3724 
3725  // Compute load value on the point
3726  gsMatrix<T> Lres, Hres;
3727  dualL.patch(m_pLoads[i].patch).eval_into(forcePoint,Lres);
3728  dualH.patch(m_pLoads[i].patch).eval_into(forcePoint,Hres);
3729  gsMatrix<T> result = (Hres-Lres).transpose() * m_pLoads[i].value;
3730  // Add load tot total error
3731  error += result(0,0);
3732  }
3733 }
3734 
3735 
3736 } // namespace gismo
Provides an evaluator for material matrices for thin shells.
ThinShellAssemblerStatus
Definition: gsThinShellAssembler.h:53
Provides declaration of FunctionExpr class.
EIGEN_STRONG_INLINE tangent_expr< T > tv(const gsGeometryMap< T > &u)
The tangent boundary vector of a geometry map in 2D.
Definition: gsExpressions.h:4513
Assembly failed due to an error in the expression (e.g. overflow)
#define index_t
Definition: gsConfig.h:32
#define GISMO_ENSURE(cond, message)
Definition: gsDebug.h:102
Provides DWR assembly routines for the Kirchhoff-Love shell.
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
Generic expressions evaluator.
Provides an evaluator for material matrices for thin shells.
#define gsWarn
Definition: gsDebug.h:50
Provides hyperelastic material matrices.
EIGEN_STRONG_INLINE reshape_expr< E > const reshape(E const &u, index_t n, index_t m)
Reshape an expression.
Definition: gsExpressions.h:1925
EIGEN_STRONG_INLINE flat_expr< E > const flat(E const &u)
Make a matrix 2x2 expression &quot;flat&quot;.
Definition: gsExpressions.h:2031
Provides a base class for material matrices.
#define GISMO_ERROR(message)
Definition: gsDebug.h:118
EIGEN_STRONG_INLINE meas_expr< T > meas(const gsGeometryMap< T > &G)
The measure of a geometry map.
Definition: gsExpressions.h:4555
EIGEN_STRONG_INLINE jac_expr< E > jac(const symbol_expr< E > &u)
The Jacobian matrix of a FE variable.
Definition: gsExpressions.h:4528