MFEM v2.0
|
00001 // Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at 00002 // the Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights 00003 // reserved. See file COPYRIGHT for details. 00004 // 00005 // This file is part of the MFEM library. For more information and source code 00006 // availability see http://mfem.googlecode.com. 00007 // 00008 // MFEM is free software; you can redistribute it and/or modify it under the 00009 // terms of the GNU Lesser General Public License (as published by the Free 00010 // Software Foundation) version 2.1 dated February 1999. 00011 00012 // Implementation of Coefficient class 00013 00014 #include <math.h> 00015 #include <limits> 00016 #include "fem.hpp" 00017 00018 double PWConstCoefficient::Eval(ElementTransformation & T, 00019 const IntegrationPoint & ip) 00020 { 00021 int att = T.Attribute; 00022 return(constants(att-1)); 00023 } 00024 00025 void PWConstCoefficient::Read(istream &in) 00026 { 00027 int i, n; 00028 00029 in >> n; 00030 constants.SetSize(n); 00031 for (i = 0; i < n; i++) 00032 in >> constants(i); 00033 } 00034 00035 double FunctionCoefficient::Eval(ElementTransformation & T, 00036 const IntegrationPoint & ip) 00037 { 00038 double x[3]; 00039 Vector transip(x, 3); 00040 00041 T.Transform(ip, transip); 00042 00043 return((*Function)(transip)); 00044 } 00045 00046 double GridFunctionCoefficient::Eval (ElementTransformation &T, 00047 const IntegrationPoint &ip) 00048 { 00049 return GridF -> GetValue (T.ElementNo, ip, Component); 00050 } 00051 00052 void VectorCoefficient::Eval(DenseMatrix &M, ElementTransformation &T, 00053 const IntegrationRule &ir) 00054 { 00055 Vector Mi; 00056 M.SetSize(vdim, ir.GetNPoints()); 00057 for (int i = 0; i < ir.GetNPoints(); i++) 00058 { 00059 M.GetColumnReference(i, Mi); 00060 const IntegrationPoint &ip = ir.IntPoint(i); 00061 T.SetIntPoint(&ip); 00062 Eval(Mi, T, ip); 00063 } 00064 } 00065 00066 void VectorFunctionCoefficient::Eval (Vector &V, ElementTransformation &T, 00067 const IntegrationPoint &ip) 00068 { 00069 double x[3]; 00070 Vector transip(x, 3); 00071 00072 T.Transform (ip, transip); 00073 00074 V.SetSize (vdim); 00075 (*Function) (transip, V); 00076 if (Q) 00077 V *= Q -> Eval (T, ip); 00078 } 00079 00080 VectorArrayCoefficient::VectorArrayCoefficient (int dim) 00081 : VectorCoefficient(dim), Coeff(dim) 00082 { 00083 for (int i = 0; i < dim; i++) 00084 Coeff[i] = NULL; 00085 } 00086 00087 VectorArrayCoefficient::~VectorArrayCoefficient() 00088 { 00089 for (int i = 0; i < vdim; i++) 00090 delete Coeff[i]; 00091 } 00092 00093 void VectorArrayCoefficient::Eval (Vector &V, ElementTransformation &T, 00094 const IntegrationPoint &ip) 00095 { 00096 int i; 00097 00098 V.SetSize(vdim); 00099 for (i = 0; i < vdim; i++) 00100 V(i) = Coeff[i] -> Eval (T, ip); 00101 } 00102 00103 VectorGridFunctionCoefficient::VectorGridFunctionCoefficient ( 00104 GridFunction *gf) : VectorCoefficient (gf -> VectorDim()) 00105 { 00106 GridFunc = gf; 00107 } 00108 00109 void VectorGridFunctionCoefficient::Eval (Vector &V, ElementTransformation &T, 00110 const IntegrationPoint &ip) 00111 { 00112 GridFunc -> GetVectorValue (T.ElementNo, ip, V); 00113 } 00114 00115 void VectorRestrictedCoefficient::Eval(Vector &V, ElementTransformation &T, 00116 const IntegrationPoint &ip) 00117 { 00118 V.SetSize(vdim); 00119 if (active_attr[T.Attribute-1]) 00120 c->Eval(V, T, ip); 00121 else 00122 V = 0.0; 00123 } 00124 00125 void MatrixFunctionCoefficient::Eval (DenseMatrix &K, ElementTransformation &T, 00126 const IntegrationPoint &ip) 00127 { 00128 double x[3]; 00129 Vector transip(x, 3); 00130 00131 T.Transform (ip, transip); 00132 00133 K.SetSize (vdim); 00134 (*Function) (transip, K); 00135 } 00136 00137 MatrixArrayCoefficient::MatrixArrayCoefficient (int dim) 00138 : MatrixCoefficient (dim) 00139 { 00140 Coeff.SetSize (vdim*vdim); 00141 } 00142 00143 MatrixArrayCoefficient::~MatrixArrayCoefficient () 00144 { 00145 for (int i=0; i< vdim*vdim; i++) 00146 delete Coeff[i]; 00147 } 00148 00149 void MatrixArrayCoefficient::Eval (DenseMatrix &K, ElementTransformation &T, 00150 const IntegrationPoint &ip) 00151 { 00152 int i, j; 00153 00154 for (i = 0; i < vdim; i++) 00155 for (j = 0; j < vdim; j++) 00156 K(i,j) = Coeff[i*vdim+j] -> Eval(T, ip); 00157 } 00158 00159 double ComputeLpNorm(double p, Coefficient &coeff, Mesh &mesh, 00160 const IntegrationRule *irs[]) 00161 { 00162 double norm = 0.0; 00163 ElementTransformation *tr; 00164 00165 for (int i = 0; i < mesh.GetNE(); i++) 00166 { 00167 tr = mesh.GetElementTransformation(i); 00168 const IntegrationRule &ir = *irs[mesh.GetElementType(i)]; 00169 for (int j = 0; j < ir.GetNPoints(); j++) 00170 { 00171 const IntegrationPoint &ip = ir.IntPoint(j); 00172 tr->SetIntPoint(&ip); 00173 double val = fabs(coeff.Eval(*tr, ip)); 00174 if (p < numeric_limits<double>::infinity()) 00175 { 00176 norm += ip.weight * tr->Weight() * pow(val, p); 00177 } 00178 else 00179 { 00180 if (norm < val) 00181 norm = val; 00182 } 00183 } 00184 } 00185 00186 if (p < numeric_limits<double>::infinity()) 00187 { 00188 // negative quadrature weights may cause norm to be negative 00189 if (norm < 0.) 00190 norm = -pow(-norm, 1. / p); 00191 else 00192 norm = pow(norm, 1. / p); 00193 } 00194 00195 return norm; 00196 }