Geant4 Cross Reference |
1 // ******************************************* 1 2 // * License and Disclaimer 3 // * 4 // * The Geant4 software is copyright of th 5 // * the Geant4 Collaboration. It is provided 6 // * conditions of the Geant4 Software License 7 // * LICENSE and available at http://cern.ch/ 8 // * include a list of copyright holders. 9 // * 10 // * Neither the authors of this software syst 11 // * institutes,nor the agencies providing fin 12 // * work make any representation or warran 13 // * regarding this software system or assum 14 // * use. Please see the license in the file 15 // * for the full disclaimer and the limitatio 16 // * 17 // * This code implementation is the result 18 // * technical work of the GEANT4 collaboratio 19 // * By using, copying, modifying or distri 20 // * any work based on the software) you ag 21 // * use in resulting scientific publicati 22 // * acceptance of all terms of the Geant4 Sof 23 // ******************************************* 24 // 25 //-------------------------------------------- 26 // The Geant4 Virtual Monte Carlo package 27 // Copyright (C) 2007 - 2015 Ivana Hrivnacova 28 // All rights reserved. 29 // 30 // For the licensing terms see geant4_vmc/LICE 31 // Contact: root-vmc@cern.ch 32 //-------------------------------------------- 33 34 /// \file G4FieldBuilder.cc 35 /// \brief Implementation of the G4FieldBuilde 36 /// 37 /// \author I. Hrivnacova; IJCLab, Orsay 38 39 #include "G4FieldBuilder.hh" 40 #include "G4FieldBuilderMessenger.hh" 41 42 #include "G4Exception.hh" 43 #include "G4FieldParameters.hh" 44 #include "G4FieldSetup.hh" 45 #include "G4LogicalVolume.hh" 46 #include "G4ios.hh" 47 48 G4ThreadLocal G4Field* G4FieldBuilder::fGloba 49 G4ThreadLocal G4bool G4FieldBuilder::fIsConstr 50 51 //____________________________________________ 52 G4FieldBuilder* G4FieldBuilder::Instance() 53 { 54 static G4FieldBuilder instance; 55 fgIsInstance = true; 56 return &instance; 57 } 58 59 //____________________________________________ 60 G4FieldBuilder::G4FieldBuilder() 61 { 62 // Default constructor 63 64 fMessenger = new G4FieldBuilderMessenger(thi 65 66 // Field parameters for global field 67 fFieldParameters.push_back(new G4FieldParame 68 } 69 70 //____________________________________________ 71 G4FieldBuilder::~G4FieldBuilder() 72 { 73 // Destructor 74 75 delete fMessenger; 76 77 for (auto parameters : fFieldParameters) { 78 delete parameters; 79 } 80 81 for (auto setup : GetFieldSetups()) { 82 delete setup; 83 } 84 85 fgIsInstance = false; 86 87 // magnetic field objects are deleted via G4 88 } 89 90 // 91 // private methods 92 // 93 94 //____________________________________________ 95 G4FieldParameters* G4FieldBuilder::GetOrCreate 96 const G4String& volumeName) 97 { 98 // Get field parameters with the given volum 99 // do not exist yet 100 101 // Get user field parameters 102 for (auto fieldParameters : fFieldParameters 103 if (fieldParameters->GetVolumeName() == vo 104 // G4cout << "Found field parameters for 105 return fieldParameters; 106 } 107 } 108 109 // Create field parameters if not yet define 110 // G4cout << "Go to create field parameters 111 auto fieldParameters = new G4FieldParameters 112 fFieldParameters.push_back(fieldParameters); 113 return fieldParameters; 114 } 115 116 //____________________________________________ 117 G4FieldSetup* G4FieldBuilder::GetFieldSetup(G4 118 { 119 // Get field setup with the given logical vo 120 121 // Get user field parameters 122 for (auto fieldSetup : GetFieldSetups()) { 123 if (fieldSetup->GetLogicalVolume() == lv) 124 return fieldSetup; 125 } 126 } 127 128 return nullptr; 129 } 130 131 //____________________________________________ 132 void G4FieldBuilder::CreateFieldSetup(G4Field* 133 G4FieldParameters* fieldParameters, G4Logica 134 { 135 // Create magnetic, electromagnetic or gravi 136 137 auto fieldSetup = new G4FieldSetup(*fieldPar 138 fieldSetup->PrintInfo(fVerboseLevel); 139 140 if (fFieldSetups.Get() == nullptr) { 141 auto fieldSetups = new std::vector<G4Field 142 fFieldSetups.Put(fieldSetups); 143 } 144 145 GetFieldSetups().push_back(fieldSetup); 146 } 147 148 //____________________________________________ 149 void G4FieldBuilder::ConstructGlobalField() 150 { 151 // Construct Geant4 global magnetic field se 152 153 if (fVerboseLevel > 1) { 154 G4cout << "G4FieldBuilder::ConstructGlobal 155 } 156 157 CreateFieldSetup(fGlobalField, fFieldParamet 158 } 159 160 //____________________________________________ 161 void G4FieldBuilder::ConstructLocalFields() 162 { 163 // Construct Geant4 local magnetic field set 164 165 if (fLocalFields.Get() == nullptr) return; 166 167 if (fVerboseLevel > 1) { 168 G4cout << "G4FieldBuilder::ConstructLocalF 169 } 170 171 // Loop over local field map 172 for (auto [lv, field] : GetLocalFields()) { 173 174 // Volume name 175 const auto& volumeName = lv->GetName(); 176 177 // Get or create user field parameters 178 G4FieldParameters* fieldParameters = 179 GetOrCreateFieldParameters(volumeName); 180 181 if (fVerboseLevel > 1) { 182 G4cout << "Construct local field in volu 183 } 184 185 // Create magnetic field 186 CreateFieldSetup(field, fieldParameters, l 187 } 188 } 189 190 //____________________________________________ 191 void G4FieldBuilder::UpdateFieldSetups() 192 { 193 // Update all field setups 194 195 if (fVerboseLevel > 1) { 196 G4cout << "G4FieldBuilder::UpdateFieldSetu 197 } 198 199 for (auto fieldSetup : GetFieldSetups()) { 200 fieldSetup->Update(); 201 202 if (fVerboseLevel > 1) { 203 fieldSetup->PrintInfo(fVerboseLevel, "up 204 } 205 } 206 } 207 208 // 209 // public methods 210 // 211 212 //____________________________________________ 213 G4FieldParameters* G4FieldBuilder::CreateField 214 const G4String& fieldVolName) 215 { 216 // Create local magnetic field parameters (c 217 // configured by the user via UI commands. 218 // The parameters are used in geometry only 219 // associated with the volumes with the give 220 221 auto fieldParameters = new G4FieldParameters 222 fFieldParameters.push_back(fieldParameters); 223 224 return fieldParameters; 225 } 226 227 //____________________________________________ 228 void G4FieldBuilder::ConstructFieldSetup() 229 { 230 // Construct setups for all registered field 231 232 if (fVerboseLevel > 1) { 233 G4cout << "G4FieldBuilder::ConstructField" 234 } 235 236 if (fIsConstructed) { 237 G4Exception( 238 "G4FieldBuilder::ConstructField:", "Geom 239 JustWarning, "Field was already construc 240 return; 241 } 242 243 ConstructGlobalField(); 244 ConstructLocalFields(); 245 246 UpdateFieldSetups(); 247 248 fIsConstructed = true; 249 } 250 251 //____________________________________________ 252 void G4FieldBuilder::UpdateField() 253 { 254 // Update magnetic field. 255 // This function must be called if the field 256 // in other than PreInit> phase. 257 258 if (fFieldSetups.Get() == nullptr) { 259 G4Exception( 260 "G4FieldBuilder::UpdateField", "GeomFiel 261 JustWarning, "No field setup is defined. 262 return; 263 } 264 265 if (fVerboseLevel > 1) { 266 G4cout << "G4FieldBuilder::UpdateField" << 267 } 268 269 // Update the objects defined in G4FieldSetu 270 UpdateFieldSetups(); 271 } 272 273 //____________________________________________ 274 void G4FieldBuilder::Reinitialize() 275 { 276 // Reinitialize if geometry has been modifie 277 // This function is called by G4RunManager d 278 279 if (fVerboseLevel > 1) { 280 G4cout << "G4FieldBuilder::Reinitialize" < 281 } 282 283 // Delete global field 284 delete fGlobalField; 285 fGlobalField = nullptr; 286 287 // Delete local fields if defined 288 if (fLocalFields.Get() != nullptr) { 289 for (auto vectorElement : GetLocalFields() 290 delete vectorElement.second; 291 } 292 // Clear local fields map 293 GetLocalFields().clear(); 294 } 295 296 // Clear field setups if defined 297 if (fFieldSetups.Get() != nullptr) { 298 for (auto fieldSetup : GetFieldSetups()) { 299 fieldSetup->SetG4Field(nullptr); 300 fieldSetup->Clear(); 301 } 302 } 303 304 fIsConstructed = false; 305 306 if (fVerboseLevel > 1) { 307 G4cout << "End of G4FieldBuilder::Reinitia 308 } 309 } 310 311 //____________________________________________ 312 void G4FieldBuilder::SetFieldType(G4FieldType 313 { 314 // Default field type is set to kMagnetic; 315 // this function should be called for other th 316 // in order to update the default equation and 317 318 if (fIsConstructed) { 319 G4Exception( 320 "G4FieldBuilder::SetFieldType:", "GeomFi 321 JustWarning, "Field was already construc 322 return; 323 } 324 325 fFieldParameters[0]->SetFieldType(fieldType) 326 327 // change default equation and stepper if ot 328 if (fieldType == kElectroMagnetic) { 329 fFieldParameters[0]->SetEquationType(kEqEl 330 fFieldParameters[0]->SetStepperType(kClass 331 } 332 } 333 334 //____________________________________________ 335 void G4FieldBuilder::SetGlobalField(G4Field* f 336 { 337 // Set or reset the global field. 338 // Update field objects, if the field was al 339 // If warn, issue a warning if the previous 340 341 if (fGlobalField != nullptr && warn) { 342 G4Exception( 343 "G4FieldBuilder::SetGlobalField:", "Geom 344 JustWarning, "The global field already e 345 } 346 delete fGlobalField; 347 fGlobalField = field; 348 349 if (fIsConstructed) { 350 // update the global field objects if alre 351 GetFieldSetups()[0]->SetG4Field(field); 352 GetFieldSetups()[0]->Update(); 353 } 354 } 355 356 //____________________________________________ 357 void G4FieldBuilder::SetLocalField( 358 G4Field* field, G4LogicalVolume* lv, G4bool 359 { 360 // Register the local field in the map. 361 // Update field objects, if the field was al 362 // If warn, issue a warning if the previous 363 364 if (lv == nullptr) { 365 G4cerr << "Cannot register local field wit 366 return; 367 } 368 369 if (fLocalFields.Get() == nullptr) { 370 auto localFields = new std::vector<std::pa 371 fLocalFields.Put(localFields); 372 } 373 374 auto it = GetLocalFields().begin(); 375 for (it = GetLocalFields().begin(); it != Ge 376 if (it->first == lv) break; 377 } 378 379 if (it != GetLocalFields().end()) { 380 // replaced field if already in the map 381 if (warn) { 382 G4ExceptionDescription descr; 383 descr << "Logical volume " << lv->GetNam 384 " It will be deleted."; 385 G4Exception( 386 "G4FieldBuilder::SetLocalField:", "Geo 387 JustWarning, descr); 388 } 389 delete it->second; 390 it->second = field; 391 } 392 else { 393 // register field in the map 394 GetLocalFields().push_back(std::pair(lv,fi 395 } 396 397 if (fIsConstructed) { 398 // update this local field objects if alre 399 auto fieldSetup = GetFieldSetup(lv); 400 if (fieldSetup == nullptr) { 401 G4Exception( 402 "G4FieldBuilder::SetLocalField:", "Geo 403 JustWarning, "Cannot get field setup f 404 return; 405 } 406 fieldSetup->SetG4Field(field); 407 fieldSetup->Update(); 408 } 409 } 410 411 //____________________________________________ 412 void G4FieldBuilder::SetUserEquationOfMotion( 413 G4EquationOfMotion* equation, G4String volum 414 { 415 // Set user equation of motion 416 417 if (!volumeName.size()) { 418 // global field 419 fFieldParameters[0]->SetUserEquationOfMoti 420 } 421 else { 422 // local field 423 // Get or create user field parameters 424 G4FieldParameters* fieldParameters = 425 GetOrCreateFieldParameters(volumeName); 426 fieldParameters->SetUserEquationOfMotion(e 427 } 428 } 429 430 //____________________________________________ 431 void G4FieldBuilder::SetUserStepper( 432 G4MagIntegratorStepper* stepper, G4String vo 433 { 434 // Set user stepper 435 436 if (!volumeName.size()) { 437 // global field 438 fFieldParameters[0]->SetUserStepper(steppe 439 } 440 else { 441 // local field 442 // Get or create user field parameters 443 G4FieldParameters* fieldParameters = 444 GetOrCreateFieldParameters(volumeName); 445 fieldParameters->SetUserStepper(stepper); 446 } 447 } 448 449 //____________________________________________ 450 G4FieldParameters* G4FieldBuilder::GetFieldPar 451 const G4String& volumeName) const 452 { 453 // Get field parameters with the given volum 454 // Return global field parameters, if volume 455 456 // Get user field parameters 457 for (auto fieldParameters : fFieldParameters 458 if (fieldParameters->GetVolumeName() == vo 459 // G4cout << "Found field parameters for 460 return fieldParameters; 461 } 462 } 463 464 G4Exception( 465 "G4FieldBuilder::GetFieldParameters:", "Ge 466 JustWarning, "Field parameters not found." 467 return nullptr; 468 } 469