Skip to content
Draft
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## v0.6.1

- Add pyFANS support for large strain and fix pyFANS MPI [#124](https://github.com/DataAnalyticsEngineering/FANS/pull/124)
- Adds support to write integration point data to disk [#117](https://github.com/DataAnalyticsEngineering/FANS/pull/117)

## v0.6.0
Expand Down
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,9 @@ find_package(nlohmann_json REQUIRED)
# TARGETS
# ##############################################################################

set(FANS_VERBOSITY 5 CACHE STRING "Set verbosity level: 0 none, 5 all")
add_definitions(-DVERBOSITY=${FANS_VERBOSITY})

option(FANS_BUILD_STATIC "Build static library" OFF)
if (FANS_BUILD_STATIC)
add_library(FANS_FANS STATIC)
Expand Down Expand Up @@ -150,6 +153,7 @@ target_include_directories(FANS_FANS PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SO
# FANS.h header that consuming projects can use
set_property(TARGET FANS_FANS PROPERTY PUBLIC_HEADER
include/general.h
include/logging.h
include/matmodel.h
include/MaterialManager.h
include/reader.h
Expand All @@ -158,6 +162,7 @@ set_property(TARGET FANS_FANS PROPERTY PUBLIC_HEADER
include/solver.h
include/setup.h
include/mixedBCs.h
include/serialization.h

include/material_models/LinearThermal.h
include/material_models/GBDiffusion.h
Expand All @@ -184,6 +189,7 @@ target_include_directories(FANS_main PRIVATE "${PROJECT_BINARY_DIR}/include")

target_sources(FANS_FANS PRIVATE
src/reader.cpp
src/logging.cpp
)

target_sources(FANS_main PRIVATE
Expand Down
98 changes: 55 additions & 43 deletions include/MaterialManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
#define MATERIALMANAGER_H

#include "general.h"
#include "logging.h"
#include "matmodel.h"
#include "serialization.h"

template <int howmany, int n_str>
Matmodel<howmany, n_str> *createMatmodel(const Reader &reader);
Expand All @@ -25,7 +27,7 @@ struct MaterialInfo {
*
*/
template <int howmany, int n_str>
class MaterialManager {
class MaterialManager : public Serializable {
private:
MaterialInfo<howmany, n_str> *phase_to_info{nullptr}; // [n_phases] - HOT DATA
int n_phases;
Expand Down Expand Up @@ -110,51 +112,47 @@ class MaterialManager {
compute_reference_stiffness(reader);

// Print detailed information about material configuration for logging
if (reader.world_rank == 0) {
printf("\n# MaterialManager initialized:\n");
printf("# Number of material models: %zu\n", models.size());
printf("# Number of phases: %d\n#\n", n_phases);

for (size_t i = 0; i < mats.size(); ++i) {
const auto &mg = mats[i];
printf("# Material Model %zu: %s\n", i + 1, mg["matmodel"].get<string>().c_str());

// Print phases
auto phases = mg["phases"].get<vector<int>>();
printf("# Phases: [");
for (size_t j = 0; j < phases.size(); ++j) {
printf("%d", phases[j]);
if (j < phases.size() - 1)
printf(", ");
}
printf("]\n");

// Print material properties
printf("# Material properties:\n");
const auto &props = mg["material_properties"];
for (auto it = props.begin(); it != props.end(); ++it) {
printf("# %s: ", it.key().c_str());
if (it.value().is_array()) {
printf("[");
for (size_t k = 0; k < it.value().size(); ++k) {
if (it.value()[k].is_number()) {
printf("%.5g", it.value()[k].get<double>());
} else if (it.value()[k].is_string()) {
printf("\"%s\"", it.value()[k].get<string>().c_str());
}
if (k < it.value().size() - 1)
printf(", ");
Log::io->info() << "\n# MaterialManager initialized:\n";
Log::io->info() << "# Number of material models: " << models.size() << "\n";
Log::io->info() << "# Number of phases: " << n_phases << "\n#\n";

for (size_t i = 0; i < mats.size(); ++i) {
const auto &mg = mats[i];
Log::io->info() << "# Material Model " << i + 1 << ": " << mg["matmodel"].get<string>() << "\n";

// Print phases
auto phases = mg["phases"].get<vector<int>>();
Log::io->info() << "# Phases: [";
for (size_t j = 0; j < phases.size(); ++j) {
Log::io->info(true) << phases[j];
if (j < phases.size() - 1) Log::io->info(true) << ", ";
}
Log::io->info(true) << "]\n";

// Print material properties
Log::io->info() << "# Material properties:\n";
const auto &props = mg["material_properties"];
for (auto it = props.begin(); it != props.end(); ++it) {
Log::io->info() << "# " << it.key() << ": ";
if (it.value().is_array()) {
Log::io->info(true) << "[";
for (size_t k = 0; k < it.value().size(); ++k) {
if (it.value()[k].is_number()) {
Log::io->info(true) << std::setprecision(5) << it.value()[k].get<double>() << std::defaultfloat;
} else if (it.value()[k].is_string()) {
Log::io->info(true) << "\"" << it.value()[k].get<string>() << "\"";
}
printf("]");
} else if (it.value().is_number()) {
printf("%.5g", it.value().get<double>());
} else if (it.value().is_string()) {
printf("\"%s\"", it.value().get<string>().c_str());
if (k < it.value().size() - 1) Log::io->info(true) << ", ";
}
printf("\n");
Log::io->info(true) << "]";
} else if (it.value().is_number()) {
Log::io->info(true) << std::setprecision(5) << it.value().get<double>() << std::defaultfloat;
} else if (it.value().is_string()) {
Log::io->info(true) << "\"" << it.value().get<string>() << "\"";
}
printf("#\n");
Log::io->info(true) << "\n";
}
Log::io->info() << "#\n";
}
}

Expand Down Expand Up @@ -204,6 +202,20 @@ class MaterialManager {
}
}

void register_serialization(registry_t &r) override
{
for (auto *model : models) {
model->register_serialization(r);
}
}

void init_deserialization() override
{
for (auto *model : models) {
model->init_deserialization();
}
}

// Update internal variables after converged time step
void update_internal_variables()
{
Expand All @@ -213,7 +225,7 @@ class MaterialManager {
}

// Set macroscale loading gradient for all models
void set_gradient(vector<double> g0)
void set_gradient(const vector<double>& g0)
{
for (auto *model : models) {
model->setGradient(g0);
Expand Down
2 changes: 0 additions & 2 deletions include/general.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,4 @@ inline void FANS_free(V *p)
}
#endif // FANS_MALLOC_H

#define VERBOSITY 0

// #define EIGEN_RUNTIME_NO_MALLOC
106 changes: 106 additions & 0 deletions include/logging.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#ifndef LOGGING_H
#define LOGGING_H

#include <chrono>
#include <fstream>
#include <iostream>
#include <sstream>
#include <memory>
#include "mpi.h"

namespace Log {

enum Level {
Error,
Info,
Warn,
Debug,
All
};

[[maybe_unused]] const std::string level_to_string(Level level);

extern Level active_level;

class Logger;
class MPI_TraceSync {
public:
explicit MPI_TraceSync(Logger &log, bool append);
~MPI_TraceSync();

template <class T>
MPI_TraceSync &operator<<(const T &v);
MPI_TraceSync &operator<<(std::ostream &(*m)(std::ostream &) );

private:
Logger &_log;
bool _append;
std::ostringstream _buffer;
};

template <class T>
MPI_TraceSync &MPI_TraceSync::operator<<(const T &v)
{
_buffer << v;
return *this;
}

class Logger {
public:
friend class MPI_TraceSync;
explicit Logger(std::string prefix, int comm_rank, int comm_size, const MPI_Comm& comm);

/// error > info > warn > debug > trace
std::ostream& error(bool append=false);
/// error > info > warn > debug > trace
std::ostream& info(bool append=false);
/// error > info > warn > debug > trace
std::ostream& warn(bool append=false);
/// error > info > warn > debug > trace
std::ostream& debug(bool append=false);
/// error > info > warn > debug > trace
MPI_TraceSync trace(bool append=false);
/// progress bar
void progress(const std::string& prefix, int step, int max);

private:
std::ostream& trace_impl(bool append=false);
/// starting time
std::chrono::steady_clock::time_point _start_time;
/// what the logger should always print first
const std::string _prefix;
/// empty stream to write nothing
std::ofstream _nullstr;
/// MPI comm rank
int _comm_rank;
/// MPI comm size
int _comm_size;
/// communicator
MPI_Comm _comm;
};

/**
* Creates all loggers and sets the level
* */
void init(int comm_rank, int comm_size, const MPI_Comm& comm);

/**
* Frees all memory
* */
void finalize();

/**
* Set activate rank
*/
[[maybe_unused]] void setActiveRank(int rank);

/// logger with prefix [GENERAL]
extern std::unique_ptr<Logger> general;
/// logger with prefix [SOLVER]
extern std::unique_ptr<Logger> solver;
/// logger with prefix [IO]
extern std::unique_ptr<Logger> io;

}; // namespace Log

#endif
11 changes: 11 additions & 0 deletions include/material_models/J2Plasticity.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,17 @@ class J2Plasticity : public SmallStrainMechModel {
psi_bar_t.resize(num_elements, Matrix<double, 6, Dynamic>::Zero(6, num_gauss_points));
}

void register_serialization(registry_t &r) override
{
SmallStrainMechModel::register_serialization(r);
for (auto &mat : plasticStrain_t) r.emplace_back(std::data(mat), (mat.size()) * sizeof(double), true);
for (auto &mat : plasticStrain) r.emplace_back(std::data(mat), (mat.size()) * sizeof(double), true);
for (auto &mat : psi_bar_t) r.emplace_back(std::data(mat), (mat.size()) * sizeof(double), true);
for (auto &mat : psi_bar) r.emplace_back(std::data(mat), (mat.size()) * sizeof(double), true);
for (auto &vec : psi_t) r.emplace_back(std::data(vec), (vec.size()) * sizeof(double), true);
for (auto &vec : psi) r.emplace_back(std::data(vec), (vec.size()) * sizeof(double), true);
}

virtual void updateInternalVariables() override
{
plasticStrain_t = plasticStrain;
Expand Down
9 changes: 9 additions & 0 deletions include/material_models/J2PlasticityNew.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@ class J2PlasticityNew : public SmallStrainMechModel {
q_t.resize(num_elements, VectorXd::Zero(num_gauss_points));
}

void register_serialization(registry_t &r) override
{
SmallStrainMechModel::register_serialization(r);
for (auto &mat : plasticStrain_t) r.emplace_back(std::data(mat), (mat.size()) * sizeof(double), true);
for (auto &mat : plasticStrain) r.emplace_back(std::data(mat), (mat.size()) * sizeof(double), true);
for (auto &vec : q_t) r.emplace_back(std::data(vec), (vec.size()) * sizeof(double), true);
for (auto &vec : q) r.emplace_back(std::data(vec), (vec.size()) * sizeof(double), true);
}

virtual void updateInternalVariables() override
{
plasticStrain_t = plasticStrain;
Expand Down
Loading
Loading