forked from lijiext/lammps
349 lines
13 KiB
C++
349 lines
13 KiB
C++
/** fe_engine :
|
|
* computes and assembles mass matrix, rhs vectors
|
|
* initial conditions handled in atc_transfer
|
|
*/
|
|
|
|
/** field structure:
|
|
a field is a dense matrix of numPoints X number of DOF in the field
|
|
a gradient is a std::vector of fields of length numSpatialDimensions
|
|
a set of fields is a map of fieldName->field of length numFields
|
|
a set of gradients is a map of fieldName->gradient of length numFields
|
|
Note: shape functions follow similar conventions with a shape function being
|
|
a field of numPoints X numNodes
|
|
and a shape function gradient being a std::vector of shape functions
|
|
of length numSpatialDimensions, although this is modified in calls when
|
|
numPoints = 1
|
|
Note: the convention between shape function format and field format allows
|
|
for shape functions to matmat nodal fields, creating matrices of
|
|
numPoints X numElementsInField for evaluating data at atomic/quadarture points
|
|
*/
|
|
|
|
/** current internal limitations:
|
|
* 3 spatial dimensions
|
|
* 8 node bricks
|
|
* structured mesh
|
|
* no stiffness matrix
|
|
(i.e. no implicit integration or special treatment of linear problems)
|
|
* lumped mass
|
|
*/
|
|
|
|
|
|
|
|
/** terminology:
|
|
density rate = flux
|
|
= Grad.FLUX(f,D_x f)
|
|
+ SOURCE(f,D_x f) + PRESCRIBED_SOURCE(x,t)
|
|
+ EXTRINSIC_SOURCE(f,D_x f,f_e,D_x f_e)
|
|
*/
|
|
|
|
#ifndef FE_ENGINE_H
|
|
#define FE_ENGINE_H
|
|
|
|
// Other headers
|
|
#include <vector>
|
|
#include <map>
|
|
|
|
// ATC_Transfer headers
|
|
#include "Array.h"
|
|
#include "Array2D.h"
|
|
#include "FE_Mesh.h"
|
|
#include "PhysicsModel.h"
|
|
#include "OutputManager.h"
|
|
|
|
using namespace std;
|
|
|
|
namespace ATC {
|
|
|
|
// Forward declarations
|
|
class ATC_Transfer;
|
|
class FE_Element;
|
|
class XT_Function;
|
|
|
|
class FE_Engine{
|
|
public:
|
|
/** constructor/s */
|
|
FE_Engine(ATC_Transfer * atcTransfer);
|
|
|
|
/** destructor */
|
|
~FE_Engine();
|
|
|
|
/** initialize */
|
|
void initialize();
|
|
|
|
/** parser/modifier */
|
|
bool modify(int narg, char **arg);
|
|
|
|
/** finish up */
|
|
void finish();
|
|
|
|
//----------------------------------------------------------------
|
|
/** \name output */
|
|
//----------------------------------------------------------------
|
|
/*@{*/
|
|
/** these assume the caller is handling the parallel collection */
|
|
void initialize_output(int rank,
|
|
string outputPrefix, OutputType otype = ENSIGHT);
|
|
|
|
/** write geometry */
|
|
void write_geometry(void);
|
|
|
|
/** write data: data is arrayed over _unique_ nodes
|
|
& then mapped by the engine */
|
|
void write_data(double time, FIELDS &soln, OUTPUT_LIST *data=NULL);
|
|
void write_data(double time, OUTPUT_LIST *data);
|
|
void write_restart_file(string fileName, OUTPUT_LIST *data)
|
|
{outputManager_.write_restart_file(fileName,data);};
|
|
void read_restart_file(string fileName, OUTPUT_LIST *data)
|
|
{outputManager_.read_restart_file(fileName,data);};
|
|
|
|
void delete_elements(const set<int> & elementList);
|
|
|
|
void add_global(string name, double value)
|
|
{outputManager_.add_global(name,value);}
|
|
void reset_globals() {outputManager_.reset_globals();}
|
|
|
|
/** pass through to access output manager */
|
|
OutputManager* output_manager() {return &outputManager_;}
|
|
/*@}*/
|
|
|
|
//----------------------------------------------------------------
|
|
/** \name assembled matrices and vectors */
|
|
//----------------------------------------------------------------
|
|
/*@{*/
|
|
/** compute a dimensionless stiffness matrix */
|
|
void compute_stiffness_matrix(SPAR_MAT &matrix) const;
|
|
|
|
/** compute a dimensionless mass matrix */
|
|
void compute_mass_matrix(SPAR_MAT &mass_matrix) const;
|
|
/** computes a dimensionless mass matrix for the given-quadrature */
|
|
void compute_mass_matrix(const DIAG_MAT &weights,
|
|
const SPAR_MAT &N,
|
|
SPAR_MAT &mass_matrix) const;
|
|
/** compute a single dimensionless mass matrix */
|
|
void compute_lumped_mass_matrix(DIAG_MAT &lumped_mass_matrix) const;
|
|
|
|
/** compute lumped mass matrix = diag (\int \rho N_I dV) */
|
|
void compute_lumped_mass_matrix(const Array<FieldName> &mask,
|
|
const FIELDS &fields,
|
|
const PhysicsModel * physicsModel,
|
|
const Array<int> & elementMaterials,
|
|
map<FieldName, DIAG_MAT> &mass_matrix,
|
|
const Array<bool> *element_mask=NULL) const;
|
|
/** compute dimensional lumped mass matrix using given quadrature */
|
|
void compute_lumped_mass_matrix(const Array<FieldName> &mask,
|
|
const FIELDS &fields,
|
|
const PhysicsModel * physicsModel,
|
|
const Array<set<int> > & pointMaterialGroups,
|
|
const DIAG_MAT &weights,
|
|
const SPAR_MAT &N,
|
|
map<FieldName, DIAG_MAT> &mass_matrix) const;
|
|
|
|
/** compute an approximation to a finite difference gradient from mesh */
|
|
void compute_gradient_matrix(GRAD_SHPFCN &grad_matrix) const;
|
|
|
|
|
|
/** compute energy */
|
|
void compute_energy(const Array<FieldName> &mask,
|
|
const FIELDS &fields,
|
|
const PhysicsModel * physicsModel,
|
|
const Array<int> & elementMaterials,
|
|
FIELDS &energy,
|
|
const Array<bool> *element_mask=NULL) const;
|
|
|
|
|
|
/** compute residual or RHS of the dynamic weak eqn */
|
|
void compute_rhs_vector(const Array2D<bool> &rhs_mask,
|
|
const FIELDS &fields,
|
|
const PhysicsModel * physicsModel,
|
|
const Array<int> & elementMaterials,
|
|
FIELDS &rhs,
|
|
const Array<bool> *element_mask=NULL) const;
|
|
|
|
/** compute RHS for given quadrature */
|
|
void compute_rhs_vector(const Array2D<bool> &rhs_mask,
|
|
const FIELDS &fields,
|
|
const PhysicsModel * physicsModel,
|
|
const Array<set<int> > & pointMaterialGroups,
|
|
const DIAG_MAT &weights,
|
|
const SPAR_MAT &N,
|
|
const GRAD_SHPFCN &dN,
|
|
FIELDS &rhs) const;
|
|
|
|
/** compute flux in domain i.e. N^T B_integrand */
|
|
void compute_flux(const Array2D<bool> & rhs_mask,
|
|
const FIELDS &fields,
|
|
const PhysicsModel * physicsModel,
|
|
const Array<int> & elementMaterials,
|
|
GRAD_FIELDS &flux,
|
|
const Array<bool> *element_mask=NULL) const;
|
|
|
|
/** compute the flux on the MD/FE boundary */
|
|
void compute_boundary_flux(
|
|
const Array2D<bool> & rhs_mask,
|
|
const FIELDS & fields,
|
|
const PhysicsModel * physicsModel,
|
|
const Array<int> & elementMaterials,
|
|
const set<PAIR> & faceSet,
|
|
FIELDS & rhs) const;
|
|
|
|
/** compute the flux on using an L2 interpolation of the flux */
|
|
void compute_boundary_flux(
|
|
const Array2D<bool> & rhs_mask,
|
|
const FIELDS & fields,
|
|
const PhysicsModel * physicsModel,
|
|
const Array<int> & elementMaterials,
|
|
const Array<set<int> > & pointMaterialGroups,
|
|
const DIAG_MAT & weights,
|
|
const SPAR_MAT & N,
|
|
const GRAD_SHPFCN & dN,
|
|
const DIAG_MAT & flux_mask,
|
|
FIELDS & rhs ) const;
|
|
|
|
/** compute prescribed flux given an array of functions of x & t */
|
|
void add_fluxes(const Array<bool> &fieldMask,
|
|
const double time,
|
|
const SURFACE_SOURCE & sourceFunctions,
|
|
FIELDS &nodalSources) const;
|
|
|
|
/** compute nodal vector of volume based sources */
|
|
void add_sources(const Array<bool> &fieldMask,
|
|
const double time,
|
|
const VOLUME_SOURCE &sourceFunctions,
|
|
FIELDS &nodalSources) const;
|
|
|
|
/** compute surface flux of a nodal field */
|
|
void field_surface_flux(const DENS_MAT & field,
|
|
const set<PAIR> &faceSet,
|
|
DENS_MAT & values,
|
|
const bool contour = false,
|
|
const int axis = 2) const;
|
|
|
|
/*@}*/
|
|
|
|
//----------------------------------------------------------------
|
|
/** \name shape functions */
|
|
//----------------------------------------------------------------
|
|
/*@{*/
|
|
/** evaluate shape function at a list of points in R^3 */
|
|
void evaluate_shape_functions(const MATRIX &coords,
|
|
SPAR_MAT &N,
|
|
Array<int> & pointToEltMap) const;
|
|
|
|
/** evaluate shape function & derivatives at a list of points in R^3 */
|
|
void evaluate_shape_functions( const MATRIX &coords,
|
|
SPAR_MAT &N,
|
|
GRAD_SHPFCN &dN,
|
|
Array<int> & pointToEltMap) const;
|
|
|
|
/** evaluate all shape function & derivatives at a specific R^3 location */
|
|
void evaluate_shape_functions(const VECTOR & x,
|
|
Array<int>& node_index,
|
|
DENS_VEC& shp,
|
|
DENS_MAT& dshp,
|
|
int & eltID) const;
|
|
|
|
/** pass through */
|
|
void shape_functions(const VECTOR &x,
|
|
DENS_VEC& shp,
|
|
int & eltID,
|
|
Array<int>& node_list) const
|
|
{ feMesh_->shape_functions(x,shp,eltID,node_list); }
|
|
|
|
void shape_functions(const VECTOR &x,
|
|
DENS_VEC& shp,
|
|
int & eltID,
|
|
Array<int>& node_list,
|
|
const Array<bool>& periodicity) const
|
|
{ feMesh_->shape_functions(x,shp,eltID,node_list, periodicity); }
|
|
/*@}*/
|
|
|
|
//----------------------------------------------------------------
|
|
/** \name accessors */
|
|
//----------------------------------------------------------------
|
|
/*@{*/
|
|
/** even though these are pass-throughs there is a necessary translation */
|
|
/** return number of unique nodes */
|
|
int get_nNodes() const { return feMesh_->get_nNodesUnique(); };
|
|
|
|
/** return number of total nodes */
|
|
int get_nNodesTotal() const { return feMesh_->get_nNodes(); };
|
|
|
|
/** return number of elements */
|
|
int get_nElements() const { return feMesh_->get_nElements(); };
|
|
|
|
/** return element connectivity */
|
|
void element_connectivity(const int eltID, Array<int> & nodes) const
|
|
{ feMesh_->element_connectivity_unique(eltID, nodes); }
|
|
|
|
/** return face connectivity */
|
|
void face_connectivity(const PAIR &faceID, Array<int> &nodes) const
|
|
{ feMesh_->face_connectivity_unique(faceID, nodes); }
|
|
|
|
/** in lieu of pass-throughs const accessors ... */
|
|
// return const ptr to mesh
|
|
const FE_Mesh* get_feMesh() const { return feMesh_;}
|
|
|
|
// return number of spatial dimensions
|
|
int get_nsd() const { return feMesh_->get_nSpatialDimensions(); }
|
|
|
|
// return if the FE mesh has been created
|
|
int fe_mesh_exist() const { return feMesh_!=NULL; }
|
|
|
|
// get nodal coordinates for a given element
|
|
void element_coordinates(const int eltIdx, DENS_MAT &coords)
|
|
{ feMesh_->element_coordinates(eltIdx,coords); }
|
|
|
|
// access list of elements to be deleted
|
|
set<int> & null_elements(void) { return nullElements_; }
|
|
/*@}*/
|
|
|
|
private:
|
|
//----------------------------------------------------------------
|
|
/** mesh setup commands (called from modify) */
|
|
//----------------------------------------------------------------
|
|
/*@{*/
|
|
|
|
/** initialized flag */
|
|
bool initialized_;
|
|
|
|
/** create a uniform, structured mesh */
|
|
void create_mesh(int nx, int ny, int nz, char * regionName,
|
|
int xperiodic, int yperiodic, int zperiodic);
|
|
/*@}*/
|
|
|
|
/** ATC transfer object */
|
|
ATC_Transfer * atcTransfer_;
|
|
|
|
/** finite element mesh */
|
|
FE_Mesh * feMesh_;
|
|
|
|
/** data that can be used for a subset of original mesh */
|
|
set<int> nullElements_;
|
|
bool amendedMeshData_;
|
|
const Array2D<int> * connectivity_;
|
|
const Array<int> * nodeMap_;
|
|
const DENS_MAT * coordinates_;
|
|
|
|
/** workspace */
|
|
int nNodesPerElement_;
|
|
int nIPsPerElement_;
|
|
int nIPsPerFace_;
|
|
int nSD_;
|
|
int nElems_;
|
|
|
|
/** output object */
|
|
OutputManager outputManager_;
|
|
|
|
/** base name for output files */
|
|
string outputPrefix_;
|
|
|
|
/** output frequency (NOTE will move to "Transfer") */
|
|
int outputFrequency_;
|
|
|
|
/** list of output timesteps */
|
|
vector<double> outputTimes_;
|
|
};
|
|
}; // end namespace ATC
|
|
|
|
#endif
|