Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007 #include <cmath>
00008
00009 #include <Teuchos_CommHelpers.hpp>
00010
00011 #include "AAdapt_InitialCondition.hpp"
00012 #include "AAdapt_AnalyticFunction.hpp"
00013 #include "Epetra_Comm.h"
00014 #include "Albany_Utils.hpp"
00015
00016 namespace AAdapt {
00017
00018 const double pi = 3.141592653589793;
00019
00020
00021 Teuchos::RCP<const Teuchos::ParameterList>
00022 getValidInitialConditionParameters(const Teuchos::ArrayRCP<std::string>& wsEBNames) {
00023 Teuchos::RCP<Teuchos::ParameterList> validPL =
00024 rcp(new Teuchos::ParameterList("ValidInitialConditionParams"));;
00025 validPL->set<std::string>("Function", "", "");
00026 Teuchos::Array<double> defaultData;
00027 validPL->set<Teuchos::Array<double> >("Function Data", defaultData, "");
00028
00029
00030
00031 for(int i = 0; i < wsEBNames.size(); i++)
00032
00033 validPL->set<Teuchos::Array<double> >(wsEBNames[i], defaultData, "");
00034
00035
00036
00037 validPL->set<Teuchos::Array<double> >("Perturb IC", defaultData, "");
00038
00039 return validPL;
00040 }
00041
00042 void InitialConditions(const Teuchos::RCP<Epetra_Vector>& soln,
00043 const Teuchos::ArrayRCP<Teuchos::ArrayRCP<Teuchos::ArrayRCP<Teuchos::ArrayRCP<int> > > >& wsElNodeEqID,
00044 const Teuchos::ArrayRCP<std::string>& wsEBNames,
00045 const Teuchos::ArrayRCP<Teuchos::ArrayRCP<Teuchos::ArrayRCP<double*> > > coords,
00046 const int neq, const int numDim,
00047 Teuchos::ParameterList& icParams, const bool hasRestartSolution) {
00048
00049 icParams.validateParameters(*AAdapt::getValidInitialConditionParameters(wsEBNames), 0);
00050
00051
00052
00053 std::string name;
00054
00055 if(!hasRestartSolution) name = icParams.get("Function", "Constant");
00056
00057 else name = icParams.get("Function", "Restart");
00058
00059 if(name == "Restart") return;
00060
00061
00062
00063 if(name == "EBPerturb" || name == "EBPerturbGaussian" || name == "EBConstant") {
00064
00065 bool perturb_values = false;
00066
00067 Teuchos::Array<double> defaultData(neq);
00068 Teuchos::Array<double> perturb_mag;
00069
00070
00071 if(name != "EBConstant" && icParams.isParameter("Perturb IC")) {
00072
00073 perturb_values = true;
00074
00075 perturb_mag = icParams.get("Perturb IC", defaultData);
00076
00077 }
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 Epetra_Vector lumpedMM(soln->Map(), true);
00094
00095
00096
00097 for(int i = 0; i < soln->MyLength(); i++)
00098
00099 (*soln)[i] = 0;
00100
00101
00102
00103
00104 Teuchos::RCP<AAdapt::AnalyticFunction> initFunc;
00105
00106 for(int ws = 0; ws < wsElNodeEqID.size(); ws++) {
00107
00108 Teuchos::Array<double> data = icParams.get(wsEBNames[ws], defaultData);
00109
00110
00111 if(perturb_values) {
00112
00113 if(name == "EBPerturb")
00114
00115 initFunc = Teuchos::rcp(new AAdapt::ConstantFunctionPerturbed(neq, numDim, ws, data, perturb_mag));
00116
00117 else
00118
00119 initFunc = Teuchos::rcp(new
00120 AAdapt::ConstantFunctionGaussianPerturbed(neq, numDim, ws, data, perturb_mag));
00121 }
00122
00123 else
00124
00125 initFunc = Teuchos::rcp(new AAdapt::ConstantFunction(neq, numDim, data));
00126
00127 std::vector<double> X(neq);
00128 std::vector<double> x(neq);
00129
00130 for(int el = 0; el < wsElNodeEqID[ws].size(); el++) {
00131
00132 for(int i = 0; i < neq; i++)
00133 X[i] = 0;
00134
00135 for(int ln = 0; ln < wsElNodeEqID[ws][el].size(); ln++)
00136 for(int i = 0; i < neq; i++)
00137 X[i] += coords[ws][el][ln][i];
00138
00139 for(int i = 0; i < neq; i++)
00140 X[i] /= (double)neq;
00141
00142 initFunc->compute(&x[0], &X[0]);
00143
00144 for(int ln = 0; ln < wsElNodeEqID[ws][el].size(); ln++) {
00145 Teuchos::ArrayRCP<int> lid = wsElNodeEqID[ws][el][ln];
00146
00147 for(int i = 0; i < neq; i++) {
00148
00149 (*soln)[lid[i]] += x[i];
00150
00151 lumpedMM[lid[i]] += 1.0;
00152
00153 }
00154
00155 }
00156 }
00157 }
00158
00159
00160
00161 for(int i = 0; i < soln->MyLength(); i++)
00162
00163 (*soln)[i] /= lumpedMM[i];
00164
00165 return;
00166
00167 }
00168
00169 if(name == "Coordinates") {
00170
00171
00172
00173 int numDOFsPerDim = neq / numDim;
00174
00175 for(int ws = 0; ws < wsElNodeEqID.size(); ws++) {
00176 for(int el = 0; el < wsElNodeEqID[ws].size(); el++) {
00177 for(int ln = 0; ln < wsElNodeEqID[ws][el].size(); ln++) {
00178
00179 const double* X = coords[ws][el][ln];
00180 Teuchos::ArrayRCP<int> lid = wsElNodeEqID[ws][el][ln];
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 for(int j = 0; j < numDOFsPerDim; j++)
00196 for(int i = 0; i < numDim; i++)
00197 (*soln)[lid[j * numDim + i]] = X[i];
00198
00199 }
00200 }
00201 }
00202
00203 }
00204
00205 else {
00206
00207 Teuchos::Array<double> defaultData(neq);
00208 Teuchos::Array<double> data = icParams.get("Function Data", defaultData);
00209
00210
00211 Teuchos::RCP<AAdapt::AnalyticFunction> initFunc
00212 = createAnalyticFunction(name, neq, numDim, data);
00213
00214
00215 std::vector<double> x(neq);
00216
00217 for(int ws = 0; ws < wsElNodeEqID.size(); ws++) {
00218 for(int el = 0; el < wsElNodeEqID[ws].size(); el++) {
00219 for(int ln = 0; ln < wsElNodeEqID[ws][el].size(); ln++) {
00220 const double* X = coords[ws][el][ln];
00221 Teuchos::ArrayRCP<int> lid = wsElNodeEqID[ws][el][ln];
00222
00223 for(int i = 0; i < neq; i++) x[i] = (*soln)[lid[i]];
00224
00225 initFunc->compute(&x[0], X);
00226
00227 for(int i = 0; i < neq; i++)(*soln)[lid[i]] = x[i];
00228 }
00229 }
00230 }
00231
00232 }
00233
00234 }
00235
00236 }