Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add madof for expl phase field #4

Closed
wants to merge 14 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*.log
*.vtf
*~
52 changes: 38 additions & 14 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,30 +21,54 @@ set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
set(EXTRA_DOXY_PATHS "${PROJECT_SOURCE_DIR} ${PROJECT_BINARY_DIR}")

if(EXISTS ${PROJECT_SOURCE_DIR}/../IFEM-Elasticity)
set(EXTRA_DOXY_PATHS "${EXTRA_DOXY_PATHS} \\
${PROJECT_SOURCE_DIR}/../IFEM-Elasticity")
if(NOT TARGET Elasticity)
add_subdirectory(../IFEM-Elasticity Elasticity)
endif()
include_directories(../IFEM-Elasticity)
set(ELASTICITY_DIR ../IFEM-Elasticity)
elseif(EXISTS ${PROJECT_SOURCE_DIR}/../Elasticity)
set(ELASTICITY_DIR ../Elasticity)
else()
message(FATAL_ERROR "Need IFEM-Elasticity in a sibling directory.")
endif()

set(EXTRA_DOXY_PATHS "${EXTRA_DOXY_PATHS} \\
${PROJECT_SOURCE_DIR}/${ELASTICITY_DIR}")
if(NOT TARGET Elasticity)
add_subdirectory(${ELASTICITY_DIR} Elasticity)
endif()
include_directories(${ELASTICITY_DIR})

set(POROELASTIC_DIR ${PROJECT_SOURCE_DIR}/../IFEM-PoroElasticity/PoroElastic)
if(NOT EXISTS ${POROELASTIC_DIR})
set(POROELASTIC_DIR ${PROJECT_SOURCE_DIR}/../PoroElasticity/PoroElastic)
endif()

if(EXISTS ${POROELASTIC_DIR})
set(EXTRA_DOXY_PATHS "${EXTRA_DOXY_PATHS} \\
${PROJECT_SOURCE_DIR}/../Elasticity")
if(NOT TARGET Elasticity)
add_subdirectory(../Elasticity Elasticity)
${PROJECT_SOURCE_DIR}/${POROELASTIC_DIR}")
if(NOT TARGET PoroElastic)
add_subdirectory(${POROELASTIC_DIR} PoroElasticity)
endif()
include_directories(../Elasticity)
include_directories(${POROELASTIC_DIR})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DIFEM_HAS_POROELASTIC")
endif()

file(GLOB FracEl_SRCS [A-Z]*.C)
set(FracEl_SRCS FractureArgs.C CahnHilliard.C SIMExplPhaseField.C
FractureElasticity.C FractureElasticityVoigt.C)
if(EXISTS ${POROELASTIC_DIR})
set(FracEl_SRCS ${FracEl_SRCS} PoroFracture.C)
endif()

add_library(CommonFrac STATIC ${FracEl_SRCS})
set(Common_LIBRARIES CommonFrac Elasticity ${IFEM_LIBRARIES})
if(EXISTS ${POROELASTIC_DIR})
set(Fracture_LIBRARIES CommonFrac PoroElastic Elasticity ${IFEM_LIBRARIES})
else()
set(Fracture_LIBRARIES ${Common_LIBRARIES})
endif()

add_executable(CahnHilliard main_CahnHilliard.C)
add_executable(FractureDynamics main_FractureDynamics.C)

target_link_libraries(CahnHilliard CommonFrac Elasticity ${IFEM_LIBRARIES})
target_link_libraries(FractureDynamics CommonFrac Elasticity ${IFEM_LIBRARIES})
target_link_libraries(CahnHilliard ${Common_LIBRARIES})
target_link_libraries(FractureDynamics ${Fracture_LIBRARIES})

list(APPEND CHECK_SOURCES main_CahnHilliard.C main_FractureDynamics.C ${FracEl_SRCS})

Expand Down Expand Up @@ -86,7 +110,7 @@ list(APPEND TEST_APPS CahnHilliard FractureDynamics)
IFEM_add_test_app(${PROJECT_SOURCE_DIR}/Test/*.C
${PROJECT_SOURCE_DIR}/Test
FractureDynamics
CommonFrac Elasticity ${IFEM_LIBRARIES})
${Fracture_LIBRARIES})

if(IFEM_COMMON_APP_BUILD)
set(TEST_APPS ${TEST_APPS} PARENT_SCOPE)
Expand Down
9 changes: 9 additions & 0 deletions FractureArgs.C
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ FractureArgs::FractureArgs () : SIMargsBase("fracturedynamics")
{
inpfile = nullptr;
integrator = coupling = 1;
poroEl = expPhase = false;
}


Expand All @@ -41,6 +42,10 @@ bool FractureArgs::parseArg (const char* argv)
integrator = 4;
else if (!strcmp(argv,"-oldHHT"))
integrator = 5;
else if (!strncmp(argv,"-poro",5))
poroEl = true;
else if (!strncmp(argv,"-explcr",7))
expPhase = true;
else if (!strncmp(argv,"-noadap",7))
adap = false;
else
Expand Down Expand Up @@ -78,6 +83,10 @@ bool FractureArgs::parse (const TiXmlElement* elem)
integrator = 4;
else if (!strcasecmp(child->Value(),"hilberhughestaylor"))
integrator = 4;
else if (!strcasecmp(child->Value(),"poroelastic"))
poroEl = true;
else if (!strcasecmp(child->Value(),"explicitphase"))
expPhase = true;
}

return this->SIMargsBase::parse(elem);
Expand Down
2 changes: 2 additions & 0 deletions FractureArgs.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ class FractureArgs : public SIMargsBase
//! 4=nonlinear Hilber-Hughes-Taylor)
char integrator;
char coupling; //!< Coupling flag (0: none, 1: staggered, 2: semi-implicit)
bool poroEl; //!< If \e true, use the poroelastic solver
bool expPhase; //!< If \e true, use an explicit phase field

//! \brief Default constructor.
FractureArgs();
Expand Down
85 changes: 74 additions & 11 deletions FractureElasticity.C
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ FractureElasticity::FractureElasticity (IntegrandBase* parent,
parent->registerVector("phasefield",&myCVec);
// Assuming second vector is pressure, third vector is pressure velocity
eC = 3; // and fourth vector is the phase field
npv = nsd+1; // Account for pressure variables in the primary solution vector
}


Expand Down Expand Up @@ -121,6 +122,19 @@ void FractureElasticity::printLog () const
}


void FractureElasticity::setMode (SIM::SolutionMode mode)
{
this->Elasticity::setMode(mode);
if (eC <= 1) return; // no parent integrand

eKg = 0; // No geometric stiffness (assuming linear behaviour)
eM = eS = 0; // Inertia and external forces are calculated by parent integrand
if (eKm) eKm = 2; // Index for stiffness matrix in parent integrand
if (iS) iS = 2; // Index for internal force vector in parent integrand
eC = mode == SIM::DYNAMIC ? 5 : 3; // include velocity & acceleration vectors
}


void FractureElasticity::initIntegration (size_t nGp, size_t)
{
// Initialize internal tensile energy buffer
Expand Down Expand Up @@ -508,12 +522,11 @@ bool FractureElasticity::evalInt (LocalIntegral& elmInt,
}


bool FractureElasticity::evalSol (Vector& s,
const FiniteElement& fe, const Vec3& X,
const std::vector<int>& MNPC) const
bool FractureElasticity::getElementSolution (Vectors& eV,
const std::vector<int>& MNPC) const
{
// Extract element displacements
Vectors eV(1+eC);
eV.resize(1+eC);
int ierr = 0;
if (!mySol.empty() && !mySol.front().empty())
ierr = utl::gather(MNPC,nsd,mySol.front(),eV.front());
Expand All @@ -522,14 +535,21 @@ bool FractureElasticity::evalSol (Vector& s,
if (!myCVec.empty() && ierr == 0)
ierr = utl::gather(MNPC,1,myCVec,eV[eC]);

if (ierr > 0)
{
std::cerr <<" *** FractureElasticity::evalSol: Detected "<< ierr
<<" node numbers out of range."<< std::endl;
return false;
}
if (ierr == 0)
return true;

return this->evalSol2(s,eV,fe,X);
std::cerr <<" *** FractureElasticity::getElementSolution: Detected "<< ierr
<<" node numbers out of range."<< std::endl;
return false;
}


bool FractureElasticity::evalSol (Vector& s,
const FiniteElement& fe, const Vec3& X,
const std::vector<int>& MNPC) const
{
Vectors eV(1+eC);
return this->getElementSolution(eV,MNPC) && this->evalSol2(s,eV,fe,X);
}


Expand Down Expand Up @@ -621,6 +641,49 @@ bool FractureElasticity::evalSol (Vector& s, const Vectors& eV,
}


double FractureElasticity::evalPhaseField (Vec3& gradD,
const Vectors& eV,
const Vector& N,
const Matrix& dNdX) const
{
if (eV.size() <= eC)
{
std::cerr <<" *** FractureElasticity::evalPhaseField:"
<<" Missing phase field solution vector."<< std::endl;
return -1.1;

}
else if (eV[eC].empty()) // No phase field ==> no crack yet
{
gradD = 0.0;
return 0.0;
}
else if (eV[eC].size() != N.size())
{
std::cerr <<" *** FractureElasticity::evalPhaseField:"
<<" Invalid phase field vector.\n size(eC) = "
<< eV[eC].size() <<" size(N) = "<< N.size() << std::endl;
return -1.2;
}

// Invert the nodal phase field values, D = 1 - C,
// since that is the convention used in the Miehe papers
Vector eD(eV[eC].size()), tmp(nsd);
for (size_t i = 0; i < eD.size(); i++)
eD[i] = 1.0 - eV[eC][i];

// Compute the phase field gradient, dD/dX
if (dNdX.multiply(eD,tmp,true))
gradD = tmp;
else
return -2.0;

// Compute the phase field value, filtering out values outside [0.0,1.0]
double d = eD.dot(N);
return d > 1.0 ? 1.0 : (d < 0.0 ? 0.0 : d);
}


size_t FractureElasticity::getNoFields (int fld) const
{
return this->Elasticity::getNoFields(fld) + (fld == 2 ? 4 : 0);
Expand Down
19 changes: 19 additions & 0 deletions FractureElasticity.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ class FractureElasticity : public Elasticity
//! \brief Sets the number of solution variables per node.
void setVar(unsigned short int n) { npv = n; }

//! \brief Defines the solution mode before the element assembly is started.
//! \param[in] mode The solution mode to use
virtual void setMode(SIM::SolutionMode mode);

//! \brief Returns whether this norm has explicit boundary contributions.
virtual bool hasBoundaryTerms() const { return m_mode != SIM::RECOVERY; }

Expand Down Expand Up @@ -96,6 +100,21 @@ class FractureElasticity : public Elasticity
virtual bool evalSol(Vector& s, const Vectors& eV, const FiniteElement& fe,
const Vec3& X, bool toLocal, Vec3* pdir) const;

//! \brief Retrieves the element solution vectors.
//! \param[out] eV Element solution vectors
//! \param[in] MNPC Nodal point correspondance for the basis function values
virtual bool getElementSolution(Vectors& eV,
const std::vector<int>& MNPC) const;

//! \brief Evaluates the phase field and gradient at current point.
//! \param[out] gradD Phase field gradient at current point
//! \param[in] eV Element solution vectors
//! \param[in] N Basis function values at current point
//! \param[in] dNdX Basis function gradients at current point
//! \return Phase field value at current point
double evalPhaseField(Vec3& gradD, const Vectors& eV,
const Vector& N, const Matrix& dNdX) const;

//! \brief Returns a pointer to the Gauss-point tensile energy array.
virtual const RealArray* getTensileEnergy() const { return &myPhi; }

Expand Down
Loading