• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

PeridigmForce_Def.hpp

Go to the documentation of this file.
00001 //*****************************************************************//
00002 //    Albany 2.0:  Copyright 2012 Sandia Corporation               //
00003 //    This Software is released under the BSD license detailed     //
00004 //    in the file "license.txt" in the top-level Albany directory  //
00005 //*****************************************************************//
00006 
00007 #include "Albany_Utils.hpp"
00008 #include "Teuchos_TestForException.hpp"
00009 #include "Phalanx_DataLayout.hpp"
00010 #include "Intrepid_FunctionSpaceTools.hpp"
00011 #include "Epetra_Vector.h"
00012 
00013 namespace LCM {
00014 
00015 //**********************************************************************
00016 template<typename EvalT, typename Traits>
00017 PeridigmForceBase<EvalT, Traits>::
00018 PeridigmForceBase(Teuchos::ParameterList& p,
00019       const Teuchos::RCP<Albany::Layouts>& dataLayout) :
00020 
00021   density              (p.get<RealType>    ("Density", 1.0)),
00022   volume               ("volume",                                          dataLayout->node_scalar),
00023   referenceCoordinates (p.get<std::string> ("Reference Coordinates Name"), dataLayout->vertices_vector),
00024   currentCoordinates   (p.get<std::string> ("Current Coordinates Name"),   dataLayout->node_vector),
00025   force                (p.get<std::string> ("Force Name"),                 dataLayout->node_vector),
00026   residual             (p.get<std::string> ("Residual Name"),              dataLayout->node_vector)
00027 {
00028   peridigmParams = Teuchos::rcp<Teuchos::ParameterList>(new Teuchos::ParameterList(p.sublist("Peridigm Parameters", true)));
00029 
00030   // For initial implementation with sphere elements, hard code the numQPs and numDims.
00031   // This will need to be generalized to enable standard FEM implementation of peridynamics
00032   numQPs  = 1;
00033   numDims = 3;
00034 
00035 //  this->addDependentField(volume);
00036   this->addDependentField(referenceCoordinates);
00037   this->addDependentField(currentCoordinates);
00038 
00039   this->addEvaluatedField(force);
00040   this->addEvaluatedField(residual);
00041 
00042   this->setName("Peridigm"+PHX::TypeString<EvalT>::value);
00043 }
00044 
00045 //**********************************************************************
00046 template<typename EvalT, typename Traits>
00047 void PeridigmForceBase<EvalT, Traits>::
00048 postRegistrationSetup(typename Traits::SetupData d,
00049                       PHX::FieldManager<Traits>& fm)
00050 {
00051 //  this->utils.setFieldData(volume, fm);
00052   this->utils.setFieldData(referenceCoordinates, fm);
00053   this->utils.setFieldData(currentCoordinates, fm);
00054   this->utils.setFieldData(force, fm);
00055   this->utils.setFieldData(residual, fm);
00056 }
00057 
00058 //**********************************************************************
00059 template<typename EvalT, typename Traits>
00060 void PeridigmForceBase<EvalT, Traits>::
00061 evaluateFields(typename Traits::EvalData workset)
00062 {
00063   TEUCHOS_TEST_FOR_EXCEPTION("PeridigmForceBase::evaluateFields not implemented for this template type",
00064            Teuchos::Exceptions::InvalidParameter, "Need specialization.");
00065 }
00066 
00067 //**********************************************************************
00068 // template<typename EvalT, typename Traits>
00069 // void PeridigmForceBase<EvalT, Traits>::
00070 // evaluateFields(typename Traits::EvalData workset)
00071 template<typename Traits>
00072 void PeridigmForce<PHAL::AlbanyTraits::Residual, Traits>::
00073 evaluateFields(typename Traits::EvalData workset)
00074 {
00075 #ifdef ALBANY_PERIDIGM
00076 
00077   // Initialize the Peridigm object, if needed
00078   // TODO 1  Can this be put in the constructor, or perhaps postRegistrationSetup()?  At the very least, should be in it's own function.
00079   if(this->peridigm.is_null()){
00080     Teuchos::RCP<Epetra_Comm> epetraComm = Albany::createEpetraCommFromMpiComm(Albany_MPI_COMM_WORLD);
00081 
00082     // \todo THIS IS GOING TO RUN INTO BIG PROBLEMS IF THERE IS MORE THAN ONE WORKSET!
00083 
00084     Epetra_BlockMap refCoordMap(static_cast<int>(workset.numCells), 3, 0, *epetraComm);
00085     Teuchos::RCP<Epetra_Vector> refCoordVec = Teuchos::rcp<Epetra_Vector>(new Epetra_Vector(refCoordMap));
00086 
00087     Epetra_BlockMap volumeMap(static_cast<int>(workset.numCells), 1, 0, *epetraComm);
00088     Teuchos::RCP<Epetra_Vector> volumeVec = Teuchos::rcp<Epetra_Vector>(new Epetra_Vector(volumeMap));
00089     Teuchos::RCP<Epetra_Vector> blockIdVec = Teuchos::rcp<Epetra_Vector>(new Epetra_Vector(volumeMap));
00090 
00091     for (std::size_t cell = 0; cell < workset.numCells; ++cell) {
00092       (*refCoordVec)[3*cell+1] = this->referenceCoordinates(cell, 0, 0);
00093       (*refCoordVec)[3*cell+1] = this->referenceCoordinates(cell, 0, 1);
00094       (*refCoordVec)[3*cell+2] = this->referenceCoordinates(cell, 0, 2);
00095       (*volumeVec)[cell] = 1.0;
00096       (*blockIdVec)[cell] = 1.0;
00097     }
00098 
00099     // Create a discretization
00100     this->peridynamicDiscretization = Teuchos::rcp<PeridigmNS::Discretization>(new PeridigmNS::AlbanyDiscretization(epetraComm,
00101                                 this->peridigmParams,
00102                                 refCoordVec,
00103                                 volumeVec,
00104                                 blockIdVec));
00105 
00106     // Create a Peridigm object
00107     this->peridigm = Teuchos::rcp<PeridigmNS::Peridigm>(new PeridigmNS::Peridigm(epetraComm, this->peridigmParams, this->peridynamicDiscretization));
00108   }
00109 
00110   // Get RCPs to important data fields
00111   Teuchos::RCP<Epetra_Vector> peridigmInitialPosition = this->peridigm->getX();
00112   Teuchos::RCP<Epetra_Vector> peridigmCurrentPosition = this->peridigm->getY();
00113   Teuchos::RCP<Epetra_Vector> peridigmDisplacement = this->peridigm->getU();
00114   Teuchos::RCP<Epetra_Vector> peridigmVelocity = this->peridigm->getV();
00115   Teuchos::RCP<Epetra_Vector> peridigmForce = this->peridigm->getForce();
00116 
00117   // Set the time step
00118   double myTimeStep = 0.1;
00119   this->peridigm->setTimeStep(myTimeStep);
00120 
00121   // apply 1% strain in x direction
00122   for(int i=0 ; i<peridigmCurrentPosition->MyLength() ; i+=3){
00123     (*peridigmCurrentPosition)[i]   = 1.01 * (*peridigmInitialPosition)[i];
00124     (*peridigmCurrentPosition)[i+1] = (*peridigmInitialPosition)[i+1];
00125     (*peridigmCurrentPosition)[i+2] = (*peridigmInitialPosition)[i+2];
00126   }
00127 
00128   // Set the peridigmDisplacement vector
00129   for(int i=0 ; i<peridigmCurrentPosition->MyLength() ; ++i)
00130     (*peridigmDisplacement)[i]   = (*peridigmCurrentPosition)[i] - (*peridigmInitialPosition)[i];
00131 
00132   // Evaluate the internal force
00133   this->peridigm->computeInternalForce();
00134 
00135   // Assume we're happy with the internal force evaluation, update the state
00136   this->peridigm->updateState();
00137 
00138   // Write to stdout
00139   int colWidth = 10;
00140 
00141 //   cout << "Initial positions:" << endl;
00142 //   for(int i=0 ; i<peridigmInitialPosition->MyLength() ;i+=3)
00143 //     cout << "  " << std::setw(colWidth) << (*peridigmInitialPosition)[i] << ", " << std::setw(colWidth) << (*peridigmInitialPosition)[i+1] << ", " << std::setw(colWidth) << (*peridigmInitialPosition)[i+2] << endl;
00144 
00145 //   cout << "\nDisplacements:" << endl;
00146 //   for(int i=0 ; i<peridigmDisplacement->MyLength() ; i+=3)
00147 //     cout << "  " << std::setw(colWidth) << (*peridigmDisplacement)[i] << ", " << std::setw(colWidth) << (*peridigmDisplacement)[i+1] << ", " << std::setw(colWidth) << (*peridigmDisplacement)[i+2] << endl;
00148 
00149 //   cout << "\nCurrent positions:" << endl;
00150 //   for(int i=0 ; i<peridigmCurrentPosition->MyLength() ; i+=3)
00151 //     cout << "  " << std::setw(colWidth) << (*peridigmCurrentPosition)[i] << ", " << std::setw(colWidth) << (*peridigmCurrentPosition)[i+1] << ", " << std::setw(colWidth) << (*peridigmCurrentPosition)[i+2] << endl;
00152 
00153   cout << "\nForces:" << endl;
00154   for(int i=0 ; i<peridigmForce->MyLength() ; i+=3)
00155     cout << "  " << std::setprecision(3) << std::setw(colWidth) << (*peridigmForce)[i] << ", " << std::setw(colWidth) << (*peridigmForce)[i+1] << ", " << std::setw(colWidth) << (*peridigmForce)[i+2] << endl;
00156 
00157   cout << endl;
00158 
00159 #endif
00160 
00161   // 1)  Copy from referenceCoordinates and displacement fields into Epetra_Vectors for Peridigm
00162 
00163   // 2)  Call Peridigm
00164 
00165   // 3)  Copy nodal forces from Epetra_Vector to multi-dimensional arrays
00166 
00167   for (std::size_t cell = 0; cell < workset.numCells; ++cell) {
00168     this->force(cell, 0, 0) = 0.0;
00169     this->force(cell, 0, 1) = 0.0;
00170     this->force(cell, 0, 2) = 0.0;
00171   }
00172 
00173 
00174   for (std::size_t cell = 0; cell < workset.numCells; ++cell) {
00175     this->residual(cell, 0, 0) = this->force(cell, 0, 0);
00176     this->residual(cell, 0, 1) = this->force(cell, 0, 1);
00177     this->residual(cell, 0, 2) = this->force(cell, 0, 2);
00178   }
00179 }
00180 
00181 } // namespace LCM
00182 

Generated on Wed Mar 26 2014 18:36:40 for Albany: a Trilinos-based PDE code by  doxygen 1.7.1