12 #include <libmesh/dense_matrix.h> 16 "LAROMANCEPartitionStressUpdate");
19 "ADLAROMANCEPartitionStressUpdate");
28 "finite_difference_width",
30 "finite_difference_width > 0",
31 "Factor multiplied against the input stress to compute the finite " 32 "difference derivative of the parition weights.");
41 _finite_difference_width(this->template getParam<
Real>(
"finite_difference_width"))
50 _partition_Mmean = getClassificationMmean();
51 _partition_Mscale = getClassificationMscale();
52 _partition_Xu = getClassificationXu();
53 _partition_Ell = getClassificationEll();
54 _partition_Eta = getClassificationEta();
55 _partition_Luu = getClassificationLuu();
56 _partition_Vind = getClassificationVind();
57 _partition_difference.resize(_partition_Xu[0].size(),
59 _partition_distance.resize(_partition_difference.size());
60 _partition_covariance.resize(_partition_distance.size());
61 _partition_b.resize(_partition_covariance.size());
62 _partition_A.resize(_partition_Luu[0].size(), _partition_Luu.size());
71 this->_json[
"m_mean"] = getClassificationMmean();
72 this->_json[
"m_scale"] = getClassificationMscale();
73 this->_json[
"xu"] = getClassificationXu();
74 this->_json[
"ell"] = getClassificationEll();
75 this->_json[
"eta"] = getClassificationEta();
76 this->_json[
"luu"] = getClassificationLuu();
77 this->_json[
"vind"] = getClassificationVind().get_values();
85 std::vector<bool> in_partition(_num_partitions,
false);
86 unsigned int num_partitions_active = 0;
87 for (
unsigned int p = 0; p < _num_partitions; ++p)
89 for (
unsigned int t = 0; t < this->_num_tiles[p]; ++t)
90 if (!in_partition[p] && this->checkInTile(p, t))
91 in_partition[p] =
true;
93 num_partitions_active += in_partition[p];
95 mooseAssert(num_partitions_active <= _num_partitions,
96 "Number of paritions active must be less than total number of paritions");
97 if (!num_partitions_active)
98 mooseException(
"Number of active partitions (",
99 num_partitions_active,
100 ") out of total number of partitions (",
102 ") is zero. This may be because you are trying to sample outside the total " 103 "applicability of the model");
105 if (_num_partitions == 1)
108 dweights_dstress[0] = 0.0;
110 else if (_num_partitions == 2)
112 if (num_partitions_active == 1)
114 std::fill(dweights_dstress.begin(), dweights_dstress.end(), 0.0);
118 else if (in_partition[1])
121 mooseError(
"Internal error: Parition weight calculation incorrect when only one " 122 "partition is applicable");
124 else if (num_partitions_active == 2)
126 weights[1] = computeSecondPartitionWeight();
127 computeDSecondPartitionWeightDStress(dweights_dstress[1]);
128 dweights_dstress[0] = -dweights_dstress[1];
130 weights[0] = 1.0 - weights[1];
133 mooseError(
"Internal error: number of partitions can only be 1 or 2");
135 if (_num_partitions == 2)
136 _second_partition_weight[_qp] = this->_partition_weights[1];
138 _second_partition_weight[_qp] = 0.0;
141 for (
unsigned int p = 0; p < _num_partitions; ++p)
143 weights[p] = (1.0 - sigmoid(0.0, 1.0, weights[p]));
144 dweights_dstress[p] *= -sigmoid(0.0, 1.0, weights[p],
true);
148 template <
bool is_ad>
154 std::vector<GenericReal<is_ad>> scaled_input_values(_num_inputs - 1);
155 unsigned int inc = 0;
158 if (i != _old_strain_input_index)
160 scaled_input_values[inc] =
161 (_input_values[i] - _partition_Mmean[inc]) / _partition_Mscale[inc];
171 _partition_difference[
j][i] =
172 Utility::pow<2>((_partition_Xu[i][
j] - scaled_input_values[i]) / _partition_Ell);
175 std::fill(_partition_distance.begin(), _partition_distance.end(), 0.0);
176 for (
const auto i :
index_range(_partition_difference))
178 for (
const auto j :
index_range(_partition_difference[0]))
179 _partition_distance[i] += _partition_difference[i][
j];
180 _partition_distance[i] = std::sqrt(_partition_distance[i]);
185 for (
const auto i :
index_range(_partition_covariance))
186 _partition_covariance[i] =
187 Utility::pow<2>(_partition_Eta) * std::exp(-0.5 * _partition_distance[i]);
190 for (
const auto i :
index_range(_partition_covariance))
191 _partition_b(i) = _partition_covariance[i];
194 for (
const auto i :
index_range(_partition_Luu[0]))
196 _partition_A(i,
j) = _partition_Luu[
j][i];
199 DenseVector<GenericReal<is_ad>> ma(_partition_b.size());
200 _partition_A.lu_solve(_partition_b, ma);
205 partition_weight += ma(i) * _partition_Vind(i);
208 partition_weight = -partition_weight + 1.0;
209 partition_weight = std::min(partition_weight, 1.0);
210 partition_weight = std::max(partition_weight, 0.0);
211 return partition_weight;
214 template <
bool is_ad>
220 _input_values[_stress_input_index] * _finite_difference_width;
221 _input_values[_stress_input_index] += fd_tol;
222 dsecond_partition_weight_dstress =
223 (computeSecondPartitionWeight() - _second_partition_weight[_qp]) / fd_tol;
224 _input_values[_stress_input_index] -= fd_tol;
virtual void initialSetup() override
Moose::GenericType< Real, is_ad > GenericReal
static InputParameters validParams()
virtual void computePartitionWeights(std::vector< GenericReal< is_ad >> &weights, std::vector< GenericReal< is_ad >> &dweights_dstress) override
Compute the weight of the different partitions.
void mooseError(Args &&... args)
virtual GenericReal< is_ad > computeSecondPartitionWeight()
Compute the partition weight on the location in input-space, based on a calibrated Gaussian Process R...
virtual void computeDSecondPartitionWeightDStress(GenericReal< is_ad > &dsecond_partition_weight_dstress)
Compute the derivative of the partition weight of the second partition w.r.t.
virtual void initialSetup() override
LAROMANCEPartitionStressUpdateBaseTempl(const InputParameters ¶meters)
virtual void exportJSON() override
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
auto index_range(const T &sizable)
static InputParameters validParams()
virtual void exportJSON()
registerMooseObjectAliased("SolidMechanicsApp", LAROMANCEPartitionStressUpdateBase, "LAROMANCEPartitionStressUpdate")