00001
00002
00003
00004
00005
00006
00007 #include "Albany_SolutionMaxValueResponseFunction.hpp"
00008 #include "Epetra_Comm.h"
00009
00010 Albany::SolutionMaxValueResponseFunction::
00011 SolutionMaxValueResponseFunction(const Teuchos::RCP<const Epetra_Comm>& comm,
00012 int neq_, int eq_, bool interleavedOrdering_) :
00013 SamplingBasedScalarResponseFunction(comm),
00014 neq(neq_), eq(eq_), interleavedOrdering(interleavedOrdering_)
00015 {
00016 }
00017
00018 Albany::SolutionMaxValueResponseFunction::
00019 ~SolutionMaxValueResponseFunction()
00020 {
00021 }
00022
00023 unsigned int
00024 Albany::SolutionMaxValueResponseFunction::
00025 numResponses() const
00026 {
00027 return 1;
00028 }
00029
00030 void
00031 Albany::SolutionMaxValueResponseFunction::
00032 evaluateResponse(const double current_time,
00033 const Epetra_Vector* xdot,
00034 const Epetra_Vector* xdotdot,
00035 const Epetra_Vector& x,
00036 const Teuchos::Array<ParamVec>& p,
00037 Epetra_Vector& g)
00038 {
00039 int index;
00040 computeMaxValue(x, g[0], index);
00041 }
00042
00043 void
00044 Albany::SolutionMaxValueResponseFunction::
00045 evaluateTangent(const double alpha,
00046 const double beta,
00047 const double omega,
00048 const double current_time,
00049 bool sum_derivs,
00050 const Epetra_Vector* xdot,
00051 const Epetra_Vector* xdotdot,
00052 const Epetra_Vector& x,
00053 const Teuchos::Array<ParamVec>& p,
00054 ParamVec* deriv_p,
00055 const Epetra_MultiVector* Vxdot,
00056 const Epetra_MultiVector* Vxdotdot,
00057 const Epetra_MultiVector* Vx,
00058 const Epetra_MultiVector* Vp,
00059 Epetra_Vector* g,
00060 Epetra_MultiVector* gx,
00061 Epetra_MultiVector* gp)
00062 {
00063 Teuchos::RCP<Epetra_MultiVector> dgdx;
00064 if (gx != NULL && Vx != NULL)
00065 dgdx = Teuchos::rcp(new Epetra_MultiVector(x.Map(), 1));
00066 else
00067 dgdx = Teuchos::rcp(gx,false);
00068 evaluateGradient(current_time, xdot, xdotdot, x, p, deriv_p, g, dgdx.get(), NULL, NULL, gp);
00069 if (gx != NULL && Vx != NULL)
00070 gx->Multiply('T', 'N', alpha, *dgdx, *Vx, 0.0);
00071 }
00072
00073 void
00074 Albany::SolutionMaxValueResponseFunction::
00075 evaluateGradient(const double current_time,
00076 const Epetra_Vector* xdot,
00077 const Epetra_Vector* xdotdot,
00078 const Epetra_Vector& x,
00079 const Teuchos::Array<ParamVec>& p,
00080 ParamVec* deriv_p,
00081 Epetra_Vector* g,
00082 Epetra_MultiVector* dg_dx,
00083 Epetra_MultiVector* dg_dxdot,
00084 Epetra_MultiVector* dg_dxdotdot,
00085 Epetra_MultiVector* dg_dp)
00086 {
00087 int global_index;
00088 double mxv;
00089 computeMaxValue(x, mxv, global_index);
00090
00091
00092 if (g != NULL)
00093 (*g)[0] = mxv;
00094
00095
00096 if (dg_dx != NULL) {
00097 int im = -1;
00098 for (int i=0; i<x.Map().NumMyElements(); i++) {
00099 if (x[i] == mxv) { (*dg_dx)[0][i] = 1.0; im = i; }
00100 else (*dg_dx)[0][i] = 0.0;
00101 }
00102
00103 }
00104
00105
00106 if (dg_dxdot != NULL)
00107 dg_dxdot->PutScalar(0.0);
00108 if (dg_dxdotdot != NULL)
00109 dg_dxdotdot->PutScalar(0.0);
00110
00111
00112 if (dg_dp != NULL)
00113 dg_dp->PutScalar(0.0);
00114 }
00115
00116 void
00117 Albany::SolutionMaxValueResponseFunction::
00118 computeMaxValue(const Epetra_Vector& x, double& global_max, int& global_index)
00119 {
00120 double my_max = -Epetra_MaxDouble;
00121 int my_index = -1, index;
00122
00123
00124 int num_my_nodes = x.MyLength() / neq;
00125 for (int node=0; node<num_my_nodes; node++) {
00126 if (interleavedOrdering) index = node*neq+eq;
00127 else index = node + eq*num_my_nodes;
00128 if (x[index] > my_max) {
00129 my_max = x[index];
00130 my_index = index;
00131 }
00132 }
00133
00134
00135 if (num_my_nodes*neq+eq < x.MyLength()) {
00136 if (interleavedOrdering) index = num_my_nodes*neq+eq;
00137 else index = num_my_nodes + eq*num_my_nodes;
00138 if (x[index] > my_max) {
00139 my_max = x[index];
00140 my_index = index;
00141 }
00142 }
00143
00144
00145 x.Comm().MaxAll(&my_max, &global_max, 1);
00146
00147
00148 if (my_max == global_max)
00149 my_index = x.Map().GID(my_index);
00150 else
00151 my_index = x.GlobalLength();
00152 x.Comm().MinAll(&my_index, &global_index, 1);
00153 }