|
| 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