Skip to content

Commit 3853908

Browse files
committed
Removed linesearch timer and added timings to update timer. Overrode some rigid domain functions to avoid performance penalty. Made performance improvements to FEOctree and FENormalProjection. Added omp pragmas in certain places.
1 parent 7d6b78b commit 3853908

13 files changed

Lines changed: 249 additions & 96 deletions

FEBioLib/FEBioModel.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1785,7 +1785,6 @@ TimingInfo FEBioModel::GetTimingInfo()
17851785
ti.total_stiff = GetTimer(TimerID::Timer_Stiffness )->GetExclusiveTime(); total += ti.total_stiff;
17861786
ti.total_rhs = GetTimer(TimerID::Timer_Residual )->GetExclusiveTime(); total += ti.total_rhs;
17871787
ti.total_update = GetTimer(TimerID::Timer_Update )->GetExclusiveTime(); total += ti.total_update;
1788-
ti.total_line_search = GetTimer(TimerID::Timer_LineSearch )->GetExclusiveTime(); total += ti.total_line_search;
17891788
ti.total_qn = GetTimer(TimerID::Timer_QNUpdate )->GetExclusiveTime(); total += ti.total_qn;
17901789
ti.total_serialize = GetTimer(TimerID::Timer_Serialize )->GetExclusiveTime(); total += ti.total_serialize;
17911790
ti.total_callback = GetTimer(TimerID::Timer_Callback )->GetExclusiveTime(); total += ti.total_callback;
@@ -1858,7 +1857,6 @@ void FEBioModel::on_cb_solved()
18581857
Timer::time_str(ti.total_stiff , sztime); feLog("\t evaluating stiffness ......... : %s (%lg sec)\n\n", sztime, ti.total_stiff);
18591858
Timer::time_str(ti.total_rhs , sztime); feLog("\t evaluating residual .......... : %s (%lg sec)\n\n", sztime, ti.total_rhs);
18601859
Timer::time_str(ti.total_update , sztime); feLog("\t model update ................. : %s (%lg sec)\n\n", sztime, ti.total_update);
1861-
Timer::time_str(ti.total_line_search, sztime); feLog("\t line search .................. : %s (%lg sec)\n\n", sztime, ti.total_line_search);
18621860
Timer::time_str(ti.total_qn , sztime); feLog("\t QN updates ................... : %s (%lg sec)\n\n", sztime, ti.total_qn);
18631861
Timer::time_str(linsol_time , sztime); feLog("\t time in linear solver ........ : %s (%lg sec)\n\n", sztime, linsol_time);
18641862
Timer::time_str(ti.total_time , sztime); feLog("\tTotal elapsed time .............. : %s (%lg sec)\n\n", sztime, ti.total_time);

FEBioLib/febiolib_types.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ struct TimingInfo {
4646
double total_rhs = 0;
4747
double total_update = 0;
4848
double total_qn = 0;
49-
double total_line_search = 0;
5049
double total_serialize = 0;
5150
double total_callback = 0;
5251
double total_other = 0;

FEBioMech/FERigidShellDomain.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,22 @@ void FERigidShellDomain::MassMatrix(FELinearSystem& LS, double scale)
359359
// nothing to do here
360360
}
361361

362+
void FERigidShellDomain::Serialize(DumpStream& ar)
363+
{
364+
// we bypass FEDomain::Serialize since we don't need to serialize anything for the rigid shells
365+
FEMeshPartition::Serialize(ar);
366+
}
367+
368+
void FERigidShellDomain::PreSolveUpdate(const FETimeInfo& timeInfo)
369+
{
370+
// nothing to do here
371+
}
372+
373+
void FERigidShellDomain::BuildMatrixProfile(FEGlobalMatrix& M)
374+
{
375+
// nothing to do here
376+
}
377+
362378
double FERigidShellDomain::detJ0(FEShellElement& el, int n)
363379
{
364380
vector<vec3d> X(FEElement::MAX_NODES);

FEBioMech/FERigidShellDomain.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,12 @@ class FERigidShellDomain : public FEShellDomain, public FEElasticDomain
9898
//! get the material (overridden from FEDomain)
9999
FEMaterial* GetMaterial() override;
100100

101+
void Serialize(DumpStream& ar) override;
102+
103+
void PreSolveUpdate(const FETimeInfo& timeInfo) override;
104+
105+
void BuildMatrixProfile(FEGlobalMatrix& M) override;
106+
101107
public: // from FEShellDomain
102108
// get a shell element
103109
FEShellElement& Element(int i) override { return m_Elem[i]; }

FEBioMech/FERigidSolidDomain.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,22 @@ void FERigidSolidDomain::Reset()
6464
// nothing to reset here
6565
}
6666

67+
void FERigidSolidDomain::Serialize(DumpStream& ar)
68+
{
69+
// we bypass FEDomain::Serialize since we don't need to serialize anything for the rigid solids
70+
FEMeshPartition::Serialize(ar);
71+
}
72+
73+
void FERigidSolidDomain::PreSolveUpdate(const FETimeInfo& timeInfo)
74+
{
75+
// nothing to do here
76+
}
77+
78+
void FERigidSolidDomain::BuildMatrixProfile(FEGlobalMatrix& M)
79+
{
80+
// nothing to do here
81+
}
82+
6783
//-----------------------------------------------------------------------------
6884
//! Calculates the stiffness matrix for 3D rigid elements.
6985
//! Rigid elements don't generate stress, so there is nothing to do here

FEBioMech/FERigidSolidDomain.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,13 @@ class FERigidSolidDomain : public FEElasticSolidDomain
4444
//! reset data
4545
void Reset() override;
4646

47+
//! serialization
48+
void Serialize(DumpStream& ar) override;
49+
50+
void PreSolveUpdate(const FETimeInfo& timeInfo) override;
51+
52+
void BuildMatrixProfile(FEGlobalMatrix& M) override;
53+
4754
public:
4855

4956
//! calculates the global stiffness matrix for this domain

FEBioMech/FERigidSolver.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1514,6 +1514,7 @@ void FERigidSolverNew::UpdateRigidBodies(vector<double>& Ui, vector<double>& ui)
15141514
// Since the rigid nodes are repositioned we need to update the displacement DOFS
15151515
FEMesh& mesh = m_fem->GetMesh();
15161516
int N = mesh.Nodes();
1517+
#pragma omp parallel for schedule(dynamic, 64)
15171518
for (int i = 0; i<N; ++i)
15181519
{
15191520
FENode& node = mesh.Node(i);

FEBioMech/FESolidSolver2.cpp

Lines changed: 49 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -663,37 +663,39 @@ void FESolidSolver2::UpdateIncrements(vector<double>& Ui, vector<double>& ui, bo
663663
m_rigidSolver.UpdateIncrements(Ui, ui, emap);
664664

665665
// update flexible nodes
666-
int n;
667-
for (int i=0; i<mesh.Nodes(); ++i)
666+
int NN = mesh.Nodes();
667+
#pragma omp parallel for
668+
for (int i=0; i<NN; ++i)
668669
{
669670
FENode& node = mesh.Node(i);
671+
const std::vector<int>& id = node.m_ID;
672+
int n;
670673

671674
// displacement dofs
672675
// current position = initial + total at prev conv step + total increment so far + current increment
673-
if ((n = node.m_ID[m_dofU[0]]) >= 0) Ui[n] += ui[n];
674-
if ((n = node.m_ID[m_dofU[1]]) >= 0) Ui[n] += ui[n];
675-
if ((n = node.m_ID[m_dofU[2]]) >= 0) Ui[n] += ui[n];
676+
if ((n = id[m_dofU[0]]) >= 0) Ui[n] += ui[n];
677+
if ((n = id[m_dofU[1]]) >= 0) Ui[n] += ui[n];
678+
if ((n = id[m_dofU[2]]) >= 0) Ui[n] += ui[n];
676679

677680
// beam rotations
681+
if ((id[m_dofQ[0]] >= 0) || (id[m_dofQ[1]] >= 0) || (id[m_dofQ[2]] >= 0))
678682
{
679683
vec3d ri, Ri;
680-
if ((n = node.m_ID[m_dofQ[0]]) >= 0) { ri.x = ui[n]; Ri.x = Ui[n]; }
681-
if ((n = node.m_ID[m_dofQ[1]]) >= 0) { ri.y = ui[n]; Ri.y = Ui[n]; }
682-
if ((n = node.m_ID[m_dofQ[2]]) >= 0) { ri.z = ui[n]; Ri.z = Ui[n]; }
684+
if ((n = id[m_dofQ[0]]) >= 0) { ri.x = ui[n]; Ri.x = Ui[n]; }
685+
if ((n = id[m_dofQ[1]]) >= 0) { ri.y = ui[n]; Ri.y = Ui[n]; }
686+
if ((n = id[m_dofQ[2]]) >= 0) { ri.z = ui[n]; Ri.z = Ui[n]; }
683687
quatd qi(ri), Qi(Ri);
684688
quatd Qn = qi * Qi;
685689
vec3d rn = Qn.GetRotationVector();
686-
if ((n = node.m_ID[m_dofQ[0]]) >= 0) { Ui[n] = rn.x; }
687-
if ((n = node.m_ID[m_dofQ[1]]) >= 0) { Ui[n] = rn.y; }
688-
if ((n = node.m_ID[m_dofQ[2]]) >= 0) { Ui[n] = rn.z; }
690+
if ((n = id[m_dofQ[0]]) >= 0) { Ui[n] = rn.x; }
691+
if ((n = id[m_dofQ[1]]) >= 0) { Ui[n] = rn.y; }
692+
if ((n = id[m_dofQ[2]]) >= 0) { Ui[n] = rn.z; }
689693
}
690694

691695
// shell dofs
692-
{
693-
if ((n = node.m_ID[m_dofSU[0]]) >= 0) Ui[n] += ui[n];
694-
if ((n = node.m_ID[m_dofSU[1]]) >= 0) Ui[n] += ui[n];
695-
if ((n = node.m_ID[m_dofSU[2]]) >= 0) Ui[n] += ui[n];
696-
}
696+
if ((n = id[m_dofSU[0]]) >= 0) Ui[n] += ui[n];
697+
if ((n = id[m_dofSU[1]]) >= 0) Ui[n] += ui[n];
698+
if ((n = id[m_dofSU[2]]) >= 0) Ui[n] += ui[n];
697699
}
698700

699701
for (int i = 0; i < fem.NonlinearConstraints(); ++i)
@@ -727,23 +729,26 @@ void FESolidSolver2::UpdateIncrements(vector<double>& Ui, vector<double>& ui, bo
727729
//! Updates the current state of the model
728730
void FESolidSolver2::Update(vector<double>& ui)
729731
{
730-
FEModel& fem = *GetFEModel();
731-
FETimeInfo& tp = fem.GetTime();
732-
tp.currentIteration = m_niter;
733-
734-
// update EAS
735-
UpdateEAS(ui);
736-
UpdateIncrementsEAS(ui, true);
732+
{
733+
TRACK_TIME(Timer_Update)
734+
FEModel& fem = *GetFEModel();
735+
FETimeInfo& tp = fem.GetTime();
736+
tp.currentIteration = m_niter;
737737

738-
// update kinematics
739-
UpdateKinematics(ui);
738+
// update EAS
739+
UpdateEAS(ui);
740+
UpdateIncrementsEAS(ui, true);
740741

741-
// update domains
742-
FEMesh& mesh = fem.GetMesh();
743-
for (int i = 0; i < mesh.Domains(); ++i)
744-
{
745-
FEDomain& dom = mesh.Domain(i);
746-
dom.IncrementalUpdate(ui, false);
742+
// update kinematics
743+
UpdateKinematics(ui);
744+
745+
// update domains
746+
FEMesh& mesh = fem.GetMesh();
747+
for (int i = 0; i < mesh.Domains(); ++i)
748+
{
749+
FEDomain& dom = mesh.Domain(i);
750+
dom.IncrementalUpdate(ui, false);
751+
}
747752
}
748753

749754
// update model state
@@ -864,7 +869,9 @@ void FESolidSolver2::PrepStep()
864869

865870
// store previous mesh state
866871
// we need them for velocity and acceleration calculations
867-
for (int i = 0; i < mesh.Nodes(); ++i)
872+
int NN = mesh.Nodes();
873+
#pragma omp parallel for
874+
for (int i = 0; i < NN; ++i)
868875
{
869876
FENode& ni = mesh.Node(i);
870877
ni.m_rp = ni.m_rt;
@@ -1616,25 +1623,27 @@ void FESolidSolver2::ExternalForces(FEGlobalVector& RHS)
16161623

16171624
// set the nodal reaction forces
16181625
// TODO: Is this a good place to do this?
1619-
for (int i = 0; i<mesh.Nodes(); ++i)
1626+
int NN = mesh.Nodes();
1627+
#pragma omp parallel for
1628+
for (int i = 0; i<NN; ++i)
16201629
{
16211630
FENode& node = mesh.Node(i);
1622-
node.set_load(m_dofU[0], 0);
1623-
node.set_load(m_dofU[1], 0);
1624-
node.set_load(m_dofU[2], 0);
16251631

16261632
int n;
16271633
if ((n = node.m_ID[m_dofU[0]]) >= 0) node.set_load(m_dofU[0], -m_Fr[n]);
1628-
if ((n = -node.m_ID[m_dofU[0]] - 2) >= 0) node.set_load(m_dofU[0], -m_Fr[n]);
1634+
else if ((n = -node.m_ID[m_dofU[0]] - 2) >= 0) node.set_load(m_dofU[0], -m_Fr[n]);
1635+
else node.set_load(m_dofU[0], 0);
16291636

16301637
if ((n = node.m_ID[m_dofU[1]]) >= 0) node.set_load(m_dofU[1], -m_Fr[n]);
1631-
if ((n = -node.m_ID[m_dofU[1]] - 2) >= 0) node.set_load(m_dofU[1], -m_Fr[n]);
1638+
else if ((n = -node.m_ID[m_dofU[1]] - 2) >= 0) node.set_load(m_dofU[1], -m_Fr[n]);
1639+
else node.set_load(m_dofU[1], 0);
16321640

16331641
if ((n = node.m_ID[m_dofU[2]]) >= 0) node.set_load(m_dofU[2], -m_Fr[n]);
1634-
if ((n = -node.m_ID[m_dofU[2]] - 2) >= 0) node.set_load(m_dofU[2], -m_Fr[n]);
1642+
else if ((n = -node.m_ID[m_dofU[2]] - 2) >= 0) node.set_load(m_dofU[2], -m_Fr[n]);
1643+
else node.set_load(m_dofU[2], 0);
16351644

16361645
// add nodal loads
1637-
double s = (m_arcLength>0 ? m_al_lam : 1.0);
1646+
// double s = (m_arcLength>0 ? m_al_lam : 1.0);
16381647
// if ((n = node.m_ID[m_dofU[0]]) >= 0) node.set_load(m_dofU[0], -m_Fn[n]*s);
16391648
// if ((n = node.m_ID[m_dofU[1]]) >= 0) node.set_load(m_dofU[1], -m_Fn[n]*s);
16401649
// if ((n = node.m_ID[m_dofU[2]]) >= 0) node.set_load(m_dofU[2], -m_Fn[n]*s);

FECore/FENewtonSolver.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -882,7 +882,6 @@ double FENewtonSolver::DoLineSearch()
882882
m_ls = 1.0;
883883
if (m_lineSearch && (m_lineSearch->m_LStol > 0.0))
884884
{
885-
TRACK_TIME(TimerID::Timer_LineSearch);
886885
m_ls = m_lineSearch->DoLineSearch();
887886
}
888887
else

FECore/FENormalProjection.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ void FENormalProjection::Init()
5050
//! of the intersection point. It searches for the closest patch based on
5151
//! algebraic value of the gap function
5252
//!
53+
//!
54+
/*
5355
FESurfaceElement* FENormalProjection::Project(vec3d r, vec3d n, double rs[2])
5456
{
5557
// let's find all the candidate surface elements
@@ -91,6 +93,44 @@ FESurfaceElement* FENormalProjection::Project(vec3d r, vec3d n, double rs[2])
9193
// we did not find a surface
9294
return 0;
9395
}
96+
*/
97+
98+
FESurfaceElement* FENormalProjection::Project(vec3d r, vec3d n, double rs[2])
99+
{
100+
bool found = false;
101+
102+
// now that we found candidate surface elements, lets see if we can find
103+
// those that intersect the ray, then pick the closest intersection
104+
double rsl[2], gl, g = 0;
105+
FESurfaceElement* pei = 0;
106+
m_OT.VisitIntersectedLeaves(r, n, m_rad, [&](int j) {
107+
// get the surface element
108+
// project the node on the element
109+
FESurfaceElement* pe = &m_surf.Element(j);
110+
if (pe->isActive())
111+
{
112+
if (m_surf.Intersect(*pe, r, n, rsl, gl, m_tol)) {
113+
if ((!found) && (gl > -m_rad)) {
114+
found = true;
115+
g = gl;
116+
rs[0] = rsl[0];
117+
rs[1] = rsl[1];
118+
pei = pe;
119+
}
120+
else if ((gl < g) && (gl > -m_rad)) {
121+
g = gl;
122+
rs[0] = rsl[0];
123+
rs[1] = rsl[1];
124+
pei = pe;
125+
}
126+
}
127+
}
128+
});
129+
if (found) return pei;
130+
131+
// we did not find a surface
132+
return 0;
133+
}
94134

95135
//-----------------------------------------------------------------------------
96136
//! This function finds the element which is intersected by the ray (r,n).

0 commit comments

Comments
 (0)