33 * @brief Calculate mechanical response of perpendicular flap shell element
44 *
55 * This program calculates the mechanical response of a perpendicular flap shell element,
6- * including deformation, stress and strain. It uses the gsPreCICE library for structural
6+ * including deformation, stress and strain. It uses the gsPreCICE library for structural
77 * analysis and gsThinShellAssembler for shell element analysis.
88 *
9- * For Kirchhoff–Love shells, a mapping is established between the mid-surface (P)
10- * and the top/bottom surfaces (Q). In this version, the mapping is updated every time step
9+ * For Kirchhoff–Love shells, a mapping is established between the mid-surface (P)
10+ * and the top/bottom surfaces (Q). In this version, the mapping is updated every time step
1111 * based on the current mid-surface geometry: The current unit normal is recalculated,
1212 * and the corresponding thickness offset is computed for updated 3D control points.
1313 *
14- * This ensures that even for large deformations and rotations the generated volume
14+ * This ensures that even for large deformations and rotations the generated volume
1515 * (i.e. the top/bottom surfaces) remain perpendicular to the current mid-surface.
1616 *
1717 * Author: J. Li, H. Verhelst
2525
2626#include < gsAssembler/gsExprEvaluator.h>
2727
28- // #include <gsElasticity/gsMassAssembler.h>
29- // #include <gsElasticity/gsElasticityAssembler.h>
30-
3128#ifdef gsKLShell_ENABLED
3229#include < gsKLShell/src/getMaterialMatrix.h>
3330#include < gsKLShell/src/gsThinShellAssembler.h>
@@ -107,9 +104,9 @@ int main(int argc, char *argv[])
107104 {
108105 real_t x = greville (0 , col);
109106 real_t y = greville (1 , col);
110- coefs (col, 0 ) = 0 ;
111- coefs (col, 1 ) = y;
112- coefs (col, 2 ) = x;
107+ coefs (col, 0 ) = 0 ;
108+ coefs (col, 1 ) = y;
109+ coefs (col, 2 ) = x;
113110 }
114111 gsTensorBSpline<2 , real_t > surface (basis, coefs);
115112 gsExprEvaluator<> ev;
@@ -120,7 +117,7 @@ int main(int argc, char *argv[])
120117 // Define thickness for shell and create 3D volume for coupling interface
121118 gsFunctionExpr<> thickness (" 0.1" , 2 );
122119 real_t shell_thickness = 0.1 ;
123-
120+
124121 // Create 3D volume using surfaceToVolume for coupling interface only
125122 gsTensorBSpline<3 , real_t > volume3D = surfaceToVolume (surface, thickness);
126123 gsGeometry<>::uPtr volume = memory::make_unique (new gsTensorBSpline<3 , real_t >(volume3D));
@@ -161,23 +158,21 @@ int main(int argc, char *argv[])
161158 gsMatrix<> quad_uv_front = gsQuadrature::getAllNodes (vbasis.basis (0 ), quadOptions, frontInterface);
162159 gsMatrix<> quad_uv_back = gsQuadrature::getAllNodes (vbasis.basis (0 ), quadOptions, backInterface);
163160
164-
161+
165162 // Evaluate positions
166163 gsMatrix<> quad_xy_front = volume->eval (quad_uv_front);
167164 gsMatrix<> quad_xy_back = volume->eval (quad_uv_back);
168-
165+
169166 // Combine them in a known order: first all front points, then all back points
170167 gsMatrix<> quad_xy (3 , quad_xy_front.cols () + quad_xy_back.cols ());
171168 quad_xy.leftCols (quad_xy_front.cols ()) = quad_xy_front;
172169 quad_xy.rightCols (quad_xy_back.cols ()) = quad_xy_back;
173-
170+
174171 // Also combine parametric coordinates for later use
175172 gsMatrix<> quad_uv (3 , quad_uv_front.cols () + quad_uv_back.cols ());
176173 quad_uv.leftCols (quad_uv_front.cols ()) = quad_uv_front;
177174 quad_uv.rightCols (quad_uv_back.cols ()) = quad_uv_back;
178175
179-
180- gsDebugVar (quad_xy);
181176 gsWriteParaviewPoints (quad_xy, " quadPointsAll" );
182177
183178 gsVector<index_t > quadPointIDs;
@@ -213,7 +208,7 @@ int main(int argc, char *argv[])
213208 // Forces will only be non-zero at specific boundary points
214209 gsMatrix<> quadPointsData (3 , quad_shell_xy.cols ());
215210 quadPointsData.setZero ();
216-
211+
217212 // Create lookup function for shell forces
218213 gsLookupFunction<real_t > surfForce (quad_shell_xy, quadPointsData);
219214
@@ -280,8 +275,8 @@ int main(int argc, char *argv[])
280275 gsStructuralAnalysisOps<real_t >::Mass_t Mass =
281276 [&M](gsSparseMatrix<real_t >& m)
282277 { m = M; return true ; };
283- gsStructuralAnalysisOps<real_t >::Stiffness_t Stiffness =
284- [&K](gsSparseMatrix<real_t > & m)
278+ gsStructuralAnalysisOps<real_t >::Stiffness_t Stiffness =
279+ [&K](gsSparseMatrix<real_t > & m)
285280 { m = K; return true ; };
286281
287282
@@ -338,48 +333,39 @@ int main(int argc, char *argv[])
338333 << " \t ||A|| = " << A.norm () << " \n " ;
339334 timestep_checkpoint = timestep;
340335 }
341-
336+
342337 // Read stress data from preCICE (3D forces on top and bottom surfaces)
343338 gsMatrix<> stressDataRead;
344339 participant.readData (SolidMesh, StressData, quadPointIDs, stressDataRead);
345- gsDebugVar (stressDataRead.dim ());
346340
347341 // Now we know the exact ordering: first quad_xy_front.cols() points are from front,
348342 // next quad_xy_back.cols() points are from back
349343 index_t numFrontPoints = quad_xy_front.cols ();
350344 index_t numBackPoints = quad_xy_back.cols ();
351-
352-
345+
346+
353347 // Average forces from front (top) and back (bottom) surfaces to get mid-surface forces
354348 gsMatrix<> avgForces (3 , numFrontPoints);
355-
349+
356350 for (index_t i = 0 ; i < numFrontPoints; ++i)
357351 {
358352 avgForces.col (i) = (stressDataRead.col (i) + stressDataRead.col (numFrontPoints + i));
359353 }
360354
361- // avgForces.row(0) << avgForces.row(2);
362-
363- // avgForces.row(2).setZero();
364-
365355 // Extract 2D parametric coordinates from 3D front boundary
366356 gsMatrix<> surf_quad_uv (2 , numFrontPoints);
367357 for (index_t i = 0 ; i < numFrontPoints; ++i)
368358 {
369359 surf_quad_uv (0 , i) = quad_uv_front (0 , i); // u parameter
370360 surf_quad_uv (1 , i) = quad_uv_front (1 , i); // v parameter
371361 }
372-
362+
373363 // Evaluate 2D positions for these parametric points
374364 gsMatrix<> surf_quad_xy = surface.eval (surf_quad_uv);
375365 // Update the quadPointsData with the average forces for the look up function
376366 quadPointsData = avgForces;
377367 // quadPointsData.setOnes();
378368
379- // Debug output
380- gsDebugVar (quadPointsData.norm ());
381- gsDebugVar (avgForces.norm ());
382-
383369 if (get_readTime)
384370 t_read += participant.readTime ();
385371 assembler->assemble ();
@@ -399,16 +385,16 @@ int main(int argc, char *argv[])
399385
400386 // Calculate deformed surface and create deformed volume
401387 gsTensorBSpline<2 , real_t > deformed_surface (basis, solution.patch (0 ).coefs ());
402-
388+
403389 // Create deformed 3D volume using surfaceToVolume
404390 gsTensorBSpline<3 , real_t > deformed_volume3D = surfaceToVolume (deformed_surface, thickness);
405-
391+
406392 // Evaluate deformed positions at coupling points
407393 gsMatrix<> deformed_quad_xy = deformed_volume3D.eval (quad_uv);
408-
394+
409395 // Calculate 3D displacement
410396 gsMatrix<> displacementData = deformed_quad_xy - quad_xy;
411-
397+
412398 // Write 3D displacement data for coupling
413399 participant.writeData (SolidMesh, DisplacementData, quadPointIDs, displacementData);
414400
@@ -451,7 +437,7 @@ int main(int argc, char *argv[])
451437 std::string fileNameVol = " deformed_volume" + util::to_string (timestep);
452438 collection_volume.addTimestep (fileNameVol, time, " .vts" );
453439 }
454-
440+
455441 }
456442 } // end while coupling loop
457443
@@ -463,11 +449,12 @@ int main(int argc, char *argv[])
463449 if (plot)
464450 {
465451 collection.save ();
466- collection_surface.save ();
452+ collection_surface.save ();
467453 collection_volume.save ();
468-
454+
469455 }
470456
457+ delete assembler;
471458 delete timeIntegrator;
472459 return EXIT_SUCCESS;
473460}
0 commit comments