Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/build_windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
# Verify MUSEN builds with different CUDA versions
compile-check:
name: compile-check (CUDA ${{ matrix.cuda }})
runs-on: windows-latest
runs-on: windows-2025
strategy:
fail-fast: false
matrix:
Expand Down Expand Up @@ -99,7 +99,7 @@ jobs:

# Build Debug, Release, Installer, ModelsCreator
full-test:
runs-on: windows-latest
runs-on: windows-2025

steps:
- name: Checkout
Expand Down Expand Up @@ -228,7 +228,7 @@ jobs:

# Full build with CUDA_VERSION_RELEASE and all compute capabilities and publish GitHub Release
release:
runs-on: windows-latest
runs-on: windows-2025
needs: [compile-check, full-test]
if: startsWith(github.ref, 'refs/tags/v')

Expand Down
13 changes: 11 additions & 2 deletions Databases/AgglomerateDatabase/AgglomeratesDatabase.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* Copyright (c) 2013-2020, MUSEN Development Team. All rights reserved.
This file is part of MUSEN framework http://msolids.net/musen.
/* Copyright (c) 2013-2020, MUSEN Development Team.
Copyright (c) 2026, DyssolTEC GmbH.
All rights reserved. This file is part of MUSEN framework https://github.com/msolids/musen.
See LICENSE file for license and warranty information. */

#include "AgglomeratesDatabase.h"
Expand Down Expand Up @@ -44,6 +45,14 @@ SAgglomerate* CAgglomeratesDatabase::GetAgglomerate(const std::string& _sKey)
return NULL;
}

const SAgglomerate* CAgglomeratesDatabase::GetAgglomerateByName(const std::string& _name) const
{
for (const auto* a : m_vAgglomerates)
if (a->sName == _name)
return a;
return nullptr;
}

double CAgglomeratesDatabase::CalculateVolume(SAgglomerate* _pAgglom)
{
double dVolume = 0;
Expand Down
6 changes: 4 additions & 2 deletions Databases/AgglomerateDatabase/AgglomeratesDatabase.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* Copyright (c) 2013-2020, MUSEN Development Team. All rights reserved.
This file is part of MUSEN framework http://msolids.net/musen.
/* Copyright (c) 2013-2020, MUSEN Development Team.
Copyright (c) 2026, DyssolTEC GmbH.
All rights reserved. This file is part of MUSEN framework https://github.com/msolids/musen.
See LICENSE file for license and warranty information. */

#pragma once
Expand Down Expand Up @@ -63,6 +64,7 @@ class CAgglomeratesDatabase

SAgglomerate* GetAgglomerate(size_t _nIndex);
SAgglomerate* GetAgglomerate(const std::string& _sKey);
const SAgglomerate* GetAgglomerateByName(const std::string& _name) const;
int GetAgglomerateIndex(const std::string& _sKey);

std::string GetFileName() { return m_sDatabaseFileName; }
Expand Down
Binary file modified Installers/Data/Databases/Agglomerates.madb
Binary file not shown.
6 changes: 4 additions & 2 deletions Modules/GeneralSources/MUSENDefinitions.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* Copyright (c) 2013-2020, MUSEN Development Team. All rights reserved.
This file is part of MUSEN framework http://msolids.net/musen.
/* Copyright (c) 2013-2020, MUSEN Development Team.
Copyright (c) 2026, DyssolTEC GmbH.
All rights reserved. This file is part of MUSEN framework https://github.com/msolids/musen.
See LICENSE file for license and warranty information. */

#pragma once
Expand Down Expand Up @@ -70,6 +71,7 @@ enum class ETXTCommands : unsigned
OBJECT_TOT_TORQUE = 43,
OBJECT_PLANE_COORD = 44,
OBJECT_TANG_OVERLAP = 45,
DYNAMIC_GENERATOR = 46,
};

// ********* physical constants
Expand Down
11 changes: 8 additions & 3 deletions Modules/ObjectsGenerator/GenerationManager.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
/* Copyright (c) 2013-2020, MUSEN Development Team.
Copyright (c) 2026, DyssolTEC GmbH.
All rights reserved. This file is part of MUSEN framework https://github.com/msolids/musen.
See LICENSE file for license and warranty information. */

#include "GenerationManager.h"

CGenerationManager::CGenerationManager() : CMusenComponent()
Expand Down Expand Up @@ -37,10 +42,11 @@ std::vector<const CObjectsGenerator*> CGenerationManager::GetGenerators() const
return res;
}

void CGenerationManager::CreateNewGenerator()
CObjectsGenerator* CGenerationManager::AddGenerator()
{
m_vGenerators.push_back(new CObjectsGenerator(m_pAgglomDB, &m_pSystemStructure->m_MaterialDatabase));
m_vGenerators.back()->m_sName = "ObjectsGenerator " + std::to_string(m_vGenerators.size());
return m_vGenerators.back();
}

void CGenerationManager::DeleteGenerator( size_t _nIndex )
Expand All @@ -57,8 +63,7 @@ void CGenerationManager::LoadConfiguration()
for (int i = 0; i < protoMessage.objects_generator().generators_size(); ++i)
{
const ProtoObjectsGenerator& protoGen = protoMessage.objects_generator().generators(i);
CreateNewGenerator();
CObjectsGenerator* gen = m_vGenerators.back();
CObjectsGenerator* gen = AddGenerator();
const int version = protoGen.version();
gen->m_sName = protoGen.name();
gen->m_sVolumeKey = protoGen.volume_key();
Expand Down
11 changes: 8 additions & 3 deletions Modules/ObjectsGenerator/GenerationManager.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* Copyright (c) 2013-2020, MUSEN Development Team. All rights reserved.
This file is part of MUSEN framework http://msolids.net/musen.
/* Copyright (c) 2013-2020, MUSEN Development Team.
Copyright (c) 2026, DyssolTEC GmbH.
All rights reserved. This file is part of MUSEN framework https://github.com/msolids/musen.
See LICENSE file for license and warranty information. */

#pragma once
Expand Down Expand Up @@ -27,7 +28,11 @@ class CGenerationManager : public CMusenComponent
// Returns const pointers to all defined generators
std::vector<const CObjectsGenerator*> GetGenerators() const;

void CreateNewGenerator();
/**
* \brief Adds a new empty generator with default name.
* \details The generator will be added to the end of the list and will be active by default.
* \return Pointer to the newly added generator. */
CObjectsGenerator* AddGenerator();
void DeleteGenerator( size_t _nIndex );

void Initialize();
Expand Down
53 changes: 51 additions & 2 deletions Modules/ObjectsGenerator/ObjectsGenerator.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
/* Copyright (c) 2013-2020, MUSEN Development Team. All rights reserved.
This file is part of MUSEN framework http://msolids.net/musen.
/* Copyright (c) 2013-2020, MUSEN Development Team.
Copyright (c) 2026, DyssolTEC GmbH.
All rights reserved. This file is part of MUSEN framework https://github.com/msolids/musen.
See LICENSE file for license and warranty information. */

#include "ObjectsGenerator.h"
#include "Quaternion.h"
#include "MUSENStringFunctions.h"

CObjectsGenerator::CObjectsGenerator(CAgglomeratesDatabase* _pAgglomD, CMaterialsDatabase* _pMaterialsDB) :
m_pAgglomDB( _pAgglomD ), m_pMaterialsDB( _pMaterialsDB )
Expand Down Expand Up @@ -301,6 +303,53 @@ bool CObjectsGenerator::IsGeneratingBonds() const
return false;
}

std::ostream& operator<<(std::ostream& _s, const CObjectsGenerator& _g)
{
const auto WriteMap = [&_s](const std::map<std::string, std::string>& _map)
{
_s << " " << _map.size();
for (const auto& [k, v] : _map)
_s << " " << MakeSingleString(k) << " " << MakeSingleString(v);
};

_s << MakeSingleString(_g.m_sName) << " " << _g.m_bActive << " "
<< MakeSingleString(_g.m_sVolumeKey) << " " << _g.m_maxIterations << " " << _g.m_bInsideGeometries << " "
<< _g.m_bGenerateMixture << " " << MakeSingleString(_g.m_sMixtureKey) << " " << MakeSingleString(_g.m_sAgglomerateKey) << " " << _g.m_dAgglomerateScaleFactor;
WriteMap(_g.m_partMaterials);
WriteMap(_g.m_bondMaterials);
_s << " " << _g.m_bRandomVelocity << " " << _g.m_vObjInitVel << " " << _g.m_dVelMagnitude << " "
<< _g.m_dStartGenerationTime << " " << _g.m_dUpdateStep << " " << _g.m_dEndGenerationTime << " "
<< static_cast<int>(_g.m_rateType) << " " << _g.m_rateValue;
return _s;
}

std::istream& operator>>(std::istream& _s, CObjectsGenerator& _g)
{
const auto ReadMap = [&_s](std::map<std::string, std::string>& _map)
{
_map.clear();
size_t n = 0;
_s >> n;
for (size_t i = 0; i < n; ++i)
{
std::string k, v;
_s >> k >> v;
_map[k] = v;
}
};
_s >> _g.m_sName >> _g.m_bActive
>> _g.m_sVolumeKey >> _g.m_maxIterations >> _g.m_bInsideGeometries
>> _g.m_bGenerateMixture >> _g.m_sMixtureKey >> _g.m_sAgglomerateKey >> _g.m_dAgglomerateScaleFactor;
ReadMap(_g.m_partMaterials);
ReadMap(_g.m_bondMaterials);
_s >> _g.m_bRandomVelocity >> _g.m_vObjInitVel >> _g.m_dVelMagnitude
>> _g.m_dStartGenerationTime >> _g.m_dUpdateStep >> _g.m_dEndGenerationTime;
int rateType = 0;
_s >> rateType >> _g.m_rateValue;
_g.m_rateType = static_cast<CObjectsGenerator::ERateType>(rateType);
return _s;
}

void CObjectsGenerator::GenerateNewObject(std::vector<CVector3>* _pCoordPart, std::vector<CQuaternion>* _pQuatPart, std::vector<double>* _pPartRad, std::vector<double>* _pPartContRad,
std::vector<std::string>* _sMaterialsKey, const SVolumeType& _boundBox, SPBC& _PBC, const double _dCurrentTime)
{
Expand Down
20 changes: 18 additions & 2 deletions Modules/ObjectsGenerator/ObjectsGenerator.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* Copyright (c) 2013-2020, MUSEN Development Team. All rights reserved.
This file is part of MUSEN framework http://msolids.net/musen.
/* Copyright (c) 2013-2020, MUSEN Development Team.
Copyright (c) 2026, DyssolTEC GmbH.
All rights reserved. This file is part of MUSEN framework https://github.com/msolids/musen.
See LICENSE file for license and warranty information. */

#pragma once
Expand Down Expand Up @@ -73,6 +74,21 @@ class CObjectsGenerator
// Checks whether the generator will produce bonds.
[[nodiscard]] bool IsGeneratingBonds() const;

/**
* \brief Text-format serialization.
* \details Config only, runtime state is skipped.
* \param _s Output stream.
* \param _g Objects generator to serialize.
* \return Reference to the output stream. */
friend std::ostream& operator<<(std::ostream& _s, const CObjectsGenerator& _g);
/**
* \brief Text-format deserialization.
* \details Config only, runtime state is skipped.
* \param _s Input stream.
* \param _g Objects generator to deserialize into.
* \return Reference to the input stream. */
friend std::istream& operator>>(std::istream& _s, CObjectsGenerator& _g);

private:
// return true if creation was successfully
void GenerateNewObject( std::vector<CVector3>* _pCoordPart, std::vector<CQuaternion>* _pQuatPart,
Expand Down
102 changes: 99 additions & 3 deletions Modules/ScriptInterface/ConsoleSimulator.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* Copyright (c) 2013-2023, MUSEN Development Team. All rights reserved.
This file is part of MUSEN framework http://msolids.net/musen.
/* Copyright (c) 2013-2023, MUSEN Development Team.
Copyright (c) 2026, DyssolTEC GmbH.
All rights reserved. This file is part of MUSEN framework https://github.com/msolids/musen.
See LICENSE file for license and warranty information. */

#include "ConsoleSimulator.h"
Expand Down Expand Up @@ -81,6 +82,12 @@ void CConsoleSimulator::SetupSystemStructure() const
pbc.SetDomain(m_job.pbcDomain.coordBeg, m_job.pbcDomain.coordEnd);
m_systemStructure.SetPBC(pbc);
}
if (!m_job.pbcVelocity.IsInf())
{
SPBC pbc = m_systemStructure.GetPBC();
pbc.vVel = m_job.pbcVelocity;
m_systemStructure.SetPBC(pbc);
}
if (m_job.resetBonds.ToBool()) m_systemStructure.ResetInitBondLength();

const auto GetGeometryPtr = [&](const SJob::SGeometryMotionInterval& _motion) -> CRealGeometry*
Expand Down Expand Up @@ -130,6 +137,93 @@ void CConsoleSimulator::SetupGenerationManager()
m_generationManager.SetSystemStructure(&m_systemStructure);
m_generationManager.LoadConfiguration();
m_agglomeratesDatabase.LoadFromFile(m_job.agglomeratesDBFileName);

const auto ResolveVolumeKey = [this](const std::string& _nameOrKey)
{
if (const auto* v = m_systemStructure.AnalysisVolumeByName(_nameOrKey))
return v->Key();
return _nameOrKey;
};
const auto ResolveCompoundKey = [this](const std::string& _nameOrKey)
{
if (const auto* c = m_systemStructure.m_MaterialDatabase.GetCompoundByName(_nameOrKey))
return c->GetKey();
return _nameOrKey;
};
const auto ResolveMixtureKey = [this](const std::string& _nameOrKey)
{
if (const auto* m = m_systemStructure.m_MaterialDatabase.GetMixtureByName(_nameOrKey))
return m->GetKey();
return _nameOrKey;
};
const auto ResolveAgglomerateKey = [this](const std::string& _nameOrKey)
{
if (const auto* a = m_agglomeratesDatabase.GetAgglomerateByName(_nameOrKey))
return a->sKey;
return _nameOrKey;
};
const auto ParseRateType = [](const std::string& _name)
{
if (_name == "OBJECTS_PER_STEP") return CObjectsGenerator::ERateType::OBJECTS_PER_STEP;
if (_name == "OBJECTS_TOTAL") return CObjectsGenerator::ERateType::OBJECTS_TOTAL;
return CObjectsGenerator::ERateType::GENERATION_RATE;
};

for (const auto& [idx1, dg] : m_job.dynamicGenerators)
{
const size_t index = idx1 - 1;
while (index >= m_generationManager.GetGeneratorsNumber())
m_generationManager.AddGenerator();
CObjectsGenerator* gen = m_generationManager.GetGenerator(index);
if (!dg.volume.empty())
gen->m_sVolumeKey = ResolveVolumeKey(dg.volume);
if (dg.maxIterations != 0)
gen->m_maxIterations = dg.maxIterations;
if (dg.inside.IsDefined())
gen->m_bInsideGeometries = dg.inside.ToBool();
// generation-mode (mixture vs agglomerate) is inferred from which key the user set; when more than one is set, the later wins
if (!dg.mixture.empty())
{
gen->m_sMixtureKey = ResolveMixtureKey(dg.mixture);
gen->m_bGenerateMixture = true;
}
if (!dg.agglomerate.empty())
{
gen->m_sAgglomerateKey = ResolveAgglomerateKey(dg.agglomerate);
gen->m_bGenerateMixture = false;
}
if (std::isfinite(dg.agglomerateScale))
{
gen->m_dAgglomerateScaleFactor = dg.agglomerateScale;
gen->m_bGenerateMixture = false;
}
// material-override maps are merged additively per alias, existing entries for other aliases stay
for (const auto& [alias, nameOrKey] : dg.partMaterials)
gen->m_partMaterials[alias] = ResolveCompoundKey(nameOrKey);
for (const auto& [alias, nameOrKey] : dg.bondMaterials)
gen->m_bondMaterials[alias] = ResolveCompoundKey(nameOrKey);
// velocity mode (fixed vs random) is inferred from which key the user set; when more than one is set, the later wins
if (!dg.velocity.IsInf())
{
gen->m_vObjInitVel = dg.velocity;
gen->m_bRandomVelocity = false;
}
if (std::isfinite(dg.velMagnitude))
{
gen->m_dVelMagnitude = dg.velMagnitude;
gen->m_bRandomVelocity = true;
}
if (std::isfinite(dg.startTime))
gen->m_dStartGenerationTime = dg.startTime;
if (std::isfinite(dg.endTime))
gen->m_dEndGenerationTime = dg.endTime;
if (std::isfinite(dg.updateStep))
gen->m_dUpdateStep = dg.updateStep;
if (!dg.rateTypeName.empty())
gen->m_rateType = ParseRateType(dg.rateTypeName);
if (std::isfinite(dg.rateValue))
gen->m_rateValue = dg.rateValue;
}
}

void CConsoleSimulator::SetupModelManager()
Expand Down Expand Up @@ -324,6 +418,8 @@ void CConsoleSimulator::PrintSimulationInfo()
if (pbc.bX) PrintFormatted(" Periodic boundary domain X [m]", pbc.initDomain.coordBeg.x, "to", pbc.initDomain.coordEnd.x);
if (pbc.bY) PrintFormatted(" Periodic boundary domain Y [m]", pbc.initDomain.coordBeg.y, "to", pbc.initDomain.coordEnd.y);
if (pbc.bZ) PrintFormatted(" Periodic boundary domain Z [m]", pbc.initDomain.coordBeg.z, "to", pbc.initDomain.coordEnd.z);
if (!pbc.vVel.IsZero())
PrintFormatted(" Periodic boundary velocity (X:Y:Z) [m/s]", pbc.vVel.x, ":", pbc.vVel.y, ":", pbc.vVel.z);
}
PrintFormatted("External acceleration (X:Y:Z) [m/s^2]", extAccel.x, ":", extAccel.y, ":", extAccel.z);
PrintFormatted("Simulation domain X [m]", simDomain.coordBeg.x, "to", simDomain.coordEnd.x);
Expand Down Expand Up @@ -396,7 +492,7 @@ template <typename ... Args>
void CConsoleSimulator::PrintFormatted(const std::string& _message, Args... args) const
{
// length of the message
static int length = 38;
static int length = 42;
// justify text
m_out.setf(std::ios::left, std::ios::adjustfield);
// print the message
Expand Down
Loading
Loading