20 std::sort(state_tags.begin(), state_tags.end(),
21 [](
const auto &lhs,
const auto &rhs) {
22 return lhs.name < rhs.name;
38 <<
"Tag name: " << name
39 <<
" is already registered with tag: " << it->second
40 <<
". Overwriting with new tag: " << tag;
44 if (p.second == tag) {
46 "Tag: " + std::to_string(tag) +
47 " is already registered with name: " + p.first);
57 if (p.second > max_tag) {
67 <<
"Tag name: " << name
85 if (p.second == tag) {
98 Data(
const std::string &data_name,
101 Data(
const std::string &data_name,
int num_components,
Tag data_tag = 0)
102 :
name(data_name),
data(num_components, 1),
112 struct DataSequence_mi_tag;
113 struct DataName_mi_tag;
119 boost::multi_index::indexed_by<
121 boost::multi_index::sequenced<
122 boost::multi_index::tag<DataSequence_mi_tag>>,
124 boost::multi_index::hashed_unique<
125 boost::multi_index::tag<DataName_mi_tag>,
126 boost::multi_index::member<Data, std::string, &Data::name>>>>;
129 return boost::multi_index::get<DataName_mi_tag>(
dataCommon);
133 return boost::multi_index::get<DataName_mi_tag>(
dataActive);
137 return boost::multi_index::get<DataName_mi_tag>(
dataDependent);
145 return boost::multi_index::get<DataName_mi_tag>(
dataState);
149 return boost::multi_index::get<DataSequence_mi_tag>(
dataState);
152 std::pair<bool, MatrixPtr>
155 int shift = 0)
override {
157 return {insert_ret.second,
158 boost::shared_ptr<MatrixDouble>(this->shared_from_this(),
159 &insert_ret.first->data)};
162 std::pair<bool, MatrixPtr>
165 int shift = 0)
override {
167 return {insert_ret.second,
168 boost::shared_ptr<MatrixDouble>(this->shared_from_this(),
169 &insert_ret.first->data)};
172 std::pair<bool, MatrixPtr>
175 int shift = 0)
override {
177 return {insert_ret.second,
178 boost::shared_ptr<MatrixDouble>(this->shared_from_this(),
179 &insert_ret.first->data)};
182 std::pair<bool, MatrixPtr>
185 int shift = 0)
override {
188 return {insert_ret.second,
189 boost::shared_ptr<MatrixDouble>(this->shared_from_this(),
190 &insert_ret.first->data)};
195 auto it = data_by_name.find(name);
196 if (it == data_by_name.end()) {
198 "Common data with name " + name +
" not found");
201 return boost::shared_ptr<MatrixDouble>(this->shared_from_this(), &it->data);
206 auto it = data_by_name.find(name);
207 if (it == data_by_name.end()) {
209 "Active data with name " + name +
" not found");
212 return boost::shared_ptr<MatrixDouble>(this->shared_from_this(), &it->data);
217 auto it = data_by_name.find(name);
218 if (it == data_by_name.end()) {
220 "Dependent data with name " + name +
" not found");
223 return boost::shared_ptr<MatrixDouble>(this->shared_from_this(), &it->data);
228 auto it = data_by_name.find(name);
229 if (it == data_by_name.end()) {
231 "Dependent derivatives data with name " + name +
235 return boost::shared_ptr<MatrixDouble>(this->shared_from_this(), &it->data);
241 auto it = state_by_name.find(name);
242 if (it == state_by_name.end()) {
244 "State data with name " + name +
" not found");
249 "MoFEM interface for state data is not set");
254 "State entity is not set");
259 "State gauss point out of range");
264 "State data " + name +
265 " is not initialised; call setupStateData() after binding");
269 double *tag_data =
nullptr;
272 const auto required_size = it->numComponents * (gg + 1);
273 auto rval = moab.tag_get_by_ptr(it->tag, &ent, 1,
274 (
const void **)&tag_data, &tag_size);
275 if (tag_data && tag_size > 0 && tag_size % it->numComponents != 0) {
277 "Inconsistent state tag size for " + name);
280 if (
rval != MB_SUCCESS || !tag_data || tag_size < required_size) {
281 std::vector<double> storage(required_size, 0);
282 if (
rval == MB_SUCCESS && tag_data && tag_size > 0) {
283 std::copy_n(tag_data, std::min(tag_size, required_size), storage.data());
285 void const *storage_ptr[] = {storage.data()};
286 int storage_size = required_size;
289 "Failed to set state data " + name);
291 (
const void **)&tag_data, &tag_size),
292 "Failed to get state data " + name);
294 if (!tag_data || tag_size < required_size ||
295 (tag_size > 0 && tag_size % it->numComponents != 0)) {
297 "Inconsistent state tag size for " + name);
301 auto *ptr = tag_data + gg * it->numComponents;
302 return boost::make_shared<MatrixAdaptor>(
303 it->numComponents, 1,
304 ublas::shallow_array_adaptor<double>(it->numComponents, ptr));
309 const auto &state_by_sequence =
310 boost::multi_index::get<DataSequence_mi_tag>(
dataState);
312 for (
const auto &state_data : state_by_sequence) {
313 if (!state_data.tag || state_data.name.empty() ||
314 state_data.numComponents <= 0)
316 state_tags.push_back(
317 {state_data.name, state_data.tag, state_data.numComponents});
325 const std::string &name,
326 int num_components)
override {
332 "State data name can not be empty");
335 if (num_components <= 0) {
337 "State data %s has non-positive number of components %d",
338 name.c_str(), num_components);
342 auto it = state_by_name.find(name);
343 if (it != state_by_name.end()) {
344 if (it->numComponents != num_components) {
346 "State data %s already exists with incompatible size",
350 state_by_name.insert(
Data{name, num_components});
360 "MoFEM interface for state data is not set");
365 const auto state_tag_name =
"_ADOLC_STATE_" +
366 std::to_string(state_data.numComponents) +
367 "_" + state_data.name;
369 state_tag_name.c_str(), 0, MB_TYPE_DOUBLE, tag,
370 MB_TAG_CREAT | MB_TAG_VARLEN | MB_TAG_SPARSE, PETSC_NULLPTR);
373 [&](
auto &data) { data.tag = tag; });
385 std::vector<double> &dependent_variables)
override {
390 std::vector<double> &dependent_variables_derivatives)
override {
392 dependent_variables_derivatives);
396 const std::vector<double> &active_variables)
override {
401 const std::vector<double> &dependent_variables)
override {
406 const std::vector<double> &dependent_variables_derivatives)
override {
408 dependent_variables_derivatives);
413 std::vector<double> &variables) {
416 auto &data_by_sequence =
417 boost::multi_index::get<DataSequence_mi_tag>(data_container);
419 int nb_variables = 0;
420 for (
const auto &d : data_by_sequence)
421 nb_variables += d.data.data().size();
423 variables.resize(nb_variables);
426 for (
const auto &d : data_by_sequence) {
428 for (
auto it = d.data.data().begin(); it != d.data.data().end();
430 variables[shift] = *it;
437 const std::vector<double> &variables) {
440 auto &data_by_sequence =
441 boost::multi_index::get<DataSequence_mi_tag>(data_container);
443 int nb_variables = 0;
444 for (
const auto &d : data_by_sequence)
445 nb_variables += d.data.data().size();
447 if (variables.size() !=
static_cast<size_t>(nb_variables)) {
449 "Inconsistent size of continuous vector");
453 for (
const auto &d : data_by_sequence) {
455 for (
auto it = d.data.data().begin(); it != d.data.data().end();
457 *it = variables[shift];
474 boost::weak_ptr<MatOpsData> base_data_ptr,
481 std::pair<bool, MatrixPtr>
484 int shift = 0)
override {
485 return baseImplPtr->insertCommonData(name, data, shift);
489 return boost::multi_index::get<DataName_mi_tag>(
dataActive);
493 return boost::multi_index::get<DataName_mi_tag>(
dataDependent);
500 std::pair<bool, MatrixPtr>
503 int shift = 0)
override {
505 if (!insert_ret.second)
507 return {
true, boost::shared_ptr<MatrixDouble>(this->shared_from_this(),
508 &insert_ret.first->data)};
511 std::pair<bool, MatrixPtr>
514 int shift = 0)
override {
516 if (!insert_ret.second)
518 return {
true, boost::shared_ptr<MatrixDouble>(this->shared_from_this(),
519 &insert_ret.first->data)};
522 std::pair<bool, MatrixPtr>
525 int shift = 0)
override {
528 if (!insert_ret.second)
530 return {
true, boost::shared_ptr<MatrixDouble>(this->shared_from_this(),
531 &insert_ret.first->data)};
544 auto it = data_by_name.find(name);
545 if (it == data_by_name.end()) {
547 "Active data with name " + name +
" not found");
550 return boost::shared_ptr<MatrixDouble>(this->shared_from_this(), &it->data);
555 auto it = data_by_name.find(name);
556 if (it == data_by_name.end()) {
558 "Dependent data with name " + name +
" not found");
561 return boost::shared_ptr<MatrixDouble>(this->shared_from_this(), &it->data);
566 auto it = data_by_name.find(name);
567 if (it == data_by_name.end()) {
569 "Dependent derivatives data with name " + name +
573 return boost::shared_ptr<MatrixDouble>(this->shared_from_this(), &it->data);
580 return baseImplPtr->getStateDataPtr(it->second, ent, gg);
581 return baseImplPtr->getStateDataPtr(name, ent, gg);
586 for (
auto &tag_info : state_tags) {
588 if (base_name == tag_info.name) {
589 tag_info.name = alias_name;
599 const std::string &name,
600 int num_components)
override {
603 return baseImplPtr->bindStateTag(m_field, it->second, num_components);
604 return baseImplPtr->bindStateTag(m_field, name, num_components);
617 std::vector<double> &dependent_variables)
override {
622 std::vector<double> &dependent_variables_derivatives)
override {
624 dependent_variables_derivatives);
628 const std::vector<double> &active_variables)
override {
633 const std::vector<double> &dependent_variables)
override {
638 const std::vector<double> &dependent_variables_derivatives)
override {
640 dependent_variables_derivatives);
653 static boost::shared_ptr<MatOpsDataImpl>
655 auto base_data = base_data_ptr.lock();
658 "Base MatOps data pointer expired");
661 auto base_impl_ptr = boost::dynamic_pointer_cast<MatOpsDataImpl>(base_data);
662 if (!base_impl_ptr) {
664 "Base MatOps data pointer has incompatible type");
667 return base_impl_ptr;
672 return boost::make_shared<MatOpsDataImpl>();
675boost::shared_ptr<MatOpsData>
679 return boost::make_shared<MatOpsDataDerivedImpl>(base_data_ptr,
680 common_data_dictionary,
681 state_data_dictionary);
688 CHKERR mat_ops_data_ptr->setActiveContinuousVector(
690 CHKERR mat_ops_data_ptr->setDependentContinuousVector(
692 constexpr int adolc_return_value = 0;
696 if (PetscUnlikely(r < adolc_return_value)) {
698 "ADOL-C function evaluation with error");
700 CHKERR mat_ops_data_ptr->getDependentContinuousVector(
706 boost::shared_ptr<MatOpsData> mat_ops_data_ptr,
int tag,
EntityHandle entity,
709 constexpr int adolc_return_value = 0;
710 CHKERR mat_ops_data_ptr->setActiveContinuousVector(
712 CHKERR mat_ops_data_ptr->setDependentContinuousVector(
715 const auto number_of_active_variables =
717 const auto number_of_dependent_variables =
720 number_of_dependent_variables * number_of_active_variables);
722 for (
unsigned int n = 0;
n != number_of_dependent_variables; ++
n) {
725 [
n * number_of_active_variables]);
731 if (PetscUnlikely(r < adolc_return_value)) {
733 "ADOL-C function evaluation with error");
735 CHKERR mat_ops_data_ptr->getDependentDerivativesContinuousVector(
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_OPERATION_UNSUCCESSFUL
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
#define MOFEM_LOG(channel, severity)
Log.
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
const double n
refractive index of diffusive medium
static void sortStateTags(StateTags &state_tags)
std::map< std::string, std::string > DataDictionary
std::vector< StateTag > StateTags
boost::shared_ptr< MatOpsData > createMatOpsDataPtr()
static MoFEMErrorCodeGeneric< moab::ErrorCode > rval
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
UBlasMatrix< double > MatrixDouble
implementation of Data Operators for Forces and Sources
static MoFEMErrorCode evaluateVariable(boost::shared_ptr< MatOpsData > mat_ops_data_ptr, int tag, EntityHandle entity, int gg)
static std::vector< double > dependentVariablesDerivatives
static std::vector< double > dependentVariables
static MoFEMErrorCode evaluateDerivatives(boost::shared_ptr< MatOpsData > mat_ops_data_ptr, int tag, EntityHandle entity, int gg)
static std::vector< double > activeVariables
static std::vector< double * > jacPtrVec
std::pair< bool, MatrixPtr > insertDependentDerivativesData(const std::string &name, const MatrixDouble &data=MatrixDouble(), int shift=0) override
DataDictionary commonDataDictionary
auto & getDataDependentByName()
MoFEMErrorCode setDependentDerivativesContinuousVector(std::vector< double > &dependent_variables_derivatives) override
std::pair< bool, MatrixPtr > insertCommonData(const std::string &name, const MatrixDouble &data=MatrixDouble(), int shift=0) override
MoFEMErrorCode bindStateTag(MoFEM::Interface &m_field, const std::string &name, int num_components) override
MatOpsDataDerivedImpl(boost::weak_ptr< MatOpsData > base_data_ptr, DataDictionary common_data_dictionary, DataDictionary state_data_dictionary)
StateMatrixPtr getStateDataPtr(const std::string &name, EntityHandle ent, int gg) override
MoFEMErrorCode getDependentDerivativesContinuousVector(const std::vector< double > &dependent_variables_derivatives) override
StateTags getStateTags() const override
DataContainer dataDependentDerivatives
auto & getDataActiveByName()
MoFEMErrorCode getActiveContinuousVector(const std::vector< double > &active_variables) override
MatrixPtr getCommonDataPtr(const std::string &name) override
MatrixPtr getDependentDerivativesDataPtr(const std::string &name) override
MatrixPtr getActiveDataPtr(const std::string &name) override
MoFEMErrorCode getDependentContinuousVector(const std::vector< double > &dependent_variables) override
MoFEMErrorCode setDependentContinuousVector(std::vector< double > &dependent_variables) override
MoFEMErrorCode setActiveContinuousVector(std::vector< double > &active_variables) override
std::pair< bool, MatrixPtr > insertActiveData(const std::string &name, const MatrixDouble &data=MatrixDouble(), int shift=0) override
MatrixPtr getDependentDataPtr(const std::string &name) override
auto & getDataDependentDerivativesByName()
DataDictionary stateDataDictionary
DataContainer dataDependent
std::pair< bool, MatrixPtr > insertDependentData(const std::string &name, const MatrixDouble &data=MatrixDouble(), int shift=0) override
static boost::shared_ptr< MatOpsDataImpl > lockBaseImplPtr(boost::weak_ptr< MatOpsData > base_data_ptr)
boost::shared_ptr< MatOpsDataImpl > baseImplPtr
MoFEMErrorCode setupStateData() override
Data(const std::string &data_name, int num_components, Tag data_tag=0)
Data(const std::string &data_name, const MatrixDouble &data_value=MatrixDouble(), int data_shift=0)
DataContainer dataDependentDerivatives
MoFEMErrorCode getActiveContinuousVector(const std::vector< double > &active_variables) override
MoFEM::Interface * mFieldPtr
StateMatrixPtr getStateDataPtr(const std::string &name, EntityHandle ent, int gg) override
auto & getDataActiveByName()
MoFEMErrorCode setupStateData() override
DataContainer dataDependent
boost::multi_index::multi_index_container< Data, boost::multi_index::indexed_by< boost::multi_index::sequenced< boost::multi_index::tag< DataSequence_mi_tag > >, boost::multi_index::hashed_unique< boost::multi_index::tag< DataName_mi_tag >, boost::multi_index::member< Data, std::string, &Data::name > > > > DataContainer
MatOpsData::StateMatrixPtr StateMatrixPtr
std::pair< bool, MatrixPtr > insertDependentDerivativesData(const std::string &name, const MatrixDouble &data=MatrixDouble(), int shift=0) override
std::pair< bool, MatrixPtr > insertDependentData(const std::string &name, const MatrixDouble &data=MatrixDouble(), int shift=0) override
MoFEMErrorCode setContinuousVector(DataContainer &data_container, std::vector< double > &variables)
auto & getDataDependentByName()
MoFEMErrorCode getDependentContinuousVector(const std::vector< double > &dependent_variables) override
MatrixPtr getCommonDataPtr(const std::string &name) override
MoFEMErrorCode bindStateTag(MoFEM::Interface &m_field, const std::string &name, int num_components) override
MatrixPtr getDependentDataPtr(const std::string &name) override
MatOpsData::MatrixPtr MatrixPtr
MoFEMErrorCode getDependentDerivativesContinuousVector(const std::vector< double > &dependent_variables_derivatives) override
MoFEMErrorCode setDependentDerivativesContinuousVector(std::vector< double > &dependent_variables_derivatives) override
auto & getDataDependentDerivativesByName()
auto & getStateDataByName()
std::pair< bool, MatrixPtr > insertCommonData(const std::string &name, const MatrixDouble &data=MatrixDouble(), int shift=0) override
MatrixPtr getDependentDerivativesDataPtr(const std::string &name) override
StateTags getStateTags() const override
MatrixPtr getActiveDataPtr(const std::string &name) override
std::pair< bool, MatrixPtr > insertActiveData(const std::string &name, const MatrixDouble &data=MatrixDouble(), int shift=0) override
auto & getDataCommonByName()
auto & getStateDataBySequence()
MoFEMErrorCode setDependentContinuousVector(std::vector< double > &dependent_variables) override
MoFEMErrorCode setActiveContinuousVector(std::vector< double > &active_variables) override
MoFEMErrorCode getContinuousVector(DataContainer &data_container, const std::vector< double > &variables)
boost::shared_ptr< MatrixAdaptor > StateMatrixPtr
boost::shared_ptr< MatrixDouble > MatrixPtr
virtual moab::Interface & get_moab()=0
Deprecated interface functions.