Skip to content

Commit c214700

Browse files
Merge pull request #14 from gismo/vertical-beam
Vertical-beam example with three coupling methods
2 parents 4ffeaf8 + dc7d833 commit c214700

File tree

19 files changed

+1181
-4
lines changed

19 files changed

+1181
-4
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
name: ci
23

34
on:
@@ -48,8 +49,6 @@ jobs:
4849
make -j 10
4950
sudo make install
5051
precice_DIR=$(pwd)
51-
export precice_DIR=$(pwd)
52-
5352
# Step to install preCICE
5453
- name: Install preCICE for mac
5554
if: runner.os == 'macOS'
@@ -63,8 +62,6 @@ jobs:
6362
make -j 10
6463
sudo make install
6564
precice_DIR=$(pwd)
66-
export precice_DIR=$(pwd)
67-
6865
- name: "Run for ${{ matrix.os }}"
6966
shell: bash
7067
working-directory: ${{ runner.workspace }}
Lines changed: 268 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
/** @file vertical-beam-IGA-IGA-fake-fluid.cpp
2+
*
3+
* @brief Provide the spline based coupling method through preCICE.
4+
*
5+
* This file is a part of G+Smo library.
6+
*
7+
* This Source Code Form is subject to the terms of the Mozilla Public
8+
* License, v. 2.0. If a copy of the MPL was not distributed with this
9+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
10+
*
11+
* Author(s): J. Li
12+
*
13+
**/
14+
15+
#include <gismo.h>
16+
#include <gsPreCICE/gsPreCICE.h>
17+
#include <gsPreCICE/gsPreCICEUtils.h>
18+
#include <gsPreCICE/gsPreCICEFunction.h>
19+
// #include <gsPreCICE/gsPreCICEVectorFunction.h>
20+
21+
#include <gsElasticity/gsMassAssembler.h>
22+
#include <gsElasticity/gsElasticityAssembler.h>
23+
24+
#ifdef gsStructuralAnalysis_ENABLED
25+
#include <gsStructuralAnalysis/src/gsDynamicSolvers/gsDynamicExplicitEuler.h>
26+
#include <gsStructuralAnalysis/src/gsDynamicSolvers/gsDynamicImplicitEuler.h>
27+
#include <gsStructuralAnalysis/src/gsDynamicSolvers/gsDynamicNewmark.h>
28+
#include <gsStructuralAnalysis/src/gsDynamicSolvers/gsDynamicBathe.h>
29+
#include <gsStructuralAnalysis/src/gsDynamicSolvers/gsDynamicWilson.h>
30+
#include <gsStructuralAnalysis/src/gsDynamicSolvers/gsDynamicRK4.h>
31+
#include <gsStructuralAnalysis/src/gsStructuralAnalysisTools/gsStructuralAnalysisUtils.h>
32+
#endif
33+
using namespace gismo;
34+
35+
int main(int argc, char *argv[])
36+
{
37+
38+
//! [Parse command line]
39+
bool plot = false;
40+
bool write = false;
41+
bool get_readTime = false; // Command line option for spline read and write time
42+
bool get_writeTime = false;
43+
index_t plotmod = 1;
44+
index_t loadCase = 0;
45+
std::string precice_config("../precice_config.xml");
46+
47+
gsCmdLine cmd("Coupled heat equation using PreCICE.");
48+
cmd.addString( "c", "config", "PreCICE config file", precice_config );
49+
cmd.addInt("l","loadCase", "Load case: 0=constant load, 1='spring' load", loadCase);
50+
cmd.addSwitch("write", "Create a file with point data", write);
51+
cmd.addSwitch("readTime", "Get the read time", get_readTime);
52+
cmd.addSwitch("writeTime", "Get the write time", get_writeTime);
53+
try { cmd.getValues(argc,argv); } catch (int rv) { return rv; }
54+
55+
GISMO_ASSERT(gsFileManager::fileExists(precice_config),"No precice config file has been defined");
56+
//! [Read input file]
57+
std::string participantName = "Fluid";
58+
gsPreCICE<real_t> participant(participantName, precice_config);
59+
60+
61+
/*
62+
* Data initialization
63+
*
64+
* This participant receives mesh information (knot vector, control points) from the solid,
65+
* and it creates its own mesh based on the information.
66+
* And writes pressure, reads displacements from the solid participant.
67+
* The follow meshes and data are made available:
68+
*
69+
* - Meshes:
70+
* + GeometryControlPointMesh: This mesh contains the control points as mesh vertices.
71+
* + GeometryKnotMesh: This mesh contains the knots as mesh vertices.
72+
* + ForceKnotMesh: This mesh contains the knots as mesh vertices for force mesh.
73+
* + ForceControlPointMesh: This mesh contains the control points as mesh vertices for force mesh.
74+
*
75+
*
76+
* - Data:
77+
* + GeometryControlPointData: This data is defined on the ControlPointMesh and stores the displacement of the control points
78+
* + ForceControlPointData: This data is defined on the ForceControlPointMesh and stores the change of pressure/stress
79+
*/
80+
81+
82+
// Meshes
83+
std::string GeometryControlPointMesh = "GeometryControlPointMesh";
84+
std::string GeometryKnotMesh = "GeometryKnotMesh";
85+
86+
87+
std::string ForceKnotMesh = "ForceKnotMesh";
88+
std::string ForceControlPointMesh = "ForceControlPointMesh";
89+
90+
91+
// Data
92+
std::string GeometryControlPointData = "GeometryControlPointData";
93+
std::string ForceControlPointData = "ForceControlPointData";
94+
// std::string GeometryKnotData = "GeometryKnotData";
95+
// std::string ForceKnotData = "ForceKnotMeshData";
96+
97+
gsMatrix<> bbox(3,2);
98+
bbox << -1e300, 1e300, // X dimension limits
99+
-1e300, 1e300, // Y dimension limits
100+
-1e300, 1e300; // Z dimension limits
101+
bbox.transposeInPlace();
102+
bbox.resize(1,bbox.rows()*bbox.cols());
103+
104+
// Step 2: Add force mesh
105+
106+
// Step 2.1: Define force knot mesh
107+
gsVector<index_t> forceKnotIDs;
108+
gsKnotVector<> kv(0,1,10,3,1); //begin, end, # interiors, mult, by default =1
109+
gsTensorBSplineBasis<2, real_t> forceBasis(kv,kv);
110+
gsMatrix<> forceControlPoints(forceBasis.size(), 3);
111+
forceControlPoints.setZero();
112+
forceControlPoints.col(2).setConstant(-5e3);
113+
forceControlPoints.transposeInPlace();
114+
115+
gsMatrix<> forceKnots = knotsToMatrix(forceBasis);
116+
117+
118+
119+
// Regenerate the geometry in another solver
120+
// forceMesh.addPatch(give(forceBasis.makeGeometry(forceControlPoints)));
121+
122+
// Step 2.1: Define force control point mesh
123+
gsVector<index_t> forceControlPointIDs;
124+
participant.addMesh(ForceKnotMesh,forceKnots,forceKnotIDs);
125+
participant.addMesh(ForceControlPointMesh,forceControlPoints,forceControlPointIDs);
126+
participant.setMeshAccessRegion(GeometryControlPointMesh, bbox);
127+
128+
real_t precice_dt = participant.initialize();
129+
130+
// Step 1: Collect geometry from PreCICE
131+
gsVector<index_t> geometryKnotIDs;
132+
gsMatrix<> geometryKnots;
133+
participant.getMeshVertexIDsAndCoordinates(GeometryKnotMesh, geometryKnotIDs, geometryKnots);
134+
135+
136+
gsBasis<> * geometryKnotBasis = knotMatrixToBasis<real_t>(geometryKnots).get();
137+
138+
gsVector<index_t> geometryControlPointIDs;
139+
gsMatrix<> geometryControlPoints;
140+
participant.getMeshVertexIDsAndCoordinates(GeometryControlPointMesh, geometryControlPointIDs, geometryControlPoints);
141+
142+
gsMultiPatch<> mp, deformation;
143+
mp.addPatch(give(geometryKnotBasis->makeGeometry(geometryControlPoints.transpose())));
144+
145+
deformation = mp;
146+
147+
148+
real_t t=0;
149+
real_t dt = precice_dt;
150+
real_t t_read = 0;
151+
real_t t_write = 0;
152+
153+
index_t timestep = 0;
154+
155+
// Define the solution collection for Paraview
156+
gsParaviewCollection collection("./output/solution");
157+
158+
gsMatrix<> points(2,1);
159+
points.col(0)<<0.5,1;
160+
161+
gsStructuralAnalysisOutput<real_t> writer("./output/pointData.csv",points);
162+
writer.init({"x","y","z"},{"time"});
163+
164+
// Time integration loop
165+
while(participant.isCouplingOngoing())
166+
{
167+
168+
// Read control point displacements
169+
participant.readData(GeometryControlPointMesh, GeometryControlPointData, geometryControlPointIDs, geometryControlPoints);
170+
deformation.patch(0).coefs() = geometryControlPoints.transpose();
171+
if (get_readTime)
172+
t_read += participant.readTime();
173+
174+
/*
175+
* Two projection approaches:
176+
* - gsQuasiInterpolate<real_t>::localIntpl(forceBasis, deformation.patch(0), coefs);
177+
* - gsL2Projection<real_t>::projectFunction(forceBasis, deformation, mp, coefs)
178+
*
179+
* Check if forceBasis + coefs gives the same as deformation.patch(0)
180+
*/
181+
if (loadCase == 0)
182+
{
183+
gsInfo << "Load case 0: Constant load\n";
184+
}
185+
else if (loadCase == 1)
186+
{
187+
gsInfo << "Load case 1: Spring load\n";
188+
if(timestep > 0)
189+
{
190+
gsMatrix<> coefs;
191+
gsL2Projection<real_t>::projectFunction(forceBasis, deformation, mp, coefs);
192+
coefs.resize(forceControlPoints.rows(),forceControlPoints.cols());
193+
forceControlPoints.row(2) = -coefs.row(2);
194+
}
195+
}
196+
else
197+
{
198+
GISMO_ERROR("Load case "<<loadCase<<" unknown.");
199+
}
200+
201+
202+
participant.writeData(ForceControlPointMesh,ForceControlPointData,forceControlPointIDs,forceControlPoints);
203+
204+
if (get_writeTime)
205+
t_write +=participant.writeTime();
206+
// bool requiresWritingCheckpoint and requiresReadingCheckpoint are **REQUIRED** in PreCICE.
207+
// And the requiresWritingCheckpoint() should be called before advance()
208+
gsMatrix<> pointDataMatrix;
209+
gsMatrix<> otherDataMatrix(1,1);
210+
if (participant.requiresWritingCheckpoint())
211+
{
212+
gsInfo<<"Reading Checkpoint\n";
213+
}
214+
215+
// do the coupling
216+
precice_dt = participant.advance(dt);
217+
218+
dt = std::min(precice_dt, dt);
219+
220+
if (participant.requiresReadingCheckpoint())
221+
{
222+
gsInfo<<"Writing Checkpoint \n";
223+
}
224+
else
225+
{
226+
t += dt;
227+
timestep++;
228+
229+
gsField<> solution(mp,deformation);
230+
if (timestep % plotmod==0 && plot)
231+
{
232+
// solution.patch(0).coefs() -= patches.patch(0).coefs();// assuming 1 patch here
233+
std::string fileName = "./output/solution" + util::to_string(timestep);
234+
gsWriteParaview<>(solution, fileName, 500);
235+
fileName = "solution" + util::to_string(timestep) + "0";
236+
collection.addTimestep(fileName,t,".vts");
237+
}
238+
if (write)
239+
{
240+
solution.patch(0).eval_into(points,pointDataMatrix);
241+
otherDataMatrix<<t;
242+
writer.add(pointDataMatrix,otherDataMatrix);
243+
}
244+
245+
// solution.patch(0).eval_into(points,pointDataMatrix);
246+
// otherDataMatrix<<time;
247+
// writer.add(pointDataMatrix,otherDataMatrix);
248+
}
249+
}
250+
if (get_readTime)
251+
{
252+
gsInfo << "Fluid Read time: " << t_read << "\n";
253+
}
254+
255+
if (get_writeTime)
256+
{
257+
gsInfo << "Fluid Write time: " << t_write << "\n";
258+
}
259+
260+
if (plot)
261+
{
262+
// Refer to gsParaviewCollection
263+
collection.save();
264+
}
265+
266+
267+
return EXIT_SUCCESS;
268+
}

0 commit comments

Comments
 (0)