Line data Source code
1 : /*************************************************/ 2 : /* DO NOT MODIFY THIS HEADER */ 3 : /* */ 4 : /* MASTODON */ 5 : /* */ 6 : /* (c) 2015 Battelle Energy Alliance, LLC */ 7 : /* ALL RIGHTS RESERVED */ 8 : /* */ 9 : /* Prepared by Battelle Energy Alliance, LLC */ 10 : /* With the U. S. Department of Energy */ 11 : /* */ 12 : /* See COPYRIGHT for full restrictions */ 13 : /*************************************************/ 14 : 15 : #include "GroundMotionSim.h" 16 : registerMooseObject("MastodonApp", GroundMotionSim); 17 : 18 : InputParameters 19 6 : GroundMotionSim::validParams() 20 : { 21 6 : InputParameters params = Function::validParams(); 22 12 : params.addRequiredParam<Real>("M", "Magnitude of Event"); 23 12 : params.addRequiredParam<Real>("R", "Joyner-Boore or Epicentral Distance"); 24 12 : params.addRequiredParam<Real>("Vs30", "Shear Wave Velocity at 30m"); 25 12 : MooseEnum F("SS TF NF", "SS"); 26 12 : MooseEnum R_type("Rjb Repi", "Rjb"); 27 12 : params.addParam<MooseEnum>("F", F, "Style of Faulting"); 28 12 : params.addParam<MooseEnum>( 29 : "R_type", R_type, "Indicates whether R distance is Joyner-Boore or Epicentral distance"); 30 12 : params.addParam<unsigned int>("n", 1012, "Random Seed"); 31 12 : params.addParam<Real>("scale_factor", 9.81, "acceleration scaling factor"); 32 6 : params.set<std::vector<Real>>("xy_data") = {}; 33 6 : params.addClassDescription("Calculates a ground acceleration history using a ground motion model " 34 : "written in a python script"); 35 6 : return params; 36 6 : } 37 : 38 : // Define arbitrarily large size of preallocated arrays for t and Acc 39 : #define BUFSIZE 20000 40 : 41 3 : GroundMotionSim::GroundMotionSim(const InputParameters & parameters) 42 6 : : PiecewiseLinearBase(parameters), _scale_factor(getParam<Real>("scale_factor")) 43 : { 44 : 45 6 : const auto M = this->template getParam<Real>("M"); 46 6 : const auto R = this->template getParam<Real>("R"); 47 6 : const auto V = this->template getParam<Real>("Vs30"); 48 6 : const auto n = this->template getParam<unsigned int>("n"); 49 3 : std::string R_type = this->template getParam<MooseEnum>("R_type"); 50 6 : std::string F = this->template getParam<MooseEnum>("F"); 51 : 52 : // Convert input parameters to strings 53 : std::string Mstr = std::to_string(M); 54 : std::string Rstr = std::to_string(R); 55 : std::string Vstr = std::to_string(V); 56 3 : std::string nstr = std::to_string(n); 57 : 58 : // Get path to simulation script 59 3 : std::string PATH = getDataFileNameByName("GMSim.py"); 60 : 61 : // Concatenate command with input parameters 62 3 : std::string command = "python3 " + PATH + " GroundMotionSim "; 63 18 : command += Mstr + " " + R_type + " " + Rstr + " " + Vstr + " " + F + " " + nstr; 64 : 65 : // Convert command to C character string for use in parse_output function 66 : char const * cmd = command.c_str(); 67 : 68 : // Initialize time and acceleration variables 69 : std::string t; 70 : std::string Acc; 71 : 72 : // Run command line parsing function 73 3 : parse_output(cmd, t, Acc); 74 : 75 : // Initialize vectors to hold data 76 : std::vector<Real> x; 77 : std::vector<Real> y; 78 3 : x.reserve(BUFSIZE); 79 3 : y.reserve(BUFSIZE); 80 : 81 : // Build an istream that holds the input string 82 6 : std::istringstream iss(t.substr(1, t.length())); 83 6 : std::istringstream jss(Acc.substr(1, Acc.length())); 84 : 85 : // Iterate over the istream, using >> to grab floats 86 : // and push_back to store them in the vector 87 3 : std::copy(std::istream_iterator<Real>(iss), std::istream_iterator<Real>(), std::back_inserter(x)); 88 : 89 3 : std::copy(std::istream_iterator<Real>(jss), std::istream_iterator<Real>(), std::back_inserter(y)); 90 : 91 : // Set the x (time) and y(acc) values in the PiecewiseLinearBase class 92 3 : setData(x, y); 93 6 : } 94 : 95 : void 96 3 : GroundMotionSim::parse_output(const char * cmd, std::string & t, std::string & Acc) const 97 : { 98 : // Function to execute command line commands that run a pythong script 99 : // which calculates the acceleration history for a ground motion. 100 : // The function then reads the output and saves it into strings 101 : 102 : // Initializing variables 103 : std::array<char, BUFSIZE> buffer; 104 : std::string result; 105 : 106 : // This variable is used to track when the output changes from 107 : // time array to acceleration array 108 : char trackbuf; 109 : 110 : // Run command and check for command line errors 111 3 : auto pipe = popen(cmd, "r"); // get rid of shared_ptr 112 3 : if (!pipe) 113 0 : throw std::runtime_error("popen() failed!"); 114 : 115 : // Iterate over the output of the command line 116 7797 : while (!feof(pipe)) 117 : { 118 : 119 7794 : if (fgets(buffer.data(), BUFSIZE, pipe) != nullptr) 120 : { 121 : 122 : // Check if the end of the t vector has been reached 123 7791 : if (trackbuf != 'A') 124 : { 125 3120 : trackbuf = buffer[0]; 126 : } 127 : 128 : // append strings with command line data 129 3120 : if (trackbuf != 'A') 130 : { 131 : t += buffer.data(); 132 : } 133 : else 134 : { 135 : Acc += buffer.data(); 136 : } 137 : } 138 : } 139 : 140 : // Close command line 141 3 : auto rc = pclose(pipe); 142 : 143 : if (rc == EXIT_SUCCESS) 144 : { // == 0 145 : } 146 : else if (rc == EXIT_FAILURE) 147 : { // EXIT_FAILURE is not used by all programs, maybe needs some adaptation. 148 : } 149 : 150 : // Remove "t=" and "Acc=" from strings 151 3 : t.erase(0, 3); 152 3 : Acc.erase(0, 5); 153 3 : return; 154 : }