PRISMS-PF  v2.1
load_user_constants.cc
Go to the documentation of this file.
1 #include "../../include/userInputParameters.h"
2 #include <deal.II/base/mpi.h>
3 #include <deal.II/base/utilities.h>
4 
5 // ==========================================================================================
6 // Method to extract the user-defined model constants
7 // ==========================================================================================
8 template <int dim>
9 void userInputParameters<dim>::load_user_constants(inputFileReader & input_file_reader, dealii::ParameterHandler & parameter_handler){
10 
11  unsigned int number_of_constants = input_file_reader.num_constants;
12 
13  for (unsigned int i=0; i<input_file_reader.model_constant_names.size(); i++){
14  model_constant_name_map[input_file_reader.model_constant_names[i]] = i;
15  }
16 
17 
18  for (unsigned int i=0; i<number_of_constants; i++){
19  std::string constants_text = "Model constant ";
20  constants_text.append(input_file_reader.model_constant_names[i]);
21  //std::cout << input_file_reader.model_constant_names[i] << std::endl;
22  std::vector<std::string> model_constants_strings = dealii::Utilities::split_string_list(parameter_handler.get(constants_text));
23 
24  // Ensure that the input includes a value and a type
25  if (model_constants_strings.size() < 2){
26  std::cerr << "PRISMS-PF ERROR: Users must input two fields for user-defined variables (value and type)." << std::endl;
27  abort();
28  }
29 
30  std::vector<std::string> model_constants_type_strings = dealii::Utilities::split_string_list(model_constants_strings.at(model_constants_strings.size()-1),' ');
31 
32  if (model_constants_strings.size() == 2){
33  if (boost::iequals(model_constants_type_strings.at(0),"double")){
34  model_constants.push_back(dealii::Utilities::string_to_double(model_constants_strings.at(0)));
35 
36  }
37  else if (boost::iequals(model_constants_type_strings.at(0),"int")){
38  model_constants.push_back(dealii::Utilities::string_to_int(model_constants_strings.at(0)));
39  }
40  else if (boost::iequals(model_constants_type_strings.at(0),"bool")){
41  bool temp;
42  if (boost::iequals(model_constants_strings.at(0),"true")){
43  temp = true;
44  }
45  else {
46  temp = false;
47  }
48  model_constants.push_back(temp);
49  }
50  else {
51  std::cerr << "PRISMS-PF ERROR: The type for user-defined variables must be 'double', 'int', 'bool', 'tensor', or 'elastic constants'." << std::endl;
52  abort();
53  }
54  }
55  else {
56  if (boost::iequals(model_constants_type_strings.at(0),"tensor")){
57  unsigned int num_elements = model_constants_strings.size()-1;
58 
59  // Strip parentheses from the input, counting how many rows there are
60  unsigned int open_parentheses = 0;
61  unsigned int close_parentheses = 0;
62  for (unsigned int element=0; element<num_elements; element++){
63  std::size_t index = 0;
64  while (index != std::string::npos){
65  index = model_constants_strings.at(element).find("(");
66  if (index != std::string::npos) {
67  model_constants_strings.at(element).erase(index,1);
68  open_parentheses++;
69  }
70  }
71  index = 0;
72  while (index != std::string::npos){
73  index = model_constants_strings.at(element).find(")");
74  if (index != std::string::npos) {
75  model_constants_strings.at(element).erase(index,1);
76  close_parentheses++;
77  }
78  }
79  }
80  if (open_parentheses != close_parentheses){
81  std::cerr << "PRISMS-PF ERROR: User-defined constant tensor does not have the same number of open and close parentheses." << std::endl;
82  abort();
83  }
84  // Rank 1 tensor
85  if (open_parentheses < 3){
86  if (num_elements > 1 && num_elements < 4){
87  dealii::Tensor<1,dim> temp;
88  for (unsigned int i=0; i<dim; i++){
89  temp[i] = dealii::Utilities::string_to_double(model_constants_strings.at(i));
90  }
91  model_constants.push_back(temp);
92  }
93  else {
94  std::cerr << "PRISMS-PF ERROR: The columns in user-defined constant tensors cannot be longer than 3 elements (internally truncated to the number of dimensions)." << std::endl;
95  abort();
96  }
97  }
98  // Rank 2 tensor
99  else if (open_parentheses < 5){
100  unsigned int row_length;
101  if (num_elements == 4){
102  row_length = 2;
103  if (dim > 2){
104  std::cerr << "PRISMS-PF ERROR: User-defined constant tensor does not have enough elements, for 3D calculations matrices must be 3x3." << std::endl;
105  abort();
106  }
107  }
108  else if (num_elements == 9){
109  row_length = 3;
110  }
111  else {
112  std::cerr << "PRISMS-PF ERROR: User-defined constant tensor does not have the correct number of elements, matrices must be 2x2 or 3x3." << std::endl;
113  abort();
114  }
115 
116  dealii::Tensor<2,dim> temp;
117  for (unsigned int i=0; i<dim; i++){
118  for (unsigned int j=0; j<dim; j++){
119  temp[i][j] = dealii::Utilities::string_to_double(model_constants_strings.at(i*row_length+j));
120  }
121  }
122  model_constants.push_back(temp);
123  }
124  }
125  else if (boost::iequals(model_constants_type_strings.at(1),"elastic") && boost::iequals(model_constants_type_strings.at(2),"constants")){
126  unsigned int num_elements = model_constants_strings.size()-1;
127 
128  // Strip parentheses from the input, counting how many rows there are
129  unsigned int open_parentheses = 0;
130  unsigned int close_parentheses = 0;
131  for (unsigned int element=0; element<num_elements; element++){
132  std::size_t index = 0;
133  while (index != std::string::npos){
134  index = model_constants_strings.at(element).find("(");
135  if (index != std::string::npos) {
136  model_constants_strings.at(element).erase(index,1);
137  open_parentheses++;
138  }
139  }
140  index = 0;
141  while (index != std::string::npos){
142  index = model_constants_strings.at(element).find(")");
143  if (index != std::string::npos) {
144  model_constants_strings.at(element).erase(index,1);
145  close_parentheses++;
146  }
147  }
148  }
149  if (open_parentheses != close_parentheses){
150  std::cerr << "PRISMS-PF ERROR: User-defined elastic constant list does not have the same number of open and close parentheses." << std::endl;
151  abort();
152  }
153 
154  // Load in the elastic constants as a vector
155  std::vector<double> temp_elastic_constants;
156  for (unsigned int i=0; i<num_elements; i++){
157  temp_elastic_constants.push_back(dealii::Utilities::string_to_double(model_constants_strings.at(i)));
158  }
159 
160  std::string elastic_const_symmetry = model_constants_type_strings.at(0);
161  dealii::Tensor<2,2*dim-1+dim/3> temp = get_Cij_tensor(temp_elastic_constants,elastic_const_symmetry);
162  model_constants.push_back(temp);
163  }
164  else {
165  std::cerr << "PRISMS-PF ERROR: Only user-defined constant tensors may have multiple elements." << std::endl;
166  abort();
167  }
168 
169  }
170  }
171 }
172 
173 // ==========================================================================================
174 // Method to build the elasticity tensor from a list of elastic constants
175 // ==========================================================================================
176 template <int dim>
177 dealii::Tensor<2,2*dim-1+dim/3> userInputParameters<dim>::get_Cij_tensor(std::vector<double> elastic_constants, const std::string elastic_const_symmetry) const{
178  // First set the material model
179  elasticityModel mat_model = ISOTROPIC;
180  if (elastic_const_symmetry == "isotropic"){
181  mat_model = ISOTROPIC;
182  }
183  else if (elastic_const_symmetry == "transverse"){
184  mat_model = TRANSVERSE;
185  }
186  else if (elastic_const_symmetry == "orthotropic"){
187  mat_model = ORTHOTROPIC;
188  }
189  else if (elastic_const_symmetry == "anisotropic"){
190  mat_model = ANISOTROPIC;
191  }
192  else {
193  // Should change to an exception
194  std::cerr << "Elastic material model is invalid, please use isotropic, transverse, orthotropic, or anisotropic" << std::endl;
195  }
196 
197  // If the material model is anisotropic for a 2D calculation but the elastic constants are given for a 3D calculation,
198  // change the elastic constant vector to the 2D form
199  if ((mat_model == ANISOTROPIC) && (dim == 2) && elastic_constants.size() == 21) {
200  std::vector<double> elastic_constants_temp = elastic_constants;
201  elastic_constants.clear();
202  std::vector<unsigned int> indices_2D = {0, 1, 5, 6, 10, 14};
203  for (unsigned int i=0; i<indices_2D.size(); i++){
204  elastic_constants.push_back(elastic_constants_temp.at(indices_2D.at(i)));
205  }
206  }
207 
208  dealii::ConditionalOStream pcout(std::cout, dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD)==0);
209 
210 
211  return getCIJMatrix(mat_model, elastic_constants, pcout);
212 }
213 
214 //implementation of various models of anisotropy for
215 //st.venant-kirchoff material model of elasticity
216 
217 //#include <deal.II/base/conditional_ostream.h>
218 
219 //Each material model is characterized by the number of independent
220 //constants required to characterize its elasticity tensor in the Voigt
221 //notation
222 
223 //3D models:
224 //ISOTROPIC - 2 constants [E, nu], where E-modulus and nu-poisson's ratio
225 //TRANSVERSE- 5 constants [C11 C33 C44 C12 C13]
226 //ORTHOTROPIC- 9 constants [C11 C22 C33 C44 C55 C66 C12 C13 C23]
227 //ANISOTROPIC- 21 constants [C11 C22 C33 C44 C55 C66 C12 C13 C14 C15
228 //C16 C23 C24 C25 C26 C34 C35 C36 C45 C46 C56]
229 
230 //2D models:
231 //ISOTROPIC- 2 constants [E, nu] (Plane Strain)
232 //ANISOTROPIC- 6 constants [C11 C22 C66 C12 C16 C26] (Plane Strain)
233 
234 //1D models:
235 //ISOTROPIC- 1 constant [E]
236 
237 template <int dim>
238 dealii::Tensor<2, 2*dim-1+dim/3> userInputParameters<dim>::getCIJMatrix(const elasticityModel model, const std::vector<double> constants, dealii::ConditionalOStream & pcout) const {
239  //CIJ.fill(0.0);
240  dealii::Tensor<2, 2*dim-1+dim/3> CIJ;
241 
242  pcout << "Reading material model:";
243  switch (dim){
244  case 1:{
245  pcout << " 1D ";
246  //1D models
247  switch (model){
248  case ISOTROPIC:{
249  pcout << " ISOTROPIC \n";
250  CIJ[0][0]=constants[0];
251  break;
252  }
253  default:{
254  std::cout << "\nelasticityModels: Supported models in 1D - ISOTROPIC\n";
255  std::cout << "See /src/elasticityModels.h\n";
256  exit(-1);
257  }
258  }
259  break;
260  }
261  case 2:{
262  pcout << " 2D ";
263  //2D models
264  switch (model){
265  case ISOTROPIC:{
266  pcout << " ISOTROPIC \n";
267  double E=constants[0], nu=constants[1];
268  double mu=E/(2*(1+nu)), lambda= nu*E/((1+nu)*(1-2*nu));
269  CIJ[0][0]=lambda+2*mu;
270  CIJ[1][1]=lambda+2*mu;
271  CIJ[2][2]=mu;
272  CIJ[0][1]=CIJ[1][0]=lambda;
273  break;
274  }
275  case ANISOTROPIC:{
276  pcout << " ANISOTROPIC \n";
277  CIJ[0][0]=constants[0]; //C11
278  CIJ[1][1]=constants[1]; //C22
279  CIJ[2][2]=constants[2]; //C33
280  CIJ[0][1]=CIJ[1][0]=constants[3]; //C12
281  CIJ[0][2]=CIJ[2][0]=constants[4]; //C13
282  CIJ[1][2]=CIJ[2][1]=constants[5]; //C23
283  break;
284  }
285  default:{
286  std::cout << "\nelasticityModels: Supported models in 2D - ISOTROPIC/ANISOTROPIC\n";
287  std::cout << "See /src/elasticityModels.h\n";
288  exit(-1);
289  }
290  }
291  break;
292  }
293  case 3:{
294  pcout << " 3D ";
295  //3D models
296  switch (model){
297  case ISOTROPIC:{
298  pcout << " ISOTROPIC \n";
299  double E=constants[0], nu=constants[1];
300  double mu=E/(2*(1+nu)), lambda= nu*E/((1+nu)*(1-2*nu));
301  CIJ[0][0]=lambda+2*mu;
302  CIJ[1][1]=lambda+2*mu;
303  CIJ[2][2]=lambda+2*mu;
304  CIJ[3][3]=mu;
305  CIJ[4][4]=mu;
306  CIJ[5][5]=mu;
307  CIJ[0][1]=CIJ[1][0]=lambda;
308  CIJ[0][2]=CIJ[2][0]=lambda;
309  CIJ[1][2]=CIJ[2][1]=lambda;
310  break;
311  }
312  case TRANSVERSE:{
313  pcout << " TRANSVERSE \n";
314  CIJ[0][0]=constants[0]; //C11
315  CIJ[1][1]=constants[0]; //C11
316  CIJ[2][2]=constants[1]; //C33
317  CIJ[3][3]=constants[2]; //C44
318  CIJ[4][4]=constants[2]; //C44
319  CIJ[5][5]=(constants[0]-constants[3])/2.0; //(C11-C12)/2
320  CIJ[0][1]=CIJ[1][0]=constants[3]; //C12
321  CIJ[0][2]=CIJ[2][0]=constants[4]; //C13
322  CIJ[1][2]=CIJ[2][1]=constants[4]; //C13
323  break;
324  }
325  case ORTHOTROPIC:{
326  pcout << " ORTHOTROPIC \n";
327  CIJ[0][0]=constants[0]; //C11
328  CIJ[1][1]=constants[1]; //C22
329  CIJ[2][2]=constants[2]; //C33
330  CIJ[3][3]=constants[3]; //C44
331  CIJ[4][4]=constants[4]; //C55
332  CIJ[5][5]=constants[5]; //C66
333  CIJ[0][1]=CIJ[1][0]=constants[6]; //C12
334  CIJ[0][2]=CIJ[2][0]=constants[7]; //C13
335  CIJ[1][2]=CIJ[2][1]=constants[8]; //C23
336  break;
337  }
338  case ANISOTROPIC:{
339  pcout << " ANISOTROPIC \n";
340  CIJ[0][0]=constants[0]; //C11
341  CIJ[1][1]=constants[1]; //C22
342  CIJ[2][2]=constants[2]; //C33
343  CIJ[3][3]=constants[3]; //C44
344  CIJ[4][4]=constants[4]; //C55
345  CIJ[5][5]=constants[5]; //C66
346  CIJ[0][1]=CIJ[1][0]=constants[6]; //C12
347  CIJ[0][2]=CIJ[2][0]=constants[7]; //C13
348  CIJ[0][3]=CIJ[3][0]=constants[8]; //C14
349  CIJ[0][4]=CIJ[4][0]=constants[9]; //C15
350  CIJ[0][5]=CIJ[5][0]=constants[10]; //C16
351  CIJ[1][2]=CIJ[2][1]=constants[11]; //C23
352  CIJ[1][3]=CIJ[3][1]=constants[12]; //C24
353  CIJ[1][4]=CIJ[4][1]=constants[13]; //C25
354  CIJ[1][5]=CIJ[5][1]=constants[14]; //C26
355  CIJ[2][3]=CIJ[3][2]=constants[15]; //C34
356  CIJ[2][4]=CIJ[4][2]=constants[16]; //C35
357  CIJ[2][5]=CIJ[5][2]=constants[17]; //C36
358  CIJ[3][4]=CIJ[4][3]=constants[18]; //C45
359  CIJ[3][5]=CIJ[5][3]=constants[19]; //C46
360  CIJ[4][5]=CIJ[5][4]=constants[20]; //C56
361  break;
362  }
363  default:{
364  std::cout << "\nelasticityModels: Supported models in 3D - ISOTROPIC/TRANSVERSE/ORTHOTROPIC/ANISOTROPIC\n";
365  std::cout << "See /src/elasticityModels.h\n";
366  exit(-1);
367  }
368  }
369  break;
370  }
371  default:{
372  std::cout << "\nelasticityModels: DIM is not 1/2/3\n";
373  exit(-1);
374  }
375  }
376  //print CIJ to terminal
377  pcout << "Elasticity matrix (Voigt notation):\n";
378  char buffer[100];
379  for (unsigned int i=0; i<2*dim-1+dim/3; i++){
380  for (unsigned int j=0; j<2*dim-1+dim/3; j++){
381  sprintf(buffer, "%8.3e ", CIJ[i][j]);
382  pcout << buffer;
383  }
384  pcout << "\n";
385  }
386  pcout << "\n";
387  return CIJ;
388 }
389 
390 // Template instantiations
391 #include "../../include/userInputParameters_template_instantiations.h"
dealii::Tensor< 2, 2 *dim-1+dim/3 > getCIJMatrix(const elasticityModel model, const std::vector< double > constants, dealii::ConditionalOStream &pcout) const
void load_user_constants(inputFileReader &input_file_reader, dealii::ParameterHandler &parameter_handler)
elasticityModel
unsigned int num_constants
std::vector< std::string > model_constant_names
dealii::Tensor< 2, 2 *dim-1+dim/3 > get_Cij_tensor(std::vector< double > elastic_constants, const std::string elastic_const_symmetry) const