Skip to content

Commit 1dced50

Browse files
committed
WIP: provide key methods to easily setup particle simulation in c++ file itself.
1 parent c7134a7 commit 1dced50

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+31925
-6124
lines changed

CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang")
6666
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
6767
endif ()
6868

69-
# set standard to 17
70-
set(CMAKE_CXX_STANDARD 20)
69+
# set standard to 23
70+
set(CMAKE_CXX_STANDARD 23)
7171

7272
if (${Enable_CMAKE_Debug_Build})
7373
message(STATUS "CMAKE_CXX_COMPILER_ID = ${CMAKE_CXX_COMPILER_ID}")

apps/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@
77
# file LICENSE)
88

99
add_subdirectory(twoparticle_demo)
10-
add_subdirectory(peridynamics)
10+
add_subdirectory(peridynamics)
11+
add_subdirectory(example-modular)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# -------------------------------------------
2+
# Copyright (c) 2021 - 2024 Prashant K. Jha
3+
# -------------------------------------------
4+
# PeriDEM https://github.com/prashjha/PeriDEM
5+
#
6+
# Distributed under the Boost Software License, Version 1.0. (See accompanying
7+
# file LICENSE)
8+
9+
set(EXECUTABLE_OUTPUT_PATH "${CMAKE_CURRENT_BINARY_DIR}")
10+
11+
add_executable(Example_Modular main.cpp)
12+
13+
target_link_libraries(Example_Modular PUBLIC Inp)

apps/example-modular/main.cpp

Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
/*
2+
* -------------------------------------------
3+
* Copyright (c) 2021 - 2024 Prashant K. Jha
4+
* -------------------------------------------
5+
* PeriDEM https://github.com/prashjha/PeriDEM
6+
*
7+
* Distributed under the Boost Software License, Version 1.0. (See accompanying
8+
* file LICENSE)
9+
*/
10+
11+
#include "inp/deckIncludes.h"
12+
13+
#include <fmt/format.h>
14+
#include <fstream>
15+
#include <iostream>
16+
#include <random>
17+
18+
std::string example_name = "Example_Modular";
19+
20+
int main(int argc, char *argv[]) {
21+
util::io::InputParser input(argc, argv);
22+
23+
// read input arguments
24+
unsigned int nThreads = 1;
25+
if (input.cmdOptionExists("-nThreads")) nThreads = std::stoi(input.getCmdOption("-nThreads"));
26+
util::parallel::initNThreads(nThreads);
27+
28+
// +------------------+
29+
// + create input decks +
30+
// +------------------+
31+
auto *deck = new inp::Input();
32+
33+
// setup
34+
// three particles
35+
// h = mesh size
36+
// annulus rectangle -> fixed dof, geometry group 1, material group 1, mesh group 1, contact group 1
37+
// outer rec: (-h, -h, 0); (0.01+h, 0.01+h, 0)
38+
// inner rec: (0, 0, 0); (0.01, 0.01, 0)
39+
//
40+
// drum2d -> velocity ic, geometry group 2, material group 2, mesh group 2, contact group 2
41+
// radius = 0.002
42+
// circle -> velocity ic, geometry group 3, material group 2, mesh group 3, contact group 2
43+
// radius = 0.002
44+
double r = 0.002;
45+
double h = r/5;
46+
47+
// <<<<<<<<<<<<<<
48+
// Model deck
49+
// <<<<<<<<<<<<<<
50+
// set values manually
51+
deck->d_modelDeck_p = std::make_shared<inp::ModelDeck>(2, 0.005, 50000,
52+
"finite_difference", "central_difference",
53+
true, 2, "Multi_Particle",
54+
0);
55+
56+
// create json object using in-built function and read it (circular but good to see the json file format and how to read it)
57+
auto modelDeckJson = inp::ModelDeck::getExampleJson(2, 0.005, 50000,
58+
"finite_difference", "central_difference",
59+
true, 2, "Multi_Particle",
60+
0);
61+
62+
std::cout << "\n\nPrinting model deck json:\n";
63+
std::cout << modelDeckJson.dump(2) << std::endl;
64+
65+
// std::cout << "\n\nPrinting model deck:\n";
66+
// std::cout << deck->d_modelDeck_p->printStr() << std::endl;
67+
68+
69+
70+
// <<<<<<<<<<<<<<
71+
// Output deck
72+
// <<<<<<<<<<<<<<
73+
// set values manually
74+
deck->d_outputDeck_p = std::make_shared<inp::OutputDeck>("vtu", "./",
75+
std::vector<std::string>({"Displacement", "Velocity", "Force", "Damage_Z", "Damage", "Particle_ID"}),
76+
1, 2, true, "zlib", true, 1, "");
77+
78+
// or create json object and set deck from the object
79+
auto outputDeckJson = inp::OutputDeck::getExampleJson("vtu", "./",
80+
{"Displacement", "Velocity", "Force", "Damage_Z", "Damage", "Particle_ID"},
81+
1, 2, true, "zlib", true, 1, "");
82+
83+
std::cout << "\n\nPrinting output deck json:\n";
84+
std::cout << outputDeckJson.dump(2) << std::endl;
85+
86+
// std::cout << "\n\nPrinting output deck:\n";
87+
// std::cout << deck->d_outputDeck_p->printStr() << std::endl;
88+
89+
// <<<<<<<<<<<<<<
90+
// Restart deck
91+
// <<<<<<<<<<<<<<
92+
deck->d_restartDeck_p = std::make_shared<inp::RestartDeck>();
93+
94+
// <<<<<<<<<<<<<<
95+
// Test deck
96+
// <<<<<<<<<<<<<<
97+
deck->d_testDeck_p = std::make_shared<inp::TestDeck>(std::string(""));
98+
99+
// or
100+
auto testDeckJson = inp::TestDeck::getExampleJson();
101+
102+
std::cout << "\n\nPrinting test deck json:\n";
103+
std::cout << testDeckJson.dump(2) << std::flush;
104+
105+
std::cout << "\n\nPrinting test deck:\n";
106+
std::cout << deck->d_testDeck_p->printStr() << std::endl;
107+
108+
if (false) deck->d_testDeck_p = std::make_shared<inp::TestDeck>(testDeckJson);
109+
110+
// <<<<<<<<<<<<<<
111+
// BC deck
112+
// <<<<<<<<<<<<<<
113+
// Zero force boundary condition, One displacement boundary condition for fixing annulus rectangle
114+
// Two Initial conditions to specify initial velocity of the particles
115+
auto bcDeckJson = inp::BCDeck::getExampleJson(0, 1, 2, false, util::Point());
116+
117+
// create this block from the BCData static function
118+
bcDeckJson["Displacement_BC"]["Set_1"] = inp::BCBaseDeck::getExampleJson("Displacement_BC", false, util::geometry::GeomData(),
119+
{0}, {}, "", {}, "", {},
120+
{1, 2}, true, "", {});
121+
// or explicitly, we can do
122+
// dispBCJson.at("Particle_List") = std::vector<size_t>({0});
123+
// dispBCJson.at("Zero_Displacement") = true;
124+
// dispBCJson.at("Direction") = std::vector<size_t>({0, 1});
125+
126+
// fix initial condition
127+
double v_mag = 0.1; // m/s
128+
{
129+
// create this block from the ICData static function
130+
bcDeckJson["IC"]["Set_1"] = inp::BCBaseDeck::getExampleJson("IC", false, util::geometry::GeomData(),
131+
{1}, {}, "", {}, "", {},
132+
{}, true, "Constant_Velocity", {v_mag*0.1, v_mag*0.9, 0.});
133+
// or explicitly, we can do
134+
// initCondJson.at("Constant_Velocity").at("Particle_List") = std::vector<size_t>({1});
135+
// initCondJson.at("Constant_Velocity").at("Velocity_Vector") = std::vector<double>{v_mag*0.1, v_mag*0.9, 0.};
136+
}
137+
{
138+
bcDeckJson["IC"]["Set_2"] = inp::BCBaseDeck::getExampleJson("IC", false, util::geometry::GeomData(),
139+
{2}, {}, "", {}, "", {},
140+
{}, true, "Constant_Velocity", {v_mag*0.5, v_mag*0.5, 0.});
141+
}
142+
143+
// create bc deck after fixing json object
144+
deck->d_bcDeck_p = std::make_shared<inp::BCDeck>(bcDeckJson);
145+
146+
std::cout << "\n\nPrinting bc deck json:\n";
147+
std::cout << bcDeckJson.dump(2) << std::flush;
148+
149+
std::cout << "\n\nPrinting bc deck:\n";
150+
std::cout << deck->d_bcDeck_p->printStr() << std::endl;
151+
152+
// <<<<<<<<<<<<<<
153+
// Particle deck
154+
// <<<<<<<<<<<<<<
155+
auto pDeckJson = json({});
156+
157+
//// create particle geometry json
158+
std::vector<util::geometry::GeomData> pGeomVec(3); // 3 geometry groups
159+
160+
pGeomVec[0].d_geomName = "rectangle_minus_rectangle";
161+
// parameters
162+
pGeomVec[0].d_geomParams = std::vector<double>({0., 0., 0., 0.01, 0.01, 0., -h, -h, 0., 0.01+h, 0.01+h, 0.});
163+
164+
pGeomVec[1].d_geomName = "drum2d";
165+
// parameters to create drum2d: R, neck width, center, axis
166+
pGeomVec[1].d_geomParams = std::vector<double>({r, r*0.5, 0.004, 0.0065, 0., 1., 0., 0.});
167+
168+
pGeomVec[2].d_geomName = "circle";
169+
// parameters to create circle: R, center
170+
pGeomVec[2].d_geomParams = std::vector<double>({1.25*r, 0.007, 0.004, 0.});
171+
172+
// create block for particle geometry
173+
auto pGeomJson = inp::ParticleDeck::getParticleGeomExampleJson(pGeomVec);
174+
// add to the particle deck json
175+
pDeckJson["Particle"] = pGeomJson;
176+
177+
//// create particle mesh deck
178+
auto pMeshJson = inp::ParticleDeck::getParticleMeshExampleJson({"mesh_annulus_rectangle.msh",
179+
"mesh_drum2d.msh", "mesh_circle.msh"});
180+
pDeckJson["Mesh"] = pMeshJson;
181+
182+
//// create particle material json
183+
auto pMatJson = inp::ParticleDeck::getParticleMaterialExampleJson(2); // two material groups
184+
185+
// material 1
186+
pMatJson["Set_1"] = inp::MaterialDeck::getExampleJson("PDState", false, -1.,
187+
2.2, 1200., 25000., 1200., 500., true, 1);
188+
189+
// material 2 (copy from material 1)
190+
pMatJson["Set_2"] = {{"Copy_Data", 1}};
191+
192+
// add to the json
193+
pDeckJson["Material"] = pMatJson;
194+
195+
//// create particle contact json
196+
auto pContactJson = inp::ParticleDeck::getParticleContactExampleJson(2);
197+
198+
// contact pair 1 - 1
199+
pContactJson["Set_1_1"] = inp::ContactPairDeck::getExampleJson(0.95,
200+
true, false, false,
201+
1e+22, 0.95, 0., 1., 1., 1., 0.);
202+
// copy other pairs
203+
pContactJson["Set_1_2"] = {{"Copy_Data", std::vector<int>({1, 1})}};
204+
pContactJson["Set_2_2"] = {{"Copy_Data", std::vector<int>({1, 1})}};
205+
206+
// add to the json
207+
pDeckJson["Contact"] = pContactJson;
208+
209+
//// create particle neighbor json
210+
pDeckJson["Neighbor"] = inp::PNeighborDeck::getExampleJson("simple_all", 5, 10, 0.5);
211+
212+
//// create particle generation json
213+
auto pGenJson = inp::PGenDeck::getExampleJson("From_File");
214+
215+
// add data that will be used to create particles
216+
pGenJson["Data"]["N"] = 3; // three particles
217+
218+
// p1
219+
pGenJson["Data"]["0"] = {{"x", 0.}, {"y", 0.}, {"z", 0.}, {"o", 0.}, {"s", 1.},
220+
{"geom_id", 0}, {"mat_id", 0}, {"mesh_id", 0}, {"contact_id", 0}};
221+
222+
// p1
223+
pGenJson["Data"]["1"] = {{"x", 0.}, {"y", 0.}, {"z", 0.}, {"o", 0.}, {"s", 1.},
224+
{"geom_id", 1}, {"mat_id", 1}, {"mesh_id", 1}, {"contact_id", 1}};
225+
226+
// p1
227+
pGenJson["Data"]["2"] = {{"x", 0.}, {"y", 0.}, {"z", 0.}, {"o", 0.}, {"s", 1.},
228+
{"geom_id", 2}, {"mat_id", 1}, {"mesh_id", 2}, {"contact_id", 1}};
229+
230+
// add to json
231+
pDeckJson["Particle_Generation"] = pGenJson;
232+
233+
//// we now have the particle information in json object, so we can read them one by one
234+
// read json object
235+
std::cout << "\n\nPrinting particle deck json:\n";
236+
std::cout << pDeckJson.dump(2) << std::endl;
237+
238+
deck->d_particleDeck_p = std::make_shared<inp::ParticleDeck>(pDeckJson, deck->d_modelDeck_p->d_particleSimType);
239+
240+
std::cout << "\n\nPrinting particle deck:\n";
241+
std::cout << deck->d_particleDeck_p->printStr() << std::endl;
242+
243+
244+
//// collect json objects into global json object that will show the structure of input file
245+
auto inputJson = json({{"Model", modelDeckJson}, {"Test", testDeckJson},
246+
{"Output", outputDeckJson}, {"Displacement_BC", bcDeckJson["Displacement_BC"]},
247+
{"IC", bcDeckJson["IC"]}, {"Particle", pDeckJson["Particle"]}, {"Mesh", pDeckJson["Mesh"]},
248+
{"Material", pDeckJson["Material"]}, {"Contact", pDeckJson["Contact"]},
249+
{"Neighbor", pDeckJson["Neighbor"]}, {"Particle_Generation", pDeckJson["Particle_Generation"]}});
250+
251+
std::cout << "\n\nPrinting global input deck json:\n";
252+
std::cout << inputJson.dump(2) << std::endl;
253+
// save to file
254+
std::ofstream f("input.json");
255+
f << inputJson.dump(2);
256+
f.close();
257+
}

0 commit comments

Comments
 (0)