Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-05 08:19:18

0001 /*******************************************************************************
0002  * Copyright (c) The JETSCAPE Collaboration, 2018
0003  *
0004  * Modular, task-based framework for simulating all aspects of heavy-ion collisions
0005  * 
0006  * For the list of contributors see AUTHORS.
0007  *
0008  * Report issues at https://github.com/JETSCAPE/JETSCAPE/issues
0009  *
0010  * or via email to bugs.jetscape@gmail.com
0011  *
0012  * Distributed under the GNU General Public License 3.0 (GPLv3 or later).
0013  * See COPYING for details.
0014  ******************************************************************************/
0015 
0016 #include "JetEnergyLossManager.h"
0017 #include "JetScapeLogger.h"
0018 #include "JetScapeSignalManager.h"
0019 #include "MakeUniqueHelper.h"
0020 #include <string>
0021 
0022 #include <iostream>
0023 #include <vector>
0024 #include <thread>
0025 
0026 using namespace std;
0027 
0028 namespace Jetscape {
0029 
0030 JetEnergyLossManager::JetEnergyLossManager() {
0031   SetId("JLossManager");
0032   GetHardPartonListConnected = false;
0033   VERBOSE(8);
0034 }
0035 
0036 JetEnergyLossManager::~JetEnergyLossManager() {
0037   // Check if this is all really needed with shared_ptr ...
0038   JSDEBUG;
0039   Clear();
0040 
0041   if (GetNumberOfTasks() > 0)
0042     EraseTaskLast();
0043 }
0044 
0045 void JetEnergyLossManager::Clear() {
0046   JSDEBUG << "Hard Parton List ...";
0047 
0048   hp.clear();
0049 
0050   int n = GetNumberOfTasks();
0051   for (int i = 1; i < n; i++)
0052     EraseTaskLast();
0053 
0054   // Clean Up not really working with iterators (see also above!!!) Some logic not clear for me.
0055   JetScapeSignalManager::Instance()->CleanUp();
0056   JetScapeTask::ClearTasks();
0057 
0058   VERBOSE(8) << hp.size();
0059 }
0060 
0061 void JetEnergyLossManager::Init() {
0062   JSINFO << "Initialize JetEnergyLoss Manager ...";
0063 
0064   if (GetNumberOfTasks() < 1) {
0065     JSWARN << " : No valid Energy Loss Manager modules found ...";
0066     exit(-1);
0067   }
0068 
0069   JSINFO << "Found " << GetNumberOfTasks()
0070          << " Eloss Manager Tasks/Modules Initialize them ... ";
0071   JetScapeTask::InitTasks();
0072 
0073   JSINFO << "Connect JetEnergyLossManager Signal to Hard Process ...";
0074   JetScapeSignalManager::Instance()->ConnectGetHardPartonListSignal(
0075       shared_from_this());
0076 
0077   // Set the pointer of JetEnergyLoss for making connections to hadronization module
0078   for (auto it : GetTaskList()) {
0079     if (dynamic_pointer_cast<JetEnergyLoss>(it))
0080 
0081       JetScapeSignalManager::Instance()->SetEnergyLossPointer(
0082           dynamic_pointer_cast<JetEnergyLoss>(it));
0083   }
0084 }
0085 
0086 void JetEnergyLossManager::WriteTask(weak_ptr<JetScapeWriter> w) {
0087   VERBOSE(8);
0088   JetScapeTask::WriteTasks(w);
0089 }
0090 
0091 void JetEnergyLossManager::Exec() {
0092   VERBOSE(1) << "Run JetEnergyLoss Manager ...";
0093   JSDEBUG << "Task Id = " << this_thread::get_id();
0094 
0095   if (GetNumberOfTasks() < 1) {
0096     JSWARN << " : No valid Energy Loss Manager modules found ...";
0097     exit(-1);
0098   }
0099 
0100   // ----------------------------------
0101   // Create needed copies and connect signal/slots accordingly ...
0102 
0103   if (GetGetHardPartonListConnected()) {
0104     GetHardPartonList(hp);
0105     VERBOSE(3) << " Number of Hard Partons = " << hp.size();
0106     for (int i = 1; i < hp.size(); i++) {
0107       JSDEBUG << "Create the " << i
0108               << " th copy because number of intital hard partons = "
0109               << hp.size();
0110       // Add(make_shared<JetEnergyLoss>(*dynamic_pointer_cast<JetEnergyLoss>(GetTaskAt(0))));
0111       auto jloss_org = dynamic_pointer_cast<JetEnergyLoss>(GetTaskAt(0));
0112       auto jloss_copy = make_shared<JetEnergyLoss>(*jloss_org);
0113 
0114       // if there is a liquefier attached to the jloss module
0115       // also attach the liquefier to the copied jloss modules
0116       // to collect hydrodynamic source terms
0117       if (!weak_ptr_is_uninitialized(jloss_org->get_liquefier())) {
0118         jloss_copy->add_a_liquefier(jloss_org->get_liquefier().lock());
0119       }
0120       Add(jloss_copy);
0121     }
0122   }
0123 
0124   VERBOSE(3) << " Found " << GetNumberOfTasks()
0125              << " Eloss Manager Tasks/Modules Execute them ... ";
0126   JSDEBUG << "Check and Create Signal/Slots via JetScapeSignalManager instance "
0127              "if needed ...";
0128 
0129   CreateSignalSlots();
0130 
0131   // ----------------------------------
0132   // Copy Shower initiating partons to JetEnergyLoss tasks ...
0133 
0134   if (GetGetHardPartonListConnected() && hp.size() > 0) {
0135     int n = 0;
0136     for (auto it : GetTaskList()) {
0137       dynamic_pointer_cast<JetEnergyLoss>(it)->AddShowerInitiatingParton(
0138           hp.at(n));
0139       n++;
0140     }
0141   }
0142 
0143   // ----------------------------------
0144   // quick and dirty here, only include after further testing (flag in init xml files ...)
0145   bool multiTask = false;
0146 
0147   // ----------------------------------
0148   //Excute JetEnergyLoss tasks and their subtasks (done via signal/slot) by hand ...
0149   //needed if only JetEnergyloss tasks in parallel (otherwise could be done via JetScapeTask, then every task a new thread for example)
0150   // Of course now the number of threads if plainly given by the number of initial hard partons and can exceed the allowed # of threads >1000
0151   // so to really do this properly one has to think about and limit to number of CPU's * N threads or something in that directions. See a quick attempt below.
0152 
0153   //DEBUG:
0154   //unsigned num_cpus = thread::hardware_concurrency();
0155   //cout << "Num of CPU's = " << num_cpus << " threads\n";
0156 
0157   if (multiTask) {
0158     int nTasks = GetNumberOfTasks();
0159     int nCPUs = thread::hardware_concurrency();
0160 
0161     vector<thread> threads;
0162 
0163     int nMaxThreads = nCPUs * 2;
0164     int n = 0;
0165 
0166     VERBOSE(3) << " Use multi-threading: (max) # of threads = # of CPU's "
0167                << nCPUs << " (found) * 2";
0168 
0169     for (auto it : GetTaskList()) {
0170       if (it->GetActive()) {
0171         threads.push_back(thread(&JetEnergyLoss::Exec,
0172                                  dynamic_pointer_cast<JetEnergyLoss>(it)));
0173         n++;
0174       }
0175       if (n == nMaxThreads) {
0176         //DEBUGTHREAD<<n;
0177         for (auto &th : threads)
0178           th.join();
0179         n = 0;
0180         threads.clear();
0181 
0182         //DEBUG:
0183         //std::this_thread::sleep_for(std::chrono::milliseconds(5000));
0184       }
0185     }
0186 
0187     if (nTasks < nMaxThreads) {
0188       for (auto &th : threads)
0189         th.join();
0190       threads.clear();
0191     }
0192   }
0193   // ----------------------------------
0194   else
0195     // Standard "serial" execution for the JetEnerguLoss (+submodules) task ...
0196     JetScapeTask::ExecuteTasks();
0197 
0198   //Add acheck if the parton shower was actually created for the Modules ....
0199   VERBOSE(3) << " " << GetNumberOfTasks()
0200              << " Eloss Manager Tasks/Modules finished.";
0201 }
0202 
0203 void JetEnergyLossManager::CreateSignalSlots() {
0204   for (auto it : GetTaskList()) {
0205     for (auto it2 : it->GetTaskList()) {
0206       if (!dynamic_pointer_cast<JetEnergyLoss>(it2)->GetJetSignalConnected()) {
0207         JetScapeSignalManager::Instance()->ConnectJetSignal(
0208             dynamic_pointer_cast<JetEnergyLoss>(it2));
0209       }
0210       if (!dynamic_pointer_cast<JetEnergyLoss>(it2)
0211                ->GetEdensitySignalConnected()) {
0212         JetScapeSignalManager::Instance()->ConnectEdensitySignal(
0213             dynamic_pointer_cast<JetEnergyLoss>(it2));
0214       }
0215       if (!dynamic_pointer_cast<JetEnergyLoss>(it2)
0216                ->GetGetHydroCellSignalConnected()) {
0217         JetScapeSignalManager::Instance()->ConnectGetHydroCellSignal(
0218             dynamic_pointer_cast<JetEnergyLoss>(it2));
0219       }
0220       if (!dynamic_pointer_cast<JetEnergyLoss>(it2)
0221                ->GetGetHydroTau0SignalConnected()) {
0222         JetScapeSignalManager::Instance()->ConnectGetHydroTau0Signal(
0223             dynamic_pointer_cast<JetEnergyLoss>(it2));
0224       }
0225 
0226       // between eloss modules and eloss
0227       // check the signals itself, probably best via manager in the long run ...
0228       if (!dynamic_pointer_cast<JetEnergyLoss>(it2)
0229                ->GetSentInPartonsConnected()) {
0230         JetScapeSignalManager::Instance()->ConnectSentInPartonsSignal(
0231             dynamic_pointer_cast<JetEnergyLoss>(it),
0232             dynamic_pointer_cast<JetEnergyLoss>(it2));
0233       }
0234     }
0235     auto liq_pt = dynamic_pointer_cast<JetEnergyLoss>(it)->get_liquefier();
0236     if (!weak_ptr_is_uninitialized(liq_pt) &&
0237         !liq_pt.lock()->get_GetHydroCellSignalConnected()) {
0238       JetScapeSignalManager::Instance()->ConnectGetHydroCellSignal(
0239           liq_pt.lock());
0240     }
0241   }
0242 
0243   JetScapeSignalManager::Instance()->PrintGetHydroCellSignalMap();
0244   VERBOSE(8);
0245   JetScapeSignalManager::Instance()->PrintSentInPartonsSignalMap();
0246 }
0247 
0248 } // end namespace Jetscape