diff --git a/src/continuum/akantu/domain_akantu.cc b/src/continuum/akantu/domain_akantu.cc index d6617ea..0c107f7 100644 --- a/src/continuum/akantu/domain_akantu.cc +++ b/src/continuum/akantu/domain_akantu.cc @@ -1,790 +1,790 @@ /** * @file domain_akantu.cc * * @author Guillaume Anciaux <guillaume.anciaux@epfl.ch> * @author Till Junge <till.junge@epfl.ch> * @author Srinivasa Babu Ramisetti <srinivasa.ramisetti@epfl.ch> * @author Nicolas Richart <nicolas.richart@epfl.ch> * * @date Mon Jul 21 10:32:33 2014 * * @brief This is the model wrapping Akantu * * @section LICENSE * * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * LibMultiScale is free software: you can redistribute it and/or modify it * under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * LibMultiScale is distributed in the hope that it will be useful, but * WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with LibMultiScale. If not, see <http://www.gnu.org/licenses/>. * */ #define TIMER /* -------------------------------------------------------------------------- */ #include "domain_akantu.hh" #include "lib_geometry.hh" #include "lm_common.hh" #include "math_tools.hh" #include "units.hh" /* -------------------------------------------------------------------------- */ #include <communicator_mpi_inline_impl.cc> /* -------------------------------------------------------------------------- */ #include <iomanip> #include <material.hh> #include <material_elastic.hh> #include <memory> +#include <mesh_accessor.hh> #include <solid_mechanics_model.hh> #include <sstream> /* -------------------------------------------------------------------------- */ __BEGIN_LIBMULTISCALE__ template <UInt Dim> DomainAkantu<Dim>::~DomainAkantu() {} /* -------------------------------------------------------------------------- */ template <UInt Dim> DomainAkantu<Dim>::DomainAkantu(LMID ID, CommGroup &GID) : LMObject(ID), DomainContinuum<ContainerElemsAkantu<Dim>, ContainerNodesAkantu<Dim>, Dim>(GID), surface_tag(""), boundary_start(0), boundary_is_traction(false), boundary_has_been_applied(false) { for (UInt i = 0; i < 3; ++i) { pbc[i] = 0; scale[i] = 0.; shift[i] = 0.; for (UInt j = 0; j < Dim; ++j) { this->boundary_stress[Dim * i + j] = std::numeric_limits<Real>::max(); } } } /* -------------------------------------------------------------------------- */ template <UInt Dim> void DomainAkantu<Dim>::scaleMesh() { auto &nodes = mesh->getNodes(); for (auto &n : akantu::make_view(nodes, Dim)) { for (UInt i = 0; i < Dim; ++i) n[i] *= scale[i]; } } /* -------------------------------------------------------------------------- */ template <UInt Dim> void DomainAkantu<Dim>::shiftMesh() { auto &nodes = mesh->getNodes(); for (auto &n : akantu::make_view(nodes, Dim)) { for (UInt i = 0; i < Dim; ++i) n[i] += shift[i]; } } /* -------------------------------------------------------------------------- */ template <UInt Dim> void DomainAkantu<Dim>::initMesh() { mesh = std::make_unique<akantu::Mesh>(Dim, this->getID(), 0); UInt prank = this->getCommGroup().getMyRank(); if (prank == 0) { if (mesh_filename != "") { mesh->read(mesh_filename); #ifndef LM_OPTIMIZED akantu::Mesh::type_iterator it = mesh->firstType(Dim); akantu::Mesh::type_iterator end = mesh->lastType(Dim); UInt ntypes = 0; for (; it != end; ++it, ++ntypes) { } LM_ASSERT(ntypes <= 1, "At current time Akantu plugin cannot support to load" << " more than one element type for volume elements"); #endif // LM_OPTIMIZED scaleMesh(); shiftMesh(); // UInt nb_fragments = mesh->createClusters(Dim); // DUMP("the number of fragments is " << nb_fragments,DBG_MESSAGE); } else { LM_ASSERT(Dim == 1, "automatic mesh generation only possible in 1D" << "a mesh file should have been provided using the" << " MESH_FILENAME keyword"); const akantu::ElementType type = akantu::_segment_2; mesh->addConnectivityType(type); Ball &b = dynamic_cast<Ball &>( *GeometryManager::getManager().getGeometry(this->geometries[0])); // number of element on each side of the zero UInt nx = (UInt)(nearbyint((b.rMax() - b.rMin()) / elem_size)); Real center = b.getCenter(0); Real rmin = b.rMin(); Real rmax = b.rMax(); Real range = rmax - rmin; Real e_size = range / nx; DUMP("element size " << e_size, DBG_MESSAGE); UInt nb_nodes; nb_nodes = 2 * nx + 1; if (rmin > 0) ++nb_nodes; UInt nb_elems; nb_elems = 2 * nx; - akantu::Array<Real> &nodes = - const_cast<akantu::Array<Real> &>(mesh->getNodes()); + akantu::Array<Real> &nodes = akantu::MeshAccessor(*mesh).getNodes(); nodes.resize(nb_nodes); // create nodes from -1 to 0 for (UInt i = 0; i < nx + 1; ++i) { nodes(i) = static_cast<Real>(i) / static_cast<Real>(nx) - 1.0; nodes(i) = nodes(i) * range - rmin + center; DUMP("creating node at position " << nodes(i), DBG_DETAIL) } // create nodes from 0 to 1 if (rmin == 0) { for (UInt i = 0; i < nx + 1; ++i) { nodes(i + nx) = static_cast<Real>(i) / static_cast<Real>(nx); nodes(i + nx) = nodes(i + nx) * range + rmin + center; DUMP("creating node at position " << nodes(i + nx), DBG_DETAIL); } } else for (UInt i = 0; i < nx + 1; ++i) { nodes(i + nx + 1) = static_cast<Real>(i) / static_cast<Real>(nx); nodes(i + nx + 1) = nodes(i + nx + 1) * range + rmin + center; DUMP("creating node at position " << nodes(i + nx + 1), DBG_DETAIL) } akantu::Array<UInt> &connectivity = - const_cast<akantu::Array<UInt> &>(mesh->getConnectivity(type)); + akantu::MeshAccessor(*mesh).getConnectivity(type); connectivity.resize(nb_elems); for (UInt i = 0; i < nx; ++i) { connectivity(i, 0) = i; connectivity(i, 1) = i + 1; } if (rmin == 0) for (UInt i = 0; i < nx; ++i) { connectivity(i + nx, 0) = i + nx; connectivity(i + nx, 1) = i + nx + 1; } else for (UInt i = 0; i < nx; ++i) { connectivity(i + nx, 0) = i + nx + 1; connectivity(i + nx, 1) = i + nx + 2; } - mesh->makeReady(); + akantu::MeshAccessor(*mesh).makeReady(); } } } /* -------------------------------------------------------------------------- */ template <UInt Dim> void DomainAkantu<Dim>::initMaterial() { if (this->material_filename == "") { LM_ASSERT(Dim == 1, "automatic material property definition only possible in 1D" << "a material file should have been provided using the" << " MATERIAL_FILENAME keyword"); DUMP( "Automatic parameter generation for LJ and lattice provided parameters", DBG_WARNING); akantu::Material &mat = model->registerNewMaterial("linear_LJ", "elastic", ""); UInt ordre = static_cast<UInt>(rcut / r0); Real coeff = MathTools::ipow(sigma / r0, 6); Real E = 24.0 * epsilon * coeff / r0 * (-7.0 * MathTools::zeta(6, ordre) + 26.0 * coeff * MathTools::zeta(12, ordre)); mat.setParam("E", E); mat.setParam("nu", 0.0); mat.setParam("rho", Real(atomic_mass / r0)); DUMP("mass density " << (Real)(atomic_mass / r0), DBG_MESSAGE); DUMP("r0 " << r0, DBG_MESSAGE); DUMP("atomic_mass " << atomic_mass, DBG_MESSAGE); } // this->model->initMaterials(); } /* -------------------------------------------------------------------------- */ template <UInt Dim> void DomainAkantu<Dim>::init() { auto &group = this->getCommGroup(); if (!group.amIinGroup()) return; if (this->material_filename != "") akantu::getStaticParser().parse(this->material_filename); akantu::debug::setDebugLevel(akantu::dbl0); // akantu::debug::setDebugLevel(akantu::dblTrace); initMesh(); DUMP("created " << this->mesh->getNodes().size() << " nodes ", DBG_MESSAGE); aka_comm = std::make_unique<akantu::Communicator>(group.getMPIComm()); this->mesh->distribute(*aka_comm); this->model = std::make_unique<akantu::SolidMechanicsModel>(*mesh, Dim, this->getID()); this->model->getFEEngine().initShapeFunctions(akantu::_not_ghost); this->model->getFEEngine().initShapeFunctions(akantu::_ghost); - + this->initMaterial(); this->model->initFull( akantu::SolidMechanicsModelOptions(akantu::_explicit_lumped_mass)); this->model->setF_M2A(code_unit_system.ft_m2v); bool pbc_activated = false; for (UInt i = 0; i < Dim; ++i) { pbc_activated |= pbc[i]; } if (pbc_activated) { DUMP("pbc with Akantu are currently not working", DBG_WARNING); // this->model->setPBC(pbc[0], pbc[1], pbc[2]); // std::map<UInt, UInt> &akantu_pairs = this->model->getPBCPairs(); // std::map<UInt, UInt>::iterator it = akantu_pairs.begin(); // std::map<UInt, UInt>::iterator end = akantu_pairs.end(); // while (it != end) { // this->pbc_pairs.push_back((*it)); // ++it; // } } this->mesh_container.getContainerElems().setSolidMechanicsModel(*this->model); this->mesh_container.getContainerNodes().setSolidMechanicsModel(*this->model); Real time_step_suggested = this->model->getStableTimeStep() / sqrt(code_unit_system.e_m2dd_tt); DUMP("Akantu's critical timestep evaluation: " << time_step_suggested, DBG_MESSAGE); if (this->timeStep > time_step_suggested) LM_FATAL("Required timestep larger than critical timestep"); this->model->setTimeStep(this->timeStep); } /* -------------------------------------------------------------------------- */ // template <UInt Dim> void DomainAkantu<Dim>::performStep1() { // STARTTIMER("AkantuStepPosition"); // // if (this->prestressed_periodicity_flag && // // !this->slave_displacements_computed) { // // this->buildSlaveDisplacements(); // // this->slave_displacements_computed = true; // //} // if ((this->haveToApplyNeumann()) && !this->boundary_has_been_applied && // (current_step >= this->boundary_start)) { // this->enableNeumanBndyConditions(); // } // UInt nb_nodes = this->model->getFEEngine().getMesh().getNbNodes(); // for (UInt n = 0; n < nb_nodes; ++n) { // for (UInt i = 0; i < Dim; ++i) { // this->getV()[Dim * n + i] += // code_unit_system.ft_m2v * .5 * this->getInternalForce()[Dim * n + // i] / this->getMass()[Dim * n + i] * this->timeStep; // LM_ASSERT(!isnan(this->getV()[Dim * n + i]) && // !isinf(this->getV()[Dim * n + i]), // "problem with velocity on node " // << n << " Dim " << i << " " // << this->getInternalForce()[Dim * n + i] << " " // << this->getMass()[Dim * n + i]); // this->getU()[Dim * n + i] += this->timeStep * this->getV()[Dim * n + // i]; // } // } // STOPTIMER("AkantuStepPosition"); // #ifdef AKANTU_HEAT_TRANSFER // if (heat_transfer_flag) // heat_transfer_model->explicitPred(); // #endif // LM_TOIMPLEMENT; // // this->mesh_container.incRelease(); // } /* -------------------------------------------------------------------------- */ // template <UInt Dim> void DomainAkantu<Dim>::performStep3() { // STARTTIMER("AkantuStepVelocity"); // UInt nb_nodes = this->model->getMesh().getNbNodes(); // for (UInt n = 0; n < nb_nodes; ++n) { // for (UInt i = 0; i < Dim; ++i) { // this->getV()[Dim * n + i] += // code_unit_system.ft_m2v * .5 * this->getInternalForce()[Dim * n + // i] / this->getMass()[Dim * n + i] * this->timeStep; // LM_ASSERT(!isnan(this->getV()[Dim * n + i]) && // !isinf(this->getV()[Dim * n + i]), // "problem with velocity on node " // << n << " Dim " << i << " " << this->getV()[Dim * n + i] // << " " << this->getInternalForce()[Dim * n + i] << " " // << this->getMass()[Dim * n + i] << " " << // this->timeStep); // } // } // STOPTIMER("AkantuStepVelocity"); // #ifdef AKANTU_HEAT_TRANSFER // if (heat_transfer_flag) // heat_transfer_model->explicitCorr(); // #endif // LM_TOIMPLEMENT; // // this->mesh_container.incRelease(); // } /* -------------------------------------------------------------------------- */ template <UInt Dim> UInt DomainAkantu<Dim>::getCurrentStep() { LM_TOIMPLEMENT; } /* -------------------------------------------------------------------------- */ template <UInt Dim> void DomainAkantu<Dim>::buildSlaveDisplacements() { typedef std::vector<std::pair<UInt, UInt>>::iterator pair_it; pair_it pbc_pair = this->pbc_pairs.begin(); pair_it end = this->pbc_pairs.end(); // upper bounds are masters, lower bounds slaves for (; pbc_pair != end; ++pbc_pair) { for (UInt direction = 0; direction < Dim; ++direction) { // this->slave_displacements.push_back( // this->getU()[Dim * pbc_pair->first + direction] - // this->getU()[Dim * pbc_pair->second + direction]); } } } /* -------------------------------------------------------------------------- */ template <UInt Dim> void DomainAkantu<Dim>::checkBoundaryInputSanity() { try { this->mesh->template createGroupsFromMeshData<std::string>( "physical_names"); } catch (...) { this->mesh->template createGroupsFromMeshData<UInt>("tag_0"); } bool is_stress; Real realmax = std::numeric_limits<Real>::max(); this->boundary_is_traction = ((this->boundary_stress[0] != realmax) && (this->boundary_stress[Dim] == realmax)); is_stress = (this->boundary_stress[Dim] != realmax); if (this->boundary_is_traction && is_stress) { LM_FATAL("you cannot specify both a traction (TRACTION_BNDY_VECTOR) and " << "a stress (TRACTION_BNDY_TENSOR) for traction " << "boundary conditions"); } else if (!this->boundary_is_traction && !is_stress) { LM_FATAL("you specified a TRACTION_BNDY_TAG, but neither a stress " << "(TRACTION_BNDY_TENSOR) nor a traction " << "(TRACTION_BNDY_VECTOR)"); } } /* -------------------------------------------------------------------------- */ template <UInt Dim> void DomainAkantu<Dim>::enableNeumanBndyConditions() { try { if (boundary_is_traction) { akantu::Vector<Real> surface_traction(Dim); for (UInt i = 0; i < Dim; ++i) { surface_traction(i) = this->boundary_stress[i]; } model->applyBC(akantu::BC::Neumann::FromSameDim(surface_traction), surface_tag); } else { akantu::Matrix<Real> surface_stress(Dim, Dim); for (UInt i = 0; i < Dim; ++i) { for (UInt j = 0; j < Dim; ++j) { surface_stress(i, j) = this->boundary_stress[Dim * i + j]; } } model->applyBC(akantu::BC::Neumann::FromHigherDim(surface_stress), surface_tag); } } catch (akantu::debug::Exception &) { } this->boundary_has_been_applied = true; } /* -------------------------------------------------------------------------- */ template <UInt Dim> void DomainAkantu<Dim>::setTimeStep(Real ts) { model->setTimeStep(ts); this->timeStep = ts; } /* -------------------------------------------------------------------------- */ template <UInt Dim> void DomainAkantu<Dim>::setCurrentStep(UInt step) { current_step = step; } /* -------------------------------------------------------------------------- */ template <UInt Dim> Real DomainAkantu<Dim>::getEpot() { LM_TOIMPLEMENT; } /* -------------------------------------------------------------------------- */ template <UInt Dim> Cube DomainAkantu<Dim>::getSubDomainBoundingBox() { akantu::Vector<Real> _xmin; akantu::Vector<Real> _xmax; _xmin = mesh->getLocalLowerBounds(); _xmax = mesh->getLocalUpperBounds(); Cube c; for (UInt k = 0; k < Dim; ++k) { c.getXmin()[k] = _xmin[k]; c.getXmax()[k] = _xmax[k]; } return c; } /* -------------------------------------------------------------------------- */ template <UInt Dim> Cube DomainAkantu<Dim>::getDomainBoundingBox() { akantu::Vector<Real> _xmin; akantu::Vector<Real> _xmax; _xmin = mesh->getLowerBounds(); _xmax = mesh->getUpperBounds(); Cube c; for (UInt k = 0; k < Dim; ++k) { c.getXmin()[k] = _xmin[k]; c.getXmax()[k] = _xmax[k]; } return c; } /* -------------------------------------------------------------------------- */ template <UInt Dim> void DomainAkantu<Dim>::initHeatTransfer() { #ifndef AKANTU_HEAT_TRANSFER LM_FATAL("Akantu was not compiled using the heat transfer model"); #else heat_transfer_model = new akantu::HeatTransferModel(*this->mesh, Dim, this->getID() + "heat"); // initialize PBC bool pbc_activated = false; for (UInt i = 0; i < Dim; ++i) { pbc_activated |= this->pbc[i]; } if (pbc_activated) { heat_transfer_model->setPBC(this->pbc[0], this->pbc[1], this->pbc[2]); std::map<UInt, UInt> &akantu_pairs = heat_transfer_model->getPBCPairs(); std::map<UInt, UInt>::iterator it = akantu_pairs.begin(); std::map<UInt, UInt>::iterator end = akantu_pairs.end(); while (it != end) { this->pbc_pairs.push_back((*it)); ++it; } } // initialize everything if (heat_transfer_material_filename != "") { this->akantu_parser.parse(this->heat_transfer_material_filename); heat_transfer_model->setParser(this->akantu_parser); heat_transfer_model->initFull(); } else LM_FATAL("Heat transfer material file not provided."); this->elems.setHeatTransferModel(*heat_transfer_model); this->nodes.setHeatTransferModel(*heat_transfer_model); this->elems.setHeatTransferFlag(heat_transfer_flag); this->nodes.setHeatTransferFlag(heat_transfer_flag); // assemble the lumped capacity heat_transfer_model->assembleCapacityLumped(); // get stable time step akantu::Real suggested_time_step_heat_transfer = heat_transfer_model->getStableTimeStep() * 0.8; DUMP("suggested timestep for heat transfer model is " << suggested_time_step_heat_transfer, DBG_MESSAGE); if (this->timeStep > suggested_time_step_heat_transfer) LM_FATAL("provided timestep is larger than the critical timestep for the " "heat transfer model: please adapt it"); heat_transfer_model->setTimeStep(this->timeStep); /* -------------------- */ // initialize the vectors /* -------------------- */ temperature = new VecAkantu(heat_transfer_model->getTemperature()); heat_flux = new VecAkantu(heat_transfer_model->getExternalHeatRate()); temperature_rate = new VecAkantu(heat_transfer_model->getTemperatureRate()); heat_transfer_model->updateResidual(); akantu::Array<bool> &boundary = heat_transfer_model->getBlockedDOFs(); UInt nb_nodes = boundary.getSize(); bool *bound = boundary.storage(); if (heat_boundary_geom != invalidGeom) { Geometry *geom_dirichlet = GeometryManager::getManager().getGeometry(heat_boundary_geom); for (UInt n = 0; n < nb_nodes; ++n, ++bound) { Real pos[Dim]; this->nodes.get(n).getPositions0(pos); if (geom_dirichlet->contains<Dim>(pos)) { *bound = true; } } } #endif } /* -------------------------------------------------------------------------- */ template <UInt Dim> void DomainAkantu<Dim>::updateGradient() { STARTTIMER("AkantuStepForce"); this->model->assembleInternalForces(); // if (this->prestressed_periodicity_flag) { // typedef std::vector<std::pair<UInt, UInt>>::iterator pair_it; // pair_it pbc_pair = this->pbc_pairs.begin(); // pair_it end = this->pbc_pairs.end(); // UInt node_counter = 0; // for (; pbc_pair != end; ++pbc_pair, ++node_counter) { // for (UInt direction = 0; direction < Dim; ++direction) { // this->getU()[Dim * pbc_pair->first + direction] += // this->slave_displacements[Dim * node_counter + direction]; // } // } // } STOPTIMER("AkantuStepForce"); // #ifdef AKANTU_HEAT_TRANSFER // if (heat_transfer_flag) // heat_transfer_model->updateResidual(); // #endif this->getOutput()->incRelease(); } /* -------------------------------------------------------------------------- */ template <UInt Dim> void DomainAkantu<Dim>::updateAcceleration() { auto &acceleration = model->getAcceleration(); auto &internal_force = model->getInternalForce(); auto &external_force = model->getExternalForce(); auto &lumped_mass = model->getMass(); for (UInt i = 0; i < acceleration.size(); ++i) { for (UInt k = 0; k < Dim; ++k) { Real f = internal_force(i, k) + external_force(i, k); acceleration(i, k) = code_unit_system.ft_m2v * f / lumped_mass(i, k); } } } /* -------------------------------------------------------------------------- */ template <UInt Dim> Real DomainAkantu<Dim>::potentialEnergy() { LM_TOIMPLEMENT; } /* -------------------------------------------------------------------------- */ template <UInt Dim> void DomainAkantu<Dim>::enforceCompatibility() { auto &blocked_dofs = model->getBlockedDOFs(); auto &acceleration = model->getAcceleration(); auto &velocity = model->getVelocity(); for (UInt i = 0; i < acceleration.size(); ++i) { for (UInt k = 0; k < Dim; ++k) { if (blocked_dofs(i, k)) { acceleration(i, k) = 0.; velocity(i, k) = 0.; } } } } /* -------------------------------------------------------------------------- */ template <UInt Dim> void DomainAkantu<Dim>::setDomainBoundingBox(const Cube &) { LM_TOIMPLEMENT; } /* -------------------------------------------------------------------------- */ template <UInt Dim> void DomainAkantu<Dim>::setSubDomainBoundingBox(const Cube &) { LM_TOIMPLEMENT; } /* -------------------------------------------------------------------------- */ // template <UInt Dim> void DomainAkantu<Dim>::performStep2() { // STARTTIMER("AkantuStepForce"); // LM_TOIMPLEMENT; // // this->model->initializeUpdateResidualData(); // // if (this->prestressed_periodicity_flag) { // // typedef std::vector<std::pair<UInt, UInt>>::iterator pair_it; // // pair_it pbc_pair = this->pbc_pairs.begin(); // // pair_it end = this->pbc_pairs.end(); // // UInt node_counter = 0; // // for (; pbc_pair != end; ++pbc_pair, ++node_counter) { // // for (UInt direction = 0; direction < Dim; ++direction) { // // this->getU()[Dim * pbc_pair->first + direction] += // // this->slave_displacements[Dim * node_counter + direction]; // // } // // } // // } // LM_TOIMPLEMENT; // // this->model->updateResidual(false); // // this->model->updateAcceleration(); // STOPTIMER("AkantuStepForce"); // #ifdef AKANTU_HEAT_TRANSFER // if (heat_transfer_flag) // heat_transfer_model->updateResidual(); // #endif // LM_TOIMPLEMENT; // // this->mesh_container.incRelease(); // } /* -------------------------------------------------------------------------- */ /* LMDESC AKANTU_BASE This domain implements the plugin with Akantu Finite Element library. */ /* LMHERITANCE domain_continuum */ template <UInt Dim> void DomainAkantu<Dim>::declareParams() { DomainContinuum<ContainerElemsAkantu<Dim>, ContainerNodesAkantu<Dim>, Dim>::declareParams(); /* LMKEYWORD MESH_FILENAME Specify the mesh file to be loaded using the MeshIO utility of Akantu */ this->parseKeyword("MESH_FILENAME", mesh_filename, ""); /* LMKEYWORD MATERIAL_FILENAME Specify the material file to be loaded for the Akantu SolidMechanicsModel object */ this->parseKeyword("MATERIAL_FILENAME", material_filename, ""); /* LMKEYWORD PBC Specify the directions in which Periodic Boundary Conditions should be activated */ this->parseVectorKeyword("PBC", Dim, pbc, VEC_DEFAULTS(0u, 0u, 0u)); /* LMKEYWORD SCALE Specify factors for each directions to be used in rescaling the mesh nodal positions */ this->parseVectorKeyword("SCALE", Dim, scale, VEC_DEFAULTS(1., 1., 1.)); /* LMKEYWORD SHIFT Specify factors for each directions to be used in shifting the mesh nodal positions */ this->parseVectorKeyword("SHIFT", Dim, shift, VEC_DEFAULTS(0., 0., 0.)); /* LMKEYWORD R0 In the case of 1D mesh allows to use a linearized LJ material definition // fitting monoatomic chain:\\ This provides the interatomic distance. */ this->parseKeyword("R0", r0, 0.); /* LMKEYWORD RCUT In the case of 1D mesh allows to use a linearized LJ material definition fitting monoatomic chain:\\ This provides the cutoff radius for the potential evaluation. */ this->parseKeyword("RCUT", rcut, 0.); /* LMKEYWORD EPSILON In the case of 1D mesh allows to use a linearized LJ material definition fitting monoatomic chain:\\ This provides the $\epsilon$ parameter in the LJ potential definition. */ this->parseKeyword("EPSILON", epsilon, 0.); /* LMKEYWORD SIGMA In the case of 1D mesh allows to use a linearized LJ material definition fitting monoatomic chain:\\ This provides the $\sigma$ parameter in the LJ potential definition. */ this->parseKeyword("SIGMA", sigma, 0.); /* LMKEYWORD MASS In the case of 1D mesh allows to use a linearized LJ material definition fitting monoatomic chain:\ \ This provides the atomic mass. */ this->parseKeyword("MASS", atomic_mass, 0.); /* LMKEYWORD ELEM_SIZE In the case of 1D mesh generates automatically a homogeneous 1D first order mesh. */ this->parseKeyword("ELEM_SIZE", elem_size, 0.); /* LMKEYWORD TRACTION_BNDY_TENSOR Specify a full stress tensor to be applied to a boundary */ this->parseVectorKeyword("TRACTION_BNDY_TENSOR", Dim * Dim, this->boundary_stress, VEC_DEFAULTS(0., 0., 0., 0., 0., 0., 0., 0., 0.)); // /* L2MKEYWORD TRACTION_BNDY_VECTOR // Specify a traction vector to be applied to a boundary */ // this->parseVectorKeyword("TRACTION_BNDY_VECTOR", Dim, // this->boundary_stress, // {0.,0.,0.}); /* LMKEYWORD TRACTION_BNDY_TAG Specify the tag of the boundary on which the traction should be applied. This refers to "tag\_1" in the msh format */ this->parseKeyword("TRACTION_BNDY_TAG", this->surface_tag, ""); /* LMKEYWORD TRACTION_BNDY_START Specify the time step at which to start applying the traction boundary conditions */ this->parseKeyword("TRACTION_BNDY_START", this->boundary_start, 0u); /* LMKEYWORD HEAT_TRANSFER To switch on the heat transfer model object */ this->parseTag("HEAT_TRANSFER", this->heat_transfer_flag, false); /* LMKEYWORD HEAT_TRANSFER_MATERIAL_FILENAME Specify the material file to be loaded for the Akantu HeatTransferModel object */ this->parseKeyword("HEAT_TRANSFER_MATERIAL_FILENAME", heat_transfer_material_filename, ""); /* LMKEYWORD HEAT_BOUNDARY Specify the geometry for which a Dirichlet boundary condition should be used for the HeatTransfer model */ this->parseKeyword("HEAT_BOUNDARY", heat_boundary_geom, invalidGeom); } /* -------------------------------------------------------------------------- */ template class DomainAkantu<3>; template class DomainAkantu<2>; template class DomainAkantu<1>; __END_LIBMULTISCALE__ diff --git a/third-party/akantu b/third-party/akantu index 08a6580..ab61214 160000 --- a/third-party/akantu +++ b/third-party/akantu @@ -1 +1 @@ -Subproject commit 08a658024aa77382333db4442ef8a6d5b49f5f5a +Subproject commit ab612145b6587e7adad44312c53b2c3067d48330