Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
262c857
Updated fils_struct.hpp to include a flag for
dseyler Nov 6, 2024
338486e
Added additional member variables associated with virtual faces
dseyler Nov 6, 2024
dea38e0
Updated fsils_bc_create to support virtual surface
dseyler Nov 7, 2024
5fbf4fb
Bug Fixes (NOT COMPLETE)
dseyler Nov 15, 2024
73e71f6
Updated several files to accomodate virtual surfaces
dseyler Feb 12, 2025
dc877cd
Added new test case for virtual surface cap
dseyler Feb 13, 2025
7c4ab5f
Updated README.md for LV_NeoHookean_passive_sv0D_capped
dseyler Feb 13, 2025
59ed2da
Merge branch '3D0DCouplingCap'
dseyler Feb 13, 2025
31af55e
Merge pull request #1 from dseyler/main
dseyler Feb 13, 2025
168a140
Added a few more functions for virtual capping
dseyler Feb 25, 2025
fca7f47
Fixed compilation errors in the code
dseyler Mar 5, 2025
2665879
Co-authored-by: Aaron Brown <[email protected]>
dseyler May 11, 2025
e0340ac
Merge branch 'SimVascular:main' into 3D0DCouplingCap
dseyler May 12, 2025
c7797cd
Merge branch 'SimVascular:main' into 3D0DCouplingCap
dseyler May 17, 2025
91802e1
Merge branch 'SimVascular:main' into 3D0DCouplingCap
dseyler May 19, 2025
f944e98
Removed debugging print statements from add_bc_mul.cpp
dseyler May 19, 2025
55af584
Merge branch 'SimVascular:main' into 3D0DCouplingCap
dseyler Jun 6, 2025
7945d6e
Merge main into 3D0DCouplingCap - resolved conflict in ComMod.cpp
dseyler Aug 22, 2025
2bfc8b7
Merge branch 'SimVascular:main' into 3D0DCouplingCap
dseyler Aug 25, 2025
944b0c8
merged main with this branch
dseyler Sep 29, 2025
fa7f300
merged main into 3D0D Coupling branch and added some test case proces…
dseyler Sep 29, 2025
4be201c
Fixed several bugs, decluttered commenting, and renamed GatherMaster …
dseyler Oct 3, 2025
276749c
Changed "virtual surface" to "cap surface." Added support for svZeroD…
dseyler Oct 7, 2025
18c5611
Fixed compilation error
dseyler Oct 7, 2025
5b06340
Merge branch 'SimVascular:main' into 3D0DCouplingCap
dseyler Oct 7, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,6 @@ Q_svZeroD
P_svZeroD
# local svZeroD build
svZeroDSolver

# test artifacts (VTK, processed results)
tests/**/calc_volume_struct_output/
64 changes: 62 additions & 2 deletions Code/Source/liner_solver/add_bc_mul.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ void add_bc_mul(FSILS_lhsType& lhs, const BcopType op_Type, const int dof, const
Vector<double> coef(lhs.nFaces);
Array<double> v(dof,lhs.nNo);

//Setting coef depending on adding resistance to stiffness or
//computing preconditioner

if (op_Type == BcopType::BCOP_TYPE_ADD) {
for (int i = 0; i < lhs.nFaces; i++) {
coef(i) = lhs.face[i].res;
Expand All @@ -70,6 +73,25 @@ void add_bc_mul(FSILS_lhsType& lhs, const BcopType op_Type, const int dof, const

for (int faIn = 0; faIn < lhs.nFaces; faIn++) {
auto& face = lhs.face[faIn];
// Cap faces do not contribute to the tangent matrix
if (face.isCap) {
continue;
}

// In the following calculations, we are computing the product of the
// coupled BC tangent contribution with the vector X (refer to Moghadam
// et al. 2013 eq. 27). This is computed by first constructing the vector
// v, which one of the integrals found in the expression, int{N_A * n_i} dGamma.
// Then, v is dotted with X to yield a quantity S. Then S is multiplied by
// by v again, and also multiplied by the appropriate coefficients in
// the expression.
// The calculations are complicated somewhat if there is a capping surface,
// but these complications are explained below.


// Calculating S, which is the inner product of the right integral (v) and
// the vector to be multiplied (X).

int nsd = std::min(face.dof, dof);

if (face.coupledFlag) {
Expand All @@ -85,15 +107,32 @@ void add_bc_mul(FSILS_lhsType& lhs, const BcopType op_Type, const int dof, const
}
// Computing S = coef * v^T * X
double S = coef(faIn) * dot::fsils_dot_v(dof, lhs.mynNo, lhs.commu, v, X);

// Add cap surface contribution to S
// Cap surfaces contribute to flow rate but not pressure
if (face.isCapped) {
int faInCap = face.faInCap;
auto& faceCap = lhs.face[faInCap];

Array<double> vcap(dof,lhs.nNo);
vcap = 0.0;
for (int a = 0; a < faceCap.nNo; a++) {
int Ac = faceCap.glob(a);
for (int i = 0; i < nsd; i++) {
vcap(i,Ac) = faceCap.valM(i,a);
}
}
// Add capping surface contribution to S
S = S + coef(faIn) * dot::fsils_dot_v(dof, lhs.mynNo, lhs.commu, vcap, X);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code in the if (face.faInCap != -1) { block should be in a function or better it should be a method in a class.


// Computing Y = Y + v * S
for (int a = 0; a < face.nNo; a++) {
int Ac = face.glob(a);
for (int i = 0; i < nsd; i++) {
Y(i,Ac) = Y(i,Ac) + v(i,Ac)*S;
}
}

}
// If face is not shared across procs
else {
Expand All @@ -105,8 +144,29 @@ void add_bc_mul(FSILS_lhsType& lhs, const BcopType op_Type, const int dof, const
S = S + face.valM(i,a)*X(i,Ac);
}
}
S = coef(faIn) * S;

// If capping surface is present add its contribution to S
if (face.isCapped) {
int faInCap = face.faInCap;
auto& faceCap = lhs.face[faInCap];

if (!faceCap.coupledFlag) {
std::cerr << "ADDBCMUL(): Cap face is not coupled. Probably cap face has zero resistance." << std::endl;
throw std::runtime_error("FSILS: FATAL ERROR");
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check this condition earlier ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is also now checked in baf_ini


for (int a = 0; a < faceCap.nNo; a++) {
int Ac = faceCap.glob(a);
for (int i = 0; i < nsd; i++) {
S = S + faceCap.valM(i,a)*X(i,Ac);
}
}
}

// Multiply S by the resistance or related quantity if
// preconditioning
S = coef(faIn) * S;

// Computing Y = Y + v * S
for (int a = 0; a < face.nNo; a++) {
int Ac = face.glob(a);
Expand Down
10 changes: 6 additions & 4 deletions Code/Source/liner_solver/bc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ namespace fsi_linear_solver {
/// lhs.face[faIn].valM
//
void fsils_bc_create(FSILS_lhsType& lhs, int faIn, int nNo, int dof, BcType BC_type, const Vector<int>& gNodes,
const Array<double>& Val)
const Array<double>& Val, bool isCap)
{
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When a developer first sees the variable named vrtual it's not clear what it means but then it looks like the c++ virtual keyword which is confusing.

If this has something do with a coupling cap then name it to reflect that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking of changing the name of the bool to isCapSurface and removing mentions of the word "virtual" so as not to confuse users

using namespace consts;

Expand All @@ -60,6 +60,7 @@ void fsils_bc_create(FSILS_lhsType& lhs, int faIn, int nNo, int dof, BcType BC_t
dmsg << "Val.size(): " << Val.size();
dmsg << "Val.nrows: " << Val.nrows_;
dmsg << "Val.ncols: " << Val.ncols_;
dmsg << "isCap: " << isCap;
#endif

if (faIn >= lhs.nFaces) {
Expand All @@ -71,9 +72,12 @@ void fsils_bc_create(FSILS_lhsType& lhs, int faIn, int nNo, int dof, BcType BC_t
throw std::runtime_error("FSILS: faIn is smaller than zero");
}

lhs.face[faIn].foC = true;
lhs.face[faIn].nNo = nNo;
lhs.face[faIn].dof = dof;
lhs.face[faIn].bGrp = BC_type;
// Set cap flag for face
lhs.face[faIn].isCap = isCap;

lhs.face[faIn].glob.resize(nNo);
lhs.face[faIn].val.resize(dof,nNo);
Expand Down Expand Up @@ -116,7 +120,6 @@ void fsils_bc_create(FSILS_lhsType& lhs, int faIn, int nNo, int dof, BcType BC_t
v(i,Ac) = lhs.face[faIn].val(i,a);
}
}

fsils_commuv(lhs, dof, v);

for (int a = 0; a < nNo; a++) {
Expand Down Expand Up @@ -184,9 +187,8 @@ void fsils_bc_update(FSILS_lhsType& lhs, int faIn, int nNo, int dof, const Array
}

// Communicate update among procs
if (lhs.face[faIn].sharedFlag){
if (lhs.face[faIn].sharedFlag && !lhs.face[faIn].isCap) {
Array<double> v(dof,lhs.nNo);
v = 0.0;

for (int a = 0; a < nNo; a++) {
int Ac = lhs.face[faIn].glob(a);
Expand Down
15 changes: 15 additions & 0 deletions Code/Source/liner_solver/fils_struct.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,21 @@ class FSILS_faceType

/// Neu W*Sai (TMP)
Array<double> valM;

/// Flag for cap face (USE)
bool isCap = false;

/// Index of mesh in msh associated with this face
int iM = -1;

/// Index of face in msh[iM].fa that caps this face
int iFa = -1;

/// Index of face in lhs.face that caps this face
int faInCap = -1;

/// Flag indicating if this face is capped by another face
bool isCapped = false;
};

/// @brief Modified in:
Expand Down
2 changes: 1 addition & 1 deletion Code/Source/liner_solver/fsils_api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
namespace fsi_linear_solver {

void fsils_bc_create(FSILS_lhsType& lhs, int faIn, int nNo, int dof, BcType BC_type, const Vector<int>& gNodes,
const Array<double>& Val);
const Array<double>& Val, bool isCap = false);

void fsils_bc_create(FSILS_lhsType& lhs, int faIn, int nNo, int dof, BcType BC_type, const Vector<int>& gNodes);

Expand Down
22 changes: 20 additions & 2 deletions Code/Source/solver/ComMod.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ class fcType
{
public:

bool defined() { return n != 0; };
bool defined() const { return n != 0; };

// If this is a ramp function
bool lrmp = false;
Expand Down Expand Up @@ -109,7 +109,7 @@ class MBType
{
public:

bool defined() { return dof != 0; };
bool defined() const { return dof != 0; };

// Degrees of freedom of d(:,.,.)
int dof = 0;
Expand Down Expand Up @@ -180,6 +180,15 @@ class bcType
// Pointer to FSILS%bc
int lsPtr = -1;

// Index of cap BC associated wtih this BC
int iCapBC = -1;

// Flag indicating if this BC has a capping BC
bool hasCapBC = false;

// Name of face that caps this surface
std::string capName;

// Undeforming Neu BC master-slave node parameters.
int masN = 0;

Expand Down Expand Up @@ -544,6 +553,9 @@ class faceType

//faceType& operator=(const faceType& rhs);

// Flag for cap face (i.e. face does not lie on volume mesh)
bool isCap = false;

// Parametric direction normal to this face (NURBS)
int d = 0;

Expand Down Expand Up @@ -571,6 +583,9 @@ class faceType
// Number of nodes
int nNo = 0;

//ID number of cap face that caps this face
int capID = -1;

// Global element Ids
Vector<int> gE;

Expand Down Expand Up @@ -919,6 +934,9 @@ class mshType
/// @brief Whether the mesh is fibers (Purkinje)
bool lFib = false;

/// @brief Whether the mesh is a cap
bool isCap = false;

/// @brief Element type
consts::ElementType eType = consts::ElementType::NA;
//int eType = eType_NA
Expand Down
4 changes: 4 additions & 0 deletions Code/Source/solver/Parameters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,9 @@ BoundaryConditionParameters::BoundaryConditionParameters()
set_parameter("Zero_out_perimeter", false, !required, zero_out_perimeter);

set_parameter("Resistance", 1.e5, !required, resistance);

set_parameter("Capping_face", "", !required, capping_face);
set_parameter("cap_svZeroDSolver_block", "", !required, cap_svzerod_solver_block);
}

void BoundaryConditionParameters::print_parameters()
Expand Down Expand Up @@ -2275,6 +2278,7 @@ FaceParameters::FaceParameters()

set_parameter("End_nodes_face_file_path", "", !required, end_nodes_face_file_path);
set_parameter("Face_file_path", "", !required, face_file_path);
set_parameter("Cap", false, !required, cap_face);

set_parameter("Quadrature_modifier_TRI3", (2.0/3.0), !required, quadrature_modifier_TRI3);
}
Expand Down
4 changes: 4 additions & 0 deletions Code/Source/solver/Parameters.h
Original file line number Diff line number Diff line change
Expand Up @@ -821,6 +821,9 @@ class BoundaryConditionParameters : public ParameterLists
Parameter<bool> zero_out_perimeter;

Parameter<double> resistance;

Parameter<std::string> capping_face;
Parameter<std::string> cap_svzerod_solver_block;
};

/// @brief The OutputParameters class stores parameters for the
Expand Down Expand Up @@ -1462,6 +1465,7 @@ class FaceParameters : public ParameterLists
Parameter<std::string> end_nodes_face_file_path;
Parameter<std::string> face_file_path;
Parameter<std::string> name;
Parameter<bool> cap_face;

Parameter<double> quadrature_modifier_TRI3;
};
Expand Down
Loading
Loading