Skip to content

Commit

Permalink
Merge pull request #13 from gjkennedy/master
Browse files Browse the repository at this point in the history
fixed tmr to use the updated cython TACSVec
  • Loading branch information
gjkennedy authored Apr 19, 2023
2 parents ce2ad27 + afbb6dd commit 364bc71
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 22 deletions.
55 changes: 43 additions & 12 deletions src/topology/TMRTopoProblem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,9 @@ TMRTopoProblem::TMRTopoProblem(TMRTopoFilter *_filter, TACSMg *_mg,

// The multigrid object
mg = _mg;
mg->incref();
if (mg) {
mg->incref();
}

// Set the number of variables per node
design_vars_per_node = assembler->getDesignVarsPerNode();
Expand All @@ -192,13 +194,17 @@ TMRTopoProblem::TMRTopoProblem(TMRTopoFilter *_filter, TACSMg *_mg,
MPI_Comm_rank(assembler->getMPIComm(), &mpi_rank);

// Set up the solver
int nrestart = 5;
int is_flexible = 0;
double atol = 1e-30;
ksm = new GMRES(mg->getMat(0), mg, gmres_iters, nrestart, is_flexible);
ksm->incref();
ksm->setMonitor(new KSMPrintStdout("GMRES", mpi_rank, 10));
ksm->setTolerances(rtol, atol);
if (mg) {
int nrestart = 5;
int is_flexible = 0;
double atol = 1e-30;
ksm = new GMRES(mg->getMat(0), mg, gmres_iters, nrestart, is_flexible);
ksm->incref();
ksm->setMonitor(new KSMPrintStdout("GMRES", mpi_rank, 10));
ksm->setTolerances(rtol, atol);
} else {
ksm = NULL;
}

// Set the iteration count
iter_count = 0;
Expand Down Expand Up @@ -282,8 +288,12 @@ TMRTopoProblem::~TMRTopoProblem() {
}

// Free the solver/multigrid information
mg->decref();
ksm->decref();
if (mg) {
mg->decref();
}
if (ksm) {
ksm->decref();
}

dfdu->decref();
adjoint->decref();
Expand Down Expand Up @@ -416,6 +426,13 @@ void TMRTopoProblem::setPrefix(const char *_prefix) {
Set the load cases for each problem
*/
void TMRTopoProblem::setLoadCases(TACSBVec **_forces, int _num_load_cases) {
if (!mg) {
fprintf(stderr,
"TMRTopoProblem: Cannot call setLoadCases, multigrid object not "
"defined\n");
return;
}

// Pre-incref the input forces
for (int i = 0; i < _num_load_cases; i++) {
if (_forces[i]) {
Expand Down Expand Up @@ -572,6 +589,13 @@ void TMRTopoProblem::addFrequencyConstraint(
TacsScalar scale, int max_subspace_size, double eigtol, int use_jd,
int fgmres_size, double eig_rtol, double eig_atol, int num_recycle,
JDRecycleType recycle_type) {
if (!mg) {
fprintf(stderr,
"TMRTopoProblem: Cannot call addFrequencyConstraint, multigrid "
"object not defined\n");
return;
}

if (!freq) {
// Create a mass matrix for the frequency constraint
TACSMat *mmat = assembler->createMat();
Expand Down Expand Up @@ -613,6 +637,13 @@ void TMRTopoProblem::addBucklingConstraint(double sigma, int num_eigvals,
TacsScalar ks_weight,
TacsScalar offset, TacsScalar scale,
int max_lanczos, double eigtol) {
if (!mg) {
fprintf(stderr,
"TMRTopoProblem: Cannot call addBucklingConstraint, multigrid "
"object not defined\n");
return;
}

if (!buck) {
// Create a geometric stiffness matrix for buckling constraint
TACSMat *gmat = assembler->createMat();
Expand Down Expand Up @@ -911,7 +942,7 @@ int TMRTopoProblem::evalObjCon(ParOptVec *pxvec, ParOptScalar *fobj,
*fobj = fcallback;
}

if (num_load_cases > 0) {
if (num_load_cases > 0 && mg) {
// Zero the variables
assembler->zeroVariables();

Expand Down Expand Up @@ -1152,7 +1183,7 @@ int TMRTopoProblem::evalObjConGradient(ParOptVec *xvec, ParOptVec *gvec,
// Evaluate the gradient of the objective. If no objective functions are
// set, the weighted sum of the compliance is used. Otherwise the weighted
// sum of the objective functions from each load case are used
if (obj_funcs) {
if (obj_funcs && mg) {
for (int i = 0; i < num_load_cases; i++) {
assembler->setVariables(vars[i]);

Expand Down
39 changes: 29 additions & 10 deletions tmr/TMR.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -5165,7 +5165,10 @@ cdef void writeOutputCallback(void *func, const char *prefix, int iter,
cdef void constraintCallback(void *func, TMRTopoFilter *fltr, TACSMg *mg,
int ncon, TacsScalar *cvals):
try:
cons = (<object>func).__call__(_init_TopoFilter(fltr), _init_Mg(mg))
mgobj = None
if mg != NULL:
mgobj = _init_Mg(mg)
cons = (<object>func).__call__(_init_TopoFilter(fltr), mgobj)
for i in range(min(len(cons), ncon)):
cvals[i] = cons[i]
except:
Expand All @@ -5177,10 +5180,13 @@ cdef void constraintCallback(void *func, TMRTopoFilter *fltr, TACSMg *mg,
cdef void constraintGradientCallback(void *func, TMRTopoFilter *fltr, TACSMg *mg,
int ncon, TACSBVec **dcdx):
try:
mgobj = None
if mg != NULL:
mgobj = _init_Mg(mg)
vecs = []
for i in range(ncon):
vecs.append(_init_Vec(dcdx[i]))
(<object>func).__call__(_init_TopoFilter(fltr), _init_Mg(mg), vecs)
(<object>func).__call__(_init_TopoFilter(fltr), mgobj, vecs)
except:
tb = traceback.format_exc()
print(tb)
Expand All @@ -5190,7 +5196,10 @@ cdef void constraintGradientCallback(void *func, TMRTopoFilter *fltr, TACSMg *mg
cdef void objectiveCallback(void *func, TMRTopoFilter *fltr, TACSMg *mg,
TacsScalar *fobj):
try:
fobj[0] = (<object>func).__call__(_init_TopoFilter(fltr), _init_Mg(mg))
mgobj = None
if mg != NULL:
mgobj = _init_Mg(mg)
fobj[0] = (<object>func).__call__(_init_TopoFilter(fltr), mgobj)
except:
tb = traceback.format_exc()
print(tb)
Expand All @@ -5200,8 +5209,12 @@ cdef void objectiveCallback(void *func, TMRTopoFilter *fltr, TACSMg *mg,
cdef void objectiveGradientCallback(void *func, TMRTopoFilter *fltr, TACSMg *mg,
TACSBVec *dfdx):
try:
mgobj = None
if mg != NULL:
mgobj = _init_Mg(mg)

vec = _init_Vec(dfdx)
(<object>func).__call__(_init_TopoFilter(fltr), _init_Mg(mg), vec)
(<object>func).__call__(_init_TopoFilter(fltr), mgobj, vec)
except:
tb = traceback.format_exc()
print(tb)
Expand All @@ -5217,14 +5230,15 @@ cdef class TopoProblem(ProblemBase):
cdef object congradfunc
cdef object objfunc
cdef object objgradfunc
def __cinit__(self, TopoFilter fltr, Pc pc,
def __cinit__(self, TopoFilter fltr, pc=None,
int gmres_subspace=50, double rtol=1e-9):
cdef TACSMg *mg = NULL

# Check for a multigrid preconditioner
mg = _dynamicTACSMg(pc.ptr)
if mg == NULL:
raise ValueError('TopoProblem requires a TACSMg preconditioner')
if pc is not None:
# Check for a multigrid preconditioner
mg = _dynamicTACSMg((<Pc>pc).ptr)
if mg == NULL:
raise ValueError('TopoProblem requires a TACSMg preconditioner')

self.callback = None
self.confunc = None
Expand Down Expand Up @@ -5311,13 +5325,18 @@ cdef class TopoProblem(ProblemBase):
Mg: geometric multigrid object associated with the TopoProblem
"""
cdef TMRTopoProblem *prob = NULL
cdef TACSMg *mg = NULL

prob = _dynamicTopoProblem(self.ptr)
if prob == NULL:
errmsg = 'Expected TMRTopoProblem got other type'
raise ValueError(errmsg)

return _init_Mg(prob.getMg())
mg = prob.getMg()
if mg != NULL:
return _init_Mg(prob.getMg())

return None

def setF5OutputFlags(self, int freq, ElementType elem_type, int flag):
"""
Expand Down

0 comments on commit 364bc71

Please sign in to comment.