Skip to content

Commit aeacf6c

Browse files
Merge branch 'main' into dev_#479
2 parents 9f19ff2 + 869da67 commit aeacf6c

File tree

24 files changed

+611
-43
lines changed

24 files changed

+611
-43
lines changed

Code/Source/solver/ComMod.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,8 +317,15 @@ class fibStrsType
317317
// Constant steady value
318318
double g = 0.0;
319319

320-
// Cross fiber stress parameter
320+
// Directional stress distribution parameters
321+
// Fraction of active stress in fiber direction (default: 1.0)
322+
double eta_f = 1.0;
323+
324+
// Fraction of active stress in sheet direction (default: 0.0)
321325
double eta_s = 0.0;
326+
327+
// Fraction of active stress in sheet-normal direction (default: 0.0)
328+
double eta_n = 0.0;
322329

323330
// Unsteady time-dependent values
324331
fcType gt;

Code/Source/solver/Parameters.cpp

Lines changed: 127 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1758,6 +1758,108 @@ void DomainParameters::set_values(tinyxml2::XMLElement* domain_elem, bool from_e
17581758
*/
17591759
}
17601760

1761+
//////////////////////////////////////////////////////////
1762+
// DirectionalDistributionParameters //
1763+
//////////////////////////////////////////////////////////
1764+
1765+
/// @brief Define the XML element name for directional distribution parameters.
1766+
const std::string DirectionalDistributionParameters::xml_element_name_ = "Directional_distribution";
1767+
1768+
DirectionalDistributionParameters::DirectionalDistributionParameters()
1769+
{
1770+
bool required = false;
1771+
1772+
// Default: all stress in fiber direction
1773+
set_parameter("Fiber_direction", 1.0, required, fiber_direction);
1774+
set_parameter("Sheet_direction", 0.0, required, sheet_direction);
1775+
set_parameter("Sheet_normal_direction", 0.0, required, sheet_normal_direction);
1776+
}
1777+
1778+
void DirectionalDistributionParameters::set_values(tinyxml2::XMLElement* xml_elem)
1779+
{
1780+
using namespace tinyxml2;
1781+
std::string error_msg = "Unknown " + xml_element_name_ + " XML element '";
1782+
1783+
using std::placeholders::_1;
1784+
using std::placeholders::_2;
1785+
1786+
std::function<void(const std::string&, const std::string&)> ftpr =
1787+
std::bind(&DirectionalDistributionParameters::set_parameter_value, *this, _1, _2);
1788+
1789+
xml_util_set_parameters(ftpr, xml_elem, error_msg);
1790+
1791+
value_set = true;
1792+
}
1793+
1794+
void DirectionalDistributionParameters::validate() const
1795+
{
1796+
if (!value_set) {
1797+
return; // No validation needed if not set (will use defaults)
1798+
}
1799+
1800+
// Check how many parameters are defined
1801+
bool fiber_defined = fiber_direction.defined();
1802+
bool sheet_defined = sheet_direction.defined();
1803+
bool normal_defined = sheet_normal_direction.defined();
1804+
1805+
int num_defined = fiber_defined + sheet_defined + normal_defined;
1806+
1807+
// Empty block is invalid - if block exists, must specify all three
1808+
if (num_defined == 0) {
1809+
throw std::runtime_error("Directional_distribution block is empty. "
1810+
"Either remove the block entirely (to use defaults: fiber=1.0, sheet=0.0, normal=0.0) "
1811+
"or specify all three directions: Fiber_direction, Sheet_direction, Sheet_normal_direction.");
1812+
}
1813+
1814+
// Partial specification is invalid
1815+
if (num_defined < 3) {
1816+
std::string msg = "Directional_distribution requires all three directions to be specified. Found: ";
1817+
if (fiber_defined) msg += "Fiber_direction ";
1818+
if (sheet_defined) msg += "Sheet_direction ";
1819+
if (normal_defined) msg += "Sheet_normal_direction ";
1820+
msg += "\nMissing: ";
1821+
if (!fiber_defined) msg += "Fiber_direction ";
1822+
if (!sheet_defined) msg += "Sheet_direction ";
1823+
if (!normal_defined) msg += "Sheet_normal_direction ";
1824+
throw std::runtime_error(msg);
1825+
}
1826+
1827+
// All three are specified, validate their values
1828+
double eta_f = fiber_direction.value();
1829+
double eta_s = sheet_direction.value();
1830+
double eta_n = sheet_normal_direction.value();
1831+
1832+
// Validate that eta_f + eta_s + eta_n = 1.0
1833+
double eta_sum = eta_f + eta_s + eta_n;
1834+
const double tol = 1.0e-10;
1835+
if (std::abs(eta_sum - 1.0) > tol) {
1836+
throw std::runtime_error("Directional distribution fractions must sum to 1.0. "
1837+
"Got: Fiber_direction=" + std::to_string(eta_f) +
1838+
", Sheet_direction=" + std::to_string(eta_s) +
1839+
", Sheet_normal_direction=" + std::to_string(eta_n) +
1840+
", sum=" + std::to_string(eta_sum));
1841+
}
1842+
1843+
// Validate that each eta is non-negative
1844+
if (eta_f < 0.0 || eta_s < 0.0 || eta_n < 0.0) {
1845+
throw std::runtime_error("Directional distribution fractions must be non-negative. "
1846+
"Got: Fiber_direction=" + std::to_string(eta_f) +
1847+
", Sheet_direction=" + std::to_string(eta_s) +
1848+
", Sheet_normal_direction=" + std::to_string(eta_n));
1849+
}
1850+
}
1851+
1852+
void DirectionalDistributionParameters::print_parameters()
1853+
{
1854+
if (!value_set) {
1855+
return;
1856+
}
1857+
std::cout << " Directional Distribution:" << std::endl;
1858+
std::cout << " Fiber_direction: " << fiber_direction.value() << std::endl;
1859+
std::cout << " Sheet_direction: " << sheet_direction.value() << std::endl;
1860+
std::cout << " Sheet_normal_direction: " << sheet_normal_direction.value() << std::endl;
1861+
}
1862+
17611863
//////////////////////////////////////////////////////////
17621864
// FiberReinforcementStressParameters //
17631865
//////////////////////////////////////////////////////////
@@ -1786,22 +1888,34 @@ void FiberReinforcementStressParameters::set_values(tinyxml2::XMLElement* xml_el
17861888
using namespace tinyxml2;
17871889
std::string error_msg = "Unknown " + xml_element_name_ + " XML element '";
17881890

1789-
// Get the 'type' from the <LS type=TYPE> element.
1891+
// Get the 'type' from the element attribute.
17901892
const char* stype;
17911893
auto result = xml_elem->QueryStringAttribute("type", &stype);
17921894
if (stype == nullptr) {
1793-
throw std::runtime_error("No TYPE given in the XML <Stimulus=TYPE> element.");
1895+
throw std::runtime_error("No TYPE given in the XML <Fiber_reinforcement_stress type=TYPE> element.");
17941896
}
17951897
type.set(std::string(stype));
17961898
auto item = xml_elem->FirstChildElement();
1797-
1798-
using std::placeholders::_1;
1799-
using std::placeholders::_2;
1800-
1801-
std::function<void(const std::string&, const std::string&)> ftpr =
1802-
std::bind( &FiberReinforcementStressParameters::set_parameter_value, *this, _1, _2);
1803-
1804-
xml_util_set_parameters(ftpr, xml_elem, error_msg);
1899+
1900+
while (item != nullptr) {
1901+
std::string name = item->Value();
1902+
1903+
if (name == DirectionalDistributionParameters::xml_element_name_) {
1904+
directional_distribution.set_values(item);
1905+
1906+
} else if (item->GetText() != nullptr) {
1907+
auto value = item->GetText();
1908+
try {
1909+
set_parameter_value(name, value);
1910+
} catch (const std::bad_function_call& exception) {
1911+
throw std::runtime_error(error_msg + name + "'.");
1912+
}
1913+
} else {
1914+
throw std::runtime_error(error_msg + name + "'.");
1915+
}
1916+
1917+
item = item->NextSiblingElement();
1918+
}
18051919

18061920
value_set = true;
18071921
}
@@ -1821,6 +1935,9 @@ void FiberReinforcementStressParameters::print_parameters()
18211935
for (auto& [ key, value ] : params_name_value) {
18221936
std::cout << key << ": " << value << std::endl;
18231937
}
1938+
1939+
// Print directional distribution if defined
1940+
directional_distribution.print_parameters();
18241941
}
18251942

18261943
//////////////////////////////////////////////////////////

Code/Source/solver/Parameters.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,6 +1113,35 @@ class ECGLeadsParameters : public ParameterLists
11131113
bool value_set = false;
11141114
};
11151115

1116+
/// @brief The DirectionalDistributionParameters class stores directional
1117+
/// distribution parameters for active stress.
1118+
///
1119+
/// \code {.xml}
1120+
/// <Directional_distribution>
1121+
/// <Fiber_direction> 1.0 </Fiber_direction>
1122+
/// <Sheet_direction> 0.0 </Sheet_direction>
1123+
/// <Sheet_normal_direction> 0.0 </Sheet_normal_direction>
1124+
/// </Directional_distribution>
1125+
/// \endcode
1126+
class DirectionalDistributionParameters : public ParameterLists
1127+
{
1128+
public:
1129+
DirectionalDistributionParameters();
1130+
1131+
static const std::string xml_element_name_;
1132+
1133+
bool defined() const { return value_set; };
1134+
void print_parameters();
1135+
void set_values(tinyxml2::XMLElement* xml_elem);
1136+
void validate() const; // Validate directional fractions
1137+
1138+
Parameter<double> fiber_direction;
1139+
Parameter<double> sheet_direction;
1140+
Parameter<double> sheet_normal_direction;
1141+
1142+
bool value_set = false;
1143+
};
1144+
11161145
/// @brief The FiberReinforcementStressParameters class stores fiber
11171146
/// reinforcement stress parameters for the 'Fiber_reinforcement_stress`
11181147
/// XML element.
@@ -1121,6 +1150,11 @@ class ECGLeadsParameters : public ParameterLists
11211150
/// <Fiber_reinforcement_stress type="Unsteady" >
11221151
/// <Temporal_values_file_path> fib_stress.dat </Temporal_values_file_path>
11231152
/// <Ramp_function> true </Ramp_function>
1153+
/// <Directional_distribution>
1154+
/// <Fiber_direction> 0.7 </Fiber_direction>
1155+
/// <Sheet_direction> 0.2 </Sheet_direction>
1156+
/// <Sheet_normal_direction> 0.1 </Sheet_normal_direction>
1157+
/// </Directional_distribution>
11241158
/// </Fiber_reinforcement_stress>
11251159
/// \endcode
11261160
class FiberReinforcementStressParameters : public ParameterLists
@@ -1140,6 +1174,9 @@ class FiberReinforcementStressParameters : public ParameterLists
11401174
Parameter<std::string> temporal_values_file_path;
11411175
Parameter<double> value;
11421176

1177+
// Directional stress distribution parameters
1178+
DirectionalDistributionParameters directional_distribution;
1179+
11431180
bool value_set = false;
11441181
};
11451182

Code/Source/solver/distribute.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1732,7 +1732,11 @@ void dist_mat_consts(const ComMod& com_mod, const CmMod& cm_mod, const cmType& c
17321732
cm.bcast(cm_mod, lStM.Tf.gt.r, "lStM.Tf.gt.r");
17331733
cm.bcast(cm_mod, lStM.Tf.gt.i, "lStM.Tf.gt.i");
17341734
}
1735+
1736+
// Broadcast directional stress distribution parameters
1737+
cm.bcast(cm_mod, &lStM.Tf.eta_f);
17351738
cm.bcast(cm_mod, &lStM.Tf.eta_s);
1739+
cm.bcast(cm_mod, &lStM.Tf.eta_n);
17361740

17371741
// Distribute CANN parameter table
17381742
if (lStM.isoType == ConstitutiveModelType::stArtificialNeuralNet) {

0 commit comments

Comments
 (0)